diff -Nru wine-staging-1.9.0~ubuntu12.04.1/aclocal.m4 wine-staging-1.9.3~ubuntu12.04.1/aclocal.m4 --- wine-staging-1.9.0~ubuntu12.04.1/aclocal.m4 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/aclocal.m4 2016-02-08 19:32:34.000000000 +0000 @@ -171,21 +171,25 @@ dnl **** Check for a mingw program, trying the various mingw prefixes **** dnl -dnl Usage: WINE_CHECK_MINGW_PROG(variable,prog,[value-if-not-found],[path]) +dnl Usage: WINE_CHECK_MINGW_PROG(variable,[value-if-not-found],[path]) dnl AC_DEFUN([WINE_CHECK_MINGW_PROG], [case "$host_cpu" in + arm*) + ac_prefix_list="armv7-w64-mingw32-clang armv7-w64-mingw32-gcc" ;; i[[3456789]]86*) ac_prefix_list="m4_foreach([ac_wine_prefix],[w64-mingw32, pc-mingw32, mingw32msvc, mingw32], - m4_foreach([ac_wine_cpu],[i686,i586,i486,i386],[ac_wine_cpu-ac_wine_prefix-$2 ])) - mingw32-$2" ;; + m4_foreach([ac_wine_cpu],[i686,i586,i486,i386],[ac_wine_cpu-ac_wine_prefix-gcc ])) + m4_foreach([ac_wine_cpu],[i686,i586,i486,i386],[ac_wine_cpu-w64-mingw32-clang ]) + mingw32-gcc" ;; x86_64) ac_prefix_list="m4_foreach([ac_wine_prefix],[pc-mingw32, w64-mingw32, mingw32msvc], - m4_foreach([ac_wine_cpu],[x86_64,amd64],[ac_wine_cpu-ac_wine_prefix-$2 ]))" ;; + m4_foreach([ac_wine_cpu],[x86_64,amd64],[ac_wine_cpu-ac_wine_prefix-gcc ])) + m4_foreach([ac_wine_cpu],[x86_64,amd64],[ac_wine_cpu-w64-mingw32-clang ])" ;; *) ac_prefix_list="" ;; esac -AC_CHECK_PROGS([$1],[$ac_prefix_list],[$3],[$4])]) +AC_CHECK_PROGS([$1],[$ac_prefix_list],[$2],[$3])]) dnl **** Define helper functions for creating config.status files **** @@ -197,6 +201,7 @@ rm -f $wine_rules_file ALL_POT_FILES="" GITIGNORE="# Automatically generated by configure; DO NOT EDIT!!" +AC_SUBST(SUBDIRS,"") AC_SUBST(ALL_TEST_RESOURCES,"") wine_fn_append_file () @@ -225,13 +230,7 @@ wine_fn_depend_rules () { - wine_fn_append_rule \ -"$ac_dir/Makefile: $srcdir/$ac_dir/Makefile.in Makefile \$(MAKEDEP) - \$(MAKEDEP) $ac_dir -depend: $ac_dir/depend -.PHONY: $ac_dir/depend -$ac_dir/depend: \$(MAKEDEP) dummy - \$(MAKEDEP) $ac_dir" + wine_fn_append_file SUBDIRS $ac_dir } wine_fn_pot_rules () @@ -242,7 +241,7 @@ then wine_fn_append_file ALL_POT_FILES $ac_dir/msg.pot wine_fn_append_rule \ -"$ac_dir/msg.pot: $ac_dir/Makefile dummy +"$ac_dir/msg.pot: dummy @cd $ac_dir && \$(MAKE) msg.pot $ac_dir/msg.pot: tools/wmc include" fi @@ -250,7 +249,7 @@ then wine_fn_append_file ALL_POT_FILES $ac_dir/rsrc.pot wine_fn_append_rule \ -"$ac_dir/rsrc.pot: $ac_dir/Makefile dummy +"$ac_dir/rsrc.pot: dummy @cd $ac_dir && \$(MAKE) rsrc.pot $ac_dir/rsrc.pot: tools/wrc include" fi @@ -262,7 +261,7 @@ wine_fn_append_rule \ "all: $ac_dir .PHONY: $ac_dir -$ac_dir: $ac_dir/Makefile dummy +$ac_dir: dummy @cd $ac_dir && \$(MAKE)" } @@ -274,7 +273,7 @@ ".PHONY: $ac_dir/install $ac_dir/uninstall $ac_dir/install:: $ac_dir @cd $ac_dir && \$(MAKE) install -$ac_dir/uninstall:: $ac_dir/Makefile +$ac_dir/uninstall:: @cd $ac_dir && \$(MAKE) uninstall install:: $ac_dir/install __uninstall__: $ac_dir/uninstall" @@ -301,40 +300,31 @@ wine_fn_clean_rules () { ac_clean=$[@] - ac_extraclean="$ac_dir/Makefile" - test "$srcdir" = . && ac_extraclean="$ac_extraclean $ac_dir/.gitignore" - case $ac_dir in - */tests) ac_extraclean="$ac_extraclean $ac_dir/testlist.c" ;; - esac if wine_fn_has_flag clean then wine_fn_append_rule \ -"__clean__: $ac_dir/clean -.PHONY: $ac_dir/clean -$ac_dir/clean: $ac_dir/Makefile - @cd $ac_dir && \$(MAKE) clean - \$(RM) $ac_extraclean" +"$ac_dir/clean: dummy + @cd $ac_dir && \$(MAKE) clean" else wine_fn_append_rule \ -"__clean__: $ac_dir/clean -.PHONY: $ac_dir/clean -$ac_dir/clean: dummy - \$(RM) \$(CLEAN_FILES:%=$ac_dir/%) $ac_clean $ac_extraclean" +"$ac_dir/clean: dummy + \$(RM) \$(CLEAN_FILES:%=$ac_dir/%) $ac_clean" fi + wine_fn_append_rule \ +"__clean__: $ac_dir/clean +.PHONY: $ac_dir/clean" } wine_fn_disabled_rules () { ac_clean=$[@] - ac_extraclean="$ac_dir/Makefile" - test "$srcdir" = . && ac_extraclean="$ac_extraclean $ac_dir/.gitignore" wine_fn_append_rule \ "__clean__: $ac_dir/clean .PHONY: $ac_dir/clean $ac_dir/clean: dummy - \$(RM) \$(CLEAN_FILES:%=$ac_dir/%) $ac_clean $ac_extraclean" + \$(RM) \$(CLEAN_FILES:%=$ac_dir/%) $ac_clean" } wine_fn_config_makefile () @@ -413,7 +403,7 @@ wine_fn_clean_rules $ac_clean wine_fn_append_rule \ "$ac_dir: __builddeps__ -manpages htmlpages sgmlpages xmlpages:: $ac_dir/Makefile +manpages htmlpages sgmlpages xmlpages:: @cd $ac_dir && \$(MAKE) \$[@] .PHONY: $ac_dir/install-lib $ac_dir/uninstall install install-lib:: $ac_dir/install-lib @@ -441,9 +431,9 @@ wine_fn_append_rule \ "__builddeps__: $ac_file.$IMPLIBEXT $ac_file.$STATIC_IMPLIBEXT $ac_file.$IMPLIBEXT $ac_file.$STATIC_IMPLIBEXT $ac_file.cross.a: $ac_deps -$ac_file.def: $srcdir/$ac_dir/$ac_name.spec $ac_dir/Makefile \$(WINEBUILD) +$ac_file.def: $srcdir/$ac_dir/$ac_name.spec \$(WINEBUILD) \$(WINEBUILD) \$(TARGETFLAGS)$ac_implibflags -w --def -o \$[@] --export $srcdir/$ac_dir/$ac_name.spec -$ac_file.$STATIC_IMPLIBEXT: $ac_dir/Makefile dummy +$ac_file.$STATIC_IMPLIBEXT: dummy @cd $ac_dir && \$(MAKE) lib$ac_implib.$STATIC_IMPLIBEXT .PHONY: $ac_dir/install-dev $ac_dir/uninstall $ac_dir/install-dev:: $ac_file.$IMPLIBEXT @@ -466,7 +456,7 @@ then wine_fn_append_rule \ "__builddeps__: $ac_file.cross.a -$ac_file.cross.a: $ac_dir/Makefile dummy +$ac_file.cross.a: dummy @cd $ac_dir && \$(MAKE) lib$ac_implib.cross.a" fi @@ -474,9 +464,9 @@ then wine_fn_append_rule \ "__builddeps__: $ac_file.$IMPLIBEXT -$ac_file.def: $srcdir/$ac_dir/$ac_name.spec $ac_dir/Makefile \$(WINEBUILD) +$ac_file.def: $srcdir/$ac_dir/$ac_name.spec \$(WINEBUILD) \$(WINEBUILD) \$(TARGETFLAGS)$ac_implibflags -w --def -o \$[@] --export $srcdir/$ac_dir/$ac_name.spec -$ac_file.a: $srcdir/$ac_dir/$ac_name.spec $ac_dir/Makefile \$(WINEBUILD) +$ac_file.a: $srcdir/$ac_dir/$ac_name.spec \$(WINEBUILD) \$(WINEBUILD) \$(TARGETFLAGS)$ac_implibflags -w --implib -o \$[@] --export $srcdir/$ac_dir/$ac_name.spec .PHONY: $ac_dir/install-dev $ac_dir/uninstall $ac_dir/install-dev:: $ac_file.$IMPLIBEXT @@ -489,7 +479,7 @@ then wine_fn_append_rule \ "__builddeps__: $ac_file.cross.a -$ac_file.cross.a: $srcdir/$ac_dir/$ac_name.spec $ac_dir/Makefile \$(WINEBUILD) +$ac_file.cross.a: $srcdir/$ac_dir/$ac_name.spec \$(WINEBUILD) \$(WINEBUILD) \$(CROSSTARGET:%=-b %)$ac_implibflags -w --implib -o \$[@] --export $srcdir/$ac_dir/$ac_name.spec" fi @@ -600,7 +590,7 @@ wine_fn_clean_rules $ac_clean wine_fn_append_rule \ -"$ac_dir: programs/winetest/Makefile __builddeps__ +"$ac_dir: __builddeps__ programs/winetest: $ac_dir check test: $ac_dir/test .PHONY: $ac_dir/test @@ -614,7 +604,7 @@ wine_fn_append_rule \ "crosstest: $ac_dir/crosstest .PHONY: $ac_dir/crosstest -$ac_dir/crosstest: $ac_dir/Makefile __builddeps__ dummy +$ac_dir/crosstest: __builddeps__ dummy @cd $ac_dir && \$(MAKE) crosstest" fi } @@ -652,7 +642,7 @@ \$(RM) $ac_links" for f in $ac_links; do wine_fn_ignore_file $f; done test -n "$ac_linkdir" || return - wine_fn_append_rule "$ac_linkdir/Makefile $ac_linkdir/depend: $ac_links" + wine_fn_append_rule "$ac_linkdir/depend: $ac_links" }]) dnl **** Define helper function to append a file to a makefile file list **** diff -Nru wine-staging-1.9.0~ubuntu12.04.1/ANNOUNCE wine-staging-1.9.3~ubuntu12.04.1/ANNOUNCE --- wine-staging-1.9.0~ubuntu12.04.1/ANNOUNCE 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/ANNOUNCE 2016-02-08 19:32:34.000000000 +0000 @@ -1,16 +1,17 @@ -The Wine development release 1.9.0 is now available. +The Wine development release 1.9.3 is now available. What's new in this release (see below for details): - - A number of fixes that were deferred during code freeze. - - WSAPoll implementation. - - Standard font dialog fixes. - - X11 drag&drop improvements. + - New version of the Gecko engine based on Firefox 44. + - JSON support in JavaScript. + - Improved line breaking in DirectWrite. + - Some more write support in WebServices. + - Still more Shader Model 4 instructions. - Various bug fixes. The source is available from the following locations: - http://dl.winehq.org/wine/source/1.9/wine-1.9.0.tar.bz2 - http://mirrors.ibiblio.org/wine/source/1.9/wine-1.9.0.tar.bz2 + http://dl.winehq.org/wine/source/1.9/wine-1.9.3.tar.bz2 + http://mirrors.ibiblio.org/wine/source/1.9/wine-1.9.3.tar.bz2 Binary packages for various distributions will be available from: @@ -26,240 +27,393 @@ ---------------------------------------------------------------- -Bugs fixed in 1.9.0 (total 43): +Bugs fixed in 1.9.3 (total 24): - 3611 CorelDRAW 9: copy/paste of graphics elements between multiple instances of the program doesn't work - 8097 Pazuru Alfabet picture display flicker - 14290 winhelp: temporary 100% CPU use when loading some help files - 15253 VB6 application doesn't fully render text using custom bitmap font (only one character shown) - 15951 Origin Pro 6.1 / 7.5 / 8.0 / 8.5: Matrix menu commands don't work (dialog for auto-spacing of levels, colors or linestyles in contour-plots not shown) - 17310 Window looses its top returning from fullscreen and is undragable from normal means - 18347 Multiple applications crash on unimplemented function gdiplus.dll.GdipImageSetAbort (Cooliris, IPLA 0.9) - 20208 Liquid Story Binder - 'z' location broken and window management issues - 22871 MinGW gdb 5.2.1 crashes when trying to enter commands - 22966 Restricted Area: incorrect rendering of character animations - 25104 ChooseFont dialog does not support non standard font sizes - 26769 Unable to play mms in Windows Media Player [9|10] with builtin wininet - 28915 Eclipse Indigo SR1 (3.7.1) C++ IDE complains "'Periodic workspace save.' has encountered a problem." (java expects NtWriteFile to support FILE_WRITE_TO_END_OF_FILE) - 29455 Call of Duty 4: persons are not visible - 30621 Web Forum Reader 3.0 shows empty/white page when adding website resource (embedded browser) - 30678 Phantasy Star Online: Ambition of The Illuminus (PSU: AOTI): resolution dropdown box empty - 30811 Music in Alpha Centauri stutters - 32650 LibreOffice 4 beta UI quite slow - 32926 PPTV 3.2.1 crashes after installation - 33101 FlashDevelop 4.3.0 (.NET 2.0 app) crashes on startup with 'Initialization failed. Please, run FlashDevelop again.' - 33641 MS Comptes Bancaires 9.0 crashes on startup - 33651 HeeksCAD & HeeksCNC fails - 33737 PowerPoint Viewer 2010 cannot start when Windows version is Vista or later ('IFileDialogCustomize::MakeProminent' and 'IFileDialogCustomize::SetControlItemState' are stubs) - 34312 3d chat client for there.com crashes - 35187 Jade Empire Special Edition configuration tool always resetting video settings - 35605 3Dmark 2000: Choosing "Run Default Benchmark" says "Benchmark Aborted!" - 35693 Kaspersky Internet Security 2010 service installation fails due to missing TDI wrapper library 'tdi.sys' - 37457 Musedit crashes when trying to transcribe from a midi file - 37580 Spotify "Browse" GUI not present. - 37646 valgrind shows an invalid free in advpack/tests/install.c - 38076 GameRanger: unimplemented function dnsapi.dll.DnsFlushResolverCacheEntry_A - 38321 Game Heroes 3.5 In The Wake Of Gods (Heroes III of Might And Magic mod): Mouse pointer disappears after click - 38580 Secret Files 1-2, UFO:Extraterrestrials Gold: hardware mouse pointer missing/corrupted - 38601 Planetary Annihilation needs WS2_32.dll.WSAPoll - 38734 Application Impact Telemetry Static Analyzer from Windows SDK 8.1 App Certification Kit needs api-ms-win-core-path-l1-1-0.dll - 38818 Umax Astra 4100 USB scanner driver installer needs setupx.dll16.DiBuildDriverIndex in Win9X mode - 39611 Any Video Converter (AVC) crashes after converting a video, needs msvcr100.dll._wtmpnam_s - 39678 Zararadio can not read folder/file name path with Latin characters - 39764 An attempt to do automatic authentication unexpectedly drops the payload from server response - 39769 Caffeine Demo fails to start with NVIDIA: Extension GL_VERSION_3_3 required for glVertexAttribDivisor not supported - 39770 "Enter/Exit Full Screen" menu isn't localized - 39789 Reusing xmlhttprequest doesn't clear previous headers - 39811 GetLongPathName not working on case insensitive filesystems when short path is passed + 12652 Tom Clancy's Rainbow Six: Vegas 2 fails to launch (number of quality levels for D3DMULTISAMPLE_NONMASKABLE multiple-sample type must not exceed 8) + 14617 Multiple Visual Basic 5/6 applications using ActiveX components depend on Standard OLE Types Typelib which is missing from 'olepro32.dll' + 28488 Arcanum: Mouseclicks in character generation screen doubled with pause + 32695 Yahoo Messenger login crashes on unimplemented function nspr4.dll.PR_SetCurrentThreadName (messenger provided 'nspr4.dll' ABI incompatible with Wine Gecko) + 32852 BioEdit: changing the install directory doesn't show the change in the GUI + 33140 Photos opened in Nikon Capture NX 2.4 have inverted red and blue channel for displaying. + 33988 Star Wars: The Force Unleashed II - Crashes with a page fault + 34504 __unDName doesn't support function pointer with type "P8" + 34507 __unDName doesn't support data type "$$B" + 37632 farcry 3 display strange colors + 37911 LINE program, black window + 39092 Regression introduced with xaudio2_8 + 39181 "When Monster Strikes", "The Vanishing of Ethan Carter Redux" require msvcr120.dll._set_FMA3_enable + 39615 Multiple applications want msdrm.dll (Dassault Systemes CATIA v5, FoxitReader 5.1) + 39686 IE frame freezes after calling the print dialog + 39865 Poker Night: changing to non-fullscreen mode crashes X. + 39875 Starcraft can't see Direct Cable Connection games hosted on another computer + 39904 Spurious "You must use msvcrt" error even when __MSVCRT__ is defined (-mno-cygwin) + 39928 Star Wars: The Old Republic corruptions in dialogues when Conversation Depth of Field is enabled + 39933 iNode 3.6 client needs ndis.sys.NdisAllocateSpinLock + 39965 Lego Mindstorms EV3 Software does not find EV3 brick using Bluetooth: needs irprops.cpl + 40021 IDEA v1.7 fails to start + 40035 VMware shared folders network provider fails loading in MPR + 40052 Opening an RTF file with "A Wine application" fails with "File not found" ---------------------------------------------------------------- -Changes since 1.8: +Changes since 1.9.2: Alex Henrie (2): - kernel32: Add TRACE to SetCommState. - ntdll: Increase maximum number of autodetected COM/LPT ports to 256. + kernel32: Set error if dstlen < 0 in codepage conversion functions. + user32: Avoid double initialization in IsDialogMessageW. -Alexandre Julliard (1): - secur32/tests: Don't check the exact number of cipher bits. +Alexandre Julliard (21): + ntdll/tests: Add some more tests for kernel object names. + ntdll/tests: Fix some more failures on restricted Windows. + wine.inf: Fix the wordpad.exe path in associations. + server: Fix initialization of mailslot objects that don't have a name. + ntdll: Add tests for kernel object names in the various open functions. + wine.inf: Add quotes around the wordpad.exe path. + server: Implement NtOpenJobObject. + ntdll: Add a helper to validate attributes in open calls, and use a common pattern in all calls. + ntdll: Add tests for NULL object attributes. + server: Use a common helper function to implement open object calls. + server: Directly return a structure in get_req_unicode_str(). + include: Update stdcall and cdecl definitions in crtdefs.h. + ntdll/tests: Add a helper function to run tests across all kernel object types. + ntdll: Add tests for the length of the object attributes structure. + server: Fix checks for a valid directory in object attributes. + user32: Add some tests for window station and desktop object names. + server: Implement serial port read interval timeouts. + server: Don't return an error if the created window station already exists. + tools: Add a script to update the ANNOUNCE file at release time. + server: Add link_name and unlink_name object operations. + server: Use the link_name operation to create named objects. + +Alistair Leslie-Hughes (5): + include: Add GdipGetPenTransform, GdipSetPenTransform declarations. + gdiplus/tests: Add Pen Transform tests. + olepro32: Add typelib resource. + d3d11: Add the Direct3D 11.1 D3D11_FORMAT_SUPPORT enum elements. + gdiplus: Implement GdipGetPenTransform. + +Andrew Eikum (2): + xaudio2: Report incoming underruns to the application. + ntdll: Implement SystemLogicalProcessorInformationEx. + +Andrey Gusev (1): + d3dx9: Fix a typo. + +André Hentschel (2): + wpcap: Forward pcap_strerror to msvcrt.strerror. + include: Add more OID defines. + +Anton Baskanov (2): + user32: Correctly update caret state in the server in SetCaretPos. + strmbase: Decommit allocator when streaming stops. + +Aric Stewart (3): + imm32: Messages from ImmGenerateMessage are sent not posted. + usp10: Directional control codes force complex itemization. + usp10: Correct math punctuation handling in itemization. + +Austin English (2): + msdrm: Add stub dll. + ndis.sys: Add NdisAllocateSpinLock stub. + +Christopher Thielen (4): + comctl32: Ensure that toolbar respond only to changes in WM_CAPTURECHANGED handler. + comctl32: Ensure that trackbar respond only to changes in WM_CAPTURECHANGED handler. + user32: Ensure that button responds only to changes in WM_CAPTURECHANGED handler. + user32: A window may be notified with WM_CAPTURECHANGED about itself if SetCapture() is called twice. + +François Gouget (18): + bcrypt/tests: Add a trailing '\n' to some ok() calls. + mshtml/tests: Add a trailing '\n' to an ok() call. + bcrypt: Add a trailing '\n' to a WARN() call. + shell32/tests: Trace the last ShellExecute command whenever a corresponding test fails. + shell32/tests: Call okShell() after a shell_execute{_ex}() test. + shell32/tests: Trace the association properties for the DDE tests. + shell32/tests: Test handling of nonexistent verbs in ShellExecute() & co. + shell32/tests: Show that verbs and classes override ShellExecute()'s normal handling of executables. + shell32/tests: Fix a couple of okChildPath()/okChildString() mixups. + advapi32/tests: Trace the SIDs if they are not as expected. + shell32/tests: Add traces to the WaitForInputIdle() hooking process. + shell32/tests: Reorder the functions to avoid forward declarations. + shell32/tests: Declare childPrintf() as a printf-style function. + shell32/tests: Check the child process exit code and close the process handle. + shell32/tests: Check for failures in the child process. + shell32/tests: Test environment variable inheritance with ShellExecute(). + shell32/tests: Add server-side DDE checks. + ntdll/tests: Fix an infinite loop on platforms where NtQuerySystemInformationEx() is not implemented. + +Frédéric Delanoy (1): + po: Update French translation. + +Hans Leidekker (14): + wininet/tests: Fix test failures. + msi: Include the dialog in the check for duplicate event subscriptions. + wined3d: Don't leak the device context on failure in context_create(). + webservices: Add support for structure types in WsWriteType. + webservices: Implement WsWriteElement. + webservices: Implement WsWriteValue. + webservices: Implement WsWriteAttribute. + webservices: Implement WsReadStartAttribute. + webservices: Add support for structure types in WsReadType. + webservices: Implement WsReadEndAttribute. + webservices: Don't validate reader state in read_endelement. + webservices: Support more writer states in WsWriteText. + webservices: Parse CDATA nodes. + webservices: Implement WsWriteStartCData and WsWriteEndCData. + +Henri Verbeet (43): + ddraw: DDSD_LPSURFACE requires a non-NULL lpSurface. + ddraw: DDSCAPS_ALLOCONLOAD doesn't override DDSD_LPSURFACE. + ddraw: DDSCAPS_ALLOCONLOAD requires DDSCAPS_TEXTURE. + wined3d: Unify WINED3D_RTYPE_TEXTURE and WINED3D_RTYPE_CUBE_TEXTURE. + wined3d: Rename WINED3D_RTYPE_VOLUME_TEXTURE to WINED3D_RTYPE_TEXTURE_3D. + wined3d: Rename the texture creation flags to WINED3D_TEXTURE_CREATE_*. + wined3d: Pass non-NULL rectangles to wined3d_surface_blt() in resolve_depth_buffer(). + wined3d: Pass non-NULL rectangles to wined3d_surface_blt() in wined3d_device_copy_resource(). + ddraw: Pass non-NULL rectangles to wined3d_surface_blt() in ddraw_surface_update_frontbuffer(). + ddraw: Pass non-NULL rectangles to wined3d_surface_blt() in ddraw_surface_blt_clipped(). + ddraw: Pass non-NULL rectangles to wined3d_surface_blt() in ddraw_surface7_BltFast(). + wined3d: Pass non-NULL rectangles to wined3d_surface_blt() in wined3d_texture_blt(). + wined3d: Require non-NULL rectangles in wined3d_surface_blt(). + d3d9: Pass non-NULL rectangles to wined3d_texture_blt() in d3d9_device_StretchRect(). + d3d9: Pass non-NULL rectangles to wined3d_texture_blt() in d3d9_device_GetRenderTargetData(). + wined3d: Require non-NULL rectangles in wined3d_texture_blt(). + ddraw: Always store a pointer to the wined3d texture in the surface. + ddraw: Use wined3d_texture_blt() in ddraw_surface7_BltFast(). + ddraw: Use wined3d_texture_blt() in ddraw_surface_blt_clipped(). + ddraw: Use wined3d_texture_blt() in ddraw_surface_update_frontbuffer(). + ddraw: Use wined3d_texture_blt() in copy_mipmap_chain(). + ddraw: Print an ERR for non-zero sub-resource indices in ddraw_surface7_Flip(). + ddraw: Use wined3d_texture_preload() in d3d_device7_PreLoad(). + ddraw: Use wined3d_texture_get_dc() in ddraw_surface_update_frontbuffer(). + ddraw: Use wined3d_texture_get_dc() in ddraw_surface7_GetDC(). + ddraw: Use wined3d_texture_release_dc() in ddraw_surface7_ReleaseDC(). + wined3d: Use wined3d_texture_get_dc() in device_load_logo(). + ddraw: Use wined3d_resource_map() in d3d_texture2_Load(). + ddraw: Use wined3d_resource_map() in surface_lock(). + ddraw: Use wined3d_resource_unmap() in ddraw_surface7_Unlock(). + wined3d: Simplify wined3d_rendertarget_view_create_from_sub_resource(). + wined3d: Use wined3d_rendertarget_view_create() in wined3d_device_init_3d(). + wined3d: Use wined3d_rendertarget_view_create() in wined3d_device_reset(). + wined3d: Pass a view to blit_shader.color_fill(). + wined3d: Pass a view to blit_shader.depth_fill(). + ddraw: Use wined3d_rendertarget_view_create_from_sub_resource() in ddraw_surface_get_rendertarget_view(). + wined3d: Merge cubetexture_init() into texture_init(). + wined3d: Introduce a debug function for struct wined3d_box. + ddraw: Move the mip-level dimensions fix-up from ddraw_surface_init() to ddraw_surface_create(). + ddraw: Use wined3d_texture_get_sub_resource() in ddraw_surface7_Flip(). + wined3d: Make the "texture" parameter to wined3d_texture_get_sub_resource() const. + wined3d: Make the "icb" field in struct wined3d_shader_reg_maps const. + wined3d: Make the "icb" field in struct wined3d_shader_instruction const. + +Hugh McMaster (7): + wineconsole: Apply the new background colour to the visible screen buffer. + kernel32: Apply the new background colour to the active line. + wineconsole: Apply the selected background colour to the entire font preview dialog. + kernel32: Implement the TRUE pathway of GetCurrentConsoleFont. + kernel32/tests: Add tests for the TRUE pathway of GetCurrentConsoleFont. + wineconsole: Improve a user dialog resource string. + user32/tests: Add some expected WPARAM values to the SetFocusComboBox sequences. + +Huw D. M. Davies (4): + bcrypt/tests: Fix incorrect null termination. + include: Add IDropSourceNotify. + shell32: The attributes is not an array, so don't label it as such. + shell32: Set the stream and storage attributes where needed. + +Jacek Caban (12): + jscript: Make parse_decimal a more generic helper. + jscript: Added new is_finite helper. + jscript: Added JSON object stub implementation. + jscript: Added JSON.parse implementation. + jscript: Added JSON.stringify implementation. + jscript: Added JSON tests. + bcrypt: Make BCRYPT_HASH_LENGTH tests more generic. + bcrypt: Make BCRYPT_HASH_LENGTH implementation more generic. + bcrypt: Added BCRYPT_ALGORITHM_NAME property implementation. + mshtml: Use script versioning 2 if we're not in quirks mode. + jscript: Fixed tests on some old jscript versions. + mshtml: Wine Gecko 2.44 release. + +Jactry Zeng (1): + winecfg: Use better shortcut keys. + +Jeremy White (1): + winspool.drv: If the call to cupsPrintFile fails, print the cups error message. + +Joachim Priesner (5): + scrrun: Implement filesys_DriveExists. + scrrun/tests: Move code to get a fixed drive to a function. + scrrun: Implement filesys_GetDrive for local drives. + comctl32: Fix comments explaining visibleOrder and firstVisible. + comctl32: Treeview: Fix crash when deleting the first visible item while bRedraw == false. + +Justas Lavišius (1): + include: Force stack alignment on x86_64. + +Józef Kucia (48): + wined3d: Add EXT_texture_integer extension. + wined3d: Set default sampler filtering to NEAREST. + wined3d: Add support for integer samplers. + wined3d: Make distinction between sampler index and sampler bind index. + wined3d: Add ARB_texture_rgb10_a2ui extension. + wined3d: Add support for WINED3DFMT_R8G8B8A8_UINT textures. + wined3d: Add support for WINED3DFMT_R8G8B8A8_SINT textures. + d3d11/tests: Add test for integer textures. + d3d10core/tests: Add test for integer textures. + wined3d: Recognize SM4 dcl_temps opcode. + wined3d: Recognize SM4 else opcode. + wined3d: Implement SM4 ieq instruction. + wined3d: Implement SM4 ilt instruction. + wined3d: Implement SM4 ineg instruction. + wined3d: Recognize SM4 not opcode. + wined3d: Implement SM4 not instruction. + wined3d: Implement SM4 ine instruction. + wined3d: Recognize SM4 round_pi opcode. + wined3d: Recognize SM4 round_z opcode. + wined3d: Implement SM4 round_pi instruction. + wined3d: Implement SM4 round_z instruction. + wined3d: Recognize SM4 sample_c_lz opcode. + wined3d: Recognize SM4 sample_b opcode. + wined3d: Validate render state in wined3d_device_set_render_state(). + ddraw: Return DDERR_INVALIDPARAMS for render states >= D3DSTATE_OVERRIDE_BIAS. + wined3d: Add support for WINED3DFMT_R32G32B32_FLOAT format. + wined3d: Add support for WINED3DFMT_R16_UNORM format. + wined3d: Recognize SM4 icb register. + wined3d: Recognize SM4 dcl_immediateConstantBuffer. + wined3d: Recognize SM4 dcl_output opcode. + wined3d: Recognize SM4 dcl_sampler opcode. + wined3d: Fix SM4 exp, log and rsq instructions. + wined3d: Clean up naming in shader_sm1.c. + wined3d: Recognize SM4 dcl_input_ps opcode. + wined3d: Recognize SM4 dcl_input opcode. + wined3d: Recognize SM4 dcl_input_ps_sgv opcode. + wined3d: Recognize SM4 dcl_input_ps_siv opcode. + wined3d: Recognize SM4 dcl_input_sgv opcode. + wined3d: Recognize SM4 dcl_output_siv opcode. + wined3d: Recognize SM4 dcl_input_siv opcode. + wined3d: Recognize SM4 dcl_globalFlags opcode. + wined3d: Recognize SM4 sample_c opcode. + wined3d: Merge shader_glsl_sample() and shader_glsl_sample_lod(). + wined3d: Implement SM4 sample_b instruction. + wined3d: Implement SM4 sample_d instruction. + d3d11/tests: Add test for SM4 sample_b instruction. + d3d10core/tests: Add test for SM4 sample_b instruction. + d3d11: Rename WINE_D3D10_TO_STR to WINE_D3D_TO_STR. + +Ken Thomases (3): + winemac: Make macdrv_process_text_input() asynchronous and process internal events while awaiting its result. + winemac: Change the processEvents parameter of -[WineEventQueue query:timeout:processEvents:] to a flags bitmask. + winemac: Don't process QUERY_IME_CHAR_RECT while waiting in OnMainThread(). -Alistair Leslie-Hughes (2): - oledb32: Convert to a BSTR to work out it size. - oledb32: GetConversionSize shouldn't fail for null variants. - -Andrew Eikum (1): - maintainers: Alphabetize. - -Andrey Melnikov (1): - gdi32: Handle NULL filename in GetICMProfileA(). - -André Hentschel (14): - winmm: Remove a dead assignment (Clang). - shell32: Minor cleanup of SHELL_execute (Clang). - xaudio2_7: Check return of IAudioClient_Start (Coverity). - wininet: Return the correct error code (Clang). - msvcrt: Don't continue on demangle failure (Coverity). - mmdevapi: Skip device if GetId fails (Coverity). - winmm: Respect return value from joyGetPos (Coverity). - version: Remove dead assignments (Clang). - services: Fix access adjustment by reordering code (Clang). - setupapi: Remove dead code (Clang). - secur32: Ignore pfQOP in VerifySignature (Clang). - sane.ds: Remove dead code (Clang). - wineboot: Remove dead code (Clang). - winedbg: Remove a dead assignment (Clang). - -Aurimas Fišeras (1): - po: Update Lithuanian translation. - -Austin English (10): - iexplore: Sync registry and program resource values. - setupx.dll16: Add DiBuildDriverIndex stub. - tdi.sys: Add a stub dll. - api-ms-win-core-path-l1-1-0: Add stub dll. - hal: Add READ_PORT_ULONG stub. - kernel32: Make CompareStringEx semi-stub flag FIXME only show once. - pdh: Add PdhGetLogFileTypeA/W stubs. - setupapi: Add SetupDiSelectBestCompatDrv stubs. - ntoskrnl.exe: Add RtlInitializeGenericTableAvl/RtlInsertElementGenericTableAvl stubs. - api-ms-win-security-lsalookup-l1-1-0: New dll. - -Bruno Jesus (1): - ws2_32: Add WSAPoll() implementation. - -Changhui Liu (2): - hidclass.sys: Initialize ext->irp_queue immediately after HID_CreateDevice. - hidclass.sys: Properly print 80 bytes in first line when tracing ParseDescriptor. - -Hans Leidekker (11): - qmgr: Use the full path for HTTP downloads. - dnsapi: Add a stub implementation of DnsFlushResolverCacheEntry_A/UTF8/W. - winhttp: Don't drain content until authorization is handled successfully. - wbemdisp: Calculate the object count returned from ISWbemObjectSet::get_Count just once. - wbemprox: Support string literals in comparisons with integer properties. - wbemprox: Implement Win32_NetworkAdapterConfiguration.Description. - wbemprox: Implement Win32_NetworkAdapterConfiguration.DefaultIPGateway. - wbemprox: Set correct variant type if array property value is NULL. - wbemprox: Implement Win32_NetworkAdapterConfiguration.DHCPEnabled. - wbemprox: Implement Win32_NetworkAdapterConfiguration.DNSServerSearchOrder. - wbemprox: Implement Win32_NetworkAdapterConfiguration.SettingID. - -Jacek Caban (2): - mshtml: Added IHTMLWindow::get_clientInformation implementation. - mshtml: Added nsIChannel::Cancel implementation. - -Jactry Zeng (10): - riched32/tests: Test EM_LINELENGTH with multibyte character. - riched20/tests: Test EM_LINELENGTH with multibyte character. - riched20/tests: Add multibyte character tests for selection. - riched32/tests: Add tests for selection. - riched20/tests: Test EM_GETTEXTRANGE with multibyte character. - riched32/tests: Test EM_GETTEXTRANGE with multibyte character. - riched20/tests: Test EM_GETSELTEXT with multibyte character. - riched32/tests: Test EM_GETSELTEXT with multibyte character. - riched20/tests: Add tests for WM_GETTEXTLENGTH. - riched32/tests: Test WM_GETTEXTLENGTH with multibyte character. - -Jeremy White (7): - kernel32/tests: Add path tests for the ./../foo case. - kernel32: Advance over the input buffer when stripping ./. - kernel32/tests: Add tests for GetLongPathName using a slash delimiter. - kernel32/tests: Add a test for GetShortPathName using a slash delimieter. - kernel32: Preserve a '/' delimiter in GetLongPathName and GetShortPathName. - kernel32/tests: Test GetLongPathNameA when the file name case differs from the input. - kernel32: Revise GetLongPathNameA to avoid overriding the input on long names. - -Joachim Priesner (1): - wbemprox: Iterate over all drives instead of just the first four. +Kira Backes (1): + user32: Add MOUSEHOOKSTRUCTEX for mouse wheel support. Lauri Kenttä (1): po: Update Finnish translation. -Michael Stefaniuc (3): - dsound: Fail to create a version 8 3d buffer with DSBCAPS_CTRLPAN. - dsound: Simplify error handling when creating a sound buffer. - dsound: Use a better name for IDirectSoundBufferImpl_Create(). - -Nikolay Sivov (32): - kernel32/tests: Some tests for ZombifyActCtx(). - user32/tests: One more activation context test for interthread SendMessage. - user.exe: Fix MapDialogRect() to actually convert passed rectangle (Coverity). - ole2nls: Fix CompareString() prototype. - ntdll: Trace RTL_BITMAP api arguments as unsigned when appropriate. - dxdiagn: Improve error handling when converting to VT_BSTR (Coverity). - regedit: Fix potential buffer leak, simplify error handling (Coverity). - winemenubuilder: Simplify MIME types list management. - gdi32: Initialize 'param' field (Coverity). - comdlg32/fontdlg: Limit text length user can type in as font point size. - comdlg32/fontdlg: Allow font sizes outside of defaults set. - comdlg32/fontdlg: Fix string format for sizes added to listbox. - comdlg32/fontdlg: Remove dead assignment (Coverity). - msvcrt: Fix char to int promotion that breaks pattern lookup. - msvcrt: Fix cwscanf* prototypes. +Matteo Bruni (16): + wined3d: Improve wined3d_popcount() implementation. + wined3d: Limit the number of WINED3D_MULTISAMPLE_NON_MASKABLE quality levels reported. + wined3d: Add ARB_internalformat_query extension. + d3d9: Return one quality level when the multisampling type isn't available. + wined3d: Add a real implementation of wined3d_check_device_multisample_type(). + wined3d: Fail texture creation when invalid multisample settings are specified. + d3d9/tests: Extend test_checkdevicemultisampletype(). + d3d9/tests: Test the creation of render targets with invalid multisample settings. + d3d8/tests: Port test_checkdevicemultisampletype() from d3d9. + d3d8/tests: Test the creation of render targets with invalid multisample settings. + d3d11: Implement d3d11_device_CheckMultisampleQualityLevels(). + d3d11: Implement d3d10_device_CheckMultisampleQualityLevels(). + d3d11/tests: Add a test for CheckMultisampleQualityLevels(). + d3d11/tests: Test the creation of textures with invalid multisample settings. + d3d10core/tests: Add a test for CheckMultisampleQualityLevels(). + d3d10core/tests: Test the creation of textures with invalid multisample settings. + +Nikolay Sivov (44): + dwrite: Cluster text position is relative to initial run. + dwrite: Fix off by one issue in line breaking rule LB21a. + dwrite: Update line breaking logic with Unicode 8.0.0 modifications. + dwrite: Don't check for line overflow for DWRITE_WORD_WRAPPING_NO_WRAP mode. + dwrite: Remove useless assignment (Coverity). + dwrite: Fix underline/strikethrough position adjustment caused by text alignment. + ctl3d32: Claim success in Ctl3dRegister(). + d2d1: Support underlined text in DrawTextLayout(). po: Update Russian translation. - msxml3: Clear request headers on Open(). - ole32: Fix parameter validation for CoGetMalloc(). - ole32: Simplify OleRegGetMiscStatus() using existing helper, use read-only key permissions. - ole32: Simplify OleRegGetUserType() using existing helper. - ole32/tests: Some tests for OleRegGetUserType(). - ole32: Ignore GetMiscStatus() returned value in OleCreate(). - ole32: Use OleRun() in OleCreate() instead of unrolling what it does. - ole32/tests: Remove some casts we don't need, fix a couple of others. - ole32/tests: Simple test for aggregation in CreateDataCache(). - dwrite/tests: One more test for duplicates in IDWriteTypography. - dwrite: Store per-range typography property. - dwrite: Optimize for the most common case of layout object initialization. - dwrite: Store last line wrapping property. - dwrite: Store optical alignment property. - dwrite: Locale layout ranged attribute is case-insensitive. - dwrite: Fix identical ranges merging. - -Paul Gofman (1): - msvcrt: Rename __libm_sse2_* functions to fix compilation when using Intel compiler. - -Piotr Caban (17): - winex11.drv: Ignore effect returned in IDropTarget::DragEnter. - winex11.drv: Call DragLeave instead of Drop if DROPEFFECT_NONE was set. - winex11.drv: Only update drop effect if IDropTarget::DragOver returned S_OK. - winex11.drv: Reset XDNDAccepted flag if IDropTarget::DragEnter fails. - winex11.drv: XDNDDropEffect stores OLE Drag&Drop effect so don't use it WS_EX_ACCEPTFILES related drops. - msvcrt: Add _strtol_l implementation. - msvcrt: Return error if last known character is further in the string then current character. - ole32: Fix apartment window class name. - msxml3: Update xmlNode reference count when nodes are merged in node_insert_before. - msxml3: Store information about ignorrable whitespace nodes in xmlNode._private variable. - msxml3: Reimplement node_get_text helper so it uses information about ignorred white space nodes. - msxml3: Add support for CDATA nodes in node_get_text. - msxml3/tests: Use exact comparison in IXMLDOMNode::get_text tests. - ntdll: Fix NtQueryDirectoryFile behavior on short file names on case insensitive file systems. - msvcp110: Always return empty string in _Read_dir on end of enumeration or error. - msvcrt: Add tmpnam_s implementation. - msvcrt: Add _wtmpnam_s implementation. - -Riccardo Bortolato (2): - ddraw: Check if surface is a mipmap sublevel or a non-positive X top level surface through caps in ddraw_surface7_GetPriority(). - ddraw7/tests: Test GetPriority() on cubemap surfaces. - -Sebastian Lackner (8): - kernel32/tests: Remove unnecessary call to GetExitCodeProcess in process tests. - ntdll: ProcessDebugFlags should return debug_children flag instead of !debugger_present. - server: Fix assignment of primary_group in token_duplicate. - tools: Remove redundant check for request size in make_requests. - advapi32: Add stubs for RegCreateKeyTransacted[A/W] functions. - ntdll/tests: Add more tests for SystemHandleInformation. - kernel32/tests: Add test for process object destruction. - pdh: Fix prototype of PdhGetLogFileType[A/W]. - -Thomas Faller (1): - ntdll: Fix valgrind heap realloc notifications. - -Thomas Petazzoni (1): - configure: Allow to override the location of the *-config scripts. - -YongHao Hu (3): - msvcp110: Add tr2_sys__Read_dir implementation. - msvcp110: Add tr2_sys__Close_dir implementation. - msvcp120/tests: Add tests of tr2_sys__Open_dir, tr2_sys__Read_dir and tr2_sys__Close_dir. + dwrite: Zero width space U+200b is not a whitespace from analyzer/layout point of view. + dwrite: Reuse linebreaking whitespace flag when filling cluster metrics. + dwrite: Reuse linebreaking isSoftHyphen flag for cluster metrics. + dwrite: Fix setting canWrapLineAfter cluster flag. + dwrite: Implement DetermineMinWidth() using line breaking info. + oleaut32/tests: Fix some test failures. + d2d1: Use drawing effect at DrawGlyphRun(). + dwrite: Fix invalid cluster metrics array index access. + dwrite: Line height/baseline includes lineGap as well. + dwrite: Fix parameter validation in CreateTextLayout()/CreateGdiCompatibleTextLayout(). + dwrite/tests: Some tests for layout based on empty text. + dwrite: Return valid metrics for layout created on empty text. + dwrite: Inline object origin is at top-left corner, not baseline. + dwrite: Don't use BOOL defined values for fields that are not BOOL. + d2d1: Use drawing effect for underlines. + dwrite: Return NULL file pointer on CreateCustomFontFileReference() failure. + dwrite: Set isNewline cluster flag. + dwrite: Update callback analysis interfaces used by layout internally. + dwrite: Use regular refcounting pattern for layout internal sink/source interfaces. + dwrite: Implement GetLocaleName() for layout analysis source. + dwrite: Implement GetTextBeforePosition() for layout analysis source. + dwrite: Remove some redundant includes. + dwrite: Fix newlineLength metric to include all newline chars at the end of the line. + dwrite: Don't use BOOL values to set bit fields. + dwrite: Improve SetScriptAnalysis()/SetBidiLevel() tracing. + dwrite: Release drawing effect after trimming sign Draw(). + dwrite/tests: Test that soft hyphen is not marked as a whitespace. + dwrite: Add a zero width line after last mandatory breakpoint. + dwrite: Invalidate layout on all cases of attribute change. + dwrite: Implement SetFlowDirection() for layout. + dwrite: Implement SetLineSpacing() for layout. + dwrite/tests: Skip tests if no English family name was returned. + dwrite: Rework Analyze() to make it easier to extend. + dwrite: Recognize Type1 .pfb files in Analyze(). + dwrite/tests: Remove failing test line, we have skips for this now. + +Paul Gofman (5): + mscoree: Make vtable and tokens local declarations arch independent. + mscoree: Implement VTable fixup for x86_64 architecture. + msvcrt: Handle of thread created by _beginthread should not be closed on thread detach. + mscoree: Add FixupVTable_Assembly function which takes preloaded assembly headers. + mscoree: Call native DllEntryPoint when it is defined in COR header. + +Pierre Schweitzer (2): + mpr: Add support for REG_EXPAND_SZ for providers path. + mpr/tests: Add tests for WNetUseConnectionA(). + +Piotr Caban (7): + oleaut32: Fix best version handling in QueryPathOfRegTypeLib when type library redirection is used. + oleaut32: Add support for best version argument in LoadRegTypeLib. + server: Avoid infinite loop when we're out of timers in set_win_timer server call. + user32: Test error returned in out of timers case. + oleaut32: Update cdguid on data reallocation in WMSFT_compile_custdata. + oleaut32: Add ICreateTypeLib2::SetCustData implementation. + oleaut32: Add ICreateTypeLib2::SetCustData tests. + +Riccardo Bortolato (3): + d3d9: Implement d3d9_device_UpdateSurface() on top of wined3d_device_copy_sub_resource_region(). + d3d9: Replace wined3d surface refcounting with texture refcounting. + wined3d: Get rid of the surface refcounting functions. + +Sebastian Lackner (2): + server: Add missing check for objattr variable in load_registry wineserver call (Coverity). + server: Avoid invalid memory access if creation of namespace fails in create_directory (Coverity). + +Snorri Sturluson (1): + ntdll: Fill in memory counters under OS X. + +Stefan Dösinger (1): + ddraw/tests: Port test_lockrect_invalid to other versions. + +Vincent Povirk (2): + kernel32/tests: Add tests for GetTimeZoneInformationForYear. + kernel32: Implement GetTimeZoneInformationForYear. -- Alexandre Julliard diff -Nru wine-staging-1.9.0~ubuntu12.04.1/AUTHORS wine-staging-1.9.3~ubuntu12.04.1/AUTHORS --- wine-staging-1.9.0~ubuntu12.04.1/AUTHORS 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/AUTHORS 2016-02-08 19:32:34.000000000 +0000 @@ -131,6 +131,7 @@ Aneurin Price Anish Mistry Anssi Hannula +Anthony Fok Antoine Chavasse Anton Baskanov Antonio Codazzi @@ -258,6 +259,7 @@ Christopher Berner Christopher Gautier Christopher Harvey +Christopher Thielen Christoph Frick Christoph von Wittich Chris Wilson @@ -755,6 +757,7 @@ Juraj Hercek Juris Smotrovs Jussi Jumppanen +Justas Lavišius Justin Bradford Justin Chevrier Justin Santa Barbara @@ -795,6 +798,7 @@ Kim Jung Eon Kim Lilliestierna Kimmo Myllyvirta +Kira Backes Kirill K. Smirnov Kirill Smelkov Kjell Rune Skaaraas @@ -1312,6 +1316,7 @@ Sin-ta Hsiea Slava Monich Slaven Rezic +Snorri Sturluson Srivatsa Kanchi, R Stas Cymbalov Stas Sergeev diff -Nru wine-staging-1.9.0~ubuntu12.04.1/configure wine-staging-1.9.3~ubuntu12.04.1/configure --- wine-staging-1.9.0~ubuntu12.04.1/configure 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/configure 2016-02-08 19:32:34.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Wine 1.9.0. +# Generated by GNU Autoconf 2.69 for Wine 1.9.3. # # Report bugs to . # @@ -580,8 +580,8 @@ # Identity of this package. PACKAGE_NAME='Wine' PACKAGE_TARNAME='wine' -PACKAGE_VERSION='1.9.0' -PACKAGE_STRING='Wine 1.9.0' +PACKAGE_VERSION='1.9.3' +PACKAGE_STRING='Wine 1.9.3' PACKAGE_BUGREPORT='wine-devel@winehq.org' PACKAGE_URL='http://www.winehq.org' @@ -714,6 +714,7 @@ DLLTOOL WINELOADER_PROGRAMS ALL_TEST_RESOURCES +SUBDIRS READELF OTOOL LDD @@ -957,6 +958,7 @@ enable_api_ms_win_security_base_l1_1_0 enable_api_ms_win_security_base_l1_2_0 enable_api_ms_win_security_lsalookup_l1_1_0 +enable_api_ms_win_security_lsalookup_l1_1_1 enable_api_ms_win_security_sddl_l1_1_0 enable_api_ms_win_service_core_l1_1_1 enable_api_ms_win_service_management_l1_1_0 @@ -1131,6 +1133,7 @@ enable_inkobj enable_inseng enable_iphlpapi +enable_irprops_cpl enable_itircl enable_itss enable_joy_cpl @@ -1173,6 +1176,7 @@ enable_msdaps enable_msdelta enable_msdmo +enable_msdrm enable_msftedit enable_msg711_acm enable_msgsm32_acm @@ -1406,6 +1410,7 @@ enable_xaudio2_6 enable_xaudio2_7 enable_xaudio2_8 +enable_xaudio2_9 enable_xinput1_1 enable_xinput1_2 enable_xinput1_3 @@ -2105,7 +2110,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Wine 1.9.0 to adapt to many kinds of systems. +\`configure' configures Wine 1.9.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -2175,7 +2180,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Wine 1.9.0:";; + short | recursive ) echo "Configuration of Wine 1.9.3:";; esac cat <<\_ACEOF @@ -2288,9 +2293,11 @@ C compiler flags for libpulse, overriding pkg-config PULSE_LIBS Linker flags for libpulse, overriding pkg-config GSTREAMER_CFLAGS - C compiler flags for gstreamer-app-0.10, overriding pkg-config + C compiler flags for gstreamer-1.0 gstreamer-video-1.0 + gstreamer-audio-1.0, overriding pkg-config GSTREAMER_LIBS - Linker flags for gstreamer-app-0.10, overriding pkg-config + Linker flags for gstreamer-1.0 gstreamer-video-1.0 + gstreamer-audio-1.0, overriding pkg-config CAPI20_CFLAGS C compiler flags for capi20, overriding pkg-config CAPI20_LIBS Linker flags for capi20, overriding pkg-config @@ -2375,7 +2382,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Wine configure 1.9.0 +Wine configure 1.9.3 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2893,7 +2900,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Wine $as_me 1.9.0, which was +It was created by Wine $as_me 1.9.3, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -6674,6 +6681,7 @@ AudioUnit/AudioComponent.h \ CL/cl.h \ Carbon/Carbon.h \ + CommonCrypto/CommonDigest.h \ CoreAudio/CoreAudio.h \ CoreServices/CoreServices.h \ DiskArbitration/DiskArbitration.h \ @@ -7391,6 +7399,8 @@ rm -f $wine_rules_file ALL_POT_FILES="" GITIGNORE="# Automatically generated by configure; DO NOT EDIT!!" +SUBDIRS="" + ALL_TEST_RESOURCES="" @@ -7420,13 +7430,7 @@ wine_fn_depend_rules () { - wine_fn_append_rule \ -"$ac_dir/Makefile: $srcdir/$ac_dir/Makefile.in Makefile \$(MAKEDEP) - \$(MAKEDEP) $ac_dir -depend: $ac_dir/depend -.PHONY: $ac_dir/depend -$ac_dir/depend: \$(MAKEDEP) dummy - \$(MAKEDEP) $ac_dir" + wine_fn_append_file SUBDIRS $ac_dir } wine_fn_pot_rules () @@ -7437,7 +7441,7 @@ then wine_fn_append_file ALL_POT_FILES $ac_dir/msg.pot wine_fn_append_rule \ -"$ac_dir/msg.pot: $ac_dir/Makefile dummy +"$ac_dir/msg.pot: dummy @cd $ac_dir && \$(MAKE) msg.pot $ac_dir/msg.pot: tools/wmc include" fi @@ -7445,7 +7449,7 @@ then wine_fn_append_file ALL_POT_FILES $ac_dir/rsrc.pot wine_fn_append_rule \ -"$ac_dir/rsrc.pot: $ac_dir/Makefile dummy +"$ac_dir/rsrc.pot: dummy @cd $ac_dir && \$(MAKE) rsrc.pot $ac_dir/rsrc.pot: tools/wrc include" fi @@ -7457,7 +7461,7 @@ wine_fn_append_rule \ "all: $ac_dir .PHONY: $ac_dir -$ac_dir: $ac_dir/Makefile dummy +$ac_dir: dummy @cd $ac_dir && \$(MAKE)" } @@ -7469,7 +7473,7 @@ ".PHONY: $ac_dir/install $ac_dir/uninstall $ac_dir/install:: $ac_dir @cd $ac_dir && \$(MAKE) install -$ac_dir/uninstall:: $ac_dir/Makefile +$ac_dir/uninstall:: @cd $ac_dir && \$(MAKE) uninstall install:: $ac_dir/install __uninstall__: $ac_dir/uninstall" @@ -7496,40 +7500,31 @@ wine_fn_clean_rules () { ac_clean=$@ - ac_extraclean="$ac_dir/Makefile" - test "$srcdir" = . && ac_extraclean="$ac_extraclean $ac_dir/.gitignore" - case $ac_dir in - */tests) ac_extraclean="$ac_extraclean $ac_dir/testlist.c" ;; - esac if wine_fn_has_flag clean then wine_fn_append_rule \ -"__clean__: $ac_dir/clean -.PHONY: $ac_dir/clean -$ac_dir/clean: $ac_dir/Makefile - @cd $ac_dir && \$(MAKE) clean - \$(RM) $ac_extraclean" +"$ac_dir/clean: dummy + @cd $ac_dir && \$(MAKE) clean" else wine_fn_append_rule \ -"__clean__: $ac_dir/clean -.PHONY: $ac_dir/clean -$ac_dir/clean: dummy - \$(RM) \$(CLEAN_FILES:%=$ac_dir/%) $ac_clean $ac_extraclean" +"$ac_dir/clean: dummy + \$(RM) \$(CLEAN_FILES:%=$ac_dir/%) $ac_clean" fi + wine_fn_append_rule \ +"__clean__: $ac_dir/clean +.PHONY: $ac_dir/clean" } wine_fn_disabled_rules () { ac_clean=$@ - ac_extraclean="$ac_dir/Makefile" - test "$srcdir" = . && ac_extraclean="$ac_extraclean $ac_dir/.gitignore" wine_fn_append_rule \ "__clean__: $ac_dir/clean .PHONY: $ac_dir/clean $ac_dir/clean: dummy - \$(RM) \$(CLEAN_FILES:%=$ac_dir/%) $ac_clean $ac_extraclean" + \$(RM) \$(CLEAN_FILES:%=$ac_dir/%) $ac_clean" } wine_fn_config_makefile () @@ -7617,7 +7612,7 @@ wine_fn_clean_rules $ac_clean wine_fn_append_rule \ "$ac_dir: __builddeps__ -manpages htmlpages sgmlpages xmlpages:: $ac_dir/Makefile +manpages htmlpages sgmlpages xmlpages:: @cd $ac_dir && \$(MAKE) \$@ .PHONY: $ac_dir/install-lib $ac_dir/uninstall install install-lib:: $ac_dir/install-lib @@ -7646,9 +7641,9 @@ wine_fn_append_rule \ "__builddeps__: $ac_file.$IMPLIBEXT $ac_file.$STATIC_IMPLIBEXT $ac_file.$IMPLIBEXT $ac_file.$STATIC_IMPLIBEXT $ac_file.cross.a: $ac_deps -$ac_file.def: $srcdir/$ac_dir/$ac_name.spec $ac_dir/Makefile \$(WINEBUILD) +$ac_file.def: $srcdir/$ac_dir/$ac_name.spec \$(WINEBUILD) \$(WINEBUILD) \$(TARGETFLAGS)$ac_implibflags -w --def -o \$@ --export $srcdir/$ac_dir/$ac_name.spec -$ac_file.$STATIC_IMPLIBEXT: $ac_dir/Makefile dummy +$ac_file.$STATIC_IMPLIBEXT: dummy @cd $ac_dir && \$(MAKE) lib$ac_implib.$STATIC_IMPLIBEXT .PHONY: $ac_dir/install-dev $ac_dir/uninstall $ac_dir/install-dev:: $ac_file.$IMPLIBEXT @@ -7671,7 +7666,7 @@ then wine_fn_append_rule \ "__builddeps__: $ac_file.cross.a -$ac_file.cross.a: $ac_dir/Makefile dummy +$ac_file.cross.a: dummy @cd $ac_dir && \$(MAKE) lib$ac_implib.cross.a" fi @@ -7679,9 +7674,9 @@ then wine_fn_append_rule \ "__builddeps__: $ac_file.$IMPLIBEXT -$ac_file.def: $srcdir/$ac_dir/$ac_name.spec $ac_dir/Makefile \$(WINEBUILD) +$ac_file.def: $srcdir/$ac_dir/$ac_name.spec \$(WINEBUILD) \$(WINEBUILD) \$(TARGETFLAGS)$ac_implibflags -w --def -o \$@ --export $srcdir/$ac_dir/$ac_name.spec -$ac_file.a: $srcdir/$ac_dir/$ac_name.spec $ac_dir/Makefile \$(WINEBUILD) +$ac_file.a: $srcdir/$ac_dir/$ac_name.spec \$(WINEBUILD) \$(WINEBUILD) \$(TARGETFLAGS)$ac_implibflags -w --implib -o \$@ --export $srcdir/$ac_dir/$ac_name.spec .PHONY: $ac_dir/install-dev $ac_dir/uninstall $ac_dir/install-dev:: $ac_file.$IMPLIBEXT @@ -7694,7 +7689,7 @@ then wine_fn_append_rule \ "__builddeps__: $ac_file.cross.a -$ac_file.cross.a: $srcdir/$ac_dir/$ac_name.spec $ac_dir/Makefile \$(WINEBUILD) +$ac_file.cross.a: $srcdir/$ac_dir/$ac_name.spec \$(WINEBUILD) \$(WINEBUILD) \$(CROSSTARGET:%=-b %)$ac_implibflags -w --implib -o \$@ --export $srcdir/$ac_dir/$ac_name.spec" fi @@ -7809,7 +7804,7 @@ wine_fn_clean_rules $ac_clean wine_fn_append_rule \ -"$ac_dir: programs/winetest/Makefile __builddeps__ +"$ac_dir: __builddeps__ programs/winetest: $ac_dir check test: $ac_dir/test .PHONY: $ac_dir/test @@ -7823,7 +7818,7 @@ wine_fn_append_rule \ "crosstest: $ac_dir/crosstest .PHONY: $ac_dir/crosstest -$ac_dir/crosstest: $ac_dir/Makefile __builddeps__ dummy +$ac_dir/crosstest: __builddeps__ dummy @cd $ac_dir && \$(MAKE) crosstest" fi } @@ -7863,7 +7858,7 @@ \$(RM) $ac_links" for f in $ac_links; do wine_fn_ignore_file $f; done test -n "$ac_linkdir" || return - wine_fn_append_rule "$ac_linkdir/Makefile $ac_linkdir/depend: $ac_links" + wine_fn_append_rule "$ac_linkdir/depend: $ac_links" } wine_binary="wine" @@ -8760,14 +8755,18 @@ CROSSTARGET="" -if test "$cross_compiling" = "no" -a "x$enable_tests" != xno -a "$LIBEXT" != "dll" +if test "x$enable_tests" != xno -a "$LIBEXT" != "dll" then case "$host_cpu" in + arm*) + ac_prefix_list="armv7-w64-mingw32-clang armv7-w64-mingw32-gcc" ;; i[3456789]86*) ac_prefix_list="i686-w64-mingw32-gcc i586-w64-mingw32-gcc i486-w64-mingw32-gcc i386-w64-mingw32-gcc i686-pc-mingw32-gcc i586-pc-mingw32-gcc i486-pc-mingw32-gcc i386-pc-mingw32-gcc i686-mingw32msvc-gcc i586-mingw32msvc-gcc i486-mingw32msvc-gcc i386-mingw32msvc-gcc i686-mingw32-gcc i586-mingw32-gcc i486-mingw32-gcc i386-mingw32-gcc - mingw32-gcc" ;; + i686-w64-mingw32-clang i586-w64-mingw32-clang i486-w64-mingw32-clang i386-w64-mingw32-clang + mingw32-gcc" ;; x86_64) - ac_prefix_list="x86_64-pc-mingw32-gcc amd64-pc-mingw32-gcc x86_64-w64-mingw32-gcc amd64-w64-mingw32-gcc x86_64-mingw32msvc-gcc amd64-mingw32msvc-gcc " ;; + ac_prefix_list="x86_64-pc-mingw32-gcc amd64-pc-mingw32-gcc x86_64-w64-mingw32-gcc amd64-w64-mingw32-gcc x86_64-mingw32msvc-gcc amd64-mingw32msvc-gcc + x86_64-w64-mingw32-clang amd64-w64-mingw32-clang " ;; *) ac_prefix_list="" ;; esac @@ -8840,6 +8839,7 @@ do case "$1" in *-gcc) CROSSTARGET=`expr "$1" : '\(.*\)-gcc'` ;; + *-clang) CROSSTARGET=`expr "$1" : '\(.*\)-clang'` ;; esac shift done @@ -11587,6 +11587,22 @@ fi + ac_wine_check_funcs_save_LIBS="$LIBS" +LIBS="$LIBS $GNUTLS_LIBS" +for ac_func in gnutls_hash +do : + ac_fn_c_check_func "$LINENO" "gnutls_hash" "ac_cv_func_gnutls_hash" +if test "x$ac_cv_func_gnutls_hash" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GNUTLS_HASH 1 +_ACEOF + +else + as_fn_append wine_notices "|libgnutls ${notice_platform}development files too old, no bcrypt hash support." +fi +done + +LIBS="$ac_wine_check_funcs_save_LIBS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else @@ -12596,19 +12612,19 @@ then if ${GSTREAMER_CFLAGS:+false} :; then : if ${PKG_CONFIG+:} false; then : - GSTREAMER_CFLAGS=`$PKG_CONFIG --cflags gstreamer-app-0.10 2>/dev/null` + GSTREAMER_CFLAGS=`$PKG_CONFIG --cflags gstreamer-1.0 gstreamer-video-1.0 gstreamer-audio-1.0 2>/dev/null` fi fi if ${GSTREAMER_LIBS:+false} :; then : if ${PKG_CONFIG+:} false; then : - GSTREAMER_LIBS=`$PKG_CONFIG --libs gstreamer-app-0.10 2>/dev/null` + GSTREAMER_LIBS=`$PKG_CONFIG --libs gstreamer-1.0 gstreamer-video-1.0 gstreamer-audio-1.0 2>/dev/null` fi fi -$as_echo "$as_me:${as_lineno-$LINENO}: gstreamer-app-0.10 cflags: $GSTREAMER_CFLAGS" >&5 -$as_echo "$as_me:${as_lineno-$LINENO}: gstreamer-app-0.10 libs: $GSTREAMER_LIBS" >&5 +$as_echo "$as_me:${as_lineno-$LINENO}: gstreamer-1.0 gstreamer-video-1.0 gstreamer-audio-1.0 cflags: $GSTREAMER_CFLAGS" >&5 +$as_echo "$as_me:${as_lineno-$LINENO}: gstreamer-1.0 gstreamer-video-1.0 gstreamer-audio-1.0 libs: $GSTREAMER_LIBS" >&5 ac_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS $GSTREAMER_CFLAGS" ac_gst_incl="" @@ -12620,15 +12636,13 @@ done GSTREAMER_CFLAGS=$ac_gst_incl CPPFLAGS="$ac_save_CPPFLAGS $GSTREAMER_CFLAGS" - ac_fn_c_check_header_mongrel "$LINENO" "gst/gstpad.h" "ac_cv_header_gst_gstpad_h" "$ac_includes_default" -if test "x$ac_cv_header_gst_gstpad_h" = xyes; then : - ac_fn_c_check_header_mongrel "$LINENO" "gst/app/gstappsink.h" "ac_cv_header_gst_app_gstappsink_h" "$ac_includes_default" -if test "x$ac_cv_header_gst_app_gstappsink_h" = xyes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gint64 defined by gst/app/gstappsink.h is indeed 64-bit" >&5 -$as_echo_n "checking whether gint64 defined by gst/app/gstappsink.h is indeed 64-bit... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ac_fn_c_check_header_mongrel "$LINENO" "gst/gst.h" "ac_cv_header_gst_gst_h" "$ac_includes_default" +if test "x$ac_cv_header_gst_gst_h" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gint64 defined by gst/gst.h is indeed 64-bit" >&5 +$as_echo_n "checking whether gint64 defined by gst/gst.h is indeed 64-bit... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +#include int main () { @@ -12640,50 +12654,13 @@ if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gst_pad_get_caps_reffed in -lgstreamer-0.10" >&5 -$as_echo_n "checking for gst_pad_get_caps_reffed in -lgstreamer-0.10... " >&6; } -if ${ac_cv_lib_gstreamer_0_10_gst_pad_get_caps_reffed+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lgstreamer-0.10 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gst_pad_get_caps_reffed (); -int -main () -{ -return gst_pad_get_caps_reffed (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_gstreamer_0_10_gst_pad_get_caps_reffed=yes -else - ac_cv_lib_gstreamer_0_10_gst_pad_get_caps_reffed=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gstreamer_0_10_gst_pad_get_caps_reffed" >&5 -$as_echo "$ac_cv_lib_gstreamer_0_10_gst_pad_get_caps_reffed" >&6; } -if test "x$ac_cv_lib_gstreamer_0_10_gst_pad_get_caps_reffed" = xyes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gst_app_buffer_new in -lgstapp-0.10" >&5 -$as_echo_n "checking for gst_app_buffer_new in -lgstapp-0.10... " >&6; } -if ${ac_cv_lib_gstapp_0_10_gst_app_buffer_new+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gst_pad_new in -lgstreamer-1.0" >&5 +$as_echo_n "checking for gst_pad_new in -lgstreamer-1.0... " >&6; } +if ${ac_cv_lib_gstreamer_1_0_gst_pad_new+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lgstapp-0.10 $GSTREAMER_LIBS $LIBS" +LIBS="-lgstreamer-1.0 $GSTREAMER_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -12693,32 +12670,30 @@ #ifdef __cplusplus extern "C" #endif -char gst_app_buffer_new (); +char gst_pad_new (); int main () { -return gst_app_buffer_new (); +return gst_pad_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_gstapp_0_10_gst_app_buffer_new=yes + ac_cv_lib_gstreamer_1_0_gst_pad_new=yes else - ac_cv_lib_gstapp_0_10_gst_app_buffer_new=no + ac_cv_lib_gstreamer_1_0_gst_pad_new=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gstapp_0_10_gst_app_buffer_new" >&5 -$as_echo "$ac_cv_lib_gstapp_0_10_gst_app_buffer_new" >&6; } -if test "x$ac_cv_lib_gstapp_0_10_gst_app_buffer_new" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gstreamer_1_0_gst_pad_new" >&5 +$as_echo "$ac_cv_lib_gstreamer_1_0_gst_pad_new" >&6; } +if test "x$ac_cv_lib_gstreamer_1_0_gst_pad_new" = xyes; then : : fi -fi - else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } @@ -12727,25 +12702,20 @@ fi -else - GSTREAMER_CFLAGS="" -fi - - CPPFLAGS=$ac_save_CPPFLAGS test -z "$GSTREAMER_CFLAGS" || GSTREAMER_CFLAGS=`echo " $GSTREAMER_CFLAGS" | sed 's/ -I\([^/]\)/ -I\$(top_builddir)\/\1/g'` test -z "$GSTREAMER_LIBS" || GSTREAMER_LIBS=`echo " $GSTREAMER_LIBS" | sed 's/ -L\([^/]\)/ -L\$(top_builddir)\/\1/g'` fi -if test "x$ac_cv_lib_gstapp_0_10_gst_app_buffer_new" != xyes -a "x$ac_cv_header_QuickTime_ImageCompression_h" != xyes; then : +if test "x$ac_cv_lib_gstreamer_1_0_gst_pad_new" != xyes -a "x$ac_cv_header_QuickTime_ImageCompression_h" != xyes; then : case "x$with_gstreamer" in - x) as_fn_append wine_notices "|gstreamer-0.10 base plugins ${notice_platform}development files not found, gstreamer support disabled" ;; + x) as_fn_append wine_notices "|gstreamer-1.0 base plugins ${notice_platform}development files not found, gstreamer support disabled" ;; xno) ;; - *) as_fn_error $? "gstreamer-0.10 base plugins ${notice_platform}development files not found, gstreamer support disabled + *) as_fn_error $? "gstreamer-1.0 base plugins ${notice_platform}development files not found, gstreamer support disabled This is an error since --with-gstreamer was requested." "$LINENO" 5 ;; esac fi -test "x$ac_cv_lib_gstapp_0_10_gst_app_buffer_new" = xyes || enable_winegstreamer=${enable_winegstreamer:-no} +test "x$ac_cv_lib_gstreamer_1_0_gst_pad_new" = xyes || enable_winegstreamer=${enable_winegstreamer:-no} ALSA_LIBS="" @@ -13724,7 +13694,29 @@ if test "x$ac_cv_have_openalsoft" != xyes then as_fn_append wine_notices "|openal-soft ${notice_platform}development files not found (or too old), XAudio2 won't be supported" + enable_x3daudio1_0=${enable_x3daudio1_0:-no} + enable_x3daudio1_1=${enable_x3daudio1_1:-no} + enable_x3daudio1_2=${enable_x3daudio1_2:-no} + enable_x3daudio1_3=${enable_x3daudio1_3:-no} + enable_x3daudio1_4=${enable_x3daudio1_4:-no} + enable_x3daudio1_5=${enable_x3daudio1_5:-no} + enable_x3daudio1_6=${enable_x3daudio1_6:-no} + enable_x3daudio1_7=${enable_x3daudio1_7:-no} + enable_xapofx1_1=${enable_xapofx1_1:-no} + enable_xapofx1_2=${enable_xapofx1_2:-no} + enable_xapofx1_3=${enable_xapofx1_3:-no} + enable_xapofx1_4=${enable_xapofx1_4:-no} + enable_xapofx1_5=${enable_xapofx1_5:-no} + enable_xaudio2_0=${enable_xaudio2_0:-no} + enable_xaudio2_1=${enable_xaudio2_1:-no} + enable_xaudio2_2=${enable_xaudio2_2:-no} + enable_xaudio2_3=${enable_xaudio2_3:-no} + enable_xaudio2_4=${enable_xaudio2_4:-no} + enable_xaudio2_5=${enable_xaudio2_5:-no} + enable_xaudio2_6=${enable_xaudio2_6:-no} enable_xaudio2_7=${enable_xaudio2_7:-no} + enable_xaudio2_8=${enable_xaudio2_8:-no} + enable_xaudio2_9=${enable_xaudio2_9:-no} fi if test "$ac_cv_header_kstat_h" = "yes" @@ -16891,6 +16883,39 @@ fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_popcount" >&5 +$as_echo_n "checking for __builtin_popcount... " >&6; } +if ${ac_cv_have___builtin_popcount+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return __builtin_popcount(1) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_have___builtin_popcount="yes" +else + ac_cv_have___builtin_popcount="no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have___builtin_popcount" >&5 +$as_echo "$ac_cv_have___builtin_popcount" >&6; } +if test "$ac_cv_have___builtin_popcount" = "yes" +then + +$as_echo "#define HAVE___BUILTIN_POPCOUNT 1" >>confdefs.h + +fi + case $host_cpu in *i[3456789]86*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need to define __i386__" >&5 @@ -17223,7 +17248,9 @@ .MAKEFILEDEPS: all: Makefile Makefile: $srcdir/Makefile.in config.status \$(MAKEDEP) - @./config.status Make.tmp Makefile" + @./config.status Make.tmp Makefile +depend: \$(MAKEDEP) dummy + \$(MAKEDEP)" test "$srcdir" = . && wine_fn_append_rule "all: .gitignore .gitignore: config.status @@ -17352,6 +17379,7 @@ wine_fn_config_dll api-ms-win-security-base-l1-1-0 enable_api_ms_win_security_base_l1_1_0 wine_fn_config_dll api-ms-win-security-base-l1-2-0 enable_api_ms_win_security_base_l1_2_0 wine_fn_config_dll api-ms-win-security-lsalookup-l1-1-0 enable_api_ms_win_security_lsalookup_l1_1_0 +wine_fn_config_dll api-ms-win-security-lsalookup-l1-1-1 enable_api_ms_win_security_lsalookup_l1_1_1 wine_fn_config_dll api-ms-win-security-sddl-l1-1-0 enable_api_ms_win_security_sddl_l1_1_0 wine_fn_config_dll api-ms-win-service-core-l1-1-1 enable_api_ms_win_service_core_l1_1_1 wine_fn_config_dll api-ms-win-service-management-l1-1-0 enable_api_ms_win_service_management_l1_1_0 @@ -17373,7 +17401,7 @@ wine_fn_config_test dlls/avifil32/tests avifil32_test wine_fn_config_dll avifile.dll16 enable_win16 wine_fn_config_dll avrt enable_avrt implib -wine_fn_config_dll bcrypt enable_bcrypt +wine_fn_config_dll bcrypt enable_bcrypt implib wine_fn_config_test dlls/bcrypt/tests bcrypt_test wine_fn_config_dll bluetoothapis enable_bluetoothapis wine_fn_config_dll browseui enable_browseui clean,po @@ -17606,6 +17634,7 @@ wine_fn_config_dll inseng enable_inseng clean wine_fn_config_dll iphlpapi enable_iphlpapi implib wine_fn_config_test dlls/iphlpapi/tests iphlpapi_test +wine_fn_config_dll irprops.cpl enable_irprops_cpl wine_fn_config_dll itircl enable_itircl wine_fn_config_dll itss enable_itss clean wine_fn_config_test dlls/itss/tests itss_test @@ -17672,6 +17701,7 @@ wine_fn_config_dll msdelta enable_msdelta wine_fn_config_dll msdmo enable_msdmo implib wine_fn_config_test dlls/msdmo/tests msdmo_test +wine_fn_config_dll msdrm enable_msdrm wine_fn_config_dll msftedit enable_msftedit wine_fn_config_dll msg711.acm enable_msg711_acm wine_fn_config_dll msgsm32.acm enable_msgsm32_acm @@ -17784,7 +17814,7 @@ wine_fn_config_test dlls/oledb32/tests oledb32_test clean wine_fn_config_dll oledlg enable_oledlg implib,po wine_fn_config_test dlls/oledlg/tests oledlg_test -wine_fn_config_dll olepro32 enable_olepro32 implib +wine_fn_config_dll olepro32 enable_olepro32 clean,implib wine_fn_config_dll olesvr.dll16 enable_win16 wine_fn_config_dll olesvr32 enable_olesvr32 implib wine_fn_config_dll olethk32 enable_olethk32 @@ -18036,7 +18066,8 @@ wine_fn_config_dll xaudio2_6 enable_xaudio2_6 clean wine_fn_config_dll xaudio2_7 enable_xaudio2_7 clean wine_fn_config_test dlls/xaudio2_7/tests xaudio2_7_test -wine_fn_config_dll xaudio2_8 enable_xaudio2_8 implib +wine_fn_config_dll xaudio2_8 enable_xaudio2_8 clean +wine_fn_config_dll xaudio2_9 enable_xaudio2_9 clean wine_fn_config_dll xinput1_1 enable_xinput1_1 wine_fn_config_dll xinput1_2 enable_xinput1_2 wine_fn_config_dll xinput1_3 enable_xinput1_3 implib xinput @@ -18824,7 +18855,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Wine $as_me 1.9.0, which was +This file was extended by Wine $as_me 1.9.3, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -18895,7 +18926,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Wine config.status 1.9.0 +Wine config.status 1.9.3 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -19018,7 +19049,7 @@ } wine_fn_output_makefile () { - cat Make.tmp - <<\_WINE_EOF >\$tmp/makefile && mv -f \$tmp/makefile \$1 && rm -f Make.tmp && "$wine_makedep" . && return + cat Make.tmp - <<\_WINE_EOF >\$tmp/makefile && mv -f \$tmp/makefile \$1 && rm -f Make.tmp && "$wine_makedep" && return `cat $wine_rules_file` _WINE_EOF as_fn_error $? "could not create Makefile" "$LINENO" 5 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/configure.ac wine-staging-1.9.3~ubuntu12.04.1/configure.ac --- wine-staging-1.9.0~ubuntu12.04.1/configure.ac 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/configure.ac 2016-02-08 19:32:34.000000000 +0000 @@ -393,6 +393,7 @@ AudioUnit/AudioComponent.h \ CL/cl.h \ Carbon/Carbon.h \ + CommonCrypto/CommonDigest.h \ CoreAudio/CoreAudio.h \ CoreServices/CoreServices.h \ DiskArbitration/DiskArbitration.h \ @@ -942,9 +943,9 @@ dnl Check for cross compiler to build test programs AC_SUBST(CROSSTARGET,"") -if test "$cross_compiling" = "no" -a "x$enable_tests" != xno -a "$LIBEXT" != "dll" +if test "x$enable_tests" != xno -a "$LIBEXT" != "dll" then - WINE_CHECK_MINGW_PROG(CROSSCC,gcc,false) + WINE_CHECK_MINGW_PROG(CROSSCC,false) if test "$CROSSCC" != "false" then ac_save_CC="$CC" @@ -958,6 +959,7 @@ do case "$1" in *-gcc) CROSSTARGET=`expr "$1" : '\(.*\)-gcc'` ;; + *-clang) CROSSTARGET=`expr "$1" : '\(.*\)-clang'` ;; esac shift done], @@ -1266,7 +1268,9 @@ [AC_CHECK_HEADER(gnutls/gnutls.h, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[static typeof(gnutls_mac_get_key_size) *func; if (func) return 0;]])], - [WINE_CHECK_SONAME(gnutls,gnutls_global_init,,[GNUTLS_CFLAGS=""],[$GNUTLS_LIBS],[[libgnutls\\(-deb0\\)\\{0,1\\}]])])], + [WINE_CHECK_SONAME(gnutls,gnutls_global_init,,[GNUTLS_CFLAGS=""],[$GNUTLS_LIBS],[[libgnutls\\(-deb0\\)\\{0,1\\}]]) + WINE_CHECK_LIB_FUNCS(gnutls_hash,[$GNUTLS_LIBS],, + [WINE_NOTICE([libgnutls ${notice_platform}development files too old, no bcrypt hash support.])])])], [GNUTLS_CFLAGS=""])]) fi WINE_WARNING_WITH(gnutls,[test "x$ac_cv_lib_soname_gnutls" = "x"], @@ -1458,7 +1462,7 @@ dnl **** Check for gstreamer **** if test "x$with_gstreamer" != "xno" then - WINE_PACKAGE_FLAGS(GSTREAMER,[gstreamer-app-0.10],,,, + WINE_PACKAGE_FLAGS(GSTREAMER,[gstreamer-1.0 gstreamer-video-1.0 gstreamer-audio-1.0],,,, [ac_gst_incl="" for i in $GSTREAMER_CFLAGS do @@ -1468,20 +1472,17 @@ done GSTREAMER_CFLAGS=$ac_gst_incl CPPFLAGS="$ac_save_CPPFLAGS $GSTREAMER_CFLAGS" - AC_CHECK_HEADER([gst/gstpad.h], - [AC_CHECK_HEADER([gst/app/gstappsink.h], - [AC_MSG_CHECKING([whether gint64 defined by gst/app/gstappsink.h is indeed 64-bit]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[static int a[sizeof(gint64) > 4 ? 1 : -1]; if (a[0]) return 0;]])], - [AC_MSG_RESULT([yes]) - AC_CHECK_LIB(gstreamer-0.10,gst_pad_get_caps_reffed, - [AC_CHECK_LIB(gstapp-0.10,gst_app_buffer_new,[:],,[$GSTREAMER_LIBS])])], - [AC_MSG_RESULT([no])])])], - [GSTREAMER_CFLAGS=""])]) -fi -WINE_NOTICE_WITH(gstreamer,[test "x$ac_cv_lib_gstapp_0_10_gst_app_buffer_new" != xyes -a "x$ac_cv_header_QuickTime_ImageCompression_h" != xyes], - [gstreamer-0.10 base plugins ${notice_platform}development files not found, gstreamer support disabled]) -test "x$ac_cv_lib_gstapp_0_10_gst_app_buffer_new" = xyes || enable_winegstreamer=${enable_winegstreamer:-no} + AC_CHECK_HEADER([gst/gst.h], + [AC_MSG_CHECKING([whether gint64 defined by gst/gst.h is indeed 64-bit]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[static int a[sizeof(gint64) > 4 ? 1 : -1]; if (a[0]) return 0;]])], + [AC_MSG_RESULT([yes]) + AC_CHECK_LIB(gstreamer-1.0,gst_pad_new,[:],,[$GSTREAMER_LIBS])], + [AC_MSG_RESULT([no])])])]) +fi +WINE_NOTICE_WITH(gstreamer,[test "x$ac_cv_lib_gstreamer_1_0_gst_pad_new" != xyes -a "x$ac_cv_header_QuickTime_ImageCompression_h" != xyes], + [gstreamer-1.0 base plugins ${notice_platform}development files not found, gstreamer support disabled]) +test "x$ac_cv_lib_gstreamer_1_0_gst_pad_new" = xyes || enable_winegstreamer=${enable_winegstreamer:-no} dnl **** Check for ALSA 1.x **** AC_SUBST(ALSA_LIBS,"") @@ -1660,7 +1661,29 @@ if test "x$ac_cv_have_openalsoft" != xyes then WINE_NOTICE([openal-soft ${notice_platform}development files not found (or too old), XAudio2 won't be supported]) + enable_x3daudio1_0=${enable_x3daudio1_0:-no} + enable_x3daudio1_1=${enable_x3daudio1_1:-no} + enable_x3daudio1_2=${enable_x3daudio1_2:-no} + enable_x3daudio1_3=${enable_x3daudio1_3:-no} + enable_x3daudio1_4=${enable_x3daudio1_4:-no} + enable_x3daudio1_5=${enable_x3daudio1_5:-no} + enable_x3daudio1_6=${enable_x3daudio1_6:-no} + enable_x3daudio1_7=${enable_x3daudio1_7:-no} + enable_xapofx1_1=${enable_xapofx1_1:-no} + enable_xapofx1_2=${enable_xapofx1_2:-no} + enable_xapofx1_3=${enable_xapofx1_3:-no} + enable_xapofx1_4=${enable_xapofx1_4:-no} + enable_xapofx1_5=${enable_xapofx1_5:-no} + enable_xaudio2_0=${enable_xaudio2_0:-no} + enable_xaudio2_1=${enable_xaudio2_1:-no} + enable_xaudio2_2=${enable_xaudio2_2:-no} + enable_xaudio2_3=${enable_xaudio2_3:-no} + enable_xaudio2_4=${enable_xaudio2_4:-no} + enable_xaudio2_5=${enable_xaudio2_5:-no} + enable_xaudio2_6=${enable_xaudio2_6:-no} enable_xaudio2_7=${enable_xaudio2_7:-no} + enable_xaudio2_8=${enable_xaudio2_8:-no} + enable_xaudio2_9=${enable_xaudio2_9:-no} fi dnl **** Check for libkstat **** @@ -2528,6 +2551,15 @@ AC_DEFINE(HAVE___BUILTIN_CLZ, 1, [Define to 1 if you have the `__builtin_clz' built-in function.]) fi +dnl Check for __builtin_popcount +AC_CACHE_CHECK([for __builtin_popcount], ac_cv_have___builtin_popcount, + AC_LINK_IFELSE([AC_LANG_PROGRAM(,[[return __builtin_popcount(1)]])], + [ac_cv_have___builtin_popcount="yes"], [ac_cv_have___builtin_popcount="no"])) +if test "$ac_cv_have___builtin_popcount" = "yes" +then + AC_DEFINE(HAVE___BUILTIN_POPCOUNT, 1, [Define to 1 if you have the `__builtin_popcount' built-in function.]) +fi + dnl *** check for the need to define platform-specific symbols case $host_cpu in @@ -2571,7 +2603,9 @@ .MAKEFILEDEPS: all: Makefile Makefile: $srcdir/Makefile.in config.status \$(MAKEDEP) - @./config.status Make.tmp Makefile]) + @./config.status Make.tmp Makefile +depend: \$(MAKEDEP) dummy + \$(MAKEDEP)]) test "$srcdir" = . && WINE_APPEND_RULE( [all: .gitignore @@ -2689,6 +2723,7 @@ WINE_CONFIG_DLL(api-ms-win-security-base-l1-1-0) WINE_CONFIG_DLL(api-ms-win-security-base-l1-2-0) WINE_CONFIG_DLL(api-ms-win-security-lsalookup-l1-1-0) +WINE_CONFIG_DLL(api-ms-win-security-lsalookup-l1-1-1) WINE_CONFIG_DLL(api-ms-win-security-sddl-l1-1-0) WINE_CONFIG_DLL(api-ms-win-service-core-l1-1-1) WINE_CONFIG_DLL(api-ms-win-service-management-l1-1-0) @@ -2710,7 +2745,7 @@ WINE_CONFIG_TEST(dlls/avifil32/tests) WINE_CONFIG_DLL(avifile.dll16,enable_win16) WINE_CONFIG_DLL(avrt,,[implib]) -WINE_CONFIG_DLL(bcrypt) +WINE_CONFIG_DLL(bcrypt,,[implib]) WINE_CONFIG_TEST(dlls/bcrypt/tests) WINE_CONFIG_DLL(bluetoothapis) WINE_CONFIG_DLL(browseui,,[clean,po]) @@ -2943,6 +2978,7 @@ WINE_CONFIG_DLL(inseng,,[clean]) WINE_CONFIG_DLL(iphlpapi,,[implib]) WINE_CONFIG_TEST(dlls/iphlpapi/tests) +WINE_CONFIG_DLL(irprops.cpl) WINE_CONFIG_DLL(itircl) WINE_CONFIG_DLL(itss,,[clean]) WINE_CONFIG_TEST(dlls/itss/tests) @@ -3009,6 +3045,7 @@ WINE_CONFIG_DLL(msdelta) WINE_CONFIG_DLL(msdmo,,[implib]) WINE_CONFIG_TEST(dlls/msdmo/tests) +WINE_CONFIG_DLL(msdrm) WINE_CONFIG_DLL(msftedit) WINE_CONFIG_DLL(msg711.acm) WINE_CONFIG_DLL(msgsm32.acm) @@ -3121,7 +3158,7 @@ WINE_CONFIG_TEST(dlls/oledb32/tests,[clean]) WINE_CONFIG_DLL(oledlg,,[implib,po]) WINE_CONFIG_TEST(dlls/oledlg/tests) -WINE_CONFIG_DLL(olepro32,,[implib]) +WINE_CONFIG_DLL(olepro32,,[clean,implib]) WINE_CONFIG_DLL(olesvr.dll16,enable_win16) WINE_CONFIG_DLL(olesvr32,,[implib]) WINE_CONFIG_DLL(olethk32) @@ -3373,7 +3410,8 @@ WINE_CONFIG_DLL(xaudio2_6,,[clean]) WINE_CONFIG_DLL(xaudio2_7,,[clean]) WINE_CONFIG_TEST(dlls/xaudio2_7/tests) -WINE_CONFIG_DLL(xaudio2_8,,[implib]) +WINE_CONFIG_DLL(xaudio2_8,,[clean]) +WINE_CONFIG_DLL(xaudio2_9,,[clean]) WINE_CONFIG_DLL(xinput1_1) WINE_CONFIG_DLL(xinput1_2) WINE_CONFIG_DLL(xinput1_3,,[implib],[xinput]) @@ -3572,7 +3610,7 @@ AC_CONFIG_COMMANDS([Makefile], [wine_fn_output_makefile Makefile], [wine_fn_output_makefile () { - cat Make.tmp - <<\_WINE_EOF >\$tmp/makefile && mv -f \$tmp/makefile \$[]1 && rm -f Make.tmp && "$wine_makedep" . && return + cat Make.tmp - <<\_WINE_EOF >\$tmp/makefile && mv -f \$tmp/makefile \$[]1 && rm -f Make.tmp && "$wine_makedep" && return `cat $wine_rules_file` _WINE_EOF AS_ERROR([could not create Makefile]) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/debian/bzr-builder.manifest wine-staging-1.9.3~ubuntu12.04.1/debian/bzr-builder.manifest --- wine-staging-1.9.0~ubuntu12.04.1/debian/bzr-builder.manifest 2015-12-28 20:10:54.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/debian/bzr-builder.manifest 2016-02-08 22:05:48.000000000 +0000 @@ -1,4 +1,4 @@ -# bzr-builder format 0.4 deb-version 1.9.0 -lp:wine revid:git-v1:93d7356290bfe5bfd2104f98592790841e33420e -merge wine-staging-files lp:wine-compholio revid:git-v1:f3609f54527d74dc0aef56c3fedb833c90e1fdb1 -merge wine-build-staging lp:~wine/wine/build-staging revid:sebastian@fds-team.de-20151228185317-117g1lgc88zfpfmd +# bzr-builder format 0.4 deb-version 1.9.3 +lp:wine revid:git-v1:c266d373deb417abef4883f59daa5d517b77e76c +merge wine-staging-files lp:wine-compholio revid:git-v1:089f367941129142040984054a8776b354380536 +merge wine-build-staging lp:~wine/wine/build-staging revid:sebastian@fds-team.de-20160208192346-iz9n1kt5gz89pg0b diff -Nru wine-staging-1.9.0~ubuntu12.04.1/debian/changelog wine-staging-1.9.3~ubuntu12.04.1/debian/changelog --- wine-staging-1.9.0~ubuntu12.04.1/debian/changelog 2015-12-28 20:10:54.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/debian/changelog 2016-02-08 22:05:48.000000000 +0000 @@ -1,9 +1,9 @@ -wine-staging (1.9.0~ubuntu12.04.1) precise; urgency=low +wine-staging (1.9.3~ubuntu12.04.1) precise; urgency=low * Auto build. - -- Sebastian Lackner Mon, 28 Dec 2015 20:10:54 +0000 + -- Sebastian Lackner Mon, 08 Feb 2016 22:05:48 +0000 -wine-staging (1.9.0) unstable; urgency=low +wine-staging (1.9.3) unstable; urgency=low * Auto build. - -- Michael Müller Mon, 28 Dec 2015 18:52:26 -0000 + -- Michael Müller Mon, 08 Feb 2016 19:19:00 -0000 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/debian/control wine-staging-1.9.3~ubuntu12.04.1/debian/control --- wine-staging-1.9.0~ubuntu12.04.1/debian/control 2015-12-28 19:46:24.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/debian/control 2016-02-08 21:24:09.000000000 +0000 @@ -30,6 +30,8 @@ libgnutls-dev, libgphoto2-dev | libgphoto2-6-dev | libgphoto2-2-dev (>= 2.4.6), libgsm1-dev, + libgstreamer1.0-dev | libtiff4, + libgstreamer-plugins-base1.0-dev | libtiff4, libgtk-3-dev, libice-dev, libjpeg-dev, @@ -110,21 +112,14 @@ libgsm1 Section: otherosfs Priority: optional -Description: special build of the popular Wine software - The Staging Edition is a special build of the popular Wine software - with patches representing my current staging tree for Wine. - . +Description: official WineHQ build of the popular Wine software Microsoft Windows Compatibility Layer (Binary Emulator and Library) Wine is a compatibility layer for running Windows applications on Linux. Applications are run at full speed without the need of cpu emulation. Wine does not require Microsoft Windows, however it can use native system dll files in place of its own if they are available. . - This package provides support for loading 32-bit x86 Windows applications - . - This package is based on a recent Wine beta. While many more applications - will work, there may be some loss of functionality compared with the stable - release provided by the regular wine package. + This package provides support for loading 32-bit x86 Windows applications. Package: wine-staging-amd64 Architecture: amd64 @@ -165,35 +160,74 @@ libgsm1 Section: otherosfs Priority: optional -Description: special build of the popular Wine software - The Staging Edition is a special build of the popular Wine software - with patches representing my current staging tree for Wine. - . +Description: official WineHQ build of the popular Wine software Microsoft Windows Compatibility Layer (Binary Emulator and Library) Wine is a compatibility layer for running Windows applications on Linux. Applications are run at full speed without the need of cpu emulation. Wine does not require Microsoft Windows, however it can use native system dll files in place of its own if they are available. . - This package provides support for loading 64-bit x86 Windows applications + This package provides support for loading 64-bit x86 Windows applications. + +Package: wine-staging-arm +Architecture: armhf +Multi-Arch: foreign +Pre-Depends: dpkg (>= 1.14.12ubuntu3), ${misc:Pre-Depends} +Depends: ${shlibs:Depends}, + libasound2-plugins, + libncurses5 +Recommends: libcapi20-3, + libcups2, + libdbus-1-3, + libfontconfig1 | libfontconfig, + libfreetype6, + libgnutls26, + libgtk-3-0, + libjpeg8, + libosmesa6, + libpcap0.8, + libpng12-0, + libpulse0, + libsane, + libssl1.0.0, + libtiff5 | libtiff4, + libtxc-dxtn-s2tc0, + libv4l-0, + libva-drm1, + libva-x11-1, + libxcomposite1, + libxcursor1, + libxi6, + libxinerama1, + libxrandr2, + libxrender1, + libxslt1.1, + libxt6, + libxxf86vm1, + libodbc1, + libgsm1 +Section: otherosfs +Priority: optional +Description: official WineHQ build of the popular Wine software + Microsoft Windows Compatibility Layer (Binary Emulator and Library) + Wine is a compatibility layer for running Windows applications on Linux. + Applications are run at full speed without the need of cpu emulation. Wine + does not require Microsoft Windows, however it can use native system dll + files in place of its own if they are available. . - This package is based on a recent Wine beta. While many more applications - will work, there may be some loss of functionality compared with the stable - release provided by the regular wine package. + This package provides support for loading 32-bit ARM Windows applications. Package: wine-staging -Architecture: i386 amd64 +Architecture: i386 amd64 armhf Multi-Arch: foreign Pre-Depends: dpkg (>= 1.14.12ubuntu3), ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends}, wine-staging-i386 (= ${binary:Version}) [i386 amd64], wine-staging-amd64 (= ${binary:Version}) [amd64], + wine-staging-arm (= ${binary:Version}) [armhf], Section: otherosfs Priority: optional -Description: special build of the popular Wine software - The Staging Edition is a special build of the popular Wine software - with patches representing my current staging tree for Wine. - . +Description: official WineHQ build of the popular Wine software Microsoft Windows Compatibility Layer (Binary Emulator and Library) Wine is a compatibility layer for running Windows applications on Linux. Applications are run at full speed without the need of cpu emulation. Wine @@ -203,24 +237,18 @@ This package includes a program loader for running unmodified Windows executables as well as the Wine project's free version of the Windows API for running programs ported from Windows. - . - This package is based on a recent Wine beta. While many more applications - will work, there may be some loss of functionality compared with the stable - release provided by the regular wine package. Package: wine-staging-dev -Architecture: i386 amd64 +Architecture: i386 amd64 armhf Pre-Depends: dpkg (>= 1.14.12ubuntu3), ${misc:Pre-Depends} Depends: libc6-dev, ${shlibs:Depends}, wine-staging-i386 (= ${binary:Version}) [i386 amd64], wine-staging-amd64 (= ${binary:Version}) [amd64], + wine-staging-arm (= ${binary:Version}) [armhf], Section: libdevel Priority: optional -Description: special build of the popular Wine software - The Staging Edition is a special build of the popular Wine software - with patches representing my current staging tree for Wine. - . +Description: official WineHQ build of the popular Wine software Microsoft Windows Compatibility Layer (Binary Emulator and Library) Wine is a compatibility layer for running Windows applications on Linux. Applications are run at full speed without the need of cpu emulation. Wine @@ -231,58 +259,45 @@ using wine's free version of the Microsoft Windows API. Package: wine-staging-dbg -Architecture: i386 amd64 +Architecture: i386 amd64 armhf Multi-Arch: same Pre-Depends: dpkg (>= 1.14.12ubuntu3), ${misc:Pre-Depends} Depends: ${shlibs:Depends}, wine-staging-i386 (= ${binary:Version}) [i386 amd64], wine-staging-amd64 (= ${binary:Version}) [amd64], + wine-staging-arm (= ${binary:Version}) [armhf], Section: debug Priority: optional -Description: special build of the popular Wine software - The Staging Edition is a special build of the popular Wine software - with patches representing my current staging tree for Wine. - . +Description: official WineHQ build of the popular Wine software Microsoft Windows Compatibility Layer (Binary Emulator and Library) Wine is a compatibility layer for running Windows applications on Linux. Applications are run at full speed without the need of cpu emulation. Wine does not require Microsoft Windows, however it can use native system dll files in place of its own if they are available. . - This package includes debugging symbols useful for reporting crashes and other - failures. + This package includes debugging symbols useful for reporting crashes and + other failures. Package: winehq-staging -Architecture: i386 amd64 +Architecture: i386 amd64 armhf Depends: wine-staging, ${misc:Depends} Section: otherosfs Priority: optional Replaces: wine, wine1.4, wine1.5, wine1.6, wine1.7, wine-i386, wine1.4-i386, wine1.5-i386, wine1.6-i386, wine1.7-i386, wine-amd64, wine1.4-amd64, - wine1.5-amd64, wine1.6-amd64, wine1.7-amd64 + wine1.5-amd64, wine1.6-amd64, wine1.7-amd64, wine32, wine64 Conflicts: wine, wine-i386, wine-amd64 Provides: wine, wine1.4, wine1.5, wine1.6, wine1.7, wine-i386, wine1.4-i386, wine1.5-i386, wine1.6-i386, wine1.7-i386, wine-amd64 [amd64], wine1.4-amd64 [amd64], wine1.5-amd64 [amd64], wine1.6-amd64 [amd64], - wine1.7-amd64 [amd64] -Description: special build of the popular Wine software - The Staging Edition is a special build of the popular Wine software - with patches representing our current staging tree for Wine. - . + wine1.7-amd64 [amd64], wine32, wine64 [amd64] +Description: official WineHQ build of the popular Wine software Microsoft Windows Compatibility Layer (Binary Emulator and Library) Wine is a compatibility layer for running Windows applications on Linux. Applications are run at full speed without the need of cpu emulation. Wine does not require Microsoft Windows, however it can use native system dll files in place of its own if they are available. . - This package includes a program loader for running unmodified Windows - executables as well as the Wine project's free version of the Windows API - for running programs ported from Windows. - . - This package is based on a recent Wine beta. While many more applications - will work, there may be some loss of functionality compared with the stable - release provided by the regular wine package. - . This compatibility package allows to use wine-staging system-wide as the default Wine version. diff -Nru wine-staging-1.9.0~ubuntu12.04.1/debian/copyright wine-staging-1.9.3~ubuntu12.04.1/debian/copyright --- wine-staging-1.9.0~ubuntu12.04.1/debian/copyright 2015-12-28 19:46:24.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/debian/copyright 2016-02-08 21:24:09.000000000 +0000 @@ -3,8 +3,8 @@ Source: http://www.winehq.org/ and http://www.wine-staging.com/ Files: * -Copyright: 1993-2015, the Wine project authors - 2014-2015, the Wine Staging project authors +Copyright: 1993-2016, the Wine project authors + 2014-2016, the Wine Staging project authors License: LGPL-2.1 Files: patches/fonts-Missing_Fonts/0001-fonts-Add-Liberation-Sans-as-an-Arial-replacement.patch diff -Nru wine-staging-1.9.0~ubuntu12.04.1/debian/rules wine-staging-1.9.3~ubuntu12.04.1/debian/rules --- wine-staging-1.9.0~ubuntu12.04.1/debian/rules 2015-12-28 19:46:24.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/debian/rules 2016-02-08 21:24:09.000000000 +0000 @@ -20,7 +20,6 @@ --mandir=\$${prefix}/share/man \ --infodir=\$${prefix}/share/info \ --enable-win64 \ - --without-gstreamer \ --with-xattr \ $(CONFFLAGS) else @@ -28,7 +27,6 @@ --libdir=\$${prefix}/lib \ --mandir=\$${prefix}/share/man \ --infodir=\$${prefix}/share/info \ - --without-gstreamer \ --with-xattr \ $(CONFFLAGS) endif diff -Nru wine-staging-1.9.0~ubuntu12.04.1/debian/wine-staging-arm.install wine-staging-1.9.3~ubuntu12.04.1/debian/wine-staging-arm.install --- wine-staging-1.9.0~ubuntu12.04.1/debian/wine-staging-arm.install 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/debian/wine-staging-arm.install 2016-02-08 21:24:09.000000000 +0000 @@ -0,0 +1,7 @@ +/opt/wine-staging/lib/libwine.so* +/opt/wine-staging/lib/wine +/opt/wine-staging/bin/wine +/opt/wine-staging/share/man/man?/wine.?* +/opt/wine-staging/share/man/de.UTF-8/man?/wine.?* +/opt/wine-staging/share/man/fr.UTF-8/man?/wine.?* +/opt/wine-staging/share/man/pl.UTF-8/man?/wine.?* diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/advapi32/registry.c wine-staging-1.9.3~ubuntu12.04.1/dlls/advapi32/registry.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/advapi32/registry.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/advapi32/registry.c 2016-02-08 19:32:34.000000000 +0000 @@ -37,6 +37,7 @@ #include "winerror.h" #include "winternl.h" #include "winuser.h" +#include "sddl.h" #include "advapi32_misc.h" #include "wine/unicode.h" @@ -648,6 +649,21 @@ return RegOpenKeyExA( hkey, name, 0, MAXIMUM_ALLOWED, retkey ); } +static WCHAR *get_thread_token_user_sid(HANDLE token) +{ + WCHAR *sidstring = NULL; + TOKEN_USER *info; + DWORD len = 0; + + GetTokenInformation(token, TokenUser, NULL, 0, &len); + + info = heap_alloc(len); + if (GetTokenInformation(token, TokenUser, info, len, &len)) + ConvertSidToStringSidW(info->User.Sid, &sidstring); + heap_free(info); + + return sidstring; +} /****************************************************************************** * RegOpenCurrentUser [ADVAPI32.@] @@ -671,7 +687,37 @@ */ LSTATUS WINAPI RegOpenCurrentUser( REGSAM access, PHKEY retkey ) { - return RegOpenKeyExA( HKEY_CURRENT_USER, "", 0, access, retkey ); + WCHAR *sidstring = NULL; + HANDLE threadtoken; + LSTATUS ret; + + /* get current user SID */ + if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &threadtoken)) + { + sidstring = get_thread_token_user_sid(threadtoken); + CloseHandle(threadtoken); + } + + if (!sidstring) + { + ImpersonateSelf(SecurityIdentification); + if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &threadtoken)) + { + sidstring = get_thread_token_user_sid(threadtoken); + CloseHandle(threadtoken); + } + RevertToSelf(); + } + + if (sidstring) + { + ret = RegOpenKeyExW( HKEY_USERS, sidstring, 0, access, retkey ); + LocalFree(sidstring); + } + else + ret = RegOpenKeyExA( HKEY_CURRENT_USER, "", 0, access, retkey ); + + return ret; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/advapi32/tests/registry.c wine-staging-1.9.3~ubuntu12.04.1/dlls/advapi32/tests/registry.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/advapi32/tests/registry.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/advapi32/tests/registry.c 2016-02-08 19:32:34.000000000 +0000 @@ -3278,6 +3278,18 @@ RegCloseKey(subkey); } +static void test_RegOpenCurrentUser(void) +{ + HKEY key; + LONG ret; + + key = HKEY_CURRENT_USER; + ret = RegOpenCurrentUser(KEY_READ, &key); + ok(!ret, "got %d, error %d\n", ret, GetLastError()); + ok(key != HKEY_CURRENT_USER, "got %p\n", key); + RegCloseKey(key); +} + START_TEST(registry) { /* Load pointers for functions that are not available in all Windows versions */ @@ -3310,6 +3322,7 @@ test_deleted_key(); test_delete_value(); test_delete_key_value(); + test_RegOpenCurrentUser(); /* cleanup */ delete_key( hkey_main ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/advapi32/tests/security.c wine-staging-1.9.3~ubuntu12.04.1/dlls/advapi32/tests/security.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/advapi32/tests/security.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/advapi32/tests/security.c 2016-02-08 19:32:34.000000000 +0000 @@ -146,6 +146,35 @@ #define STRSID_OK 0 #define STRSID_OPT 1 +#define SID_SLOTS 4 +static char debugsid_str[SID_SLOTS][256]; +static int debugsid_index = 0; +static const char* debugstr_sid(PSID sid) +{ + LPSTR sidstr; + DWORD le = GetLastError(); + char* res = debugsid_str[debugsid_index]; + debugsid_index = (debugsid_index + 1) % SID_SLOTS; + if (!pConvertSidToStringSidA) + strcpy(res, "missing ConvertSidToStringSidA"); + else if (!pConvertSidToStringSidA(sid, &sidstr)) + sprintf(res, "ConvertSidToStringSidA failed le=%u", GetLastError()); + else if (strlen(sidstr) > sizeof(*debugsid_str) - 1) + { + memcpy(res, sidstr, sizeof(*debugsid_str) - 4); + strcpy(res + sizeof(*debugsid_str) - 4, "..."); + LocalFree(sidstr); + } + else + { + strcpy(res, sidstr); + LocalFree(sidstr); + } + /* Restore the last error in case ConvertSidToStringSidA() modified it */ + SetLastError(le); + return res; +} + struct sidRef { SID_IDENTIFIER_AUTHORITY auth; @@ -240,7 +269,8 @@ res = GetSecurityDescriptorOwner(queriedSD, &owner, &owner_defaulted); ok_(__FILE__, line)(res, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); - ok_(__FILE__, line)(EqualSid(owner, expected), "Owner SIDs are not equal\n"); + ok_(__FILE__, line)(EqualSid(owner, expected), "Owner SIDs are not equal %s != %s\n", + debugstr_sid(owner), debugstr_sid(expected)); ok_(__FILE__, line)(!owner_defaulted, "Defaulted is true\n"); HeapFree(GetProcessHeap(), 0, queriedSD); @@ -258,7 +288,8 @@ res = GetSecurityDescriptorGroup(queriedSD, &group, &group_defaulted); ok_(__FILE__, line)(res, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); - ok_(__FILE__, line)(EqualSid(group, expected), "Group SIDs are not equal\n"); + ok_(__FILE__, line)(EqualSid(group, expected), "Group SIDs are not equal %s != %s\n", + debugstr_sid(group), debugstr_sid(expected)); ok_(__FILE__, line)(!group_defaulted, "Defaulted is true\n"); HeapFree(GetProcessHeap(), 0, queriedSD); @@ -2186,7 +2217,8 @@ ok(ret, "Failed to lookup account name %s\n",name); ok(sid_size != 0, "sid_size was zero\n"); - ok(EqualSid(psid,wk_sid),"(%s) Sids fail to match well known sid!\n",name); + ok(EqualSid(psid,wk_sid),"%s Sid %s fails to match well known sid %s!\n", + name, debugstr_sid(psid), debugstr_sid(wk_sid)); ok(!lstrcmpA(account, wk_account), "Expected %s , got %s\n", account, wk_account); ok(!lstrcmpA(domain, wk_domain), "Expected %s, got %s\n", wk_domain, domain); @@ -3145,9 +3177,9 @@ bret = EqualSid(&ace->SidStart, user_sid); if (todo_sid) todo_wine - ok_(__FILE__, line)(bret, "Current User ACE != Current User SID\n"); + ok_(__FILE__, line)(bret, "Current User ACE (%s) != Current User SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); else - ok_(__FILE__, line)(bret, "Current User ACE != Current User SID\n"); + ok_(__FILE__, line)(bret, "Current User ACE (%s) != Current User SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); if (todo_flags) todo_wine @@ -3171,9 +3203,9 @@ bret = EqualSid(&ace->SidStart, admin_sid); if (todo_sid) todo_wine - ok_(__FILE__, line)(bret, "Administators Group ACE != Administators Group SID\n"); + ok_(__FILE__, line)(bret, "Administators Group ACE (%s) != Administators Group SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); else - ok_(__FILE__, line)(bret, "Administators Group ACE != Administators Group SID\n"); + ok_(__FILE__, line)(bret, "Administators Group ACE (%s) != Administators Group SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); if (todo_flags) todo_wine @@ -3591,7 +3623,8 @@ bret = pGetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get Current User ACE.\n"); bret = EqualSid(&ace->SidStart, user_sid); - todo_wine ok(bret, "Current User ACE != Current User SID.\n"); + todo_wine ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", + debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", @@ -3603,7 +3636,8 @@ ok(bret, "Failed to get Administators Group ACE.\n"); bret = EqualSid(&ace->SidStart, admin_sid); todo_wine ok(bret || broken(!bret) /* win2k */, - "Administators Group ACE != Administators Group SID.\n"); + "Administators Group ACE (%s) != Administators Group SID (%s).\n", + debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */, @@ -3737,14 +3771,15 @@ bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted); ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); ok(owner != NULL, "owner should not be NULL\n"); - ok(EqualSid(owner, admin_sid), "MACHINE\\Software owner SID != Administrators SID.\n"); + ok(EqualSid(owner, admin_sid), "MACHINE\\Software owner SID (%s) != Administrators SID (%s).\n", debugstr_sid(owner), debugstr_sid(admin_sid)); bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted); ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); ok(group != NULL, "group should not be NULL\n"); ok(EqualSid(group, admin_sid) || broken(EqualSid(group, system_sid)) /* before Win7 */ || broken(((SID*)group)->SubAuthority[0] == SECURITY_NT_NON_UNIQUE) /* Vista */, - "MACHINE\\Software group SID != Local System SID.\n"); + "MACHINE\\Software group SID (%s) != Local System SID (%s or %s)\n", + debugstr_sid(group), debugstr_sid(admin_sid), debugstr_sid(system_sid)); LocalFree(pSD); /* Test querying the DACL of a built-in registry key */ @@ -4379,7 +4414,8 @@ bret = pGetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get Current User ACE.\n"); bret = EqualSid(&ace->SidStart, user_sid); - todo_wine ok(bret, "Current User ACE != Current User SID.\n"); + todo_wine ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", + debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", @@ -4390,7 +4426,7 @@ bret = pGetAce(pDacl, 1, (VOID **)&ace); ok(bret, "Failed to get Administators Group ACE.\n"); bret = EqualSid(&ace->SidStart, admin_sid); - todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n"); + todo_wine ok(bret, "Administators Group ACE (%s) != Administators Group SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", @@ -4539,7 +4575,8 @@ SetLastError(0xdeadbeef); ret = EqualSid(sid1, sid2); - ok(ret, "Same sids should have been equal\n"); + ok(ret, "Same sids should have been equal %s != %s\n", + debugstr_sid(sid1), debugstr_sid(sid2)); ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef), /* NT4 */ "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n", @@ -5683,7 +5720,6 @@ HANDLE token; DWORD size; DWORD res; - char *sidname = NULL; static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, {SECURITY_MANDATORY_HIGH_RID}}; static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, @@ -5715,14 +5751,10 @@ ok(tml->Label.Attributes == (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED), "got 0x%x (expected 0x%x)\n", tml->Label.Attributes, (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED)); - SetLastError(0xdeadbeef); - res = pConvertSidToStringSidA(tml->Label.Sid, &sidname); - ok(res, "got %u and %u\n", res, GetLastError()); - ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level), - "got %s (expected 'S-1-16-8192' or 'S-1-16-12288')\n", sidname); + "got %s (expected %s or %s)\n", debugstr_sid(tml->Label.Sid), + debugstr_sid(&medium_level), debugstr_sid(&high_level)); - LocalFree(sidname); CloseHandle(token); } @@ -6037,7 +6069,8 @@ InitializeSid(domain_sid2, &domain_ident, 4); for (i = 0; i < 4; i++) *GetSidSubAuthority(domain_sid2, i) = *GetSidSubAuthority(user_sid, i); - ok(EqualSid(domain_sid, domain_sid2), "unexpected domain sid\n"); + ok(EqualSid(domain_sid, domain_sid2), "unexpected domain sid %s != %s\n", + debugstr_sid(domain_sid), debugstr_sid(domain_sid2)); HeapFree(GetProcessHeap(), 0, user); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-core-localization-l1-2-0/api-ms-win-core-localization-l1-2-0.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-core-localization-l1-2-0/api-ms-win-core-localization-l1-2-0.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-core-localization-l1-2-0/api-ms-win-core-localization-l1-2-0.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-core-localization-l1-2-0/api-ms-win-core-localization-l1-2-0.spec 2016-02-08 19:32:34.000000000 +0000 @@ -23,7 +23,7 @@ @ stub GetProcessPreferredUILanguages @ stdcall GetSystemDefaultLCID() kernel32.GetSystemDefaultLCID @ stdcall GetSystemDefaultLangID() kernel32.GetSystemDefaultLangID -@ stub GetSystemPreferredUILanguages +@ stdcall GetSystemPreferredUILanguages(long ptr ptr ptr) kernel32.GetSystemPreferredUILanguages @ stdcall GetThreadLocale() kernel32.GetThreadLocale @ stdcall GetThreadPreferredUILanguages(long ptr ptr ptr) kernel32.GetThreadPreferredUILanguages @ stdcall GetThreadUILanguage() kernel32.GetThreadUILanguage diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-core-localization-l1-2-1/api-ms-win-core-localization-l1-2-1.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-core-localization-l1-2-1/api-ms-win-core-localization-l1-2-1.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-core-localization-l1-2-1/api-ms-win-core-localization-l1-2-1.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-core-localization-l1-2-1/api-ms-win-core-localization-l1-2-1.spec 2016-02-08 19:32:34.000000000 +0000 @@ -24,7 +24,7 @@ @ stub GetProcessPreferredUILanguages @ stdcall GetSystemDefaultLCID() kernel32.GetSystemDefaultLCID @ stdcall GetSystemDefaultLangID() kernel32.GetSystemDefaultLangID -@ stub GetSystemPreferredUILanguages +@ stdcall GetSystemPreferredUILanguages(long ptr ptr ptr) kernel32.GetSystemPreferredUILanguages @ stdcall GetThreadLocale() kernel32.GetThreadLocale @ stdcall GetThreadPreferredUILanguages(long ptr ptr ptr) kernel32.GetThreadPreferredUILanguages @ stdcall GetThreadUILanguage() kernel32.GetThreadUILanguage diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-core-sysinfo-l1-1-0/api-ms-win-core-sysinfo-l1-1-0.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-core-sysinfo-l1-1-0/api-ms-win-core-sysinfo-l1-1-0.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-core-sysinfo-l1-1-0/api-ms-win-core-sysinfo-l1-1-0.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-core-sysinfo-l1-1-0/api-ms-win-core-sysinfo-l1-1-0.spec 2016-02-08 19:32:34.000000000 +0000 @@ -15,7 +15,7 @@ @ stdcall -ret64 GetTickCount64() kernel32.GetTickCount64 @ stdcall GetTickCount() kernel32.GetTickCount @ stdcall GetTimeZoneInformation(ptr) kernel32.GetTimeZoneInformation -@ stub GetTimeZoneInformationForYear +@ stdcall GetTimeZoneInformationForYear(long ptr ptr) kernel32.GetTimeZoneInformationForYear @ stdcall GetVersion() kernel32.GetVersion @ stdcall GetVersionExA(ptr) kernel32.GetVersionExA @ stdcall GetVersionExW(ptr) kernel32.GetVersionExW diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-core-timezone-l1-1-0/api-ms-win-core-timezone-l1-1-0.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-core-timezone-l1-1-0/api-ms-win-core-timezone-l1-1-0.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-core-timezone-l1-1-0/api-ms-win-core-timezone-l1-1-0.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-core-timezone-l1-1-0/api-ms-win-core-timezone-l1-1-0.spec 2016-02-08 19:32:34.000000000 +0000 @@ -3,7 +3,7 @@ @ stdcall GetDynamicTimeZoneInformation(ptr) kernel32.GetDynamicTimeZoneInformation @ stub GetDynamicTimeZoneInformationEffectiveYears @ stdcall GetTimeZoneInformation(ptr) kernel32.GetTimeZoneInformation -@ stub GetTimeZoneInformationForYear +@ stdcall GetTimeZoneInformationForYear(long ptr ptr) kernel32.GetTimeZoneInformationForYear @ stub SetDynamicTimeZoneInformation @ stdcall SetTimeZoneInformation(ptr) kernel32.SetTimeZoneInformation @ stdcall SystemTimeToFileTime(ptr ptr) kernel32.SystemTimeToFileTime diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec 2016-02-08 19:32:34.000000000 +0000 @@ -55,7 +55,7 @@ @ stub _dexp @ stub _dlog @ stub _dnorm -@ stub _dpcomp +@ cdecl _dpcomp(double double) ucrtbase._dpcomp @ stub _dpoly @ stub _dscale @ cdecl _dsign(double) ucrtbase._dsign @@ -69,7 +69,7 @@ @ stub _fdlog @ stub _fdnorm @ cdecl _fdopen(long str) ucrtbase._fdopen -@ stub _fdpcomp +@ cdecl _fdpcomp(float float) ucrtbase._fdpcomp @ stub _fdpoly @ stub _fdscale @ cdecl _fdsign(float) ucrtbase._fdsign @@ -93,7 +93,7 @@ @ cdecl _ldclass(double) ucrtbase._ldclass @ stub _ldexp @ stub _ldlog -@ stub _ldpcomp +@ cdecl _ldpcomp(double double) ucrtbase._ldpcomp @ stub _ldpoly @ stub _ldscale @ cdecl _ldsign(double) ucrtbase._ldsign @@ -117,7 +117,7 @@ @ cdecl -arch=arm,x86_64 _nextafterf(float float) ucrtbase._nextafterf @ cdecl _scalb(double long) ucrtbase._scalb @ cdecl -arch=arm,x86_64 _scalbf(float long) ucrtbase._scalbf -@ stub _set_FMA3_enable +@ cdecl -arch=win64 _set_FMA3_enable(long) ucrtbase._set_FMA3_enable @ cdecl -arch=i386 _set_SSE2_enable(long) ucrtbase._set_SSE2_enable @ cdecl _y0(double) ucrtbase._y0 @ cdecl _y1(double) ucrtbase._y1 @@ -246,9 +246,9 @@ @ cdecl fmax(double double) ucrtbase.fmax @ cdecl fmaxf(float float) ucrtbase.fmaxf @ cdecl fmaxl(double double) ucrtbase.fmaxl -@ stub fmin -@ stub fminf -@ stub fminl +@ cdecl fmin(double double) ucrtbase.fmin +@ cdecl fminf(float float) ucrtbase.fminf +@ cdecl fminl(double double) ucrtbase.fminl @ cdecl fmod(double double) ucrtbase.fmod @ cdecl -arch=arm,x86_64 fmodf(float float) ucrtbase.fmodf @ cdecl frexp(double ptr) ucrtbase.frexp @@ -293,9 +293,9 @@ @ stub nearbyint @ stub nearbyintf @ stub nearbyintl -@ stub nextafter -@ stub nextafterf -@ stub nextafterl +@ cdecl nextafter(double double) ucrtbase.nextafter +@ cdecl nextafterf(float float) ucrtbase.nextafterf +@ cdecl nextafterl(double double) ucrtbase.nextafterl @ stub nexttoward @ stub nexttowardf @ stub nexttowardl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-crt-multibyte-l1-1-0/api-ms-win-crt-multibyte-l1-1-0.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-crt-multibyte-l1-1-0/api-ms-win-crt-multibyte-l1-1-0.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-crt-multibyte-l1-1-0/api-ms-win-crt-multibyte-l1-1-0.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-crt-multibyte-l1-1-0/api-ms-win-crt-multibyte-l1-1-0.spec 2016-02-08 19:32:34.000000000 +0000 @@ -104,7 +104,7 @@ @ stub _mbscspn_l @ cdecl _mbsdec(ptr ptr) ucrtbase._mbsdec @ stub _mbsdec_l -@ stub _mbsdup +@ cdecl _mbsdup(str) ucrtbase._mbsdup @ cdecl _mbsicmp(str str) ucrtbase._mbsicmp @ stub _mbsicmp_l @ cdecl _mbsicoll(str str) ucrtbase._mbsicoll diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec 2016-02-08 19:32:34.000000000 +0000 @@ -30,7 +30,7 @@ @ cdecl _controlfp_s(ptr long long) ucrtbase._controlfp_s @ stub _crt_at_quick_exit @ cdecl _crt_atexit(ptr) ucrtbase._crt_atexit -@ stub _crt_debugger_hook +@ cdecl _crt_debugger_hook(long) ucrtbase._crt_debugger_hook @ cdecl _endthread() ucrtbase._endthread @ cdecl _endthreadex(long) ucrtbase._endthreadex @ cdecl _errno() ucrtbase._errno diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-crt-time-l1-1-0/api-ms-win-crt-time-l1-1-0.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-crt-time-l1-1-0/api-ms-win-crt-time-l1-1-0.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-crt-time-l1-1-0/api-ms-win-crt-time-l1-1-0.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-crt-time-l1-1-0/api-ms-win-crt-time-l1-1-0.spec 2016-02-08 19:32:34.000000000 +0000 @@ -4,7 +4,7 @@ @ cdecl _Strftime(str long str ptr ptr) ucrtbase._Strftime @ cdecl _W_Getdays() ucrtbase._W_Getdays @ cdecl _W_Getmonths() ucrtbase._W_Getmonths -@ stub _W_Gettnames +@ cdecl _W_Gettnames() ucrtbase._W_Gettnames @ stub _Wcsftime @ cdecl __daylight() ucrtbase.__daylight @ cdecl __dstbias() ucrtbase.__dstbias @@ -56,9 +56,9 @@ @ cdecl _wasctime_s(ptr long ptr) ucrtbase._wasctime_s @ stub _wcsftime_l @ cdecl _wctime32(ptr) ucrtbase._wctime32 -@ stub _wctime32_s +@ cdecl _wctime32_s(ptr long ptr) ucrtbase._wctime32_s @ cdecl _wctime64(ptr) ucrtbase._wctime64 -@ stub _wctime64_s +@ cdecl _wctime64_s(ptr long ptr) ucrtbase._wctime64_s @ cdecl _wstrdate(ptr) ucrtbase._wstrdate @ cdecl _wstrdate_s(ptr long) ucrtbase._wstrdate_s @ cdecl _wstrtime(ptr) ucrtbase._wstrtime diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-security-lsalookup-l1-1-1/api-ms-win-security-lsalookup-l1-1-1.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-security-lsalookup-l1-1-1/api-ms-win-security-lsalookup-l1-1-1.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-security-lsalookup-l1-1-1/api-ms-win-security-lsalookup-l1-1-1.spec 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-security-lsalookup-l1-1-1/api-ms-win-security-lsalookup-l1-1-1.spec 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,16 @@ +@ stub EnumerateIdentityProviders +@ stub GetDefaultIdentityProvider +@ stub GetIdentityProviderInfoByGUID +@ stub GetIdentityProviderInfoByName +@ stub LookupAccountNameLocalA +@ stub LookupAccountNameLocalW +@ stub LookupAccountSidLocalA +@ stub LookupAccountSidLocalW +@ stub LsaLookupClose +@ stub LsaLookupFreeMemory +@ stub LsaLookupGetDomainInfo +@ stub LsaLookupManageSidNameMapping +@ stub LsaLookupOpenLocalPolicy +@ stub LsaLookupTranslateNames +@ stub LsaLookupTranslateSids +@ stub ReleaseIdentityProviderEnumContext diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-security-lsalookup-l1-1-1/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-security-lsalookup-l1-1-1/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/api-ms-win-security-lsalookup-l1-1-1/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/api-ms-win-security-lsalookup-l1-1-1/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1 @@ +MODULE = api-ms-win-security-lsalookup-l1-1-1.dll diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/appwiz.cpl/addons.c wine-staging-1.9.3~ubuntu12.04.1/dlls/appwiz.cpl/addons.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/appwiz.cpl/addons.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/appwiz.cpl/addons.c 2016-02-08 19:32:34.000000000 +0000 @@ -51,14 +51,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(appwizcpl); -#define GECKO_VERSION "2.40" +#define GECKO_VERSION "2.44" #ifdef __i386__ #define ARCH_STRING "x86" -#define GECKO_SHA "7001a6ed5b02d0ae4e73b14c92018d604b87f3ad" +#define GECKO_SHA "7930300c531d975ad63ee20d5e9b3974e339e43e" #elif defined(__x86_64__) #define ARCH_STRING "x86_64" -#define GECKO_SHA "356c414527b08b015b6dc53dbbf78d752320ae90" +#define GECKO_SHA "ed473f584938ebe8da1f6e660610e616104567b3" #else #define ARCH_STRING "" #define GECKO_SHA "???" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/avifil32/api.c wine-staging-1.9.3~ubuntu12.04.1/dlls/avifil32/api.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/avifil32/api.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/avifil32/api.c 2016-02-08 19:32:34.000000000 +0000 @@ -2289,8 +2289,8 @@ if (nStreams <= 0) return AVIERR_BADPARAM; - streams = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(void *)); - options = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(void *)); + streams = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(*streams)); + options = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(*options)); if (!streams || !options) { ret = AVIERR_MEMORY; @@ -2303,8 +2303,8 @@ __ms_va_start(vl, lpOptions); for (i = 1; i < nStreams; i++) { - streams[i] = va_arg(vl, void *); - options[i] = va_arg(vl, void *); + streams[i] = va_arg(vl, PAVISTREAM); + options[i] = va_arg(vl, PAVICOMPRESSOPTIONS); } __ms_va_end(vl); @@ -2332,8 +2332,8 @@ if (nStreams <= 0) return AVIERR_BADPARAM; - streams = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(void *)); - options = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(void *)); + streams = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(*streams)); + options = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(*options)); if (!streams || !options) { ret = AVIERR_MEMORY; @@ -2346,8 +2346,8 @@ __ms_va_start(vl, lpOptions); for (i = 1; i < nStreams; i++) { - streams[i] = va_arg(vl, void *); - options[i] = va_arg(vl, void *); + streams[i] = va_arg(vl, PAVISTREAM); + options[i] = va_arg(vl, PAVICOMPRESSOPTIONS); } __ms_va_end(vl); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/bcrypt/bcrypt_main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/bcrypt/bcrypt_main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/bcrypt/bcrypt_main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/bcrypt/bcrypt_main.c 2016-02-08 19:32:34.000000000 +0000 @@ -18,8 +18,15 @@ */ #include "config.h" +#include "wine/port.h" #include +#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H +#include +#elif defined(SONAME_LIBGNUTLS) +#include +#include +#endif #include "ntstatus.h" #define WIN32_NO_STATUS @@ -27,10 +34,90 @@ #include "winbase.h" #include "ntsecapi.h" #include "bcrypt.h" + #include "wine/debug.h" +#include "wine/library.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(bcrypt); +static HINSTANCE instance; + +#if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) +WINE_DECLARE_DEBUG_CHANNEL(winediag); + +static void *libgnutls_handle; +#define MAKE_FUNCPTR(f) static typeof(f) * p##f +MAKE_FUNCPTR(gnutls_global_deinit); +MAKE_FUNCPTR(gnutls_global_init); +MAKE_FUNCPTR(gnutls_global_set_log_function); +MAKE_FUNCPTR(gnutls_global_set_log_level); +MAKE_FUNCPTR(gnutls_hash); +MAKE_FUNCPTR(gnutls_hash_deinit); +MAKE_FUNCPTR(gnutls_hash_init); +MAKE_FUNCPTR(gnutls_perror); +#undef MAKE_FUNCPTR + +static void gnutls_log( int level, const char *msg ) +{ + TRACE( "<%d> %s", level, msg ); +} + +static BOOL gnutls_initialize(void) +{ + int ret; + + if (!(libgnutls_handle = wine_dlopen( SONAME_LIBGNUTLS, RTLD_NOW, NULL, 0 ))) + { + ERR_(winediag)( "failed to load libgnutls, no support for crypto hashes\n" ); + return FALSE; + } + +#define LOAD_FUNCPTR(f) \ + if (!(p##f = wine_dlsym( libgnutls_handle, #f, NULL, 0 ))) \ + { \ + ERR( "failed to load %s\n", #f ); \ + goto fail; \ + } + + LOAD_FUNCPTR(gnutls_global_deinit) + LOAD_FUNCPTR(gnutls_global_init) + LOAD_FUNCPTR(gnutls_global_set_log_function) + LOAD_FUNCPTR(gnutls_global_set_log_level) + LOAD_FUNCPTR(gnutls_hash); + LOAD_FUNCPTR(gnutls_hash_deinit); + LOAD_FUNCPTR(gnutls_hash_init); + LOAD_FUNCPTR(gnutls_perror) +#undef LOAD_FUNCPTR + + if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS) + { + pgnutls_perror( ret ); + goto fail; + } + + if (TRACE_ON( bcrypt )) + { + pgnutls_global_set_log_level( 4 ); + pgnutls_global_set_log_function( gnutls_log ); + } + + return TRUE; + +fail: + wine_dlclose( libgnutls_handle, NULL, 0 ); + libgnutls_handle = NULL; + return FALSE; +} + +static void gnutls_uninitialize(void) +{ + pgnutls_global_deinit(); + wine_dlclose( libgnutls_handle, NULL, 0 ); + libgnutls_handle = NULL; +} +#endif /* HAVE_GNUTLS_HASH && !HAVE_COMMONCRYPTO_COMMONDIGEST_H */ + NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG dwAlgOperations, ULONG *pAlgCount, BCRYPT_ALGORITHM_IDENTIFIER **ppAlgList, ULONG dwFlags) { @@ -78,24 +165,83 @@ return STATUS_NOT_IMPLEMENTED; } -NTSTATUS WINAPI BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *algorithm, LPCWSTR algorithmId, - LPCWSTR implementation, DWORD flags) +#define MAGIC_ALG (('A' << 24) | ('L' << 16) | ('G' << 8) | '0') +#define MAGIC_HASH (('H' << 24) | ('A' << 16) | ('S' << 8) | 'H') +struct object { - FIXME("%p, %s, %s, %08x - stub\n", algorithm, wine_dbgstr_w(algorithmId), wine_dbgstr_w(implementation), flags); + ULONG magic; +}; - if (!algorithm) - return STATUS_INVALID_PARAMETER; +enum alg_id +{ + ALG_ID_SHA1, + ALG_ID_SHA256, + ALG_ID_SHA384, + ALG_ID_SHA512 +}; + +static const struct { + ULONG hash_length; + const WCHAR *alg_name; +} alg_props[] = { + /* ALG_ID_SHA1 */ { 20, BCRYPT_SHA1_ALGORITHM }, + /* ALG_ID_SHA256 */ { 32, BCRYPT_SHA256_ALGORITHM }, + /* ALG_ID_SHA384 */ { 48, BCRYPT_SHA384_ALGORITHM }, + /* ALG_ID_SHA512 */ { 64, BCRYPT_SHA512_ALGORITHM } +}; - *algorithm = NULL; +struct algorithm +{ + struct object hdr; + enum alg_id id; +}; - return STATUS_NOT_IMPLEMENTED; +NTSTATUS WINAPI BCryptOpenAlgorithmProvider( BCRYPT_ALG_HANDLE *handle, LPCWSTR id, LPCWSTR implementation, DWORD flags ) +{ + struct algorithm *alg; + enum alg_id alg_id; + + TRACE( "%p, %s, %s, %08x\n", handle, wine_dbgstr_w(id), wine_dbgstr_w(implementation), flags ); + + if (!handle || !id) return STATUS_INVALID_PARAMETER; + if (flags) + { + FIXME( "unimplemented flags %08x\n", flags ); + return STATUS_NOT_IMPLEMENTED; + } + + if (!strcmpW( id, BCRYPT_SHA1_ALGORITHM )) alg_id = ALG_ID_SHA1; + else if (!strcmpW( id, BCRYPT_SHA256_ALGORITHM )) alg_id = ALG_ID_SHA256; + else if (!strcmpW( id, BCRYPT_SHA384_ALGORITHM )) alg_id = ALG_ID_SHA384; + else if (!strcmpW( id, BCRYPT_SHA512_ALGORITHM )) alg_id = ALG_ID_SHA512; + else + { + FIXME( "algorithm %s not supported\n", debugstr_w(id) ); + return STATUS_NOT_IMPLEMENTED; + } + if (implementation && strcmpW( implementation, MS_PRIMITIVE_PROVIDER )) + { + FIXME( "implementation %s not supported\n", debugstr_w(implementation) ); + return STATUS_NOT_IMPLEMENTED; + } + + if (!(alg = HeapAlloc( GetProcessHeap(), 0, sizeof(*alg) ))) return STATUS_NO_MEMORY; + alg->hdr.magic = MAGIC_ALG; + alg->id = alg_id; + + *handle = alg; + return STATUS_SUCCESS; } -NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE algorithm, DWORD flags) +NTSTATUS WINAPI BCryptCloseAlgorithmProvider( BCRYPT_ALG_HANDLE handle, DWORD flags ) { - FIXME("%p, %08x - stub\n", algorithm, flags); + struct algorithm *alg = handle; - return STATUS_NOT_IMPLEMENTED; + TRACE( "%p, %08x\n", handle, flags ); + + if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE; + HeapFree( GetProcessHeap(), 0, alg ); + return STATUS_SUCCESS; } NTSTATUS WINAPI BCryptGetFipsAlgorithmMode(BOOLEAN *enabled) @@ -109,17 +255,391 @@ return STATUS_SUCCESS; } -NTSTATUS WINAPI BCryptGetProperty(BCRYPT_HANDLE obj, LPCWSTR prop, UCHAR *buffer, ULONG count, ULONG *res, ULONG flags) +#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H +struct hash { - FIXME("%p, %s, %p, %u, %p, %08x - stub\n", obj, wine_dbgstr_w(prop), buffer, count, res, flags); + struct object hdr; + enum alg_id alg_id; + union + { + CC_SHA1_CTX sha1_ctx; + CC_SHA256_CTX sha256_ctx; + CC_SHA512_CTX sha512_ctx; + } u; +}; +static NTSTATUS hash_init( struct hash *hash ) +{ + switch (hash->alg_id) + { + case ALG_ID_SHA1: + CC_SHA1_Init( &hash->u.sha1_ctx ); + break; + + case ALG_ID_SHA256: + CC_SHA256_Init( &hash->u.sha256_ctx ); + break; + + case ALG_ID_SHA384: + CC_SHA384_Init( &hash->u.sha512_ctx ); + break; + + case ALG_ID_SHA512: + CC_SHA512_Init( &hash->u.sha512_ctx ); + break; + + default: + ERR( "unhandled id %u\n", hash->alg_id ); + return STATUS_NOT_IMPLEMENTED; + } + return STATUS_SUCCESS; +} + +static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size ) +{ + switch (hash->alg_id) + { + case ALG_ID_SHA1: + CC_SHA1_Update( &hash->u.sha1_ctx, input, size ); + break; + + case ALG_ID_SHA256: + CC_SHA256_Update( &hash->u.sha256_ctx, input, size ); + break; + + case ALG_ID_SHA384: + CC_SHA384_Update( &hash->u.sha512_ctx, input, size ); + break; + + case ALG_ID_SHA512: + CC_SHA512_Update( &hash->u.sha512_ctx, input, size ); + break; + + default: + ERR( "unhandled id %u\n", hash->alg_id ); + return STATUS_NOT_IMPLEMENTED; + } + return STATUS_SUCCESS; +} + +static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size ) +{ + switch (hash->alg_id) + { + case ALG_ID_SHA1: + CC_SHA1_Final( output, &hash->u.sha1_ctx ); + break; + + case ALG_ID_SHA256: + CC_SHA256_Final( output, &hash->u.sha256_ctx ); + break; + + case ALG_ID_SHA384: + CC_SHA384_Final( output, &hash->u.sha512_ctx ); + break; + + case ALG_ID_SHA512: + CC_SHA512_Final( output, &hash->u.sha512_ctx ); + break; + + default: + ERR( "unhandled id %u\n", hash->alg_id ); + break; + } + return STATUS_SUCCESS; +} +#elif defined(HAVE_GNUTLS_HASH) +struct hash +{ + struct object hdr; + enum alg_id alg_id; + gnutls_hash_hd_t handle; +}; + +static NTSTATUS hash_init( struct hash *hash ) +{ + gnutls_digest_algorithm_t alg; + + if (!libgnutls_handle) return STATUS_INTERNAL_ERROR; + + switch (hash->alg_id) + { + case ALG_ID_SHA1: + alg = GNUTLS_DIG_SHA1; + break; + + case ALG_ID_SHA256: + alg = GNUTLS_DIG_SHA256; + break; + + case ALG_ID_SHA384: + alg = GNUTLS_DIG_SHA384; + break; + + case ALG_ID_SHA512: + alg = GNUTLS_DIG_SHA512; + break; + + default: + ERR( "unhandled id %u\n", hash->alg_id ); + return STATUS_NOT_IMPLEMENTED; + } + + if (pgnutls_hash_init( &hash->handle, alg )) return STATUS_INTERNAL_ERROR; + return STATUS_SUCCESS; +} + +static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size ) +{ + if (pgnutls_hash( hash->handle, input, size )) return STATUS_INTERNAL_ERROR; + return STATUS_SUCCESS; +} + +static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size ) +{ + pgnutls_hash_deinit( hash->handle, output ); + return STATUS_SUCCESS; +} +#else +struct hash +{ + struct object hdr; + enum alg_id alg_id; +}; + +static NTSTATUS hash_init( struct hash *hash ) +{ + ERR( "support for hashes not available at build time\n" ); return STATUS_NOT_IMPLEMENTED; } -NTSTATUS WINAPI BCryptCreateHash(BCRYPT_ALG_HANDLE algorithm, BCRYPT_HASH_HANDLE* hash, UCHAR* hashobject, - ULONG hashobjectlen, UCHAR *secret, ULONG secretlen, ULONG flags) +static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size ) { - FIXME("%p, %p, %p, %u, %p, %u, %08x - stub\n", algorithm, hash, hashobject, hashobjectlen, secret, secretlen, flags); + ERR( "support for hashes not available at build time\n" ); + return STATUS_NOT_IMPLEMENTED; +} +static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size ) +{ + ERR( "support for hashes not available at build time\n" ); return STATUS_NOT_IMPLEMENTED; } +#endif + +#define OBJECT_LENGTH_SHA1 278 +#define OBJECT_LENGTH_SHA256 286 +#define OBJECT_LENGTH_SHA384 382 +#define OBJECT_LENGTH_SHA512 382 + +static NTSTATUS generic_alg_property( enum alg_id id, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) +{ + if (!strcmpW( prop, BCRYPT_HASH_LENGTH )) + { + *ret_size = sizeof(ULONG); + if (size < sizeof(ULONG)) + return STATUS_BUFFER_TOO_SMALL; + if(buf) + *(ULONG*)buf = alg_props[id].hash_length; + return STATUS_SUCCESS; + } + + if (!strcmpW( prop, BCRYPT_ALGORITHM_NAME )) + { + *ret_size = (strlenW(alg_props[id].alg_name)+1)*sizeof(WCHAR); + if (size < *ret_size) + return STATUS_BUFFER_TOO_SMALL; + if(buf) + memcpy(buf, alg_props[id].alg_name, *ret_size); + return STATUS_SUCCESS; + } + + return STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS get_alg_property( enum alg_id id, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) +{ + NTSTATUS status; + ULONG value; + + status = generic_alg_property( id, prop, buf, size, ret_size ); + if (status != STATUS_NOT_IMPLEMENTED) + return status; + + switch (id) + { + case ALG_ID_SHA1: + if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH )) + { + value = OBJECT_LENGTH_SHA1; + break; + } + FIXME( "unsupported sha1 algorithm property %s\n", debugstr_w(prop) ); + return STATUS_NOT_IMPLEMENTED; + + case ALG_ID_SHA256: + if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH )) + { + value = OBJECT_LENGTH_SHA256; + break; + } + FIXME( "unsupported sha256 algorithm property %s\n", debugstr_w(prop) ); + return STATUS_NOT_IMPLEMENTED; + + case ALG_ID_SHA384: + if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH )) + { + value = OBJECT_LENGTH_SHA384; + break; + } + FIXME( "unsupported sha384 algorithm property %s\n", debugstr_w(prop) ); + return STATUS_NOT_IMPLEMENTED; + + case ALG_ID_SHA512: + if (!strcmpW( prop, BCRYPT_OBJECT_LENGTH )) + { + value = OBJECT_LENGTH_SHA512; + break; + } + FIXME( "unsupported sha512 algorithm property %s\n", debugstr_w(prop) ); + return STATUS_NOT_IMPLEMENTED; + + default: + FIXME( "unsupported algorithm %u\n", id ); + return STATUS_NOT_IMPLEMENTED; + } + + if (size < sizeof(ULONG)) + { + *ret_size = sizeof(ULONG); + return STATUS_BUFFER_TOO_SMALL; + } + if (buf) *(ULONG *)buf = value; + *ret_size = sizeof(ULONG); + + return STATUS_SUCCESS; +} + +static NTSTATUS get_hash_property( enum alg_id id, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) +{ + NTSTATUS status; + + status = generic_alg_property( id, prop, buf, size, ret_size ); + if (status == STATUS_NOT_IMPLEMENTED) + FIXME( "unsupported property %s\n", debugstr_w(prop) ); + return status; +} + +NTSTATUS WINAPI BCryptGetProperty( BCRYPT_HANDLE handle, LPCWSTR prop, UCHAR *buffer, ULONG count, ULONG *res, ULONG flags ) +{ + struct object *object = handle; + + TRACE( "%p, %s, %p, %u, %p, %08x\n", handle, wine_dbgstr_w(prop), buffer, count, res, flags ); + + if (!object) return STATUS_INVALID_HANDLE; + if (!prop || !res) return STATUS_INVALID_PARAMETER; + + switch (object->magic) + { + case MAGIC_ALG: + { + const struct algorithm *alg = (const struct algorithm *)object; + return get_alg_property( alg->id, prop, buffer, count, res ); + } + case MAGIC_HASH: + { + const struct hash *hash = (const struct hash *)object; + return get_hash_property( hash->alg_id, prop, buffer, count, res ); + } + default: + WARN( "unknown magic %08x\n", object->magic ); + return STATUS_INVALID_HANDLE; + } +} + +NTSTATUS WINAPI BCryptCreateHash( BCRYPT_ALG_HANDLE algorithm, BCRYPT_HASH_HANDLE *handle, UCHAR *object, ULONG objectlen, + UCHAR *secret, ULONG secretlen, ULONG flags ) +{ + struct algorithm *alg = algorithm; + struct hash *hash; + NTSTATUS status; + + TRACE( "%p, %p, %p, %u, %p, %u, %08x - stub\n", algorithm, handle, object, objectlen, + secret, secretlen, flags ); + if (flags) + { + FIXME( "unimplemented flags %08x\n", flags ); + return STATUS_NOT_IMPLEMENTED; + } + + if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE; + if (object) FIXME( "ignoring object buffer\n" ); + + if (!(hash = HeapAlloc( GetProcessHeap(), 0, sizeof(*hash) ))) return STATUS_NO_MEMORY; + hash->hdr.magic = MAGIC_HASH; + hash->alg_id = alg->id; + if ((status = hash_init( hash )) != STATUS_SUCCESS) + { + HeapFree( GetProcessHeap(), 0, hash ); + return status; + } + + *handle = hash; + return STATUS_SUCCESS; +} + +NTSTATUS WINAPI BCryptDestroyHash( BCRYPT_HASH_HANDLE handle ) +{ + struct hash *hash = handle; + + TRACE( "%p\n", handle ); + + if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE; + HeapFree( GetProcessHeap(), 0, hash ); + return STATUS_SUCCESS; +} + +NTSTATUS WINAPI BCryptHashData( BCRYPT_HASH_HANDLE handle, UCHAR *input, ULONG size, ULONG flags ) +{ + struct hash *hash = handle; + + TRACE( "%p, %p, %u, %08x\n", handle, input, size, flags ); + + if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE; + if (!input) return STATUS_INVALID_PARAMETER; + + return hash_update( hash, input, size ); +} + +NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE handle, UCHAR *output, ULONG size, ULONG flags ) +{ + struct hash *hash = handle; + + TRACE( "%p, %p, %u, %08x\n", handle, output, size, flags ); + + if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE; + if (!output) return STATUS_INVALID_PARAMETER; + + return hash_finish( hash, output, size ); +} + +BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) +{ + switch (reason) + { + case DLL_PROCESS_ATTACH: + instance = hinst; + DisableThreadLibraryCalls( hinst ); +#if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) + gnutls_initialize(); +#endif + break; + + case DLL_PROCESS_DETACH: + if (reserved) break; +#if defined(HAVE_GNUTLS_HASH) && !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) + gnutls_uninitialize(); +#endif + break; + } + return TRUE; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/bcrypt/bcrypt.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/bcrypt/bcrypt.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/bcrypt/bcrypt.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/bcrypt/bcrypt.spec 2016-02-08 19:32:34.000000000 +0000 @@ -8,7 +8,7 @@ @ stub BCryptDecrypt @ stub BCryptDeleteContext @ stub BCryptDeriveKey -@ stub BCryptDestroyHash +@ stdcall BCryptDestroyHash(ptr) @ stub BCryptDestroyKey @ stub BCryptDestroySecret @ stub BCryptDuplicateHash @@ -22,14 +22,14 @@ @ stub BCryptEnumRegisteredProviders @ stub BCryptExportKey @ stub BCryptFinalizeKeyPair -@ stub BCryptFinishHash +@ stdcall BCryptFinishHash(ptr ptr long long) @ stub BCryptFreeBuffer @ stdcall BCryptGenRandom(ptr ptr long long) @ stub BCryptGenerateKeyPair @ stub BCryptGenerateSymmetricKey @ stdcall BCryptGetFipsAlgorithmMode(ptr) @ stdcall BCryptGetProperty(ptr wstr ptr long ptr long) -@ stub BCryptHashData +@ stdcall BCryptHashData(ptr ptr long long) @ stub BCryptImportKey @ stub BCryptImportKeyPair @ stdcall BCryptOpenAlgorithmProvider(ptr wstr wstr long) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/bcrypt/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/bcrypt/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/bcrypt/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/bcrypt/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,5 +1,7 @@ MODULE = bcrypt.dll IMPORTS = advapi32 +IMPORTLIB = bcrypt +EXTRAINCL = $(GNUTLS_CFLAGS) C_SRCS = \ bcrypt_main.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/bcrypt/tests/bcrypt.c wine-staging-1.9.3~ubuntu12.04.1/dlls/bcrypt/tests/bcrypt.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/bcrypt/tests/bcrypt.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/bcrypt/tests/bcrypt.c 2016-02-08 19:32:34.000000000 +0000 @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include #define WIN32_NO_STATUS #include @@ -25,57 +26,32 @@ #include "wine/test.h" -static NTSTATUS (WINAPI *pBCryptGenRandom)(BCRYPT_ALG_HANDLE hAlgorithm, PUCHAR pbBuffer, - ULONG cbBuffer, ULONG dwFlags); -static NTSTATUS (WINAPI *pBCryptGetFipsAlgorithmMode)(BOOLEAN *enabled); - -static BOOL Init(void) -{ - HMODULE hbcrypt = LoadLibraryA("bcrypt.dll"); - if (!hbcrypt) - { - win_skip("bcrypt library not available\n"); - return FALSE; - } - - pBCryptGenRandom = (void *)GetProcAddress(hbcrypt, "BCryptGenRandom"); - pBCryptGetFipsAlgorithmMode = (void *)GetProcAddress(hbcrypt, "BCryptGetFipsAlgorithmMode"); - - return TRUE; -} - static void test_BCryptGenRandom(void) { NTSTATUS ret; UCHAR buffer[256]; - if (!pBCryptGenRandom) - { - win_skip("BCryptGenRandom is not available\n"); - return; - } - - ret = pBCryptGenRandom(NULL, NULL, 0, 0); + ret = BCryptGenRandom(NULL, NULL, 0, 0); ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret); - ret = pBCryptGenRandom(NULL, buffer, 0, 0); + ret = BCryptGenRandom(NULL, buffer, 0, 0); ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret); - ret = pBCryptGenRandom(NULL, buffer, sizeof(buffer), 0); + ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), 0); ok(ret == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got 0x%x\n", ret); - ret = pBCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG); + ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG); ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret); - ret = pBCryptGenRandom(NULL, buffer, sizeof(buffer), + ret = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG|BCRYPT_RNG_USE_ENTROPY_IN_BUFFER); ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret); - ret = pBCryptGenRandom(NULL, NULL, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG); + ret = BCryptGenRandom(NULL, NULL, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG); ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret); /* Zero sized buffer should work too */ - ret = pBCryptGenRandom(NULL, buffer, 0, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + ret = BCryptGenRandom(NULL, buffer, 0, BCRYPT_USE_SYSTEM_PREFERRED_RNG); ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret); /* Test random number generation - It's impossible for a sane RNG to return 8 zeros */ memset(buffer, 0, 16); - ret = pBCryptGenRandom(NULL, buffer, 8, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + ret = BCryptGenRandom(NULL, buffer, 8, BCRYPT_USE_SYSTEM_PREFERRED_RNG); ok(ret == STATUS_SUCCESS, "Expected success, got 0x%x\n", ret); ok(memcmp(buffer, buffer + 8, 8), "Expected a random number, got 0\n"); } @@ -85,24 +61,355 @@ NTSTATUS ret; BOOLEAN enabled; - if (!pBCryptGetFipsAlgorithmMode) + ret = BCryptGetFipsAlgorithmMode(&enabled); + ok(ret == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%x\n", ret); + + ret = BCryptGetFipsAlgorithmMode(NULL); + ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret); +} + +static void format_hash(const UCHAR *bytes, ULONG size, char *buf) +{ + ULONG i; + buf[0] = '\0'; + for (i = 0; i < size; i++) { - win_skip("BCryptGetFipsAlgorithmMode is not available\n"); - return; + sprintf(buf + i * 2, "%02x", bytes[i]); } + return; +} - ret = pBCryptGetFipsAlgorithmMode(&enabled); - ok(ret == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%x\n", ret); +static int strcmp_wa(const WCHAR *strw, const char *stra) +{ + WCHAR buf[512]; + MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(buf[0])); + return lstrcmpW(strw, buf); +} - ret = pBCryptGetFipsAlgorithmMode(NULL); - ok(ret == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got 0x%x\n", ret); +#define test_hash_length(a,b) _test_hash_length(__LINE__,a,b) +static void _test_hash_length(unsigned line, void *handle, ULONG exlen) +{ + ULONG len = 0xdeadbeef, size = 0xdeadbeef; + NTSTATUS status; + + status = BCryptGetProperty(handle, BCRYPT_HASH_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); + ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %08x\n", status); + ok_(__FILE__,line)(size == sizeof(len), "got %u\n", size); + ok_(__FILE__,line)(len == exlen, "len = %u, expected %u\n", len, exlen); } -START_TEST(bcrypt) +#define test_alg_name(a,b) _test_alg_name(__LINE__,a,b) +static void _test_alg_name(unsigned line, void *handle, const char *exname) +{ + ULONG size = 0xdeadbeef; + UCHAR buf[256]; + const WCHAR *name = (const WCHAR*)buf; + NTSTATUS status; + + status = BCryptGetProperty(handle, BCRYPT_ALGORITHM_NAME, buf, sizeof(buf), &size, 0); + ok_(__FILE__,line)(status == STATUS_SUCCESS, "BCryptGetProperty failed: %08x\n", status); + ok_(__FILE__,line)(size == (strlen(exname)+1)*sizeof(WCHAR), "got %u\n", size); + ok_(__FILE__,line)(!strcmp_wa(name, exname), "alg name = %s, expected %s\n", wine_dbgstr_w(name), exname); +} + +static void test_sha1(void) { - if (!Init()) - return; + static const char expected[] = "961fa64958818f767707072755d7018dcd278e94"; + BCRYPT_ALG_HANDLE alg; + BCRYPT_HASH_HANDLE hash; + UCHAR buf[512], sha1[20]; + ULONG size, len; + char str[41]; + NTSTATUS ret; + + alg = NULL; + ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(alg != NULL, "alg not set\n"); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(size == sizeof(len), "got %u\n", size); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0); + ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); + ok(len == 0xdeadbeef, "got %u\n", len); + ok(size == sizeof(len), "got %u\n", size); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(len != 0xdeadbeef, "len not set\n"); + ok(size == sizeof(len), "got %u\n", size); + + test_hash_length(alg, 20); + test_alg_name(alg, "SHA1"); + + hash = NULL; + len = sizeof(buf); + ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(hash != NULL, "hash not set\n"); + + ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + + test_hash_length(hash, 20); + test_alg_name(hash, "SHA1"); + + memset(sha1, 0, sizeof(sha1)); + ret = BCryptFinishHash(hash, sha1, sizeof(sha1), 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + format_hash( sha1, sizeof(sha1), str ); + ok(!strcmp(str, expected), "got %s\n", str); + + ret = BCryptDestroyHash(hash); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + + ret = BCryptCloseAlgorithmProvider(alg, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); +} + +static void test_sha256(void) +{ + static const char expected[] = + "ceb73749c899693706ede1e30c9929b3fd5dd926163831c2fb8bd41e6efb1126"; + BCRYPT_ALG_HANDLE alg; + BCRYPT_HASH_HANDLE hash; + UCHAR buf[512], sha256[32]; + ULONG size, len; + char str[65]; + NTSTATUS ret; + + alg = NULL; + ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA256_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(alg != NULL, "alg not set\n"); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(size == sizeof(len), "got %u\n", size); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0); + ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); + ok(len == 0xdeadbeef, "got %u\n", len); + ok(size == sizeof(len), "got %u\n", size); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(len != 0xdeadbeef, "len not set\n"); + ok(size == sizeof(len), "got %u\n", size); + + test_hash_length(alg, 32); + test_alg_name(alg, "SHA256"); + + hash = NULL; + len = sizeof(buf); + ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(hash != NULL, "hash not set\n"); + + ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + + test_hash_length(hash, 32); + test_alg_name(hash, "SHA256"); + + memset(sha256, 0, sizeof(sha256)); + ret = BCryptFinishHash(hash, sha256, sizeof(sha256), 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + format_hash( sha256, sizeof(sha256), str ); + ok(!strcmp(str, expected), "got %s\n", str); + + ret = BCryptDestroyHash(hash); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + + ret = BCryptCloseAlgorithmProvider(alg, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); +} + +static void test_sha384(void) +{ + static const char expected[] = + "62b21e90c9022b101671ba1f808f8631a8149f0f12904055839a35c1ca78ae5363eed1e743a692d70e0504b0cfd12ef9"; + BCRYPT_ALG_HANDLE alg; + BCRYPT_HASH_HANDLE hash; + UCHAR buf[512], sha384[48]; + ULONG size, len; + char str[97]; + NTSTATUS ret; + + alg = NULL; + ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA384_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(alg != NULL, "alg not set\n"); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(size == sizeof(len), "got %u\n", size); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0); + ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); + ok(len == 0xdeadbeef, "got %u\n", len); + ok(size == sizeof(len), "got %u\n", size); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(len != 0xdeadbeef, "len not set\n"); + ok(size == sizeof(len), "got %u\n", size); + + test_hash_length(alg, 48); + test_alg_name(alg, "SHA384"); + + hash = NULL; + len = sizeof(buf); + ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(hash != NULL, "hash not set\n"); + + ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + + test_hash_length(hash, 48); + test_alg_name(hash, "SHA384"); + + memset(sha384, 0, sizeof(sha384)); + ret = BCryptFinishHash(hash, sha384, sizeof(sha384), 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + format_hash( sha384, sizeof(sha384), str ); + ok(!strcmp(str, expected), "got %s\n", str); + + ret = BCryptDestroyHash(hash); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + + ret = BCryptCloseAlgorithmProvider(alg, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); +} + +static void test_sha512(void) +{ + static const char expected[] = + "d55ced17163bf5386f2cd9ff21d6fd7fe576a915065c24744d09cfae4ec84ee1e" + "f6ef11bfbc5acce3639bab725b50a1fe2c204f8c820d6d7db0df0ecbc49c5ca"; + BCRYPT_ALG_HANDLE alg; + BCRYPT_HASH_HANDLE hash; + UCHAR buf[512], sha512[64]; + ULONG size, len; + char str[129]; + NTSTATUS ret; + + alg = NULL; + ret = BCryptOpenAlgorithmProvider(&alg, BCRYPT_SHA512_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(alg != NULL, "alg not set\n"); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(NULL, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_INVALID_HANDLE, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, NULL, (UCHAR *)&len, sizeof(len), &size, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, sizeof(len), NULL, 0); + ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, NULL, sizeof(len), &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(size == sizeof(len), "got %u\n", size); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len, 0, &size, 0); + ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret); + ok(len == 0xdeadbeef, "got %u\n", len); + ok(size == sizeof(len), "got %u\n", size); + + len = size = 0xdeadbeef; + ret = BCryptGetProperty(alg, BCRYPT_OBJECT_LENGTH, (UCHAR *)&len , sizeof(len), &size, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(len != 0xdeadbeef, "len not set\n"); + ok(size == sizeof(len), "got %u\n", size); + + test_hash_length(alg, 64); + test_alg_name(alg, "SHA512"); + + hash = NULL; + len = sizeof(buf); + ret = BCryptCreateHash(alg, &hash, buf, len, NULL, 0, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + ok(hash != NULL, "hash not set\n"); + + ret = BCryptHashData(hash, (UCHAR *)"test", sizeof("test"), 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + + test_hash_length(hash, 64); + test_alg_name(hash, "SHA512"); + + memset(sha512, 0, sizeof(sha512)); + ret = BCryptFinishHash(hash, sha512, sizeof(sha512), 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + format_hash( sha512, sizeof(sha512), str ); + ok(!strcmp(str, expected), "got %s\n", str); + ret = BCryptDestroyHash(hash); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); + + ret = BCryptCloseAlgorithmProvider(alg, 0); + ok(ret == STATUS_SUCCESS, "got %08x\n", ret); +} + +START_TEST(bcrypt) +{ test_BCryptGenRandom(); test_BCryptGetFipsAlgorithmMode(); + test_sha1(); + test_sha256(); + test_sha384(); + test_sha512(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/bcrypt/tests/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/bcrypt/tests/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/bcrypt/tests/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/bcrypt/tests/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,5 +1,5 @@ TESTDLL = bcrypt.dll -IMPORTS = user32 +IMPORTS = bcrypt user32 C_SRCS = \ bcrypt.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/listview.c wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/listview.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/listview.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/listview.c 2016-02-08 19:32:34.000000000 +0000 @@ -8808,6 +8808,7 @@ if (infoPtr->dwStyle & LVS_OWNERDATA) { INT nOldCount = infoPtr->nItemCount; + infoPtr->nItemCount = nItems; if (nItems < nOldCount) { @@ -8820,7 +8821,6 @@ } } - infoPtr->nItemCount = nItems; LISTVIEW_UpdateScroll(infoPtr); /* the flags are valid only in ownerdata report and list modes */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/tests/listview.c wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/tests/listview.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/tests/listview.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/tests/listview.c 2016-02-08 19:32:34.000000000 +0000 @@ -198,7 +198,7 @@ { 0 } }; -static const struct message ownderdata_select_focus_parent_seq[] = { +static const struct message ownerdata_select_focus_parent_seq[] = { { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, { WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA }, { WM_NOTIFY, sent|id|optional, 0, 0, LVN_GETDISPINFOA }, /* version 4.7x */ @@ -3146,7 +3146,7 @@ res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); expect(TRUE, res); - ok_sequence(sequences, PARENT_SEQ_INDEX, ownderdata_select_focus_parent_seq, + ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_select_focus_parent_seq, "ownerdata select notification", TRUE); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -3157,7 +3157,7 @@ res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); expect(TRUE, res); - ok_sequence(sequences, PARENT_SEQ_INDEX, ownderdata_select_focus_parent_seq, + ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_select_focus_parent_seq, "ownerdata focus notification", TRUE); /* select all, check notifications */ @@ -3418,6 +3418,28 @@ style = GetWindowLongPtrA(hwnd, GWL_STYLE); ok(style & LVS_SORTDESCENDING, "Expected LVS_SORTDESCENDING to be set\n"); DestroyWindow(hwnd); + + /* The focused item is updated after the invalidation */ + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 3, 0); + expect(TRUE, res); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_FOCUSED; + item.state = LVIS_FOCUSED; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + expect(TRUE, res); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 0, 0); + expect(TRUE, res); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "ownerdata setitemcount", FALSE); + + res = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED); + expect(-1, res); + DestroyWindow(hwnd); } static void test_norecompute(void) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/tests/trackbar.c wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/tests/trackbar.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/tests/trackbar.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/tests/trackbar.c 2016-02-08 19:32:34.000000000 +0000 @@ -29,8 +29,19 @@ #define PARENT_SEQ_INDEX 0 #define TRACKBAR_SEQ_INDEX 1 +static const DWORD defaultstyle = WS_VISIBLE | TBS_TOOLTIPS | TBS_ENABLESELRANGE | TBS_FIXEDLENGTH | TBS_AUTOTICKS; static HWND hWndParent; +static LRESULT WINAPI trackbar_no_wmpaint_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + + if (message == WM_PAINT) + return 0; + + return CallWindowProcA(oldproc, hwnd, message, wParam, lParam); +} + static struct msg_sequence *sequences[NUM_MSG_SEQUENCE]; static const struct message empty_seq[] = { @@ -464,14 +475,27 @@ return hWndTrack; } +static HWND create_trackbar2(DWORD style, HWND parent) +{ + RECT rect; + GetClientRect(parent, &rect); + return CreateWindowA(TRACKBAR_CLASSA, "Trackbar Control", style, + rect.right, rect.bottom, 100, 50, + parent, NULL, GetModuleHandleA(NULL), NULL); +} + /* test functions for setters, getters, and sequences */ -static void test_trackbar_buddy(HWND hWndTrackbar){ - HWND hWndLeftBuddy; +static void test_trackbar_buddy(void) +{ + HWND hWndLeftBuddy, hWndTrackbar; HWND hWndRightBuddy; HWND hWndCurrentBuddy; HWND rTest; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); hWndLeftBuddy = CreateWindowA(STATUSCLASSNAMEA, NULL, 0, 0, 0, 300, 20, NULL, NULL, NULL, NULL); @@ -515,11 +539,17 @@ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, buddy_window_test_seq, "buddy test sequence", TRUE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_buddy_window_test_seq, "parent buddy test seq", TRUE); + DestroyWindow(hWndTrackbar); } -static void test_line_size(HWND hWndTrackbar){ +static void test_line_size(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); /* test TBM_SETLINESIZE */ @@ -534,12 +564,19 @@ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, line_size_test_seq, "linesize test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent line test sequence", FALSE); + + DestroyWindow(hWndTrackbar); } -static void test_page_size(HWND hWndTrackbar){ +static void test_page_size(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); /* test TBM_SETPAGESIZE */ @@ -570,12 +607,22 @@ expect(20, r); r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0); expect(-2, r); + + DestroyWindow(hWndTrackbar); } -static void test_position(HWND hWndTrackbar){ +static void test_position(void) +{ + HWND hWndTrackbar; + RECT rect, rect2; + WNDPROC oldproc; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* test TBM_SETPOS */ SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, -1); r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0); @@ -598,12 +645,55 @@ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, position_test_seq, "position test sequence", TRUE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_position_test_seq, "parent position test sequence", TRUE); + + DestroyWindow(hWndTrackbar); + + hWndTrackbar = create_trackbar2(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + + /* subclassing procedure blocks WM_PAINT */ + oldproc = (WNDPROC)SetWindowLongPtrA(hWndTrackbar, GWLP_WNDPROC, (LONG_PTR)trackbar_no_wmpaint_proc); + SetWindowLongPtrA(hWndTrackbar, GWLP_USERDATA, (LONG_PTR)oldproc); + + memset(&rect, 0, sizeof(rect)); + memset(&rect2, 0, sizeof(rect2)); + + SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect); + + /* without repaint */ + SendMessageA(hWndTrackbar, TBM_SETPOS, FALSE, 25); + r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0); + ok(r == 25, "got %d\n", r); + SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect2); + ok(rect.left == rect2.left, "got %d\n", rect.left); + + /* with repaint */ + SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, 30); + r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0); + ok(r == 30, "got %d\n", r); + SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect2); + ok(rect.left != rect2.left, "got %d, expected %d\n", rect2.left, rect.left); + + /* now move it with keys */ + SendMessageA(hWndTrackbar, WM_KEYDOWN, VK_END, 0); + r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0); + ok(r == 100, "got %d\n", r); + SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect); + ok(rect.left != rect2.left, "got %d, expected %d\n", rect.left, rect2.left); + + DestroyWindow(hWndTrackbar); } -static void test_range(HWND hWndTrackbar){ +static void test_range(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* test TBM_SETRANGE */ SendMessageA(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(0, 10)); r = SendMessageA(hWndTrackbar, TBM_GETRANGEMAX, 0,0); @@ -661,12 +751,23 @@ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, range_test_seq, "range test sequence", TRUE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_range_test_seq, "parent range test sequence", TRUE); + + DestroyWindow(hWndTrackbar); } -static void test_selection(HWND hWndTrackbar){ +static void test_selection(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + + SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, FALSE, 5); + SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 10); + flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* test TBM_SETSEL */ SendMessageA(hWndTrackbar, TBM_SETSEL, TRUE, MAKELONG(0,10)); r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0); @@ -722,12 +823,20 @@ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, selection_test_seq, "selection test sequence", TRUE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_selection_test_seq, "parent selection test sequence", TRUE); + + DestroyWindow(hWndTrackbar); } -static void test_thumb_length(HWND hWndTrackbar){ +static void test_thumb_length(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* testing TBM_SETTHUMBLENGTH */ SendMessageA(hWndTrackbar, TBM_SETTHUMBLENGTH, 15, 0); r = SendMessageA(hWndTrackbar, TBM_GETTHUMBLENGTH, 0,0); @@ -751,11 +860,21 @@ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, thumb_length_test_seq, "thumb length test sequence", TRUE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_thumb_length_test_seq, "parent thumb length test sequence", TRUE); + + DestroyWindow(hWndTrackbar); } -static void test_tic_settings(HWND hWndTrackbar){ +static void test_tic_settings(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + + SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, FALSE, 5); + SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 10); + /* testing TBM_SETTIC */ /* Set tics at 5 and 10 */ /* 0 and 20 are out of range and should not be set */ @@ -815,11 +934,16 @@ expect(3, r); } -static void test_tic_placement(HWND hWndTrackbar){ +static void test_tic_placement(void) +{ + HWND hWndTrackbar; int r; DWORD *rPTics; DWORD numtics; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + SendMessageA(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(1, 6)); SendMessageA(hWndTrackbar, TBM_SETTICFREQ, 1, 0); @@ -850,15 +974,21 @@ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, tic_placement_test_seq, "get tic placement test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent get tic placement test sequence", FALSE); -} + DestroyWindow(hWndTrackbar); +} -static void test_tool_tips(HWND hWndTrackbar){ - int r; - HWND hWndTooltip; +static void test_tool_tips(void) +{ + HWND hWndTooltip, hWndTrackbar; HWND rTest; + int r; + + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* testing TBM_SETTIPSIDE */ r = SendMessageA(hWndTrackbar, TBM_SETTIPSIDE, TBTS_TOP, 0); expect(TBTS_TOP, r); @@ -894,13 +1024,21 @@ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, tool_tips_test_seq, "tool tips test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent tool tips test sequence", FALSE); + + DestroyWindow(hWndTrackbar); } -static void test_unicode(HWND hWndTrackbar){ +static void test_unicode(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* testing TBM_SETUNICODEFORMAT */ r = SendMessageA(hWndTrackbar, TBM_SETUNICODEFORMAT, TRUE, 0); ok(r == FALSE, "Expected FALSE, got %d\n",r); @@ -913,11 +1051,18 @@ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, unicode_test_seq, "unicode test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent unicode test sequence", FALSE); + + DestroyWindow(hWndTrackbar); } -static void test_ignore_selection(HWND hWndTrackbar){ +static void test_ignore_selection(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(0, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); /* test TBM_SETSEL ensure that it is ignored */ SendMessageA(hWndTrackbar, TBM_SETSEL, TRUE, MAKELONG(0,10)); @@ -955,6 +1100,8 @@ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, ignore_selection_test_seq, "ignore selection setting test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent ignore selection setting test sequence", FALSE); + + DestroyWindow(hWndTrackbar); } static void test_initial_state(void) @@ -1034,72 +1181,55 @@ DestroyWindow(hWnd); } -START_TEST(trackbar) +static void test_create(void) { - DWORD style = WS_VISIBLE | TBS_TOOLTIPS | TBS_ENABLESELRANGE | TBS_FIXEDLENGTH | TBS_AUTOTICKS; HWND hWndTrackbar; - init_msg_sequences(sequences, NUM_MSG_SEQUENCE); - InitCommonControls(); - - /* create parent window */ - hWndParent = create_parent_window(); - ok(hWndParent != NULL, "Failed to create parent Window!\n"); - - if(!hWndParent){ - skip("parent window not present\n"); - return; - } - flush_sequences(sequences, NUM_MSG_SEQUENCE); - /* create trackbar with set styles */ - hWndTrackbar = create_trackbar(style, hWndParent); - + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); ok(hWndTrackbar != NULL, "Expected non NULL value\n"); - - if (!hWndTrackbar){ - skip("trackbar control not present?\n"); - return; - } - ok_sequence(sequences, TRACKBAR_SEQ_INDEX, empty_seq, "create Trackbar Window", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_create_trackbar_wnd_seq, "parent trackbar window", TRUE); - flush_sequences(sequences, NUM_MSG_SEQUENCE); - /* TEST OF ALL SETTER and GETTER MESSAGES with required styles turned on*/ - test_trackbar_buddy(hWndTrackbar); - test_line_size(hWndTrackbar); - test_page_size(hWndTrackbar); - test_position(hWndTrackbar); - test_range(hWndTrackbar); - test_selection(hWndTrackbar); - test_thumb_length(hWndTrackbar); - test_tic_settings(hWndTrackbar); - test_tic_placement(hWndTrackbar); - test_tool_tips(hWndTrackbar); - test_unicode(hWndTrackbar); - test_TBS_AUTOTICKS(); + DestroyWindow(hWndTrackbar); + /* no style bits */ flush_sequences(sequences, NUM_MSG_SEQUENCE); + hWndTrackbar = create_trackbar(0, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + ok_sequence(sequences, PARENT_SEQ_INDEX, parent_new_window_test_seq, "new trackbar window test sequence", TRUE); DestroyWindow(hWndTrackbar); +} - /* test getters and setters without styles set */ - hWndTrackbar = create_trackbar(0, hWndParent); +START_TEST(trackbar) +{ + init_msg_sequences(sequences, NUM_MSG_SEQUENCE); + InitCommonControls(); - ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + /* create parent window */ + hWndParent = create_parent_window(); + ok(hWndParent != NULL, "Failed to create parent Window!\n"); - if (!hWndTrackbar){ - skip("trackbar control not present?\n"); + if(!hWndParent){ + skip("parent window not present\n"); return; } - ok_sequence(sequences, PARENT_SEQ_INDEX, parent_new_window_test_seq, "new trackbar window test sequence", TRUE); - - test_ignore_selection(hWndTrackbar); - - DestroyWindow(hWndTrackbar); - + test_create(); + test_trackbar_buddy(); + test_line_size(); + test_page_size(); + test_position(); + test_range(); + test_selection(); + test_thumb_length(); + test_tic_settings(); + test_tic_placement(); + test_tool_tips(); + test_unicode(); + test_TBS_AUTOTICKS(); + test_ignore_selection(); test_initial_state(); DestroyWindow(hWndParent); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/tests/treeview.c wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/tests/treeview.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/tests/treeview.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/tests/treeview.c 2016-02-08 19:32:34.000000000 +0000 @@ -1878,8 +1878,13 @@ { const struct message *msg; HWND hTree; + HTREEITEM hItem1, hItem2; + TVINSERTSTRUCTA ins; INT ret; + static CHAR item1[] = "Item 1"; + static CHAR item2[] = "Item 2"; + hTree = create_treeview_control(0); fill_tree(hTree); @@ -1901,6 +1906,34 @@ ok(ret == 0, "got %d\n", ret); DestroyWindow(hTree); + + /* Regression test for a crash when deleting the first visible item while bRedraw == false. */ + hTree = create_treeview_control(0); + + ins.hParent = TVI_ROOT; + ins.hInsertAfter = TVI_ROOT; + U(ins).item.mask = TVIF_TEXT; + U(ins).item.pszText = item1; + hItem1 = TreeView_InsertItemA(hTree, &ins); + ok(hItem1 != NULL, "InsertItem failed\n"); + + ins.hParent = TVI_ROOT; + ins.hInsertAfter = hItem1; + U(ins).item.mask = TVIF_TEXT; + U(ins).item.pszText = item2; + hItem2 = TreeView_InsertItemA(hTree, &ins); + ok(hItem2 != NULL, "InsertItem failed\n"); + + ret = SendMessageA(hTree, WM_SETREDRAW, FALSE, 0); + ok(ret == 0, "got %d\n", ret); + + ret = SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hItem1); + ok(ret == TRUE, "got %d\n", ret); + + ret = SendMessageA(hTree, WM_SETREDRAW, TRUE, 0); + ok(ret == 0, "got %d\n", ret); + + DestroyWindow(hTree); } static void test_cchildren(void) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/toolbar.c wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/toolbar.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/toolbar.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/toolbar.c 2016-02-08 19:32:34.000000000 +0000 @@ -6807,6 +6807,7 @@ return TOOLBAR_MouseLeave (infoPtr); case WM_CAPTURECHANGED: + if (hwnd == (HWND)lParam) return 0; return TOOLBAR_CaptureChanged(infoPtr); case WM_NCACTIVATE: diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/trackbar.c wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/trackbar.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/trackbar.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/trackbar.c 2016-02-08 19:32:34.000000000 +0000 @@ -1229,9 +1229,12 @@ if (infoPtr->lPos > infoPtr->lRangeMax) infoPtr->lPos = infoPtr->lRangeMax; - infoPtr->flags |= TB_THUMBPOSCHANGED; - if (fPosition && oldPos != lPosition) TRACKBAR_InvalidateThumbMove(infoPtr, oldPos, lPosition); + if (fPosition && oldPos != lPosition) + { + TRACKBAR_UpdateThumb(infoPtr); + TRACKBAR_InvalidateThumbMove(infoPtr, oldPos, lPosition); + } return 0; } @@ -1818,7 +1821,7 @@ } if (pos != infoPtr->lPos) { - infoPtr->flags |=TB_THUMBPOSCHANGED; + TRACKBAR_UpdateThumb (infoPtr); TRACKBAR_InvalidateThumbMove (infoPtr, pos, infoPtr->lPos); } @@ -1976,6 +1979,7 @@ case WM_CAPTURECHANGED: + if (hwnd == (HWND)lParam) return 0; return TRACKBAR_CaptureChanged (infoPtr); case WM_CREATE: diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/treeview.c wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/treeview.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/comctl32/treeview.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/comctl32/treeview.c 2016-02-08 19:32:34.000000000 +0000 @@ -96,7 +96,7 @@ HTREEITEM focusedItem; /* item that was under the cursor when WM_LBUTTONDOWN was received */ HTREEITEM editItem; /* item being edited with builtin edit box */ - HTREEITEM firstVisible; /* handle to first visible item */ + HTREEITEM firstVisible; /* handle to item whose top edge is at y = 0 */ LONG maxVisibleOrder; HTREEITEM dropItem; /* handle to item selected by drag cursor */ HTREEITEM insertMarkItem; /* item after which insertion mark is placed */ @@ -162,7 +162,10 @@ LONG imageOffset; LONG textOffset; LONG textWidth; /* horizontal text extent for pszText */ - LONG visibleOrder; /* visible ordering, 0 is first visible item */ + LONG visibleOrder; /* Depth-first numbering of the items whose ancestors are all expanded, + corresponding to a top-to-bottom ordering in the tree view. + Each item takes up "item.iIntegral" spots in the visible order. + 0 is the root's first child. */ const TREEVIEW_INFO *infoPtr; /* tree data this item belongs to */ } TREEVIEW_ITEM; @@ -1577,11 +1580,13 @@ TREEVIEW_VerifyTree(infoPtr); + if (visible) + TREEVIEW_SetFirstVisible(infoPtr, newFirstVisible, TRUE); + if (!infoPtr->bRedraw) return TRUE; if (visible) { - TREEVIEW_SetFirstVisible(infoPtr, newFirstVisible, TRUE); TREEVIEW_RecalculateVisibleOrder(infoPtr, prev); TREEVIEW_UpdateScrollBars(infoPtr); TREEVIEW_Invalidate(infoPtr, NULL); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/comdlg32/itemdlg.c wine-staging-1.9.3~ubuntu12.04.1/dlls/comdlg32/itemdlg.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/comdlg32/itemdlg.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/comdlg32/itemdlg.c 2016-02-08 19:32:34.000000000 +0000 @@ -370,13 +370,13 @@ lstrcpyW(*str, This->set_filename); return len; } - return FALSE; + return 0; } len = SendMessageW(hwnd_edit, WM_GETTEXTLENGTH, 0, 0); *str = CoTaskMemAlloc(sizeof(WCHAR)*(len+1)); if(!*str) - return FALSE; + return 0; SendMessageW(hwnd_edit, WM_GETTEXT, len+1, (LPARAM)*str); return len; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/comdlg32/printdlg.c wine-staging-1.9.3~ubuntu12.04.1/dlls/comdlg32/printdlg.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/comdlg32/printdlg.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/comdlg32/printdlg.c 2016-02-08 19:32:34.000000000 +0000 @@ -4126,7 +4126,7 @@ hr = E_FAIL; lppd->hDevMode = update_devmode_handleA(lppd->hDevMode, dm); - if (!hr && lppd->hDevMode) { + if (hr == S_OK && lppd->hDevMode) { if (lppd->Flags & PD_RETURNDC) { lppd->hDC = CreateDCA(dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, dm); if (!lppd->hDC) @@ -4274,7 +4274,7 @@ hr = E_FAIL; lppd->hDevMode = update_devmode_handleW(lppd->hDevMode, dm); - if (!hr && lppd->hDevMode) { + if (hr == S_OK && lppd->hDevMode) { if (lppd->Flags & PD_RETURNDC) { lppd->hDC = CreateDCW(dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, dm); if (!lppd->hDC) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/commdlg.dll16/colordlg.c wine-staging-1.9.3~ubuntu12.04.1/dlls/commdlg.dll16/colordlg.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/commdlg.dll16/colordlg.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/commdlg.dll16/colordlg.c 2016-02-08 19:32:34.000000000 +0000 @@ -62,6 +62,9 @@ cc32.lpCustColors = MapSL( cc16->lpCustColors ); cc32.Flags = cc16->Flags & ~(CC_ENABLETEMPLATE | CC_ENABLETEMPLATEHANDLE | CC_ENABLEHOOK); cc32.lCustData = cc16->lCustData; + cc32.hInstance = NULL; + cc32.lpfnHook = NULL; + cc32.lpTemplateName = NULL; if (cc16->Flags & (CC_ENABLETEMPLATE | CC_ENABLETEMPLATEHANDLE)) FIXME( "custom templates no longer supported, using default\n" ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/crtdll/crtdll.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/crtdll/crtdll.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/crtdll/crtdll.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/crtdll/crtdll.spec 2016-02-08 19:32:34.000000000 +0000 @@ -346,7 +346,7 @@ @ cdecl asin(double) msvcrt.asin @ cdecl atan(double) msvcrt.atan @ cdecl atan2(double double) msvcrt.atan2 -@ cdecl atexit(ptr) msvcrt.atexit +@ cdecl -private atexit(ptr) msvcrt.atexit @ cdecl atof(str) msvcrt.atof @ cdecl atoi(str) msvcrt.atoi @ cdecl atol(str) msvcrt.atol diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/crypt32/chain.c wine-staging-1.9.3~ubuntu12.04.1/dlls/crypt32/chain.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/crypt32/chain.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/crypt32/chain.c 2016-02-08 19:32:34.000000000 +0000 @@ -2293,7 +2293,10 @@ chain->context.dwRevocationFreshnessTime = 0; } else + { + CRYPT_FreeSimpleChain(simpleChain); ret = FALSE; + } *ppChain = chain; } return ret; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ctl3d32/ctl3d32.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ctl3d32/ctl3d32.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ctl3d32/ctl3d32.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ctl3d32/ctl3d32.c 2016-02-08 19:32:34.000000000 +0000 @@ -75,7 +75,7 @@ BOOL WINAPI Ctl3dRegister(HINSTANCE hInst) { - return FALSE; + return TRUE; } BOOL WINAPI Ctl3dSubclassCtl(HWND hwnd) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d2d1/render_target.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d2d1/render_target.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d2d1/render_target.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d2d1/render_target.c 2016-02-08 19:32:34.000000000 +0000 @@ -32,6 +32,17 @@ D2D1_DRAW_TEXT_OPTIONS options; }; +static ID2D1Brush *d2d_draw_get_text_brush(struct d2d_draw_text_layout_ctx *context, IUnknown *effect) +{ + ID2D1Brush *brush = NULL; + + if (effect && SUCCEEDED(IUnknown_QueryInterface(effect, &IID_ID2D1Brush, (void**)&brush))) + return brush; + + ID2D1Brush_AddRef(context->brush); + return context->brush; +} + static void d2d_point_set(D2D1_POINT_2F *dst, float x, float y) { dst->x = x; @@ -888,6 +899,7 @@ const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode) { + struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface); IDWriteTextLayout *text_layout; IDWriteFactory *dwrite_factory; D2D1_POINT_2F origin; @@ -898,9 +910,6 @@ iface, debugstr_wn(string, string_len), string_len, text_format, layout_rect, brush, options, measuring_mode); - if (measuring_mode != DWRITE_MEASURING_MODE_NATURAL) - FIXME("Ignoring measuring mode %#x.\n", measuring_mode); - if (FAILED(hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown **)&dwrite_factory))) { @@ -908,8 +917,13 @@ return; } - hr = IDWriteFactory_CreateTextLayout(dwrite_factory, string, string_len, text_format, - layout_rect->right - layout_rect->left, layout_rect->bottom - layout_rect->top, &text_layout); + if (measuring_mode == DWRITE_MEASURING_MODE_NATURAL) + hr = IDWriteFactory_CreateTextLayout(dwrite_factory, string, string_len, text_format, + layout_rect->right - layout_rect->left, layout_rect->bottom - layout_rect->top, &text_layout); + else + hr = IDWriteFactory_CreateGdiCompatibleTextLayout(dwrite_factory, string, string_len, text_format, + layout_rect->right - layout_rect->left, layout_rect->bottom - layout_rect->top, render_target->dpi_x / 96.0f, + (DWRITE_MATRIX*)&render_target->drawing_state.transform, measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, &text_layout); IDWriteFactory_Release(dwrite_factory); if (FAILED(hr)) { @@ -1436,6 +1450,8 @@ dpi_x = 96.0f; dpi_y = 96.0f; } + else if (dpi_x <= 0.0f || dpi_y <= 0.0f) + return; render_target->dpi_x = dpi_x; render_target->dpi_y = dpi_y; @@ -1633,6 +1649,7 @@ struct d2d_d3d_render_target *render_target = impl_from_IDWriteTextRenderer(iface); D2D1_POINT_2F baseline_origin = {baseline_origin_x, baseline_origin_y}; struct d2d_draw_text_layout_ctx *context = ctx; + ID2D1Brush *brush; TRACE("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, " "measuring_mode %#x, glyph_run %p, desc %p, effect %p.\n", @@ -1641,14 +1658,16 @@ if (desc) WARN("Ignoring glyph run description %p.\n", desc); - if (effect) - FIXME("Ignoring effect %p.\n", effect); if (context->options & ~D2D1_DRAW_TEXT_OPTIONS_NO_SNAP) FIXME("Ignoring options %#x.\n", context->options); + brush = d2d_draw_get_text_brush(context, effect); + TRACE("%s\n", debugstr_wn(desc->string, desc->stringLength)); ID2D1RenderTarget_DrawGlyphRun(&render_target->ID2D1RenderTarget_iface, - baseline_origin, glyph_run, context->brush, measuring_mode); + baseline_origin, glyph_run, brush, measuring_mode); + + ID2D1Brush_Release(brush); return S_OK; } @@ -1656,10 +1675,31 @@ static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawUnderline(IDWriteTextRenderer *iface, void *ctx, float baseline_origin_x, float baseline_origin_y, const DWRITE_UNDERLINE *underline, IUnknown *effect) { - FIXME("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, underline %p, effect %p stub!\n", + struct d2d_d3d_render_target *render_target = impl_from_IDWriteTextRenderer(iface); + const D2D1_MATRIX_3X2_F *m = &render_target->drawing_state.transform; + struct d2d_draw_text_layout_ctx *context = ctx; + float min_thickness; + ID2D1Brush *brush; + D2D1_RECT_F rect; + + TRACE("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, underline %p, effect %p\n", iface, ctx, baseline_origin_x, baseline_origin_y, underline, effect); - return E_NOTIMPL; + /* minimal thickness in DIPs that will result in at least 1 pixel thick line */ + min_thickness = 96.0f / (render_target->dpi_y * sqrtf(m->_21 * m->_21 + m->_22 * m->_22)); + + rect.left = baseline_origin_x; + rect.top = baseline_origin_y + underline->offset; + rect.right = baseline_origin_x + underline->width; + rect.bottom = baseline_origin_y + underline->offset + max(underline->thickness, min_thickness); + + brush = d2d_draw_get_text_brush(context, effect); + + ID2D1RenderTarget_FillRectangle(&render_target->ID2D1RenderTarget_iface, &rect, brush); + + ID2D1Brush_Release(brush); + + return S_OK; } static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawStrikethrough(IDWriteTextRenderer *iface, void *ctx, @@ -2033,6 +2073,18 @@ 0.0f, 1.0f, 0.0f, 0.0f, }; + float dpi_x, dpi_y; + + dpi_x = desc->dpiX; + dpi_y = desc->dpiY; + + if (dpi_x == 0.0f && dpi_y == 0.0f) + { + dpi_x = 96.0f; + dpi_y = 96.0f; + } + else if (dpi_x <= 0.0f || dpi_y <= 0.0f) + return E_INVALIDARG; if (desc->type != D2D1_RENDER_TARGET_TYPE_DEFAULT && desc->type != D2D1_RENDER_TARGET_TYPE_HARDWARE) WARN("Ignoring render target type %#x.\n", desc->type); @@ -2223,14 +2275,8 @@ goto err; } - render_target->dpi_x = desc->dpiX; - render_target->dpi_y = desc->dpiY; - - if (render_target->dpi_x == 0.0f && render_target->dpi_y == 0.0f) - { - render_target->dpi_x = 96.0f; - render_target->dpi_y = 96.0f; - } + render_target->dpi_x = dpi_x; + render_target->dpi_y = dpi_y; return S_OK; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d2d1/tests/d2d1.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d2d1/tests/d2d1.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d2d1/tests/d2d1.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d2d1/tests/d2d1.c 2016-02-08 19:32:34.000000000 +0000 @@ -587,6 +587,29 @@ ok(dpi_x == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_x); ok(dpi_y == 96.0f, "Got unexpected dpi_y %.8e.\n", dpi_y); + ID2D1RenderTarget_SetDpi(rt, 192.0f, 192.0f); + ID2D1RenderTarget_SetDpi(rt, 0.0f, 96.0f); + ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y); + ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x); + ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y); + + ID2D1RenderTarget_SetDpi(rt, -10.0f, 96.0f); + ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y); + ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x); + ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y); + + ID2D1RenderTarget_SetDpi(rt, 96.0f, -10.0f); + ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y); + ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x); + ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y); + + ID2D1RenderTarget_SetDpi(rt, 96.0f, 0.0f); + ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y); + ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x); + ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y); + + ID2D1RenderTarget_SetDpi(rt, 96.0f, 96.0f); + /* Transformations apply to clip rects, the effective clip rect is the * (axis-aligned) bounding box of the transformed clip rect. */ set_point(&point, 320.0f, 240.0f); @@ -2428,6 +2451,181 @@ DestroyWindow(window); } +static void test_create_target(void) +{ + IDXGISwapChain *swapchain; + ID2D1Factory *factory; + ID2D1RenderTarget *rt; + ID3D10Device1 *device; + IDXGISurface *surface; + HWND window; + HRESULT hr; + static const struct + { + float dpi_x, dpi_y; + float rt_dpi_x, rt_dpi_y; + HRESULT hr; + } + create_dpi_tests[] = + { + { 0.0f, 0.0f, 96.0f, 96.0f, S_OK }, + { 192.0f, 0.0f, 96.0f, 96.0f, E_INVALIDARG }, + { 0.0f, 192.0f, 96.0f, 96.0f, E_INVALIDARG }, + { 192.0f, -10.0f, 96.0f, 96.0f, E_INVALIDARG }, + { -10.0f, 192.0f, 96.0f, 96.0f, E_INVALIDARG }, + { 48.0f, 96.0f, 48.0f, 96.0f, S_OK }, + }; + unsigned int i; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + window = CreateWindowA("static", "d2d1_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + swapchain = create_swapchain(device, window, TRUE); + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface); + ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr); + + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + + for (i = 0; i < sizeof(create_dpi_tests) / sizeof(*create_dpi_tests); ++i) + { + D2D1_RENDER_TARGET_PROPERTIES desc; + float dpi_x, dpi_y; + + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = create_dpi_tests[i].dpi_x; + desc.dpiY = create_dpi_tests[i].dpi_y; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, &desc, &rt); + ok(hr == create_dpi_tests[i].hr, "Wrong return code, hr %#x, expected %#x, test %u.\n", hr, + create_dpi_tests[i].hr, i); + + if (FAILED(hr)) + continue; + + ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y); + ok(dpi_x == create_dpi_tests[i].rt_dpi_x, "Wrong dpi_x %.8e, expected %.8e, test %u\n", + dpi_x, create_dpi_tests[i].rt_dpi_x, i); + ok(dpi_y == create_dpi_tests[i].rt_dpi_y, "Wrong dpi_y %.8e, expected %.8e, test %u\n", + dpi_y, create_dpi_tests[i].rt_dpi_y, i); + + ID2D1RenderTarget_Release(rt); + } + + ID2D1Factory_Release(factory); + IDXGISurface_Release(surface); + IDXGISwapChain_Release(swapchain); + ID3D10Device1_Release(device); + DestroyWindow(window); +} + +static void test_draw_text_layout(void) +{ + static const WCHAR tahomaW[] = {'T','a','h','o','m','a',0}; + static const WCHAR textW[] = {'t','e','x','t',0}; + static const WCHAR emptyW[] = {0}; + D2D1_RENDER_TARGET_PROPERTIES desc; + IDXGISwapChain *swapchain; + ID2D1Factory *factory, *factory2; + ID2D1RenderTarget *rt, *rt2; + ID3D10Device1 *device; + IDXGISurface *surface; + HWND window; + HRESULT hr; + IDWriteFactory *dwrite_factory; + IDWriteTextFormat *text_format; + IDWriteTextLayout *text_layout; + D2D1_POINT_2F origin; + DWRITE_TEXT_RANGE range; + D2D1_COLOR_F color; + ID2D1SolidColorBrush *brush, *brush2; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + window = CreateWindowA("static", "d2d1_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + swapchain = create_swapchain(device, window, TRUE); + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface); + ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr); + + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory2); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + ok(factory != factory2, "got same factory\n"); + + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = 0.0f; + desc.dpiY = 0.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, &desc, &rt); + ok(SUCCEEDED(hr), "Failed to create a target, hr %#x.\n", hr); + + hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory2, surface, &desc, &rt2); + ok(SUCCEEDED(hr), "Failed to create a target, hr %#x.\n", hr); + + hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown **)&dwrite_factory); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + + hr = IDWriteFactory_CreateTextFormat(dwrite_factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, 10.0f, emptyW, &text_format); + ok(SUCCEEDED(hr), "Failed to create text format, hr %#x.\n", hr); + + hr = IDWriteFactory_CreateTextLayout(dwrite_factory, textW, 4, text_format, 100.0f, 100.0f, &text_layout); + ok(SUCCEEDED(hr), "Failed to create text layout, hr %#x.\n", hr); + + set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f); + hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush); + ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr); + + hr = ID2D1RenderTarget_CreateSolidColorBrush(rt2, &color, NULL, &brush2); + ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr); + + /* effect brush is created from different factory */ + range.startPosition = 0; + range.length = 4; + hr = IDWriteTextLayout_SetDrawingEffect(text_layout, (IUnknown*)brush2, range); + ok(SUCCEEDED(hr), "Failed to set drawing effect, hr %#x.\n", hr); + + ID2D1RenderTarget_BeginDraw(rt); + + origin.x = origin.y = 0.0f; + ID2D1RenderTarget_DrawTextLayout(rt, origin, text_layout, (ID2D1Brush*)brush, D2D1_DRAW_TEXT_OPTIONS_NONE); + + hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL); +todo_wine + ok(hr == D2DERR_WRONG_FACTORY, "EndDraw failure expected, hr %#x.\n", hr); + + IDWriteTextFormat_Release(text_format); + IDWriteTextLayout_Release(text_layout); + IDWriteFactory_Release(dwrite_factory); + ID2D1RenderTarget_Release(rt); + ID2D1RenderTarget_Release(rt2); + + ID2D1Factory_Release(factory); + ID2D1Factory_Release(factory2); + IDXGISurface_Release(surface); + IDXGISwapChain_Release(swapchain); + ID3D10Device1_Release(device); + DestroyWindow(window); +} + START_TEST(d2d1) { test_clip(); @@ -2440,4 +2638,6 @@ test_shared_bitmap(); test_bitmap_updates(); test_opacity_brush(); + test_create_target(); + test_draw_text_layout(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d10core/tests/device.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d10core/tests/device.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d10core/tests/device.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d10core/tests/device.c 2016-02-08 19:32:34.000000000 +0000 @@ -305,6 +305,7 @@ ID3D10Device *device, *tmp; D3D10_TEXTURE2D_DESC desc; ID3D10Texture2D *texture; + UINT quality_level_count; IDXGISurface *surface; HRESULT hr; @@ -389,6 +390,25 @@ if (SUCCEEDED(hr)) IDXGISurface_Release(surface); ID3D10Texture2D_Release(texture); + ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 2, &quality_level_count); + desc.ArraySize = 1; + desc.SampleDesc.Count = 2; + hr = ID3D10Device_CreateTexture2D(device, &desc, NULL, &texture); + if (quality_level_count) + { + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ID3D10Texture2D_Release(texture); + desc.SampleDesc.Quality = quality_level_count; + hr = ID3D10Device_CreateTexture2D(device, &desc, NULL, &texture); + } + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + /* We assume 15 samples multisampling is never supported in practice. */ + desc.SampleDesc.Count = 15; + desc.SampleDesc.Quality = 0; + hr = ID3D10Device_CreateTexture2D(device, &desc, NULL, &texture); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + refcount = ID3D10Device_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); } @@ -3228,33 +3248,50 @@ static void test_texture(void) { - ID3D10RenderTargetView *backbuffer_rtv; + struct shader + { + const DWORD *code; + size_t size; + }; + struct texture + { + UINT width; + UINT height; + UINT miplevel_count; + DXGI_FORMAT format; + D3D10_SUBRESOURCE_DATA data[3]; + }; + D3D10_SUBRESOURCE_DATA resource_data; + const struct texture *current_texture; D3D10_TEXTURE2D_DESC texture_desc; - ID3D10SamplerState *sampler_state; - ID3D10ShaderResourceView *ps_srv; D3D10_SAMPLER_DESC sampler_desc; ID3D10InputLayout *input_layout; + const struct shader *current_ps; + ID3D10ShaderResourceView *srv; D3D10_BUFFER_DESC buffer_desc; ID3D10Texture2D *backbuffer; + ID3D10RenderTargetView *rtv; + ID3D10SamplerState *sampler; unsigned int stride, offset; struct texture_readback rb; IDXGISwapChain *swapchain; ID3D10Texture2D *texture; ID3D10VertexShader *vs; ID3D10PixelShader *ps; + ID3D10Buffer *vb, *cb; ID3D10Device *device; + unsigned int i, x, y; + struct vec4 miplevel; D3D10_VIEWPORT vp; - unsigned int i, j; - ID3D10Buffer *vb; ULONG refcount; - DWORD color; HWND window; + DWORD color; HRESULT hr; static const D3D10_INPUT_ELEMENT_DESC layout_desc[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, }; static const DWORD vs_code[] = { @@ -3272,7 +3309,107 @@ 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, }; - static const DWORD ps_code[] = + static const DWORD ps_ld_code[] = + { +#if 0 + Texture2D t; + + float miplevel; + + float4 main(float4 position : SV_POSITION) : SV_TARGET + { + float3 p; + t.GetDimensions(miplevel, p.x, p.y, p.z); + p.z = miplevel; + p *= float3(position.x / 640.0f, position.y / 480.0f, 1.0f); + return t.Load(int3(p)); + } +#endif + 0x43425844, 0xbdda6bdf, 0xc6ffcdf1, 0xa58596b3, 0x822383f0, 0x00000001, 0x000001ac, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000110, 0x00000040, + 0x00000044, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04001858, 0x00107000, 0x00000000, + 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, + 0x02000068, 0x00000001, 0x0600001c, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, + 0x0700003d, 0x001000f2, 0x00000000, 0x0010000a, 0x00000000, 0x00107e46, 0x00000000, 0x07000038, + 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00101046, 0x00000000, 0x06000036, 0x001000c2, + 0x00000000, 0x00208006, 0x00000000, 0x00000000, 0x0a000038, 0x001000f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x3f800000, 0x3f800000, 0x0500001b, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000000, 0x0700002d, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00107e46, 0x00000000, 0x0100003e, + }; + static const DWORD ps_ld_sint8_code[] = + { +#if 0 + Texture2D t; + + float4 main(float4 position : SV_POSITION) : SV_TARGET + { + float3 p, s; + int4 c; + + p = float3(position.x / 640.0f, position.y / 480.0f, 0.0f); + t.GetDimensions(0, s.x, s.y, s.z); + p *= s; + + c = t.Load(int3(p)); + return (max(c / (float4)127, (float4)-1) + (float4)1) / 2.0f; + } +#endif + 0x43425844, 0xb3d0b0fc, 0x0e486f4a, 0xf67eec12, 0xfb9dd52f, 0x00000001, 0x00000240, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x000001a4, 0x00000040, + 0x00000069, 0x04001858, 0x00107000, 0x00000000, 0x00003333, 0x04002064, 0x00101032, 0x00000000, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0700003d, 0x001000f2, + 0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000000, 0x0a000038, 0x00100032, 0x00000001, + 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x08000036, + 0x001000c2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07000038, + 0x001000f2, 0x00000000, 0x00100f46, 0x00000000, 0x00100e46, 0x00000001, 0x0500001b, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000000, 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00107e46, 0x00000000, 0x0500002b, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x0a000038, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x3c010204, 0x3c010204, 0x3c010204, + 0x3c010204, 0x0a000034, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0xbf800000, + 0xbf800000, 0xbf800000, 0xbf800000, 0x0a000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0a000038, 0x001020f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x0100003e, + }; + static const DWORD ps_ld_uint8_code[] = + { +#if 0 + Texture2D t; + + float4 main(float4 position : SV_POSITION) : SV_TARGET + { + float3 p, s; + + p = float3(position.x / 640.0f, position.y / 480.0f, 0.0f); + t.GetDimensions(0, s.x, s.y, s.z); + p *= s; + + return t.Load(int3(p)) / (float4)255; + } +#endif + 0x43425844, 0xd09917eb, 0x4508a07e, 0xb0b7250a, 0x228c1f0e, 0x00000001, 0x000001c8, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x0000012c, 0x00000040, + 0x0000004b, 0x04001858, 0x00107000, 0x00000000, 0x00004444, 0x04002064, 0x00101032, 0x00000000, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0700003d, 0x001000f2, + 0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000000, 0x0a000038, 0x00100032, 0x00000001, + 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x08000036, + 0x001000c2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07000038, + 0x001000f2, 0x00000000, 0x00100f46, 0x00000000, 0x00100e46, 0x00000001, 0x0500001b, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000000, 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00107e46, 0x00000000, 0x05000056, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x0a000038, + 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x3b808081, 0x3b808081, 0x3b808081, + 0x3b808081, 0x0100003e, + }; + static const DWORD ps_sample_code[] = { #if 0 Texture2D t; @@ -3298,29 +3435,245 @@ 0x3b088889, 0x00000000, 0x00000000, 0x09000045, 0x001020f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e, }; + static const DWORD ps_sample_b_code[] = + { +#if 0 + Texture2D t; + SamplerState s; + + float bias; + + float4 main(float4 position : SV_POSITION) : SV_Target + { + float2 p; + + p.x = position.x / 640.0f; + p.y = position.y / 480.0f; + return t.SampleBias(s, p, bias); + } +#endif + 0x43425844, 0xc39b0686, 0x8244a7fc, 0x14c0b97a, 0x2900b3b7, 0x00000001, 0x00000150, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000b4, 0x00000040, + 0x0000002d, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, + 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000, + 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x0c00004a, + 0x001020f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x0020800a, 0x00000000, 0x00000000, 0x0100003e, + }; + static const DWORD ps_sample_l_code[] = + { +#if 0 + Texture2D t; + SamplerState s; + + float level; + + float4 main(float4 position : SV_POSITION) : SV_Target + { + float2 p; + + p.x = position.x / 640.0f; + p.y = position.y / 480.0f; + return t.SampleLevel(s, p, level); + } +#endif + 0x43425844, 0x61e05d85, 0x2a7300fb, 0x0a83706b, 0x889d1683, 0x00000001, 0x00000150, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000b4, 0x00000040, + 0x0000002d, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, + 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000, + 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x0c000048, + 0x001020f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x0020800a, 0x00000000, 0x00000000, 0x0100003e, + }; + static const struct shader ps_ld = {ps_ld_code, sizeof(ps_ld_code)}; + static const struct shader ps_ld_sint8 = {ps_ld_sint8_code, sizeof(ps_ld_sint8_code)}; + static const struct shader ps_ld_uint8 = {ps_ld_uint8_code, sizeof(ps_ld_uint8_code)}; + static const struct shader ps_sample = {ps_sample_code, sizeof(ps_sample_code)}; + static const struct shader ps_sample_b = {ps_sample_b_code, sizeof(ps_sample_b_code)}; + static const struct shader ps_sample_l = {ps_sample_l_code, sizeof(ps_sample_l_code)}; static const struct { - float x, y; + struct vec2 position; } quad[] = { - {-1.0f, -1.0f}, - {-1.0f, 1.0f}, - { 1.0f, -1.0f}, - { 1.0f, 1.0f}, + {{-1.0f, -1.0f}}, + {{-1.0f, 1.0f}}, + {{ 1.0f, -1.0f}}, + {{ 1.0f, 1.0f}}, }; - static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f}; - static const DWORD bitmap_data[] = + static const DWORD rgba_level_0[] = { 0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00, 0xffff0000, 0xffff00ff, 0xff000000, 0xff7f7f7f, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, }; + static const DWORD rgba_level_1[] = + { + 0xffffffff, 0xff0000ff, + 0xff000000, 0xff00ff00, + }; + static const DWORD rgba_level_2[] = + { + 0xffff0000, + }; + static const BYTE bc1_data[4 * 8] = + { + 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + }; + static const BYTE bc2_data[4 * 16] = + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + }; + static const BYTE bc3_data[4 * 16] = + { + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + }; + static const struct texture rgba_texture = + { + 4, 4, 3, DXGI_FORMAT_R8G8B8A8_UNORM, + { + {rgba_level_0, 4 * sizeof(*rgba_level_0), 0}, + {rgba_level_1, 2 * sizeof(*rgba_level_1), 0}, + {rgba_level_2, sizeof(*rgba_level_2), 0}, + } + }; + static const struct texture bc1_texture = {8, 8, 1, DXGI_FORMAT_BC1_UNORM, {{bc1_data, 2 * 8}}}; + static const struct texture bc2_texture = {8, 8, 1, DXGI_FORMAT_BC2_UNORM, {{bc2_data, 2 * 16}}}; + static const struct texture bc3_texture = {8, 8, 1, DXGI_FORMAT_BC3_UNORM, {{bc3_data, 2 * 16}}}; + static const struct texture sint8_texture = {4, 4, 1, DXGI_FORMAT_R8G8B8A8_SINT, + {{rgba_level_0, 4 * sizeof(*rgba_level_0)}}}; + static const struct texture uint8_texture = {4, 4, 1, DXGI_FORMAT_R8G8B8A8_UINT, + {{rgba_level_0, 4 * sizeof(*rgba_level_0)}}}; + static const DWORD level_1_colors[] = + { + 0xffffffff, 0xffffffff, 0xff0000ff, 0xff0000ff, + 0xffffffff, 0xffffffff, 0xff0000ff, 0xff0000ff, + 0xff000000, 0xff000000, 0xff00ff00, 0xff00ff00, + 0xff000000, 0xff000000, 0xff00ff00, 0xff00ff00, + }; + static const DWORD lerp_1_2_colors[] = + { + 0xffff7f7f, 0xffff7f7f, 0xff7f007f, 0xff7f007f, + 0xffff7f7f, 0xffff7f7f, 0xff7f007f, 0xff7f007f, + 0xff7f0000, 0xff7f0000, 0xff7f7f00, 0xff7f7f00, + 0xff7f0000, 0xff7f0000, 0xff7f7f00, 0xff7f7f00, + }; + static const DWORD level_2_colors[] = + { + 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + }; + static const DWORD bc_colors[] = + { + 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xff00ff00, + 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xff00ff00, + 0xffff0000, 0xffff0000, 0xffffffff, 0xffffffff, + 0xffff0000, 0xffff0000, 0xffffffff, 0xffffffff, + }; + static const DWORD sint8_colors[] = + { + 0x7e80807e, 0x7e807e7e, 0x7e807e80, 0x7e7e7e80, + 0x7e7e8080, 0x7e7e7f7f, 0x7e808080, 0x7effffff, + 0x7e7e7e7e, 0x7e7e7e7e, 0x7e7e7e7e, 0x7e808080, + 0x7e7e7e7e, 0x7e7f7f7f, 0x7e7f7f7f, 0x7e7f7f7f, + }; + static const DWORD zero_colors[4 * 4] = {0}; + static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f}; + + static const struct test + { + const struct shader *ps; + const struct texture *texture; + D3D10_FILTER filter; + float lod_bias; + float min_lod; + float max_lod; + float miplevel; + const DWORD *expected_colors; + } + tests[] = + { + {&ps_ld, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, rgba_level_0}, + {&ps_ld, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 1.0f, level_1_colors}, + {&ps_ld, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 2.0f, level_2_colors}, + {&ps_ld, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 3.0f, zero_colors}, + {&ps_ld, &bc1_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_ld, &bc1_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 1.0f, zero_colors}, + {&ps_ld, &bc2_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_ld, &bc2_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 1.0f, zero_colors}, + {&ps_ld, &bc3_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_ld, &bc3_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 1.0f, zero_colors}, + {&ps_ld_sint8, &sint8_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, sint8_colors}, + {&ps_ld_uint8, &uint8_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, rgba_level_0}, + {&ps_sample, &bc1_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_sample, &bc2_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_sample, &bc3_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_sample, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, rgba_level_0}, + {&ps_sample, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D10_FLOAT32_MAX, 0.0f, rgba_level_0}, + {&ps_sample, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 2.0f, 0.0f, D3D11_FLOAT32_MAX, 0.0f, rgba_level_0}, + {&ps_sample, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 8.0f, 0.0f, D3D11_FLOAT32_MAX, 0.0f, level_1_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 0.0f, rgba_level_0}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 8.0f, 0.0f, D3D11_FLOAT32_MAX, 0.0f, level_1_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 8.0f, level_1_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 8.4f, level_1_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 8.5f, level_2_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 9.0f, level_2_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 2.0f, 1.0f, rgba_level_0}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 2.0f, 9.0f, level_2_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 1.0f, 9.0f, level_1_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 9.0f, rgba_level_0}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D10_FLOAT32_MAX, -1.0f, rgba_level_0}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D10_FLOAT32_MAX, 0.0f, rgba_level_0}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D10_FLOAT32_MAX, 0.4f, rgba_level_0}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D10_FLOAT32_MAX, 0.5f, level_1_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D10_FLOAT32_MAX, 1.0f, level_1_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D10_FLOAT32_MAX, 1.4f, level_1_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D10_FLOAT32_MAX, 1.5f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D10_FLOAT32_MAX, 2.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D10_FLOAT32_MAX, 3.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D10_FLOAT32_MAX, 4.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR, 0.0f, 0.0f, D3D10_FLOAT32_MAX, 1.5f, lerp_1_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 0.0f, D3D10_FLOAT32_MAX, -2.0f, rgba_level_0}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 0.0f, D3D10_FLOAT32_MAX, -1.0f, level_1_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 0.0f, D3D10_FLOAT32_MAX, 0.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 0.0f, D3D10_FLOAT32_MAX, 1.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 0.0f, D3D10_FLOAT32_MAX, 1.5f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 2.0f, 2.0f, -9.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 2.0f, 2.0f, -1.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 2.0f, 2.0f, 0.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 2.0f, 2.0f, 1.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 2.0f, 2.0f, 9.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 2.0f, 2.0f, 2.0f, -9.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 2.0f, 2.0f, 2.0f, -1.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 2.0f, 2.0f, 2.0f, 0.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 2.0f, 2.0f, 2.0f, 1.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D10_FILTER_MIN_MAG_MIP_POINT, 2.0f, 2.0f, 2.0f, 9.0f, level_2_colors}, + }; if (!(device = create_device())) { - skip("Failed to create device, skipping tests.\n"); + skip("Failed to create device.\n"); return; } window = CreateWindowA("static", "d3d10core_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, @@ -3346,9 +3699,38 @@ hr = ID3D10Device_CreateBuffer(device, &buffer_desc, &resource_data, &vb); ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr); + buffer_desc.ByteWidth = sizeof(miplevel); + buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; + + hr = ID3D10Device_CreateBuffer(device, &buffer_desc, NULL, &cb); + ok(SUCCEEDED(hr), "Failed to create constant buffer, hr %#x.\n", hr); + + hr = ID3D10Device_CreateVertexShader(device, vs_code, sizeof(vs_code), &vs); + ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); + + hr = ID3D10Device_CreateRenderTargetView(device, (ID3D10Resource *)backbuffer, NULL, &rtv); + ok(SUCCEEDED(hr), "Failed to create rendertarget view, hr %#x.\n", hr); + + ID3D10Device_OMSetRenderTargets(device, 1, &rtv, NULL); + ID3D10Device_IASetInputLayout(device, input_layout); + ID3D10Device_IASetPrimitiveTopology(device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + stride = sizeof(*quad); + offset = 0; + ID3D10Device_IASetVertexBuffers(device, 0, 1, &vb, &stride, &offset); + ID3D10Device_VSSetShader(device, vs); + ID3D10Device_PSSetConstantBuffers(device, 0, 1, &cb); + + vp.TopLeftX = 0; + vp.TopLeftY = 0; + vp.Width = 640; + vp.Height = 480; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + ID3D10Device_RSSetViewports(device, 1, &vp); + texture_desc.Width = 4; texture_desc.Height = 4; - texture_desc.MipLevels = 1; + texture_desc.MipLevels = 3; texture_desc.ArraySize = 1; texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; texture_desc.SampleDesc.Count = 1; @@ -3358,15 +3740,6 @@ texture_desc.CPUAccessFlags = 0; texture_desc.MiscFlags = 0; - resource_data.pSysMem = bitmap_data; - resource_data.SysMemPitch = 4 * sizeof(*bitmap_data); - - hr = ID3D10Device_CreateTexture2D(device, &texture_desc, &resource_data, &texture); - ok(SUCCEEDED(hr), "Failed to create a 2d texture, hr %#x\n", hr); - - hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture, NULL, &ps_srv); - ok(SUCCEEDED(hr), "Failed to create shader resource view, hr %#x\n", hr); - sampler_desc.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT; sampler_desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP; sampler_desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP; @@ -3379,63 +3752,101 @@ sampler_desc.BorderColor[2] = 0.0f; sampler_desc.BorderColor[3] = 0.0f; sampler_desc.MinLOD = 0.0f; - sampler_desc.MaxLOD = 0.0f; + sampler_desc.MaxLOD = D3D10_FLOAT32_MAX; - hr = ID3D10Device_CreateSamplerState(device, &sampler_desc, &sampler_state); - ok(SUCCEEDED(hr), "Failed to create sampler state, hr %#x.\n", hr); + ps = NULL; + srv = NULL; + sampler = NULL; + texture = NULL; + current_ps = NULL; + current_texture = NULL; + for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) + { + const struct test *test = &tests[i]; - hr = ID3D10Device_CreateVertexShader(device, vs_code, sizeof(vs_code), &vs); - ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); - hr = ID3D10Device_CreatePixelShader(device, ps_code, sizeof(ps_code), &ps); - ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); + if (current_ps != test->ps) + { + if (ps) + ID3D10PixelShader_Release(ps); - hr = ID3D10Device_CreateRenderTargetView(device, (ID3D10Resource *)backbuffer, NULL, &backbuffer_rtv); - ok(SUCCEEDED(hr), "Failed to create rendertarget view, hr %#x.\n", hr); + current_ps = test->ps; - ID3D10Device_OMSetRenderTargets(device, 1, &backbuffer_rtv, NULL); - ID3D10Device_IASetInputLayout(device, input_layout); - ID3D10Device_IASetPrimitiveTopology(device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - stride = sizeof(*quad); - offset = 0; - ID3D10Device_IASetVertexBuffers(device, 0, 1, &vb, &stride, &offset); - ID3D10Device_VSSetShader(device, vs); - ID3D10Device_PSSetShaderResources(device, 0, 1, &ps_srv); - ID3D10Device_PSSetSamplers(device, 0, 1, &sampler_state); - ID3D10Device_PSSetShader(device, ps); + hr = ID3D10Device_CreatePixelShader(device, current_ps->code, current_ps->size, &ps); + ok(SUCCEEDED(hr), "Test %u: Failed to create pixel shader, hr %#x.\n", i, hr); - vp.TopLeftX = 0; - vp.TopLeftY = 0; - vp.Width = 640; - vp.Height = 480; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - ID3D10Device_RSSetViewports(device, 1, &vp); + ID3D10Device_PSSetShader(device, ps); + } - ID3D10Device_ClearRenderTargetView(device, backbuffer_rtv, red); + if (current_texture != test->texture) + { + if (texture) + ID3D10Texture2D_Release(texture); + if (srv) + ID3D10ShaderResourceView_Release(srv); - ID3D10Device_Draw(device, 4, 0); + current_texture = test->texture; - get_texture_readback(backbuffer, &rb); - for (i = 0; i < 4; ++i) - { - for (j = 0; j < 4; ++j) + texture_desc.Width = current_texture->width; + texture_desc.Height = current_texture->height; + texture_desc.MipLevels = current_texture->miplevel_count; + texture_desc.Format = current_texture->format; + + hr = ID3D10Device_CreateTexture2D(device, &texture_desc, current_texture->data, &texture); + ok(SUCCEEDED(hr), "Test %u: Failed to create 2d texture, hr %#x.\n", i, hr); + + hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture, NULL, &srv); + ok(SUCCEEDED(hr), "Test %u: Failed to create shader resource view, hr %#x.\n", i, hr); + + ID3D10Device_PSSetShaderResources(device, 0, 1, &srv); + } + + if (!sampler || (sampler_desc.Filter != test->filter + || sampler_desc.MipLODBias != test->lod_bias + || sampler_desc.MinLOD != test->min_lod + || sampler_desc.MaxLOD != test->max_lod)) { - color = get_readback_color(&rb, 80 + j * 160, 60 + i * 120); - ok(compare_color(color, bitmap_data[j + i * 4], 1), - "Got unexpected color 0x%08x at (%u, %u), expected 0x%08x.\n", - color, j, i, bitmap_data[j + i * 4]); + if (sampler) + ID3D10SamplerState_Release(sampler); + + sampler_desc.Filter = test->filter; + sampler_desc.MipLODBias = test->lod_bias; + sampler_desc.MinLOD = test->min_lod; + sampler_desc.MaxLOD = test->max_lod; + + hr = ID3D10Device_CreateSamplerState(device, &sampler_desc, &sampler); + ok(SUCCEEDED(hr), "Test %u: Failed to create sampler state, hr %#x.\n", i, hr); + + ID3D10Device_PSSetSamplers(device, 0, 1, &sampler); } - } - release_texture_readback(&rb); + miplevel.x = test->miplevel; + ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)cb, 0, NULL, &miplevel, 0, 0); + + ID3D10Device_ClearRenderTargetView(device, rtv, red); + ID3D10Device_Draw(device, 4, 0); + + get_texture_readback(backbuffer, &rb); + for (x = 0; x < 4; ++x) + { + for (y = 0; y < 4; ++y) + { + color = get_readback_color(&rb, 80 + x * 160, 60 + y * 120); + ok(compare_color(color, test->expected_colors[y * 4 + x], 1), + "Test %u: Got unexpected color 0x%08x at (%u, %u).\n", i, color, x, y); + } + } + release_texture_readback(&rb); + } + ID3D10ShaderResourceView_Release(srv); + ID3D10SamplerState_Release(sampler); + ID3D10Texture2D_Release(texture); ID3D10PixelShader_Release(ps); + + ID3D10Buffer_Release(cb); ID3D10VertexShader_Release(vs); - ID3D10SamplerState_Release(sampler_state); - ID3D10ShaderResourceView_Release(ps_srv); - ID3D10Texture2D_Release(texture); ID3D10Buffer_Release(vb); ID3D10InputLayout_Release(input_layout); - ID3D10RenderTargetView_Release(backbuffer_rtv); + ID3D10RenderTargetView_Release(rtv); ID3D10Texture2D_Release(backbuffer); IDXGISwapChain_Release(swapchain); refcount = ID3D10Device_Release(device); @@ -4317,6 +4728,9 @@ set_box(&box, 4, 4, 0, 3, 1, 1); ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)texture, 0, &box, bitmap_data, sizeof(*bitmap_data), 0); + set_box(&box, 0, 0, 0, 4, 4, 0); + ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)texture, 0, &box, + bitmap_data, 4 * sizeof(*bitmap_data), 0); ID3D10Device_Draw(device, 4, 0); get_texture_readback(backbuffer, &rb); for (i = 0; i < 4; ++i) @@ -4362,6 +4776,430 @@ DestroyWindow(window); } +static void test_copy_subresource_region(void) +{ + ID3D10Texture2D *dst_texture, *src_texture; + ID3D10RenderTargetView *backbuffer_rtv; + D3D10_SUBRESOURCE_DATA resource_data; + D3D10_TEXTURE2D_DESC texture_desc; + ID3D10SamplerState *sampler_state; + ID3D10ShaderResourceView *ps_srv; + D3D10_SAMPLER_DESC sampler_desc; + ID3D10InputLayout *input_layout; + D3D10_BUFFER_DESC buffer_desc; + ID3D10Texture2D *backbuffer; + unsigned int stride, offset; + struct texture_readback rb; + IDXGISwapChain *swapchain; + ID3D10VertexShader *vs; + ID3D10PixelShader *ps; + ID3D10Device *device; + D3D10_VIEWPORT vp; + unsigned int i, j; + ID3D10Buffer *vb; + ULONG refcount; + D3D10_BOX box; + DWORD color; + HWND window; + HRESULT hr; + + static const D3D10_INPUT_ELEMENT_DESC layout_desc[] = + { + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }; + static const DWORD vs_code[] = + { +#if 0 + float4 main(float4 position : POSITION) : SV_POSITION + { + return position; + } +#endif + 0x43425844, 0xa7a2f22d, 0x83ff2560, 0xe61638bd, 0x87e3ce90, 0x00000001, 0x000000d8, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040, + 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, + 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, + }; + static const DWORD ps_code[] = + { +#if 0 + Texture2D t; + SamplerState s; + + float4 main(float4 position : SV_POSITION) : SV_Target + { + float2 p; + + p.x = position.x / 640.0f; + p.y = position.y / 480.0f; + return t.Sample(s, p); + } +#endif + 0x43425844, 0x1ce9b612, 0xc8176faa, 0xd37844af, 0xdb515605, 0x00000001, 0x00000134, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000098, 0x00000040, + 0x00000026, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, + 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, + 0x3b088889, 0x00000000, 0x00000000, 0x09000045, 0x001020f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e, + }; + static const struct + { + float x, y; + } + quad[] = + { + {-1.0f, -1.0f}, + {-1.0f, 1.0f}, + { 1.0f, -1.0f}, + { 1.0f, 1.0f}, + }; + static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f}; + static const DWORD bitmap_data[] = + { + 0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00, + 0xffff0000, 0xffff00ff, 0xff000000, 0xff7f7f7f, + 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + }; + static const DWORD expected_colors[] = + { + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffff00, 0xff0000ff, 0xff00ffff, 0x00000000, + 0xff7f7f7f, 0xffff0000, 0xffff00ff, 0xff7f7f7f, + 0xffffffff, 0xffffffff, 0xff000000, 0x00000000, + }; + + if (!(device = create_device())) + { + skip("Failed to create device.\n"); + return; + } + window = CreateWindowA("static", "d3d10core_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + swapchain = create_swapchain(device, window, TRUE); + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D10Texture2D, (void **)&backbuffer); + ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr); + + hr = ID3D10Device_CreateInputLayout(device, layout_desc, sizeof(layout_desc) / sizeof(*layout_desc), + vs_code, sizeof(vs_code), &input_layout); + ok(SUCCEEDED(hr), "Failed to create input layout, hr %#x.\n", hr); + + buffer_desc.ByteWidth = sizeof(quad); + buffer_desc.Usage = D3D10_USAGE_DEFAULT; + buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + buffer_desc.CPUAccessFlags = 0; + buffer_desc.MiscFlags = 0; + + resource_data.pSysMem = quad; + resource_data.SysMemPitch = 0; + resource_data.SysMemSlicePitch = 0; + + hr = ID3D10Device_CreateBuffer(device, &buffer_desc, &resource_data, &vb); + ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr); + + texture_desc.Width = 4; + texture_desc.Height = 4; + texture_desc.MipLevels = 1; + texture_desc.ArraySize = 1; + texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + texture_desc.SampleDesc.Count = 1; + texture_desc.SampleDesc.Quality = 0; + texture_desc.Usage = D3D10_USAGE_DEFAULT; + texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; + texture_desc.CPUAccessFlags = 0; + texture_desc.MiscFlags = 0; + + hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &dst_texture); + ok(SUCCEEDED(hr), "Failed to create 2d texture, hr %#x.\n", hr); + + texture_desc.Usage = D3D10_USAGE_IMMUTABLE; + + resource_data.pSysMem = bitmap_data; + resource_data.SysMemPitch = 4 * sizeof(*bitmap_data); + + hr = ID3D10Device_CreateTexture2D(device, &texture_desc, &resource_data, &src_texture); + ok(SUCCEEDED(hr), "Failed to create 2d texture, hr %#x.\n", hr); + + hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)dst_texture, NULL, &ps_srv); + ok(SUCCEEDED(hr), "Failed to create shader resource view, hr %#x.\n", hr); + + sampler_desc.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT; + sampler_desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP; + sampler_desc.MipLODBias = 0.0f; + sampler_desc.MaxAnisotropy = 0; + sampler_desc.ComparisonFunc = D3D10_COMPARISON_NEVER; + sampler_desc.BorderColor[0] = 0.0f; + sampler_desc.BorderColor[1] = 0.0f; + sampler_desc.BorderColor[2] = 0.0f; + sampler_desc.BorderColor[3] = 0.0f; + sampler_desc.MinLOD = 0.0f; + sampler_desc.MaxLOD = 0.0f; + + hr = ID3D10Device_CreateSamplerState(device, &sampler_desc, &sampler_state); + ok(SUCCEEDED(hr), "Failed to create sampler state, hr %#x.\n", hr); + + hr = ID3D10Device_CreateVertexShader(device, vs_code, sizeof(vs_code), &vs); + ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); + hr = ID3D10Device_CreatePixelShader(device, ps_code, sizeof(ps_code), &ps); + ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); + + hr = ID3D10Device_CreateRenderTargetView(device, (ID3D10Resource *)backbuffer, NULL, &backbuffer_rtv); + ok(SUCCEEDED(hr), "Failed to create rendertarget view, hr %#x.\n", hr); + + ID3D10Device_OMSetRenderTargets(device, 1, &backbuffer_rtv, NULL); + ID3D10Device_IASetInputLayout(device, input_layout); + ID3D10Device_IASetPrimitiveTopology(device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + stride = sizeof(*quad); + offset = 0; + ID3D10Device_IASetVertexBuffers(device, 0, 1, &vb, &stride, &offset); + ID3D10Device_VSSetShader(device, vs); + ID3D10Device_PSSetShaderResources(device, 0, 1, &ps_srv); + ID3D10Device_PSSetSamplers(device, 0, 1, &sampler_state); + ID3D10Device_PSSetShader(device, ps); + + vp.TopLeftX = 0; + vp.TopLeftY = 0; + vp.Width = 640; + vp.Height = 480; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + ID3D10Device_RSSetViewports(device, 1, &vp); + + ID3D10Device_ClearRenderTargetView(device, backbuffer_rtv, red); + + set_box(&box, 0, 0, 0, 2, 2, 1); + ID3D10Device_CopySubresourceRegion(device, (ID3D10Resource *)dst_texture, 0, + 1, 1, 0, (ID3D10Resource *)src_texture, 0, &box); + set_box(&box, 1, 2, 0, 4, 3, 1); + ID3D10Device_CopySubresourceRegion(device, (ID3D10Resource *)dst_texture, 0, + 0, 3, 0, (ID3D10Resource *)src_texture, 0, &box); + set_box(&box, 0, 3, 0, 4, 4, 1); + ID3D10Device_CopySubresourceRegion(device, (ID3D10Resource *)dst_texture, 0, + 0, 0, 0, (ID3D10Resource *)src_texture, 0, &box); + set_box(&box, 3, 0, 0, 4, 2, 1); + ID3D10Device_CopySubresourceRegion(device, (ID3D10Resource *)dst_texture, 0, + 0, 1, 0, (ID3D10Resource *)src_texture, 0, &box); + set_box(&box, 3, 1, 0, 4, 2, 1); + ID3D10Device_CopySubresourceRegion(device, (ID3D10Resource *)dst_texture, 0, + 3, 2, 0, (ID3D10Resource *)src_texture, 0, &box); + set_box(&box, 0, 0, 0, 4, 4, 0); + ID3D10Device_CopySubresourceRegion(device, (ID3D10Resource *)dst_texture, 0, + 0, 0, 0, (ID3D10Resource *)src_texture, 0, &box); + ID3D10Device_Draw(device, 4, 0); + get_texture_readback(backbuffer, &rb); + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + color = get_readback_color(&rb, 80 + j * 160, 60 + i * 120); + ok(compare_color(color, expected_colors[j + i * 4], 1), + "Got unexpected color 0x%08x at (%u, %u), expected 0x%08x.\n", + color, j, i, expected_colors[j + i * 4]); + } + } + release_texture_readback(&rb); + + ID3D10Device_CopySubresourceRegion(device, (ID3D10Resource *)dst_texture, 0, + 0, 0, 0, (ID3D10Resource *)src_texture, 0, NULL); + ID3D10Device_Draw(device, 4, 0); + get_texture_readback(backbuffer, &rb); + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + color = get_readback_color(&rb, 80 + j * 160, 60 + i * 120); + ok(compare_color(color, bitmap_data[j + i * 4], 1), + "Got unexpected color 0x%08x at (%u, %u), expected 0x%08x.\n", + color, j, i, bitmap_data[j + i * 4]); + } + } + release_texture_readback(&rb); + + ID3D10PixelShader_Release(ps); + ID3D10VertexShader_Release(vs); + ID3D10SamplerState_Release(sampler_state); + ID3D10ShaderResourceView_Release(ps_srv); + ID3D10Texture2D_Release(dst_texture); + ID3D10Texture2D_Release(src_texture); + ID3D10Buffer_Release(vb); + ID3D10InputLayout_Release(input_layout); + ID3D10RenderTargetView_Release(backbuffer_rtv); + ID3D10Texture2D_Release(backbuffer); + IDXGISwapChain_Release(swapchain); + refcount = ID3D10Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + +static void test_multisample_init(void) +{ + D3D10_TEXTURE2D_DESC desc; + ID3D10Texture2D *backbuffer, *multi; + ID3D10Device *device; + ULONG refcount; + DWORD color; + HRESULT hr; + unsigned int x, y; + struct texture_readback rb; + BOOL all_zero = TRUE; + UINT count = 0; + HWND window; + IDXGISwapChain *swapchain; + ID3D10RenderTargetView *rtview; + static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f}; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 2, &count); + ok(SUCCEEDED(hr), "Failed to get quality levels, hr %#x.\n", hr); + if (!count) + { + skip("Multisampling not supported for DXGI_FORMAT_R8G8B8A8_UNORM, skipping tests.\n"); + goto done; + } + + window = CreateWindowA("static", "d3d10core_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + swapchain = create_swapchain(device, window, TRUE); + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D10Texture2D, (void **)&backbuffer); + ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr); + hr = ID3D10Device_CreateRenderTargetView(device, (ID3D10Resource *)backbuffer, NULL, &rtview); + ok(SUCCEEDED(hr), "Failed to create rendertarget view, hr %#x.\n", hr); + ID3D10Device_ClearRenderTargetView(device, rtview, white); + + desc.Width = 640; + desc.Height = 480; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 2; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D10_USAGE_DEFAULT; + desc.BindFlags = D3D10_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + hr = ID3D10Device_CreateTexture2D(device, &desc, NULL, &multi); + ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); + + ID3D10Device_ResolveSubresource(device, (ID3D10Resource *)backbuffer, 0, + (ID3D10Resource *)multi, 0, DXGI_FORMAT_R8G8B8A8_UNORM); + + get_texture_readback(backbuffer, &rb); + for (y = 0; y < 480; ++y) + { + for (x = 0; x < 640; ++x) + { + color = get_readback_color(&rb, x, y); + if (!compare_color(color, 0x00000000, 0)) + { + all_zero = FALSE; + break; + } + } + if (!all_zero) + break; + } + release_texture_readback(&rb); + todo_wine ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y); + + ID3D10RenderTargetView_Release(rtview); + ID3D10Texture2D_Release(backbuffer); + IDXGISwapChain_Release(swapchain); + ID3D10Texture2D_Release(multi); + DestroyWindow(window); +done: + refcount = ID3D10Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + +static void test_check_multisample_quality_levels(void) +{ + ID3D10Device *device; + UINT quality_levels; + ULONG refcount; + HRESULT hr; + + if (!(device = create_device())) + { + skip("Failed to create device.\n"); + return; + } + + ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 2, &quality_levels); + if (!quality_levels) + { + skip("Multisampling not supported for DXGI_FORMAT_R8G8B8A8_UNORM, skipping test.\n"); + goto done; + } + + quality_levels = 0xdeadbeef; + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_UNKNOWN, 2, &quality_levels); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + quality_levels = 0xdeadbeef; + hr = ID3D10Device_CheckMultisampleQualityLevels(device, 65536, 2, &quality_levels); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + todo_wine ok(quality_levels == 0xdeadbeef, "Got unexpected quality_levels %u.\n", quality_levels); + + quality_levels = 0xdeadbeef; + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 0, NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 0, &quality_levels); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + + quality_levels = 0xdeadbeef; + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 1, NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 1, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels); + + quality_levels = 0xdeadbeef; + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 2, NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 2, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + + /* We assume 15 samples multisampling is never supported in practice. */ + quality_levels = 0xdeadbeef; + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 15, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 32, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + quality_levels = 0xdeadbeef; + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 33, &quality_levels); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + quality_levels = 0xdeadbeef; + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 64, &quality_levels); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + + hr = ID3D10Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_BC3_UNORM, 2, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + +done: + refcount = ID3D10Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + START_TEST(device) { test_feature_level(); @@ -4389,4 +5227,7 @@ test_il_append_aligned(); test_fragment_coords(); test_update_subresource(); + test_copy_subresource_region(); + test_multisample_init(); + test_check_multisample_quality_levels(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d11/device.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d11/device.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d11/device.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d11/device.c 2016-02-08 19:32:34.000000000 +0000 @@ -820,10 +820,31 @@ ID3D11Resource *dst_resource, UINT dst_subresource_idx, UINT dst_x, UINT dst_y, UINT dst_z, ID3D11Resource *src_resource, UINT src_subresource_idx, const D3D11_BOX *src_box) { - FIXME("iface %p, dst_resource %p, dst_subresource_idx %u, dst_x %u, dst_y %u, dst_z %u, " - "src_resource %p, src_subresource_idx %u, src_box %p stub!\n", + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext(iface); + struct wined3d_resource *wined3d_dst_resource, *wined3d_src_resource; + struct wined3d_box wined3d_src_box; + + TRACE("iface %p, dst_resource %p, dst_subresource_idx %u, dst_x %u, dst_y %u, dst_z %u, " + "src_resource %p, src_subresource_idx %u, src_box %p.\n", iface, dst_resource, dst_subresource_idx, dst_x, dst_y, dst_z, src_resource, src_subresource_idx, src_box); + + if (src_box) + { + wined3d_src_box.left = src_box->left; + wined3d_src_box.top = src_box->top; + wined3d_src_box.front = src_box->front; + wined3d_src_box.right = src_box->right; + wined3d_src_box.bottom = src_box->bottom; + wined3d_src_box.back = src_box->back; + } + + wined3d_dst_resource = wined3d_resource_from_d3d11_resource(dst_resource); + wined3d_src_resource = wined3d_resource_from_d3d11_resource(src_resource); + wined3d_mutex_lock(); + wined3d_device_copy_sub_resource_region(device->wined3d_device, wined3d_dst_resource, dst_subresource_idx, + dst_x, dst_y, dst_z, wined3d_src_resource, src_subresource_idx, src_box ? &wined3d_src_box : NULL); + wined3d_mutex_unlock(); } static void STDMETHODCALLTYPE d3d11_immediate_context_CopyResource(ID3D11DeviceContext *iface, @@ -2402,10 +2423,41 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CheckMultisampleQualityLevels(ID3D11Device *iface, DXGI_FORMAT format, UINT sample_count, UINT *quality_level_count) { - FIXME("iface %p, format %u, sample_count %u, quality_level_count %p stub!\n", - iface, format, sample_count, quality_level_count); + struct d3d_device *device = impl_from_ID3D11Device(iface); + struct wined3d_device_creation_parameters params; + struct wined3d *wined3d; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, format %s, sample_count %u, quality_level_count %p.\n", + iface, debug_dxgi_format(format), sample_count, quality_level_count); + + if (!quality_level_count) + return E_INVALIDARG; + + *quality_level_count = 0; + + if (!sample_count) + return E_FAIL; + if (sample_count == 1) + { + *quality_level_count = 1; + return S_OK; + } + if (sample_count > D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT) + return E_FAIL; + + wined3d_mutex_lock(); + wined3d = wined3d_device_get_wined3d(device->wined3d_device); + wined3d_device_get_creation_parameters(device->wined3d_device, ¶ms); + hr = wined3d_check_device_multisample_type(wined3d, params.adapter_idx, params.device_type, + wined3dformat_from_dxgi_format(format), TRUE, sample_count, quality_level_count); + wined3d_mutex_unlock(); + + if (hr == WINED3DERR_INVALIDCALL) + return E_INVALIDARG; + if (hr == WINED3DERR_NOTAVAILABLE) + return S_OK; + return hr; } static void STDMETHODCALLTYPE d3d11_device_CheckCounterInfo(ID3D11Device *iface, D3D11_COUNTER_INFO *info) @@ -3186,17 +3238,21 @@ iface, dst_resource, dst_subresource_idx, dst_x, dst_y, dst_z, src_resource, src_subresource_idx, src_box); + if (src_box) + { + wined3d_src_box.left = src_box->left; + wined3d_src_box.top = src_box->top; + wined3d_src_box.front = src_box->front; + wined3d_src_box.right = src_box->right; + wined3d_src_box.bottom = src_box->bottom; + wined3d_src_box.back = src_box->back; + } + wined3d_dst_resource = wined3d_resource_from_d3d10_resource(dst_resource); wined3d_src_resource = wined3d_resource_from_d3d10_resource(src_resource); - wined3d_src_box.left = src_box->left; - wined3d_src_box.top = src_box->top; - wined3d_src_box.front = src_box->front; - wined3d_src_box.right = src_box->right; - wined3d_src_box.bottom = src_box->bottom; - wined3d_src_box.back = src_box->back; wined3d_mutex_lock(); wined3d_device_copy_sub_resource_region(device->wined3d_device, wined3d_dst_resource, dst_subresource_idx, - dst_x, dst_y, dst_z, wined3d_src_resource, src_subresource_idx, &wined3d_src_box); + dst_x, dst_y, dst_z, wined3d_src_resource, src_subresource_idx, src_box ? &wined3d_src_box : NULL); wined3d_mutex_unlock(); } @@ -4447,10 +4503,13 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CheckMultisampleQualityLevels(ID3D10Device1 *iface, DXGI_FORMAT format, UINT sample_count, UINT *quality_level_count) { - FIXME("iface %p, format %s, sample_count %u, quality_level_count %p stub!\n", + struct d3d_device *device = impl_from_ID3D10Device(iface); + + TRACE("iface %p, format %s, sample_count %u, quality_level_count %p.\n", iface, debug_dxgi_format(format), sample_count, quality_level_count); - return E_NOTIMPL; + return d3d11_device_CheckMultisampleQualityLevels(&device->ID3D11Device_iface, format, + sample_count, quality_level_count); } static void STDMETHODCALLTYPE d3d10_device_CheckCounterInfo(ID3D10Device1 *iface, D3D10_COUNTER_INFO *counter_info) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d11/tests/d3d11.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d11/tests/d3d11.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d11/tests/d3d11.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d11/tests/d3d11.c 2016-02-08 19:32:34.000000000 +0000 @@ -508,6 +508,7 @@ ID3D11Device *device, *tmp; D3D11_TEXTURE2D_DESC desc; ID3D11Texture2D *texture; + UINT quality_level_count; IDXGISurface *surface; HRESULT hr; @@ -590,6 +591,25 @@ ok(FAILED(hr), "Texture should not implement IDXGISurface.\n"); ID3D11Texture2D_Release(texture); + ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 2, &quality_level_count); + desc.ArraySize = 1; + desc.SampleDesc.Count = 2; + hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture); + if (quality_level_count) + { + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ID3D11Texture2D_Release(texture); + desc.SampleDesc.Quality = quality_level_count; + hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture); + } + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + /* We assume 15 samples multisampling is never supported in practice. */ + desc.SampleDesc.Count = 15; + desc.SampleDesc.Quality = 0; + hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + refcount = ID3D11Device_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); } @@ -2851,34 +2871,51 @@ static void test_texture(void) { - ID3D11RenderTargetView *backbuffer_rtv; + struct shader + { + const DWORD *code; + size_t size; + }; + struct texture + { + UINT width; + UINT height; + UINT miplevel_count; + DXGI_FORMAT format; + D3D11_SUBRESOURCE_DATA data[3]; + }; + D3D11_SUBRESOURCE_DATA resource_data; + const struct texture *current_texture; D3D11_TEXTURE2D_DESC texture_desc; - ID3D11SamplerState *sampler_state; - ID3D11ShaderResourceView *ps_srv; D3D11_SAMPLER_DESC sampler_desc; ID3D11InputLayout *input_layout; + const struct shader *current_ps; + ID3D11ShaderResourceView *srv; D3D11_BUFFER_DESC buffer_desc; ID3D11DeviceContext *context; ID3D11Texture2D *backbuffer; + ID3D11RenderTargetView *rtv; + ID3D11SamplerState *sampler; unsigned int stride, offset; struct texture_readback rb; IDXGISwapChain *swapchain; ID3D11Texture2D *texture; ID3D11VertexShader *vs; ID3D11PixelShader *ps; + ID3D11Buffer *vb, *cb; ID3D11Device *device; + unsigned int i, x, y; + struct vec4 miplevel; D3D11_VIEWPORT vp; - unsigned int i, j; - ID3D11Buffer *vb; ULONG refcount; - DWORD color; HWND window; + DWORD color; HRESULT hr; static const D3D11_INPUT_ELEMENT_DESC layout_desc[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; static const DWORD vs_code[] = { @@ -2896,7 +2933,107 @@ 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, }; - static const DWORD ps_code[] = + static const DWORD ps_ld_code[] = + { +#if 0 + Texture2D t; + + float miplevel; + + float4 main(float4 position : SV_POSITION) : SV_TARGET + { + float3 p; + t.GetDimensions(miplevel, p.x, p.y, p.z); + p.z = miplevel; + p *= float3(position.x / 640.0f, position.y / 480.0f, 1.0f); + return t.Load(int3(p)); + } +#endif + 0x43425844, 0xbdda6bdf, 0xc6ffcdf1, 0xa58596b3, 0x822383f0, 0x00000001, 0x000001ac, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000110, 0x00000040, + 0x00000044, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04001858, 0x00107000, 0x00000000, + 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, + 0x02000068, 0x00000001, 0x0600001c, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, + 0x0700003d, 0x001000f2, 0x00000000, 0x0010000a, 0x00000000, 0x00107e46, 0x00000000, 0x07000038, + 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00101046, 0x00000000, 0x06000036, 0x001000c2, + 0x00000000, 0x00208006, 0x00000000, 0x00000000, 0x0a000038, 0x001000f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x3f800000, 0x3f800000, 0x0500001b, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000000, 0x0700002d, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00107e46, 0x00000000, 0x0100003e, + }; + static const DWORD ps_ld_sint8_code[] = + { +#if 0 + Texture2D t; + + float4 main(float4 position : SV_POSITION) : SV_TARGET + { + float3 p, s; + int4 c; + + p = float3(position.x / 640.0f, position.y / 480.0f, 0.0f); + t.GetDimensions(0, s.x, s.y, s.z); + p *= s; + + c = t.Load(int3(p)); + return (max(c / (float4)127, (float4)-1) + (float4)1) / 2.0f; + } +#endif + 0x43425844, 0xb3d0b0fc, 0x0e486f4a, 0xf67eec12, 0xfb9dd52f, 0x00000001, 0x00000240, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x000001a4, 0x00000040, + 0x00000069, 0x04001858, 0x00107000, 0x00000000, 0x00003333, 0x04002064, 0x00101032, 0x00000000, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0700003d, 0x001000f2, + 0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000000, 0x0a000038, 0x00100032, 0x00000001, + 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x08000036, + 0x001000c2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07000038, + 0x001000f2, 0x00000000, 0x00100f46, 0x00000000, 0x00100e46, 0x00000001, 0x0500001b, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000000, 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00107e46, 0x00000000, 0x0500002b, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x0a000038, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x3c010204, 0x3c010204, 0x3c010204, + 0x3c010204, 0x0a000034, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0xbf800000, + 0xbf800000, 0xbf800000, 0xbf800000, 0x0a000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0a000038, 0x001020f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x0100003e, + }; + static const DWORD ps_ld_uint8_code[] = + { +#if 0 + Texture2D t; + + float4 main(float4 position : SV_POSITION) : SV_TARGET + { + float3 p, s; + + p = float3(position.x / 640.0f, position.y / 480.0f, 0.0f); + t.GetDimensions(0, s.x, s.y, s.z); + p *= s; + + return t.Load(int3(p)) / (float4)255; + } +#endif + 0x43425844, 0xd09917eb, 0x4508a07e, 0xb0b7250a, 0x228c1f0e, 0x00000001, 0x000001c8, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x0000012c, 0x00000040, + 0x0000004b, 0x04001858, 0x00107000, 0x00000000, 0x00004444, 0x04002064, 0x00101032, 0x00000000, + 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0700003d, 0x001000f2, + 0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000000, 0x0a000038, 0x00100032, 0x00000001, + 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x08000036, + 0x001000c2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x07000038, + 0x001000f2, 0x00000000, 0x00100f46, 0x00000000, 0x00100e46, 0x00000001, 0x0500001b, 0x001000f2, + 0x00000000, 0x00100e46, 0x00000000, 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00107e46, 0x00000000, 0x05000056, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x0a000038, + 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x3b808081, 0x3b808081, 0x3b808081, + 0x3b808081, 0x0100003e, + }; + static const DWORD ps_sample_code[] = { #if 0 Texture2D t; @@ -2922,25 +3059,241 @@ 0x3b088889, 0x00000000, 0x00000000, 0x09000045, 0x001020f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e, }; + static const DWORD ps_sample_b_code[] = + { +#if 0 + Texture2D t; + SamplerState s; + + float bias; + + float4 main(float4 position : SV_POSITION) : SV_Target + { + float2 p; + + p.x = position.x / 640.0f; + p.y = position.y / 480.0f; + return t.SampleBias(s, p, bias); + } +#endif + 0x43425844, 0xc39b0686, 0x8244a7fc, 0x14c0b97a, 0x2900b3b7, 0x00000001, 0x00000150, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000b4, 0x00000040, + 0x0000002d, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, + 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000, + 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x0c00004a, + 0x001020f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x0020800a, 0x00000000, 0x00000000, 0x0100003e, + }; + static const DWORD ps_sample_l_code[] = + { +#if 0 + Texture2D t; + SamplerState s; + + float level; + + float4 main(float4 position : SV_POSITION) : SV_Target + { + float2 p; + + p.x = position.x / 640.0f; + p.y = position.y / 480.0f; + return t.SampleLevel(s, p, level); + } +#endif + 0x43425844, 0x61e05d85, 0x2a7300fb, 0x0a83706b, 0x889d1683, 0x00000001, 0x00000150, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000b4, 0x00000040, + 0x0000002d, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000, 0x00000000, + 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, + 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000, + 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x0c000048, + 0x001020f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, + 0x0020800a, 0x00000000, 0x00000000, 0x0100003e, + }; + static const struct shader ps_ld = {ps_ld_code, sizeof(ps_ld_code)}; + static const struct shader ps_ld_sint8 = {ps_ld_sint8_code, sizeof(ps_ld_sint8_code)}; + static const struct shader ps_ld_uint8 = {ps_ld_uint8_code, sizeof(ps_ld_uint8_code)}; + static const struct shader ps_sample = {ps_sample_code, sizeof(ps_sample_code)}; + static const struct shader ps_sample_b = {ps_sample_b_code, sizeof(ps_sample_b_code)}; + static const struct shader ps_sample_l = {ps_sample_l_code, sizeof(ps_sample_l_code)}; static const struct { - float x, y; + struct vec2 position; } quad[] = { - {-1.0f, -1.0f}, - {-1.0f, 1.0f}, - { 1.0f, -1.0f}, - { 1.0f, 1.0f}, + {{-1.0f, -1.0f}}, + {{-1.0f, 1.0f}}, + {{ 1.0f, -1.0f}}, + {{ 1.0f, 1.0f}}, }; - static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f}; - static const DWORD bitmap_data[] = + static const DWORD rgba_level_0[] = { 0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00, 0xffff0000, 0xffff00ff, 0xff000000, 0xff7f7f7f, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, }; + static const DWORD rgba_level_1[] = + { + 0xffffffff, 0xff0000ff, + 0xff000000, 0xff00ff00, + }; + static const DWORD rgba_level_2[] = + { + 0xffff0000, + }; + static const BYTE bc1_data[4 * 8] = + { + 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + }; + static const BYTE bc2_data[4 * 16] = + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + }; + static const BYTE bc3_data[4 * 16] = + { + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + }; + static const struct texture rgba_texture = + { + 4, 4, 3, DXGI_FORMAT_R8G8B8A8_UNORM, + { + {rgba_level_0, 4 * sizeof(*rgba_level_0), 0}, + {rgba_level_1, 2 * sizeof(*rgba_level_1), 0}, + {rgba_level_2, sizeof(*rgba_level_2), 0}, + } + }; + static const struct texture bc1_texture = {8, 8, 1, DXGI_FORMAT_BC1_UNORM, {{bc1_data, 2 * 8}}}; + static const struct texture bc2_texture = {8, 8, 1, DXGI_FORMAT_BC2_UNORM, {{bc2_data, 2 * 16}}}; + static const struct texture bc3_texture = {8, 8, 1, DXGI_FORMAT_BC3_UNORM, {{bc3_data, 2 * 16}}}; + static const struct texture sint8_texture = {4, 4, 1, DXGI_FORMAT_R8G8B8A8_SINT, + {{rgba_level_0, 4 * sizeof(*rgba_level_0)}}}; + static const struct texture uint8_texture = {4, 4, 1, DXGI_FORMAT_R8G8B8A8_UINT, + {{rgba_level_0, 4 * sizeof(*rgba_level_0)}}}; + static const DWORD level_1_colors[] = + { + 0xffffffff, 0xffffffff, 0xff0000ff, 0xff0000ff, + 0xffffffff, 0xffffffff, 0xff0000ff, 0xff0000ff, + 0xff000000, 0xff000000, 0xff00ff00, 0xff00ff00, + 0xff000000, 0xff000000, 0xff00ff00, 0xff00ff00, + }; + static const DWORD lerp_1_2_colors[] = + { + 0xffff7f7f, 0xffff7f7f, 0xff7f007f, 0xff7f007f, + 0xffff7f7f, 0xffff7f7f, 0xff7f007f, 0xff7f007f, + 0xff7f0000, 0xff7f0000, 0xff7f7f00, 0xff7f7f00, + 0xff7f0000, 0xff7f0000, 0xff7f7f00, 0xff7f7f00, + }; + static const DWORD level_2_colors[] = + { + 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + }; + static const DWORD bc_colors[] = + { + 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xff00ff00, + 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xff00ff00, + 0xffff0000, 0xffff0000, 0xffffffff, 0xffffffff, + 0xffff0000, 0xffff0000, 0xffffffff, 0xffffffff, + }; + static const DWORD sint8_colors[] = + { + 0x7e80807e, 0x7e807e7e, 0x7e807e80, 0x7e7e7e80, + 0x7e7e8080, 0x7e7e7f7f, 0x7e808080, 0x7effffff, + 0x7e7e7e7e, 0x7e7e7e7e, 0x7e7e7e7e, 0x7e808080, + 0x7e7e7e7e, 0x7e7f7f7f, 0x7e7f7f7f, 0x7e7f7f7f, + }; + static const DWORD zero_colors[4 * 4] = {0}; + static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f}; + + static const struct test + { + const struct shader *ps; + const struct texture *texture; + D3D11_FILTER filter; + float lod_bias; + float min_lod; + float max_lod; + float miplevel; + const DWORD *expected_colors; + } + tests[] = + { + {&ps_ld, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, rgba_level_0}, + {&ps_ld, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 1.0f, level_1_colors}, + {&ps_ld, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 2.0f, level_2_colors}, + {&ps_ld, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 3.0f, zero_colors}, + {&ps_ld, &bc1_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_ld, &bc1_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 1.0f, zero_colors}, + {&ps_ld, &bc2_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_ld, &bc2_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 1.0f, zero_colors}, + {&ps_ld, &bc3_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_ld, &bc3_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 1.0f, zero_colors}, + {&ps_ld_sint8, &sint8_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, sint8_colors}, + {&ps_ld_uint8, &uint8_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, rgba_level_0}, + {&ps_sample, &bc1_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_sample, &bc2_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_sample, &bc3_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, bc_colors}, + {&ps_sample, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 0.0f, rgba_level_0}, + {&ps_sample, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 0.0f, rgba_level_0}, + {&ps_sample, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 2.0f, 0.0f, D3D11_FLOAT32_MAX, 0.0f, rgba_level_0}, + {&ps_sample, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 8.0f, 0.0f, D3D11_FLOAT32_MAX, 0.0f, level_1_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 0.0f, rgba_level_0}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 8.0f, 0.0f, D3D11_FLOAT32_MAX, 0.0f, level_1_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 8.0f, level_1_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 8.4f, level_1_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 8.5f, level_2_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 9.0f, level_2_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 2.0f, 1.0f, rgba_level_0}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 2.0f, 9.0f, level_2_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 1.0f, 9.0f, level_1_colors}, + {&ps_sample_b, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, 0.0f, 9.0f, rgba_level_0}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, -1.0f, rgba_level_0}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 0.0f, rgba_level_0}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 0.4f, rgba_level_0}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 0.5f, level_1_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 1.0f, level_1_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 1.4f, level_1_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 1.5f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 2.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 3.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 4.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, 0.0f, 0.0f, D3D11_FLOAT32_MAX, 1.5f, lerp_1_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 0.0f, D3D11_FLOAT32_MAX, -2.0f, rgba_level_0}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 0.0f, D3D11_FLOAT32_MAX, -1.0f, level_1_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 0.0f, D3D11_FLOAT32_MAX, 0.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 0.0f, D3D11_FLOAT32_MAX, 1.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 0.0f, D3D11_FLOAT32_MAX, 1.5f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 2.0f, 2.0f, -9.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 2.0f, 2.0f, -1.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 2.0f, 2.0f, 0.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 2.0f, 2.0f, 1.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, 2.0f, 2.0f, 2.0f, 9.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 2.0f, 2.0f, 2.0f, -9.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 2.0f, 2.0f, 2.0f, -1.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 2.0f, 2.0f, 2.0f, 0.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 2.0f, 2.0f, 2.0f, 1.0f, level_2_colors}, + {&ps_sample_l, &rgba_texture, D3D11_FILTER_MIN_MAG_MIP_POINT, 2.0f, 2.0f, 2.0f, 9.0f, level_2_colors}, + }; if (!(device = create_device(NULL))) { @@ -2971,9 +3324,40 @@ hr = ID3D11Device_CreateBuffer(device, &buffer_desc, &resource_data, &vb); ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr); + buffer_desc.ByteWidth = sizeof(miplevel); + buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + + hr = ID3D11Device_CreateBuffer(device, &buffer_desc, NULL, &cb); + ok(SUCCEEDED(hr), "Failed to create constant buffer, hr %#x.\n", hr); + + hr = ID3D11Device_CreateVertexShader(device, vs_code, sizeof(vs_code), NULL, &vs); + ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); + + hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)backbuffer, NULL, &rtv); + ok(SUCCEEDED(hr), "Failed to create rendertarget view, hr %#x.\n", hr); + + ID3D11Device_GetImmediateContext(device, &context); + + ID3D11DeviceContext_OMSetRenderTargets(context, 1, &rtv, NULL); + ID3D11DeviceContext_IASetInputLayout(context, input_layout); + ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + stride = sizeof(*quad); + offset = 0; + ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &vb, &stride, &offset); + ID3D11DeviceContext_VSSetShader(context, vs, NULL, 0); + ID3D11DeviceContext_PSSetConstantBuffers(context, 0, 1, &cb); + + vp.TopLeftX = 0.0f; + vp.TopLeftY = 0.0f; + vp.Width = 640.0f; + vp.Height = 480.0f; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + texture_desc.Width = 4; texture_desc.Height = 4; - texture_desc.MipLevels = 1; + texture_desc.MipLevels = 3; texture_desc.ArraySize = 1; texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; texture_desc.SampleDesc.Count = 1; @@ -2983,15 +3367,6 @@ texture_desc.CPUAccessFlags = 0; texture_desc.MiscFlags = 0; - resource_data.pSysMem = bitmap_data; - resource_data.SysMemPitch = 4 * sizeof(*bitmap_data); - - hr = ID3D11Device_CreateTexture2D(device, &texture_desc, &resource_data, &texture); - ok(SUCCEEDED(hr), "Failed to create 2d texture, hr %#x.\n", hr); - - hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)texture, NULL, &ps_srv); - ok(SUCCEEDED(hr), "Failed to create shader resource view, hr %#x.\n", hr); - sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; @@ -3004,68 +3379,104 @@ sampler_desc.BorderColor[2] = 0.0f; sampler_desc.BorderColor[3] = 0.0f; sampler_desc.MinLOD = 0.0f; - sampler_desc.MaxLOD = 0.0f; + sampler_desc.MaxLOD = D3D11_FLOAT32_MAX; - hr = ID3D11Device_CreateSamplerState(device, &sampler_desc, &sampler_state); - ok(SUCCEEDED(hr), "Failed to create sampler state, hr %#x.\n", hr); + ps = NULL; + srv = NULL; + sampler = NULL; + texture = NULL; + current_ps = NULL; + current_texture = NULL; + for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) + { + const struct test *test = &tests[i]; - hr = ID3D11Device_CreateVertexShader(device, vs_code, sizeof(vs_code), NULL, &vs); - ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); - hr = ID3D11Device_CreatePixelShader(device, ps_code, sizeof(ps_code), NULL, &ps); - ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); + if (current_ps != test->ps) + { + if (ps) + ID3D11PixelShader_Release(ps); - hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)backbuffer, NULL, &backbuffer_rtv); - ok(SUCCEEDED(hr), "Failed to create rendertarget view, hr %#x.\n", hr); + current_ps = test->ps; - ID3D11Device_GetImmediateContext(device, &context); + hr = ID3D11Device_CreatePixelShader(device, current_ps->code, current_ps->size, NULL, &ps); + ok(SUCCEEDED(hr), "Test %u: Failed to create pixel shader, hr %#x.\n", i, hr); - ID3D11DeviceContext_OMSetRenderTargets(context, 1, &backbuffer_rtv, NULL); - ID3D11DeviceContext_IASetInputLayout(context, input_layout); - ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - stride = sizeof(*quad); - offset = 0; - ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &vb, &stride, &offset); - ID3D11DeviceContext_VSSetShader(context, vs, NULL, 0); - ID3D11DeviceContext_PSSetShaderResources(context, 0, 1, &ps_srv); - ID3D11DeviceContext_PSSetSamplers(context, 0, 1, &sampler_state); - ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0); + ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0); + } - vp.TopLeftX = 0.0f; - vp.TopLeftY = 0.0f; - vp.Width = 640.0f; - vp.Height = 480.0f; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + if (current_texture != test->texture) + { + if (texture) + ID3D11Texture2D_Release(texture); + if (srv) + ID3D11ShaderResourceView_Release(srv); - ID3D11DeviceContext_ClearRenderTargetView(context, backbuffer_rtv, red); + current_texture = test->texture; - ID3D11DeviceContext_Draw(context, 4, 0); + texture_desc.Width = current_texture->width; + texture_desc.Height = current_texture->height; + texture_desc.MipLevels = current_texture->miplevel_count; + texture_desc.Format = current_texture->format; - get_texture_readback(backbuffer, &rb); - for (i = 0; i < 4; ++i) - { - for (j = 0; j < 4; ++j) + hr = ID3D11Device_CreateTexture2D(device, &texture_desc, current_texture->data, &texture); + ok(SUCCEEDED(hr), "Test %u: Failed to create 2d texture, hr %#x.\n", i, hr); + + hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)texture, NULL, &srv); + ok(SUCCEEDED(hr), "Test %u: Failed to create shader resource view, hr %#x.\n", i, hr); + + ID3D11DeviceContext_PSSetShaderResources(context, 0, 1, &srv); + } + + if (!sampler || (sampler_desc.Filter != test->filter + || sampler_desc.MipLODBias != test->lod_bias + || sampler_desc.MinLOD != test->min_lod + || sampler_desc.MaxLOD != test->max_lod)) + { + if (sampler) + ID3D11SamplerState_Release(sampler); + + sampler_desc.Filter = test->filter; + sampler_desc.MipLODBias = test->lod_bias; + sampler_desc.MinLOD = test->min_lod; + sampler_desc.MaxLOD = test->max_lod; + + hr = ID3D11Device_CreateSamplerState(device, &sampler_desc, &sampler); + ok(SUCCEEDED(hr), "Test %u: Failed to create sampler state, hr %#x.\n", i, hr); + + ID3D11DeviceContext_PSSetSamplers(context, 0, 1, &sampler); + } + + miplevel.x = test->miplevel; + ID3D11DeviceContext_UpdateSubresource(context, (ID3D11Resource *)cb, 0, NULL, &miplevel, 0, 0); + + ID3D11DeviceContext_ClearRenderTargetView(context, rtv, red); + ID3D11DeviceContext_Draw(context, 4, 0); + + get_texture_readback(backbuffer, &rb); + for (x = 0; x < 4; ++x) { - color = get_readback_color(&rb, 80 + j * 160, 60 + i * 120); - ok(compare_color(color, bitmap_data[j + i * 4], 1), - "Got unexpected color 0x%08x at (%u, %u), expected 0x%08x.\n", - color, j, i, bitmap_data[j + i * 4]); + for (y = 0; y < 4; ++y) + { + color = get_readback_color(&rb, 80 + x * 160, 60 + y * 120); + ok(compare_color(color, test->expected_colors[y * 4 + x], 1), + "Test %u: Got unexpected color 0x%08x at (%u, %u).\n", i, color, x, y); + } } + release_texture_readback(&rb); } - release_texture_readback(&rb); - + ID3D11ShaderResourceView_Release(srv); + ID3D11SamplerState_Release(sampler); + ID3D11Texture2D_Release(texture); ID3D11PixelShader_Release(ps); + + ID3D11Buffer_Release(cb); ID3D11VertexShader_Release(vs); - ID3D11SamplerState_Release(sampler_state); - ID3D11ShaderResourceView_Release(ps_srv); - ID3D11Texture2D_Release(texture); ID3D11Buffer_Release(vb); ID3D11InputLayout_Release(input_layout); - ID3D11RenderTargetView_Release(backbuffer_rtv); + ID3D11RenderTargetView_Release(rtv); ID3D11Texture2D_Release(backbuffer); - IDXGISwapChain_Release(swapchain); ID3D11DeviceContext_Release(context); + IDXGISwapChain_Release(swapchain); refcount = ID3D11Device_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); DestroyWindow(window); @@ -3962,6 +4373,9 @@ set_box(&box, 4, 4, 0, 3, 1, 1); ID3D11DeviceContext_UpdateSubresource(context, (ID3D11Resource *)texture, 0, &box, bitmap_data, sizeof(*bitmap_data), 0); + set_box(&box, 0, 0, 0, 4, 4, 0); + ID3D11DeviceContext_UpdateSubresource(context, (ID3D11Resource *)texture, 0, &box, + bitmap_data, 4 * sizeof(*bitmap_data), 0); ID3D11DeviceContext_Draw(context, 4, 0); get_texture_readback(backbuffer, &rb); for (i = 0; i < 4; ++i) @@ -4008,16 +4422,285 @@ DestroyWindow(window); } -static void test_resource_map(void) +static void test_copy_subresource_region(void) { - D3D11_MAPPED_SUBRESOURCE mapped_subresource; - D3D11_TEXTURE3D_DESC texture3d_desc; - D3D11_TEXTURE2D_DESC texture2d_desc; + ID3D11Texture2D *dst_texture, *src_texture; + ID3D11RenderTargetView *backbuffer_rtv; + D3D11_SUBRESOURCE_DATA resource_data; + D3D11_TEXTURE2D_DESC texture_desc; + ID3D11SamplerState *sampler_state; + ID3D11ShaderResourceView *ps_srv; + D3D11_SAMPLER_DESC sampler_desc; + ID3D11InputLayout *input_layout; D3D11_BUFFER_DESC buffer_desc; ID3D11DeviceContext *context; - ID3D11Texture3D *texture3d; - ID3D11Texture2D *texture2d; - ID3D11Buffer *buffer; + ID3D11Texture2D *backbuffer; + unsigned int stride, offset; + struct texture_readback rb; + IDXGISwapChain *swapchain; + ID3D11VertexShader *vs; + ID3D11PixelShader *ps; + ID3D11Device *device; + D3D11_VIEWPORT vp; + unsigned int i, j; + ID3D11Buffer *vb; + ULONG refcount; + D3D11_BOX box; + DWORD color; + HWND window; + HRESULT hr; + + static const D3D11_INPUT_ELEMENT_DESC layout_desc[] = + { + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }; + static const DWORD vs_code[] = + { +#if 0 + float4 main(float4 position : POSITION) : SV_POSITION + { + return position; + } +#endif + 0x43425844, 0xa7a2f22d, 0x83ff2560, 0xe61638bd, 0x87e3ce90, 0x00000001, 0x000000d8, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, + 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040, + 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, + 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, + }; + static const DWORD ps_code[] = + { +#if 0 + Texture2D t; + SamplerState s; + + float4 main(float4 position : SV_POSITION) : SV_Target + { + float2 p; + + p.x = position.x / 640.0f; + p.y = position.y / 480.0f; + return t.Sample(s, p); + } +#endif + 0x43425844, 0x1ce9b612, 0xc8176faa, 0xd37844af, 0xdb515605, 0x00000001, 0x00000134, 0x00000003, + 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000098, 0x00000040, + 0x00000026, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, + 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, + 0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, + 0x3b088889, 0x00000000, 0x00000000, 0x09000045, 0x001020f2, 0x00000000, 0x00100046, 0x00000000, + 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e, + }; + static const struct + { + float x, y; + } + quad[] = + { + {-1.0f, -1.0f}, + {-1.0f, 1.0f}, + { 1.0f, -1.0f}, + { 1.0f, 1.0f}, + }; + static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f}; + static const DWORD bitmap_data[] = + { + 0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00, + 0xffff0000, 0xffff00ff, 0xff000000, 0xff7f7f7f, + 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + }; + static const DWORD expected_colors[] = + { + 0xffffffff, 0xff000000, 0xff000000, 0xff000000, + 0xffffff00, 0xff0000ff, 0xff00ffff, 0x00000000, + 0xff7f7f7f, 0xffff0000, 0xffff00ff, 0xff7f7f7f, + 0xffffffff, 0xffffffff, 0xff000000, 0x00000000, + }; + + if (!(device = create_device(NULL))) + { + skip("Failed to create device.\n"); + return; + } + window = CreateWindowA("static", "d3d11_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + swapchain = create_swapchain(device, window, TRUE); + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D11Texture2D, (void **)&backbuffer); + ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr); + + hr = ID3D11Device_CreateInputLayout(device, layout_desc, sizeof(layout_desc) / sizeof(*layout_desc), + vs_code, sizeof(vs_code), &input_layout); + ok(SUCCEEDED(hr), "Failed to create input layout, hr %#x.\n", hr); + + buffer_desc.ByteWidth = sizeof(quad); + buffer_desc.Usage = D3D11_USAGE_DEFAULT; + buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + buffer_desc.CPUAccessFlags = 0; + buffer_desc.MiscFlags = 0; + buffer_desc.StructureByteStride = 0; + + resource_data.pSysMem = quad; + resource_data.SysMemPitch = 0; + resource_data.SysMemSlicePitch = 0; + + hr = ID3D11Device_CreateBuffer(device, &buffer_desc, &resource_data, &vb); + ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr); + + texture_desc.Width = 4; + texture_desc.Height = 4; + texture_desc.MipLevels = 1; + texture_desc.ArraySize = 1; + texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + texture_desc.SampleDesc.Count = 1; + texture_desc.SampleDesc.Quality = 0; + texture_desc.Usage = D3D11_USAGE_DEFAULT; + texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + texture_desc.CPUAccessFlags = 0; + texture_desc.MiscFlags = 0; + + hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &dst_texture); + ok(SUCCEEDED(hr), "Failed to create 2d texture, hr %#x.\n", hr); + + texture_desc.Usage = D3D11_USAGE_IMMUTABLE; + + resource_data.pSysMem = bitmap_data; + resource_data.SysMemPitch = 4 * sizeof(*bitmap_data); + + hr = ID3D11Device_CreateTexture2D(device, &texture_desc, &resource_data, &src_texture); + ok(SUCCEEDED(hr), "Failed to create 2d texture, hr %#x.\n", hr); + + hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)dst_texture, NULL, &ps_srv); + ok(SUCCEEDED(hr), "Failed to create shader resource view, hr %#x.\n", hr); + + sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.MipLODBias = 0.0f; + sampler_desc.MaxAnisotropy = 0; + sampler_desc.ComparisonFunc = D3D11_COMPARISON_NEVER; + sampler_desc.BorderColor[0] = 0.0f; + sampler_desc.BorderColor[1] = 0.0f; + sampler_desc.BorderColor[2] = 0.0f; + sampler_desc.BorderColor[3] = 0.0f; + sampler_desc.MinLOD = 0.0f; + sampler_desc.MaxLOD = 0.0f; + + hr = ID3D11Device_CreateSamplerState(device, &sampler_desc, &sampler_state); + ok(SUCCEEDED(hr), "Failed to create sampler state, hr %#x.\n", hr); + + hr = ID3D11Device_CreateVertexShader(device, vs_code, sizeof(vs_code), NULL, &vs); + ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr); + hr = ID3D11Device_CreatePixelShader(device, ps_code, sizeof(ps_code), NULL, &ps); + ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); + + hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)backbuffer, NULL, &backbuffer_rtv); + ok(SUCCEEDED(hr), "Failed to create rendertarget view, hr %#x.\n", hr); + + ID3D11Device_GetImmediateContext(device, &context); + + ID3D11DeviceContext_OMSetRenderTargets(context, 1, &backbuffer_rtv, NULL); + ID3D11DeviceContext_IASetInputLayout(context, input_layout); + ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + stride = sizeof(*quad); + offset = 0; + ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &vb, &stride, &offset); + ID3D11DeviceContext_VSSetShader(context, vs, NULL, 0); + ID3D11DeviceContext_PSSetShaderResources(context, 0, 1, &ps_srv); + ID3D11DeviceContext_PSSetSamplers(context, 0, 1, &sampler_state); + ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0); + + vp.TopLeftX = 0.0f; + vp.TopLeftY = 0.0f; + vp.Width = 640.0f; + vp.Height = 480.0f; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + ID3D11DeviceContext_RSSetViewports(context, 1, &vp); + + ID3D11DeviceContext_ClearRenderTargetView(context, backbuffer_rtv, red); + + set_box(&box, 0, 0, 0, 2, 2, 1); + ID3D11DeviceContext_CopySubresourceRegion(context, (ID3D11Resource *)dst_texture, 0, + 1, 1, 0, (ID3D11Resource *)src_texture, 0, &box); + set_box(&box, 1, 2, 0, 4, 3, 1); + ID3D11DeviceContext_CopySubresourceRegion(context, (ID3D11Resource *)dst_texture, 0, + 0, 3, 0, (ID3D11Resource *)src_texture, 0, &box); + set_box(&box, 0, 3, 0, 4, 4, 1); + ID3D11DeviceContext_CopySubresourceRegion(context, (ID3D11Resource *)dst_texture, 0, + 0, 0, 0, (ID3D11Resource *)src_texture, 0, &box); + set_box(&box, 3, 0, 0, 4, 2, 1); + ID3D11DeviceContext_CopySubresourceRegion(context, (ID3D11Resource *)dst_texture, 0, + 0, 1, 0, (ID3D11Resource *)src_texture, 0, &box); + set_box(&box, 3, 1, 0, 4, 2, 1); + ID3D11DeviceContext_CopySubresourceRegion(context, (ID3D11Resource *)dst_texture, 0, + 3, 2, 0, (ID3D11Resource *)src_texture, 0, &box); + set_box(&box, 0, 0, 0, 4, 4, 0); + ID3D11DeviceContext_CopySubresourceRegion(context, (ID3D11Resource *)dst_texture, 0, + 0, 0, 0, (ID3D11Resource *)src_texture, 0, &box); + ID3D11DeviceContext_Draw(context, 4, 0); + get_texture_readback(backbuffer, &rb); + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + color = get_readback_color(&rb, 80 + j * 160, 60 + i * 120); + ok(compare_color(color, expected_colors[j + i * 4], 1), + "Got unexpected color 0x%08x at (%u, %u), expected 0x%08x.\n", + color, j, i, expected_colors[j + i * 4]); + } + } + release_texture_readback(&rb); + + ID3D11DeviceContext_CopySubresourceRegion(context, (ID3D11Resource *)dst_texture, 0, + 0, 0, 0, (ID3D11Resource *)src_texture, 0, NULL); + ID3D11DeviceContext_Draw(context, 4, 0); + get_texture_readback(backbuffer, &rb); + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + color = get_readback_color(&rb, 80 + j * 160, 60 + i * 120); + ok(compare_color(color, bitmap_data[j + i * 4], 1), + "Got unexpected color 0x%08x at (%u, %u), expected 0x%08x.\n", + color, j, i, bitmap_data[j + i * 4]); + } + } + release_texture_readback(&rb); + + ID3D11PixelShader_Release(ps); + ID3D11VertexShader_Release(vs); + ID3D11SamplerState_Release(sampler_state); + ID3D11ShaderResourceView_Release(ps_srv); + ID3D11Texture2D_Release(dst_texture); + ID3D11Texture2D_Release(src_texture); + ID3D11Buffer_Release(vb); + ID3D11InputLayout_Release(input_layout); + ID3D11RenderTargetView_Release(backbuffer_rtv); + ID3D11Texture2D_Release(backbuffer); + IDXGISwapChain_Release(swapchain); + ID3D11DeviceContext_Release(context); + refcount = ID3D11Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + +static void test_resource_map(void) +{ + D3D11_MAPPED_SUBRESOURCE mapped_subresource; + D3D11_TEXTURE3D_DESC texture3d_desc; + D3D11_TEXTURE2D_DESC texture2d_desc; + D3D11_BUFFER_DESC buffer_desc; + ID3D11DeviceContext *context; + ID3D11Texture3D *texture3d; + ID3D11Texture2D *texture2d; + ID3D11Buffer *buffer; ID3D11Device *device; ULONG refcount; HRESULT hr; @@ -4150,6 +4833,170 @@ ok(!refcount, "Device has %u references left.\n", refcount); } +static void test_multisample_init(void) +{ + D3D11_TEXTURE2D_DESC desc; + ID3D11Texture2D *backbuffer, *multi; + ID3D11Device *device; + ID3D11DeviceContext *context; + ULONG refcount; + DWORD color; + HRESULT hr; + unsigned int x, y; + struct texture_readback rb; + BOOL all_zero = TRUE; + UINT count = 0; + HWND window; + IDXGISwapChain *swapchain; + ID3D11RenderTargetView *rtview; + static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f}; + + if (!(device = create_device(NULL))) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 2, &count); + ok(SUCCEEDED(hr), "Failed to get quality levels, hr %#x.\n", hr); + if (!count) + { + skip("Multisampling not supported for DXGI_FORMAT_R8G8B8A8_UNORM, skipping tests.\n"); + goto done; + } + + window = CreateWindowA("static", "d3d11_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + swapchain = create_swapchain(device, window, TRUE); + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_ID3D11Texture2D, (void **)&backbuffer); + ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr); + hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)backbuffer, NULL, &rtview); + ok(SUCCEEDED(hr), "Failed to create rendertarget view, hr %#x.\n", hr); + + ID3D11Device_GetImmediateContext(device, &context); + ID3D11DeviceContext_ClearRenderTargetView(context, rtview, white); + + desc.Width = 640; + desc.Height = 480; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 2; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &multi); + ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); + + ID3D11DeviceContext_ResolveSubresource(context, (ID3D11Resource *)backbuffer, 0, + (ID3D11Resource *)multi, 0, DXGI_FORMAT_R8G8B8A8_UNORM); + + get_texture_readback(backbuffer, &rb); + for (y = 0; y < 480; ++y) + { + for (x = 0; x < 640; ++x) + { + color = get_readback_color(&rb, x, y); + if (!compare_color(color, 0x00000000, 0)) + { + all_zero = FALSE; + break; + } + } + if (!all_zero) + break; + } + release_texture_readback(&rb); + todo_wine ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y); + + ID3D11DeviceContext_Release(context); + ID3D11RenderTargetView_Release(rtview); + ID3D11Texture2D_Release(backbuffer); + IDXGISwapChain_Release(swapchain); + ID3D11Texture2D_Release(multi); + DestroyWindow(window); +done: + refcount = ID3D11Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + +static void test_check_multisample_quality_levels(void) +{ + ID3D11Device *device; + UINT quality_levels; + ULONG refcount; + HRESULT hr; + + if (!(device = create_device(NULL))) + { + skip("Failed to create device.\n"); + return; + } + + ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 2, &quality_levels); + if (!quality_levels) + { + skip("Multisampling not supported for DXGI_FORMAT_R8G8B8A8_UNORM, skipping test.\n"); + goto done; + } + + quality_levels = 0xdeadbeef; + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_UNKNOWN, 2, &quality_levels); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + quality_levels = 0xdeadbeef; + hr = ID3D11Device_CheckMultisampleQualityLevels(device, 65536, 2, &quality_levels); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + todo_wine ok(quality_levels == 0xdeadbeef, "Got unexpected quality_levels %u.\n", quality_levels); + + quality_levels = 0xdeadbeef; + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 0, NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 0, &quality_levels); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + + quality_levels = 0xdeadbeef; + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 1, NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 1, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels); + + quality_levels = 0xdeadbeef; + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 2, NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 2, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + + /* We assume 15 samples multisampling is never supported in practice. */ + quality_levels = 0xdeadbeef; + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 15, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 32, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + quality_levels = 0xdeadbeef; + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 33, &quality_levels); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + quality_levels = 0xdeadbeef; + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_R8G8B8A8_UNORM, 64, &quality_levels); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + + hr = ID3D11Device_CheckMultisampleQualityLevels(device, DXGI_FORMAT_BC3_UNORM, 2, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(!quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + +done: + refcount = ID3D11Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + START_TEST(d3d11) { test_create_device(); @@ -4178,5 +5025,8 @@ test_il_append_aligned(); test_fragment_coords(); test_update_subresource(); + test_copy_subresource_region(); test_resource_map(); + test_multisample_init(); + test_check_multisample_quality_levels(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d11/texture.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d11/texture.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d11/texture.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d11/texture.c 2016-02-08 19:32:34.000000000 +0000 @@ -462,7 +462,7 @@ if (desc->SampleDesc.Count > 1) FIXME("Multisampled textures not implemented.\n"); - wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE; + wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); wined3d_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = desc->SampleDesc.Quality; @@ -482,6 +482,8 @@ WARN("Failed to create wined3d texture, hr %#x.\n", hr); wined3d_private_store_cleanup(&texture->private_store); wined3d_mutex_unlock(); + if (hr == WINED3DERR_NOTAVAILABLE) + hr = E_INVALIDARG; return hr; } texture->desc.MipLevels = levels; @@ -914,7 +916,7 @@ wined3d_private_store_init(&texture->private_store); texture->desc = *desc; - wined3d_desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE; + wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_3D; wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = 0; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d11/utils.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d11/utils.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d11/utils.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d11/utils.c 2016-02-08 19:32:34.000000000 +0000 @@ -24,22 +24,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d11); -#define WINE_D3D10_TO_STR(x) case x: return #x +#define WINE_D3D_TO_STR(x) case x: return #x const char *debug_d3d10_primitive_topology(D3D10_PRIMITIVE_TOPOLOGY topology) { switch (topology) { - WINE_D3D10_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED); - WINE_D3D10_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_POINTLIST); - WINE_D3D10_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINELIST); - WINE_D3D10_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP); - WINE_D3D10_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - WINE_D3D10_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - WINE_D3D10_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ); - WINE_D3D10_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ); - WINE_D3D10_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ); - WINE_D3D10_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_POINTLIST); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINELIST); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ); + WINE_D3D_TO_STR(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ); default: FIXME("Unrecognized D3D10_PRIMITIVE_TOPOLOGY %#x\n", topology); return "unrecognized"; @@ -50,102 +50,102 @@ { switch(format) { - WINE_D3D10_TO_STR(DXGI_FORMAT_UNKNOWN); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32B32A32_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32B32A32_FLOAT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32B32A32_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32B32A32_SINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32B32_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32B32_FLOAT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32B32_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32B32_SINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16B16A16_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16B16A16_FLOAT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16B16A16_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16B16A16_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16B16A16_SNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16B16A16_SINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32_FLOAT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G32_SINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32G8X24_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_D32_FLOAT_S8X24_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R10G10B10A2_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_R10G10B10A2_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R10G10B10A2_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R11G11B10_FLOAT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8B8A8_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8B8A8_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8B8A8_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8B8A8_SNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8B8A8_SINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16_FLOAT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16_SNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16G16_SINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_D32_FLOAT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32_FLOAT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R32_SINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R24G8_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_D24_UNORM_S8_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R24_UNORM_X8_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_X24_TYPELESS_G8_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8_SNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8_SINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16_FLOAT); - WINE_D3D10_TO_STR(DXGI_FORMAT_D16_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16_SNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R16_SINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8_UINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8_SNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8_SINT); - WINE_D3D10_TO_STR(DXGI_FORMAT_A8_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R1_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_R9G9B9E5_SHAREDEXP); - WINE_D3D10_TO_STR(DXGI_FORMAT_R8G8_B8G8_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_G8R8_G8B8_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC1_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC1_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC1_UNORM_SRGB); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC2_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC2_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC2_UNORM_SRGB); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC3_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC3_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC3_UNORM_SRGB); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC4_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC4_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC4_SNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC5_TYPELESS); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC5_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_BC5_SNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_B5G6R5_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_B5G5R5A1_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_B8G8R8A8_UNORM); - WINE_D3D10_TO_STR(DXGI_FORMAT_B8G8R8X8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_UNKNOWN); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32A32_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32A32_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32A32_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32A32_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32B32_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16B16A16_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G32_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32G8X24_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_D32_FLOAT_S8X24_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R10G10B10A2_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R10G10B10A2_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R10G10B10A2_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R11G11B10_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8B8A8_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16G16_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_D32_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R32_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R24G8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_D24_UNORM_S8_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R24_UNORM_X8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_X24_TYPELESS_G8_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_FLOAT); + WINE_D3D_TO_STR(DXGI_FORMAT_D16_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R16_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_R8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8_UINT); + WINE_D3D_TO_STR(DXGI_FORMAT_R8_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R8_SINT); + WINE_D3D_TO_STR(DXGI_FORMAT_A8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R1_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_R9G9B9E5_SHAREDEXP); + WINE_D3D_TO_STR(DXGI_FORMAT_R8G8_B8G8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_G8R8_G8B8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC1_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC1_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC1_UNORM_SRGB); + WINE_D3D_TO_STR(DXGI_FORMAT_BC2_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC2_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC2_UNORM_SRGB); + WINE_D3D_TO_STR(DXGI_FORMAT_BC3_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC3_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC3_UNORM_SRGB); + WINE_D3D_TO_STR(DXGI_FORMAT_BC4_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC4_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC4_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC5_TYPELESS); + WINE_D3D_TO_STR(DXGI_FORMAT_BC5_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_BC5_SNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_B5G6R5_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_B5G5R5A1_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_B8G8R8A8_UNORM); + WINE_D3D_TO_STR(DXGI_FORMAT_B8G8R8X8_UNORM); default: FIXME("Unrecognized DXGI_FORMAT %#x\n", format); return "unrecognized"; } } -#undef WINE_D3D10_TO_STR +#undef WINE_D3D_TO_STR DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/device.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/device.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/device.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/device.c 2016-02-08 19:32:34.000000000 +0000 @@ -619,7 +619,7 @@ { struct d3d8_surface *surface; - if (desc.resource_type == WINED3D_RTYPE_TEXTURE) + if (desc.resource_type == WINED3D_RTYPE_TEXTURE_2D) { IUnknown *parent = wined3d_resource_get_parent(resource); IDirect3DBaseTexture8 *texture; @@ -950,7 +950,7 @@ device, width, height, format, flags, surface, usage, pool, multisample_type, multisample_quality); - desc.resource_type = WINED3D_RTYPE_TEXTURE; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = multisample_type; desc.multisample_quality = multisample_quality; @@ -995,7 +995,7 @@ *surface = NULL; if (lockable) - flags |= WINED3D_SURFACE_MAPPABLE; + flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; return d3d8_device_create_surface(device, width, height, format, flags, surface, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, 0); @@ -1013,7 +1013,7 @@ *surface = NULL; /* TODO: Verify that Discard is false */ - return d3d8_device_create_surface(device, width, height, format, WINED3D_SURFACE_MAPPABLE, + return d3d8_device_create_surface(device, width, height, format, WINED3D_TEXTURE_CREATE_MAPPABLE, surface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, 0); } @@ -1028,7 +1028,7 @@ *surface = NULL; - return d3d8_device_create_surface(device, width, height, format, WINED3D_SURFACE_MAPPABLE, + return d3d8_device_create_surface(device, width, height, format, WINED3D_TEXTURE_CREATE_MAPPABLE, surface, 0, D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, 0); } @@ -1288,7 +1288,7 @@ } else { - hr = WINED3DERR_NOTFOUND; + hr = D3DERR_NOTFOUND; *depth_stencil = NULL; } wined3d_mutex_unlock(); @@ -3039,8 +3039,8 @@ TRACE("device_parent %p, container_parent %p, desc %p, texture %p.\n", device_parent, container_parent, desc, texture); - if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, - WINED3D_SURFACE_MAPPABLE, NULL, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, texture))) + if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, WINED3D_TEXTURE_CREATE_MAPPABLE, + NULL, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/directx.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/directx.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/directx.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/directx.c 2016-02-08 19:32:34.000000000 +0000 @@ -238,16 +238,38 @@ TRACE("iface %p, adapter %u, device_type %#x, adapter_format %#x, usage %#x, resource_type %#x, format %#x.\n", iface, adapter, device_type, adapter_format, usage, resource_type, format); + usage = usage & (WINED3DUSAGE_MASK | WINED3DUSAGE_QUERY_MASK); switch (resource_type) { + case D3DRTYPE_SURFACE: + wined3d_rtype = WINED3D_RTYPE_SURFACE; + break; + + case D3DRTYPE_VOLUME: + wined3d_rtype = WINED3D_RTYPE_VOLUME; + break; + + case D3DRTYPE_TEXTURE: + wined3d_rtype = WINED3D_RTYPE_TEXTURE_2D; + break; + + case D3DRTYPE_VOLUMETEXTURE: + wined3d_rtype = WINED3D_RTYPE_TEXTURE_3D; + break; + + case D3DRTYPE_CUBETEXTURE: + wined3d_rtype = WINED3D_RTYPE_TEXTURE_2D; + usage |= WINED3DUSAGE_LEGACY_CUBEMAP; + break; + case D3DRTYPE_VERTEXBUFFER: case D3DRTYPE_INDEXBUFFER: wined3d_rtype = WINED3D_RTYPE_BUFFER; break; default: - wined3d_rtype = resource_type; - break; + FIXME("Unhandled resource type %#x.\n", resource_type); + return WINED3DERR_INVALIDCALL; } wined3d_mutex_lock(); @@ -267,6 +289,9 @@ TRACE("iface %p, adapter %u, device_type %#x, format %#x, windowed %#x, multisample_type %#x.\n", iface, adapter, device_type, format, windowed, multisample_type); + if (multisample_type > D3DMULTISAMPLE_16_SAMPLES) + return D3DERR_INVALIDCALL; + wined3d_mutex_lock(); hr = wined3d_check_device_multisample_type(d3d8->wined3d, adapter, device_type, wined3dformat_from_d3dformat(format), windowed, diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/surface.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/surface.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/surface.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/surface.c 2016-02-08 19:32:34.000000000 +0000 @@ -204,26 +204,36 @@ struct wined3d_box box; struct wined3d_map_desc map_desc; HRESULT hr; + D3DRESOURCETYPE type; TRACE("iface %p, locked_rect %p, rect %s, flags %#x.\n", iface, locked_rect, wine_dbgstr_rect(rect), flags); wined3d_mutex_lock(); + + if (surface->texture) + type = IDirect3DBaseTexture8_GetType(&surface->texture->IDirect3DBaseTexture8_iface); + else + type = D3DRTYPE_SURFACE; + if (rect) { D3DSURFACE_DESC desc; IDirect3DSurface8_GetDesc(iface, &desc); - if ((rect->left < 0) + if (type != D3DRTYPE_TEXTURE + && ((rect->left < 0) || (rect->top < 0) || (rect->left >= rect->right) || (rect->top >= rect->bottom) || (rect->right > desc.Width) - || (rect->bottom > desc.Height)) + || (rect->bottom > desc.Height))) { WARN("Trying to lock an invalid rectangle, returning D3DERR_INVALIDCALL\n"); wined3d_mutex_unlock(); + locked_rect->Pitch = 0; + locked_rect->pBits = NULL; return D3DERR_INVALIDCALL; } box.left = rect->left; @@ -243,7 +253,7 @@ locked_rect->Pitch = map_desc.row_pitch; locked_rect->pBits = map_desc.data; } - else + else if (type != D3DRTYPE_TEXTURE) { locked_rect->Pitch = 0; locked_rect->pBits = NULL; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/tests/device.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/tests/device.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/tests/device.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/tests/device.c 2016-02-08 19:32:34.000000000 +0000 @@ -790,6 +790,120 @@ DestroyWindow(window); } +static void test_checkdevicemultisampletype(void) +{ + IDirect3D8 *d3d; + HWND window; + HRESULT hr; + + window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + ok(!!window, "Failed to create a window.\n"); + d3d = Direct3DCreate8(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + + if (IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES) == D3DERR_NOTAVAILABLE) + { + skip("Multisampling not supported for D3DFMT_X8R8G8B8, skipping test.\n"); + goto cleanup; + } + + hr = IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_UNKNOWN, TRUE, D3DMULTISAMPLE_NONE); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + hr = IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + 65536, TRUE, D3DMULTISAMPLE_NONE); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + + hr = IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONE); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + hr = IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, FALSE, D3DMULTISAMPLE_NONE); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + + hr = IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + + /* We assume D3DMULTISAMPLE_15_SAMPLES is never supported in practice. */ + hr = IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_15_SAMPLES); + ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, 65536); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_DXT5, TRUE, D3DMULTISAMPLE_2_SAMPLES); + ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr); + +cleanup: + IDirect3D8_Release(d3d); + DestroyWindow(window); +} + +static void test_invalid_multisample(void) +{ + IDirect3DDevice8 *device; + IDirect3DSurface8 *rt; + IDirect3D8 *d3d; + BOOL available; + ULONG refcount; + HWND window; + HRESULT hr; + + window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + ok(!!window, "Failed to create a window.\n"); + d3d = Direct3DCreate8(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + + if (!(device = create_device(d3d, window, NULL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + goto cleanup; + } + + available = SUCCEEDED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)); + + hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, + D3DFMT_X8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt); + if (available) + { + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + IDirect3DSurface8_Release(rt); + } + else + { + ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr); + } + + /* We assume D3DMULTISAMPLE_15_SAMPLES is never supported in practice. */ + available = SUCCEEDED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_15_SAMPLES)); + hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, + D3DFMT_X8R8G8B8, D3DMULTISAMPLE_15_SAMPLES, FALSE, &rt); + if (available) + { + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + IDirect3DSurface8_Release(rt); + } + else + { + ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr); + } + + refcount = IDirect3DDevice8_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +cleanup: + IDirect3D8_Release(d3d); + DestroyWindow(window); +} + static void test_cursor(void) { HMODULE user32_handle = GetModuleHandleA("user32.dll"); @@ -4632,15 +4746,35 @@ {136, 60, 144, 68}, /* left > surface */ {60, 136, 68, 144}, /* top > surface */ }; - IDirect3DSurface8 *surface = NULL; + IDirect3DSurface8 *surface; + IDirect3DTexture8 *texture; + IDirect3DCubeTexture8 *cube_texture; D3DLOCKED_RECT locked_rect; IDirect3DDevice8 *device; IDirect3D8 *d3d8; - unsigned int i; + unsigned int i, r; ULONG refcount; HWND window; BYTE *base; HRESULT hr; + unsigned int offset, expected_offset; + static const struct + { + D3DRESOURCETYPE type; + D3DPOOL pool; + const char *name; + BOOL validate, clear; + } + resources[] = + { + {D3DRTYPE_SURFACE, D3DPOOL_SCRATCH, "scratch surface", TRUE, TRUE}, + {D3DRTYPE_TEXTURE, D3DPOOL_MANAGED, "managed texture", FALSE, FALSE}, + {D3DRTYPE_TEXTURE, D3DPOOL_SYSTEMMEM, "sysmem texture", FALSE, FALSE}, + {D3DRTYPE_TEXTURE, D3DPOOL_SCRATCH, "scratch texture", FALSE, FALSE}, + {D3DRTYPE_CUBETEXTURE, D3DPOOL_MANAGED, "default cube texture", TRUE, TRUE}, + {D3DRTYPE_CUBETEXTURE, D3DPOOL_SYSTEMMEM, "sysmem cube texture", TRUE, TRUE}, + {D3DRTYPE_CUBETEXTURE, D3DPOOL_SCRATCH, "scratch cube texture", TRUE, TRUE}, + }; window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); @@ -4654,69 +4788,239 @@ return; } - hr = IDirect3DDevice8_CreateImageSurface(device, 128, 128, D3DFMT_A8R8G8B8, &surface); - ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); - hr = IDirect3DSurface8_LockRect(surface, &locked_rect, NULL, 0); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - base = locked_rect.pBits; - hr = IDirect3DSurface8_UnlockRect(surface); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); - - for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i) + for (r = 0; r < sizeof(resources) / sizeof(*resources); ++r) { - unsigned int offset, expected_offset; - const RECT *rect = &valid[i]; + texture = NULL; + cube_texture = NULL; + switch (resources[r].type) + { + case D3DRTYPE_SURFACE: + hr = IDirect3DDevice8_CreateImageSurface(device, 128, 128, D3DFMT_A8R8G8B8, &surface); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, type %s.\n", hr, resources[r].name); + break; - locked_rect.pBits = (BYTE *)0xdeadbeef; - locked_rect.Pitch = 0xdeadbeef; + case D3DRTYPE_TEXTURE: + hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8, + resources[r].pool, &texture); + ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, type %s.\n", hr, resources[r].name); + hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &surface); + ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x, type %s.\n", hr, resources[r].name); + break; - hr = IDirect3DSurface8_LockRect(surface, &locked_rect, rect, 0); - ok(SUCCEEDED(hr), "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n", - rect->left, rect->top, rect->right, rect->bottom, hr); + case D3DRTYPE_CUBETEXTURE: + hr = IDirect3DDevice8_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8, + resources[r].pool, &cube_texture); + ok(SUCCEEDED(hr), "Failed to create cube texture, hr %#x, type %s.\n", hr, resources[r].name); + hr = IDirect3DCubeTexture8_GetCubeMapSurface(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, &surface); + ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x, type %s.\n", hr, resources[r].name); + break; - offset = (BYTE *)locked_rect.pBits - base; - expected_offset = rect->top * locked_rect.Pitch + rect->left * 4; - ok(offset == expected_offset, - "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n", - offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom); + default: + break; + } + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, NULL, 0); + ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, type %s.\n", hr, resources[r].name); + base = locked_rect.pBits; + hr = IDirect3DSurface8_UnlockRect(surface); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + + for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i) + { + const RECT *rect = &valid[i]; + + locked_rect.pBits = (BYTE *)0xdeadbeef; + locked_rect.Pitch = 0xdeadbeef; + + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, rect, 0); + ok(SUCCEEDED(hr), "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x, type %s.\n", + rect->left, rect->top, rect->right, rect->bottom, hr, resources[r].name); + + offset = (BYTE *)locked_rect.pBits - base; + expected_offset = rect->top * locked_rect.Pitch + rect->left * 4; + ok(offset == expected_offset, + "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d], type %s.\n", + offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom, + resources[r].name); + + hr = IDirect3DSurface8_UnlockRect(surface); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s\n", hr, resources[r].name); + + if (texture) + { + hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, rect, 0); + ok(SUCCEEDED(hr), "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x, type %s.\n", + rect->left, rect->top, rect->right, rect->bottom, hr, resources[r].name); + + offset = (BYTE *)locked_rect.pBits - base; + ok(offset == expected_offset, + "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d], type %s.\n", + offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom, + resources[r].name); + hr = IDirect3DTexture8_UnlockRect(texture, 0); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + } + if (cube_texture) + { + hr = IDirect3DCubeTexture8_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, &locked_rect, rect, 0); + ok(SUCCEEDED(hr), "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x, type %s.\n", + rect->left, rect->top, rect->right, rect->bottom, hr, resources[r].name); + + offset = (BYTE *)locked_rect.pBits - base; + ok(offset == expected_offset, + "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d], type %s.\n", + offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom, + resources[r].name); + + hr = IDirect3DCubeTexture8_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + } + } + + for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i) + { + const RECT *rect = &invalid[i]; + + locked_rect.pBits = (void *)0xdeadbeef; + locked_rect.Pitch = 1; + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, rect, 0); + if (resources[r].validate) + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, rect->left, rect->top, rect->right, rect->bottom, resources[r].name); + else + ok(SUCCEEDED(hr), "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, rect->left, rect->top, rect->right, rect->bottom, resources[r].name); + + if (SUCCEEDED(hr)) + { + offset = (BYTE *)locked_rect.pBits - base; + expected_offset = rect->top * locked_rect.Pitch + rect->left * 4; + ok(offset == expected_offset, + "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d], type %s.\n", + offset, expected_offset, rect->left, rect->top, + rect->right, rect->bottom, resources[r].name); + + hr = IDirect3DSurface8_UnlockRect(surface); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + } + else + { + ok(!locked_rect.pBits, "Got unexpected pBits %p, type %s.\n", + locked_rect.pBits, resources[r].name); + ok(!locked_rect.Pitch, "Got unexpected Pitch %u, type %s.\n", + locked_rect.Pitch, resources[r].name); + } + } + + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, NULL, 0); + ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x, type %s.\n", + hr, resources[r].name); + locked_rect.pBits = (void *)0xdeadbeef; + locked_rect.Pitch = 1; + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + if (resources[r].clear) + { + ok(!locked_rect.pBits, "Got unexpected pBits %p, type %s.\n", + locked_rect.pBits, resources[r].name); + ok(!locked_rect.Pitch, "Got unexpected Pitch %u, type %s.\n", + locked_rect.Pitch, resources[r].name); + } + else + { + ok(locked_rect.pBits == (void *)0xdeadbeef, "Got unexpected pBits %p, type %s.\n", + locked_rect.pBits, resources[r].name); + ok(locked_rect.Pitch == 1, "Got unexpected Pitch %u, type %s.\n", + locked_rect.Pitch, resources[r].name); + } hr = IDirect3DSurface8_UnlockRect(surface); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); - } + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); - for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i) - { - const RECT *rect = &invalid[i]; + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, &valid[0], 0); + ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, resources[r].name); + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, &valid[0], 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, resources[r].name); + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, &valid[1], 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, valid[1].left, valid[1].top, valid[1].right, valid[1].bottom, resources[r].name); + hr = IDirect3DSurface8_UnlockRect(surface); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); - hr = IDirect3DSurface8_LockRect(surface, &locked_rect, rect, 0); - ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n", - hr, rect->left, rect->top, rect->right, rect->bottom); - } + IDirect3DSurface8_Release(surface); + if (texture) + { + hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0); + ok(SUCCEEDED(hr), "Failed to lock texture with rect NULL, hr %#x, type %s.\n", + hr, resources[r].name); + locked_rect.pBits = (void *)0xdeadbeef; + locked_rect.Pitch = 1; + hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + ok(locked_rect.pBits == (void *)0xdeadbeef, "Got unexpected pBits %p, type %s.\n", + locked_rect.pBits, resources[r].name); + ok(locked_rect.Pitch == 1, "Got unexpected Pitch %u, type %s.\n", + locked_rect.Pitch, resources[r].name); + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + hr = IDirect3DTexture8_UnlockRect(texture, 0); + ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name); + + hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, &valid[0], 0); + ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, resources[r].name); + hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, &valid[0], 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, resources[r].name); + hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, &valid[1], 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, valid[1].left, valid[1].top, valid[1].right, valid[1].bottom, resources[r].name); + hr = IDirect3DTexture8_UnlockRect(texture, 0); + ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name); - hr = IDirect3DSurface8_LockRect(surface, &locked_rect, NULL, 0); - ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x.\n", hr); - locked_rect.pBits = (void *)0xdeadbeef; - locked_rect.Pitch = 1; - hr = IDirect3DSurface8_LockRect(surface, &locked_rect, NULL, 0); - ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); - ok(!locked_rect.pBits, "Got unexpected pBits %p.\n", locked_rect.pBits); - ok(!locked_rect.Pitch, "Got unexpected Pitch %u.\n", locked_rect.Pitch); - hr = IDirect3DSurface8_UnlockRect(surface); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); + IDirect3DTexture8_Release(texture); + } - hr = IDirect3DSurface8_LockRect(surface, &locked_rect, &valid[0], 0); - ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n", - hr, valid[0].left, valid[0].top, valid[0].right, valid[0].bottom); - hr = IDirect3DSurface8_LockRect(surface, &locked_rect, &valid[0], 0); - ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n", - hr, valid[0].left, valid[0].top, valid[0].right, valid[0].bottom); - hr = IDirect3DSurface8_LockRect(surface, &locked_rect, &valid[1], 0); - ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n", - hr, valid[1].left, valid[1].top, valid[1].right, valid[1].bottom); - hr = IDirect3DSurface8_UnlockRect(surface); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); + if (cube_texture) + { + hr = IDirect3DCubeTexture8_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, + &locked_rect, NULL, 0); + ok(SUCCEEDED(hr), "Failed to lock texture with rect NULL, hr %#x, type %s.\n", + hr, resources[r].name); + locked_rect.pBits = (void *)0xdeadbeef; + locked_rect.Pitch = 1; + hr = IDirect3DCubeTexture8_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, + &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + ok(!locked_rect.pBits, "Got unexpected pBits %p, type %s.\n", + locked_rect.pBits, resources[r].name); + ok(!locked_rect.Pitch, "Got unexpected Pitch %u, type %s.\n", + locked_rect.Pitch, resources[r].name); + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + hr = IDirect3DCubeTexture8_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0); + ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name); + + hr = IDirect3DCubeTexture8_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, + &locked_rect, &valid[0], 0); + ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, resources[r].name); + hr = IDirect3DCubeTexture8_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, + &locked_rect, &valid[0], 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, resources[r].name); + hr = IDirect3DCubeTexture8_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, + &locked_rect, &valid[1], 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, valid[1].left, valid[1].top, valid[1].right, valid[1].bottom, resources[r].name); + hr = IDirect3DCubeTexture8_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0); + ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name); + + IDirect3DTexture8_Release(cube_texture); + } + } - IDirect3DSurface8_Release(surface); refcount = IDirect3DDevice8_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); IDirect3D8_Release(d3d8); @@ -5160,7 +5464,7 @@ IDirect3DSurface8 *surface; D3DLOCKED_RECT locked_rect; IDirect3DDevice8 *device; - unsigned int i, j, w, h; + unsigned int i, j, k, w, h; IDirect3D8 *d3d; ULONG refcount; HWND window; @@ -5168,6 +5472,21 @@ RECT rect; BOOL tex_pow2, cube_pow2; D3DCAPS8 caps; + static const RECT invalid[] = + { + {60, 60, 60, 68}, /* 0 height */ + {60, 60, 68, 60}, /* 0 width */ + {68, 60, 60, 68}, /* left > right */ + {60, 68, 68, 60}, /* top > bottom */ + {-8, 60, 0, 68}, /* left < surface */ + {60, -8, 68, 0}, /* top < surface */ + {-16, 60, -8, 68}, /* right < surface */ + {60, -16, 68, -8}, /* bottom < surface */ + {60, 60, 136, 68}, /* right > surface */ + {60, 60, 68, 136}, /* bottom > surface */ + {136, 60, 144, 68}, /* left > surface */ + {60, 136, 68, 144}, /* top > surface */ + }; window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); @@ -5383,6 +5702,19 @@ } } + for (k = 0; k < sizeof(invalid) / sizeof(*invalid); ++k) + { + hr = IDirect3DSurface8_LockRect(surface, &locked_rect, &invalid[k], 0); + ok(FAILED(hr) == !pools[j].success, "Invalid lock %s(%#x), expected %s, format %s, pool %s, case %u.\n", + SUCCEEDED(hr) ? "succeeded" : "failed", hr, pools[j].success ? "success" : "failure", + formats[i].name, pools[j].name, k); + if (SUCCEEDED(hr)) + { + hr = IDirect3DSurface8_UnlockRect(surface); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); + } + } + SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height); hr = IDirect3DSurface8_LockRect(surface, &locked_rect, &rect, 0); ok(hr == D3D_OK, "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name); @@ -5577,6 +5909,82 @@ DestroyWindow(window); } +static void test_managed_buffer(void) +{ + static const unsigned int vertex_count = 1024; + IDirect3DVertexBuffer8 *buffer; + D3DVERTEXBUFFER_DESC desc; + IDirect3DDevice8 *device; + struct vec3 *ptr, *ptr2; + IDirect3D8 *d3d8; + unsigned int i; + UINT refcount; + HWND window; + HRESULT hr; + + window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + d3d8 = Direct3DCreate8(D3D_SDK_VERSION); + ok(!!d3d8, "Failed to create a D3D object.\n"); + if (!(device = create_device(d3d8, window, NULL))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + IDirect3D8_Release(d3d8); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice8_CreateVertexBuffer(device, vertex_count * sizeof(*ptr), 0, 0, D3DPOOL_MANAGED, &buffer); + ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr); + hr = IDirect3DVertexBuffer8_GetDesc(buffer, &desc); + ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr); + ok(desc.Pool == D3DPOOL_MANAGED, "Got unexpected pool %#x.\n", desc.Pool); + ok(!desc.Usage, "Got unexpected usage %#x.\n", desc.Usage); + + hr = IDirect3DVertexBuffer8_Lock(buffer, 0, vertex_count * sizeof(*ptr), (BYTE **)&ptr, D3DLOCK_DISCARD); + ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr); + for (i = 0; i < vertex_count; ++i) + { + ptr[i].x = i * 1.0f; + ptr[i].y = i * 2.0f; + ptr[i].z = i * 3.0f; + } + hr = IDirect3DVertexBuffer8_Unlock(buffer); + ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr); + + hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ); + ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr); + hr = IDirect3DDevice8_SetStreamSource(device, 0, buffer, sizeof(*ptr)); + ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr); + hr = IDirect3DDevice8_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice8_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + hr = IDirect3DVertexBuffer8_Lock(buffer, 0, vertex_count * sizeof(*ptr2), (BYTE **)&ptr2, D3DLOCK_DISCARD); + ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr); + ok(ptr2 == ptr, "Got unexpected ptr2 %p, expected %p.\n", ptr2, ptr); + for (i = 0; i < vertex_count; ++i) + { + if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f) + { + ok(FALSE, "Got unexpected vertex %u {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n", + i, ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f); + break; + } + } + hr = IDirect3DVertexBuffer8_Unlock(buffer); + ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr); + + IDirect3DVertexBuffer8_Release(buffer); + refcount = IDirect3DDevice8_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + IDirect3D8_Release(d3d8); + DestroyWindow(window); +} + static void test_npot_textures(void) { IDirect3DDevice8 *device = NULL; @@ -7492,6 +7900,8 @@ test_swapchain(); test_refcount(); test_mipmap_levels(); + test_checkdevicemultisampletype(); + test_invalid_multisample(); test_cursor(); test_cursor_pos(); test_states(); @@ -7530,6 +7940,7 @@ test_surface_blocks(); test_set_palette(); test_swvp_buffer(); + test_managed_buffer(); test_npot_textures(); test_volume_locking(); test_update_volumetexture(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/tests/visual.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/tests/visual.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/tests/visual.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/tests/visual.c 2016-02-08 19:32:34.000000000 +0000 @@ -8478,9 +8478,9 @@ * functionality being available. */ /* PHONG should be the same as GOURAUD, since no hardware implements * this. */ - ok(color0 == tests[i].color0, "Test %u shading has color0 %08x, expected %08x.\n", + ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n", i, color0, tests[i].color0); - ok(color1 == tests[i].color1, "Test %u shading has color1 %08x, expected %08x.\n", + ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n", i, color1, tests[i].color1); IDirect3DDevice8_SetVertexShader(device, 0); @@ -8650,7 +8650,6 @@ const struct test { - BOOL todo; DWORD tex_op_caps; D3DCOLOR expected_color; struct texture_stage stage[8]; @@ -8658,7 +8657,6 @@ tests[] = { { - FALSE, D3DTEXOPCAPS_DISABLE, 0x80ffff02, { @@ -8671,7 +8669,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1, 0x80ffff02, { @@ -8687,7 +8684,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1, 0x80ffff02, { @@ -8704,7 +8700,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1, 0x80ffff02, { @@ -8721,7 +8716,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1, 0x00000000, { @@ -8739,7 +8733,6 @@ }, { - TRUE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE, 0x80ff0000, { @@ -8768,7 +8761,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE, 0x80ff0000, { @@ -8796,7 +8788,6 @@ }, }, { - TRUE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE, 0x80ff0000, { @@ -8826,7 +8817,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE, 0x00ff0000, { @@ -8858,7 +8848,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE, 0x80ff0000, { @@ -8891,7 +8880,6 @@ }, { - TRUE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_ADD, 0x80ff0000, @@ -8925,7 +8913,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_MODULATE2X, 0x80ffff00, @@ -8959,7 +8946,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP, 0x80ffff02, { @@ -9131,16 +9117,8 @@ get_rt_readback(backbuffer, &rb); color = get_readback_color(&rb, 320, 240); - if (current_test->todo) - { - todo_wine ok(color_match(color, current_test->expected_color, 1), - "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color); - } - else - { - ok(color_match(color, current_test->expected_color, 1), - "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color); - } + ok(color_match(color, current_test->expected_color, 1), + "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color); release_surface_readback(&rb); hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL); ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/texture.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/texture.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d8/texture.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d8/texture.c 2016-02-08 19:32:34.000000000 +0000 @@ -1150,14 +1150,14 @@ UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) { struct wined3d_resource_desc desc; - DWORD surface_flags = 0; + DWORD flags = 0; HRESULT hr; texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl; d3d8_resource_init(&texture->resource); list_init(&texture->rtv_list); - desc.resource_type = WINED3D_RTYPE_TEXTURE; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; @@ -1170,13 +1170,13 @@ desc.size = 0; if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) - surface_flags |= WINED3D_SURFACE_MAPPABLE; + flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; if (!levels) levels = wined3d_log2i(max(width, height)) + 1; wined3d_mutex_lock(); - hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, levels, flags, NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1195,19 +1195,19 @@ UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) { struct wined3d_resource_desc desc; - DWORD surface_flags = 0; + DWORD flags = 0; HRESULT hr; texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl; d3d8_resource_init(&texture->resource); list_init(&texture->rtv_list); - desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = usage & WINED3DUSAGE_MASK; - desc.usage |= WINED3DUSAGE_TEXTURE; + desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; desc.pool = pool; desc.width = edge_length; desc.height = edge_length; @@ -1215,13 +1215,13 @@ desc.size = 0; if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) - surface_flags |= WINED3D_SURFACE_MAPPABLE; + flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; if (!levels) levels = wined3d_log2i(edge_length) + 1; wined3d_mutex_lock(); - hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, levels, flags, NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1246,7 +1246,7 @@ d3d8_resource_init(&texture->resource); list_init(&texture->rtv_list); - desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE; + desc.resource_type = WINED3D_RTYPE_TEXTURE_3D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/d3d9_private.h wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/d3d9_private.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/d3d9_private.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/d3d9_private.h 2016-02-08 19:32:34.000000000 +0000 @@ -219,7 +219,6 @@ struct d3d9_resource resource; struct wined3d_texture *wined3d_texture; unsigned int sub_resource_idx; - struct wined3d_surface *wined3d_surface; struct list rtv_entry; struct wined3d_rendertarget_view *wined3d_rtv; IDirect3DDevice9Ex *parent_device; @@ -229,8 +228,8 @@ }; struct wined3d_rendertarget_view *d3d9_surface_get_rendertarget_view(struct d3d9_surface *surface) DECLSPEC_HIDDEN; -void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, - struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; +void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture, + unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface) DECLSPEC_HIDDEN; struct d3d9_vertexbuffer diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/device.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/device.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/device.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/device.c 2016-02-08 19:32:34.000000000 +0000 @@ -611,7 +611,7 @@ { struct d3d9_surface *surface; - if (desc.resource_type == WINED3D_RTYPE_TEXTURE) + if (desc.resource_type == WINED3D_RTYPE_TEXTURE_2D) { IUnknown *parent = wined3d_resource_get_parent(resource); IDirect3DBaseTexture9 *texture; @@ -1119,7 +1119,7 @@ device, width, height, format, flags, surface, usage, pool, multisample_type, multisample_quality); - desc.resource_type = WINED3D_RTYPE_TEXTURE; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = multisample_type; desc.multisample_quality = multisample_quality; @@ -1137,6 +1137,8 @@ { wined3d_mutex_unlock(); WARN("Failed to create texture, hr %#x.\n", hr); + if (hr == WINED3DERR_NOTAVAILABLE) + hr = D3DERR_INVALIDCALL; return hr; } @@ -1182,7 +1184,7 @@ } if (lockable) - flags |= WINED3D_SURFACE_MAPPABLE; + flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; return d3d9_device_create_surface(device, width, height, format, flags, surface, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); @@ -1193,7 +1195,7 @@ BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle) { struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); - DWORD flags = WINED3D_SURFACE_MAPPABLE; + DWORD flags = WINED3D_TEXTURE_CREATE_MAPPABLE; TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n" "discard %#x, surface %p, shared_handle %p.\n", @@ -1213,7 +1215,7 @@ } if (discard) - flags |= WINED3D_SURFACE_DISCARD; + flags |= WINED3D_TEXTURE_CREATE_DISCARD; return d3d9_device_create_surface(device, width, height, format, flags, surface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); @@ -1227,16 +1229,32 @@ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); struct d3d9_surface *src = unsafe_impl_from_IDirect3DSurface9(src_surface); struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(dst_surface); + struct wined3d_box src_box; HRESULT hr; TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_point %p.\n", iface, src_surface, src_rect, dst_surface, dst_point); + if (src_rect) + { + src_box.left = src_rect->left; + src_box.top = src_rect->top; + src_box.right = src_rect->right; + src_box.bottom = src_rect->bottom; + src_box.front = 0; + src_box.back = 1; + } + wined3d_mutex_lock(); - hr = wined3d_device_update_surface(device->wined3d_device, src->wined3d_surface, src_rect, - dst->wined3d_surface, dst_point); + hr = wined3d_device_copy_sub_resource_region(device->wined3d_device, + wined3d_texture_get_resource(dst->wined3d_texture), dst->sub_resource_idx, dst_point ? dst_point->x : 0, + dst_point ? dst_point->y : 0, 0, wined3d_texture_get_resource(src->wined3d_texture), + src->sub_resource_idx, src_rect ? &src_box : NULL); wined3d_mutex_unlock(); + if (FAILED(hr)) + return D3DERR_INVALIDCALL; + return hr; } @@ -1267,20 +1285,32 @@ struct d3d9_surface *dst_impl = unsafe_impl_from_IDirect3DSurface9(dst_surface); struct wined3d_resource_desc wined3d_desc; struct wined3d_resource *sub_resource; + RECT dst_rect, src_rect; HRESULT hr; TRACE("iface %p, render_target %p, dst_surface %p.\n", iface, render_target, dst_surface); wined3d_mutex_lock(); + sub_resource = wined3d_texture_get_sub_resource(dst_impl->wined3d_texture, dst_impl->sub_resource_idx); + wined3d_resource_get_desc(sub_resource, &wined3d_desc); + dst_rect.left = 0; + dst_rect.top = 0; + dst_rect.right = wined3d_desc.width; + dst_rect.bottom = wined3d_desc.height; + sub_resource = wined3d_texture_get_sub_resource(rt_impl->wined3d_texture, rt_impl->sub_resource_idx); wined3d_resource_get_desc(sub_resource, &wined3d_desc); + src_rect.left = 0; + src_rect.top = 0; + src_rect.right = wined3d_desc.width; + src_rect.bottom = wined3d_desc.height; /* TODO: Check surface sizes, pools, etc. */ if (wined3d_desc.multisample_type) hr = D3DERR_INVALIDCALL; else - hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, NULL, - rt_impl->wined3d_texture, rt_impl->sub_resource_idx, NULL, 0, NULL, WINED3D_TEXF_POINT); + hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect, + rt_impl->wined3d_texture, rt_impl->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT); wined3d_mutex_unlock(); return hr; @@ -1313,6 +1343,7 @@ HRESULT hr = D3DERR_INVALIDCALL; struct wined3d_resource_desc src_desc, dst_desc; struct wined3d_resource *sub_resource; + RECT d, s; TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n", iface, src_surface, src_rect, dst_surface, dst_rect, filter); @@ -1320,9 +1351,25 @@ wined3d_mutex_lock(); sub_resource = wined3d_texture_get_sub_resource(dst->wined3d_texture, dst->sub_resource_idx); wined3d_resource_get_desc(sub_resource, &dst_desc); + if (!dst_rect) + { + d.left = 0; + d.top = 0; + d.right = dst_desc.width; + d.bottom = dst_desc.height; + dst_rect = &d; + } sub_resource = wined3d_texture_get_sub_resource(src->wined3d_texture, src->sub_resource_idx); wined3d_resource_get_desc(sub_resource, &src_desc); + if (!src_rect) + { + s.left = 0; + s.top = 0; + s.right = src_desc.width; + s.bottom = src_desc.height; + src_rect = &s; + } if (src_desc.usage & WINED3DUSAGE_DEPTHSTENCIL) { @@ -1332,26 +1379,22 @@ goto done; } - if (src_rect) + if (src_rect->left || src_rect->top || src_rect->right != src_desc.width + || src_rect->bottom != src_desc.height) { - if (src_rect->left || src_rect->top || src_rect->right != src_desc.width - || src_rect->bottom != src_desc.height) - { - WARN("Rejecting depth / stencil blit with invalid source rect %s.\n", - wine_dbgstr_rect(src_rect)); - goto done; - } + WARN("Rejecting depth / stencil blit with invalid source rect %s.\n", + wine_dbgstr_rect(src_rect)); + goto done; } - if (dst_rect) + + if (dst_rect->left || dst_rect->top || dst_rect->right != dst_desc.width + || dst_rect->bottom != dst_desc.height) { - if (dst_rect->left || dst_rect->top || dst_rect->right != dst_desc.width - || dst_rect->bottom != dst_desc.height) - { - WARN("Rejecting depth / stencil blit with invalid destination rect %s.\n", - wine_dbgstr_rect(dst_rect)); - goto done; - } + WARN("Rejecting depth / stencil blit with invalid destination rect %s.\n", + wine_dbgstr_rect(dst_rect)); + goto done; } + if (src_desc.width != dst_desc.width || src_desc.height != dst_desc.height) { WARN("Rejecting depth / stencil blit with mismatched surface sizes.\n"); @@ -1465,7 +1508,7 @@ * regardless of the pool they're created in. Should we set dynamic usage * here? */ return d3d9_device_create_surface(device, width, height, format, - WINED3D_SURFACE_MAPPABLE, surface, 0, pool, D3DMULTISAMPLE_NONE, 0, user_mem); + WINED3D_TEXTURE_CREATE_MAPPABLE, surface, 0, pool, D3DMULTISAMPLE_NONE, 0, user_mem); } static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWORD idx, IDirect3DSurface9 *surface) @@ -1525,7 +1568,7 @@ } else { - hr = WINED3DERR_NOTFOUND; + hr = D3DERR_NOTFOUND; *surface = NULL; } wined3d_mutex_unlock(); @@ -1571,7 +1614,7 @@ } else { - hr = WINED3DERR_NOTFOUND; + hr = D3DERR_NOTFOUND; *depth_stencil = NULL; } wined3d_mutex_unlock(); @@ -3352,16 +3395,28 @@ UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage) { - FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n" - "discard %#x, surface %p, shared_handle %p, usage %#x stub!\n", + struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + DWORD flags = WINED3D_TEXTURE_CREATE_MAPPABLE; + + TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u, " + "discard %#x, surface %p, shared_handle %p, usage %#x.\n", iface, width, height, format, multisample_type, multisample_quality, discard, surface, shared_handle, usage); - *surface = NULL; + if (usage & D3DUSAGE_DEPTHSTENCIL) + { + WARN("Invalid usage %#x.\n", usage); + return D3DERR_INVALIDCALL; + } + if (shared_handle) FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle); - return E_NOTIMPL; + if (discard) + flags |= WINED3D_TEXTURE_CREATE_DISCARD; + + return d3d9_device_create_surface(device, width, height, format, flags, surface, + D3DUSAGE_DEPTHSTENCIL | usage, D3DPOOL_DEFAULT, multisample_type, multisample_quality, NULL); } static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_ResetEx(IDirect3DDevice9Ex *iface, @@ -3590,7 +3645,7 @@ if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface)))) return E_OUTOFMEMORY; - surface_init(d3d_surface, wined3d_texture, sub_resource_idx, surface, parent_ops); + surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops); *parent = d3d_surface; TRACE("Created surface %p.\n", d3d_surface); @@ -3630,7 +3685,7 @@ container_parent = &device->IDirect3DDevice9Ex_iface; if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, - WINED3D_SURFACE_MAPPABLE, NULL, container_parent, &d3d9_null_wined3d_parent_ops, texture))) + WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, container_parent, &d3d9_null_wined3d_parent_ops, texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/directx.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/directx.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/directx.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/directx.c 2016-02-08 19:32:34.000000000 +0000 @@ -254,16 +254,38 @@ TRACE("iface %p, adapter %u, device_type %#x, adapter_format %#x, usage %#x, resource_type %#x, format %#x.\n", iface, adapter, device_type, adapter_format, usage, resource_type, format); + usage = usage & (WINED3DUSAGE_MASK | WINED3DUSAGE_QUERY_MASK); switch (resource_type) { + case D3DRTYPE_SURFACE: + wined3d_rtype = WINED3D_RTYPE_SURFACE; + break; + + case D3DRTYPE_VOLUME: + wined3d_rtype = WINED3D_RTYPE_VOLUME; + break; + + case D3DRTYPE_TEXTURE: + wined3d_rtype = WINED3D_RTYPE_TEXTURE_2D; + break; + + case D3DRTYPE_VOLUMETEXTURE: + wined3d_rtype = WINED3D_RTYPE_TEXTURE_3D; + break; + + case D3DRTYPE_CUBETEXTURE: + wined3d_rtype = WINED3D_RTYPE_TEXTURE_2D; + usage |= WINED3DUSAGE_LEGACY_CUBEMAP; + break; + case D3DRTYPE_VERTEXBUFFER: case D3DRTYPE_INDEXBUFFER: wined3d_rtype = WINED3D_RTYPE_BUFFER; break; default: - wined3d_rtype = resource_type; - break; + FIXME("Unhandled resource type %#x.\n", resource_type); + return WINED3DERR_INVALIDCALL; } wined3d_mutex_lock(); @@ -283,10 +305,15 @@ TRACE("iface %p, adapter %u, device_type %#x, format %#x, windowed %#x, multisample_type %#x, levels %p.\n", iface, adapter, device_type, format, windowed, multisample_type, levels); + if (multisample_type > D3DMULTISAMPLE_16_SAMPLES) + return D3DERR_INVALIDCALL; + wined3d_mutex_lock(); hr = wined3d_check_device_multisample_type(d3d9->wined3d, adapter, device_type, wined3dformat_from_d3dformat(format), windowed, multisample_type, levels); wined3d_mutex_unlock(); + if (hr == WINED3DERR_NOTAVAILABLE && levels) + *levels = 1; return hr; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/surface.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/surface.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/surface.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/surface.c 2016-02-08 19:32:34.000000000 +0000 @@ -71,7 +71,7 @@ wined3d_mutex_lock(); if (surface->wined3d_rtv) wined3d_rendertarget_view_incref(surface->wined3d_rtv); - wined3d_surface_incref(surface->wined3d_surface); + wined3d_texture_incref(surface->wined3d_texture); wined3d_mutex_unlock(); } @@ -101,7 +101,7 @@ wined3d_mutex_lock(); if (surface->wined3d_rtv) wined3d_rendertarget_view_decref(surface->wined3d_rtv); - wined3d_surface_decref(surface->wined3d_surface); + wined3d_texture_decref(surface->wined3d_texture); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ @@ -357,8 +357,8 @@ surface_wined3d_object_destroyed, }; -void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, - struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) +void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture, + unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) { struct wined3d_resource_desc desc; IDirect3DBaseTexture9 *texture; @@ -366,7 +366,6 @@ surface->IDirect3DSurface9_iface.lpVtbl = &d3d9_surface_vtbl; d3d9_resource_init(&surface->resource); surface->resource.refcount = 0; - surface->wined3d_surface = wined3d_surface; list_init(&surface->rtv_entry); surface->container = wined3d_texture_get_parent(wined3d_texture); surface->wined3d_texture = wined3d_texture; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/tests/d3d9ex.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/tests/d3d9ex.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/tests/d3d9ex.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/tests/d3d9ex.c 2016-02-08 19:32:34.000000000 +0000 @@ -42,6 +42,11 @@ DWORD flags; }; +static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier) +{ + return !strcmp(identifier->Driver, "d3d10warp.dll"); +} + static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff) { unsigned int i; @@ -617,7 +622,7 @@ todo_wine ok(S2(U1(startmode)).dmDisplayOrientation == DMDO_180 && rotation == D3DDISPLAYROTATION_180, "rotation is %d instead of %d\n", rotation, S2(U1(startmode)).dmDisplayOrientation); - trace("GetAdapterDisplayModeEx returned Width = %d,Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d\n", + trace("GetAdapterDisplayModeEx returned Width = %d, Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d\n", mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation); /* test GetAdapterDisplayModeEx with null pointer for D3DDISPLAYROTATION */ @@ -644,6 +649,81 @@ IDirect3D9Ex_Release(d3d9ex); } +static void test_create_depth_stencil_surface_ex(void) +{ + static const struct + { + DWORD usage; + HRESULT hr; + BOOL broken_warp; + } + tests[] = + { + {0, D3D_OK, FALSE}, + {D3DUSAGE_DEPTHSTENCIL, D3DERR_INVALIDCALL, FALSE}, + {D3DUSAGE_RESTRICTED_CONTENT, D3D_OK, TRUE}, + }; + + D3DADAPTER_IDENTIFIER9 identifier; + D3DSURFACE_DESC surface_desc; + IDirect3DDevice9Ex *device; + IDirect3DSurface9 *surface; + IDirect3D9 *d3d; + unsigned int i; + HWND window; + HRESULT hr; + ULONG ref; + BOOL warp; + + window = create_window(); + + if (!(device = create_device(window, NULL))) + { + skip("Failed to create a D3D device.\n"); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice9Ex_GetDirect3D(device, &d3d); + ok(SUCCEEDED(hr), "Failed to get Direct3D9, hr %#x.\n", hr); + hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier); + ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr); + warp = adapter_is_warp(&identifier); + IDirect3D9_Release(d3d); + + for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) + { + surface = (IDirect3DSurface9 *)0xdeadbeef; + hr = IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(device, 64, 64, D3DFMT_D24S8, + D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL, tests[i].usage); + ok(hr == tests[i].hr || broken(warp && tests[i].broken_warp), + "Test %u: Got unexpected hr %#x.\n", i, hr); + if (SUCCEEDED(hr)) + { + hr = IDirect3DSurface9_GetDesc(surface, &surface_desc); + ok(SUCCEEDED(hr), "Test %u: GetDesc failed, hr %#x.\n", i, hr); + ok(surface_desc.Type == D3DRTYPE_SURFACE, "Test %u: Got unexpected type %#x.\n", + i, surface_desc.Type); + ok(surface_desc.Pool == D3DPOOL_DEFAULT, "Test %u: Got unexpected pool %#x.\n", + i, surface_desc.Pool); + ok(surface_desc.Usage == (tests[i].usage | D3DUSAGE_DEPTHSTENCIL), + "Test %u: Got unexpected usage %#x.\n", i, surface_desc.Usage); + + ref = IDirect3DSurface9_Release(surface); + ok(!ref, "Test %u: Surface has %u references left.\n", i, ref); + } + else + { + ok(surface == (IDirect3DSurface9 *)0xdeadbeef || broken(warp && tests[i].broken_warp), + "Test %u: Got unexpected surface pointer %p.\n", i, surface); + } + } + + ref = IDirect3DDevice9Ex_Release(device); + ok(!ref, "Device has %u references left.\n", ref); + DestroyWindow(window); +} + static void test_user_memory(void) { static const struct @@ -3078,6 +3158,7 @@ test_swapchain_get_displaymode_ex(); test_get_adapter_luid(); test_get_adapter_displaymode_ex(); + test_create_depth_stencil_surface_ex(); test_user_memory(); test_reset(); test_reset_resources(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/tests/device.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/tests/device.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/tests/device.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/tests/device.c 2016-02-08 19:32:34.000000000 +0000 @@ -1003,10 +1003,8 @@ static void test_checkdevicemultisampletype(void) { - IDirect3DDevice9 *device; DWORD quality_levels; IDirect3D9 *d3d; - ULONG refcount; HWND window; HRESULT hr; @@ -1015,34 +1013,145 @@ ok(!!window, "Failed to create a window.\n"); d3d = Direct3DCreate9(D3D_SDK_VERSION); ok(!!d3d, "Failed to create a D3D object.\n"); - if (!(device = create_device(d3d, window, NULL))) + + if (IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL) == D3DERR_NOTAVAILABLE) { - skip("Failed to create a 3D device, skipping test.\n"); + skip("Multisampling not supported for D3DFMT_X8R8G8B8, skipping test.\n"); goto cleanup; } + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_UNKNOWN, TRUE, D3DMULTISAMPLE_NONE, NULL); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + 65536, TRUE, D3DMULTISAMPLE_NONE, NULL); + todo_wine ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, NULL); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + quality_levels = 0; hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality_levels); - ok(SUCCEEDED(hr) || hr == D3DERR_NOTAVAILABLE, "CheckDeviceMultiSampleType failed with (%08x)\n", hr); - if (hr == D3DERR_NOTAVAILABLE) - { - skip("IDirect3D9_CheckDeviceMultiSampleType not available\n"); - goto cleanup; - } + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels); - + quality_levels = 0; hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality_levels); - ok(SUCCEEDED(hr), "CheckDeviceMultiSampleType failed with (%08x)\n", hr); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels); + quality_levels = 0; + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONMASKABLE, NULL); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONMASKABLE, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + + quality_levels = 0; + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &quality_levels); + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + ok(quality_levels, "Got unexpected quality_levels %u.\n", quality_levels); + + /* We assume D3DMULTISAMPLE_15_SAMPLES is never supported in practice. */ + quality_levels = 0; + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_15_SAMPLES, NULL); + ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr); + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_15_SAMPLES, &quality_levels); + ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr); + ok(quality_levels == 1, "Got unexpected quality_levels %u.\n", quality_levels); + + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, 65536, NULL); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_DXT5, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL); + ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr); + cleanup: - if (device) + IDirect3D9_Release(d3d); + DestroyWindow(window); +} + +static void test_invalid_multisample(void) +{ + IDirect3DDevice9 *device; + IDirect3DSurface9 *rt; + DWORD quality_levels; + IDirect3D9 *d3d; + BOOL available; + ULONG refcount; + HWND window; + HRESULT hr; + + window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + ok(!!window, "Failed to create a window.\n"); + d3d = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + + if (!(device = create_device(d3d, window, NULL))) { - refcount = IDirect3DDevice9_Release(device); - ok(!refcount, "Device has %u references left.\n", refcount); + skip("Failed to create a 3D device, skipping test.\n"); + goto cleanup; + } + + available = SUCCEEDED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_NONMASKABLE, &quality_levels)); + hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, + D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONMASKABLE, 0, FALSE, &rt, NULL); + if (available) + { + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + IDirect3DSurface9_Release(rt); + hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, + D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONMASKABLE, quality_levels, FALSE, &rt, NULL); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + } + else + { + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + } + + available = SUCCEEDED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &quality_levels)); + hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, + D3DFMT_X8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL); + if (available) + { + ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr); + IDirect3DSurface9_Release(rt); + hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, + D3DFMT_X8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, quality_levels, FALSE, &rt, NULL); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + } + else + { + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); } + + /* We assume D3DMULTISAMPLE_15_SAMPLES is never supported in practice. */ + hr = IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_15_SAMPLES, NULL); + ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, + D3DFMT_X8R8G8B8, D3DMULTISAMPLE_15_SAMPLES, 0, FALSE, &rt, NULL); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + + refcount = IDirect3DDevice9_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +cleanup: IDirect3D9_Release(d3d); DestroyWindow(window); } @@ -7032,12 +7141,30 @@ IDirect3DSurface9 *surface = NULL; D3DLOCKED_RECT locked_rect; IDirect3DDevice9 *device; + IDirect3DTexture9 *texture; + IDirect3DCubeTexture9 *cube_texture; IDirect3D9 *d3d; - unsigned int i; + unsigned int i, r; ULONG refcount; HWND window; BYTE *base; HRESULT hr; + static const struct + { + D3DRESOURCETYPE type; + D3DPOOL pool; + const char *name; + } + resources[] = + { + {D3DRTYPE_SURFACE, D3DPOOL_SCRATCH, "scratch surface"}, + {D3DRTYPE_TEXTURE, D3DPOOL_MANAGED, "managed texture"}, + {D3DRTYPE_TEXTURE, D3DPOOL_SYSTEMMEM, "sysmem texture"}, + {D3DRTYPE_TEXTURE, D3DPOOL_SCRATCH, "scratch texture"}, + {D3DRTYPE_CUBETEXTURE, D3DPOOL_MANAGED, "default cube texture"}, + {D3DRTYPE_CUBETEXTURE, D3DPOOL_SYSTEMMEM, "sysmem cube texture"}, + {D3DRTYPE_CUBETEXTURE, D3DPOOL_SCRATCH, "scratch cube texture"}, + }; window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); @@ -7051,68 +7178,226 @@ return; } - hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128, - D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL); - ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); - hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - base = locked_rect.pBits; - hr = IDirect3DSurface9_UnlockRect(surface); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); - - for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); ++i) + for (r = 0; r < sizeof(resources) / sizeof(*resources); ++r) { - unsigned int offset, expected_offset; - const RECT *rect = &test_data[i].rect; + texture = NULL; + cube_texture = NULL; + switch (resources[r].type) + { + case D3DRTYPE_SURFACE: + hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128, + D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, type %s.\n", + hr, resources[r].name); + break; - locked_rect.pBits = (BYTE *)0xdeadbeef; - locked_rect.Pitch = 0xdeadbeef; + case D3DRTYPE_TEXTURE: + hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8, + resources[r].pool, &texture, NULL); + ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, type %s.\n", + hr, resources[r].name); + hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface); + ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x, type %s.\n", + hr, resources[r].name); + break; - hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0); - /* Windows XP accepts invalid locking rectangles, windows 7 rejects - * them. Some games (C&C3) depend on the XP behavior, mark the Win 7 - * one broken. */ - ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result), - "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x.\n", - rect->left, rect->top, rect->right, rect->bottom, hr); - if (FAILED(hr)) - continue; + case D3DRTYPE_CUBETEXTURE: + hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8, + resources[r].pool, &cube_texture, NULL); + ok(SUCCEEDED(hr), "Failed to create cube texture, hr %#x, type %s.\n", + hr, resources[r].name); + hr = IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture, + D3DCUBEMAP_FACE_NEGATIVE_X, 0, &surface); + ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x, type %s.\n", + hr, resources[r].name); + break; - offset = (BYTE *)locked_rect.pBits - base; - expected_offset = rect->top * locked_rect.Pitch + rect->left * 4; - ok(offset == expected_offset, - "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d].\n", - offset, expected_offset, rect->left, rect->top, rect->right, rect->bottom); + default: + break; + } + + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0); + ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, type %s.\n", hr, resources[r].name); + base = locked_rect.pBits; + hr = IDirect3DSurface9_UnlockRect(surface); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + + for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i) + { + unsigned int offset, expected_offset; + const RECT *rect = &test_data[i].rect; + + locked_rect.pBits = (BYTE *)0xdeadbeef; + locked_rect.Pitch = 0xdeadbeef; + + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, rect, 0); + /* Windows XP accepts invalid locking rectangles, windows 7 rejects + * them. Some games (C&C3) depend on the XP behavior, mark the Win 7 + * one broken. */ + ok(SUCCEEDED(hr) || broken(hr == test_data[i].win7_result), + "Failed to lock surface with rect [%d, %d]->[%d, %d], hr %#x, type %s.\n", + rect->left, rect->top, rect->right, rect->bottom, hr, resources[r].name); + if (FAILED(hr)) + continue; + + offset = (BYTE *)locked_rect.pBits - base; + expected_offset = rect->top * locked_rect.Pitch + rect->left * 4; + ok(offset == expected_offset, + "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d], type %s.\n", + offset, expected_offset, rect->left, rect->top, + rect->right, rect->bottom, resources[r].name); + + hr = IDirect3DSurface9_UnlockRect(surface); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + + if (texture) + { + hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, rect, 0); + ok(SUCCEEDED(hr), + "Failed to lock texture with rect [%d, %d]->[%d, %d], hr %#x, type %s.\n", + rect->left, rect->top, rect->right, rect->bottom, hr, resources[r].name); + if (FAILED(hr)) + continue; + + offset = (BYTE *)locked_rect.pBits - base; + expected_offset = rect->top * locked_rect.Pitch + rect->left * 4; + ok(offset == expected_offset, + "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d], type %s.\n", + offset, expected_offset, rect->left, rect->top, + rect->right, rect->bottom, resources[r].name); + + hr = IDirect3DTexture9_UnlockRect(texture, 0); + ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name); + } + if (cube_texture) + { + hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, + &locked_rect, rect, 0); + ok(SUCCEEDED(hr), + "Failed to lock texture with rect [%d, %d]->[%d, %d], hr %#x, type %s.\n", + rect->left, rect->top, rect->right, rect->bottom, hr, resources[r].name); + if (FAILED(hr)) + continue; + + offset = (BYTE *)locked_rect.pBits - base; + expected_offset = rect->top * locked_rect.Pitch + rect->left * 4; + ok(offset == expected_offset, + "Got unexpected offset %u (expected %u) for rect [%d, %d]->[%d, %d], type %s.\n", + offset, expected_offset, rect->left, rect->top, + rect->right, rect->bottom, resources[r].name); + hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0); + ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name); + } + } + + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0); + ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x, type %s.\n", hr, resources[r].name); + locked_rect.pBits = (BYTE *)0xdeadbeef; + locked_rect.Pitch = 1; + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p, type %s.\n", + locked_rect.pBits, resources[r].name); + ok(locked_rect.Pitch == 1, "Got unexpected pitch %d, type %s.\n", + locked_rect.Pitch, resources[r].name); hr = IDirect3DSurface9_UnlockRect(surface); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); - } + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); - hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0); - ok(SUCCEEDED(hr), "Failed to lock surface with rect NULL, hr %#x.\n", hr); - locked_rect.pBits = (BYTE *)0xdeadbeef; - locked_rect.Pitch = 1; - hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0); - ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); - ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p\n", - locked_rect.pBits); - ok(locked_rect.Pitch == 1, "Got unexpected pitch %d\n", locked_rect.Pitch); - hr = IDirect3DSurface9_UnlockRect(surface); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, test_data[0].rect.left, test_data[0].rect.top, + test_data[0].rect.right, test_data[0].rect.bottom, resources[r].name); + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, test_data[0].rect.left, test_data[0].rect.top, + test_data[0].rect.right, test_data[0].rect.bottom, resources[r].name); + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, test_rect_2.left, test_rect_2.top, + test_rect_2.right, test_rect_2.bottom, resources[r].name); + hr = IDirect3DSurface9_UnlockRect(surface); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); - hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0); - ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n", - hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom); - hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_data[0].rect, 0); - ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n", - hr, test_data[0].rect.left, test_data[0].rect.top, test_data[0].rect.right, test_data[0].rect.bottom); - hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &test_rect_2, 0); - ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d].\n", - hr, test_rect_2.left, test_rect_2.top, test_rect_2.right, test_rect_2.bottom); - hr = IDirect3DSurface9_UnlockRect(surface); - ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); + IDirect3DSurface9_Release(surface); + + if (texture) + { + hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0); + ok(SUCCEEDED(hr), "Failed to lock texture with rect NULL, hr %#x, type %s.\n", + hr, resources[r].name); + locked_rect.pBits = (BYTE *)0xdeadbeef; + locked_rect.Pitch = 1; + hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p, type %s.\n", + locked_rect.pBits, resources[r].name); + ok(locked_rect.Pitch == 1, "Got unexpected pitch %d, type %s.\n", + locked_rect.Pitch, resources[r].name); + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + hr = IDirect3DTexture9_UnlockRect(texture, 0); + ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name); + + hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, &test_data[0].rect, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, test_data[0].rect.left, test_data[0].rect.top, + test_data[0].rect.right, test_data[0].rect.bottom, resources[r].name); + hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, &test_data[0].rect, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, test_data[0].rect.left, test_data[0].rect.top, + test_data[0].rect.right, test_data[0].rect.bottom, resources[r].name); + hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, &test_rect_2, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, test_rect_2.left, test_rect_2.top, + test_rect_2.right, test_rect_2.bottom, resources[r].name); + hr = IDirect3DTexture9_UnlockRect(texture, 0); + ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name); + + IDirect3DTexture9_Release(texture); + } + if (cube_texture) + { + hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, + &locked_rect, NULL, 0); + ok(SUCCEEDED(hr), "Failed to lock texture with rect NULL, hr %#x, type %s.\n", + hr, resources[r].name); + locked_rect.pBits = (BYTE *)0xdeadbeef; + locked_rect.Pitch = 1; + hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, + &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + ok(locked_rect.pBits == (BYTE *)0xdeadbeef, "Got unexpected pBits: %p, type %s.\n", + locked_rect.pBits, resources[r].name); + ok(locked_rect.Pitch == 1, "Got unexpected pitch %d, type %s.\n", + locked_rect.Pitch, resources[r].name); + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0); + ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name); + + hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, + &locked_rect, &test_data[0].rect, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, test_data[0].rect.left, test_data[0].rect.top, + test_data[0].rect.right, test_data[0].rect.bottom, resources[r].name); + hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, + &locked_rect, &test_data[0].rect, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, test_data[0].rect.left, test_data[0].rect.top, + test_data[0].rect.right, test_data[0].rect.bottom, resources[r].name); + hr = IDirect3DCubeTexture9_LockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0, + &locked_rect, &test_rect_2, 0); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, test_rect_2.left, test_rect_2.top, + test_rect_2.right, test_rect_2.bottom, resources[r].name); + hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, D3DCUBEMAP_FACE_NEGATIVE_X, 0); + ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x, type %s.\n", hr, resources[r].name); + + IDirect3DCubeTexture9_Release(cube_texture); + } + } - IDirect3DSurface9_Release(surface); refcount = IDirect3DDevice9_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); IDirect3D9_Release(d3d); @@ -7646,7 +7931,7 @@ IDirect3DSurface9 *surface; D3DLOCKED_RECT locked_rect; IDirect3DDevice9 *device; - unsigned int i, j, w, h; + unsigned int i, j, k, w, h; BOOL surface_only; IDirect3D9 *d3d; ULONG refcount; @@ -7655,6 +7940,21 @@ RECT rect; BOOL tex_pow2, cube_pow2; D3DCAPS9 caps; + static const RECT invalid[] = + { + {60, 60, 60, 68}, /* 0 height */ + {60, 60, 68, 60}, /* 0 width */ + {68, 60, 60, 68}, /* left > right */ + {60, 68, 68, 60}, /* top > bottom */ + {-8, 60, 0, 68}, /* left < surface */ + {60, -8, 68, 0}, /* top < surface */ + {-16, 60, -8, 68}, /* right < surface */ + {60, -16, 68, -8}, /* bottom < surface */ + {60, 60, 136, 68}, /* right > surface */ + {60, 60, 68, 136}, /* bottom > surface */ + {136, 60, 144, 68}, /* left > surface */ + {60, 136, 68, 144}, /* top > surface */ + }; window = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); @@ -7903,6 +8203,19 @@ } } + for (k = 0; k < sizeof(invalid) / sizeof(*invalid); ++k) + { + hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &invalid[k], 0); + ok(FAILED(hr) == !pools[j].success, "Invalid lock %s(%#x), expected %s, format %s, pool %s, case %u.\n", + SUCCEEDED(hr) ? "succeeded" : "failed", hr, pools[j].success ? "success" : "failure", + formats[i].name, pools[j].name, k); + if (SUCCEEDED(hr)) + { + hr = IDirect3DSurface9_UnlockRect(surface); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr); + } + } + SetRect(&rect, 0, 0, formats[i].block_width, formats[i].block_height); hr = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, 0); ok(SUCCEEDED(hr), "Got unexpected hr %#x for format %s, pool %s.\n", hr, formats[i].name, pools[j].name); @@ -7944,7 +8257,7 @@ rect.right = formats[i].block_width; rect.bottom = formats[i].block_height; hr = IDirect3DTexture9_LockRect(texture, 1, &locked_rect, &rect, 0); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); if (SUCCEEDED(hr)) IDirect3DTexture9_UnlockRect(texture, 1); @@ -8102,6 +8415,83 @@ DestroyWindow(window); } +static void test_managed_buffer(void) +{ + static const unsigned int vertex_count = 1024; + IDirect3DVertexBuffer9 *buffer; + D3DVERTEXBUFFER_DESC desc; + IDirect3DDevice9 *device; + struct vec3 *ptr, *ptr2; + IDirect3D9 *d3d9; + unsigned int i; + UINT refcount; + HWND window; + HRESULT hr; + + window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + d3d9 = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!d3d9, "Failed to create a D3D object.\n"); + if (!(device = create_device(d3d9, window, NULL))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + IDirect3D9_Release(d3d9); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice9_CreateVertexBuffer(device, vertex_count * sizeof(*ptr), + 0, 0, D3DPOOL_MANAGED, &buffer, NULL); + ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr); + hr = IDirect3DVertexBuffer9_GetDesc(buffer, &desc); + ok(SUCCEEDED(hr), "Failed to get desc, hr %#x.\n", hr); + ok(desc.Pool == D3DPOOL_MANAGED, "Got unexpected pool %#x.\n", desc.Pool); + ok(!desc.Usage, "Got unexpected usage %#x.\n", desc.Usage); + + hr = IDirect3DVertexBuffer9_Lock(buffer, 0, vertex_count * sizeof(*ptr), (void **)&ptr, D3DLOCK_DISCARD); + ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr); + for (i = 0; i < vertex_count; ++i) + { + ptr[i].x = i * 1.0f; + ptr[i].y = i * 2.0f; + ptr[i].z = i * 3.0f; + } + hr = IDirect3DVertexBuffer9_Unlock(buffer); + ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr); + + hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ); + ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*ptr)); + ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr); + hr = IDirect3DDevice9_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + hr = IDirect3DVertexBuffer9_Lock(buffer, 0, vertex_count * sizeof(*ptr2), (void **)&ptr2, D3DLOCK_DISCARD); + ok(SUCCEEDED(hr), "Failed to lock buffer, hr %#x.\n", hr); + ok(ptr2 == ptr, "Got unexpected ptr2 %p, expected %p.\n", ptr2, ptr); + for (i = 0; i < vertex_count; ++i) + { + if (ptr2[i].x != i * 1.0f || ptr2[i].y != i * 2.0f || ptr2[i].z != i * 3.0f) + { + ok(FALSE, "Got unexpected vertex %u {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n", + i, ptr2[i].x, ptr2[i].y, ptr2[i].z, i * 1.0f, i * 2.0f, i * 3.0f); + break; + } + } + hr = IDirect3DVertexBuffer9_Unlock(buffer); + ok(SUCCEEDED(hr), "Failed to unlock buffer, hr %#x.\n", hr); + + IDirect3DVertexBuffer9_Release(buffer); + refcount = IDirect3DDevice9_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + IDirect3D9_Release(d3d9); + DestroyWindow(window); +} + static void test_npot_textures(void) { IDirect3DDevice9 *device = NULL; @@ -9882,7 +10272,7 @@ hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, surface_dst, NULL); ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr); hr = IDirect3DDevice9_UpdateSurface(device, surface2, NULL, surface_dst2, NULL); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); /* Apparently there's no validation on the container. */ hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture, @@ -10396,6 +10786,7 @@ test_refcount(); test_mipmap_levels(); test_checkdevicemultisampletype(); + test_invalid_multisample(); test_cursor(); test_cursor_pos(); test_reset_fullscreen(); @@ -10446,6 +10837,7 @@ test_surface_blocks(); test_set_palette(); test_swvp_buffer(); + test_managed_buffer(); test_npot_textures(); test_vidmem_accounting(); test_volume_locking(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/tests/visual.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/tests/visual.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/tests/visual.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/tests/visual.c 2016-02-08 19:32:34.000000000 +0000 @@ -8474,16 +8474,16 @@ * this. */ if (tests[i].todo) { - todo_wine ok(color0 == tests[i].color0, "Test %u shading has color0 %08x, expected %08x.\n", + todo_wine ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n", i, color0, tests[i].color0); - todo_wine ok(color1 == tests[i].color1, "Test %u shading has color1 %08x, expected %08x.\n", + todo_wine ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n", i, color1, tests[i].color1); } else { - ok(color0 == tests[i].color0, "Test %u shading has color0 %08x, expected %08x.\n", + ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n", i, color0, tests[i].color0); - ok(color1 == tests[i].color1, "Test %u shading has color1 %08x, expected %08x.\n", + ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n", i, color1, tests[i].color1); } IDirect3DDevice9_SetVertexShader(device, NULL); @@ -20678,7 +20678,6 @@ const struct test { - BOOL todo; DWORD tex_op_caps; D3DCOLOR expected_color; struct texture_stage stage[8]; @@ -20686,7 +20685,6 @@ tests[] = { { - FALSE, D3DTEXOPCAPS_DISABLE, 0x80ffff02, { @@ -20699,7 +20697,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1, 0x80ffff02, { @@ -20715,7 +20712,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1, 0x80ffff02, { @@ -20732,7 +20728,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1, 0x80ffff02, { @@ -20749,7 +20744,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1, 0x00000000, { @@ -20766,7 +20760,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT, 0x80f0f000, { @@ -20792,7 +20785,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT, 0x71f0f000, { @@ -20824,7 +20816,6 @@ }, { - TRUE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE, 0x80ff0000, { @@ -20853,7 +20844,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE, 0x80ff0000, { @@ -20881,7 +20871,6 @@ }, }, { - TRUE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE, 0x80ff0000, { @@ -20911,7 +20900,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE, 0x00ff0000, { @@ -20943,7 +20931,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE, 0x80ff0000, { @@ -20976,7 +20963,6 @@ }, { - TRUE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_ADD, 0x80ff0000, @@ -21011,7 +20997,6 @@ }, }, { - TRUE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_MODULATE2X, 0x80ff0000, @@ -21046,7 +21031,6 @@ }, }, { - TRUE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_MODULATE2X, 0x80ffff00, @@ -21083,7 +21067,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP, 0x01234567, { @@ -21137,7 +21120,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP, 0x00234567, { @@ -21188,7 +21170,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP, 0x01234567, { @@ -21242,7 +21223,6 @@ }, }, { - FALSE, D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP, 0x01234567, { @@ -21424,16 +21404,8 @@ get_rt_readback(backbuffer, &rb); color = get_readback_color(&rb, 320, 240); - if (current_test->todo) - { - todo_wine ok(color_match(color, current_test->expected_color, 1), - "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color); - } - else - { - ok(color_match(color, current_test->expected_color, 1), - "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color); - } + ok(color_match(color, current_test->expected_color, 1), + "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color); release_surface_readback(&rb); hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/texture.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/texture.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3d9/texture.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3d9/texture.c 2016-02-08 19:32:34.000000000 +0000 @@ -1280,14 +1280,14 @@ UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) { struct wined3d_resource_desc desc; - DWORD surface_flags = 0; + DWORD flags = 0; HRESULT hr; texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl; d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); - desc.resource_type = WINED3D_RTYPE_TEXTURE; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; @@ -1300,7 +1300,7 @@ desc.size = 0; if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) - surface_flags |= WINED3D_SURFACE_MAPPABLE; + flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; if (!levels) { @@ -1311,7 +1311,7 @@ } wined3d_mutex_lock(); - hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, levels, flags, NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1330,19 +1330,19 @@ UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) { struct wined3d_resource_desc desc; - DWORD surface_flags = 0; + DWORD flags = 0; HRESULT hr; texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl; d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); - desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; desc.usage = usage & WINED3DUSAGE_MASK; - desc.usage |= WINED3DUSAGE_TEXTURE; + desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; desc.pool = pool; desc.width = edge_length; desc.height = edge_length; @@ -1350,7 +1350,7 @@ desc.size = 0; if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) - surface_flags |= WINED3D_SURFACE_MAPPABLE; + flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; if (!levels) { @@ -1361,7 +1361,7 @@ } wined3d_mutex_lock(); - hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags, + hr = wined3d_texture_create(device->wined3d_device, &desc, levels, flags, NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); wined3d_mutex_unlock(); if (FAILED(hr)) @@ -1386,7 +1386,7 @@ d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); - desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE; + desc.resource_type = WINED3D_RTYPE_TEXTURE_3D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3drm/tests/d3drm.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3drm/tests/d3drm.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3drm/tests/d3drm.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3drm/tests/d3drm.c 2016-02-08 19:32:34.000000000 +0000 @@ -2,6 +2,7 @@ * Copyright 2010, 2012 Christian Costa * Copyright 2012 André Hentschel * Copyright 2011-2014 Henri Verbeet for CodeWeavers + * Copyright 2014-2015 Aaryaman Vasishta * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -3693,6 +3694,404 @@ DestroyWindow(window); } +static char *create_bitmap(unsigned int w, unsigned int h, BOOL palettized) +{ + unsigned int bpp = palettized ? 8 : 24; + BITMAPFILEHEADER file_header; + DWORD written, size, ret; + unsigned char *buffer; + char path[MAX_PATH]; + unsigned int i, j; + BITMAPINFO *info; + char *filename; + HANDLE file; + + ret = GetTempPathA(MAX_PATH, path); + ok(ret, "Failed to get temporary file path.\n"); + filename = HeapAlloc(GetProcessHeap(), 0, MAX_PATH); + ret = GetTempFileNameA(path, "d3d", 0, filename); + ok(ret, "Failed to get filename.\n"); + file = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "Failed to open temporary file \"%s\".\n", filename); + + size = FIELD_OFFSET(BITMAPINFO, bmiColors[palettized ? 256 : 0]); + + memset(&file_header, 0, sizeof(file_header)); + file_header.bfType = 0x4d42; /* BM */ + file_header.bfOffBits = sizeof(file_header) + size; + file_header.bfSize = file_header.bfOffBits + w * h * (bpp / 8); + ret = WriteFile(file, &file_header, sizeof(file_header), &written, NULL); + ok(ret && written == sizeof(file_header), "Failed to write file header.\n"); + + info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biBitCount = bpp; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biWidth = w; + info->bmiHeader.biHeight = h; + info->bmiHeader.biCompression = BI_RGB; + if (palettized) + { + for (i = 0; i < 256; ++i) + { + info->bmiColors[i].rgbBlue = i; + info->bmiColors[i].rgbGreen = i; + info->bmiColors[i].rgbRed = i; + } + } + ret = WriteFile(file, info, size, &written, NULL); + ok(ret && written == size, "Failed to write bitmap info.\n"); + HeapFree(GetProcessHeap(), 0, info); + + size = w * h * (bpp / 8); + buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + for (i = 0, j = 0; i < size;) + { + if (palettized) + { + buffer[i++] = j++; + j %= 256; + } + else + { + buffer[i++] = j % 251; + buffer[i++] = j % 239; + buffer[i++] = j++ % 247; + } + } + ret = WriteFile(file, buffer, size, &written, NULL); + ok(ret && written == size, "Failed to write bitmap data.\n"); + HeapFree(GetProcessHeap(), 0, buffer); + + CloseHandle(file); + + return filename; +} + +static void test_bitmap_data(unsigned int test_idx, const D3DRMIMAGE *img, + BOOL upside_down, unsigned int w, unsigned int h, BOOL palettized) +{ + const unsigned char *data = img->buffer1; + unsigned int i, j; + + ok(img->width == w, "Test %u: Got unexpected image width %u, expected %u.\n", test_idx, img->width, w); + ok(img->height == h, "Test %u: Got unexpected image height %u, expected %u.\n", test_idx, img->height, h); + ok(img->aspectx == 1, "Test %u: Got unexpected image aspectx %u.\n", test_idx, img->aspectx); + ok(img->aspecty == 1, "Test %u: Got unexpected image aspecty %u.\n", test_idx, img->aspecty); + ok(!img->buffer2, "Test %u: Got unexpected image buffer2 %p.\n", test_idx, img->buffer2); + + /* The image is palettized if the total number of colors used is <= 256. */ + if (w * h > 256 && !palettized) + { + /* D3drm aligns the 24bpp texture to 4 bytes in the buffer, with one + * byte padding from 24bpp texture. */ + ok(img->depth == 32, "Test %u: Got unexpected image depth %u.\n", test_idx, img->depth); + ok(img->rgb == TRUE, "Test %u: Got unexpected image rgb %#x.\n", test_idx, img->rgb); + ok(img->bytes_per_line == w * 4, "Test %u: Got unexpected image bytes per line %u, expected %u.\n", + test_idx, img->bytes_per_line, w * 4); + ok(img->red_mask == 0xff0000, "Test %u: Got unexpected image red mask %#x.\n", test_idx, img->red_mask); + ok(img->green_mask == 0x00ff00, "Test %u: Got unexpected image green mask %#x.\n", test_idx, img->green_mask); + ok(img->blue_mask == 0x0000ff, "Test %u: Got unexpected image blue mask %#x.\n", test_idx, img->blue_mask); + ok(!img->alpha_mask, "Test %u: Got unexpected image alpha mask %#x.\n", test_idx, img->alpha_mask); + ok(!img->palette_size, "Test %u: Got unexpected palette size %u.\n", test_idx, img->palette_size); + ok(!img->palette, "Test %u: Got unexpected image palette %p.\n", test_idx, img->palette); + for (i = 0; i < h; ++i) + { + for (j = 0; j < w; ++j) + { + const unsigned char *ptr = &data[i * img->bytes_per_line + j * 4]; + unsigned int idx = upside_down ? (h - 1 - i) * w + j : i * w + j; + + if (ptr[0] != idx % 251 || ptr[1] != idx % 239 || ptr[2] != idx % 247 || ptr[3] != 0xff) + { + ok(0, "Test %u: Got unexpected color 0x%02x%02x%02x%02x at position %u, %u, " + "expected 0x%02x%02x%02x%02x.\n", test_idx, ptr[0], ptr[1], ptr[2], ptr[3], + j, i, idx % 251, idx % 239, idx % 247, 0xff); + return; + } + } + } + return; + } + + ok(img->depth == 8, "Test %u: Got unexpected image depth %u.\n", test_idx, img->depth); + ok(!img->rgb, "Test %u: Got unexpected image rgb %#x.\n", test_idx, img->rgb); + ok(img->red_mask == 0xff, "Test %u: Got unexpected image red mask %#x.\n", test_idx, img->red_mask); + ok(img->green_mask == 0xff, "Test %u: Got unexpected image green mask %#x.\n", test_idx, img->green_mask); + ok(img->blue_mask == 0xff, "Test %u: Got unexpected image blue mask %#x.\n", test_idx, img->blue_mask); + ok(!img->alpha_mask, "Test %u: Got unexpected image alpha mask %#x.\n", test_idx, img->alpha_mask); + ok(!!img->palette, "Test %u: Got unexpected image palette %p.\n", test_idx, img->palette); + if (!palettized) + { + /* In this case, bytes_per_line is aligned to the next multiple of + * 4 from width. */ + ok(img->bytes_per_line == ((w + 3) & ~3), "Test %u: Got unexpected image bytes per line %u, expected %u.\n", + test_idx, img->bytes_per_line, (w + 3) & ~3); + ok(img->palette_size == w * h, "Test %u: Got unexpected palette size %u, expected %u.\n", + test_idx, img->palette_size, w * h); + for (i = 0; i < img->palette_size; ++i) + { + unsigned int idx = upside_down ? (h - 1) * w - i + (i % w) * 2 : i; + ok(img->palette[i].red == idx % 251 + && img->palette[i].green == idx % 239 && img->palette[i].blue == idx % 247, + "Test %u: Got unexpected palette entry (%u) color 0x%02x%02x%02x.\n", + test_idx, i, img->palette[i].red, img->palette[i].green, img->palette[i].blue); + ok(img->palette[i].flags == D3DRMPALETTE_READONLY, + "Test %u: Got unexpected palette entry (%u) flags %#x.\n", + test_idx, i, img->palette[i].flags); + } + for (i = 0; i < h; ++i) + { + for (j = 0; j < w; ++j) + { + if (data[i * img->bytes_per_line + j] != i * w + j) + { + ok(0, "Test %u: Got unexpected color 0x%02x at position %u, %u, expected 0x%02x.\n", + test_idx, data[i * img->bytes_per_line + j], j, i, i * w + j); + return; + } + } + } + return; + } + + /* bytes_per_line is not always aligned by d3drm depending on the + * format. */ + ok(img->bytes_per_line == w, "Test %u: Got unexpected image bytes per line %u, expected %u.\n", + test_idx, img->bytes_per_line, w); + ok(img->palette_size == 256, "Test %u: Got unexpected palette size %u.\n", test_idx, img->palette_size); + for (i = 0; i < 256; ++i) + { + ok(img->palette[i].red == i && img->palette[i].green == i && img->palette[i].blue == i, + "Test %u: Got unexpected palette entry (%u) color 0x%02x%02x%02x.\n", + test_idx, i, img->palette[i].red, img->palette[i].green, img->palette[i].blue); + ok(img->palette[i].flags == D3DRMPALETTE_READONLY, + "Test %u: Got unexpected palette entry (%u) flags %#x.\n", + test_idx, i, img->palette[i].flags); + } + for (i = 0; i < h; ++i) + { + for (j = 0; j < w; ++j) + { + unsigned int idx = upside_down ? (h - 1 - i) * w + j : i * w + j; + if (data[i * img->bytes_per_line + j] != idx % 256) + { + ok(0, "Test %u: Got unexpected color 0x%02x at position %u, %u, expected 0x%02x.\n", + test_idx, data[i * img->bytes_per_line + j], j, i, idx % 256); + return; + } + } + } +} + +static void test_load_texture(void) +{ + IDirect3DRMTexture3 *texture3; + IDirect3DRMTexture2 *texture2; + IDirect3DRMTexture *texture1; + D3DRMIMAGE *d3drm_img; + IDirect3DRM3 *d3drm3; + IDirect3DRM2 *d3drm2; + IDirect3DRM *d3drm1; + char *filename; + HRESULT hr; + BOOL ret; + int i; + + static const struct + { + unsigned int w; + unsigned int h; + BOOL palettized; + } + tests[] = + { + {100, 100, TRUE }, + {99, 100, TRUE }, + {100, 100, FALSE}, + {99, 100, FALSE}, + {3, 39, FALSE}, + }; + + hr = Direct3DRMCreate(&d3drm1); + ok(hr == D3DRM_OK, "Failed to create IDirect3DRM object, hr %#x.\n", hr); + hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2); + ok(SUCCEEDED(hr), "Failed to get IDirect3DRM2 interface, hr %#x.\n", hr); + hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3); + ok(SUCCEEDED(hr), "Failed to get IDirect3DRM3 interface, hr %#x.\n", hr); + + for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) + { + filename = create_bitmap(tests[i].w, tests[i].h, tests[i].palettized); + + hr = IDirect3DRM_LoadTexture(d3drm1, filename, &texture1); + ok(SUCCEEDED(hr), "Test %u: Failed to load texture, hr %#x.\n", i, hr); + d3drm_img = IDirect3DRMTexture_GetImage(texture1); + todo_wine ok(!!d3drm_img, "Test %u: Failed to get image.\n", i); + if (d3drm_img) + test_bitmap_data(i * 4, d3drm_img, FALSE, tests[i].w, tests[i].h, tests[i].palettized); + IDirect3DRMTexture_Release(texture1); + + hr = IDirect3DRM2_LoadTexture(d3drm2, filename, &texture2); + ok(SUCCEEDED(hr), "Test %u: Failed to load texture, hr %#x.\n", i, hr); + d3drm_img = IDirect3DRMTexture2_GetImage(texture2); + todo_wine ok(!!d3drm_img, "Test %u: Failed to get image.\n", i); + if (d3drm_img) + test_bitmap_data(i * 4 + 1, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized); + IDirect3DRMTexture2_Release(texture2); + + hr = IDirect3DRM3_LoadTexture(d3drm3, filename, &texture3); + ok(SUCCEEDED(hr), "Test %u: Failed to load texture, hr %#x.\n", i, hr); + d3drm_img = IDirect3DRMTexture3_GetImage(texture3); + todo_wine ok(!!d3drm_img, "Test %u: Failed to get image.\n", i); + if (d3drm_img) + test_bitmap_data(i * 4 + 2, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized); + /* Test whether querying a version 1 texture from version 3 causes a + * change in the loading behavior. */ + hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)&texture1); + ok(SUCCEEDED(hr), "Failed to get IDirect3DRMTexture interface, hr %#x.\n", hr); + d3drm_img = IDirect3DRMTexture_GetImage(texture1); + todo_wine ok(!!d3drm_img, "Test %u: Failed to get image.\n", i); + if (d3drm_img) + test_bitmap_data(i * 4 + 3, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized); + IDirect3DRMTexture_Release(texture1); + IDirect3DRMTexture3_Release(texture3); + + ret = DeleteFileA(filename); + ok(ret, "Test %u: Failed to delete bitmap \"%s\".\n", i, filename); + HeapFree(GetProcessHeap(), 0, filename); + } + + IDirect3DRM3_Release(d3drm3); + IDirect3DRM2_Release(d3drm2); + IDirect3DRM_Release(d3drm1); +} + +static void test_texture_qi(void) +{ + static const struct qi_test tests[] = + { + { &IID_IDirect3DRM3, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRM2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRM, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMDevice, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMDevice2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMDevice3, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMWinDevice, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMObject, &IID_IUnknown, S_OK }, + { &IID_IDirect3DRMViewport, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMViewport2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMFrame, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMFrame2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMFrame3, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMVisual, &IID_IUnknown, S_OK }, + { &IID_IDirect3DRMMesh, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMMeshBuilder, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMMeshBuilder2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMMeshBuilder3, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMFace, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMFace2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMLight, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMTexture, &IID_IUnknown, S_OK }, + { &IID_IDirect3DRMTexture2, &IID_IUnknown, S_OK }, + { &IID_IDirect3DRMTexture3, &IID_IUnknown, S_OK }, + { &IID_IDirect3DRMWrap, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMMaterial, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMMaterial2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMAnimation, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMAnimation2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMAnimationSet, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMAnimationSet2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMObjectArray, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMDeviceArray, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMViewportArray, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMFrameArray, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMVisualArray, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMLightArray, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMPickedArray, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMFaceArray, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMAnimationArray, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMUserVisual, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMShadow, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMShadow2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMInterpolator, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMProgressiveMesh, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMPicked2Array, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DRMClippedVisual, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirectDrawClipper, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirectDrawSurface7, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirectDrawSurface4, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirectDrawSurface3, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirectDrawSurface2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirectDrawSurface, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DDevice7, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DDevice3, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DDevice2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DDevice, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3D7, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3D3, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3D2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3D, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirectDraw7, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirectDraw4, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirectDraw3, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirectDraw2, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirectDraw, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IDirect3DLight, NULL, CLASS_E_CLASSNOTAVAILABLE }, + { &IID_IUnknown, &IID_IUnknown, S_OK, }, + }; + HRESULT hr; + IDirect3DRM *d3drm1; + IDirect3DRM2 *d3drm2; + IDirect3DRM3 *d3drm3; + IDirect3DRMTexture *texture1; + IDirect3DRMTexture2 *texture2; + IDirect3DRMTexture3 *texture3; + IUnknown *unknown; + char *filename; + BOOL check; + + hr = Direct3DRMCreate(&d3drm1); + ok(SUCCEEDED(hr), "Cannot get IDirect3DRM interface (hr = %#x)\n", hr); + filename = create_bitmap(1, 1, TRUE); + hr = IDirect3DRM_LoadTexture(d3drm1, filename, &texture1); + ok(SUCCEEDED(hr), "Failed to load texture (hr = %#x).\n", hr); + ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture interface (hr = %#x)\n", hr); + hr = IDirect3DRMTexture_QueryInterface(texture1, &IID_IUnknown, (void **)&unknown); + ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMTexture (hr = %#x)\n", hr); + IDirect3DRMTexture_Release(texture1); + test_qi("texture1_qi", unknown, &IID_IUnknown, tests, sizeof(tests) / sizeof(*tests)); + IUnknown_Release(unknown); + + hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2); + ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %#x).\n", hr); + hr = IDirect3DRM2_LoadTexture(d3drm2, filename, &texture2); + ok(SUCCEEDED(hr), "Failed to load texture (hr = %#x).\n", hr); + hr = IDirect3DRMTexture2_QueryInterface(texture2, &IID_IUnknown, (void **)&unknown); + ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMTexture2 (hr = %#x)\n", hr); + IDirect3DRMTexture2_Release(texture2); + test_qi("texture2_qi", unknown, &IID_IUnknown, tests, sizeof(tests) / sizeof(*tests)); + IUnknown_Release(unknown); + + hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3); + ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %#x).\n", hr); + hr = IDirect3DRM3_LoadTexture(d3drm3, filename, &texture3); + ok(SUCCEEDED(hr), "Failed to load texture (hr = %#x).\n", hr); + ok(SUCCEEDED(hr), "Cannot get IDirect3DRMTexture3 interface (hr = %#x)\n", hr); + hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IUnknown, (void **)&unknown); + ok(SUCCEEDED(hr), "Cannot get IUnknown interface from IDirect3DRMTexture3 (hr = %#x)\n", hr); + IDirect3DRMTexture3_Release(texture3); + test_qi("texture3_qi", unknown, &IID_IUnknown, tests, sizeof(tests) / sizeof(*tests)); + IUnknown_Release(unknown); + + IDirect3DRM3_Release(d3drm3); + IDirect3DRM2_Release(d3drm2); + IDirect3DRM_Release(d3drm1); + check = DeleteFileA(filename); + ok(check, "Cannot delete image stored in %s (error = %d).\n", filename, GetLastError()); + HeapFree(GetProcessHeap(), 0, filename); +} + START_TEST(d3drm) { test_MeshBuilder(); @@ -3720,4 +4119,6 @@ test_create_device_from_d3d1(); test_create_device_from_d3d2(); test_create_device_from_d3d3(); + test_load_texture(); + test_texture_qi(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3drm/texture.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3drm/texture.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3drm/texture.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3drm/texture.c 2016-02-08 19:32:34.000000000 +0000 @@ -679,21 +679,26 @@ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); - if (IsEqualGUID(riid, &IID_IDirect3DRMTexture2) - || IsEqualGUID(riid, &IID_IDirect3DRMTexture) + if (IsEqualGUID(riid, &IID_IDirect3DRMTexture3) + || IsEqualGUID(riid, &IID_IDirect3DRMVisual) + || IsEqualGUID(riid, &IID_IDirect3DRMObject) || IsEqualGUID(riid, &IID_IUnknown)) { + *out = &texture->IDirect3DRMTexture3_iface; + } + else if (IsEqualGUID(riid, &IID_IDirect3DRMTexture2)) + { *out = &texture->IDirect3DRMTexture2_iface; } - else if (IsEqualGUID(riid, &IID_IDirect3DRMTexture3)) + else if (IsEqualGUID(riid, &IID_IDirect3DRMTexture)) { - *out = &texture->IDirect3DRMTexture3_iface; + *out = &texture->IDirect3DRMTexture_iface; } else { *out = NULL; - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); - return E_NOINTERFACE; + WARN("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(riid)); + return CLASS_E_CLASSNOTAVAILABLE; } IUnknown_AddRef((IUnknown *)*out); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/animation.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/animation.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/animation.c 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/animation.c 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,469 @@ +/* + * Animation Controller operations specific to D3DX9. + * + * Copyright (C) 2015 Christian Costa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "wine/debug.h" +#include "d3dx9_36_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx); + +struct d3dx9_animation_controller +{ + ID3DXAnimationController ID3DXAnimationController_iface; + LONG ref; + + UINT max_outputs; + UINT max_sets; + UINT max_tracks; + UINT max_events; +}; + +static inline struct d3dx9_animation_controller *impl_from_ID3DXAnimationController(ID3DXAnimationController *iface) +{ + return CONTAINING_RECORD(iface, struct d3dx9_animation_controller, ID3DXAnimationController_iface); +} + +static HRESULT WINAPI d3dx9_animation_controller_QueryInterface(ID3DXAnimationController *iface, REFIID riid, void **out) +{ + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_ID3DXAnimationController)) + { + iface->lpVtbl->AddRef(iface); + *out = iface; + return D3D_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI d3dx9_animation_controller_AddRef(ID3DXAnimationController *iface) +{ + struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); + ULONG refcount = InterlockedIncrement(&animation->ref); + + TRACE("%p increasing refcount to %u.\n", animation, refcount); + + return refcount; +} + +static ULONG WINAPI d3dx9_animation_controller_Release(ID3DXAnimationController *iface) +{ + struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); + ULONG refcount = InterlockedDecrement(&animation->ref); + + TRACE("%p decreasing refcount to %u.\n", animation, refcount); + + if (!refcount) + { + HeapFree(GetProcessHeap(), 0, animation); + } + + return refcount; +} + +static UINT WINAPI d3dx9_animation_controller_GetMaxNumAnimationOutputs(ID3DXAnimationController *iface) +{ + struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); + + TRACE("iface %p.\n", iface); + + return animation->max_outputs; +} + +static UINT WINAPI d3dx9_animation_controller_GetMaxNumAnimationSets(ID3DXAnimationController *iface) +{ + struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); + + TRACE("iface %p.\n", iface); + + return animation->max_sets; +} + +static UINT WINAPI d3dx9_animation_controller_GetMaxNumTracks(ID3DXAnimationController *iface) +{ + struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); + + TRACE("iface %p.\n", iface); + + return animation->max_tracks; +} + +static UINT WINAPI d3dx9_animation_controller_GetMaxNumEvents(ID3DXAnimationController *iface) +{ + struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); + + TRACE("iface %p.\n", iface); + + return animation->max_events; +} + +static HRESULT WINAPI d3dx9_animation_controller_RegisterAnimationOutput(ID3DXAnimationController *iface, + const char *name, D3DXMATRIX *matrix, D3DXVECTOR3 *scale, D3DXQUATERNION *rotation, D3DXVECTOR3 *translation) +{ + FIXME("iface %p, name %s, matrix %p, scale %p, rotation %p, translation %p stub.\n", iface, debugstr_a(name), + matrix, scale, rotation, translation); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_RegisterAnimationSet(ID3DXAnimationController *iface, + ID3DXAnimationSet *anim_set) +{ + FIXME("iface %p, anim_set %p stub.\n", iface, anim_set); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_UnregisterAnimationSet(ID3DXAnimationController *iface, + ID3DXAnimationSet *anim_set) +{ + FIXME("iface %p, anim_set %p stub.\n", iface, anim_set); + + return E_NOTIMPL; +} + +static UINT WINAPI d3dx9_animation_controller_GetNumAnimationSets(ID3DXAnimationController *iface) +{ + FIXME("iface %p stub.\n", iface); + + return 0; +} + +static HRESULT WINAPI d3dx9_animation_controller_GetAnimationSet(ID3DXAnimationController *iface, + UINT index, ID3DXAnimationSet **anim_set) +{ + FIXME("iface %p, index %u, anim_set %p stub.\n", iface, index, anim_set); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_GetAnimationSetByName(ID3DXAnimationController *iface, + const char *name, ID3DXAnimationSet **anim_set) +{ + FIXME("iface %p, name %s, anim_set %p stub.\n", iface, debugstr_a(name), anim_set); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_AdvanceTime(ID3DXAnimationController *iface, double time_delta, + ID3DXAnimationCallbackHandler *callback_handler) +{ + FIXME("iface %p, time_delta %.16e, callback_handler %p stub.\n", iface, time_delta, callback_handler); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_Reset(ID3DXAnimationController *iface) +{ + FIXME("iface %p stub.\n", iface); + + return E_NOTIMPL; +} + +static double WINAPI d3dx9_animation_controller_GetTime(ID3DXAnimationController *iface) +{ + FIXME("iface %p stub.\n", iface); + + return 0.0; +} + +static HRESULT WINAPI d3dx9_animation_controller_SetTrackAnimationSet(ID3DXAnimationController *iface, + UINT track, ID3DXAnimationSet *anim_set) +{ + FIXME("iface %p, track %u, anim_set %p stub.\n", iface, track, anim_set); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_GetTrackAnimationSet(ID3DXAnimationController *iface, + UINT track, ID3DXAnimationSet **anim_set) +{ + FIXME("iface %p, track %u, anim_set %p stub.\n", iface, track, anim_set); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_SetTrackPriority(ID3DXAnimationController *iface, + UINT track, D3DXPRIORITY_TYPE priority) +{ + FIXME("iface %p, track %u, priority %u stub.\n", iface, track, priority); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_SetTrackSpeed(ID3DXAnimationController *iface, + UINT track, float speed) +{ + FIXME("iface %p, track %u, speed %.8e stub.\n", iface, track, speed); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_SetTrackWeight(ID3DXAnimationController *iface, + UINT track, float weight) +{ + FIXME("iface %p, track %u, weight %.8e stub.\n", iface, track, weight); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_SetTrackPosition(ID3DXAnimationController *iface, + UINT track, double position) +{ + FIXME("iface %p, track %u, position %.16e stub.\n", iface, track, position); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_SetTrackEnable(ID3DXAnimationController *iface, + UINT track, BOOL enable) +{ + FIXME("iface %p, track %u, enable %#x stub.\n", iface, track, enable); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_SetTrackDesc(ID3DXAnimationController *iface, + UINT track, D3DXTRACK_DESC *desc) +{ + FIXME("iface %p, track %u, desc %p stub.\n", iface, track, desc); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_GetTrackDesc(ID3DXAnimationController *iface, + UINT track, D3DXTRACK_DESC *desc) +{ + FIXME("iface %p, track %u, desc %p stub.\n", iface, track, desc); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_SetPriorityBlend(ID3DXAnimationController *iface, + float blend_weight) +{ + FIXME("iface %p, blend_weight %.8e stub.\n", iface, blend_weight); + + return E_NOTIMPL; +} + +static float WINAPI d3dx9_animation_controller_GetPriorityBlend(ID3DXAnimationController *iface) +{ + FIXME("iface %p stub.\n", iface); + + return 0.0f; +} + +static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_KeyTrackSpeed(ID3DXAnimationController *iface, + UINT track, float new_speed, double start_time, double duration, D3DXTRANSITION_TYPE transition) +{ + FIXME("iface %p, track %u, new_speed %.8e, start_time %.16e, duration %.16e, transition %u stub.\n", iface, + track, new_speed, start_time, duration, transition); + + return 0; +} + +static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_KeyTrackWeight(ID3DXAnimationController *iface, + UINT track, float new_weight, double start_time, double duration, D3DXTRANSITION_TYPE transition) +{ + FIXME("iface %p, track %u, new_weight %.8e, start_time %.16e, duration %.16e, transition %u stub.\n", iface, + track, new_weight, start_time, duration, transition); + + return 0; +} + +static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_KeyTrackPosition(ID3DXAnimationController *iface, + UINT track, double new_position, double start_time) +{ + FIXME("iface %p, track %u, new_position %.16e, start_time %.16e stub.\n", iface, + track, new_position, start_time); + + return 0; +} + +static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_KeyTrackEnable(ID3DXAnimationController *iface, + UINT track, BOOL new_enable, double start_time) +{ + FIXME("iface %p, track %u, new_enable %#x, start_time %.16e stub.\n", iface, + track, new_enable, start_time); + + return 0; +} + +static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_KeyTrackBlend(ID3DXAnimationController *iface, + float new_blend_weight, double start_time, double duration, D3DXTRANSITION_TYPE transition) +{ + FIXME("iface %p, new_blend_weight %.8e, start_time %.16e, duration %.16e, transition %u stub.\n", iface, + new_blend_weight, start_time, duration, transition); + + return 0; +} + +static HRESULT WINAPI d3dx9_animation_controller_UnkeyEvent(ID3DXAnimationController *iface, D3DXEVENTHANDLE event) +{ + FIXME("iface %p, event %u stub.\n", iface, event); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_UnkeyAllTrackEvents(ID3DXAnimationController *iface, UINT track) +{ + FIXME("iface %p, track %u stub.\n", iface, track); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_UnkeyAllPriorityBlends(ID3DXAnimationController *iface) +{ + FIXME("iface %p stub.\n", iface); + + return E_NOTIMPL; +} + +static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_GetCurrentTrackEvent(ID3DXAnimationController *iface, + UINT track, D3DXEVENT_TYPE event_type) +{ + FIXME("iface %p, track %u, event_type %u stub.\n", iface, track, event_type); + + return 0; +} + +static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_GetCurrentPriorityBlend(ID3DXAnimationController *iface) +{ + FIXME("iface %p stub.\n", iface); + + return 0; +} + +static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_GetUpcomingTrackEvent(ID3DXAnimationController *iface, + UINT track, D3DXEVENTHANDLE event) +{ + FIXME("iface %p, track %u, event %u stub.\n", iface, track, event); + + return 0; +} + +static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_GetUpcomingPriorityBlend(ID3DXAnimationController *iface, + D3DXEVENTHANDLE event) +{ + FIXME("iface %p, event %u stub.\n", iface, event); + + return 0; +} + +static HRESULT WINAPI d3dx9_animation_controller_ValidateEvent(ID3DXAnimationController *iface, D3DXEVENTHANDLE event) +{ + FIXME("iface %p, event %u stub.\n", iface, event); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_GetEventDesc(ID3DXAnimationController *iface, + D3DXEVENTHANDLE event, D3DXEVENT_DESC *desc) +{ + FIXME("iface %p, event %u, desc %p stub.\n", iface, event, desc); + + return E_NOTIMPL; +} + +static HRESULT WINAPI d3dx9_animation_controller_CloneAnimationController(ID3DXAnimationController *iface, UINT max_outputs, + UINT max_sets, UINT max_tracks, UINT max_events, ID3DXAnimationController **anim_controller) +{ + FIXME("iface %p, max_outputs %u, max_sets %u, max_tracks %u, max_events %u, anim_controller %p stub.\n", + iface, max_outputs, max_sets, max_tracks, max_events, anim_controller); + + return E_NOTIMPL; +} + +static const struct ID3DXAnimationControllerVtbl d3dx9_animation_controller_vtbl = +{ + d3dx9_animation_controller_QueryInterface, + d3dx9_animation_controller_AddRef, + d3dx9_animation_controller_Release, + d3dx9_animation_controller_GetMaxNumAnimationOutputs, + d3dx9_animation_controller_GetMaxNumAnimationSets, + d3dx9_animation_controller_GetMaxNumTracks, + d3dx9_animation_controller_GetMaxNumEvents, + d3dx9_animation_controller_RegisterAnimationOutput, + d3dx9_animation_controller_RegisterAnimationSet, + d3dx9_animation_controller_UnregisterAnimationSet, + d3dx9_animation_controller_GetNumAnimationSets, + d3dx9_animation_controller_GetAnimationSet, + d3dx9_animation_controller_GetAnimationSetByName, + d3dx9_animation_controller_AdvanceTime, + d3dx9_animation_controller_Reset, + d3dx9_animation_controller_GetTime, + d3dx9_animation_controller_SetTrackAnimationSet, + d3dx9_animation_controller_GetTrackAnimationSet, + d3dx9_animation_controller_SetTrackPriority, + d3dx9_animation_controller_SetTrackSpeed, + d3dx9_animation_controller_SetTrackWeight, + d3dx9_animation_controller_SetTrackPosition, + d3dx9_animation_controller_SetTrackEnable, + d3dx9_animation_controller_SetTrackDesc, + d3dx9_animation_controller_GetTrackDesc, + d3dx9_animation_controller_SetPriorityBlend, + d3dx9_animation_controller_GetPriorityBlend, + d3dx9_animation_controller_KeyTrackSpeed, + d3dx9_animation_controller_KeyTrackWeight, + d3dx9_animation_controller_KeyTrackPosition, + d3dx9_animation_controller_KeyTrackEnable, + d3dx9_animation_controller_KeyTrackBlend, + d3dx9_animation_controller_UnkeyEvent, + d3dx9_animation_controller_UnkeyAllTrackEvents, + d3dx9_animation_controller_UnkeyAllPriorityBlends, + d3dx9_animation_controller_GetCurrentTrackEvent, + d3dx9_animation_controller_GetCurrentPriorityBlend, + d3dx9_animation_controller_GetUpcomingTrackEvent, + d3dx9_animation_controller_GetUpcomingPriorityBlend, + d3dx9_animation_controller_ValidateEvent, + d3dx9_animation_controller_GetEventDesc, + d3dx9_animation_controller_CloneAnimationController +}; + +HRESULT WINAPI D3DXCreateAnimationController(UINT max_outputs, UINT max_sets, + UINT max_tracks, UINT max_events, ID3DXAnimationController **controller) +{ + struct d3dx9_animation_controller *object; + + TRACE("max_outputs %u, max_sets %u, max_tracks %u, max_events %u, controller %p.\n", + max_outputs, max_sets, max_tracks, max_events, controller); + + if (!max_outputs || !max_sets || !max_tracks || !max_events || !controller) + return D3D_OK; + + object = HeapAlloc(GetProcessHeap(), 0, sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->ID3DXAnimationController_iface.lpVtbl = &d3dx9_animation_controller_vtbl; + object->ref = 1; + object->max_outputs = max_outputs; + object->max_sets = max_sets; + object->max_tracks = max_tracks; + object->max_events = max_events; + + *controller = &object->ID3DXAnimationController_iface; + + return D3D_OK; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/core.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/core.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/core.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/core.c 2016-02-08 19:32:34.000000000 +0000 @@ -157,7 +157,7 @@ *buffer = &object->ID3DXBuffer_iface; - TRACE("Created ID3DBuffer %p\n", *buffer); + TRACE("Created ID3DXBuffer %p.\n", *buffer); return D3D_OK; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/d3dx9_36.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/d3dx9_36.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/d3dx9_36.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/d3dx9_36.spec 2016-02-08 19:32:34.000000000 +0000 @@ -28,9 +28,9 @@ @ stub D3DXComputeTangentFrame(ptr long) @ stdcall D3DXComputeTangentFrameEx(ptr long long long long long long long long long ptr float float float ptr ptr) @ stub D3DXConcatenateMeshes(ptr long long ptr ptr ptr ptr ptr) -@ stub D3DXConvertMeshSubsetToSingleStrip(ptr long long ptr ptr) +@ stdcall D3DXConvertMeshSubsetToSingleStrip(ptr long long ptr ptr) @ stub D3DXConvertMeshSubsetToStrips(ptr long long ptr ptr ptr ptr) -@ stub D3DXCreateAnimationController(long long long long ptr) +@ stdcall D3DXCreateAnimationController(long long long long ptr) @ stdcall D3DXCreateBox(ptr float float float ptr ptr) @ stdcall D3DXCreateBuffer(long ptr) @ stub D3DXCreateCompressedAnimationSet(ptr long long ptr long ptr ptr) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -3,6 +3,7 @@ IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 C_SRCS = \ + animation.c \ core.c \ d3dx9_36_main.c \ effect.c \ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/mesh.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/mesh.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/mesh.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/mesh.c 2016-02-08 19:32:34.000000000 +0000 @@ -7549,3 +7549,12 @@ return E_NOTIMPL; } + +HRESULT WINAPI D3DXConvertMeshSubsetToSingleStrip(struct ID3DXBaseMesh *mesh_in, DWORD attribute_id, + DWORD ib_flags, struct IDirect3DIndexBuffer9 **index_buffer, DWORD *index_count) +{ + FIXME("mesh_in %p, attribute_id %u, ib_flags %u, index_buffer %p, index_count %p stub.\n", + mesh_in, attribute_id, ib_flags, index_buffer, index_count); + + return E_NOTIMPL; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/surface.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/surface.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/surface.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/surface.c 2016-02-08 19:32:34.000000000 +0000 @@ -487,13 +487,11 @@ memset(header, 0, sizeof(*header)); header->signature = MAKEFOURCC('D','D','S',' '); - header->size = sizeof(*header); - header->flags = DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PITCH | DDS_PIXELFORMAT | DDS_MIPMAPCOUNT; + /* The signature is not really part of the DDS header */ + header->size = sizeof(*header) - FIELD_OFFSET(struct dds_header, size); + header->flags = DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT; header->height = src_desc.Height; header->width = src_desc.Width; - header->pitch_or_linear_size = dst_pitch; - header->depth = 1; - header->miplevels = 1; header->caps = DDS_CAPS_TEXTURE; hr = d3dformat_to_dds_pixel_format(&header->pixel_format, src_desc.Format); if (FAILED(hr)) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/tests/core.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/tests/core.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/tests/core.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/tests/core.c 2016-02-08 19:32:34.000000000 +0000 @@ -81,7 +81,7 @@ ok(!size, "GetBufferSize failed, got %u, expected %u\n", size, 0); count = ID3DXBuffer_Release(buffer); - ok(!count, "ID3DBuffer has %u references left\n", count); + ok(!count, "ID3DXBuffer has %u references left\n", count); hr = D3DXCreateBuffer(3, &buffer); ok(hr == D3D_OK, "D3DXCreateBuffer failed, got %#x, expected %#x\n", hr, D3D_OK); @@ -90,7 +90,7 @@ ok(size == 3, "GetBufferSize failed, got %u, expected %u\n", size, 3); count = ID3DXBuffer_Release(buffer); - ok(!count, "ID3DBuffer has %u references left\n", count); + ok(!count, "ID3DXBuffer has %u references left\n", count); } static void test_ID3DXSprite(IDirect3DDevice9 *device) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/tests/mesh.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/tests/mesh.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/tests/mesh.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/tests/mesh.c 2016-02-08 19:32:34.000000000 +0000 @@ -11100,6 +11100,70 @@ free_test_context(test_context); } +static void D3DXCreateAnimationControllerTest(void) +{ + HRESULT hr; + ID3DXAnimationController *animation; + UINT value; + + hr = D3DXCreateAnimationController(0, 0, 0, 0, NULL); + ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr); + + animation = (void*)0xdeadbeef; + hr = D3DXCreateAnimationController(0, 1, 1, 1, &animation); + ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr); + ok(animation == (void*)0xdeadbeef, "Got unexpected animation %p.\n", animation); + + animation = (void*)0xdeadbeef; + hr = D3DXCreateAnimationController(1, 0, 1, 1, &animation); + ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr); + ok(animation == (void*)0xdeadbeef, "Got unexpected animation %p.\n", animation); + + animation = (void*)0xdeadbeef; + hr = D3DXCreateAnimationController(1, 1, 0, 1, &animation); + ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr); + ok(animation == (void*)0xdeadbeef, "Got unexpected animation %p.\n", animation); + + animation = (void*)0xdeadbeef; + hr = D3DXCreateAnimationController(1, 1, 1, 0, &animation); + ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr); + ok(animation == (void*)0xdeadbeef, "Got unexpected animation %p.\n", animation); + + hr = D3DXCreateAnimationController(1, 1, 1, 1, &animation); + ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr); + + value = animation->lpVtbl->GetMaxNumAnimationOutputs(animation); + ok(value == 1, "Got unexpected value %u.\n", value); + + value = animation->lpVtbl->GetMaxNumAnimationSets(animation); + ok(value == 1, "Got unexpected value %u.\n", value); + + value = animation->lpVtbl->GetMaxNumTracks(animation); + ok(value == 1, "Got unexpected value %u.\n", value); + + value = animation->lpVtbl->GetMaxNumEvents(animation); + ok(value == 1, "Got unexpected value %u.\n", value); + + animation->lpVtbl->Release(animation); + + hr = D3DXCreateAnimationController(100, 101, 102, 103, &animation); + ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr); + + value = animation->lpVtbl->GetMaxNumAnimationOutputs(animation); + ok(value == 100, "Got unexpected value %u.\n", value); + + value = animation->lpVtbl->GetMaxNumAnimationSets(animation); + ok(value == 101, "Got unexpected value %u.\n", value); + + value = animation->lpVtbl->GetMaxNumTracks(animation); + ok(value == 102, "Got unexpected value %u.\n", value); + + value = animation->lpVtbl->GetMaxNumEvents(animation); + ok(value == 103, "Got unexpected value %u.\n", value); + + animation->lpVtbl->Release(animation); +} + START_TEST(mesh) { D3DXBoundProbeTest(); @@ -11116,6 +11180,7 @@ D3DXCreateCylinderTest(); D3DXCreateTextTest(); D3DXCreateTorusTest(); + D3DXCreateAnimationControllerTest(); test_get_decl_length(); test_get_decl_vertex_size(); test_fvf_decl_conversion(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/tests/surface.c wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/tests/surface.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/d3dx9_36/tests/surface.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/d3dx9_36/tests/surface.c 2016-02-08 19:32:34.000000000 +0000 @@ -175,6 +175,7 @@ #define DDS_LINEARSIZE 0x00080000 /* dds_header.caps */ +#define DDSCAPS_ALPHA 0x00000002 #define DDS_CAPS_TEXTURE 0x00001000 /* dds_pixel_format.flags */ @@ -199,7 +200,6 @@ struct dds_header { - DWORD magic; DWORD size; DWORD flags; DWORD height; @@ -211,7 +211,9 @@ struct dds_pixel_format pixel_format; DWORD caps; DWORD caps2; - DWORD reserved2[3]; + DWORD caps3; + DWORD caps4; + DWORD reserved2; }; /* fills dds_header with reasonable default values */ @@ -219,7 +221,6 @@ { memset(header, 0, sizeof(*header)); - header->magic = MAKEFOURCC('D','D','S',' '); header->size = sizeof(*header); header->flags = DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT; header->height = 4; @@ -247,10 +248,12 @@ D3DXIMAGE_INFO info; struct { + DWORD magic; struct dds_header header; BYTE data[256]; } dds; + dds.magic = MAKEFOURCC('D','D','S',' '); fill_dds_header(&dds.header); dds.header.pixel_format.flags = flags; dds.header.pixel_format.fourcc = fourcc; @@ -278,6 +281,7 @@ D3DXIMAGE_INFO info; struct { + DWORD magic; struct dds_header header; BYTE data[4096 * 1024]; } *dds; @@ -396,9 +400,10 @@ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { - DWORD file_size = sizeof(dds->header) + tests[i].pixel_data_size; + DWORD file_size = sizeof(dds->magic) + sizeof(dds->header) + tests[i].pixel_data_size; assert(file_size <= sizeof(*dds)); + dds->magic = MAKEFOURCC('D','D','S',' '); fill_dds_header(&dds->header); dds->header.flags |= tests[i].flags; dds->header.width = tests[i].width; @@ -1231,6 +1236,12 @@ RECT rect; ID3DXBuffer *buffer; IDirect3DSurface9 *surface; + struct + { + DWORD magic; + struct dds_header header; + BYTE *data; + } *dds; hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL); if (FAILED(hr)) { @@ -1248,6 +1259,42 @@ ID3DXBuffer_Release(buffer); } + SetRectEmpty(&rect); + hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, NULL, &rect); + todo_wine ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + if (SUCCEEDED(hr)) + { + dds = ID3DXBuffer_GetBufferPointer(buffer); + + ok(dds->magic == MAKEFOURCC('D','D','S',' '), "Got unexpected DDS signature %#x.\n", dds->magic); + ok(dds->header.size == sizeof(dds->header), "Got unexpected DDS size %u.\n", dds->header.size); + ok(!dds->header.height, "Got unexpected height %u.\n", dds->header.height); + ok(!dds->header.width, "Got unexpected width %u.\n", dds->header.width); + ok(!dds->header.depth, "Got unexpected depth %u.\n", dds->header.depth); + ok(!dds->header.miplevels, "Got unexpected miplevels %u.\n", dds->header.miplevels); + ok(!dds->header.pitch_or_linear_size, "Got unexpected pitch_or_linear_size %u.\n", dds->header.pitch_or_linear_size); + ok(dds->header.caps == (DDS_CAPS_TEXTURE | DDSCAPS_ALPHA), "Got unexpected caps %#x.\n", dds->header.caps); + ok(dds->header.flags == (DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT), + "Got unexpected flags %#x.\n", dds->header.flags); + ID3DXBuffer_Release(buffer); + } + + hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, NULL, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + dds = ID3DXBuffer_GetBufferPointer(buffer); + ok(dds->magic == MAKEFOURCC('D','D','S',' '), "Got unexpected DDS signature %#x.\n", dds->magic); + ok(dds->header.size == sizeof(dds->header), "Got unexpected DDS size %u.\n", dds->header.size); + ok(dds->header.height == 4, "Got unexpected height %u.\n", dds->header.height); + ok(dds->header.width == 4, "Got unexpected width %u.\n", dds->header.width); + ok(!dds->header.depth, "Got unexpected depth %u.\n", dds->header.depth); + ok(!dds->header.miplevels, "Got unexpected miplevels %u.\n", dds->header.miplevels); + ok(!dds->header.pitch_or_linear_size, "Got unexpected pitch_or_linear_size %u.\n", dds->header.pitch_or_linear_size); + todo_wine ok(dds->header.caps == (DDS_CAPS_TEXTURE | DDSCAPS_ALPHA), "Got unexpected caps %#x.\n", dds->header.caps); + ok(dds->header.flags == (DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT), + "Got unexpected flags %#x.\n", dds->header.flags); + ID3DXBuffer_Release(buffer); + IDirect3DSurface9_Release(surface); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/ddraw.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/ddraw.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/ddraw.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/ddraw.c 2016-02-08 19:32:34.000000000 +0000 @@ -4765,7 +4765,7 @@ return DDERR_OUTOFVIDEOMEMORY; } - ddraw_surface_init(ddraw_surface, ddraw, wined3d_texture_get_parent(wined3d_texture), surface, parent_ops); + ddraw_surface_init(ddraw_surface, ddraw, wined3d_texture, sub_resource_idx, surface, parent_ops); *parent = ddraw_surface; ddraw_update_lost_surfaces(ddraw); @@ -4816,13 +4816,13 @@ } if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, desc, 1, - WINED3D_SURFACE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, texture))) + WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, texture))) { WARN("Failed to create texture, hr %#x.\n", hr); return hr; } - ddraw->wined3d_frontbuffer = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(*texture, 0)); + ddraw->wined3d_frontbuffer = *texture; return hr; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/ddraw_private.h wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/ddraw_private.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/ddraw_private.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/ddraw_private.h 2016-02-08 19:32:34.000000000 +0000 @@ -92,7 +92,7 @@ struct ddraw_surface *primary; RECT primary_lock; - struct wined3d_surface *wined3d_frontbuffer; + struct wined3d_texture *wined3d_frontbuffer; struct wined3d_swapchain *wined3d_swapchain; HWND swapchain_window; @@ -163,6 +163,7 @@ struct ddraw *ddraw; struct wined3d_surface *wined3d_surface; struct wined3d_texture *wined3d_texture; + unsigned int sub_resource_idx; struct wined3d_rendertarget_view *wined3d_rtv; struct wined3d_private_store private_store; struct d3d_device *device1; @@ -209,7 +210,8 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc, struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) DECLSPEC_HIDDEN; struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddraw_surface *surface) DECLSPEC_HIDDEN; -void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture, +void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; ULONG ddraw_surface_release_iface(struct ddraw_surface *This) DECLSPEC_HIDDEN; HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/device.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/device.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/device.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/device.c 2016-02-08 19:32:34.000000000 +0000 @@ -1091,7 +1091,7 @@ for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i) { if (wined3d_check_device_format(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL, - mode.format_id, 0, WINED3D_RTYPE_TEXTURE, FormatList[i]) == D3D_OK) + mode.format_id, 0, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK) { DDPIXELFORMAT pformat; @@ -1114,7 +1114,7 @@ { if (wined3d_check_device_format(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_QUERY_LEGACYBUMPMAP, - WINED3D_RTYPE_TEXTURE, BumpFormatList[i]) == D3D_OK) + WINED3D_RTYPE_TEXTURE_2D, BumpFormatList[i]) == D3D_OK) { DDPIXELFORMAT pformat; @@ -1219,7 +1219,7 @@ for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i) { if (wined3d_check_device_format(device->ddraw->wined3d, 0, WINED3D_DEVICE_TYPE_HAL, - mode.format_id, 0, WINED3D_RTYPE_TEXTURE, FormatList[i]) == D3D_OK) + mode.format_id, 0, WINED3D_RTYPE_TEXTURE_2D, FormatList[i]) == D3D_OK) { DDSURFACEDESC sdesc; @@ -2755,6 +2755,12 @@ TRACE("iface %p, state %#x, value %#x.\n", iface, state, value); + if (state >= D3DSTATE_OVERRIDE_BIAS) + { + WARN("Unhandled state %#x.\n", state); + return DDERR_INVALIDPARAMS; + } + wined3d_mutex_lock(); switch (state) @@ -5625,7 +5631,7 @@ return DDERR_INVALIDPARAMS; wined3d_mutex_lock(); - wined3d_surface_preload(surface->wined3d_surface); + wined3d_texture_preload(surface->wined3d_texture); wined3d_mutex_unlock(); return D3D_OK; @@ -5944,10 +5950,10 @@ return !dest_level && levelFound; } -static void copy_mipmap_chain(struct d3d_device *device, struct ddraw_surface *dest, +static void copy_mipmap_chain(struct d3d_device *device, struct ddraw_surface *dst, struct ddraw_surface *src, const POINT *DestPoint, const RECT *SrcRect) { - struct ddraw_surface *src_level, *dest_level; + struct ddraw_surface *dst_level, *src_level; IDirectDrawSurface7 *temp; DDSURFACEDESC2 ddsd; POINT point; @@ -5959,7 +5965,7 @@ /* Copy palette, if possible. */ IDirectDrawSurface7_GetPalette(&src->IDirectDrawSurface7_iface, &pal_src); - IDirectDrawSurface7_GetPalette(&dest->IDirectDrawSurface7_iface, &pal); + IDirectDrawSurface7_GetPalette(&dst->IDirectDrawSurface7_iface, &pal); if (pal_src != NULL && pal != NULL) { @@ -5979,36 +5985,37 @@ if (SUCCEEDED(hr)) { - IDirectDrawSurface7_SetColorKey(&dest->IDirectDrawSurface7_iface, ckeyflag, &ddckey); + IDirectDrawSurface7_SetColorKey(&dst->IDirectDrawSurface7_iface, ckeyflag, &ddckey); } } src_level = src; - dest_level = dest; + dst_level = dst; point = *DestPoint; src_rect = *SrcRect; - for (;src_level && dest_level;) + for (;src_level && dst_level;) { - if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth && - src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight) + if (src_level->surface_desc.dwWidth == dst_level->surface_desc.dwWidth + && src_level->surface_desc.dwHeight == dst_level->surface_desc.dwHeight) { UINT src_w = src_rect.right - src_rect.left; UINT src_h = src_rect.bottom - src_rect.top; RECT dst_rect = {point.x, point.y, point.x + src_w, point.y + src_h}; - if (FAILED(hr = wined3d_surface_blt(dest_level->wined3d_surface, &dst_rect, - src_level->wined3d_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT))) + if (FAILED(hr = wined3d_texture_blt(dst_level->wined3d_texture, dst_level->sub_resource_idx, &dst_rect, + src_level->wined3d_texture, src_level->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT))) ERR("Blit failed, hr %#x.\n", hr); ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL; - IDirectDrawSurface7_GetAttachedSurface(&dest_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp); + IDirectDrawSurface7_GetAttachedSurface(&dst_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp); - if (dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface); + if (dst_level != dst) + IDirectDrawSurface7_Release(&dst_level->IDirectDrawSurface7_iface); - dest_level = unsafe_impl_from_IDirectDrawSurface7(temp); + dst_level = unsafe_impl_from_IDirectDrawSurface7(temp); } ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; @@ -6028,8 +6035,10 @@ src_rect.bottom = (src_rect.bottom + 1) / 2; } - if (src_level && src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface); - if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface); + if (src_level && src_level != src) + IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface); + if (dst_level && dst_level != dst) + IDirectDrawSurface7_Release(&dst_level->IDirectDrawSurface7_iface); } /***************************************************************************** diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/surface.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/surface.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/surface.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/surface.c 2016-02-08 19:32:34.000000000 +0000 @@ -46,22 +46,19 @@ int x, y, w, h; HRESULT hr; BOOL ret; + RECT r; if (!rect) { - x = 0; - y = 0; - w = surface->surface_desc.dwWidth; - h = surface->surface_desc.dwHeight; - } - else - { - x = rect->left; - y = rect->top; - w = rect->right - rect->left; - h = rect->bottom - rect->top; + SetRect(&r, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight); + rect = &r; } + x = rect->left; + y = rect->top; + w = rect->right - rect->left; + h = rect->bottom - rect->top; + if (w <= 0 || h <= 0) return DD_OK; @@ -72,11 +69,11 @@ if (read) return DD_OK; - return wined3d_surface_blt(surface->ddraw->wined3d_frontbuffer, rect, - surface->wined3d_surface, rect, 0, NULL, WINED3D_TEXF_POINT); + return wined3d_texture_blt(surface->ddraw->wined3d_frontbuffer, 0, rect, + surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT); } - if (FAILED(hr = wined3d_surface_getdc(surface->wined3d_surface, &surface_dc))) + if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, &surface_dc))) { ERR("Failed to get surface DC, hr %#x.\n", hr); return hr; @@ -86,7 +83,7 @@ if (!(screen_dc = GetDC(NULL))) { - wined3d_surface_releasedc(surface->wined3d_surface, surface_dc); + wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, surface_dc); ERR("Failed to get screen DC.\n"); return E_FAIL; } @@ -99,7 +96,7 @@ surface_dc, x, y, SRCCOPY); ReleaseDC(NULL, screen_dc); - wined3d_surface_releasedc(surface->wined3d_surface, surface_dc); + wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, surface_dc); if (!ret) { @@ -326,10 +323,7 @@ wined3d_mutex_lock(); if (surface->wined3d_rtv) wined3d_rendertarget_view_incref(surface->wined3d_rtv); - if (surface->wined3d_surface) - wined3d_surface_incref(surface->wined3d_surface); - if (surface->wined3d_texture) - wined3d_texture_incref(surface->wined3d_texture); + wined3d_texture_incref(surface->wined3d_texture); wined3d_mutex_unlock(); } } @@ -532,10 +526,7 @@ if (surface->wined3d_rtv) wined3d_rendertarget_view_decref(surface->wined3d_rtv); - if (surface->wined3d_texture) - wined3d_texture_decref(surface->wined3d_texture); - if (surface->wined3d_surface) - wined3d_surface_decref(surface->wined3d_surface); + wined3d_texture_decref(surface->wined3d_texture); } ULONG ddraw_surface_release_iface(struct ddraw_surface *This) @@ -950,17 +941,17 @@ * For more details, see IWineD3DSurface::LockRect * *****************************************************************************/ -static HRESULT surface_lock(struct ddraw_surface *This, - RECT *Rect, DDSURFACEDESC2 *DDSD, DWORD Flags, HANDLE h) +static HRESULT surface_lock(struct ddraw_surface *surface, + RECT *rect, DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h) { struct wined3d_box box; struct wined3d_map_desc map_desc; HRESULT hr = DD_OK; - TRACE("This %p, rect %s, surface_desc %p, flags %#x, h %p.\n", - This, wine_dbgstr_rect(Rect), DDSD, Flags, h); + TRACE("surface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", + surface, wine_dbgstr_rect(rect), surface_desc, flags, h); - /* This->surface_desc.dwWidth and dwHeight are changeable, thus lock */ + /* surface->surface_desc.dwWidth and dwHeight are changeable, thus lock */ wined3d_mutex_lock(); /* Should I check for the handle to be NULL? @@ -970,33 +961,31 @@ */ /* Windows zeroes this if the rect is invalid */ - DDSD->lpSurface = 0; + surface_desc->lpSurface = NULL; - if (Rect) + if (rect) { - if ((Rect->left < 0) - || (Rect->top < 0) - || (Rect->left > Rect->right) - || (Rect->top > Rect->bottom) - || (Rect->right > This->surface_desc.dwWidth) - || (Rect->bottom > This->surface_desc.dwHeight)) + if ((rect->left < 0) || (rect->top < 0) + || (rect->left > rect->right) || (rect->right > surface->surface_desc.dwWidth) + || (rect->top > rect->bottom) || (rect->bottom > surface->surface_desc.dwHeight)) { WARN("Trying to lock an invalid rectangle, returning DDERR_INVALIDPARAMS\n"); wined3d_mutex_unlock(); return DDERR_INVALIDPARAMS; } - box.left = Rect->left; - box.top = Rect->top; - box.right = Rect->right; - box.bottom = Rect->bottom; + box.left = rect->left; + box.top = rect->top; + box.right = rect->right; + box.bottom = rect->bottom; box.front = 0; box.back = 1; } - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(This, Rect, TRUE); + if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE); if (SUCCEEDED(hr)) - hr = wined3d_surface_map(This->wined3d_surface, &map_desc, Rect ? &box : NULL, Flags); + hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), + surface->sub_resource_idx, &map_desc, rect ? &box : NULL, flags); if (FAILED(hr)) { wined3d_mutex_unlock(); @@ -1013,22 +1002,23 @@ } } - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { - if (Flags & DDLOCK_READONLY) - memset(&This->ddraw->primary_lock, 0, sizeof(This->ddraw->primary_lock)); - else if (Rect) - This->ddraw->primary_lock = *Rect; + if (flags & DDLOCK_READONLY) + memset(&surface->ddraw->primary_lock, 0, sizeof(surface->ddraw->primary_lock)); + else if (rect) + surface->ddraw->primary_lock = *rect; else - SetRect(&This->ddraw->primary_lock, 0, 0, This->surface_desc.dwWidth, This->surface_desc.dwHeight); + SetRect(&surface->ddraw->primary_lock, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight); } /* Windows does not set DDSD_LPSURFACE on locked surfaces. */ - DD_STRUCT_COPY_BYSIZE(DDSD,&(This->surface_desc)); - DDSD->lpSurface = map_desc.data; + DD_STRUCT_COPY_BYSIZE(surface_desc, &surface->surface_desc); + surface_desc->lpSurface = map_desc.data; TRACE("locked surface returning description :\n"); - if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(DDSD); + if (TRACE_ON(ddraw)) + DDRAW_dump_surface_desc(surface_desc); wined3d_mutex_unlock(); @@ -1169,7 +1159,7 @@ TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(pRect)); wined3d_mutex_lock(); - hr = wined3d_surface_unmap(surface->wined3d_surface); + hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE); wined3d_mutex_unlock(); @@ -1248,6 +1238,8 @@ tmp_rtv = ddraw_surface_get_rendertarget_view(dst_impl); tmp = dst_impl->wined3d_surface; + if (dst_impl->sub_resource_idx) + ERR("Invalid sub-resource index %u on surface %p.\n", dst_impl->sub_resource_idx, dst_impl); texture = dst_impl->wined3d_texture; rtv = wined3d_device_get_rendertarget_view(dst_impl->ddraw->wined3d_device, 0); ddraw_texture = wined3d_texture_get_parent(dst_impl->wined3d_texture); @@ -1276,10 +1268,12 @@ wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE); wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); dst_impl->wined3d_rtv = src_rtv; - wined3d_resource_set_parent(wined3d_surface_get_resource(src_impl->wined3d_surface), dst_impl); + wined3d_resource_set_parent(wined3d_texture_get_sub_resource(src_impl->wined3d_texture, 0), dst_impl); dst_impl->wined3d_surface = src_impl->wined3d_surface; prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), ddraw_texture); + if (src_impl->sub_resource_idx) + ERR("Invalid sub-resource index %u on surface %p.\n", src_impl->sub_resource_idx, src_impl); dst_impl->wined3d_texture = src_impl->wined3d_texture; ddraw_texture = prev_ddraw_texture; } @@ -1306,11 +1300,13 @@ wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE); wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); dst_impl->wined3d_rtv = src_rtv; - wined3d_resource_set_parent(wined3d_surface_get_resource(src_impl->wined3d_surface), dst_impl); + wined3d_resource_set_parent(wined3d_texture_get_sub_resource(src_impl->wined3d_texture, 0), dst_impl); dst_impl->wined3d_surface = src_impl->wined3d_surface; prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), ddraw_texture); ddraw_texture = prev_ddraw_texture; + if (src_impl->sub_resource_idx) + ERR("Invalid sub-resource index %u on surface %p.\n", src_impl->sub_resource_idx, src_impl); dst_impl->wined3d_texture = src_impl->wined3d_texture; dst_impl = src_impl; } @@ -1322,7 +1318,7 @@ wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, tmp_rtv, FALSE); wined3d_rendertarget_view_set_parent(tmp_rtv, src_impl); src_impl->wined3d_rtv = tmp_rtv; - wined3d_resource_set_parent(wined3d_surface_get_resource(tmp), src_impl); + wined3d_resource_set_parent(wined3d_texture_get_sub_resource(texture, 0), src_impl); src_impl->wined3d_surface = tmp; wined3d_resource_set_parent(wined3d_texture_get_resource(texture), ddraw_texture); src_impl->wined3d_texture = texture; @@ -1398,7 +1394,8 @@ struct ddraw_surface *src_surface, const RECT *src_rect_in, DWORD flags, const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) { - struct wined3d_surface *wined3d_src_surface = src_surface ? src_surface->wined3d_surface : NULL; + struct wined3d_texture *wined3d_src_texture; + unsigned int src_sub_resource_idx; RECT src_rect, dst_rect; float scale_x, scale_y; const RECT *clip_rect; @@ -1407,19 +1404,6 @@ HRESULT hr = DD_OK; UINT i; - if (!dst_surface->clipper) - { - if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(src_surface, src_rect_in, TRUE); - if (SUCCEEDED(hr)) - hr = wined3d_surface_blt(dst_surface->wined3d_surface, dst_rect_in, - wined3d_src_surface, src_rect_in, flags, fx, filter); - if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) - hr = ddraw_surface_update_frontbuffer(dst_surface, dst_rect_in, FALSE); - - return hr; - } - if (!dst_rect_in) { dst_rect.left = 0; @@ -1451,10 +1435,28 @@ if (IsRectEmpty(&src_rect)) return DDERR_INVALIDRECT; + + wined3d_src_texture = src_surface->wined3d_texture; + src_sub_resource_idx = src_surface->sub_resource_idx; } else { SetRect(&src_rect, 0, 0, 0, 0); + wined3d_src_texture = NULL; + src_sub_resource_idx = 0; + } + + if (!dst_surface->clipper) + { + if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE); + if (SUCCEEDED(hr)) + hr = wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, &dst_rect, + wined3d_src_texture, src_sub_resource_idx, &src_rect, flags, fx, filter); + if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) + hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE); + + return hr; } scale_x = (float)(src_rect.right - src_rect.left) / (float)(dst_rect.right - dst_rect.left); @@ -1500,8 +1502,8 @@ } } - if (FAILED(hr = wined3d_surface_blt(dst_surface->wined3d_surface, &clip_rect[i], - wined3d_src_surface, &src_rect_clipped, flags, fx, filter))) + if (FAILED(hr = wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, + &clip_rect[i], wined3d_src_texture, src_sub_resource_idx, &src_rect_clipped, flags, fx, filter))) break; if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) @@ -1653,7 +1655,6 @@ switch(hr) { case WINED3DERR_NOTAVAILABLE: return DDERR_UNSUPPORTED; - case WINED3DERR_WRONGTEXTUREFORMAT: return DDERR_INVALIDPIXELFORMAT; default: return hr; } } @@ -2121,7 +2122,7 @@ if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE); if (SUCCEEDED(hr)) - hr = wined3d_surface_getdc(surface->wined3d_surface, hdc); + hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, hdc); if (SUCCEEDED(hr) && format_is_paletteindexed(&surface->surface_desc.u4.ddpfPixelFormat)) { @@ -2209,7 +2210,7 @@ TRACE("iface %p, dc %p.\n", iface, hdc); wined3d_mutex_lock(); - hr = wined3d_surface_releasedc(surface->wined3d_surface, hdc); + hr = wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, hdc); if (SUCCEEDED(hr) && (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE); wined3d_mutex_unlock(); @@ -2377,12 +2378,9 @@ WARN("Called on offscreenplain surface, returning DDERR_INVALIDOBJECT.\n"); hr = DDERR_INVALIDOBJECT; } - else if (!(surface->surface_desc.ddsCaps.dwCaps2 & managed) - || (surface->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL) - || ((surface->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) - && !(surface->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEX))) + else if (!(surface->surface_desc.ddsCaps.dwCaps2 & managed) || !surface->is_complex_root) { - WARN("Called on non-managed texture, mipmap sublevel or non +X toplevel surface, returning DDERR_INVALIDPARAMS.\n"); + WARN("Called on non-managed texture or non-root surface, returning DDERR_INVALIDPARAMS.\n"); hr = DDERR_INVALIDPARAMS; } else @@ -4034,13 +4032,6 @@ return DDERR_INVALIDOBJECT; } - if (!surface->wined3d_texture) - { - ERR("The ddraw surface has no wined3d texture.\n"); - wined3d_mutex_unlock(); - return DDERR_INVALIDOBJECT; - } - hr = wined3d_texture_set_lod(surface->wined3d_texture, MaxLOD); wined3d_mutex_unlock(); @@ -4100,44 +4091,38 @@ * For more details, see IWineD3DSurface::BltFast * *****************************************************************************/ -static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurface7 *iface, DWORD dstx, DWORD dsty, - IDirectDrawSurface7 *Source, RECT *rsrc, DWORD trans) +static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurface7 *iface, + DWORD dst_x, DWORD dst_y, IDirectDrawSurface7 *src_surface, RECT *src_rect, DWORD trans) { - struct ddraw_surface *This = impl_from_IDirectDrawSurface7(iface); - struct ddraw_surface *src = unsafe_impl_from_IDirectDrawSurface7(Source); + struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface); + struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface7(src_surface); DWORD src_w, src_h, dst_w, dst_h; HRESULT hr = DD_OK; + RECT dst_rect, s; DWORD flags = 0; - RECT dst_rect; TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n", - iface, dstx, dsty, Source, wine_dbgstr_rect(rsrc), trans); + iface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), trans); - dst_w = This->surface_desc.dwWidth; - dst_h = This->surface_desc.dwHeight; + dst_w = dst_impl->surface_desc.dwWidth; + dst_h = dst_impl->surface_desc.dwHeight; - /* Source must be != NULL, This is not checked by windows. Windows happily throws a 0xc0000005 - * in that case - */ - if(rsrc) - { - src_w = rsrc->right - rsrc->left; - src_h = rsrc->bottom - rsrc->top; - } - else + if (!src_rect) { - src_w = src->surface_desc.dwWidth; - src_h = src->surface_desc.dwHeight; + SetRect(&s, 0, 0, src_impl->surface_desc.dwWidth, src_impl->surface_desc.dwHeight); + src_rect = &s; } - if (src_w > dst_w || dstx > dst_w - src_w - || src_h > dst_h || dsty > dst_h - src_h) + src_w = src_rect->right - src_rect->left; + src_h = src_rect->bottom - src_rect->top; + if (src_w > dst_w || dst_x > dst_w - src_w + || src_h > dst_h || dst_y > dst_h - src_h) { WARN("Destination area out of bounds, returning DDERR_INVALIDRECT.\n"); return DDERR_INVALIDRECT; } - SetRect(&dst_rect, dstx, dsty, dstx + src_w, dsty + src_h); + SetRect(&dst_rect, dst_x, dst_y, dst_x + src_w, dst_y + src_h); if (trans & DDBLTFAST_SRCCOLORKEY) flags |= WINEDDBLT_KEYSRC; if (trans & DDBLTFAST_DESTCOLORKEY) @@ -4148,26 +4133,25 @@ flags |= WINEDDBLT_DONOTWAIT; wined3d_mutex_lock(); - if (This->clipper) + if (dst_impl->clipper) { wined3d_mutex_unlock(); WARN("Destination surface has a clipper set, returning DDERR_BLTFASTCANTCLIP.\n"); return DDERR_BLTFASTCANTCLIP; } - if (src->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - hr = ddraw_surface_update_frontbuffer(src, rsrc, TRUE); + if (src_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE); if (SUCCEEDED(hr)) - hr = wined3d_surface_blt(This->wined3d_surface, &dst_rect, - src->wined3d_surface, rsrc, flags, NULL, WINED3D_TEXF_POINT); - if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) - hr = ddraw_surface_update_frontbuffer(This, &dst_rect, FALSE); + hr = wined3d_texture_blt(dst_impl->wined3d_texture, dst_impl->sub_resource_idx, &dst_rect, + src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect, flags, NULL, WINED3D_TEXF_POINT); + if (SUCCEEDED(hr) && (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) + hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE); wined3d_mutex_unlock(); switch(hr) { case WINED3DERR_NOTAVAILABLE: return DDERR_UNSUPPORTED; - case WINED3DERR_WRONGTEXTUREFORMAT: return DDERR_INVALIDPIXELFORMAT; default: return hr; } } @@ -4711,7 +4695,7 @@ } } - if (surface->wined3d_texture) + if (surface->is_complex_root) hr = wined3d_texture_set_color_key(surface->wined3d_texture, flags, color_key ? (struct wined3d_color_key *)&fixed_color_key : NULL); @@ -4726,13 +4710,8 @@ TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); - wined3d_mutex_lock(); - if (!surface->wined3d_texture) - { - wined3d_mutex_unlock(); + if (surface->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL) return DDERR_NOTONMIPMAPSUBLEVEL; - } - wined3d_mutex_unlock(); return ddraw_surface_set_color_key(surface, flags, color_key); } @@ -5082,6 +5061,7 @@ { struct ddraw_surface *dst_surface = impl_from_IDirect3DTexture2(iface); struct ddraw_surface *src_surface = unsafe_impl_from_IDirect3DTexture2(src_texture); + struct wined3d_resource *dst_resource, *src_resource; HRESULT hr; TRACE("iface %p, src_texture %p.\n", iface, src_texture); @@ -5094,6 +5074,9 @@ wined3d_mutex_lock(); + dst_resource = wined3d_texture_get_resource(dst_surface->wined3d_texture); + src_resource = wined3d_texture_get_resource(src_surface->wined3d_texture); + if (((src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) || (src_surface->surface_desc.u2.dwMipMapCount != dst_surface->surface_desc.u2.dwMipMapCount)) @@ -5151,22 +5134,19 @@ DDCKEY_SRCBLT, &src_desc->ddckCKSrcBlt); } - /* Copy the main memory texture into the surface that corresponds - * to the OpenGL texture object. */ - - hr = wined3d_surface_map(src_surface->wined3d_surface, &src_map_desc, NULL, 0); - if (FAILED(hr)) + if (FAILED(hr = wined3d_resource_map(src_resource, + src_surface->sub_resource_idx, &src_map_desc, NULL, 0))) { ERR("Failed to lock source surface, hr %#x.\n", hr); wined3d_mutex_unlock(); return D3DERR_TEXTURE_LOAD_FAILED; } - hr = wined3d_surface_map(dst_surface->wined3d_surface, &dst_map_desc, NULL, 0); - if (FAILED(hr)) + if (FAILED(hr = wined3d_resource_map(dst_resource, + dst_surface->sub_resource_idx, &dst_map_desc, NULL, 0))) { ERR("Failed to lock destination surface, hr %#x.\n", hr); - wined3d_surface_unmap(src_surface->wined3d_surface); + wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx); wined3d_mutex_unlock(); return D3DERR_TEXTURE_LOAD_FAILED; } @@ -5176,8 +5156,8 @@ else memcpy(dst_map_desc.data, src_map_desc.data, src_map_desc.row_pitch * src_desc->dwHeight); - wined3d_surface_unmap(src_surface->wined3d_surface); - wined3d_surface_unmap(dst_surface->wined3d_surface); + wined3d_resource_unmap(dst_resource, dst_surface->sub_resource_idx); + wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx); } if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) @@ -5663,15 +5643,16 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc, struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) { + struct wined3d_resource_desc wined3d_desc, wined3d_mip_desc; struct ddraw_surface *root, *mip, **attach; - struct wined3d_resource_desc wined3d_desc; struct wined3d_texture *wined3d_texture; struct wined3d_resource *resource; struct wined3d_display_mode mode; DDSURFACEDESC2 *desc, *mip_desc; struct ddraw_texture *texture; - UINT layers, levels, i, j; + unsigned int layers = 1; unsigned int pitch = 0; + UINT levels, i, j; HRESULT hr; TRACE("ddraw %p, surface_desc %p, surface %p, outer_unknown %p, version %u.\n", @@ -5743,6 +5724,14 @@ return DDERR_INVALIDCAPS; } + if ((desc->ddsCaps.dwCaps & (DDSCAPS_ALLOCONLOAD | DDSCAPS_MIPMAP)) + && !(desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)) + { + WARN("Caps %#x require DDSCAPS_TEXTURE.\n", desc->ddsCaps.dwCaps); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDCAPS; + } + if ((desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES) && !(desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)) { @@ -5795,6 +5784,7 @@ ddrawformat_from_wined3dformat(&desc->u4.ddpfPixelFormat, mode.format_id); } + wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; wined3d_desc.format = wined3dformat_from_ddrawformat(&desc->u4.ddpfPixelFormat); if (wined3d_desc.format == WINED3DFMT_UNKNOWN) { @@ -5883,7 +5873,10 @@ { /* Undocumented feature: Create sublevels until either the * width or the height is 1. */ - desc->u2.dwMipMapCount = wined3d_log2i(min(desc->dwWidth, desc->dwHeight)) + 1; + if (version == 7) + desc->u2.dwMipMapCount = wined3d_log2i(max(desc->dwWidth, desc->dwHeight)) + 1; + else + desc->u2.dwMipMapCount = wined3d_log2i(min(desc->dwWidth, desc->dwHeight)) + 1; } } else @@ -5907,9 +5900,12 @@ DWORD usage = 0; if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) - rtype = WINED3D_RTYPE_CUBE_TEXTURE; + { + usage |= WINED3DUSAGE_LEGACY_CUBEMAP; + rtype = WINED3D_RTYPE_TEXTURE_2D; + } else if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) - rtype = WINED3D_RTYPE_TEXTURE; + rtype = WINED3D_RTYPE_TEXTURE_2D; else rtype = WINED3D_RTYPE_SURFACE; @@ -5968,10 +5964,6 @@ } } - /* If the surface is of the 'ALLOCONLOAD' type, ignore the LPSURFACE - * field. Frank Herbert's Dune specifies a NULL pointer for lpSurface. */ - if ((desc->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) || !desc->lpSurface) - desc->dwFlags &= ~DDSD_LPSURFACE; if (desc->dwFlags & DDSD_LPSURFACE) { if (wined3d_desc.pool != WINED3D_POOL_SYSTEM_MEM) @@ -5988,6 +5980,13 @@ return DDERR_INVALIDPARAMS; } + if (!desc->lpSurface) + { + WARN("NULL surface memory pointer specified.\n"); + HeapFree(GetProcessHeap(), 0, texture); + return DDERR_INVALIDPARAMS; + } + if (format_is_compressed(&desc->u4.ddpfPixelFormat)) { if (version != 4 && (desc->dwFlags & DDSD_PITCH)) @@ -6056,23 +6055,18 @@ if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) { - wined3d_desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE; + wined3d_desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP; layers = 6; } - else - { - wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE; - layers = 1; - } /* Some applications assume surfaces will always be mapped at the same * address. Some of those also assume that this address is valid even when * the surface isn't mapped, and that updates done this way will be * visible on the screen. The game Nox is such an application, * Commandos: Behind Enemy Lines is another. We set - * WINED3D_SURFACE_PIN_SYSMEM because of this. */ + * WINED3D_TEXTURE_CREATE_PIN_SYSMEM because of this. */ if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, levels, - WINED3D_SURFACE_PIN_SYSMEM, NULL, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) + WINED3D_TEXTURE_CREATE_PIN_SYSMEM, NULL, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, texture); @@ -6081,7 +6075,7 @@ resource = wined3d_texture_get_sub_resource(wined3d_texture, 0); root = wined3d_resource_get_parent(resource); - root->wined3d_texture = wined3d_texture; + wined3d_texture_decref(wined3d_texture); root->is_complex_root = TRUE; texture->root = root; @@ -6109,9 +6103,17 @@ mip_desc = &mip->surface_desc; if (j) + { + wined3d_resource_get_desc(resource, &wined3d_mip_desc); + mip_desc->dwWidth = wined3d_mip_desc.width; + mip_desc->dwHeight = wined3d_mip_desc.height; + mip_desc->ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL; + } else + { mip_desc->ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL; + } if (mip_desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) { @@ -6184,7 +6186,8 @@ desc->u5.dwBackBufferCount = 0; if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, &wined3d_desc, 1, - WINED3D_SURFACE_PIN_SYSMEM, NULL, texture, &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) + WINED3D_TEXTURE_CREATE_PIN_SYSMEM, NULL, texture, + &ddraw_texture_wined3d_parent_ops, &wined3d_texture))) { HeapFree(GetProcessHeap(), 0, texture); hr = hr_ddraw_from_wined3d(hr); @@ -6193,7 +6196,7 @@ resource = wined3d_texture_get_sub_resource(wined3d_texture, 0); last = wined3d_resource_get_parent(resource); - last->wined3d_texture = wined3d_texture; + wined3d_texture_decref(wined3d_texture); texture->root = last; if (desc->dwFlags & DDSD_CKDESTOVERLAY) @@ -6232,11 +6235,12 @@ return hr; } -void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture, +void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) { + struct ddraw_texture *texture = wined3d_texture_get_parent(wined3d_texture); DDSURFACEDESC2 *desc = &surface->surface_desc; - struct wined3d_resource_desc wined3d_desc; unsigned int version = texture->version; surface->IDirectDrawSurface7_iface.lpVtbl = &ddraw_surface7_vtbl; @@ -6268,9 +6272,6 @@ } *desc = texture->surface_desc; - wined3d_resource_get_desc(wined3d_surface_get_resource(wined3d_surface), &wined3d_desc); - desc->dwWidth = wined3d_desc.width; - desc->dwHeight = wined3d_desc.height; surface->first_attached = surface; if (format_is_compressed(&desc->u4.ddpfPixelFormat)) @@ -6291,8 +6292,9 @@ } desc->lpSurface = NULL; - wined3d_surface_incref(wined3d_surface); surface->wined3d_surface = wined3d_surface; + wined3d_texture_incref(surface->wined3d_texture = wined3d_texture); + surface->sub_resource_idx = sub_resource_idx; *parent_ops = &ddraw_surface_wined3d_parent_ops; wined3d_private_store_init(&surface->private_store); @@ -6326,8 +6328,8 @@ if (surface->wined3d_rtv) return surface->wined3d_rtv; - if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(surface->wined3d_surface, - surface, &ddraw_view_wined3d_parent_ops, &surface->wined3d_rtv))) + if (FAILED(hr = wined3d_rendertarget_view_create_from_sub_resource(surface->wined3d_texture, + surface->sub_resource_idx, surface, &ddraw_view_wined3d_parent_ops, &surface->wined3d_rtv))) { ERR("Failed to create rendertarget view, hr %#x.\n", hr); return NULL; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/tests/ddraw1.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/tests/ddraw1.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/tests/ddraw1.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/tests/ddraw1.c 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,5 @@ /* + * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com) * Copyright 2011-2014 Henri Verbeet for CodeWeavers * Copyright 2012-2013 Stefan Dösinger for CodeWeavers * @@ -21,6 +22,7 @@ #include "wine/test.h" #include "d3d.h" +static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *); static DEVMODEW registry_mode; struct create_window_thread_param @@ -4885,7 +4887,7 @@ static const struct { - DWORD placement; + DWORD caps; DWORD flags_in; DWORD pitch_in; HRESULT hr; @@ -4895,26 +4897,58 @@ } test_data[] = { - {DDSCAPS_VIDEOMEMORY, 0, 0, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_PITCH, 0x104, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_PITCH, 0x0f8, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, 0, 0, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH, 0x104, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH, 0x0f8, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH | DDSD_LINEARSIZE, 0, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE, 0, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDPARAMS, - 0, 0, 0 }, + /* 0 */ + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x104, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x0f8, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + /* 5 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x104, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x0f8, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH | DDSD_LINEARSIZE, 0, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE, 0, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + /* 10 */ + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_ALLOCONLOAD, + 0, 0, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0 }, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_ALLOCONLOAD, + 0, 0, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0 }, + /* 15 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDPARAMS, + 0, 0, 0 }, }; DWORD flags_mask = DDSD_PITCH | DDSD_LPSURFACE | DDSD_LINEARSIZE; @@ -4932,11 +4966,10 @@ memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | test_data[i].flags_in; - surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | test_data[i].placement; + surface_desc.ddsCaps.dwCaps = test_data[i].caps; surface_desc.dwWidth = 63; surface_desc.dwHeight = 63; U1(surface_desc).lPitch = test_data[i].pitch_in; - surface_desc.lpSurface = mem; surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat); surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB; U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32; @@ -4944,8 +4977,16 @@ U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x0000ff00; U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x000000ff; hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); - ok(hr == test_data[i].hr || (test_data[i].placement == DDSCAPS_VIDEOMEMORY && hr == DDERR_NODIRECTDRAWHW), - "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr); + if (test_data[i].flags_in & DDSD_LPSURFACE) + { + HRESULT expected_hr = SUCCEEDED(test_data[i].hr) ? DDERR_INVALIDPARAMS : test_data[i].hr; + ok(hr == expected_hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, expected_hr); + surface_desc.lpSurface = mem; + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); + } + if ((test_data[i].caps & DDSCAPS_VIDEOMEMORY) && hr == DDERR_NODIRECTDRAWHW) + continue; + ok(hr == test_data[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr); if (FAILED(hr)) continue; @@ -4956,14 +4997,17 @@ ok((surface_desc.dwFlags & flags_mask) == test_data[i].flags_out, "Test %u: Got unexpected flags %#x, expected %#x.\n", i, surface_desc.dwFlags & flags_mask, test_data[i].flags_out); - if (sizeof(void *) != sizeof(DWORD) && test_data[i].pitch_out32 != test_data[i].pitch_out64) - todo_wine ok(U1(surface_desc).lPitch == test_data[i].pitch_out64, - "Test %u: Got unexpected pitch %u, expected %u.\n", - i, U1(surface_desc).lPitch, test_data[i].pitch_out64); - else - ok(U1(surface_desc).lPitch == test_data[i].pitch_out32, - "Test %u: Got unexpected pitch %u, expected %u.\n", - i, U1(surface_desc).lPitch, test_data[i].pitch_out32); + if (!(test_data[i].caps & DDSCAPS_TEXTURE)) + { + if (is_ddraw64 && test_data[i].pitch_out32 != test_data[i].pitch_out64) + todo_wine ok(U1(surface_desc).lPitch == test_data[i].pitch_out64, + "Test %u: Got unexpected pitch %u, expected %u.\n", + i, U1(surface_desc).lPitch, test_data[i].pitch_out64); + else + ok(U1(surface_desc).lPitch == test_data[i].pitch_out32, + "Test %u: Got unexpected pitch %u, expected %u.\n", + i, U1(surface_desc).lPitch, test_data[i].pitch_out32); + } ok(!surface_desc.lpSurface, "Test %u: Got unexpected lpSurface %p.\n", i, surface_desc.lpSurface); IDirectDrawSurface_Release(surface); @@ -4975,17 +5019,38 @@ DestroyWindow(window); } -static void test_mipmap_lock(void) +static void test_mipmap(void) { IDirectDrawSurface *surface, *surface2; DDSURFACEDESC surface_desc; IDirectDraw *ddraw; + unsigned int i; ULONG refcount; HWND window; HRESULT hr; DDSCAPS caps = {DDSCAPS_COMPLEX}; DDCAPS hal_caps; + static const struct + { + DWORD flags; + DWORD caps; + DWORD width; + DWORD height; + DWORD mipmap_count_in; + HRESULT hr; + DWORD mipmap_count_out; + } + tests[] = + { + {DDSD_MIPMAPCOUNT, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 3, DD_OK, 3}, + {DDSD_MIPMAPCOUNT, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 0, DDERR_INVALIDPARAMS, 0}, + {0, DDSCAPS_TEXTURE | DDSCAPS_MIPMAP, 128, 32, 0, DD_OK, 1}, + {0, DDSCAPS_MIPMAP, 128, 32, 0, DDERR_INVALIDCAPS, 0}, + {0, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 0, DD_OK, 6}, + {0, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 32, 64, 0, DD_OK, 6}, + }; + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); ddraw = create_ddraw(); @@ -4999,38 +5064,58 @@ ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr); if ((hal_caps.ddsCaps.dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP)) != (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP)) { - skip("Mipmapped textures not supported, skipping mipmap lock test.\n"); + skip("Mipmapped textures not supported, skipping tests.\n"); IDirectDraw_Release(ddraw); DestroyWindow(window); return; } - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT; - surface_desc.dwWidth = 4; - surface_desc.dwHeight = 4; - U2(surface_desc).dwMipMapCount = 2; - surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP - | DDSCAPS_SYSTEMMEMORY; - hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); - ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); - hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &surface2); - ok(SUCCEEDED(hr), "Failed to get attached surface, hr %#x.\n", hr); + for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | tests[i].flags; + surface_desc.ddsCaps.dwCaps = tests[i].caps; + surface_desc.dwWidth = tests[i].width; + surface_desc.dwHeight = tests[i].height; + if (tests[i].flags & DDSD_MIPMAPCOUNT) + U2(surface_desc).dwMipMapCount = tests[i].mipmap_count_in; + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == tests[i].hr, "Test %u: Got unexpected hr %#x.\n", i, hr); + if (FAILED(hr)) + continue; - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, 0, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - hr = IDirectDrawSurface_Lock(surface2, NULL, &surface_desc, 0, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - IDirectDrawSurface_Unlock(surface2, NULL); - IDirectDrawSurface_Unlock(surface, NULL); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface_GetSurfaceDesc(surface, &surface_desc); + ok(SUCCEEDED(hr), "Test %u: Failed to get surface desc, hr %#x.\n", i, hr); + ok(surface_desc.dwFlags & DDSD_MIPMAPCOUNT, + "Test %u: Got unexpected flags %#x.\n", i, surface_desc.dwFlags); + ok(U2(surface_desc).dwMipMapCount == tests[i].mipmap_count_out, + "Test %u: Got unexpected mipmap count %u.\n", i, U2(surface_desc).dwMipMapCount); + + if (U2(surface_desc).dwMipMapCount > 1) + { + hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &surface2); + ok(SUCCEEDED(hr), "Test %u: Failed to get attached surface, hr %#x.\n", i, hr); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, 0, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to lock surface, hr %#x.\n", i, hr); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface_Lock(surface2, NULL, &surface_desc, 0, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to lock surface, hr %#x.\n", i, hr); + IDirectDrawSurface_Unlock(surface2, NULL); + IDirectDrawSurface_Unlock(surface, NULL); + + IDirectDrawSurface_Release(surface2); + } + + IDirectDrawSurface_Release(surface); + } - IDirectDrawSurface_Release(surface2); - IDirectDrawSurface_Release(surface); refcount = IDirectDraw_Release(ddraw); ok(!refcount, "Got unexpected refcount %u.\n", refcount); DestroyWindow(window); @@ -7951,9 +8036,9 @@ * functionality being available. */ /* PHONG should be the same as GOURAUD, since no hardware implements * this. */ - ok(color0 == tests[i].color0, "Test %u shading has color0 %08x, expected %08x.\n", + ok(compare_color(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n", i, color0, tests[i].color0); - ok(color1 == tests[i].color1, "Test %u shading has color1 %08x, expected %08x.\n", + ok(compare_color(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n", i, color1, tests[i].color1); } @@ -7968,6 +8053,153 @@ DestroyWindow(window); } +static void test_lockrect_invalid(void) +{ + unsigned int i, r; + IDirectDraw *ddraw; + IDirectDrawSurface *surface; + HWND window; + HRESULT hr; + DDSURFACEDESC surface_desc; + DDCAPS hal_caps; + DWORD needed_caps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY; + static RECT valid[] = + { + {60, 60, 68, 68}, + {60, 60, 60, 68}, + {60, 60, 68, 60}, + {120, 60, 128, 68}, + {60, 120, 68, 128}, + }; + static RECT invalid[] = + { + {68, 60, 60, 68}, /* left > right */ + {60, 68, 68, 60}, /* top > bottom */ + {-8, 60, 0, 68}, /* left < surface */ + {60, -8, 68, 0}, /* top < surface */ + {-16, 60, -8, 68}, /* right < surface */ + {60, -16, 68, -8}, /* bottom < surface */ + {60, 60, 136, 68}, /* right > surface */ + {60, 60, 68, 136}, /* bottom > surface */ + {136, 60, 144, 68}, /* left > surface */ + {60, 136, 68, 144}, /* top > surface */ + }; + static const struct + { + DWORD caps; + const char *name; + HRESULT hr; + } + resources[] = + { + {DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY, "sysmem offscreenplain", DDERR_INVALIDPARAMS}, + {DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY, "vidmem offscreenplain", DDERR_INVALIDPARAMS}, + {DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY, "sysmem texture", DDERR_INVALIDPARAMS}, + {DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, "vidmem texture", DDERR_INVALIDPARAMS}, + }; + + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); + + memset(&hal_caps, 0, sizeof(hal_caps)); + hal_caps.dwSize = sizeof(hal_caps); + hr = IDirectDraw_GetCaps(ddraw, &hal_caps, NULL); + ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr); + if ((hal_caps.ddsCaps.dwCaps & needed_caps) != needed_caps) + { + skip("Required surface types not supported, skipping test.\n"); + goto done; + } + + for (r = 0; r < sizeof(resources) / sizeof(*resources); ++r) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = resources[r].caps; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat); + surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32; + U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xff0000; + U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00ff00; + U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000ff; + + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, type %s.\n", hr, resources[r].name); + + hr = IDirectDrawSurface_Lock(surface, NULL, NULL, DDLOCK_WAIT, NULL); + ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + + for (i = 0; i < sizeof(valid) / sizeof(*valid); ++i) + { + RECT *rect = &valid[i]; + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + + hr = IDirectDrawSurface_Lock(surface, rect, &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock failed (%#x) for rect [%d, %d]->[%d, %d], type %s.\n", + hr, rect->left, rect->top, rect->right, rect->bottom, resources[r].name); + + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + } + + for (i = 0; i < sizeof(invalid) / sizeof(*invalid); ++i) + { + RECT *rect = &invalid[i]; + + memset(&surface_desc, 1, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + + hr = IDirectDrawSurface_Lock(surface, rect, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == resources[r].hr, "Lock returned %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, rect->left, rect->top, rect->right, rect->bottom, resources[r].name); + if (SUCCEEDED(hr)) + { + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + } + else + ok(!surface_desc.lpSurface, "Got unexpected lpSurface %p.\n", surface_desc.lpSurface); + } + + hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock(rect = NULL) failed, hr %#x, type %s.\n", + hr, resources[r].name); + hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned %#x, type %s.\n", + hr, resources[r].name); + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + + hr = IDirectDrawSurface_Lock(surface, &valid[0], &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock(rect = [%d, %d]->[%d, %d]) failed (%#x).\n", + valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); + hr = IDirectDrawSurface_Lock(surface, &valid[0], &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (%#x).\n", + valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); + + /* Locking a different rectangle returns DD_OK, but it seems to break the surface. + * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */ + + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + + IDirectDrawSurface_Release(surface); + } + +done: + IDirectDraw_Release(ddraw); + DestroyWindow(window); +} + START_TEST(ddraw1) { IDirectDraw *ddraw; @@ -8025,7 +8257,7 @@ test_surface_attachment(); test_pixel_format(); test_create_surface_pitch(); - test_mipmap_lock(); + test_mipmap(); test_palette_complex(); test_p8_rgb_blit(); test_material(); @@ -8040,4 +8272,5 @@ test_colorkey_precision(); test_range_colorkey(); test_shademode(); + test_lockrect_invalid(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/tests/ddraw2.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/tests/ddraw2.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/tests/ddraw2.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/tests/ddraw2.c 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,5 @@ /* + * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com) * Copyright 2011-2014 Henri Verbeet for CodeWeavers * Copyright 2012-2014 Stefan Dösinger for CodeWeavers * @@ -23,6 +24,7 @@ #include "wine/test.h" #include "d3d.h" +static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *); static DEVMODEW registry_mode; struct create_window_thread_param @@ -5927,7 +5929,7 @@ static const struct { - DWORD placement; + DWORD caps; DWORD flags_in; DWORD pitch_in; HRESULT hr; @@ -5937,26 +5939,58 @@ } test_data[] = { - {DDSCAPS_VIDEOMEMORY, 0, 0, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_PITCH, 0x104, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_PITCH, 0x0f8, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, 0, 0, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH, 0x104, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH, 0x0f8, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH | DDSD_LINEARSIZE, 0, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE, 0, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDPARAMS, - 0, 0, 0 }, + /* 0 */ + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x104, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x0f8, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + /* 5 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x104, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x0f8, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH | DDSD_LINEARSIZE, 0, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE, 0, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + /* 10 */ + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_ALLOCONLOAD, + 0, 0, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0 }, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_ALLOCONLOAD, + 0, 0, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0 }, + /* 15 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDPARAMS, + 0, 0, 0 }, }; DWORD flags_mask = DDSD_PITCH | DDSD_LPSURFACE | DDSD_LINEARSIZE; @@ -5974,11 +6008,10 @@ memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | test_data[i].flags_in; - surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | test_data[i].placement; + surface_desc.ddsCaps.dwCaps = test_data[i].caps; surface_desc.dwWidth = 63; surface_desc.dwHeight = 63; U1(surface_desc).lPitch = test_data[i].pitch_in; - surface_desc.lpSurface = mem; surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat); surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB; U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32; @@ -5986,8 +6019,16 @@ U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x0000ff00; U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x000000ff; hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL); - ok(hr == test_data[i].hr || (test_data[i].placement == DDSCAPS_VIDEOMEMORY && hr == DDERR_NODIRECTDRAWHW), - "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr); + if (test_data[i].flags_in & DDSD_LPSURFACE) + { + HRESULT expected_hr = SUCCEEDED(test_data[i].hr) ? DDERR_INVALIDPARAMS : test_data[i].hr; + ok(hr == expected_hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, expected_hr); + surface_desc.lpSurface = mem; + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL); + } + if ((test_data[i].caps & DDSCAPS_VIDEOMEMORY) && hr == DDERR_NODIRECTDRAWHW) + continue; + ok(hr == test_data[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr); if (FAILED(hr)) continue; @@ -5998,14 +6039,18 @@ ok((surface_desc.dwFlags & flags_mask) == test_data[i].flags_out, "Test %u: Got unexpected flags %#x, expected %#x.\n", i, surface_desc.dwFlags & flags_mask, test_data[i].flags_out); - if (sizeof(void *) != sizeof(DWORD) && test_data[i].pitch_out32 != test_data[i].pitch_out64) - todo_wine ok(U1(surface_desc).lPitch == test_data[i].pitch_out64, - "Test %u: Got unexpected pitch %u, expected %u.\n", - i, U1(surface_desc).lPitch, test_data[i].pitch_out64); - else - ok(U1(surface_desc).lPitch == test_data[i].pitch_out32, - "Test %u: Got unexpected pitch %u, expected %u.\n", - i, U1(surface_desc).lPitch, test_data[i].pitch_out32); + /* The pitch for textures seems to be implementation specific. */ + if (!(test_data[i].caps & DDSCAPS_TEXTURE)) + { + if (is_ddraw64 && test_data[i].pitch_out32 != test_data[i].pitch_out64) + todo_wine ok(U1(surface_desc).lPitch == test_data[i].pitch_out64, + "Test %u: Got unexpected pitch %u, expected %u.\n", + i, U1(surface_desc).lPitch, test_data[i].pitch_out64); + else + ok(U1(surface_desc).lPitch == test_data[i].pitch_out32, + "Test %u: Got unexpected pitch %u, expected %u.\n", + i, U1(surface_desc).lPitch, test_data[i].pitch_out32); + } ok(!surface_desc.lpSurface, "Test %u: Got unexpected lpSurface %p.\n", i, surface_desc.lpSurface); IDirectDrawSurface_Release(surface); @@ -6017,18 +6062,39 @@ DestroyWindow(window); } -static void test_mipmap_lock(void) +static void test_mipmap(void) { IDirectDrawSurface *surface1; IDirectDrawSurface2 *surface, *surface2; DDSURFACEDESC surface_desc; IDirectDraw2 *ddraw; + unsigned int i; ULONG refcount; HWND window; HRESULT hr; DDSCAPS caps = {DDSCAPS_COMPLEX}; DDCAPS hal_caps; + static const struct + { + DWORD flags; + DWORD caps; + DWORD width; + DWORD height; + DWORD mipmap_count_in; + HRESULT hr; + DWORD mipmap_count_out; + } + tests[] = + { + {DDSD_MIPMAPCOUNT, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 3, DD_OK, 3}, + {DDSD_MIPMAPCOUNT, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 0, DDERR_INVALIDPARAMS, 0}, + {0, DDSCAPS_TEXTURE | DDSCAPS_MIPMAP, 128, 32, 0, DD_OK, 1}, + {0, DDSCAPS_MIPMAP, 128, 32, 0, DDERR_INVALIDCAPS, 0}, + {0, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 0, DD_OK, 6}, + {0, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 32, 64, 0, DD_OK, 6}, + }; + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); ddraw = create_ddraw(); @@ -6042,42 +6108,62 @@ ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr); if ((hal_caps.ddsCaps.dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP)) != (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP)) { - skip("Mipmapped textures not supported, skipping mipmap lock test.\n"); + skip("Mipmapped textures not supported, skipping tests.\n"); IDirectDraw2_Release(ddraw); DestroyWindow(window); return; } - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT; - surface_desc.dwWidth = 4; - surface_desc.dwHeight = 4; - U2(surface_desc).dwMipMapCount = 2; - surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP - | DDSCAPS_SYSTEMMEMORY; - hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface1, NULL); - ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); + for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | tests[i].flags; + surface_desc.ddsCaps.dwCaps = tests[i].caps; + surface_desc.dwWidth = tests[i].width; + surface_desc.dwHeight = tests[i].height; + if (tests[i].flags & DDSD_MIPMAPCOUNT) + U2(surface_desc).dwMipMapCount = tests[i].mipmap_count_in; + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface1, NULL); + ok(hr == tests[i].hr, "Test %u: Got unexpected hr %#x.\n", i, hr); + if (FAILED(hr)) + continue; - hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface2, (void **)&surface); - ok(SUCCEEDED(hr), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr); - IDirectDrawSurface_Release(surface1); - hr = IDirectDrawSurface2_GetAttachedSurface(surface, &caps, &surface2); - ok(SUCCEEDED(hr), "Failed to get attached surface, hr %#x.\n", hr); + hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface2, (void **)&surface); + ok(SUCCEEDED(hr), "Test %u: Failed to get IDirectDrawSurface2 interface, hr %#x.\n", i, hr); + IDirectDrawSurface_Release(surface1); - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - hr = IDirectDrawSurface2_Lock(surface, NULL, &surface_desc, 0, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - hr = IDirectDrawSurface2_Lock(surface2, NULL, &surface_desc, 0, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - IDirectDrawSurface2_Unlock(surface2, NULL); - IDirectDrawSurface2_Unlock(surface, NULL); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface2_GetSurfaceDesc(surface, &surface_desc); + ok(SUCCEEDED(hr), "Test %u: Failed to get surface desc, hr %#x.\n", i, hr); + ok(surface_desc.dwFlags & DDSD_MIPMAPCOUNT, + "Test %u: Got unexpected flags %#x.\n", i, surface_desc.dwFlags); + ok(U2(surface_desc).dwMipMapCount == tests[i].mipmap_count_out, + "Test %u: Got unexpected mipmap count %u.\n", i, U2(surface_desc).dwMipMapCount); + + if (U2(surface_desc).dwMipMapCount > 1) + { + hr = IDirectDrawSurface2_GetAttachedSurface(surface, &caps, &surface2); + ok(SUCCEEDED(hr), "Test %u: Failed to get attached surface, hr %#x.\n", i, hr); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface2_Lock(surface, NULL, &surface_desc, 0, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to lock surface, hr %#x.\n", i, hr); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface2_Lock(surface2, NULL, &surface_desc, 0, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to lock surface, hr %#x.\n", i, hr); + IDirectDrawSurface2_Unlock(surface2, NULL); + IDirectDrawSurface2_Unlock(surface, NULL); + + IDirectDrawSurface2_Release(surface2); + } + + IDirectDrawSurface2_Release(surface); + } - IDirectDrawSurface2_Release(surface2); - IDirectDrawSurface2_Release(surface); refcount = IDirectDraw2_Release(ddraw); ok(!refcount, "Got unexpected refcount %u.\n", refcount); DestroyWindow(window); @@ -9054,9 +9140,9 @@ * functionality being available. */ /* PHONG should be the same as GOURAUD, since no hardware implements * this. */ - ok(color0 == tests[i].color0, "Test %u shading has color0 %08x, expected %08x.\n", + ok(compare_color(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n", i, color0, tests[i].color0); - ok(color1 == tests[i].color1, "Test %u shading has color1 %08x, expected %08x.\n", + ok(compare_color(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n", i, color1, tests[i].color1); } @@ -9070,6 +9156,157 @@ DestroyWindow(window); } +static void test_lockrect_invalid(void) +{ + unsigned int i, r; + IDirectDraw2 *ddraw; + IDirectDrawSurface *surface1; + IDirectDrawSurface2 *surface; + HWND window; + HRESULT hr; + DDSURFACEDESC surface_desc; + DDCAPS hal_caps; + DWORD needed_caps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY; + static RECT valid[] = + { + {60, 60, 68, 68}, + {60, 60, 60, 68}, + {60, 60, 68, 60}, + {120, 60, 128, 68}, + {60, 120, 68, 128}, + }; + static RECT invalid[] = + { + {68, 60, 60, 68}, /* left > right */ + {60, 68, 68, 60}, /* top > bottom */ + {-8, 60, 0, 68}, /* left < surface */ + {60, -8, 68, 0}, /* top < surface */ + {-16, 60, -8, 68}, /* right < surface */ + {60, -16, 68, -8}, /* bottom < surface */ + {60, 60, 136, 68}, /* right > surface */ + {60, 60, 68, 136}, /* bottom > surface */ + {136, 60, 144, 68}, /* left > surface */ + {60, 136, 68, 144}, /* top > surface */ + }; + static const struct + { + DWORD caps; + const char *name; + HRESULT hr; + } + resources[] = + { + {DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY, "sysmem offscreenplain", DDERR_INVALIDPARAMS}, + {DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY, "vidmem offscreenplain", DDERR_INVALIDPARAMS}, + {DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY, "sysmem texture", DDERR_INVALIDPARAMS}, + {DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, "vidmem texture", DDERR_INVALIDPARAMS}, + }; + + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); + + memset(&hal_caps, 0, sizeof(hal_caps)); + hal_caps.dwSize = sizeof(hal_caps); + hr = IDirectDraw2_GetCaps(ddraw, &hal_caps, NULL); + ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr); + if ((hal_caps.ddsCaps.dwCaps & needed_caps) != needed_caps) + { + skip("Required surface types not supported, skipping test.\n"); + goto done; + } + + for (r = 0; r < sizeof(resources) / sizeof(*resources); ++r) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = resources[r].caps; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat); + surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32; + U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xff0000; + U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00ff00; + U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000ff; + + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface1, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, type %s.\n", hr, resources[r].name); + hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface2, (void **)&surface); + ok(SUCCEEDED(hr), "Failed to QI IDirectDrawSurface2 interface, hr %#x.\n", hr); + IDirectDrawSurface_Release(surface1); + + hr = IDirectDrawSurface2_Lock(surface, NULL, NULL, DDLOCK_WAIT, NULL); + ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + + for (i = 0; i < sizeof(valid) / sizeof(*valid); ++i) + { + RECT *rect = &valid[i]; + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + + hr = IDirectDrawSurface2_Lock(surface, rect, &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock failed (%#x) for rect [%d, %d]->[%d, %d], type %s.\n", + hr, rect->left, rect->top, rect->right, rect->bottom, resources[r].name); + + hr = IDirectDrawSurface2_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + } + + for (i = 0; i < sizeof(invalid) / sizeof(*invalid); ++i) + { + RECT *rect = &invalid[i]; + + memset(&surface_desc, 1, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + + hr = IDirectDrawSurface2_Lock(surface, rect, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == resources[r].hr, "Lock returned %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, rect->left, rect->top, rect->right, rect->bottom, resources[r].name); + if (SUCCEEDED(hr)) + { + hr = IDirectDrawSurface2_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + } + else + ok(!surface_desc.lpSurface, "Got unexpected lpSurface %p.\n", surface_desc.lpSurface); + } + + hr = IDirectDrawSurface2_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock(rect = NULL) failed, hr %#x, type %s.\n", + hr, resources[r].name); + hr = IDirectDrawSurface2_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned %#x, type %s.\n", + hr, resources[r].name); + hr = IDirectDrawSurface2_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + + hr = IDirectDrawSurface2_Lock(surface, &valid[0], &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock(rect = [%d, %d]->[%d, %d]) failed (%#x).\n", + valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); + hr = IDirectDrawSurface2_Lock(surface, &valid[0], &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (%#x).\n", + valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); + + /* Locking a different rectangle returns DD_OK, but it seems to break the surface. + * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */ + + hr = IDirectDrawSurface2_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + + IDirectDrawSurface2_Release(surface); + } + +done: + IDirectDraw2_Release(ddraw); + DestroyWindow(window); +} + START_TEST(ddraw2) { IDirectDraw2 *ddraw; @@ -9133,7 +9370,7 @@ test_surface_attachment(); test_pixel_format(); test_create_surface_pitch(); - test_mipmap_lock(); + test_mipmap(); test_palette_complex(); test_p8_rgb_blit(); test_material(); @@ -9149,4 +9386,5 @@ test_colorkey_precision(); test_range_colorkey(); test_shademode(); + test_lockrect_invalid(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/tests/ddraw4.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/tests/ddraw4.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/tests/ddraw4.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/tests/ddraw4.c 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,5 @@ /* + * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com) * Copyright 2011-2014 Henri Verbeet for CodeWeavers * Copyright 2012-2014 Stefan Dösinger for CodeWeavers * @@ -23,6 +24,7 @@ #include #include "d3d.h" +static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *); static DEVMODEW registry_mode; struct vec2 @@ -7448,7 +7450,7 @@ static const struct { - DWORD placement; + DWORD caps; DWORD flags_in; DWORD pitch_in; HRESULT hr; @@ -7458,38 +7460,77 @@ } test_data[] = { - {DDSCAPS_VIDEOMEMORY, 0, 0, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_PITCH, 0x104, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_PITCH, 0x0f8, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, 0, 0, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH, 0x104, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH, 0x0f8, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH | DDSD_LINEARSIZE, 0, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE, 0, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x100, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x0fe, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x0fc, DD_OK, - DDSD_PITCH, 0x0fc, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x0f8, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_LINEARSIZE, 0x100, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_LINEARSIZE, 0x3f00, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH | DDSD_LINEARSIZE, 0x100, DD_OK, - DDSD_PITCH, 0x100, 0x100}, + /* 0 */ + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x104, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x0f8, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + /* 5 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x104, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x0f8, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH | DDSD_LINEARSIZE, 0, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE, 0, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + /* 10 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x0fe, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x0fc, DD_OK, + DDSD_PITCH, 0x0fc, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x0f8, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_LINEARSIZE, 0x100, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_LINEARSIZE, 0x3f00, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + /* 15 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH | DDSD_LINEARSIZE, 0x100, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_ALLOCONLOAD, + 0, 0, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0 }, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_ALLOCONLOAD, + 0, 0, DDERR_INVALIDCAPS, + 0, 0, 0 }, + /* 20 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DD_OK, + DDSD_PITCH, 0x100, 0 }, }; DWORD flags_mask = DDSD_PITCH | DDSD_LPSURFACE | DDSD_LINEARSIZE; @@ -7507,11 +7548,10 @@ memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | test_data[i].flags_in; - surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | test_data[i].placement; + surface_desc.ddsCaps.dwCaps = test_data[i].caps; surface_desc.dwWidth = 63; surface_desc.dwHeight = 63; U1(surface_desc).lPitch = test_data[i].pitch_in; - surface_desc.lpSurface = mem; U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat); U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB; U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32; @@ -7519,8 +7559,16 @@ U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00; U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff; hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); - ok(hr == test_data[i].hr || (test_data[i].placement == DDSCAPS_VIDEOMEMORY && hr == DDERR_NODIRECTDRAWHW), - "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr); + if (test_data[i].flags_in & DDSD_LPSURFACE) + { + HRESULT expected_hr = SUCCEEDED(test_data[i].hr) ? DDERR_INVALIDPARAMS : test_data[i].hr; + ok(hr == expected_hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, expected_hr); + surface_desc.lpSurface = mem; + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); + } + if ((test_data[i].caps & DDSCAPS_VIDEOMEMORY) && hr == DDERR_NODIRECTDRAWHW) + continue; + ok(hr == test_data[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr); if (FAILED(hr)) continue; @@ -7531,14 +7579,18 @@ ok((surface_desc.dwFlags & flags_mask) == test_data[i].flags_out, "Test %u: Got unexpected flags %#x, expected %#x.\n", i, surface_desc.dwFlags & flags_mask, test_data[i].flags_out); - if (sizeof(void *) != sizeof(DWORD) && test_data[i].pitch_out32 != test_data[i].pitch_out64) - todo_wine ok(U1(surface_desc).lPitch == test_data[i].pitch_out64, - "Test %u: Got unexpected pitch %u, expected %u.\n", - i, U1(surface_desc).lPitch, test_data[i].pitch_out64); - else - ok(U1(surface_desc).lPitch == test_data[i].pitch_out32, - "Test %u: Got unexpected pitch %u, expected %u.\n", - i, U1(surface_desc).lPitch, test_data[i].pitch_out32); + /* The pitch for textures seems to be implementation specific. */ + if (!(test_data[i].caps & DDSCAPS_TEXTURE)) + { + if (is_ddraw64 && test_data[i].pitch_out32 != test_data[i].pitch_out64) + todo_wine ok(U1(surface_desc).lPitch == test_data[i].pitch_out64, + "Test %u: Got unexpected pitch %u, expected %u.\n", + i, U1(surface_desc).lPitch, test_data[i].pitch_out64); + else + ok(U1(surface_desc).lPitch == test_data[i].pitch_out32, + "Test %u: Got unexpected pitch %u, expected %u.\n", + i, U1(surface_desc).lPitch, test_data[i].pitch_out32); + } ok(!surface_desc.lpSurface, "Test %u: Got unexpected lpSurface %p.\n", i, surface_desc.lpSurface); IDirectDrawSurface4_Release(surface); @@ -7550,17 +7602,38 @@ DestroyWindow(window); } -static void test_mipmap_lock(void) +static void test_mipmap(void) { IDirectDrawSurface4 *surface, *surface2; DDSURFACEDESC2 surface_desc; IDirectDraw4 *ddraw; + unsigned int i; ULONG refcount; HWND window; HRESULT hr; DDSCAPS2 caps = {DDSCAPS_COMPLEX, 0, 0, {0}}; DDCAPS hal_caps; + static const struct + { + DWORD flags; + DWORD caps; + DWORD width; + DWORD height; + DWORD mipmap_count_in; + HRESULT hr; + DWORD mipmap_count_out; + } + tests[] = + { + {DDSD_MIPMAPCOUNT, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 3, DD_OK, 3}, + {DDSD_MIPMAPCOUNT, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 0, DDERR_INVALIDPARAMS, 0}, + {0, DDSCAPS_TEXTURE | DDSCAPS_MIPMAP, 128, 32, 0, DD_OK, 1}, + {0, DDSCAPS_MIPMAP, 128, 32, 0, DDERR_INVALIDCAPS, 0}, + {0, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 0, DD_OK, 6}, + {0, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 32, 64, 0, DD_OK, 6}, + }; + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); ddraw = create_ddraw(); @@ -7574,38 +7647,58 @@ ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr); if ((hal_caps.ddsCaps.dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP)) != (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP)) { - skip("Mipmapped textures not supported, skipping mipmap lock test.\n"); + skip("Mipmapped textures not supported, skipping tests.\n"); IDirectDraw4_Release(ddraw); DestroyWindow(window); return; } - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT; - surface_desc.dwWidth = 4; - surface_desc.dwHeight = 4; - U2(surface_desc).dwMipMapCount = 2; - surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP - | DDSCAPS_SYSTEMMEMORY; - hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); - ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); - hr = IDirectDrawSurface4_GetAttachedSurface(surface, &caps, &surface2); - ok(SUCCEEDED(hr), "Failed to get attached surface, hr %#x.\n", hr); + for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | tests[i].flags; + surface_desc.ddsCaps.dwCaps = tests[i].caps; + surface_desc.dwWidth = tests[i].width; + surface_desc.dwHeight = tests[i].height; + if (tests[i].flags & DDSD_MIPMAPCOUNT) + U2(surface_desc).dwMipMapCount = tests[i].mipmap_count_in; + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == tests[i].hr, "Test %u: Got unexpected hr %#x.\n", i, hr); + if (FAILED(hr)) + continue; - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - hr = IDirectDrawSurface4_Lock(surface, NULL, &surface_desc, 0, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - hr = IDirectDrawSurface4_Lock(surface2, NULL, &surface_desc, 0, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - IDirectDrawSurface4_Unlock(surface2, NULL); - IDirectDrawSurface4_Unlock(surface, NULL); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface4_GetSurfaceDesc(surface, &surface_desc); + ok(SUCCEEDED(hr), "Test %u: Failed to get surface desc, hr %#x.\n", i, hr); + ok(surface_desc.dwFlags & DDSD_MIPMAPCOUNT, + "Test %u: Got unexpected flags %#x.\n", i, surface_desc.dwFlags); + ok(U2(surface_desc).dwMipMapCount == tests[i].mipmap_count_out, + "Test %u: Got unexpected mipmap count %u.\n", i, U2(surface_desc).dwMipMapCount); + + if (U2(surface_desc).dwMipMapCount > 1) + { + hr = IDirectDrawSurface4_GetAttachedSurface(surface, &caps, &surface2); + ok(SUCCEEDED(hr), "Test %u: Failed to get attached surface, hr %#x.\n", i, hr); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface4_Lock(surface, NULL, &surface_desc, 0, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to lock surface, hr %#x.\n", i, hr); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface4_Lock(surface2, NULL, &surface_desc, 0, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to lock surface, hr %#x.\n", i, hr); + IDirectDrawSurface4_Unlock(surface2, NULL); + IDirectDrawSurface4_Unlock(surface, NULL); + + IDirectDrawSurface4_Release(surface2); + } + + IDirectDrawSurface4_Release(surface); + } - IDirectDrawSurface4_Release(surface2); - IDirectDrawSurface4_Release(surface); refcount = IDirectDraw4_Release(ddraw); ok(!refcount, "Got unexpected refcount %u.\n", refcount); DestroyWindow(window); @@ -10223,9 +10316,9 @@ * functionality being available. */ /* PHONG should be the same as GOURAUD, since no hardware implements * this. */ - ok(color0 == tests[i].color0, "Test %u shading has color0 %08x, expected %08x.\n", + ok(compare_color(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n", i, color0, tests[i].color0); - ok(color1 == tests[i].color1, "Test %u shading has color1 %08x, expected %08x.\n", + ok(compare_color(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n", i, color1, tests[i].color1); } @@ -10239,6 +10332,156 @@ DestroyWindow(window); } +static void test_lockrect_invalid(void) +{ + unsigned int i, r; + IDirectDraw4 *ddraw; + IDirectDrawSurface4 *surface; + HWND window; + HRESULT hr; + DDSURFACEDESC2 surface_desc; + DDCAPS hal_caps; + DWORD needed_caps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY; + static RECT valid[] = + { + {60, 60, 68, 68}, + {60, 60, 60, 68}, + {60, 60, 68, 60}, + {120, 60, 128, 68}, + {60, 120, 68, 128}, + }; + static RECT invalid[] = + { + {68, 60, 60, 68}, /* left > right */ + {60, 68, 68, 60}, /* top > bottom */ + {-8, 60, 0, 68}, /* left < surface */ + {60, -8, 68, 0}, /* top < surface */ + {-16, 60, -8, 68}, /* right < surface */ + {60, -16, 68, -8}, /* bottom < surface */ + {60, 60, 136, 68}, /* right > surface */ + {60, 60, 68, 136}, /* bottom > surface */ + {136, 60, 144, 68}, /* left > surface */ + {60, 136, 68, 144}, /* top > surface */ + }; + static const struct + { + DWORD caps, caps2; + const char *name; + HRESULT hr; + } + resources[] = + { + {DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY, 0, "sysmem offscreenplain", DDERR_INVALIDPARAMS}, + {DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY, 0, "vidmem offscreenplain", DDERR_INVALIDPARAMS}, + {DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY, 0, "sysmem texture", DDERR_INVALIDPARAMS}, + {DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, 0, "vidmem texture", DDERR_INVALIDPARAMS}, + {DDSCAPS_TEXTURE, DDSCAPS2_TEXTUREMANAGE, "managed texture", DDERR_INVALIDPARAMS}, + }; + + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); + + memset(&hal_caps, 0, sizeof(hal_caps)); + hal_caps.dwSize = sizeof(hal_caps); + hr = IDirectDraw4_GetCaps(ddraw, &hal_caps, NULL); + ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr); + if ((hal_caps.ddsCaps.dwCaps & needed_caps) != needed_caps + || !(hal_caps.ddsCaps.dwCaps & DDSCAPS2_TEXTUREMANAGE)) + { + skip("Required surface types not supported, skipping test.\n"); + goto done; + } + + for (r = 0; r < sizeof(resources) / sizeof(*resources); ++r) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = resources[r].caps; + surface_desc.ddsCaps.dwCaps2 = resources[r].caps2; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat); + U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32; + U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0xff0000; + U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x00ff00; + U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x0000ff; + + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, type %s.\n", hr, resources[r].name); + + hr = IDirectDrawSurface4_Lock(surface, NULL, NULL, DDLOCK_WAIT, NULL); + ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + + for (i = 0; i < sizeof(valid) / sizeof(*valid); ++i) + { + RECT *rect = &valid[i]; + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + + hr = IDirectDrawSurface4_Lock(surface, rect, &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock failed (%#x) for rect [%d, %d]->[%d, %d], type %s.\n", + hr, rect->left, rect->top, rect->right, rect->bottom, resources[r].name); + + hr = IDirectDrawSurface4_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + } + + for (i = 0; i < sizeof(invalid) / sizeof(*invalid); ++i) + { + RECT *rect = &invalid[i]; + + memset(&surface_desc, 1, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + + hr = IDirectDrawSurface4_Lock(surface, rect, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == resources[r].hr, "Lock returned %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, rect->left, rect->top, rect->right, rect->bottom, resources[r].name); + if (SUCCEEDED(hr)) + { + hr = IDirectDrawSurface4_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + } + else + ok(!surface_desc.lpSurface, "Got unexpected lpSurface %p.\n", surface_desc.lpSurface); + } + + hr = IDirectDrawSurface4_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock(rect = NULL) failed, hr %#x, type %s.\n", + hr, resources[r].name); + hr = IDirectDrawSurface4_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned %#x, type %s.\n", + hr, resources[r].name); + hr = IDirectDrawSurface4_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + + hr = IDirectDrawSurface4_Lock(surface, &valid[0], &surface_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock(rect = [%d, %d]->[%d, %d]) failed (%#x).\n", + valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); + hr = IDirectDrawSurface4_Lock(surface, &valid[0], &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (%#x).\n", + valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); + + /* Locking a different rectangle returns DD_OK, but it seems to break the surface. + * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */ + + hr = IDirectDrawSurface4_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + + IDirectDrawSurface4_Release(surface); + } + +done: + IDirectDraw4_Release(ddraw); + DestroyWindow(window); +} + START_TEST(ddraw4) { IDirectDraw4 *ddraw; @@ -10310,7 +10553,7 @@ test_private_data(); test_pixel_format(); test_create_surface_pitch(); - test_mipmap_lock(); + test_mipmap(); test_palette_complex(); test_p8_rgb_blit(); test_material(); @@ -10325,4 +10568,5 @@ test_colorkey_precision(); test_range_colorkey(); test_shademode(); + test_lockrect_invalid(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/tests/ddraw7.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/tests/ddraw7.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/tests/ddraw7.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/tests/ddraw7.c 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,5 @@ /* + * Copyright 2005 Antoine Chavasse (a.chavasse@gmail.com) * Copyright 2006, 2012-2014 Stefan Dösinger for CodeWeavers * Copyright 2011-2014 Henri Verbeet for CodeWeavers * @@ -1764,15 +1765,15 @@ color_key.dwColorSpaceLowValue = 0x000000ff; color_key.dwColorSpaceHighValue = 0x000000ff; hr = IDirectDrawSurface7_SetColorKey(mipmap, DDCKEY_SRCBLT, &color_key); - todo_wine ok(SUCCEEDED(hr), "Failed to set color key, hr %#x.\n", hr); + ok(SUCCEEDED(hr), "Failed to set color key, hr %#x.\n", hr); color_key.dwColorSpaceLowValue = 0; color_key.dwColorSpaceHighValue = 0; hr = IDirectDrawSurface7_GetColorKey(mipmap, DDCKEY_SRCBLT, &color_key); - todo_wine ok(SUCCEEDED(hr), "Failed to get color key, hr %#x.\n", hr); - todo_wine ok(color_key.dwColorSpaceLowValue == 0x000000ff, "Got unexpected value 0x%08x.\n", + ok(SUCCEEDED(hr), "Failed to get color key, hr %#x.\n", hr); + ok(color_key.dwColorSpaceLowValue == 0x000000ff, "Got unexpected value 0x%08x.\n", color_key.dwColorSpaceLowValue); - todo_wine ok(color_key.dwColorSpaceHighValue == 0x000000ff, "Got unexpected value 0x%08x.\n", + ok(color_key.dwColorSpaceHighValue == 0x000000ff, "Got unexpected value 0x%08x.\n", color_key.dwColorSpaceHighValue); IDirectDrawSurface_AddRef(mipmap); @@ -7297,7 +7298,7 @@ static const struct { - DWORD placement; + DWORD caps; DWORD flags_in; DWORD pitch_in; HRESULT hr; @@ -7307,38 +7308,77 @@ } test_data[] = { - {DDSCAPS_VIDEOMEMORY, 0, 0, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_PITCH, 0x104, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_PITCH, 0x0f8, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_VIDEOMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, 0, 0, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH, 0x104, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH, 0x0f8, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_PITCH | DDSD_LINEARSIZE, 0, DD_OK, - DDSD_PITCH, 0x100, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE, 0, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x100, DD_OK, - DDSD_PITCH, 0x100, 0x100}, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x0fe, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x0fc, DD_OK, - DDSD_PITCH, 0x0fc, 0x0fc}, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH, 0x0f8, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_LINEARSIZE, 0x100, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_LINEARSIZE, 0x3f00, DDERR_INVALIDPARAMS, - 0, 0, 0 }, - {DDSCAPS_SYSTEMMEMORY, DDSD_LPSURFACE | DDSD_PITCH | DDSD_LINEARSIZE, 0x100, DD_OK, - DDSD_PITCH, 0x100, 0x100}, + /* 0 */ + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x104, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x0f8, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + /* 5 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x104, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH, 0x0f8, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_PITCH | DDSD_LINEARSIZE, 0, DD_OK, + DDSD_PITCH, 0x100, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE, 0, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + /* 10 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x0fe, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x0fc, DD_OK, + DDSD_PITCH, 0x0fc, 0x0fc}, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH, 0x0f8, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_LINEARSIZE, 0x100, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_LINEARSIZE, 0x3f00, DDERR_INVALIDPARAMS, + 0, 0, 0 }, + /* 15 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN, + DDSD_LPSURFACE | DDSD_PITCH | DDSD_LINEARSIZE, 0x100, DD_OK, + DDSD_PITCH, 0x100, 0x100}, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_ALLOCONLOAD, + 0, 0, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0 }, + {DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DDERR_INVALIDCAPS, + 0, 0, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_ALLOCONLOAD, + 0, 0, DDERR_INVALIDCAPS, + 0, 0, 0 }, + /* 20 */ + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + 0, 0, DD_OK, + DDSD_PITCH, 0x100, 0 }, + {DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD, + DDSD_LPSURFACE | DDSD_PITCH, 0x100, DD_OK, + DDSD_PITCH, 0x100, 0 }, }; DWORD flags_mask = DDSD_PITCH | DDSD_LPSURFACE | DDSD_LINEARSIZE; @@ -7356,11 +7396,10 @@ memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | test_data[i].flags_in; - surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | test_data[i].placement; + surface_desc.ddsCaps.dwCaps = test_data[i].caps; surface_desc.dwWidth = 63; surface_desc.dwHeight = 63; U1(surface_desc).lPitch = test_data[i].pitch_in; - surface_desc.lpSurface = mem; U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat); U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB; U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32; @@ -7368,8 +7407,19 @@ U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00; U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff; hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); - ok(hr == test_data[i].hr || (test_data[i].placement == DDSCAPS_VIDEOMEMORY && hr == DDERR_NODIRECTDRAWHW), - "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr); + if (test_data[i].flags_in & DDSD_LPSURFACE) + { + HRESULT expected_hr = SUCCEEDED(test_data[i].hr) ? DDERR_INVALIDPARAMS : test_data[i].hr; + ok(hr == expected_hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, expected_hr); + surface_desc.lpSurface = mem; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); + } + if ((test_data[i].caps & DDSCAPS_VIDEOMEMORY) && hr == DDERR_NODIRECTDRAWHW) + continue; + if (is_ddraw64 && (test_data[i].caps & DDSCAPS_TEXTURE) && SUCCEEDED(test_data[i].hr)) + todo_wine ok(hr == E_NOINTERFACE, "Test %u: Got unexpected hr %#x.\n", i, hr); + else + ok(hr == test_data[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n", i, hr, test_data[i].hr); if (FAILED(hr)) continue; @@ -7380,14 +7430,18 @@ ok((surface_desc.dwFlags & flags_mask) == test_data[i].flags_out, "Test %u: Got unexpected flags %#x, expected %#x.\n", i, surface_desc.dwFlags & flags_mask, test_data[i].flags_out); - if (sizeof(void *) != sizeof(DWORD) && test_data[i].pitch_out32 != test_data[i].pitch_out64) - todo_wine ok(U1(surface_desc).lPitch == test_data[i].pitch_out64, - "Test %u: Got unexpected pitch %u, expected %u.\n", - i, U1(surface_desc).lPitch, test_data[i].pitch_out64); - else - ok(U1(surface_desc).lPitch == test_data[i].pitch_out32, - "Test %u: Got unexpected pitch %u, expected %u.\n", - i, U1(surface_desc).lPitch, test_data[i].pitch_out32); + /* The pitch for textures seems to be implementation specific. */ + if (!(test_data[i].caps & DDSCAPS_TEXTURE)) + { + if (is_ddraw64 && test_data[i].pitch_out32 != test_data[i].pitch_out64) + todo_wine ok(U1(surface_desc).lPitch == test_data[i].pitch_out64, + "Test %u: Got unexpected pitch %u, expected %u.\n", + i, U1(surface_desc).lPitch, test_data[i].pitch_out64); + else + ok(U1(surface_desc).lPitch == test_data[i].pitch_out32, + "Test %u: Got unexpected pitch %u, expected %u.\n", + i, U1(surface_desc).lPitch, test_data[i].pitch_out32); + } ok(!surface_desc.lpSurface, "Test %u: Got unexpected lpSurface %p.\n", i, surface_desc.lpSurface); IDirectDrawSurface7_Release(surface); @@ -7399,17 +7453,38 @@ DestroyWindow(window); } -static void test_mipmap_lock(void) +static void test_mipmap(void) { IDirectDrawSurface7 *surface, *surface2; DDSURFACEDESC2 surface_desc; IDirectDraw7 *ddraw; + unsigned int i; ULONG refcount; HWND window; HRESULT hr; DDSCAPS2 caps = {DDSCAPS_COMPLEX, 0, 0, {0}}; DDCAPS hal_caps; + static const struct + { + DWORD flags; + DWORD caps; + DWORD width; + DWORD height; + DWORD mipmap_count_in; + HRESULT hr; + DWORD mipmap_count_out; + } + tests[] = + { + {DDSD_MIPMAPCOUNT, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 3, DD_OK, 3}, + {DDSD_MIPMAPCOUNT, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 0, DDERR_INVALIDPARAMS, 0}, + {0, DDSCAPS_TEXTURE | DDSCAPS_MIPMAP, 128, 32, 0, DD_OK, 1}, + {0, DDSCAPS_MIPMAP, 128, 32, 0, DDERR_INVALIDCAPS, 0}, + {0, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 128, 32, 0, DD_OK, 8}, + {0, DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP, 32, 64, 0, DD_OK, 7}, + }; + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); ddraw = create_ddraw(); @@ -7424,38 +7499,58 @@ if ((hal_caps.ddsCaps.dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP)) != (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP) || is_ddraw64) { - skip("Mipmapped textures not supported, skipping mipmap lock test.\n"); + skip("Mipmapped textures not supported, skipping tests.\n"); IDirectDraw7_Release(ddraw); DestroyWindow(window); return; } - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT; - surface_desc.dwWidth = 4; - surface_desc.dwHeight = 4; - U2(surface_desc).dwMipMapCount = 2; - surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP - | DDSCAPS_SYSTEMMEMORY; - hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); - ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); - hr = IDirectDrawSurface7_GetAttachedSurface(surface, &caps, &surface2); - ok(SUCCEEDED(hr), "Failed to get attached surface, hr %#x.\n", hr); + for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | tests[i].flags; + surface_desc.ddsCaps.dwCaps = tests[i].caps; + surface_desc.dwWidth = tests[i].width; + surface_desc.dwHeight = tests[i].height; + if (tests[i].flags & DDSD_MIPMAPCOUNT) + U2(surface_desc).dwMipMapCount = tests[i].mipmap_count_in; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == tests[i].hr, "Test %u: Got unexpected hr %#x.\n", i, hr); + if (FAILED(hr)) + continue; - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, 0, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - memset(&surface_desc, 0, sizeof(surface_desc)); - surface_desc.dwSize = sizeof(surface_desc); - hr = IDirectDrawSurface7_Lock(surface2, NULL, &surface_desc, 0, NULL); - ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr); - IDirectDrawSurface7_Unlock(surface2, NULL); - IDirectDrawSurface7_Unlock(surface, NULL); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &surface_desc); + ok(SUCCEEDED(hr), "Test %u: Failed to get surface desc, hr %#x.\n", i, hr); + ok(surface_desc.dwFlags & DDSD_MIPMAPCOUNT, + "Test %u: Got unexpected flags %#x.\n", i, surface_desc.dwFlags); + ok(U2(surface_desc).dwMipMapCount == tests[i].mipmap_count_out, + "Test %u: Got unexpected mipmap count %u.\n", i, U2(surface_desc).dwMipMapCount); + + if (U2(surface_desc).dwMipMapCount > 1) + { + hr = IDirectDrawSurface7_GetAttachedSurface(surface, &caps, &surface2); + ok(SUCCEEDED(hr), "Test %u: Failed to get attached surface, hr %#x.\n", i, hr); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, 0, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to lock surface, hr %#x.\n", i, hr); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface7_Lock(surface2, NULL, &surface_desc, 0, NULL); + ok(SUCCEEDED(hr), "Test %u: Failed to lock surface, hr %#x.\n", i, hr); + IDirectDrawSurface7_Unlock(surface2, NULL); + IDirectDrawSurface7_Unlock(surface, NULL); + + IDirectDrawSurface7_Release(surface2); + } + + IDirectDrawSurface7_Release(surface); + } - IDirectDrawSurface7_Release(surface2); - IDirectDrawSurface7_Release(surface); refcount = IDirectDraw7_Release(ddraw); ok(!refcount, "Got unexpected refcount %u.\n", refcount); DestroyWindow(window); @@ -8436,10 +8531,7 @@ static void test_resource_priority(void) { IDirectDrawSurface7 *surface, *mipmap; - D3DDEVICEDESC7 device_desc; DDSURFACEDESC2 surface_desc; - IDirect3D7 *d3d; - IDirect3DDevice7 *device; IDirectDraw7 *ddraw; ULONG refcount; HWND window; @@ -8472,19 +8564,10 @@ window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); - if (!(device = create_device(window, DDSCL_NORMAL))) - { - skip("Failed to create a 3D device, skipping test.\n"); - DestroyWindow(window); - return; - } - hr = IDirect3DDevice7_GetCaps(device, &device_desc); - ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr); - hr = IDirect3DDevice7_GetDirect3D(device, &d3d); - ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr); - hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw); - ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr); - IDirect3D7_Release(d3d); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); memset(&hal_caps, 0, sizeof(hal_caps)); hal_caps.dwSize = sizeof(hal_caps); @@ -8505,12 +8588,6 @@ surface_desc.dwWidth = 32; surface_desc.dwHeight = 32; surface_desc.ddsCaps.dwCaps = test_data[i].caps; - if ((test_data[i].caps2 & DDSCAPS2_CUBEMAP) - && !(device_desc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP)) - { - skip("Device does not support cubemaps.\n"); - continue; - } surface_desc.ddsCaps.dwCaps2 = test_data[i].caps2; hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); if (is_ddraw64 && (test_data[i].caps & DDSCAPS_TEXTURE)) @@ -8550,10 +8627,10 @@ if (test_data[i].caps2 & DDSCAPS2_CUBEMAP) { caps.dwCaps2 = DDSCAPS2_CUBEMAP_NEGATIVEZ; - priority = 0xdeadbeef; hr = IDirectDrawSurface7_GetAttachedSurface(surface, &caps, &mipmap); ok(SUCCEEDED(hr), "Failed to get attached surface, i %u, hr %#x.\n", i, hr); /* IDirectDrawSurface7_SetPriority crashes when called on non-positive X surfaces on Windows */ + priority = 0xdeadbeef; hr = IDirectDrawSurface7_GetPriority(mipmap, &priority); ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x, type %s.\n", hr, test_data[i].name); ok(priority == 0xdeadbeef, "Got unexpected priority %u, type %s.\n", priority, test_data[i].name); @@ -8595,8 +8672,7 @@ ok(!refcount, "Got unexpected refcount %u.\n", refcount); done: - IDirectDraw7_Release(ddraw); - refcount = IDirect3DDevice7_Release(device); + refcount = IDirectDraw7_Release(ddraw); ok(!refcount, "Got unexpected refcount %u.\n", refcount); DestroyWindow(window); } @@ -10506,9 +10582,9 @@ * functionality being available. */ /* PHONG should be the same as GOURAUD, since no hardware implements * this. */ - ok(color0 == tests[i].color0, "Test %u shading has color0 %08x, expected %08x.\n", + ok(compare_color(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n", i, color0, tests[i].color0); - ok(color1 == tests[i].color1, "Test %u shading has color1 %08x, expected %08x.\n", + ok(compare_color(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n", i, color1, tests[i].color1); } @@ -10521,6 +10597,170 @@ DestroyWindow(window); } +static void test_lockrect_invalid(void) +{ + unsigned int i, r; + IDirectDraw7 *ddraw; + IDirectDrawSurface7 *surface; + HWND window; + HRESULT hr; + DDSURFACEDESC2 surface_desc; + DDSURFACEDESC2 locked_desc; + DDCAPS hal_caps; + DWORD needed_caps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY; + static RECT valid[] = + { + {60, 60, 68, 68}, + {60, 60, 60, 68}, + {60, 60, 68, 60}, + {120, 60, 128, 68}, + {60, 120, 68, 128}, + }; + static RECT invalid[] = + { + {68, 60, 60, 68}, /* left > right */ + {60, 68, 68, 60}, /* top > bottom */ + {-8, 60, 0, 68}, /* left < surface */ + {60, -8, 68, 0}, /* top < surface */ + {-16, 60, -8, 68}, /* right < surface */ + {60, -16, 68, -8}, /* bottom < surface */ + {60, 60, 136, 68}, /* right > surface */ + {60, 60, 68, 136}, /* bottom > surface */ + {136, 60, 144, 68}, /* left > surface */ + {60, 136, 68, 144}, /* top > surface */ + }; + static const struct + { + DWORD caps, caps2; + const char *name; + HRESULT hr; + } + resources[] = + { + {DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY, 0, "sysmem offscreenplain", DDERR_INVALIDPARAMS}, + {DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY, 0, "vidmem offscreenplain", DDERR_INVALIDPARAMS}, + {DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY, 0, "sysmem texture", DD_OK}, + {DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY, 0, "vidmem texture", DDERR_INVALIDPARAMS}, + {DDSCAPS_TEXTURE, DDSCAPS2_TEXTUREMANAGE, "managed texture", DD_OK}, + }; + + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); + + memset(&hal_caps, 0, sizeof(hal_caps)); + hal_caps.dwSize = sizeof(hal_caps); + hr = IDirectDraw7_GetCaps(ddraw, &hal_caps, NULL); + ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr); + if ((hal_caps.ddsCaps.dwCaps & needed_caps) != needed_caps + || !(hal_caps.ddsCaps.dwCaps & DDSCAPS2_TEXTUREMANAGE)) + { + skip("Required surface types not supported, skipping test.\n"); + goto done; + } + + for (r = 0; r < sizeof(resources) / sizeof(*resources); ++r) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = resources[r].caps; + surface_desc.ddsCaps.dwCaps2 = resources[r].caps2; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat); + U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32; + U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0xff0000; + U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x00ff00; + U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x0000ff; + + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); + if (is_ddraw64 && (resources[r].caps & DDSCAPS_TEXTURE)) + { + todo_wine ok(hr == E_NOINTERFACE, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + if (SUCCEEDED(hr)) + IDirectDrawSurface7_Release(surface); + continue; + } + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, type %s.\n", hr, resources[r].name); + + /* Crashes in ddraw7 + hr = IDirectDrawSurface7_Lock(surface, NULL, NULL, DDLOCK_WAIT, NULL); + ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x, type %s.\n", hr, resources[r].name); + */ + + for (i = 0; i < sizeof(valid) / sizeof(*valid); ++i) + { + RECT *rect = &valid[i]; + + memset(&locked_desc, 0, sizeof(locked_desc)); + locked_desc.dwSize = sizeof(locked_desc); + + hr = IDirectDrawSurface7_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock failed (%#x) for rect [%d, %d]->[%d, %d], type %s.\n", + hr, rect->left, rect->top, rect->right, rect->bottom, resources[r].name); + + hr = IDirectDrawSurface7_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + } + + for (i = 0; i < sizeof(invalid) / sizeof(*invalid); ++i) + { + RECT *rect = &invalid[i]; + + memset(&locked_desc, 1, sizeof(locked_desc)); + locked_desc.dwSize = sizeof(locked_desc); + + hr = IDirectDrawSurface7_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL); + if (SUCCEEDED(resources[r].hr)) + todo_wine ok(hr == resources[r].hr, "Lock returned %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, rect->left, rect->top, rect->right, rect->bottom, resources[r].name); + else + ok(hr == resources[r].hr, "Lock returned %#x for rect [%d, %d]->[%d, %d], type %s.\n", + hr, rect->left, rect->top, rect->right, rect->bottom, resources[r].name); + if (SUCCEEDED(hr)) + { + hr = IDirectDrawSurface7_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + } + else + ok(!locked_desc.lpSurface, "Got unexpected lpSurface %p.\n", locked_desc.lpSurface); + } + + hr = IDirectDrawSurface7_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock(rect = NULL) failed, hr %#x, type %s.\n", + hr, resources[r].name); + hr = IDirectDrawSurface7_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL); + ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned %#x, type %s.\n", + hr, resources[r].name); + hr = IDirectDrawSurface7_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + + hr = IDirectDrawSurface7_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL); + ok(SUCCEEDED(hr), "Lock(rect = [%d, %d]->[%d, %d]) failed (%#x).\n", + valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); + hr = IDirectDrawSurface7_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL); + ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (%#x).\n", + valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); + + /* Locking a different rectangle returns DD_OK, but it seems to break the surface. + * Afterwards unlocking the surface fails(NULL rectangle or both locked rectangles) */ + + hr = IDirectDrawSurface7_Unlock(surface, NULL); + ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, type %s.\n", hr, resources[r].name); + + IDirectDrawSurface7_Release(surface); + } + +done: + IDirectDraw7_Release(ddraw); + DestroyWindow(window); +} + START_TEST(ddraw7) { HMODULE module = GetModuleHandleA("ddraw.dll"); @@ -10599,7 +10839,7 @@ test_private_data(); test_pixel_format(); test_create_surface_pitch(); - test_mipmap_lock(); + test_mipmap(); test_palette_complex(); test_p8_rgb_blit(); test_material(); @@ -10618,4 +10858,5 @@ test_colorkey_precision(); test_range_colorkey(); test_shademode(); + test_lockrect_invalid(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/tests/dsurface.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/tests/dsurface.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ddraw/tests/dsurface.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ddraw/tests/dsurface.c 2016-02-08 19:32:34.000000000 +0000 @@ -61,158 +61,6 @@ } } -static void MipMapCreationTest(void) -{ - IDirectDrawSurface *lpDDSMipMapTest; - DDSURFACEDESC ddsd; - HRESULT rc; - - /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX, - DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of - requested mipmap levels. */ - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - U2(ddsd).dwMipMapCount = 3; - ddsd.dwWidth = 128; - ddsd.dwHeight = 32; - rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL); - ok(rc==DD_OK,"CreateSurface returned: %x\n",rc); - if (FAILED(rc)) - { - skip("failed to create surface\n"); - return; - } - - /* Check the number of created mipmaps */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(ddsd); - rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd); - ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc); - ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT, - "GetSurfaceDesc returned no mipmapcount.\n"); - ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n", - U2(ddsd).dwMipMapCount); - - /* Destroy the surface. */ - IDirectDrawSurface_Release(lpDDSMipMapTest); - - - /* Second mipmap creation test: create a surface without a mipmap - count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX. - This creates a single mipmap level. */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP; - ddsd.dwWidth = 128; - ddsd.dwHeight = 32; - rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL); - ok(rc==DD_OK,"CreateSurface returned: %x\n",rc); - if (FAILED(rc)) - { - skip("failed to create surface\n"); - return; - } - /* Check the number of created mipmaps */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(ddsd); - rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd); - ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc); - ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT, - "GetSurfaceDesc returned no mipmapcount.\n"); - ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n", - U2(ddsd).dwMipMapCount); - - /* Destroy the surface. */ - IDirectDrawSurface_Release(lpDDSMipMapTest); - - - /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP, - DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT. - It's an undocumented features where a chain of mipmaps, starting from - he specified size and down to the smallest size, is automatically - created. - Anarchy Online needs this feature to work. */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - ddsd.dwWidth = 128; - ddsd.dwHeight = 32; - rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL); - ok(rc==DD_OK,"CreateSurface returned: %x\n",rc); - if (FAILED(rc)) - { - skip("failed to create surface\n"); - return; - } - - /* Check the number of created mipmaps */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(ddsd); - rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd); - ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc); - ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT, - "GetSurfaceDesc returned no mipmapcount.\n"); - ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n", - U2(ddsd).dwMipMapCount); - - /* Destroy the surface. */ - IDirectDrawSurface_Release(lpDDSMipMapTest); - - - /* Fourth mipmap creation test: same as above with a different texture - size. - The purpose is to verify that the number of generated mipmaps is - dependent on the smallest dimension. */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - ddsd.dwWidth = 32; - ddsd.dwHeight = 64; - rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL); - ok(rc==DD_OK,"CreateSurface returned: %x\n",rc); - if (FAILED(rc)) - { - skip("failed to create surface\n"); - return; - } - - /* Check the number of created mipmaps */ - memset(&ddsd, 0, sizeof(DDSURFACEDESC)); - ddsd.dwSize = sizeof(ddsd); - rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd); - ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc); - ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT, - "GetSurfaceDesc returned no mipmapcount.\n"); - ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n", - U2(ddsd).dwMipMapCount); - - /* Destroy the surface. */ - IDirectDrawSurface_Release(lpDDSMipMapTest); - - - /* Fifth mipmap creation test: try to create a surface with - DDSCAPS_COMPLEX, DDSCAPS_MIPMAP, DDSD_MIPMAPCOUNT, - where dwMipMapCount = 0. This should fail. */ - - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP; - U2(ddsd).dwMipMapCount = 0; - ddsd.dwWidth = 128; - ddsd.dwHeight = 32; - rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL); - ok(rc==DDERR_INVALIDPARAMS,"CreateSurface returned: %x\n",rc); - - /* Destroy the surface. */ - if( rc == DD_OK ) - IDirectDrawSurface_Release(lpDDSMipMapTest); - -} - static void SrcColorKey32BlitTest(void) { IDirectDrawSurface *lpSrc; @@ -1360,126 +1208,6 @@ if (dd7) IDirectDraw7_Release(dd7); } -static void test_lockrect_invalid(void) -{ - unsigned int i, j; - - RECT valid[] = { - {60, 60, 68, 68}, - {60, 60, 60, 68}, - {60, 60, 68, 60}, - {120, 60, 128, 68}, - {60, 120, 68, 128}, - }; - - RECT invalid[] = { - {68, 60, 60, 68}, /* left > right */ - {60, 68, 68, 60}, /* top > bottom */ - {-8, 60, 0, 68}, /* left < surface */ - {60, -8, 68, 0}, /* top < surface */ - {-16, 60, -8, 68}, /* right < surface */ - {60, -16, 68, -8}, /* bottom < surface */ - {60, 60, 136, 68}, /* right > surface */ - {60, 60, 68, 136}, /* bottom > surface */ - {136, 60, 144, 68}, /* left > surface */ - {60, 136, 68, 144}, /* top > surface */ - }; - - const DWORD dds_caps[] = { - DDSCAPS_OFFSCREENPLAIN - }; - - for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j) - { - IDirectDrawSurface *surface = 0; - DDSURFACEDESC surface_desc = {0}; - DDSURFACEDESC locked_desc = {0}; - HRESULT hr; - - surface_desc.dwSize = sizeof(surface_desc); - surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat); - surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - surface_desc.ddsCaps.dwCaps = dds_caps[j]; - surface_desc.dwWidth = 128; - surface_desc.dwHeight = 128; - surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB; - U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32; - U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000; - U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00; - U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF; - - hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL); - ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr); - if (FAILED(hr)) - { - skip("failed to create surface\n"); - continue; - } - - hr = IDirectDrawSurface_Lock(surface, NULL, NULL, DDLOCK_WAIT, NULL); - ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for NULL DDSURFACEDESC," - " expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, DDERR_INVALIDPARAMS); - - for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i) - { - RECT *rect = &valid[i]; - - memset(&locked_desc, 0, sizeof(locked_desc)); - locked_desc.dwSize = sizeof(locked_desc); - - hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL); - ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n", - hr, rect->left, rect->top, rect->right, rect->bottom); - - hr = IDirectDrawSurface_Unlock(surface, NULL); - ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr); - } - - for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i) - { - RECT *rect = &invalid[i]; - - memset(&locked_desc, 1, sizeof(locked_desc)); - locked_desc.dwSize = sizeof(locked_desc); - - hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL); - ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]" - ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top, - rect->right, rect->bottom, DDERR_INVALIDPARAMS); - ok(!locked_desc.lpSurface, "IDirectDrawSurface_Lock did not set lpSurface in the surface desc to zero.\n"); - } - - hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL); - ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr); - hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL); - ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr); - if(SUCCEEDED(hr)) { - hr = IDirectDrawSurface_Unlock(surface, NULL); - ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr); - } - hr = IDirectDrawSurface_Unlock(surface, NULL); - ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr); - - memset(&locked_desc, 0, sizeof(locked_desc)); - locked_desc.dwSize = sizeof(locked_desc); - hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL); - ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n", - valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); - hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL); - ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n", - valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr); - - /* Locking a different rectangle returns DD_OK, but it seems to break the surface. - * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles - */ - - hr = IDirectDrawSurface_Unlock(surface, NULL); - ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr); - - IDirectDrawSurface_Release(surface); - } -} - static void CompressedTest(void) { HRESULT hr; @@ -3932,7 +3660,6 @@ return; } - MipMapCreationTest(); SrcColorKey32BlitTest(); QueryInterface(); GetDDInterface_1(); @@ -3941,7 +3668,6 @@ GetDDInterface_7(); EnumTest(); CubeMapTest(); - test_lockrect_invalid(); CompressedTest(); SizeTest(); BltParamTest(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dmime/performance.c wine-staging-1.9.3~ubuntu12.04.1/dlls/dmime/performance.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dmime/performance.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dmime/performance.c 2016-02-08 19:32:34.000000000 +0000 @@ -1035,7 +1035,7 @@ memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); - desc.dwFlags = DSBCAPS_CTRLFX | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS; + desc.dwFlags = DSBCAPS_CTRLFX | DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS; desc.dwBufferBytes = DSBSIZE_MIN; desc.dwReserved = 0; desc.lpwfxFormat = &format; @@ -1046,14 +1046,14 @@ desc.dwFlags |= DSBCAPS_CTRL3D | DSBCAPS_CTRLFREQUENCY | DSBCAPS_MUTE3DATMAXDISTANCE; break; case DMUS_APATH_DYNAMIC_MONO: - desc.dwFlags |= DSBCAPS_CTRLFREQUENCY; + desc.dwFlags |= DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY; break; case DMUS_APATH_SHARED_STEREOPLUSREVERB: /* normally we have to create 2 buffers (one for music other for reverb) * in this case. See msdn */ case DMUS_APATH_DYNAMIC_STEREO: - desc.dwFlags |= DSBCAPS_CTRLFREQUENCY; + desc.dwFlags |= DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY; format.nChannels = 2; format.nBlockAlign *= 2; format.nAvgBytesPerSec *=2; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/analyzer.c wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/analyzer.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/analyzer.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/analyzer.c 2016-02-08 19:32:34.000000000 +0000 @@ -34,7 +34,7 @@ struct dwritescript_properties { DWRITE_SCRIPT_PROPERTIES props; UINT32 scripttag; /* OpenType script tag */ - UINT32 scriptalttag; /* Version 2 tag, 0 is not defined */ + UINT32 scriptalttag; /* Version 2 tag, 0 if not defined */ BOOL is_complex; const struct scriptshaping_ops *ops; }; @@ -177,6 +177,11 @@ }; #undef _OT +const char *debugstr_sa_script(UINT16 script) +{ + return script < Script_LastId ? debugstr_an((char*)&dwritescripts_properties[script].props.isoScriptCode, 4): "not defined"; +} + struct dwrite_numbersubstitution { IDWriteNumberSubstitution IDWriteNumberSubstitution_iface; LONG ref; @@ -326,6 +331,12 @@ } } +BOOL lb_is_newline_char(WCHAR ch) +{ + short c = get_table_entry(wine_linebreak_table, ch); + return c == b_LF || c == b_NL || c == b_CR || c == b_BK; +} + static HRESULT analyze_linebreaks(const WCHAR *text, UINT32 count, DWRITE_LINE_BREAKPOINT *breakpoints) { struct linebreaking_state state; @@ -347,8 +358,8 @@ breakpoints[i].breakConditionBefore = DWRITE_BREAK_CONDITION_CAN_BREAK; breakpoints[i].breakConditionAfter = DWRITE_BREAK_CONDITION_CAN_BREAK; - breakpoints[i].isWhitespace = break_class[i] == b_BK || break_class[i] == b_ZW || break_class[i] == b_SP || isspaceW(text[i]); - breakpoints[i].isSoftHyphen = FALSE; + breakpoints[i].isWhitespace = !!isspaceW(text[i]); + breakpoints[i].isSoftHyphen = text[i] == 0x00ad /* Unicode Soft Hyphen */; breakpoints[i].padding = 0; /* LB1 - resolve some classes. TODO: use external algorithms for these classes. */ @@ -522,15 +533,19 @@ case b_BB: set_break_condition(i, BreakConditionAfter, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, &state); break; - /* LB21a */ + /* LB21a, LB21b */ case b_HL: - if (i < count-2) + /* LB21a */ + if (i < count-1) switch (break_class[i+1]) { case b_HY: case b_BA: set_break_condition(i+1, BreakConditionAfter, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, &state); } + /* LB21b */ + if (i > 0 && break_class[i-1] == b_SY) + set_break_condition(i, BreakConditionBefore, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, &state); break; /* LB22 */ case b_IN: @@ -540,6 +555,7 @@ { case b_AL: case b_HL: + case b_EX: case b_ID: case b_IN: case b_NU: @@ -1056,8 +1072,8 @@ a = 0; advances[i] = get_scaled_advance_width(a, emSize, &metrics); - offsets[i].advanceOffset = 0.0; - offsets[i].ascenderOffset = 0.0; + offsets[i].advanceOffset = 0.0f; + offsets[i].ascenderOffset = 0.0f; } /* FIXME: actually apply features */ @@ -1105,11 +1121,11 @@ hr = IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1, emSize, ppdip, transform, use_gdi_natural, is_sideways, 1, &glyphs[i], &a); if (FAILED(hr)) - advances[i] = 0.0; + advances[i] = 0.0f; else advances[i] = floorf(a * emSize * ppdip / metrics.designUnitsPerEm + 0.5f) / ppdip; - offsets[i].advanceOffset = 0.0; - offsets[i].ascenderOffset = 0.0; + offsets[i].advanceOffset = 0.0f; + offsets[i].ascenderOffset = 0.0f; } /* FIXME: actually apply features */ @@ -1120,7 +1136,7 @@ static inline FLOAT get_cluster_advance(const FLOAT *advances, UINT32 start, UINT32 end) { - FLOAT advance = 0.0; + FLOAT advance = 0.0f; for (; start < end; start++) advance += advances[start]; return advance; @@ -1130,9 +1146,9 @@ FLOAT min_advance_width, UINT32 g, FLOAT const *advances, DWRITE_GLYPH_OFFSET const *offsets, DWRITE_SHAPING_GLYPH_PROPERTIES const *props, FLOAT *modified_advances, DWRITE_GLYPH_OFFSET *modified_offsets) { - BOOL reduced = leading_spacing < 0.0 || trailing_spacing < 0.0; + BOOL reduced = leading_spacing < 0.0f || trailing_spacing < 0.0f; FLOAT advance = advances[g]; - FLOAT origin = 0.0; + FLOAT origin = 0.0f; if (props[g].isZeroWidthSpace) { modified_advances[g] = advances[g]; @@ -1141,32 +1157,32 @@ } /* first apply negative spacing and check if we hit minimum width */ - if (leading_spacing < 0.0) { + if (leading_spacing < 0.0f) { advance += leading_spacing; origin -= leading_spacing; } - if (trailing_spacing < 0.0) + if (trailing_spacing < 0.0f) advance += trailing_spacing; if (advance < min_advance_width) { - FLOAT half = (min_advance_width - advance) / 2.0; + FLOAT half = (min_advance_width - advance) / 2.0f; if (!reduced) origin -= half; - else if (leading_spacing < 0.0 && trailing_spacing < 0.0) + else if (leading_spacing < 0.0f && trailing_spacing < 0.0f) origin -= half; - else if (leading_spacing < 0.0) + else if (leading_spacing < 0.0f) origin -= min_advance_width - advance; advance = min_advance_width; } /* now apply positive spacing adjustments */ - if (leading_spacing > 0.0) { + if (leading_spacing > 0.0f) { advance += leading_spacing; origin -= leading_spacing; } - if (trailing_spacing > 0.0) + if (trailing_spacing > 0.0f) advance += trailing_spacing; modified_advances[g] = advance; @@ -1180,21 +1196,21 @@ UINT32 start, UINT32 end, FLOAT const *advances, DWRITE_GLYPH_OFFSET const *offsets, FLOAT *modified_advances, DWRITE_GLYPH_OFFSET *modified_offsets) { - BOOL reduced = leading_spacing < 0.0 || trailing_spacing < 0.0; + BOOL reduced = leading_spacing < 0.0f || trailing_spacing < 0.0f; FLOAT advance = get_cluster_advance(advances, start, end); - FLOAT origin = 0.0; + FLOAT origin = 0.0f; UINT16 g; modified_advances[start] = advances[start]; modified_advances[end-1] = advances[end-1]; /* first apply negative spacing and check if we hit minimum width */ - if (leading_spacing < 0.0) { + if (leading_spacing < 0.0f) { advance += leading_spacing; modified_advances[start] += leading_spacing; origin -= leading_spacing; } - if (trailing_spacing < 0.0) { + if (trailing_spacing < 0.0f) { advance += trailing_spacing; modified_advances[end-1] += trailing_spacing; } @@ -1209,12 +1225,12 @@ modified_advances[start] += half; modified_advances[end-1] += half; } - else if (leading_spacing < 0.0 && trailing_spacing < 0.0) { + else if (leading_spacing < 0.0f && trailing_spacing < 0.0f) { origin -= half; modified_advances[start] += half; modified_advances[end-1] += half; } - else if (leading_spacing < 0.0) { + else if (leading_spacing < 0.0f) { origin -= advance; modified_advances[start] += advance; } @@ -1223,11 +1239,11 @@ } /* now apply positive spacing adjustments */ - if (leading_spacing > 0.0) { + if (leading_spacing > 0.0f) { modified_advances[start] += leading_spacing; origin -= leading_spacing; } - if (trailing_spacing > 0.0) + if (trailing_spacing > 0.0f) modified_advances[end-1] += trailing_spacing; for (g = start; g < end; g++) { @@ -1273,15 +1289,15 @@ If it's the case advance width is incremented up to minimum value. Important part is the direction in which this increment is applied; - it depends on from which directions total cluster advance was trimmed + it depends on direction from which total cluster advance was trimmed at step 1. So it could be incremented from leading, trailing, or both sides. When applied to both sides, each side gets half of difference - that bring advance to minimum width. + that brings advance to minimum width. 3. Positive adjustments - After minimum width rule was applied, positive spacing is applied in same - way as negative ones on step 1. + After minimum width rule was applied, positive spacing is applied in the same + way as negative one on step 1. Glyph offset for leading glyph is adjusted too in a way that glyph origin keeps its position in coordinate system where initial advance width is counted @@ -1305,13 +1321,13 @@ TRACE("(%.2f %.2f %.2f %u %u %p %p %p %p %p %p)\n", leading_spacing, trailing_spacing, min_advance_width, len, glyph_count, clustermap, advances, offsets, props, modified_advances, modified_offsets); - if (min_advance_width < 0.0) { + if (min_advance_width < 0.0f) { memset(modified_advances, 0, glyph_count*sizeof(*modified_advances)); return E_INVALIDARG; } /* minimum advance is not applied if no adjustments were made */ - if (leading_spacing == 0.0 && trailing_spacing == 0.0) { + if (leading_spacing == 0.0f && trailing_spacing == 0.0f) { memmove(modified_advances, advances, glyph_count*sizeof(*advances)); memmove(modified_offsets, offsets, glyph_count*sizeof(*offsets)); return S_OK; @@ -1469,10 +1485,10 @@ DWRITE_GLYPH_ORIENTATION_ANGLE angle, BOOL is_sideways, FLOAT originX, FLOAT originY, DWRITE_MATRIX *m) { static const DWRITE_MATRIX transforms[] = { - { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, - { 0.0, 1.0, -1.0, 0.0, 0.0, 0.0 }, - { -1.0, 0.0, 0.0, -1.0, 0.0, 0.0 }, - { 0.0, -1.0, 1.0, 0.0, 0.0, 0.0 } + { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f }, + { -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, + { 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f } }; TRACE("(%d %d %.2f %.2f %p)\n", angle, is_sideways, originX, originY, m); @@ -1506,7 +1522,7 @@ /* shift components represent transform necessary to get from original point to rotated one in new coordinate system */ - if ((originX != 0.0 || originY != 0.0) && angle != DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES) { + if ((originX != 0.0f || originY != 0.0f) && angle != DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES) { m->dx = originX - (m->m11 * originX + m->m21 * originY); m->dy = originY - (m->m12 * originX + m->m22 * originY); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/dwrite_private.h wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/dwrite_private.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/dwrite_private.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/dwrite_private.h 2016-02-08 19:32:34.000000000 +0000 @@ -99,6 +99,8 @@ m->dx, m->dy); } +const char *debugstr_sa_script(UINT16) DECLSPEC_HIDDEN; + static inline unsigned short get_table_entry(const unsigned short *table, WCHAR ch) { return table[table[table[ch >> 8] + ((ch >> 4) & 0x0f)] + (ch & 0xf)]; @@ -139,6 +141,7 @@ extern HRESULT get_family_names_from_stream(IDWriteFontFileStream*,UINT32,DWRITE_FONT_FACE_TYPE,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT create_colorglyphenum(FLOAT,FLOAT,const DWRITE_GLYPH_RUN*,const DWRITE_GLYPH_RUN_DESCRIPTION*,DWRITE_MEASURING_MODE, const DWRITE_MATRIX*,UINT32,IDWriteColorGlyphRunEnumerator**) DECLSPEC_HIDDEN; +extern BOOL lb_is_newline_char(WCHAR) DECLSPEC_HIDDEN; /* Opentype font table functions */ struct dwrite_font_props { @@ -175,22 +178,6 @@ extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLSPEC_HIDDEN; extern WCHAR bidi_get_mirrored_char(WCHAR) DECLSPEC_HIDDEN; -enum outline_point_tag { - OUTLINE_POINT_START = 1 << 0, - OUTLINE_POINT_END = 1 << 1, - OUTLINE_POINT_BEZIER = 1 << 2, - OUTLINE_POINT_LINE = 1 << 3 -}; - -struct glyph_outline { - D2D1_POINT_2F *points; - UINT8 *tags; - UINT16 count; - FLOAT advance; -}; - -extern HRESULT new_glyph_outline(UINT32,struct glyph_outline**) DECLSPEC_HIDDEN; - /* FreeType integration */ struct dwrite_glyphbitmap { IDWriteFontFace2 *fontface; @@ -209,7 +196,8 @@ extern HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace2*,UINT16,UINT16,DWRITE_GLYPH_METRICS*) DECLSPEC_HIDDEN; extern void freetype_notify_cacheremove(IDWriteFontFace2*) DECLSPEC_HIDDEN; extern BOOL freetype_is_monospaced(IDWriteFontFace2*) DECLSPEC_HIDDEN; -extern HRESULT freetype_get_glyph_outline(IDWriteFontFace2*,FLOAT,UINT16,USHORT,struct glyph_outline**) DECLSPEC_HIDDEN; +extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace2*,FLOAT,UINT16 const*,FLOAT const*, DWRITE_GLYPH_OFFSET const*, + UINT32,BOOL,IDWriteGeometrySink*) DECLSPEC_HIDDEN; extern UINT16 freetype_get_glyphcount(IDWriteFontFace2*) DECLSPEC_HIDDEN; extern UINT16 freetype_get_glyphindex(IDWriteFontFace2*,UINT32,INT) DECLSPEC_HIDDEN; extern BOOL freetype_has_kerning_pairs(IDWriteFontFace2*) DECLSPEC_HIDDEN; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/font.c wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/font.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/font.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/font.c 2016-02-08 19:32:34.000000000 +0000 @@ -2,7 +2,7 @@ * Font and collections * * Copyright 2011 Huw Davies - * Copyright 2012, 2014-2015 Nikolay Sivov for CodeWeavers + * Copyright 2012, 2014-2016 Nikolay Sivov for CodeWeavers * Copyright 2014 Aric Stewart for CodeWeavers * * This library is free software; you can redistribute it and/or @@ -202,6 +202,8 @@ DWRITE_CARET_METRICS caret; INT charmap; BOOL is_symbol; + BOOL has_kerning_pairs : 1; + BOOL is_monospaced : 1; struct dwrite_fonttable cmap; struct dwrite_fonttable vdmx; @@ -584,84 +586,11 @@ IDWriteFontFileStream_ReleaseFileFragment(This->streams[0], table_context); } -HRESULT new_glyph_outline(UINT32 count, struct glyph_outline **ret) -{ - struct glyph_outline *outline; - D2D1_POINT_2F *points; - UINT8 *tags; - - *ret = NULL; - - outline = heap_alloc(sizeof(*outline)); - if (!outline) - return E_OUTOFMEMORY; - - points = heap_alloc(count*sizeof(D2D1_POINT_2F)); - tags = heap_alloc_zero(count*sizeof(UINT8)); - if (!points || !tags) { - heap_free(points); - heap_free(tags); - heap_free(outline); - return E_OUTOFMEMORY; - } - - outline->points = points; - outline->tags = tags; - outline->count = count; - outline->advance = 0.0; - - *ret = outline; - return S_OK; -} - -static void free_glyph_outline(struct glyph_outline *outline) -{ - heap_free(outline->points); - heap_free(outline->tags); - heap_free(outline); -} - -static void report_glyph_outline(const struct glyph_outline *outline, IDWriteGeometrySink *sink) -{ - UINT16 p; - - for (p = 0; p < outline->count; p++) { - if (outline->tags[p] & OUTLINE_POINT_START) { - ID2D1SimplifiedGeometrySink_BeginFigure(sink, outline->points[p], D2D1_FIGURE_BEGIN_FILLED); - continue; - } - - if (outline->tags[p] & OUTLINE_POINT_LINE) - ID2D1SimplifiedGeometrySink_AddLines(sink, outline->points+p, 1); - else if (outline->tags[p] & OUTLINE_POINT_BEZIER) { - static const UINT16 segment_length = 3; - ID2D1SimplifiedGeometrySink_AddBeziers(sink, (D2D1_BEZIER_SEGMENT*)&outline->points[p], 1); - p += segment_length - 1; - } - - if (outline->tags[p] & OUTLINE_POINT_END) - ID2D1SimplifiedGeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED); - } -} - -static inline void translate_glyph_outline(struct glyph_outline *outline, FLOAT xoffset, FLOAT yoffset) -{ - UINT16 p; - - for (p = 0; p < outline->count; p++) { - outline->points[p].x += xoffset; - outline->points[p].y += yoffset; - } -} - static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace2 *iface, FLOAT emSize, UINT16 const *glyphs, FLOAT const* advances, DWRITE_GLYPH_OFFSET const *offsets, UINT32 count, BOOL is_sideways, BOOL is_rtl, IDWriteGeometrySink *sink) { struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface); - FLOAT advance = 0.0; - HRESULT hr; - UINT32 g; TRACE("(%p)->(%.2f %p %p %p %u %d %d %p)\n", This, emSize, glyphs, advances, offsets, count, is_sideways, is_rtl, sink); @@ -672,42 +601,7 @@ if (is_sideways) FIXME("sideways mode is not supported.\n"); - if (count) - ID2D1SimplifiedGeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING); - - for (g = 0; g < count; g++) { - FLOAT xoffset = 0.0, yoffset = 0.0; - struct glyph_outline *outline; - - /* FIXME: cache outlines */ - - hr = freetype_get_glyph_outline(iface, emSize, glyphs[g], This->simulations, &outline); - if (FAILED(hr)) - return hr; - - /* glyph offsets act as current glyph adjustment */ - if (offsets) { - xoffset += is_rtl ? -offsets[g].advanceOffset : offsets[g].advanceOffset; - yoffset -= offsets[g].ascenderOffset; - } - - if (g == 0) - advance = is_rtl ? -outline->advance : 0.0; - - xoffset += advance; - translate_glyph_outline(outline, xoffset, yoffset); - - /* update advance to next glyph */ - if (advances) - advance += is_rtl ? -advances[g] : advances[g]; - else - advance += is_rtl ? -outline->advance : outline->advance; - - report_glyph_outline(outline, sink); - free_glyph_outline(outline); - } - - return S_OK; + return freetype_get_glyphrun_outline(iface, emSize, glyphs, advances, offsets, count, is_rtl, sink); } static DWRITE_RENDERING_MODE fontface_renderingmode_from_measuringmode(DWRITE_MEASURING_MODE measuring, @@ -845,13 +739,13 @@ TRACE("(%p)->(%.2f %.2f %p %p)\n", This, em_size, pixels_per_dip, m, metrics); - if (em_size <= 0.0 || pixels_per_dip <= 0.0) { + if (em_size <= 0.0f || pixels_per_dip <= 0.0f) { memset(metrics, 0, sizeof(*metrics)); return E_INVALIDARG; } em_size *= pixels_per_dip; - if (m && m->m22 != 0.0) + if (m && m->m22 != 0.0f) em_size *= fabs(m->m22); scale = em_size / design->designUnitsPerEm; @@ -916,7 +810,7 @@ { struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface); TRACE("(%p)\n", This); - return freetype_is_monospaced(iface); + return This->is_monospaced; } static HRESULT WINAPI dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace2 *iface, @@ -947,13 +841,13 @@ TRACE("(%p)->(%.2f %.2f %p %d %d %u %p %p)\n", This, em_size, ppdip, m, use_gdi_natural, is_sideways, glyph_count, glyphs, advances); - if (em_size < 0.0 || ppdip <= 0.0) { + if (em_size < 0.0f || ppdip <= 0.0f) { memset(advances, 0, sizeof(*advances) * glyph_count); return E_INVALIDARG; } em_size *= ppdip; - if (em_size == 0.0) { + if (em_size == 0.0f) { memset(advances, 0, sizeof(*advances) * glyph_count); return S_OK; } @@ -986,6 +880,11 @@ return E_INVALIDARG; } + if (!This->has_kerning_pairs) { + memset(adjustments, 0, count*sizeof(INT32)); + return S_OK; + } + for (i = 0; i < count-1; i++) adjustments[i] = freetype_get_kerning_pair_adjustment(iface, indices[i], indices[i+1]); adjustments[count-1] = 0; @@ -997,7 +896,7 @@ { struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface); TRACE("(%p)\n", This); - return freetype_has_kerning_pairs(iface); + return This->has_kerning_pairs; } static HRESULT WINAPI dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace2 *iface, @@ -2028,11 +1927,11 @@ family_data->fonts[family_data->font_count] = font_data; family_data->font_count++; if (font_data->style == DWRITE_FONT_STYLE_NORMAL) - family_data->has_normal_face = TRUE; + family_data->has_normal_face = 1; else if (font_data->style == DWRITE_FONT_STYLE_OBLIQUE) - family_data->has_oblique_face = TRUE; + family_data->has_oblique_face = 1; else - family_data->has_italic_face = TRUE; + family_data->has_italic_face = 1; return S_OK; } @@ -2737,7 +2636,7 @@ /* for known weight values use appropriate names */ else if (is_known_weight_value(font->weight, weightW)) { } - /* use Wnnn format as a fallback in case weight is not one of defined values */ + /* use Wnnn format as a fallback in case weight is not one of known values */ else { static const WCHAR fmtW[] = {'W','%','d',0}; sprintfW(weightW, fmtW, font->weight); @@ -2834,8 +2733,8 @@ data->face_index = face_index; data->face_type = face_type; data->simulations = DWRITE_FONT_SIMULATIONS_NONE; - data->bold_sim_tested = FALSE; - data->oblique_sim_tested = FALSE; + data->bold_sim_tested = 0; + data->oblique_sim_tested = 0; IDWriteFontFile_AddRef(file); IDWriteFactory2_AddRef(factory); @@ -2912,9 +2811,9 @@ data->ref = 1; data->font_count = 0; data->font_alloc = 2; - data->has_normal_face = FALSE; - data->has_oblique_face = FALSE; - data->has_italic_face = FALSE; + data->has_normal_face = 0; + data->has_oblique_face = 0; + data->has_italic_face = 0; data->fonts = heap_alloc(sizeof(*data->fonts)*data->font_alloc); if (!data->fonts) { @@ -2940,7 +2839,7 @@ if (family->fonts[i]->bold_sim_tested) continue; - family->fonts[i]->bold_sim_tested = TRUE; + family->fonts[i]->bold_sim_tested = 1; for (j = i; j < family->font_count; j++) { if (family->fonts[j]->bold_sim_tested) continue; @@ -2951,7 +2850,7 @@ weight = family->fonts[j]->weight; heaviest = j; } - family->fonts[j]->bold_sim_tested = TRUE; + family->fonts[j]->bold_sim_tested = 1; } } @@ -2993,7 +2892,7 @@ strcatW(facenameW, boldW); if (init_font_data_from_font(family->fonts[heaviest], DWRITE_FONT_SIMULATIONS_BOLD, facenameW, &boldface) == S_OK) { - boldface->bold_sim_tested = TRUE; + boldface->bold_sim_tested = 1; fontfamily_add_font(family, boldface); } } @@ -3012,7 +2911,7 @@ if (family->fonts[i]->oblique_sim_tested) continue; - family->fonts[i]->oblique_sim_tested = TRUE; + family->fonts[i]->oblique_sim_tested = 1; if (family->fonts[i]->style == DWRITE_FONT_STYLE_NORMAL) regular = i; else if (family->fonts[i]->style == DWRITE_FONT_STYLE_OBLIQUE) @@ -3026,7 +2925,7 @@ if ((family->fonts[i]->weight == family->fonts[j]->weight) && (family->fonts[i]->stretch == family->fonts[j]->stretch)) { - family->fonts[j]->oblique_sim_tested = TRUE; + family->fonts[j]->oblique_sim_tested = 1; if (regular == ~0 && family->fonts[j]->style == DWRITE_FONT_STYLE_NORMAL) regular = j; @@ -3057,7 +2956,7 @@ strcatW(facenameW, obliqueW); if (init_font_data_from_font(family->fonts[regular], DWRITE_FONT_SIMULATIONS_OBLIQUE, facenameW, &obliqueface) == S_OK) { - obliqueface->oblique_sim_tested = TRUE; + obliqueface->oblique_sim_tested = 1; fontfamily_add_font(family, obliqueface); } } @@ -3234,6 +3133,27 @@ return ref; } +static HRESULT create_local_file_reference(IDWriteFactory2 *factory, const WCHAR *filename, IDWriteFontFile **file) +{ + HRESULT hr; + + /* Fonts installed in 'Fonts' system dir don't get full path in registry font files cache */ + if (!strchrW(filename, '\\')) { + static const WCHAR fontsW[] = {'\\','f','o','n','t','s','\\',0}; + WCHAR fullpathW[MAX_PATH]; + + GetWindowsDirectoryW(fullpathW, sizeof(fullpathW)/sizeof(WCHAR)); + strcatW(fullpathW, fontsW); + strcatW(fullpathW, filename); + + hr = IDWriteFactory2_CreateFontFileReference(factory, fullpathW, NULL, file); + } + else + hr = IDWriteFactory2_CreateFontFileReference(factory, filename, NULL, file); + + return hr; +} + static HRESULT WINAPI systemfontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator *iface, IDWriteFontFile **file) { struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface); @@ -3266,19 +3186,7 @@ return E_FAIL; } - /* Fonts installed in 'Fonts' system dir don't get full path in registry font files cache */ - if (!strchrW(filename, '\\')) { - static const WCHAR fontsW[] = {'\\','f','o','n','t','s','\\',0}; - WCHAR fullpathW[MAX_PATH]; - - GetWindowsDirectoryW(fullpathW, sizeof(fullpathW)/sizeof(WCHAR)); - strcatW(fullpathW, fontsW); - strcatW(fullpathW, filename); - - hr = IDWriteFactory2_CreateFontFileReference(enumerator->factory, fullpathW, NULL, file); - } - else - hr = IDWriteFactory2_CreateFontFileReference(enumerator->factory, filename, NULL, file); + hr = create_local_file_reference(enumerator->factory, filename, file); heap_free(value); heap_free(filename); @@ -3379,56 +3287,145 @@ return hr; } -static HRESULT WINAPI eudcfontfileenumerator_QueryInterface(IDWriteFontFileEnumerator *iface, REFIID riid, void **obj) +static HRESULT eudc_collection_add_family(IDWriteFactory2 *factory, struct dwrite_fontcollection *collection, + const WCHAR *keynameW, const WCHAR *pathW) { - *obj = NULL; + static const WCHAR defaultfontW[] = {'S','y','s','t','e','m','D','e','f','a','u','l','t','E','U','D','C','F','o','n','t',0}; + static const WCHAR emptyW[] = {0}; + IDWriteLocalizedStrings *names; + DWRITE_FONT_FACE_TYPE face_type; + DWRITE_FONT_FILE_TYPE file_type; + BOOL supported; + UINT32 face_count, i; + IDWriteFontFile *file; + HRESULT hr; + struct dwrite_fontfamily_data *family_data; - if (IsEqualIID(riid, &IID_IDWriteFontFileEnumerator) || IsEqualIID(riid, &IID_IUnknown)) { - IDWriteFontFileEnumerator_AddRef(iface); - *obj = iface; - return S_OK; + /* create font file from this path */ + hr = create_local_file_reference(factory, pathW, &file); + if (FAILED(hr)) + return S_FALSE; + + /* failed font files are skipped */ + hr = IDWriteFontFile_Analyze(file, &supported, &file_type, &face_type, &face_count); + if (FAILED(hr) || !supported || face_count == 0) { + TRACE("unsupported font (%p, 0x%08x, %d, %u)\n", file, hr, supported, face_count); + IDWriteFontFile_Release(file); + return S_FALSE; } - return E_NOINTERFACE; -} + /* create and init new family */ -static ULONG WINAPI eudcfontfileenumerator_AddRef(IDWriteFontFileEnumerator *iface) -{ - return 2; -} + /* Family names are added for non-specific locale, represented with empty string. + Default family appears with empty family name. */ + create_localizedstrings(&names); + if (!strcmpiW(keynameW, defaultfontW)) + add_localizedstring(names, emptyW, emptyW); + else + add_localizedstring(names, emptyW, keynameW); -static ULONG WINAPI eudcfontfileenumerator_Release(IDWriteFontFileEnumerator *iface) -{ - return 1; -} + hr = init_fontfamily_data(names, &family_data); + IDWriteLocalizedStrings_Release(names); + if (hr != S_OK) { + IDWriteFontFile_Release(file); + return hr; + } -static HRESULT WINAPI eudcfontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator *iface, IDWriteFontFile **file) -{ - *file = NULL; - return E_FAIL; -} + /* fill with faces */ + for (i = 0; i < face_count; i++) { + struct dwrite_font_data *font_data; -static HRESULT WINAPI eudcfontfileenumerator_MoveNext(IDWriteFontFileEnumerator *iface, BOOL *current) -{ - *current = FALSE; - return S_OK; + /* alloc and init new font data structure */ + hr = init_font_data(factory, file, face_type, i, &names, &font_data); + if (FAILED(hr)) + continue; + + IDWriteLocalizedStrings_Release(names); + + /* add font to family */ + hr = fontfamily_add_font(family_data, font_data); + if (hr != S_OK) + release_font_data(font_data); + } + + /* add family to collection */ + hr = fontcollection_add_family(collection, family_data); + if (FAILED(hr)) + release_fontfamily_data(family_data); + IDWriteFontFile_Release(file); + + return hr; } -static const struct IDWriteFontFileEnumeratorVtbl eudcfontfileenumeratorvtbl = +HRESULT get_eudc_fontcollection(IDWriteFactory2 *factory, IDWriteFontCollection **ret) { - eudcfontfileenumerator_QueryInterface, - eudcfontfileenumerator_AddRef, - eudcfontfileenumerator_Release, - eudcfontfileenumerator_MoveNext, - eudcfontfileenumerator_GetCurrentFontFile -}; + static const WCHAR eudckeyfmtW[] = {'E','U','D','C','\\','%','u',0}; + struct dwrite_fontcollection *collection; + static const WCHAR emptyW[] = {0}; + WCHAR eudckeypathW[16]; + HKEY eudckey; + DWORD index; + BOOL exists; + LONG retval; + HRESULT hr; + UINT32 i; -static IDWriteFontFileEnumerator eudc_fontfile_enumerator = { &eudcfontfileenumeratorvtbl }; + TRACE("building EUDC font collection for factory %p, ACP %u\n", factory, GetACP()); -HRESULT get_eudc_fontcollection(IDWriteFactory2 *factory, IDWriteFontCollection **collection) -{ - TRACE("building EUDC font collection for factory %p\n", factory); - return create_font_collection(factory, &eudc_fontfile_enumerator, FALSE, collection); + *ret = NULL; + + collection = heap_alloc(sizeof(struct dwrite_fontcollection)); + if (!collection) return E_OUTOFMEMORY; + + hr = init_font_collection(collection, FALSE); + if (FAILED(hr)) { + heap_free(collection); + return hr; + } + + *ret = &collection->IDWriteFontCollection_iface; + + /* return empty collection if EUDC fonts are not configured */ + sprintfW(eudckeypathW, eudckeyfmtW, GetACP()); + if (RegOpenKeyExW(HKEY_CURRENT_USER, eudckeypathW, 0, GENERIC_READ, &eudckey)) + return S_OK; + + retval = ERROR_SUCCESS; + index = 0; + while (retval != ERROR_NO_MORE_ITEMS) { + WCHAR keynameW[64], pathW[MAX_PATH]; + DWORD type, path_len, name_len; + + path_len = sizeof(pathW)/sizeof(*pathW); + name_len = sizeof(keynameW)/sizeof(*keynameW); + retval = RegEnumValueW(eudckey, index++, keynameW, &name_len, NULL, &type, (BYTE*)pathW, &path_len); + if (retval || type != REG_SZ) + continue; + + hr = eudc_collection_add_family(factory, collection, keynameW, pathW); + if (hr != S_OK) + WARN("failed to add family %s, path %s\n", debugstr_w(keynameW), debugstr_w(pathW)); + } + RegCloseKey(eudckey); + + /* try to add global default if not defined for specific codepage */ + exists = FALSE; + hr = IDWriteFontCollection_FindFamilyName(&collection->IDWriteFontCollection_iface, emptyW, + &index, &exists); + if (FAILED(hr) || !exists) { + const WCHAR globaldefaultW[] = {'E','U','D','C','.','T','T','E',0}; + hr = eudc_collection_add_family(factory, collection, emptyW, globaldefaultW); + if (hr != S_OK) + WARN("failed to add global default EUDC font, 0x%08x\n", hr); + } + + /* EUDC collection offers simulated faces too */ + for (i = 0; i < collection->family_count; i++) { + fontfamily_add_bold_simulated_face(collection->family_data[i]); + fontfamily_add_oblique_simulated_face(collection->family_data[i]); + } + + return S_OK; } static HRESULT WINAPI dwritefontfile_QueryInterface(IDWriteFontFile *iface, REFIID riid, void **obj) @@ -3494,7 +3491,8 @@ return S_OK; } -static HRESULT WINAPI dwritefontfile_Analyze(IDWriteFontFile *iface, BOOL *isSupportedFontType, DWRITE_FONT_FILE_TYPE *fontFileType, DWRITE_FONT_FACE_TYPE *fontFaceType, UINT32 *numberOfFaces) +static HRESULT WINAPI dwritefontfile_Analyze(IDWriteFontFile *iface, BOOL *isSupportedFontType, DWRITE_FONT_FILE_TYPE *fontFileType, + DWRITE_FONT_FACE_TYPE *fontFaceType, UINT32 *numberOfFaces) { struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface); IDWriteFontFileStream *stream; @@ -3632,6 +3630,8 @@ } } fontface->charmap = freetype_get_charmap_index(&fontface->IDWriteFontFace2_iface, &fontface->is_symbol); + fontface->has_kerning_pairs = freetype_has_kerning_pairs(&fontface->IDWriteFontFace2_iface); + fontface->is_monospaced = freetype_is_monospaced(&fontface->IDWriteFontFace2_iface); *ret = &fontface->IDWriteFontFace2_iface; return S_OK; @@ -3782,9 +3782,13 @@ localfontfilestream_GetLastWriteTime }; -static HRESULT create_localfontfilestream(const void *file_ptr, UINT64 size, struct local_cached_stream *entry, IDWriteFontFileStream** iface) +static HRESULT create_localfontfilestream(const void *file_ptr, UINT64 size, struct local_cached_stream *entry, IDWriteFontFileStream **ret) { - struct dwrite_localfontfilestream *This = heap_alloc(sizeof(struct dwrite_localfontfilestream)); + struct dwrite_localfontfilestream *This; + + *ret = NULL; + + This = heap_alloc(sizeof(struct dwrite_localfontfilestream)); if (!This) return E_OUTOFMEMORY; @@ -3795,7 +3799,7 @@ This->size = size; This->entry = entry; - *iface = &This->IDWriteFontFileStream_iface; + *ret = &This->IDWriteFontFileStream_iface; return S_OK; } @@ -3835,7 +3839,7 @@ struct local_cached_stream *stream, *stream2; /* This will detach all entries from cache. Entries are released together with streams, - so stream controls its lifetime. */ + so stream controls cache entry lifetime. */ LIST_FOR_EACH_ENTRY_SAFE(stream, stream2, &This->streams, struct local_cached_stream, entry) list_init(&stream->entry); @@ -3962,9 +3966,13 @@ localfontfileloader_GetLastWriteTimeFromKey }; -HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) +HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader **ret) { - struct dwrite_localfontfileloader *This = heap_alloc(sizeof(struct dwrite_localfontfileloader)); + struct dwrite_localfontfileloader *This; + + *ret = NULL; + + This = heap_alloc(sizeof(struct dwrite_localfontfileloader)); if (!This) return E_OUTOFMEMORY; @@ -3972,7 +3980,7 @@ This->ref = 1; list_init(&This->streams); - *iface = &This->IDWriteLocalFontFileLoader_iface; + *ret = &This->IDWriteLocalFontFileLoader_iface; return S_OK; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/freetype.c wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/freetype.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/freetype.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/freetype.c 2016-02-08 19:32:34.000000000 +0000 @@ -32,7 +32,6 @@ #endif /* HAVE_FT2BUILD_H */ #include "windef.h" -#include "dwrite_2.h" #include "wine/library.h" #include "wine/debug.h" @@ -77,6 +76,7 @@ MAKE_FUNCPTR(FT_Load_Glyph); MAKE_FUNCPTR(FT_New_Memory_Face); MAKE_FUNCPTR(FT_Outline_Copy); +MAKE_FUNCPTR(FT_Outline_Decompose); MAKE_FUNCPTR(FT_Outline_Done); MAKE_FUNCPTR(FT_Outline_Get_Bitmap); MAKE_FUNCPTR(FT_Outline_New); @@ -163,6 +163,7 @@ LOAD_FUNCPTR(FT_Load_Glyph) LOAD_FUNCPTR(FT_New_Memory_Face) LOAD_FUNCPTR(FT_Outline_Copy) + LOAD_FUNCPTR(FT_Outline_Decompose) LOAD_FUNCPTR(FT_Outline_Done) LOAD_FUNCPTR(FT_Outline_Get_Bitmap) LOAD_FUNCPTR(FT_Outline_New) @@ -261,22 +262,75 @@ EnterCriticalSection(&freetype_cs); if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) - is_monospaced = FT_IS_FIXED_WIDTH(face); + is_monospaced = !!FT_IS_FIXED_WIDTH(face); LeaveCriticalSection(&freetype_cs); return is_monospaced; } -static inline void ft_vector_to_d2d_point(const FT_Vector *v, D2D1_POINT_2F *p) +struct decompose_context { + IDWriteGeometrySink *sink; + FLOAT xoffset; + FLOAT yoffset; + BOOL figure_started; + BOOL figure_closed; + BOOL move_to; /* last call was 'move_to' */ + FT_Vector origin; /* 'pen' position from last call */ +}; + +static inline void ft_vector_to_d2d_point(const FT_Vector *v, FLOAT xoffset, FLOAT yoffset, D2D1_POINT_2F *p) +{ + p->x = (v->x / 64.0f) + xoffset; + p->y = (v->y / 64.0f) + yoffset; +} + +static int decompose_move_to(const FT_Vector *to, void *user) { - p->x = v->x / 64.0; - p->y = v->y / 64.0; + struct decompose_context *ctxt = (struct decompose_context*)user; + D2D1_POINT_2F point; + + if (ctxt->figure_started) { + ID2D1SimplifiedGeometrySink_EndFigure(ctxt->sink, D2D1_FIGURE_END_CLOSED); + ctxt->figure_closed = TRUE; + } + else + ctxt->figure_closed = FALSE; + ctxt->figure_started = TRUE; + + ft_vector_to_d2d_point(to, ctxt->xoffset, ctxt->yoffset, &point); + ID2D1SimplifiedGeometrySink_BeginFigure(ctxt->sink, point, D2D1_FIGURE_BEGIN_FILLED); + ctxt->move_to = TRUE; + ctxt->origin = *to; + return 0; +} + +static int decompose_line_to(const FT_Vector *to, void *user) +{ + struct decompose_context *ctxt = (struct decompose_context*)user; + /* special case for empty contours, in a way freetype returns them */ + if (ctxt->move_to && !memcmp(to, &ctxt->origin, sizeof(*to))) { + ID2D1SimplifiedGeometrySink_EndFigure(ctxt->sink, D2D1_FIGURE_END_CLOSED); + ctxt->figure_closed = TRUE; + } + else { + D2D1_POINT_2F point; + ft_vector_to_d2d_point(to, ctxt->xoffset, ctxt->yoffset, &point); + ID2D1SimplifiedGeometrySink_AddLines(ctxt->sink, &point, 1); + ctxt->figure_closed = FALSE; + } + ctxt->move_to = FALSE; + ctxt->origin = *to; + return 0; } -/* Convert the quadratic Beziers to cubic Beziers. */ -static void get_cubic_glyph_outline(const FT_Outline *outline, short point, short first_pt, - short contour, FT_Vector *cubic_control) +static int decompose_conic_to(const FT_Vector *control, const FT_Vector *to, void *user) { + struct decompose_context *ctxt = (struct decompose_context*)user; + D2D1_POINT_2F points[3]; + FT_Vector cubic[3]; + + /* convert from quadratic to cubic */ + /* The parametric eqn for a cubic Bezier is, from PLRM: r(t) = at^3 + bt^2 + ct + r0 @@ -294,108 +348,85 @@ and of course r0 = p0, r3 = p2 */ - /* FIXME: Possible optimization in endpoint calculation - if there are two consecutive curves */ - cubic_control[0] = outline->points[point-1]; - if (!(outline->tags[point-1] & FT_Curve_Tag_On)) { - cubic_control[0].x += outline->points[point].x + 1; - cubic_control[0].y += outline->points[point].y + 1; - cubic_control[0].x >>= 1; - cubic_control[0].y >>= 1; - } - if (point+1 > outline->contours[contour]) - cubic_control[3] = outline->points[first_pt]; - else { - cubic_control[3] = outline->points[point+1]; - if (!(outline->tags[point+1] & FT_Curve_Tag_On)) { - cubic_control[3].x += outline->points[point].x + 1; - cubic_control[3].y += outline->points[point].y + 1; - cubic_control[3].x >>= 1; - cubic_control[3].y >>= 1; - } - } - /* r1 = 1/3 p0 + 2/3 p1 r2 = 1/3 p2 + 2/3 p1 */ - cubic_control[1].x = (2 * outline->points[point].x + 1) / 3; - cubic_control[1].y = (2 * outline->points[point].y + 1) / 3; - cubic_control[2] = cubic_control[1]; - cubic_control[1].x += (cubic_control[0].x + 1) / 3; - cubic_control[1].y += (cubic_control[0].y + 1) / 3; - cubic_control[2].x += (cubic_control[3].x + 1) / 3; - cubic_control[2].y += (cubic_control[3].y + 1) / 3; -} - -static short get_outline_data(const FT_Outline *outline, struct glyph_outline *ret) -{ - short contour, point = 0, first_pt, count; - - for (contour = 0, count = 0; contour < outline->n_contours; contour++) { - first_pt = point; - if (ret) { - ft_vector_to_d2d_point(&outline->points[point], &ret->points[count]); - ret->tags[count] = OUTLINE_POINT_START; - if (count) - ret->tags[count-1] |= OUTLINE_POINT_END; - } - - point++; - count++; - - while (point <= outline->contours[contour]) { - do { - if (outline->tags[point] & FT_Curve_Tag_On) { - if (ret) { - ft_vector_to_d2d_point(&outline->points[point], &ret->points[count]); - ret->tags[count] |= OUTLINE_POINT_LINE; - } + cubic[0].x = (2 * control->x + 1) / 3; + cubic[0].y = (2 * control->y + 1) / 3; + cubic[1] = cubic[0]; + cubic[0].x += (ctxt->origin.x + 1) / 3; + cubic[0].y += (ctxt->origin.y + 1) / 3; + cubic[1].x += (to->x + 1) / 3; + cubic[1].y += (to->y + 1) / 3; + cubic[2] = *to; + + ft_vector_to_d2d_point(cubic, ctxt->xoffset, ctxt->yoffset, points); + ft_vector_to_d2d_point(cubic + 1, ctxt->xoffset, ctxt->yoffset, points + 1); + ft_vector_to_d2d_point(cubic + 2, ctxt->xoffset, ctxt->yoffset, points + 2); + ID2D1SimplifiedGeometrySink_AddBeziers(ctxt->sink, (D2D1_BEZIER_SEGMENT*)points, 1); + ctxt->figure_closed = FALSE; + ctxt->move_to = FALSE; + ctxt->origin = *to; + return 0; +} + +static int decompose_cubic_to(const FT_Vector *control1, const FT_Vector *control2, + const FT_Vector *to, void *user) +{ + struct decompose_context *ctxt = (struct decompose_context*)user; + D2D1_POINT_2F points[3]; + + ft_vector_to_d2d_point(control1, ctxt->xoffset, ctxt->yoffset, points); + ft_vector_to_d2d_point(control2, ctxt->xoffset, ctxt->yoffset, points + 1); + ft_vector_to_d2d_point(to, ctxt->xoffset, ctxt->yoffset, points + 2); + ID2D1SimplifiedGeometrySink_AddBeziers(ctxt->sink, (D2D1_BEZIER_SEGMENT*)points, 1); + ctxt->figure_closed = FALSE; + ctxt->move_to = FALSE; + ctxt->origin = *to; + return 0; +} + +static void decompose_outline(FT_Outline *outline, FLOAT xoffset, FLOAT yoffset, IDWriteGeometrySink *sink) +{ + static const FT_Outline_Funcs decompose_funcs = { + decompose_move_to, + decompose_line_to, + decompose_conic_to, + decompose_cubic_to, + 0, + 0 + }; + struct decompose_context context; + + context.sink = sink; + context.xoffset = xoffset; + context.yoffset = yoffset; + context.figure_started = FALSE; + context.figure_closed = FALSE; + context.move_to = FALSE; + context.origin.x = 0; + context.origin.y = 0; - point++; - count++; - } - else { - - if (ret) { - FT_Vector cubic_control[4]; - - get_cubic_glyph_outline(outline, point, first_pt, contour, cubic_control); - ft_vector_to_d2d_point(&cubic_control[1], &ret->points[count]); - ft_vector_to_d2d_point(&cubic_control[2], &ret->points[count+1]); - ft_vector_to_d2d_point(&cubic_control[3], &ret->points[count+2]); - ret->tags[count] = OUTLINE_POINT_BEZIER; - ret->tags[count+1] = OUTLINE_POINT_BEZIER; - ret->tags[count+2] = OUTLINE_POINT_BEZIER; - } + pFT_Outline_Decompose(outline, &decompose_funcs, &context); - count += 3; - point++; - } - } while (point <= outline->contours[contour] && - (outline->tags[point] & FT_Curve_Tag_On) == - (outline->tags[point-1] & FT_Curve_Tag_On)); - - if (point <= outline->contours[contour] && - outline->tags[point] & FT_Curve_Tag_On) - { - /* This is the closing pt of a bezier, but we've already - added it, so just inc point and carry on */ - point++; - } - } - } - - if (ret) - ret->tags[count-1] |= OUTLINE_POINT_END; - - return count; + if (!context.figure_closed && outline->n_points) + ID2D1SimplifiedGeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED); } -HRESULT freetype_get_glyph_outline(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 index, USHORT simulations, struct glyph_outline **ret) +HRESULT freetype_get_glyphrun_outline(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 const *glyphs, FLOAT const *advances, + DWRITE_GLYPH_OFFSET const *offsets, UINT32 count, BOOL is_rtl, IDWriteGeometrySink *sink) { FTC_ScalerRec scaler; + USHORT simulations; HRESULT hr = S_OK; FT_Size size; + if (!count) + return S_OK; + + ID2D1SimplifiedGeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING); + + simulations = IDWriteFontFace2_GetSimulations(fontface); + scaler.face_id = fontface; scaler.width = emSize; scaler.height = emSize; @@ -405,26 +436,45 @@ EnterCriticalSection(&freetype_cs); if (pFTC_Manager_LookupSize(cache_manager, &scaler, &size) == 0) { - if (pFT_Load_Glyph(size->face, index, FT_LOAD_NO_BITMAP) == 0) { - FT_Outline *outline = &size->face->glyph->outline; - short count; - FT_Matrix m; - - m.xx = 1 << 16; - m.xy = simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0; - m.yx = 0; - m.yy = -(1 << 16); /* flip Y axis */ - - pFT_Outline_Transform(outline, &m); - - count = get_outline_data(outline, NULL); - hr = new_glyph_outline(count, ret); - if (hr == S_OK) { - get_outline_data(outline, *ret); - (*ret)->advance = size->face->glyph->metrics.horiAdvance >> 6; - } - } + FLOAT advance = 0.0f; + UINT32 g; + + for (g = 0; g < count; g++) { + if (pFT_Load_Glyph(size->face, glyphs[g], FT_LOAD_NO_BITMAP) == 0) { + FLOAT ft_advance = size->face->glyph->metrics.horiAdvance >> 6; + FT_Outline *outline = &size->face->glyph->outline; + FLOAT xoffset = 0.0f, yoffset = 0.0f; + FT_Matrix m; + + m.xx = 1 << 16; + m.xy = simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0; + m.yx = 0; + m.yy = -(1 << 16); /* flip Y axis */ + + pFT_Outline_Transform(outline, &m); + + /* glyph offsets act as current glyph adjustment */ + if (offsets) { + xoffset += is_rtl ? -offsets[g].advanceOffset : offsets[g].advanceOffset; + yoffset -= offsets[g].ascenderOffset; + } + + if (g == 0 && is_rtl) + advance = advances ? -advances[g] : -ft_advance; + + xoffset += advance; + decompose_outline(outline, xoffset, yoffset, sink); + + /* update advance to next glyph */ + if (advances) + advance += is_rtl ? -advances[g] : advances[g]; + else + advance += is_rtl ? -ft_advance : ft_advance; + } + } } + else + hr = E_FAIL; LeaveCriticalSection(&freetype_cs); return hr; @@ -469,7 +519,7 @@ EnterCriticalSection(&freetype_cs); if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) - has_kerning_pairs = FT_HAS_KERNING(face); + has_kerning_pairs = !!FT_HAS_KERNING(face); LeaveCriticalSection(&freetype_cs); return has_kerning_pairs; @@ -775,9 +825,9 @@ return FALSE; } -HRESULT freetype_get_glyph_outline(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 index, USHORT simulations, struct glyph_outline **ret) +HRESULT freetype_get_glyphrun_outline(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 const *glyphs, FLOAT const *advances, + DWRITE_GLYPH_OFFSET const *offsets, UINT32 count, BOOL is_rtl, IDWriteGeometrySink *sink) { - *ret = NULL; return E_NOTIMPL; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/gdiinterop.c wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/gdiinterop.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/gdiinterop.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/gdiinterop.c 2016-02-08 19:32:34.000000000 +0000 @@ -422,6 +422,11 @@ if (texturetype == DWRITE_TEXTURE_CLEARTYPE_3x1) size *= 3; bitmap = heap_alloc_zero(size); + if (!bitmap) { + IDWriteGlyphRunAnalysis_Release(analysis); + return E_OUTOFMEMORY; + } + hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, texturetype, &target, bitmap, size); if (hr == S_OK) { /* blit to target dib */ @@ -461,7 +466,7 @@ TRACE("(%p)->(%.2f)\n", This, ppdip); - if (ppdip <= 0.0) + if (ppdip <= 0.0f) return E_INVALIDARG; This->ppdip = ppdip; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/layout.c wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/layout.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/layout.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/layout.c 2016-02-08 19:32:34.000000000 +0000 @@ -1,7 +1,7 @@ /* * Text format and layout * - * Copyright 2012, 2014-2015 Nikolay Sivov for CodeWeavers + * Copyright 2012, 2014-2016 Nikolay Sivov for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -102,6 +102,7 @@ enum layout_range_kind { LAYOUT_RANGE_REGULAR, + LAYOUT_RANGE_UNDERLINE, LAYOUT_RANGE_STRIKETHROUGH, LAYOUT_RANGE_EFFECT, LAYOUT_RANGE_SPACING, @@ -121,7 +122,6 @@ FLOAT fontsize; DWRITE_FONT_STRETCH stretch; IDWriteInlineObject *object; - BOOL underline; BOOL pair_kerning; IDWriteFontCollection *collection; WCHAR locale[LOCALE_NAME_MAX_LENGTH]; @@ -184,25 +184,33 @@ UINT32 start; /* relative text position, 0 means first text position of a nominal run */ UINT32 length; /* length in codepoints that this run covers */ UINT32 glyphcount; /* total glyph count in this run */ + IUnknown *effect; /* original reference is kept only at range level */ FLOAT origin_x; /* baseline X position */ FLOAT origin_y; /* baseline Y position */ FLOAT align_dx; /* adjustment from text alignment */ FLOAT width; /* run width */ UINT16 *clustermap; /* effective clustermap, allocated separately, is not reused from nominal map */ - UINT32 line; + UINT32 line; /* 0-based line index in line metrics array */ + BOOL underlined; /* set if this run is underlined */ }; struct layout_effective_inline { struct list entry; - IDWriteInlineObject *object; - IUnknown *effect; - FLOAT origin_x; - FLOAT origin_y; - FLOAT align_dx; - FLOAT width; - BOOL is_sideways; - BOOL is_rtl; - UINT32 line; + const struct layout_run *run; /* nominal run this one is based on */ + IUnknown *effect; /* original reference is kept only at range level */ + FLOAT origin_x; /* left X position */ + FLOAT origin_y; /* left top corner Y position */ + FLOAT align_dx; /* adjustment from text alignment */ + FLOAT width; /* object width as it's reported it */ + BOOL is_sideways; /* vertical flow direction flag passed to Draw */ + BOOL is_rtl; /* bidi flag passed to Draw */ + UINT32 line; /* 0-based line index in line metrics array */ +}; + +struct layout_underline { + struct list entry; + const struct layout_effective_run *run; + DWRITE_UNDERLINE u; }; struct layout_strikethrough { @@ -226,14 +234,15 @@ struct dwrite_textlayout { IDWriteTextLayout2 IDWriteTextLayout2_iface; IDWriteTextFormat1 IDWriteTextFormat1_iface; - IDWriteTextAnalysisSink IDWriteTextAnalysisSink_iface; - IDWriteTextAnalysisSource IDWriteTextAnalysisSource_iface; + IDWriteTextAnalysisSink1 IDWriteTextAnalysisSink1_iface; + IDWriteTextAnalysisSource1 IDWriteTextAnalysisSource1_iface; LONG ref; WCHAR *str; UINT32 len; struct dwrite_textformat_data format; struct list strike_ranges; + struct list underline_ranges; struct list typographies; struct list effects; struct list spacing; @@ -242,6 +251,7 @@ /* lists ready to use by Draw() */ struct list eruns; struct list inlineobjects; + struct list underlines; struct list strikethrough; USHORT recompute; @@ -313,14 +323,14 @@ return CONTAINING_RECORD(iface, struct dwrite_textlayout, IDWriteTextFormat1_iface); } -static inline struct dwrite_textlayout *impl_from_IDWriteTextAnalysisSink(IDWriteTextAnalysisSink *iface) +static inline struct dwrite_textlayout *impl_from_IDWriteTextAnalysisSink1(IDWriteTextAnalysisSink1 *iface) { - return CONTAINING_RECORD(iface, struct dwrite_textlayout, IDWriteTextAnalysisSink_iface); + return CONTAINING_RECORD(iface, struct dwrite_textlayout, IDWriteTextAnalysisSink1_iface); } -static inline struct dwrite_textlayout *impl_from_IDWriteTextAnalysisSource(IDWriteTextAnalysisSource *iface) +static inline struct dwrite_textlayout *impl_from_IDWriteTextAnalysisSource1(IDWriteTextAnalysisSource1 *iface) { - return CONTAINING_RECORD(iface, struct dwrite_textlayout, IDWriteTextAnalysisSource_iface); + return CONTAINING_RECORD(iface, struct dwrite_textlayout, IDWriteTextAnalysisSource1_iface); } static inline struct dwrite_textformat *impl_from_IDWriteTextFormat1(IDWriteTextFormat1 *iface) @@ -340,10 +350,9 @@ return CONTAINING_RECORD(iface, struct dwrite_typography, IDWriteTypography_iface); } -static inline const char *debugstr_run(const struct regular_layout_run *run) +static inline const char *debugstr_rundescr(const DWRITE_GLYPH_RUN_DESCRIPTION *descr) { - return wine_dbg_sprintf("[%u,%u)", run->descr.textPosition, run->descr.textPosition + - run->descr.stringLength); + return wine_dbg_sprintf("[%u,%u)", descr->textPosition, descr->textPosition + descr->stringLength); } static inline BOOL is_layout_gdi_compatible(struct dwrite_textlayout *layout) @@ -391,6 +400,31 @@ return S_OK; } +static inline HRESULT format_set_flowdirection(struct dwrite_textformat_data *format, + DWRITE_FLOW_DIRECTION direction, BOOL *changed) +{ + if ((UINT32)direction > DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT) + return E_INVALIDARG; + if (changed) *changed = format->flow != direction; + format->flow = direction; + return S_OK; +} + +static inline HRESULT format_set_linespacing(struct dwrite_textformat_data *format, + DWRITE_LINE_SPACING_METHOD method, FLOAT spacing, FLOAT baseline, BOOL *changed) +{ + if (spacing < 0.0f || (UINT32)method > DWRITE_LINE_SPACING_METHOD_UNIFORM) + return E_INVALIDARG; + + if (changed) *changed = format->spacingmethod != method || + format->spacing != spacing || format->baseline != baseline; + + format->spacingmethod = method; + format->spacing = spacing; + format->baseline = baseline; + return S_OK; +} + static HRESULT get_fontfallback_from_format(const struct dwrite_textformat_data *format, IDWriteFontFallback **fallback) { *fallback = format->fallback; @@ -418,6 +452,11 @@ return S_OK; } +static BOOL is_run_rtl(const struct layout_effective_run *run) +{ + return run->run->u.regular.run.bidiLevel & 1; +} + static struct layout_run *alloc_layout_run(enum layout_run_kind kind) { struct layout_run *ret; @@ -457,6 +496,7 @@ struct layout_effective_inline *in, *in2; struct layout_effective_run *cur, *cur2; struct layout_strikethrough *s, *s2; + struct layout_underline *u, *u2; LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->eruns, struct layout_effective_run, entry) { list_remove(&cur->entry); @@ -469,6 +509,11 @@ heap_free(in); } + LIST_FOR_EACH_ENTRY_SAFE(u, u2, &layout->underlines, struct layout_underline, entry) { + list_remove(&u->entry); + heap_free(u); + } + LIST_FOR_EACH_ENTRY_SAFE(s, s2, &layout->strikethrough, struct layout_strikethrough, entry) { list_remove(&s->entry); heap_free(s); @@ -548,8 +593,8 @@ layout->actual_breakpoints[i].breakConditionAfter = DWRITE_BREAK_CONDITION_MAY_NOT_BREAK; } - layout->actual_breakpoints[i].isWhitespace = FALSE; - layout->actual_breakpoints[i].isSoftHyphen = FALSE; + layout->actual_breakpoints[i].isWhitespace = 0; + layout->actual_breakpoints[i].isSoftHyphen = 0; } return S_OK; @@ -573,35 +618,33 @@ /* For clusters made of control chars we report zero glyphs, and we need zero cluster width as well; advances are already computed at this point and are not necessary zero. */ - metrics->width = 0.0; + metrics->width = 0.0f; if (run->run.glyphCount) { for (j = start_glyph; j < stop_glyph; j++) metrics->width += run->run.glyphAdvances[j]; } metrics->length = length; - position = stop_position; + position = run->descr.textPosition + stop_position; if (stop_glyph == run->glyphcount) - breakcondition = get_effective_breakpoint(layout, stop_position).breakConditionAfter; + breakcondition = get_effective_breakpoint(layout, position).breakConditionAfter; else { - breakcondition = get_effective_breakpoint(layout, stop_position).breakConditionBefore; - if (stop_position) position = stop_position - 1; + breakcondition = get_effective_breakpoint(layout, position).breakConditionBefore; + if (stop_position) position -= 1; } metrics->canWrapLineAfter = breakcondition == DWRITE_BREAK_CONDITION_CAN_BREAK || breakcondition == DWRITE_BREAK_CONDITION_MUST_BREAK; if (metrics->length == 1) { - WORD type = 0; - - GetStringTypeW(CT_CTYPE1, &layout->str[position], 1, &type); - metrics->isWhitespace = !!(type & C1_SPACE); - metrics->isNewline = FALSE /* FIXME */; - metrics->isSoftHyphen = layout->str[position] == 0x00ad /* Unicode Soft Hyphen */; + DWRITE_LINE_BREAKPOINT bp = get_effective_breakpoint(layout, position); + metrics->isWhitespace = bp.isWhitespace; + metrics->isNewline = metrics->canWrapLineAfter && lb_is_newline_char(layout->str[position]); + metrics->isSoftHyphen = bp.isSoftHyphen; } else { - metrics->isWhitespace = FALSE; - metrics->isNewline = FALSE; - metrics->isSoftHyphen = FALSE; + metrics->isWhitespace = 0; + metrics->isNewline = 0; + metrics->isSoftHyphen = 0; } metrics->isRightToLeft = run->run.bidiLevel & 1; metrics->padding = 0; @@ -649,9 +692,57 @@ } } -static inline FLOAT get_scaled_font_metric(UINT32 metric, FLOAT emSize, const DWRITE_FONT_METRICS *metrics) +#define SCALE_FONT_METRIC(metric, emSize, metrics) ((FLOAT)(metric) * (emSize) / (FLOAT)(metrics)->designUnitsPerEm) + +static HRESULT create_fontface_by_pos(struct dwrite_textlayout *layout, struct layout_range *range, IDWriteFontFace **fontface) { - return (FLOAT)metric * emSize / (FLOAT)metrics->designUnitsPerEm; + static DWRITE_GLYPH_RUN_DESCRIPTION descr = { 0 }; + IDWriteFontFamily *family; + BOOL exists = FALSE; + IDWriteFont *font; + UINT32 index; + HRESULT hr; + + *fontface = NULL; + + hr = IDWriteFontCollection_FindFamilyName(range->collection, range->fontfamily, &index, &exists); + if (FAILED(hr) || !exists) { + WARN("%s: family %s not found in collection %p\n", debugstr_rundescr(&descr), debugstr_w(range->fontfamily), range->collection); + return hr; + } + + hr = IDWriteFontCollection_GetFontFamily(range->collection, index, &family); + if (FAILED(hr)) + return hr; + + hr = IDWriteFontFamily_GetFirstMatchingFont(family, range->weight, range->stretch, range->style, &font); + IDWriteFontFamily_Release(family); + if (FAILED(hr)) { + WARN("%s: failed to get a matching font\n", debugstr_rundescr(&descr)); + return hr; + } + + hr = IDWriteFont_CreateFontFace(font, fontface); + IDWriteFont_Release(font); + return hr; +} + +static void layout_get_font_metrics(struct dwrite_textlayout *layout, IDWriteFontFace *fontface, FLOAT emsize, + DWRITE_FONT_METRICS *fontmetrics) +{ + if (is_layout_gdi_compatible(layout)) { + HRESULT hr = IDWriteFontFace_GetGdiCompatibleMetrics(fontface, emsize, layout->ppdip, &layout->transform, fontmetrics); + if (FAILED(hr)) + WARN("failed to get compat metrics, 0x%08x\n", hr); + } + else + IDWriteFontFace_GetMetrics(fontface, fontmetrics); +} + +static void layout_get_font_height(FLOAT emsize, DWRITE_FONT_METRICS *fontmetrics, FLOAT *baseline, FLOAT *height) +{ + *baseline = SCALE_FONT_METRIC(fontmetrics->ascent + fontmetrics->lineGap, emsize, fontmetrics); + *height = SCALE_FONT_METRIC(fontmetrics->ascent + fontmetrics->descent + fontmetrics->lineGap, emsize, fontmetrics); } static HRESULT layout_compute_runs(struct dwrite_textlayout *layout) @@ -703,14 +794,14 @@ } /* initial splitting by script */ - hr = IDWriteTextAnalyzer_AnalyzeScript(analyzer, &layout->IDWriteTextAnalysisSource_iface, - range->h.range.startPosition, get_clipped_range_length(layout, range), &layout->IDWriteTextAnalysisSink_iface); + hr = IDWriteTextAnalyzer_AnalyzeScript(analyzer, (IDWriteTextAnalysisSource*)&layout->IDWriteTextAnalysisSource1_iface, + range->h.range.startPosition, get_clipped_range_length(layout, range), (IDWriteTextAnalysisSink*)&layout->IDWriteTextAnalysisSink1_iface); if (FAILED(hr)) break; /* this splits it further */ - hr = IDWriteTextAnalyzer_AnalyzeBidi(analyzer, &layout->IDWriteTextAnalysisSource_iface, - range->h.range.startPosition, get_clipped_range_length(layout, range), &layout->IDWriteTextAnalysisSink_iface); + hr = IDWriteTextAnalyzer_AnalyzeBidi(analyzer, (IDWriteTextAnalysisSource*)&layout->IDWriteTextAnalysisSource1_iface, + range->h.range.startPosition, get_clipped_range_length(layout, range), (IDWriteTextAnalysisSink*)&layout->IDWriteTextAnalysisSink1_iface); if (FAILED(hr)) break; } @@ -721,10 +812,7 @@ DWRITE_SHAPING_TEXT_PROPERTIES *text_props = NULL; struct regular_layout_run *run = &r->u.regular; DWRITE_FONT_METRICS fontmetrics = { 0 }; - IDWriteFontFamily *family; - UINT32 index, max_count; - IDWriteFont *font; - BOOL exists = TRUE; + UINT32 max_count; /* we need to do very little in case of inline objects */ if (r->kind == LAYOUT_RUN_INLINE) { @@ -732,13 +820,13 @@ struct layout_cluster *c = &layout->clusters[cluster]; DWRITE_INLINE_OBJECT_METRICS inlinemetrics; - metrics->width = 0.0; + metrics->width = 0.0f; metrics->length = r->u.object.length; - metrics->canWrapLineAfter = FALSE; - metrics->isWhitespace = FALSE; - metrics->isNewline = FALSE; - metrics->isSoftHyphen = FALSE; - metrics->isRightToLeft = FALSE; + metrics->canWrapLineAfter = 0; + metrics->isWhitespace = 0; + metrics->isNewline = 0; + metrics->isSoftHyphen = 0; + metrics->isRightToLeft = 0; metrics->padding = 0; c->run = r; c->position = 0; /* there's always one cluster per inline object, so 0 is valid value */ @@ -760,26 +848,7 @@ } range = get_layout_range_by_pos(layout, run->descr.textPosition); - - hr = IDWriteFontCollection_FindFamilyName(range->collection, range->fontfamily, &index, &exists); - if (FAILED(hr) || !exists) { - WARN("%s: family %s not found in collection %p\n", debugstr_run(run), debugstr_w(range->fontfamily), range->collection); - continue; - } - - hr = IDWriteFontCollection_GetFontFamily(range->collection, index, &family); - if (FAILED(hr)) - continue; - - hr = IDWriteFontFamily_GetFirstMatchingFont(family, range->weight, range->stretch, range->style, &font); - IDWriteFontFamily_Release(family); - if (FAILED(hr)) { - WARN("%s: failed to get a matching font\n", debugstr_run(run)); - continue; - } - - hr = IDWriteFont_CreateFontFace(font, &run->run.fontFace); - IDWriteFont_Release(font); + hr = create_fontface_by_pos(layout, range, &run->run.fontFace); if (FAILED(hr)) continue; @@ -822,7 +891,7 @@ if (FAILED(hr)) { heap_free(text_props); heap_free(glyph_props); - WARN("%s: shaping failed 0x%08x\n", debugstr_run(run), hr); + WARN("%s: shaping failed 0x%08x\n", debugstr_rundescr(&run->descr), hr); continue; } @@ -850,7 +919,7 @@ heap_free(text_props); heap_free(glyph_props); if (FAILED(hr)) - WARN("%s: failed to get glyph placement info, 0x%08x\n", debugstr_run(run), hr); + WARN("%s: failed to get glyph placement info, 0x%08x\n", debugstr_rundescr(&run->descr), hr); run->run.glyphAdvances = run->advances; run->run.glyphOffsets = run->offsets; @@ -864,23 +933,10 @@ run->run.glyphCount = run->glyphcount; /* baseline derived from font metrics */ - if (is_layout_gdi_compatible(layout)) { - hr = IDWriteFontFace_GetGdiCompatibleMetrics(run->run.fontFace, - run->run.fontEmSize, - layout->ppdip, - &layout->transform, - &fontmetrics); - if (FAILED(hr)) - WARN("failed to get compat metrics, 0x%08x\n", hr); - } - else - IDWriteFontFace_GetMetrics(run->run.fontFace, &fontmetrics); - - r->baseline = get_scaled_font_metric(fontmetrics.ascent, run->run.fontEmSize, &fontmetrics); - r->height = get_scaled_font_metric(fontmetrics.ascent + fontmetrics.descent, run->run.fontEmSize, &fontmetrics); + layout_get_font_metrics(layout, run->run.fontFace, run->run.fontEmSize, &fontmetrics); + layout_get_font_height(run->run.fontEmSize, &fontmetrics, &r->baseline, &r->height); layout_set_cluster_metrics(layout, r, &cluster); - continue; memerr: @@ -900,7 +956,7 @@ if (hr == S_OK) { layout->cluster_count = cluster; if (cluster) - layout->clustermetrics[cluster-1].canWrapLineAfter = TRUE; + layout->clustermetrics[cluster-1].canWrapLineAfter = 1; } IDWriteTextAnalyzer_Release(analyzer); @@ -927,8 +983,8 @@ if (FAILED(hr)) return hr; - hr = IDWriteTextAnalyzer_AnalyzeLineBreakpoints(analyzer, &layout->IDWriteTextAnalysisSource_iface, - 0, layout->len, &layout->IDWriteTextAnalysisSink_iface); + hr = IDWriteTextAnalyzer_AnalyzeLineBreakpoints(analyzer, (IDWriteTextAnalysisSource*)&layout->IDWriteTextAnalysisSource1_iface, + 0, layout->len, (IDWriteTextAnalysisSink*)&layout->IDWriteTextAnalysisSink1_iface); IDWriteTextAnalyzer_Release(analyzer); } if (layout->actual_breakpoints) { @@ -956,7 +1012,7 @@ static inline FLOAT get_cluster_range_width(struct dwrite_textlayout *layout, UINT32 start, UINT32 end) { - FLOAT width = 0.0; + FLOAT width = 0.0f; for (; start < end; start++) width += layout->clustermetrics[start].width; return width; @@ -986,10 +1042,66 @@ return erun->run->u.regular.run.bidiLevel & 1; } +/* A set of parameters that additionally splits resulting runs. It happens after shaping and all text processing, + no glyph changes are possible. It's understandable for drawing effects, because DrawGlyphRun() reports them as + one of the arguments, but it also happens for decorations, so every effective run has uniform + underline/strikethough/effect tuple. */ +struct layout_final_splitting_params { + BOOL strikethrough; + BOOL underline; + IUnknown *effect; +}; + +static inline BOOL layout_get_strikethrough_from_pos(struct dwrite_textlayout *layout, UINT32 pos) +{ + struct layout_range_header *h = get_layout_range_header_by_pos(&layout->strike_ranges, pos); + return ((struct layout_range_bool*)h)->value; +} + +static inline BOOL layout_get_underline_from_pos(struct dwrite_textlayout *layout, UINT32 pos) +{ + struct layout_range_header *h = get_layout_range_header_by_pos(&layout->underline_ranges, pos); + return ((struct layout_range_bool*)h)->value; +} + +static void layout_splitting_params_from_pos(struct dwrite_textlayout *layout, UINT32 pos, + struct layout_final_splitting_params *params) +{ + params->strikethrough = layout_get_strikethrough_from_pos(layout, pos); + params->underline = layout_get_underline_from_pos(layout, pos); + params->effect = layout_get_effect_from_pos(layout, pos); +} + +static BOOL is_same_splitting_params(const struct layout_final_splitting_params *left, + const struct layout_final_splitting_params *right) +{ + return left->strikethrough == right->strikethrough && + left->underline == right->underline && + left->effect == right->effect; +} + +static void layout_get_erun_font_metrics(struct dwrite_textlayout *layout, struct layout_effective_run *erun, + DWRITE_FONT_METRICS *metrics) +{ + memset(metrics, 0, sizeof(*metrics)); + if (is_layout_gdi_compatible(layout)) { + HRESULT hr = IDWriteFontFace_GetGdiCompatibleMetrics( + erun->run->u.regular.run.fontFace, + erun->run->u.regular.run.fontEmSize, + layout->ppdip, + &layout->transform, + metrics); + if (FAILED(hr)) + WARN("failed to get font metrics, 0x%08x\n", hr); + } + else + IDWriteFontFace_GetMetrics(erun->run->u.regular.run.fontFace, metrics); +} + /* Effective run is built from consecutive clusters of a single nominal run, 'first_cluster' is 0 based cluster index, 'cluster_count' indicates how many clusters to add, including first one. */ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const struct layout_run *r, UINT32 first_cluster, - UINT32 cluster_count, UINT32 line, FLOAT origin_x, BOOL strikethrough) + UINT32 cluster_count, UINT32 line, FLOAT origin_x, struct layout_final_splitting_params *params) { BOOL is_rtl = layout->format.readingdir == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT; UINT32 i, start, length, last_cluster; @@ -1002,11 +1114,11 @@ if (!inlineobject) return E_OUTOFMEMORY; - inlineobject->object = r->u.object.object; + inlineobject->run = r; inlineobject->width = get_cluster_range_width(layout, first_cluster, first_cluster + cluster_count); inlineobject->origin_x = is_rtl ? origin_x - inlineobject->width : origin_x; - inlineobject->origin_y = 0.0; /* set after line is built */ - inlineobject->align_dx = 0.0; + inlineobject->origin_y = 0.0f; /* set after line is built */ + inlineobject->align_dx = 0.0f; /* It's not clear how these two are set, possibly directionality is derived from surrounding text (replaced text could have @@ -1050,8 +1162,8 @@ else run->origin_x = origin_x; - run->origin_y = 0.0; /* set after line is built */ - run->align_dx = 0.0; + run->origin_y = 0.0f; /* set after line is built */ + run->align_dx = 0.0f; run->line = line; if (r->u.regular.run.glyphCount) { @@ -1068,35 +1180,26 @@ for (i = 0; i < length; i++) run->clustermap[i] = r->u.regular.clustermap[start + i] - r->u.regular.clustermap[start]; + run->effect = params->effect; + run->underlined = params->underline; list_add_tail(&layout->eruns, &run->entry); /* Strikethrough style is guaranteed to be consistent within effective run, - it's width equals to run width, thikness and offset are derived from + its width equals to run width, thickness and offset are derived from font metrics, rest of the values are from layout or run itself */ - if (strikethrough) { - DWRITE_FONT_METRICS metrics = { 0 }; + if (params->strikethrough) { struct layout_strikethrough *s; + DWRITE_FONT_METRICS metrics; s = heap_alloc(sizeof(*s)); if (!s) return E_OUTOFMEMORY; - if (is_layout_gdi_compatible(layout)) { - HRESULT hr = IDWriteFontFace_GetGdiCompatibleMetrics( - r->u.regular.run.fontFace, - r->u.regular.run.fontEmSize, - layout->ppdip, - &layout->transform, - &metrics); - if (FAILED(hr)) - WARN("failed to get font metrics, 0x%08x\n", hr); - } - else - IDWriteFontFace_GetMetrics(r->u.regular.run.fontFace, &metrics); - + layout_get_erun_font_metrics(layout, run, &metrics); s->s.width = get_cluster_range_width(layout, first_cluster, first_cluster + cluster_count); - s->s.thickness = metrics.strikethroughThickness; - s->s.offset = metrics.strikethroughPosition; + s->s.thickness = SCALE_FONT_METRIC(metrics.strikethroughThickness, r->u.regular.run.fontEmSize, &metrics); + /* Negative offset moves it above baseline as Y coordinate grows downward. */ + s->s.offset = -SCALE_FONT_METRIC(metrics.strikethroughPosition, r->u.regular.run.fontEmSize, &metrics); s->s.readingDirection = layout->format.readingdir; s->s.flowDirection = layout->format.flow; s->s.localeName = r->u.regular.descr.localeName; @@ -1132,11 +1235,6 @@ return S_OK; } -static inline BOOL layout_get_strikethrough_from_pos(struct dwrite_textlayout *layout, UINT32 pos) -{ - struct layout_range_header *h = get_layout_range_header_by_pos(&layout->strike_ranges, pos); - return ((struct layout_range_bool*)h)->value; -} static inline struct layout_effective_run *layout_get_next_erun(struct dwrite_textlayout *layout, const struct layout_effective_run *cur) @@ -1152,6 +1250,20 @@ return LIST_ENTRY(e, struct layout_effective_run, entry); } +static inline struct layout_effective_run *layout_get_prev_erun(struct dwrite_textlayout *layout, + const struct layout_effective_run *cur) +{ + struct list *e; + + if (!cur) + e = list_tail(&layout->eruns); + else + e = list_prev(&layout->eruns, &cur->entry); + if (!e) + return NULL; + return LIST_ENTRY(e, struct layout_effective_run, entry); +} + static inline struct layout_effective_inline *layout_get_next_inline_run(struct dwrite_textlayout *layout, const struct layout_effective_inline *cur) { @@ -1169,7 +1281,7 @@ static FLOAT layout_get_line_width(struct dwrite_textlayout *layout, struct layout_effective_run *erun, struct layout_effective_inline *inrun, UINT32 line) { - FLOAT width = 0.0; + FLOAT width = 0.0f; while (erun && erun->line == line) { width += erun->width; @@ -1235,16 +1347,16 @@ inrun = layout_get_next_inline_run(layout, NULL); while (erun) { - erun->align_dx = 0.0; + erun->align_dx = 0.0f; erun = layout_get_next_erun(layout, erun); } while (inrun) { - inrun->align_dx = 0.0; + inrun->align_dx = 0.0f; inrun = layout_get_next_inline_run(layout, inrun); } - layout->metrics.left = is_rtl ? layout->metrics.layoutWidth - layout->metrics.width : 0.0; + layout->metrics.left = is_rtl ? layout->metrics.layoutWidth - layout->metrics.width : 0.0f; } static void layout_apply_trailing_alignment(struct dwrite_textlayout *layout) @@ -1262,7 +1374,7 @@ FLOAT shift = layout->metrics.layoutWidth - width; if (is_rtl) - shift *= -1.0; + shift *= -1.0f; while (erun && erun->line == line) { erun->align_dx = shift; @@ -1275,14 +1387,14 @@ } } - layout->metrics.left = is_rtl ? 0.0 : layout->metrics.layoutWidth - layout->metrics.width; + layout->metrics.left = is_rtl ? 0.0f : layout->metrics.layoutWidth - layout->metrics.width; } static inline FLOAT layout_get_centered_shift(struct dwrite_textlayout *layout, BOOL skiptransform, FLOAT width, FLOAT det) { if (is_layout_gdi_compatible(layout)) { - struct dwrite_vec vec = { layout->metrics.layoutWidth - width, 0.0 }; + struct dwrite_vec vec = { layout->metrics.layoutWidth - width, 0.0f}; layout_apply_snapping(&vec, skiptransform, layout->ppdip, &layout->transform, det); return floorf(vec.x / 2.0f); } @@ -1309,7 +1421,7 @@ FLOAT shift = layout_get_centered_shift(layout, skiptransform, width, det); if (is_rtl) - shift *= -1.0; + shift *= -1.0f; while (erun && erun->line == line) { erun->align_dx = shift; @@ -1322,7 +1434,7 @@ } } - layout->metrics.left = (layout->metrics.layoutWidth - layout->metrics.width) / 2.0; + layout->metrics.left = (layout->metrics.layoutWidth - layout->metrics.width) / 2.0f; } static void layout_apply_text_alignment(struct dwrite_textlayout *layout) @@ -1350,7 +1462,7 @@ { struct layout_effective_inline *inrun; struct layout_effective_run *erun; - FLOAT origin_y = 0.0; + FLOAT origin_y = 0.0f; UINT32 line; /* alignment mode defines origin, after that all run origins are updated @@ -1359,13 +1471,13 @@ switch (layout->format.paralign) { case DWRITE_PARAGRAPH_ALIGNMENT_NEAR: - origin_y = 0.0; + origin_y = 0.0f; break; case DWRITE_PARAGRAPH_ALIGNMENT_FAR: origin_y = layout->metrics.layoutHeight - layout->metrics.height; break; case DWRITE_PARAGRAPH_ALIGNMENT_CENTER: - origin_y = (layout->metrics.layoutHeight - layout->metrics.height) / 2.0; + origin_y = (layout->metrics.layoutHeight - layout->metrics.height) / 2.0f; break; default: ; @@ -1384,23 +1496,143 @@ } while (inrun && inrun->line == line) { - inrun->origin_y = origin_y; + inrun->origin_y = origin_y - inrun->run->baseline; inrun = layout_get_next_inline_run(layout, inrun); } } } +struct layout_underline_splitting_params { + const WCHAR *locale; /* points to range data, no additional allocation */ + IUnknown *effect; /* does not hold another reference */ +}; + +static void init_u_splitting_params_from_erun(struct layout_effective_run *erun, + struct layout_underline_splitting_params *params) +{ + params->locale = erun->run->u.regular.descr.localeName; + params->effect = erun->effect; +} + +static BOOL is_same_u_splitting(struct layout_underline_splitting_params *left, + struct layout_underline_splitting_params *right) +{ + return left->effect == right->effect && !strcmpiW(left->locale, right->locale); +} + +static HRESULT layout_add_underline(struct dwrite_textlayout *layout, struct layout_effective_run *first, + struct layout_effective_run *last) +{ + struct layout_effective_run *cur; + DWRITE_FONT_METRICS metrics; + FLOAT thickness, offset; + + if (first == layout_get_prev_erun(layout, last)) { + layout_get_erun_font_metrics(layout, first, &metrics); + thickness = SCALE_FONT_METRIC(metrics.underlineThickness, first->run->u.regular.run.fontEmSize, &metrics); + offset = SCALE_FONT_METRIC(metrics.underlinePosition, first->run->u.regular.run.fontEmSize, &metrics); + } + else { + FLOAT width = 0.0f; + + /* Single underline is added for consecutive underlined runs. In this case underline parameters are + calculated as weighted average, where run width acts as a weight. */ + thickness = offset = 0.0f; + cur = first; + do { + layout_get_erun_font_metrics(layout, cur, &metrics); + + thickness += SCALE_FONT_METRIC(metrics.underlineThickness, cur->run->u.regular.run.fontEmSize, &metrics) * cur->width; + offset += SCALE_FONT_METRIC(metrics.underlinePosition, cur->run->u.regular.run.fontEmSize, &metrics) * cur->width; + width += cur->width; + + cur = layout_get_next_erun(layout, cur); + } while (cur != last); + + thickness /= width; + offset /= width; + } + + cur = first; + do { + struct layout_underline_splitting_params params, prev_params; + struct layout_effective_run *next, *w; + struct layout_underline *u; + + init_u_splitting_params_from_erun(cur, &prev_params); + while ((next = layout_get_next_erun(layout, cur)) != last) { + init_u_splitting_params_from_erun(next, ¶ms); + if (!is_same_u_splitting(&prev_params, ¶ms)) + break; + cur = next; + } + + u = heap_alloc(sizeof(*u)); + if (!u) + return E_OUTOFMEMORY; + + w = cur; + u->u.width = 0.0f; + while (w != next) { + u->u.width += w->width; + w = layout_get_next_erun(layout, w); + } + + u->u.thickness = thickness; + /* Font metrics convention is to have it negative when below baseline, for rendering + however Y grows from baseline down for horizontal baseline. */ + u->u.offset = -offset; + u->u.runHeight = 0.0f; /* FIXME */ + u->u.readingDirection = is_run_rtl(cur) ? DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : + DWRITE_READING_DIRECTION_LEFT_TO_RIGHT; + u->u.flowDirection = layout->format.flow; + u->u.localeName = cur->run->u.regular.descr.localeName; + u->u.measuringMode = layout->measuringmode; + u->run = cur; + list_add_tail(&layout->underlines, &u->entry); + + cur = next; + } while (cur != last); + + return S_OK; +} + +/* Adds zero width line, metrics are derived from font at specified text position. */ +static HRESULT layout_set_dummy_line_metrics(struct dwrite_textlayout *layout, UINT32 pos, UINT32 *line) +{ + DWRITE_FONT_METRICS fontmetrics; + DWRITE_LINE_METRICS metrics; + struct layout_range *range; + IDWriteFontFace *fontface; + HRESULT hr; + + range = get_layout_range_by_pos(layout, pos); + hr = create_fontface_by_pos(layout, range, &fontface); + if (FAILED(hr)) + return hr; + + layout_get_font_metrics(layout, fontface, range->fontsize, &fontmetrics); + layout_get_font_height(range->fontsize, &fontmetrics, &metrics.baseline, &metrics.height); + IDWriteFontFace_Release(fontface); + + metrics.length = 0; + metrics.trailingWhitespaceLength = 0; + metrics.newlineLength = 0; + metrics.isTrimmed = FALSE; + return layout_set_line_metrics(layout, &metrics, line); +} + static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout) { BOOL is_rtl = layout->format.readingdir == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT; + struct layout_final_splitting_params prev_params, params; + struct layout_effective_run *erun, *first_underlined; struct layout_effective_inline *inrun; - struct layout_effective_run *erun; const struct layout_run *run; DWRITE_LINE_METRICS metrics; FLOAT width, origin_x, origin_y; UINT32 i, start, line, textpos; HRESULT hr; - BOOL s[2]; if (!(layout->recompute & RECOMPUTE_EFFECTIVE_RUNS)) return S_OK; @@ -1410,21 +1642,23 @@ return hr; layout->metrics.lineCount = 0; - origin_x = is_rtl ? layout->metrics.layoutWidth : 0.0; + origin_x = is_rtl ? layout->metrics.layoutWidth : 0.0f; line = 0; run = layout->clusters[0].run; memset(&metrics, 0, sizeof(metrics)); - s[0] = s[1] = layout_get_strikethrough_from_pos(layout, 0); - for (i = 0, start = 0, textpos = 0, width = 0.0; i < layout->cluster_count; i++) { + layout_splitting_params_from_pos(layout, 0, ¶ms); + prev_params = params; + + for (i = 0, start = 0, textpos = 0, width = 0.0f; i < layout->cluster_count; i++) { BOOL overflow; - s[1] = layout_get_strikethrough_from_pos(layout, textpos); + layout_splitting_params_from_pos(layout, textpos, ¶ms); /* switched to next nominal run, at this point all previous pending clusters are already checked for layout line overflow, so new effective run will fit in current line */ - if (run != layout->clusters[i].run || s[0] != s[1]) { - hr = layout_add_effective_run(layout, run, start, i - start, line, origin_x, s[0]); + if (run != layout->clusters[i].run || !is_same_splitting_params(&prev_params, ¶ms)) { + hr = layout_add_effective_run(layout, run, start, i - start, line, origin_x, &prev_params); if (FAILED(hr)) return hr; origin_x += is_rtl ? -get_cluster_range_width(layout, start, i) : @@ -1434,7 +1668,8 @@ } overflow = layout->clustermetrics[i].canWrapLineAfter && - (width + layout->clustermetrics[i].width > layout->metrics.layoutWidth); + (width + layout->clustermetrics[i].width > layout->metrics.layoutWidth) && + (layout->format.wrapping != DWRITE_WORD_WRAPPING_NO_WRAP); /* check if we got new */ if (overflow || layout->clustermetrics[i].isNewline || /* always wrap on new line */ @@ -1442,17 +1677,21 @@ UINT32 strlength, last_cluster, index; FLOAT descent, trailingspacewidth; + struct layout_final_splitting_params *p; if (!overflow) { width += layout->clustermetrics[i].width; metrics.length += layout->clustermetrics[i].length; last_cluster = i; + p = ¶ms; } - else + else { last_cluster = i ? i - 1 : i; + p = &prev_params; + } if (i >= start) { - hr = layout_add_effective_run(layout, run, start, last_cluster - start + 1, line, origin_x, s[0]); + hr = layout_add_effective_run(layout, run, start, last_cluster - start + 1, line, origin_x, p); if (FAILED(hr)) return hr; /* we don't need to update origin for next run as we're going to wrap */ @@ -1462,22 +1701,25 @@ trailing properties for current line */ strlength = metrics.length; index = last_cluster; - trailingspacewidth = 0.0; + trailingspacewidth = 0.0f; while (strlength) { DWRITE_CLUSTER_METRICS *cluster = &layout->clustermetrics[index]; + struct layout_cluster *lc = &layout->clusters[index]; + WCHAR ch; - if (!cluster->isNewline && !cluster->isWhitespace) + /* This also filters out clusters added from inline objects, those are never + treated as a white space. */ + if (!cluster->isWhitespace) break; - if (cluster->isNewline) { - metrics.trailingWhitespaceLength += cluster->length; + /* Every isNewline cluster is also isWhitespace, but not every + newline character cluster has isNewline set, so go back to original string. */ + ch = lc->run->u.regular.descr.string[lc->position]; + if (cluster->length == 1 && lb_is_newline_char(ch)) metrics.newlineLength += cluster->length; - } - if (cluster->isWhitespace) { - metrics.trailingWhitespaceLength += cluster->length; - trailingspacewidth += cluster->width; - } + metrics.trailingWhitespaceLength += cluster->length; + trailingspacewidth += cluster->width; strlength -= cluster->length; index--; @@ -1486,8 +1728,8 @@ /* look for max baseline and descent for this line */ strlength = metrics.length; index = last_cluster; - metrics.baseline = 0.0; - descent = 0.0; + metrics.baseline = 0.0f; + descent = 0.0f; while (strlength) { DWRITE_CLUSTER_METRICS *cluster = &layout->clustermetrics[index]; const struct layout_run *cur = layout->clusters[index].run; @@ -1516,7 +1758,7 @@ width = layout->clustermetrics[i].width; memset(&metrics, 0, sizeof(metrics)); - origin_x = is_rtl ? layout->metrics.layoutWidth : 0.0; + origin_x = is_rtl ? layout->metrics.layoutWidth : 0.0f; start = i; } else { @@ -1524,20 +1766,33 @@ width += layout->clustermetrics[i].width; } - s[0] = s[1]; + prev_params = params; textpos += layout->clustermetrics[i].length; } - layout->metrics.left = is_rtl ? layout->metrics.layoutWidth - layout->metrics.width : 0; - layout->metrics.top = 0.0; + /* Add dummy line if: + - there's no text, metrics come from first range in this case; + - last ended with a mandatory break, metrics come from last text position. + */ + if (layout->len == 0) + hr = layout_set_dummy_line_metrics(layout, 0, &line); + else if (layout->clustermetrics[layout->cluster_count-1].isNewline) + hr = layout_set_dummy_line_metrics(layout, layout->len-1, &line); + if (FAILED(hr)) + return hr; + + layout->metrics.left = is_rtl ? layout->metrics.layoutWidth - layout->metrics.width : 0.0f; + layout->metrics.top = 0.0f; layout->metrics.maxBidiReorderingDepth = 1; /* FIXME */ - layout->metrics.height = 0.0; + layout->metrics.height = 0.0f; /* Now all line info is here, update effective runs positions in flow direction */ erun = layout_get_next_erun(layout, NULL); + first_underlined = erun && erun->underlined ? erun : NULL; + inrun = layout_get_next_inline_run(layout, NULL); - origin_y = 0.0; + origin_y = 0.0f; for (line = 0; line < layout->metrics.lineCount; line++) { origin_y += layout->lines[line].baseline; @@ -1546,11 +1801,18 @@ while (erun && erun->line == line) { erun->origin_y = origin_y; erun = layout_get_next_erun(layout, erun); + + if (first_underlined && (!erun || !erun->underlined)) { + layout_add_underline(layout, first_underlined, erun); + first_underlined = NULL; + } + else if (!first_underlined && erun && erun->underlined) + first_underlined = erun; } /* Same for inline runs */ while (inrun && inrun->line == line) { - inrun->origin_y = origin_y; + inrun->origin_y = origin_y - inrun->run->baseline; inrun = layout_get_next_inline_run(layout, inrun); } @@ -1592,7 +1854,7 @@ case LAYOUT_RANGE_ATTR_EFFECT: return range_iface->iface == value->u.effect; case LAYOUT_RANGE_ATTR_UNDERLINE: - return range->underline == value->u.underline; + return range_bool->value == value->u.underline; case LAYOUT_RANGE_ATTR_STRIKETHROUGH: return range_bool->value == value->u.strikethrough; case LAYOUT_RANGE_ATTR_PAIR_KERNING: @@ -1629,12 +1891,12 @@ left->stretch == right->stretch && left->fontsize == right->fontsize && left->object == right->object && - left->underline == right->underline && left->pair_kerning == right->pair_kerning && left->collection == right->collection && !strcmpiW(left->locale, right->locale) && !strcmpW(left->fontfamily, right->fontfamily); } + case LAYOUT_RANGE_UNDERLINE: case LAYOUT_RANGE_STRIKETHROUGH: { struct layout_range_bool const *left = (struct layout_range_bool const*)hleft; @@ -1687,7 +1949,6 @@ range->stretch = layout->format.stretch; range->fontsize = layout->format.fontsize; range->object = NULL; - range->underline = FALSE; range->pair_kerning = FALSE; range->fontfamily = heap_strdupW(layout->format.family_name); @@ -1704,6 +1965,7 @@ h = &range->h; break; } + case LAYOUT_RANGE_UNDERLINE: case LAYOUT_RANGE_STRIKETHROUGH: { struct layout_range_bool *range; @@ -1734,9 +1996,9 @@ range = heap_alloc(sizeof(*range)); if (!range) return NULL; - range->leading = 0.0; - range->trailing = 0.0; - range->min_advance = 0.0; + range->leading = 0.0f; + range->trailing = 0.0f; + range->min_advance = 0.0f; h = &range->h; break; } @@ -1778,6 +2040,7 @@ ret = &range->h; break; } + case LAYOUT_RANGE_UNDERLINE: case LAYOUT_RANGE_STRIKETHROUGH: { struct layout_range_bool *strike = heap_alloc(sizeof(*strike)); @@ -1859,6 +2122,11 @@ free_layout_range(cur); } + LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->underline_ranges, struct layout_range_header, entry) { + list_remove(&cur->entry); + free_layout_range(cur); + } + LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &layout->strike_ranges, struct layout_range_header, entry) { list_remove(&cur->entry); free_layout_range(cur); @@ -1958,8 +2226,8 @@ changed = set_layout_range_iface_attr((IUnknown**)&dest_iface->iface, (IUnknown*)value->u.effect); break; case LAYOUT_RANGE_ATTR_UNDERLINE: - changed = dest->underline != value->u.underline; - dest->underline = value->u.underline; + changed = dest_bool->value != value->u.underline; + dest_bool->value = value->u.underline; break; case LAYOUT_RANGE_ATTR_STRIKETHROUGH: changed = dest_bool->value != value->u.strikethrough; @@ -1974,8 +2242,10 @@ break; case LAYOUT_RANGE_ATTR_LOCALE: changed = strcmpiW(dest->locale, value->u.locale) != 0; - if (changed) + if (changed) { strcpyW(dest->locale, value->u.locale); + strlwrW(dest->locale); + } break; case LAYOUT_RANGE_ATTR_FONTFAMILY: changed = strcmpW(dest->fontfamily, value->u.fontfamily) != 0; @@ -2014,7 +2284,7 @@ return S_OK; } -/* Set attribute value for given range, does all needed splitting/merging of existing ranges. */ +/* Sets attribute value for given range, does all needed splitting/merging of existing ranges. */ static HRESULT set_layout_range_attr(struct dwrite_textlayout *layout, enum layout_range_attr_kind attr, struct layout_range_attr_value *value) { struct layout_range_header *cur, *right, *left, *outer; @@ -2034,13 +2304,15 @@ case LAYOUT_RANGE_ATTR_STRETCH: case LAYOUT_RANGE_ATTR_FONTSIZE: case LAYOUT_RANGE_ATTR_INLINE: - case LAYOUT_RANGE_ATTR_UNDERLINE: case LAYOUT_RANGE_ATTR_PAIR_KERNING: case LAYOUT_RANGE_ATTR_FONTCOLL: case LAYOUT_RANGE_ATTR_LOCALE: case LAYOUT_RANGE_ATTR_FONTFAMILY: ranges = &layout->ranges; break; + case LAYOUT_RANGE_ATTR_UNDERLINE: + ranges = &layout->underline_ranges; + break; case LAYOUT_RANGE_ATTR_STRIKETHROUGH: ranges = &layout->strike_ranges; break; @@ -2116,6 +2388,7 @@ list_add_after(&outer->entry, &cur->entry); list_add_after(&cur->entry, &right->entry); + layout->recompute = RECOMPUTE_EVERYTHING; return S_OK; } @@ -2455,7 +2728,7 @@ TRACE("(%p)->(%.2f)\n", This, maxWidth); - if (maxWidth < 0.0) + if (maxWidth < 0.0f) return E_INVALIDARG; This->metrics.layoutWidth = maxWidth; @@ -2468,7 +2741,7 @@ TRACE("(%p)->(%.2f)\n", This, maxHeight); - if (maxHeight < 0.0) + if (maxHeight < 0.0f) return E_INVALIDARG; This->metrics.layoutHeight = maxHeight; @@ -2551,7 +2824,7 @@ TRACE("(%p)->(%.2f %s)\n", This, size, debugstr_range(&range)); - if (size <= 0.0) + if (size <= 0.0f) return E_INVALIDARG; value.range = range; @@ -2743,15 +3016,12 @@ UINT32 position, BOOL *underline, DWRITE_TEXT_RANGE *r) { struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface); - struct layout_range *range; + struct layout_range_bool *range; TRACE("(%p)->(%u %p %p)\n", This, position, underline, r); - if (position >= This->len) - return S_OK; - - range = get_layout_range_by_pos(This, position); - *underline = range->underline; + range = (struct layout_range_bool*)get_layout_range_header_by_pos(&This->underline_ranges, position); + *underline = range->value; return return_range(&range->h, r); } @@ -2844,7 +3114,7 @@ if (!skiptransform) { /* apply transform */ - vec[0] = 0.0; + vec[0] = 0.0f; vec[1] = coord * ppdip; vec2[0] = m->m11 * vec[0] + m->m21 * vec[1] + m->dx; @@ -2872,7 +3142,8 @@ struct layout_effective_inline *inlineobject; struct layout_effective_run *run; struct layout_strikethrough *s; - FLOAT det = 0.0, ppdip = 0.0; + struct layout_underline *u; + FLOAT det = 0.0f, ppdip = 0.0f; DWRITE_MATRIX m = { 0 }; HRESULT hr; @@ -2896,15 +3167,15 @@ return hr; /* it's only allowed to have a diagonal/antidiagonal transform matrix */ - if (ppdip <= 0.0 || - (m.m11 * m.m22 != 0.0 && (m.m12 != 0.0 || m.m21 != 0.0)) || - (m.m12 * m.m21 != 0.0 && (m.m11 != 0.0 || m.m22 != 0.0))) + if (ppdip <= 0.0f || + (m.m11 * m.m22 != 0.0f && (m.m12 != 0.0f || m.m21 != 0.0f)) || + (m.m12 * m.m21 != 0.0f && (m.m11 != 0.0f || m.m22 != 0.0f))) disabled = TRUE; else skiptransform = should_skip_transform(&m, &det); } -#define SNAP_COORD(x) renderer_apply_snapping((x), skiptransform, ppdip, det, &m) +#define SNAP_COORD(x) (disabled ? (x) : renderer_apply_snapping((x), skiptransform, ppdip, det, &m)) /* 1. Regular runs */ LIST_FOR_EACH_ENTRY(run, &This->eruns, struct layout_effective_run, entry) { const struct regular_layout_run *regular = &run->run->u.regular; @@ -2934,11 +3205,11 @@ IDWriteTextRenderer_DrawGlyphRun(renderer, context, run->origin_x + run->align_dx + origin_x, - disabled ? run->origin_y + origin_y : SNAP_COORD(run->origin_y + origin_y), + SNAP_COORD(run->origin_y + origin_y), This->measuringmode, &glyph_run, &descr, - NULL); + run->effect); } /* 2. Inline objects */ @@ -2946,23 +3217,32 @@ IDWriteTextRenderer_DrawInlineObject(renderer, context, inlineobject->origin_x + inlineobject->align_dx + origin_x, - disabled ? inlineobject->origin_y + origin_y : SNAP_COORD(inlineobject->origin_y + origin_y), - inlineobject->object, + SNAP_COORD(inlineobject->origin_y + origin_y), + inlineobject->run->u.object.object, inlineobject->is_sideways, inlineobject->is_rtl, inlineobject->effect); } - /* TODO: 3. Underlines */ + /* 3. Underlines */ + LIST_FOR_EACH_ENTRY(u, &This->underlines, struct layout_underline, entry) { + IDWriteTextRenderer_DrawUnderline(renderer, + context, + /* horizontal underline always grows from left to right, width is always added to origin regardless of run direction */ + (is_run_rtl(u->run) ? u->run->origin_x - u->run->width : u->run->origin_x) + u->run->align_dx + origin_x, + SNAP_COORD(u->run->origin_y + origin_y), + &u->u, + u->run->effect); + } /* 4. Strikethrough */ LIST_FOR_EACH_ENTRY(s, &This->strikethrough, struct layout_strikethrough, entry) { IDWriteTextRenderer_DrawStrikethrough(renderer, context, - s->run->origin_x, - disabled ? s->run->origin_y : SNAP_COORD(s->run->origin_y), + s->run->origin_x + s->run->align_dx + origin_x, + SNAP_COORD(s->run->origin_y + origin_y), &s->s, - NULL); + s->run->effect); } #undef SNAP_COORD @@ -3029,23 +3309,12 @@ return max_count >= This->cluster_count ? S_OK : E_NOT_SUFFICIENT_BUFFER; } -/* Only to be used with DetermineMinWidth() to find the longest cluster sequence that we don't want to try - too hard to break. */ -static inline BOOL is_terminal_cluster(struct dwrite_textlayout *layout, UINT32 index) -{ - if (layout->clustermetrics[index].isWhitespace || layout->clustermetrics[index].isNewline || - (index == layout->cluster_count - 1)) - return TRUE; - /* check next one */ - return (index < layout->cluster_count - 1) && layout->clustermetrics[index+1].isWhitespace; -} - static HRESULT WINAPI dwritetextlayout_DetermineMinWidth(IDWriteTextLayout2 *iface, FLOAT* min_width) { struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface); + UINT32 start; FLOAT width; HRESULT hr; - UINT32 i; TRACE("(%p)->(%p)\n", This, min_width); @@ -3055,25 +3324,35 @@ if (!(This->recompute & RECOMPUTE_MINIMAL_WIDTH)) goto width_done; - *min_width = 0.0; + *min_width = 0.0f; hr = layout_compute(This); if (FAILED(hr)) return hr; - for (i = 0; i < This->cluster_count;) { - if (is_terminal_cluster(This, i)) { - width = This->clustermetrics[i].width; - i++; - } - else { - width = 0.0; - while (!is_terminal_cluster(This, i)) { - width += This->clustermetrics[i].width; - i++; - } - /* count last one too */ - width += This->clustermetrics[i].width; - } + /* Find widest word without emergency breaking between clusters, trailing whitespaces + preceding breaking point do not contribute to word width. */ + for (start = 0; start < This->cluster_count;) { + UINT32 end = start, j, next; + + /* Last cluster always could be wrapped after. */ + while (!This->clustermetrics[end].canWrapLineAfter) + end++; + /* make is so current cluster range that we can wrap after is [start,end) */ + end++; + + next = end; + + /* Ignore trailing whitespace clusters, in case of single space range will + be reduced to empty range, or [start,start+1). */ + while (end > start && This->clustermetrics[end-1].isWhitespace) + end--; + + /* check if cluster range exceeds last minimal width */ + width = 0.0f; + for (j = start; j < end; j++) + width += This->clustermetrics[j].width; + + start = next; if (width > This->minwidth) This->minwidth = width; @@ -3149,7 +3428,7 @@ TRACE("(%p)->(%.2f %.2f %.2f %s)\n", This, leading, trailing, min_advance, debugstr_range(&range)); - if (min_advance < 0.0) + if (min_advance < 0.0f) return E_INVALIDARG; value.range = range; @@ -3431,8 +3710,19 @@ static HRESULT WINAPI dwritetextformat1_layout_SetFlowDirection(IDWriteTextFormat1 *iface, DWRITE_FLOW_DIRECTION direction) { struct dwrite_textlayout *This = impl_layout_form_IDWriteTextFormat1(iface); - FIXME("(%p)->(%d): stub\n", This, direction); - return E_NOTIMPL; + BOOL changed; + HRESULT hr; + + TRACE("(%p)->(%d)\n", This, direction); + + hr = format_set_flowdirection(&This->format, direction, &changed); + if (FAILED(hr)) + return hr; + + if (changed) + This->recompute = RECOMPUTE_EVERYTHING; + + return S_OK; } static HRESULT WINAPI dwritetextformat1_layout_SetIncrementalTabStop(IDWriteTextFormat1 *iface, FLOAT tabstop) @@ -3450,12 +3740,23 @@ return E_NOTIMPL; } -static HRESULT WINAPI dwritetextformat1_layout_SetLineSpacing(IDWriteTextFormat1 *iface, DWRITE_LINE_SPACING_METHOD spacing, - FLOAT line_spacing, FLOAT baseline) +static HRESULT WINAPI dwritetextformat1_layout_SetLineSpacing(IDWriteTextFormat1 *iface, DWRITE_LINE_SPACING_METHOD method, + FLOAT spacing, FLOAT baseline) { struct dwrite_textlayout *This = impl_layout_form_IDWriteTextFormat1(iface); - FIXME("(%p)->(%d %f %f): stub\n", This, spacing, line_spacing, baseline); - return E_NOTIMPL; + BOOL changed; + HRESULT hr; + + TRACE("(%p)->(%d %f %f)\n", This, method, spacing, baseline); + + hr = format_set_linespacing(&This->format, method, spacing, baseline, &changed); + if (FAILED(hr)) + return hr; + + if (changed) + This->recompute = RECOMPUTE_EVERYTHING; + + return S_OK; } static DWRITE_TEXT_ALIGNMENT WINAPI dwritetextformat1_layout_GetTextAlignment(IDWriteTextFormat1 *iface) @@ -3497,7 +3798,7 @@ { struct dwrite_textlayout *This = impl_layout_form_IDWriteTextFormat1(iface); FIXME("(%p): stub\n", This); - return 0.0; + return 0.0f; } static HRESULT WINAPI dwritetextformat1_layout_GetTrimming(IDWriteTextFormat1 *iface, DWRITE_TRIMMING *options, @@ -3701,12 +4002,15 @@ dwritetextformat1_layout_GetFontFallback }; -static HRESULT WINAPI dwritetextlayout_sink_QueryInterface(IDWriteTextAnalysisSink *iface, +static HRESULT WINAPI dwritetextlayout_sink_QueryInterface(IDWriteTextAnalysisSink1 *iface, REFIID riid, void **obj) { - if (IsEqualIID(riid, &IID_IDWriteTextAnalysisSink) || IsEqualIID(riid, &IID_IUnknown)) { + if (IsEqualIID(riid, &IID_IDWriteTextAnalysisSink1) || + IsEqualIID(riid, &IID_IDWriteTextAnalysisSink) || + IsEqualIID(riid, &IID_IUnknown)) + { *obj = iface; - IDWriteTextAnalysisSink_AddRef(iface); + IDWriteTextAnalysisSink1_AddRef(iface); return S_OK; } @@ -3714,23 +4018,25 @@ return E_NOINTERFACE; } -static ULONG WINAPI dwritetextlayout_sink_AddRef(IDWriteTextAnalysisSink *iface) +static ULONG WINAPI dwritetextlayout_sink_AddRef(IDWriteTextAnalysisSink1 *iface) { - return 2; + struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink1(iface); + return IDWriteTextLayout2_AddRef(&layout->IDWriteTextLayout2_iface); } -static ULONG WINAPI dwritetextlayout_sink_Release(IDWriteTextAnalysisSink *iface) +static ULONG WINAPI dwritetextlayout_sink_Release(IDWriteTextAnalysisSink1 *iface) { - return 1; + struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink1(iface); + return IDWriteTextLayout2_Release(&layout->IDWriteTextLayout2_iface); } -static HRESULT WINAPI dwritetextlayout_sink_SetScriptAnalysis(IDWriteTextAnalysisSink *iface, +static HRESULT WINAPI dwritetextlayout_sink_SetScriptAnalysis(IDWriteTextAnalysisSink1 *iface, UINT32 position, UINT32 length, DWRITE_SCRIPT_ANALYSIS const* sa) { - struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink(iface); + struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink1(iface); struct layout_run *run; - TRACE("%u %u script=%d\n", position, length, sa->script); + TRACE("[%u,%u) script=%u:%s\n", position, position + length, sa->script, debugstr_sa_script(sa->script)); run = alloc_layout_run(LAYOUT_RUN_REGULAR); if (!run) @@ -3744,10 +4050,10 @@ return S_OK; } -static HRESULT WINAPI dwritetextlayout_sink_SetLineBreakpoints(IDWriteTextAnalysisSink *iface, +static HRESULT WINAPI dwritetextlayout_sink_SetLineBreakpoints(IDWriteTextAnalysisSink1 *iface, UINT32 position, UINT32 length, DWRITE_LINE_BREAKPOINT const* breakpoints) { - struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink(iface); + struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink1(iface); if (position + length > layout->len) return E_FAIL; @@ -3756,13 +4062,13 @@ return S_OK; } -static HRESULT WINAPI dwritetextlayout_sink_SetBidiLevel(IDWriteTextAnalysisSink *iface, UINT32 position, +static HRESULT WINAPI dwritetextlayout_sink_SetBidiLevel(IDWriteTextAnalysisSink1 *iface, UINT32 position, UINT32 length, UINT8 explicitLevel, UINT8 resolvedLevel) { - struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink(iface); + struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink1(iface); struct layout_run *cur_run; - TRACE("%u %u %u %u\n", position, length, explicitLevel, resolvedLevel); + TRACE("[%u,%u) %u %u\n", position, position + length, explicitLevel, resolvedLevel); LIST_FOR_EACH_ENTRY(cur_run, &layout->runs, struct layout_run, entry) { struct regular_layout_run *cur = &cur_run->u.regular; @@ -3812,30 +4118,39 @@ return S_OK; } -static HRESULT WINAPI dwritetextlayout_sink_SetNumberSubstitution(IDWriteTextAnalysisSink *iface, +static HRESULT WINAPI dwritetextlayout_sink_SetNumberSubstitution(IDWriteTextAnalysisSink1 *iface, UINT32 position, UINT32 length, IDWriteNumberSubstitution* substitution) { return E_NOTIMPL; } -static const IDWriteTextAnalysisSinkVtbl dwritetextlayoutsinkvtbl = { +static HRESULT WINAPI dwritetextlayout_sink_SetGlyphOrientation(IDWriteTextAnalysisSink1 *iface, + UINT32 position, UINT32 length, DWRITE_GLYPH_ORIENTATION_ANGLE angle, UINT8 adjusted_bidi_level, + BOOL is_sideways, BOOL is_rtl) +{ + return E_NOTIMPL; +} + +static const IDWriteTextAnalysisSink1Vtbl dwritetextlayoutsinkvtbl = { dwritetextlayout_sink_QueryInterface, dwritetextlayout_sink_AddRef, dwritetextlayout_sink_Release, dwritetextlayout_sink_SetScriptAnalysis, dwritetextlayout_sink_SetLineBreakpoints, dwritetextlayout_sink_SetBidiLevel, - dwritetextlayout_sink_SetNumberSubstitution + dwritetextlayout_sink_SetNumberSubstitution, + dwritetextlayout_sink_SetGlyphOrientation }; -static HRESULT WINAPI dwritetextlayout_source_QueryInterface(IDWriteTextAnalysisSource *iface, +static HRESULT WINAPI dwritetextlayout_source_QueryInterface(IDWriteTextAnalysisSource1 *iface, REFIID riid, void **obj) { - if (IsEqualIID(riid, &IID_IDWriteTextAnalysisSource) || + if (IsEqualIID(riid, &IID_IDWriteTextAnalysisSource1) || + IsEqualIID(riid, &IID_IDWriteTextAnalysisSource) || IsEqualIID(riid, &IID_IUnknown)) { *obj = iface; - IDWriteTextAnalysisSource_AddRef(iface); + IDWriteTextAnalysisSource1_AddRef(iface); return S_OK; } @@ -3843,20 +4158,22 @@ return E_NOINTERFACE; } -static ULONG WINAPI dwritetextlayout_source_AddRef(IDWriteTextAnalysisSource *iface) +static ULONG WINAPI dwritetextlayout_source_AddRef(IDWriteTextAnalysisSource1 *iface) { - return 2; + struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface); + return IDWriteTextLayout2_AddRef(&layout->IDWriteTextLayout2_iface); } -static ULONG WINAPI dwritetextlayout_source_Release(IDWriteTextAnalysisSource *iface) +static ULONG WINAPI dwritetextlayout_source_Release(IDWriteTextAnalysisSource1 *iface) { - return 1; + struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface); + return IDWriteTextLayout2_Release(&layout->IDWriteTextLayout2_iface); } -static HRESULT WINAPI dwritetextlayout_source_GetTextAtPosition(IDWriteTextAnalysisSource *iface, +static HRESULT WINAPI dwritetextlayout_source_GetTextAtPosition(IDWriteTextAnalysisSource1 *iface, UINT32 position, WCHAR const** text, UINT32* text_len) { - struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource(iface); + struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface); TRACE("(%p)->(%u %p %p)\n", layout, position, text, text_len); @@ -3872,34 +4189,74 @@ return S_OK; } -static HRESULT WINAPI dwritetextlayout_source_GetTextBeforePosition(IDWriteTextAnalysisSource *iface, +static HRESULT WINAPI dwritetextlayout_source_GetTextBeforePosition(IDWriteTextAnalysisSource1 *iface, UINT32 position, WCHAR const** text, UINT32* text_len) { - FIXME("%u %p %p: stub\n", position, text, text_len); - return E_NOTIMPL; + struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface); + + TRACE("(%p)->(%u %p %p)\n", layout, position, text, text_len); + + if (position > 0 && position < layout->len) { + *text = layout->str; + *text_len = position; + } + else { + *text = NULL; + *text_len = 0; + } + + return S_OK; } -static DWRITE_READING_DIRECTION WINAPI dwritetextlayout_source_GetParagraphReadingDirection(IDWriteTextAnalysisSource *iface) +static DWRITE_READING_DIRECTION WINAPI dwritetextlayout_source_GetParagraphReadingDirection(IDWriteTextAnalysisSource1 *iface) { - struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource(iface); + struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface); return IDWriteTextLayout2_GetReadingDirection(&layout->IDWriteTextLayout2_iface); } -static HRESULT WINAPI dwritetextlayout_source_GetLocaleName(IDWriteTextAnalysisSource *iface, +static HRESULT WINAPI dwritetextlayout_source_GetLocaleName(IDWriteTextAnalysisSource1 *iface, UINT32 position, UINT32* text_len, WCHAR const** locale) { - FIXME("%u %p %p: stub\n", position, text_len, locale); - return E_NOTIMPL; + struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSource1(iface); + struct layout_range *range = get_layout_range_by_pos(layout, position); + + if (position < layout->len) { + struct layout_range *next; + + *locale = range->locale; + *text_len = range->h.range.length - position; + + next = LIST_ENTRY(list_next(&layout->ranges, &range->h.entry), struct layout_range, h.entry); + while (next && next->h.range.startPosition < layout->len && !strcmpW(range->locale, next->locale)) { + *text_len += next->h.range.length; + next = LIST_ENTRY(list_next(&layout->ranges, &next->h.entry), struct layout_range, h.entry); + } + + *text_len = min(*text_len, layout->len - position); + } + else { + *locale = NULL; + *text_len = 0; + } + + return S_OK; } -static HRESULT WINAPI dwritetextlayout_source_GetNumberSubstitution(IDWriteTextAnalysisSource *iface, +static HRESULT WINAPI dwritetextlayout_source_GetNumberSubstitution(IDWriteTextAnalysisSource1 *iface, UINT32 position, UINT32* text_len, IDWriteNumberSubstitution **substitution) { FIXME("%u %p %p: stub\n", position, text_len, substitution); return E_NOTIMPL; } -static const IDWriteTextAnalysisSourceVtbl dwritetextlayoutsourcevtbl = { +static HRESULT WINAPI dwritetextlayout_source_GetVerticalGlyphOrientation(IDWriteTextAnalysisSource1 *iface, + UINT32 position, UINT32 *length, DWRITE_VERTICAL_GLYPH_ORIENTATION *orientation, UINT8 *bidi_level) +{ + FIXME("%u %p %p %p: stub\n", position, length, orientation, bidi_level); + return E_NOTIMPL; +} + +static const IDWriteTextAnalysisSource1Vtbl dwritetextlayoutsourcevtbl = { dwritetextlayout_source_QueryInterface, dwritetextlayout_source_AddRef, dwritetextlayout_source_Release, @@ -3907,7 +4264,8 @@ dwritetextlayout_source_GetTextBeforePosition, dwritetextlayout_source_GetParagraphReadingDirection, dwritetextlayout_source_GetLocaleName, - dwritetextlayout_source_GetNumberSubstitution + dwritetextlayout_source_GetNumberSubstitution, + dwritetextlayout_source_GetVerticalGlyphOrientation }; static HRESULT layout_format_from_textformat(struct dwrite_textlayout *layout, IDWriteTextFormat *format) @@ -3923,7 +4281,11 @@ layout->format.locale = heap_strdupW(textformat->format.locale); layout->format.family_name = heap_strdupW(textformat->format.family_name); if (!layout->format.locale || !layout->format.family_name) + { + heap_free(layout->format.locale); + heap_free(layout->format.family_name); return E_OUTOFMEMORY; + } if (layout->format.trimmingsign) IDWriteInlineObject_AddRef(layout->format.trimmingsign); @@ -3993,14 +4355,14 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *format, FLOAT maxwidth, FLOAT maxheight, struct dwrite_textlayout *layout) { - struct layout_range_header *range, *strike, *effect, *spacing, *typography; + struct layout_range_header *range, *strike, *underline, *effect, *spacing, *typography; static const DWRITE_TEXT_RANGE r = { 0, ~0u }; HRESULT hr; layout->IDWriteTextLayout2_iface.lpVtbl = &dwritetextlayoutvtbl; layout->IDWriteTextFormat1_iface.lpVtbl = &dwritetextformat1_layout_vtbl; - layout->IDWriteTextAnalysisSink_iface.lpVtbl = &dwritetextlayoutsinkvtbl; - layout->IDWriteTextAnalysisSource_iface.lpVtbl = &dwritetextlayoutsourcevtbl; + layout->IDWriteTextAnalysisSink1_iface.lpVtbl = &dwritetextlayoutsinkvtbl; + layout->IDWriteTextAnalysisSource1_iface.lpVtbl = &dwritetextlayoutsourcevtbl; layout->ref = 1; layout->len = len; layout->recompute = RECOMPUTE_EVERYTHING; @@ -4011,13 +4373,15 @@ layout->clusters = NULL; layout->lines = NULL; layout->line_alloc = 0; - layout->minwidth = 0.0; + layout->minwidth = 0.0f; list_init(&layout->eruns); list_init(&layout->inlineobjects); + list_init(&layout->underlines); list_init(&layout->strikethrough); list_init(&layout->runs); list_init(&layout->ranges); list_init(&layout->strike_ranges); + list_init(&layout->underline_ranges); list_init(&layout->effects); list_init(&layout->spacing); list_init(&layout->typographies); @@ -4027,7 +4391,7 @@ layout->metrics.layoutHeight = maxheight; layout->measuringmode = DWRITE_MEASURING_MODE_NATURAL; - layout->ppdip = 0.0; + layout->ppdip = 0.0f; memset(&layout->transform, 0, sizeof(layout->transform)); layout->str = heap_strdupnW(str, len); @@ -4042,20 +4406,24 @@ range = alloc_layout_range(layout, &r, LAYOUT_RANGE_REGULAR); strike = alloc_layout_range(layout, &r, LAYOUT_RANGE_STRIKETHROUGH); + underline = alloc_layout_range(layout, &r, LAYOUT_RANGE_UNDERLINE); effect = alloc_layout_range(layout, &r, LAYOUT_RANGE_EFFECT); spacing = alloc_layout_range(layout, &r, LAYOUT_RANGE_SPACING); typography = alloc_layout_range(layout, &r, LAYOUT_RANGE_TYPOGRAPHY); - if (!range || !strike || !effect || !spacing || !typography) { + if (!range || !strike || !effect || !spacing || !typography || !underline) { free_layout_range(range); free_layout_range(strike); + free_layout_range(underline); free_layout_range(effect); free_layout_range(spacing); + free_layout_range(typography); hr = E_OUTOFMEMORY; goto fail; } list_add_head(&layout->ranges, &range->entry); list_add_head(&layout->strike_ranges, &strike->entry); + list_add_head(&layout->underline_ranges, &underline->entry); list_add_head(&layout->effects, &effect->entry); list_add_head(&layout->spacing, &spacing->entry); list_add_head(&layout->typographies, &typography->entry); @@ -4073,6 +4441,9 @@ *ret = NULL; + if (!format || !str) + return E_INVALIDARG; + layout = heap_alloc(sizeof(struct dwrite_textlayout)); if (!layout) return E_OUTOFMEMORY; @@ -4091,6 +4462,9 @@ *ret = NULL; + if (!format || !str) + return E_INVALIDARG; + layout = heap_alloc(sizeof(struct dwrite_textlayout)); if (!layout) return E_OUTOFMEMORY; @@ -4152,11 +4526,14 @@ { struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface); DWRITE_TEXT_RANGE range = { 0, ~0u }; + HRESULT hr; TRACE("(%p)->(%p %p %.2f %.2f %d %d %p)\n", This, context, renderer, originX, originY, is_sideways, is_rtl, effect); IDWriteTextLayout_SetDrawingEffect(This->layout, effect, range); - return IDWriteTextLayout_Draw(This->layout, context, renderer, originX, originY); + hr = IDWriteTextLayout_Draw(This->layout, context, renderer, originX, originY); + IDWriteTextLayout_SetDrawingEffect(This->layout, NULL, range); + return hr; } static HRESULT WINAPI dwritetrimmingsign_GetMetrics(IDWriteInlineObject *iface, DWRITE_INLINE_OBJECT_METRICS *ret) @@ -4174,8 +4551,8 @@ } ret->width = metrics.width; - ret->height = 0.0; - ret->baseline = 0.0; + ret->height = 0.0f; + ret->baseline = 0.0f; ret->supportsSideways = FALSE; return S_OK; } @@ -4258,7 +4635,7 @@ This->IDWriteInlineObject_iface.lpVtbl = &dwritetrimmingsignvtbl; This->ref = 1; - hr = IDWriteFactory2_CreateTextLayout(factory, &ellipsisW, 1, format, 0.0, 0.0, &This->layout); + hr = IDWriteFactory2_CreateTextLayout(factory, &ellipsisW, 1, format, 0.0f, 0.0f, &This->layout); if (FAILED(hr)) { heap_free(This); return hr; @@ -4345,14 +4722,8 @@ static HRESULT WINAPI dwritetextformat_SetFlowDirection(IDWriteTextFormat1 *iface, DWRITE_FLOW_DIRECTION direction) { struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface); - TRACE("(%p)->(%d)\n", This, direction); - - if ((UINT32)direction > DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT) - return E_INVALIDARG; - - This->format.flow = direction; - return S_OK; + return format_set_flowdirection(&This->format, direction, NULL); } static HRESULT WINAPI dwritetextformat_SetIncrementalTabStop(IDWriteTextFormat1 *iface, FLOAT tabstop) @@ -4381,16 +4752,8 @@ FLOAT spacing, FLOAT baseline) { struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface); - TRACE("(%p)->(%d %f %f)\n", This, method, spacing, baseline); - - if (spacing < 0.0 || (UINT32)method > DWRITE_LINE_SPACING_METHOD_UNIFORM) - return E_INVALIDARG; - - This->format.spacingmethod = method; - This->format.spacing = spacing; - This->format.baseline = baseline; - return S_OK; + return format_set_linespacing(&This->format, method, spacing, baseline, NULL); } static DWRITE_TEXT_ALIGNMENT WINAPI dwritetextformat_GetTextAlignment(IDWriteTextFormat1 *iface) @@ -4432,7 +4795,7 @@ { struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface); FIXME("(%p): stub\n", This); - return 0.0; + return 0.0f; } static HRESULT WINAPI dwritetextformat_GetTrimming(IDWriteTextFormat1 *iface, DWRITE_TRIMMING *options, @@ -4662,6 +5025,8 @@ This->format.family_len = strlenW(family_name); This->format.locale = heap_strdupW(locale); This->format.locale_len = strlenW(locale); + /* force locale name to lower case, layout will inherit this modified value */ + strlwrW(This->format.locale); This->format.weight = weight; This->format.style = style; This->format.fontsize = size; @@ -4675,8 +5040,8 @@ This->format.flow = DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM; This->format.spacingmethod = DWRITE_LINE_SPACING_METHOD_DEFAULT; This->format.vertical_orientation = DWRITE_VERTICAL_GLYPH_ORIENTATION_DEFAULT; - This->format.spacing = 0.0; - This->format.baseline = 0.0; + This->format.spacing = 0.0f; + This->format.baseline = 0.0f; This->format.trimming.granularity = DWRITE_TRIMMING_GRANULARITY_NONE; This->format.trimming.delimiter = 0; This->format.trimming.delimiterCount = 0; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/main.c 2016-02-08 19:32:34.000000000 +0000 @@ -779,6 +779,8 @@ TRACE("(%p)->(%p %u %p %p)\n", This, reference_key, key_size, loader, font_file); + *font_file = NULL; + if (!loader || !factory_get_file_loader(This, loader)) return E_INVALIDARG; @@ -921,7 +923,7 @@ if (!fixme_once++) FIXME("(%p): monitor setting ignored\n", monitor); - hr = IDWriteFactory2_CreateCustomRenderingParams(iface, 0.0, 0.0, 1.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_DEFAULT, + hr = IDWriteFactory2_CreateCustomRenderingParams(iface, 0.0f, 0.0f, 1.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_DEFAULT, DWRITE_GRID_FIT_MODE_DEFAULT, ¶ms2); *params = (IDWriteRenderingParams*)params2; return hr; @@ -936,7 +938,7 @@ TRACE("(%p)->(%f %f %f %d %d %p)\n", This, gamma, enhancedContrast, cleartype_level, geometry, mode, params); - hr = IDWriteFactory2_CreateCustomRenderingParams(iface, gamma, enhancedContrast, 1.0, cleartype_level, geometry, + hr = IDWriteFactory2_CreateCustomRenderingParams(iface, gamma, enhancedContrast, 1.0f, cleartype_level, geometry, mode, DWRITE_GRID_FIT_MODE_DEFAULT, ¶ms2); *params = (IDWriteRenderingParams*)params2; return hr; @@ -1045,9 +1047,9 @@ UINT32 len, IDWriteTextFormat *format, FLOAT max_width, FLOAT max_height, IDWriteTextLayout **layout) { struct dwritefactory *This = impl_from_IDWriteFactory2(iface); + TRACE("(%p)->(%s:%u %p %f %f %p)\n", This, debugstr_wn(string, len), len, format, max_width, max_height, layout); - if (!format) return E_INVALIDARG; return create_textlayout(string, len, format, max_width, max_height, layout); } @@ -1060,7 +1062,6 @@ TRACE("(%p)->(%s:%u %p %f %f %f %p %d %p)\n", This, debugstr_wn(string, len), len, format, layout_width, layout_height, pixels_per_dip, transform, use_gdi_natural, layout); - if (!format) return E_INVALIDARG; return create_gdicompat_textlayout(string, len, format, layout_width, layout_height, pixels_per_dip, transform, use_gdi_natural, layout); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/opentype.c wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/opentype.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/opentype.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/opentype.c 2016-02-08 19:32:34.000000000 +0000 @@ -715,50 +715,137 @@ (type == DWRITE_FONT_FACE_TYPE_RAW_CFF); } -HRESULT opentype_analyze_font(IDWriteFontFileStream *stream, UINT32* font_count, DWRITE_FONT_FILE_TYPE *file_type, DWRITE_FONT_FACE_TYPE *face_type, BOOL *supported) +typedef HRESULT (*dwrite_fontfile_analyzer)(IDWriteFontFileStream *stream, UINT32 *font_count, DWRITE_FONT_FILE_TYPE *file_type, + DWRITE_FONT_FACE_TYPE *face_type); + +static HRESULT opentype_ttc_analyzer(IDWriteFontFileStream *stream, UINT32 *font_count, DWRITE_FONT_FILE_TYPE *file_type, + DWRITE_FONT_FACE_TYPE *face_type) { - /* TODO: Do font validation */ - DWRITE_FONT_FACE_TYPE face; - const void *font_data; - const char* tag; + static const DWORD ttctag = MS_TTCF_TAG; + const TTC_Header_V1 *header; void *context; HRESULT hr; - hr = IDWriteFontFileStream_ReadFileFragment(stream, &font_data, 0, sizeof(TTC_Header_V1), &context); + hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&header, 0, sizeof(header), &context); if (FAILED(hr)) return hr; - tag = font_data; - *file_type = DWRITE_FONT_FILE_TYPE_UNKNOWN; - face = DWRITE_FONT_FACE_TYPE_UNKNOWN; - *font_count = 0; - - if (DWRITE_MAKE_OPENTYPE_TAG(tag[0], tag[1], tag[2], tag[3]) == MS_TTCF_TAG) - { - const TTC_Header_V1 *header = font_data; + if (!memcmp(header->TTCTag, &ttctag, sizeof(ttctag))) { *font_count = GET_BE_DWORD(header->numFonts); *file_type = DWRITE_FONT_FILE_TYPE_TRUETYPE_COLLECTION; - face = DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION; + *face_type = DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION; } - else if (GET_BE_DWORD(*(DWORD*)font_data) == 0x10000) - { + + IDWriteFontFileStream_ReleaseFileFragment(stream, context); + + return *file_type != DWRITE_FONT_FILE_TYPE_UNKNOWN ? S_OK : S_FALSE; +} + +static HRESULT opentype_ttf_analyzer(IDWriteFontFileStream *stream, UINT32 *font_count, DWRITE_FONT_FILE_TYPE *file_type, + DWRITE_FONT_FACE_TYPE *face_type) +{ + const DWORD *header; + void *context; + HRESULT hr; + + hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&header, 0, sizeof(*header), &context); + if (FAILED(hr)) + return hr; + + if (GET_BE_DWORD(*header) == 0x10000) { *font_count = 1; *file_type = DWRITE_FONT_FILE_TYPE_TRUETYPE; - face = DWRITE_FONT_FACE_TYPE_TRUETYPE; + *face_type = DWRITE_FONT_FACE_TYPE_TRUETYPE; } - else if (DWRITE_MAKE_OPENTYPE_TAG(tag[0], tag[1], tag[2], tag[3]) == MS_OTTO_TAG) - { + + IDWriteFontFileStream_ReleaseFileFragment(stream, context); + + return *file_type != DWRITE_FONT_FILE_TYPE_UNKNOWN ? S_OK : S_FALSE; +} + +static HRESULT opentype_otf_analyzer(IDWriteFontFileStream *stream, UINT32 *font_count, DWRITE_FONT_FILE_TYPE *file_type, + DWRITE_FONT_FACE_TYPE *face_type) +{ + const DWORD *header; + void *context; + HRESULT hr; + + hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&header, 0, sizeof(*header), &context); + if (FAILED(hr)) + return hr; + + if (GET_BE_DWORD(*header) == MS_OTTO_TAG) { *font_count = 1; *file_type = DWRITE_FONT_FILE_TYPE_CFF; - face = DWRITE_FONT_FACE_TYPE_CFF; + *face_type = DWRITE_FONT_FACE_TYPE_CFF; } - if (face_type) - *face_type = face; + IDWriteFontFileStream_ReleaseFileFragment(stream, context); + + return *file_type != DWRITE_FONT_FILE_TYPE_UNKNOWN ? S_OK : S_FALSE; +} + +static HRESULT opentype_type1_analyzer(IDWriteFontFileStream *stream, UINT32 *font_count, DWRITE_FONT_FILE_TYPE *file_type, + DWRITE_FONT_FACE_TYPE *face_type) +{ + struct type1_header { + WORD tag; + char data[14]; + }; + const struct type1_header *header; + void *context; + HRESULT hr; + + hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&header, 0, sizeof(*header), &context); + if (FAILED(hr)) + return hr; - *supported = is_face_type_supported(face); + /* tag is followed by plain text section */ + if (header->tag == 0x8001 && + (!memcmp(header->data, "%!PS-AdobeFont", 14) || + !memcmp(header->data, "%!FontType", 10))) { + *font_count = 1; + *file_type = DWRITE_FONT_FILE_TYPE_TYPE1_PFB; + *face_type = DWRITE_FONT_FACE_TYPE_TYPE1; + } IDWriteFontFileStream_ReleaseFileFragment(stream, context); + + return *file_type != DWRITE_FONT_FILE_TYPE_UNKNOWN ? S_OK : S_FALSE; +} + +HRESULT opentype_analyze_font(IDWriteFontFileStream *stream, UINT32* font_count, DWRITE_FONT_FILE_TYPE *file_type, DWRITE_FONT_FACE_TYPE *face_type, BOOL *supported) +{ + static dwrite_fontfile_analyzer fontfile_analyzers[] = { + opentype_ttf_analyzer, + opentype_otf_analyzer, + opentype_ttc_analyzer, + opentype_type1_analyzer, + NULL + }; + dwrite_fontfile_analyzer *analyzer = fontfile_analyzers; + DWRITE_FONT_FACE_TYPE face; + HRESULT hr; + + if (!face_type) + face_type = &face; + + *file_type = DWRITE_FONT_FILE_TYPE_UNKNOWN; + *face_type = DWRITE_FONT_FACE_TYPE_UNKNOWN; + *font_count = 0; + + while (*analyzer) { + hr = (*analyzer)(stream, font_count, file_type, face_type); + if (FAILED(hr)) + return hr; + + if (hr == S_OK) + break; + + analyzer++; + } + + *supported = is_face_type_supported(*face_type); return S_OK; } @@ -1302,7 +1389,7 @@ return exists ? S_OK : E_FAIL; } -/* Provides a conversion from DWRITE to OpenType name ids, input id be valid, it's not checked. */ +/* Provides a conversion from DWRITE to OpenType name ids, input id should be valid, it's not checked. */ HRESULT opentype_get_font_info_strings(const void *table_data, DWRITE_INFORMATIONAL_STRING_ID id, IDWriteLocalizedStrings **strings) { return opentype_get_font_strings_from_id(table_data, dwriteid_to_opentypeid[id], strings); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/tests/analyzer.c wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/tests/analyzer.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/tests/analyzer.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/tests/analyzer.c 2016-02-08 19:32:34.000000000 +0000 @@ -27,7 +27,6 @@ #include "initguid.h" #include "windows.h" -#include "dwrite.h" #include "dwrite_2.h" #include "wine/test.h" @@ -966,21 +965,44 @@ }; static struct linebreaks_test linebreaks_tests[] = { - { {'A','-','B',' ','C',0x58a,'D',0x2010,'E',0x2012,'F',0x2013,'\t',0}, + { {'A','-','B',' ','C',0x58a,'D',0x2010,'E',0x2012,'F',0x2013,'\t',0xc,0xb,0x2028,0x2029,0x200b,0}, { - { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, FALSE, FALSE }, - { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, FALSE, FALSE }, - { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, FALSE, FALSE }, - { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, TRUE, FALSE }, - { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, FALSE, FALSE }, - { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, FALSE, FALSE }, - { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, FALSE, FALSE }, - { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, FALSE, FALSE }, - { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, FALSE, FALSE }, - { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, FALSE, FALSE }, - { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, FALSE, FALSE }, - { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, FALSE, FALSE }, - { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, TRUE, FALSE } + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 1, 0 }, + { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 1, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_MUST_BREAK, 1, 0 }, + { DWRITE_BREAK_CONDITION_MUST_BREAK, DWRITE_BREAK_CONDITION_MUST_BREAK, 1, 0 }, + { DWRITE_BREAK_CONDITION_MUST_BREAK, DWRITE_BREAK_CONDITION_MUST_BREAK, 1, 0 }, + { DWRITE_BREAK_CONDITION_MUST_BREAK, DWRITE_BREAK_CONDITION_MUST_BREAK, 1, 0 }, + { DWRITE_BREAK_CONDITION_MUST_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 0 }, + } + }, + /* Soft hyphen, visible word dividers */ + { {'A',0xad,'B',0x5be,'C',0xf0b,'D',0x1361,'E',0x17d8,'F',0x17da,'G',0}, + { + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 1 }, + { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_MAY_NOT_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 0 }, + { DWRITE_BREAK_CONDITION_CAN_BREAK, DWRITE_BREAK_CONDITION_CAN_BREAK, 0, 0 }, } }, { { 0 } } @@ -988,6 +1010,7 @@ static void compare_breakpoints(const struct linebreaks_test *test, DWRITE_LINE_BREAKPOINT *actual) { + static const char *conditions[] = {"N","CB","NB","B"}; const WCHAR *text = test->text; int cmp = memcmp(test->bp, actual, sizeof(*actual)*BREAKPOINT_COUNT); ok(!cmp, "%s: got wrong breakpoint data\n", wine_dbgstr_w(test->text)); @@ -995,16 +1018,19 @@ int i = 0; while (*text) { ok(!memcmp(&test->bp[i], &actual[i], sizeof(*actual)), - "%s: got (%d, %d, %d, %d), expected (%d, %d, %d, %d)\n", + "%s: got [%s, %s] (%s, %s), expected [%s, %s] (%s, %s)\n", wine_dbgstr_wn(&test->text[i], 1), - g_actual_bp[i].breakConditionBefore, - g_actual_bp[i].breakConditionAfter, - g_actual_bp[i].isWhitespace, - g_actual_bp[i].isSoftHyphen, - test->bp[i].breakConditionBefore, - test->bp[i].breakConditionAfter, - test->bp[i].isWhitespace, - test->bp[i].isSoftHyphen); + conditions[g_actual_bp[i].breakConditionBefore], + conditions[g_actual_bp[i].breakConditionAfter], + g_actual_bp[i].isWhitespace ? "WS" : "0", + g_actual_bp[i].isSoftHyphen ? "SHY" : "0", + conditions[test->bp[i].breakConditionBefore], + conditions[test->bp[i].breakConditionAfter], + test->bp[i].isWhitespace ? "WS" : "0", + test->bp[i].isSoftHyphen ? "SHY" : "0"); + if (g_actual_bp[i].isSoftHyphen) + ok(!g_actual_bp[i].isWhitespace, "%s: soft hyphen marked as a whitespace\n", + wine_dbgstr_wn(&test->text[i], 1)); text++; i++; } @@ -1016,6 +1042,7 @@ static const WCHAR emptyW[] = {0}; const struct linebreaks_test *ptr = linebreaks_tests; IDWriteTextAnalyzer *analyzer; + UINT32 i = 0; HRESULT hr; hr = IDWriteFactory_CreateTextAnalyzer(factory, &analyzer); @@ -1027,13 +1054,24 @@ while (*ptr->text) { + UINT32 len; + g_source = ptr->text; + len = lstrlenW(g_source); + + if (len > BREAKPOINT_COUNT) { + ok(0, "test %u: increase BREAKPOINT_COUNT to at least %u\n", i, len); + i++; + ptr++; + continue; + } memset(g_actual_bp, 0, sizeof(g_actual_bp)); - hr = IDWriteTextAnalyzer_AnalyzeLineBreakpoints(analyzer, &analysissource, 0, lstrlenW(g_source), &analysissink); + hr = IDWriteTextAnalyzer_AnalyzeLineBreakpoints(analyzer, &analysissource, 0, len, &analysissink); ok(hr == S_OK, "got 0x%08x\n", hr); compare_breakpoints(ptr, g_actual_bp); + i++; ptr++; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/tests/font.c wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/tests/font.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/tests/font.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/tests/font.c 2016-02-08 19:32:34.000000000 +0000 @@ -139,6 +139,44 @@ return fontface; } +static IDWriteFont *get_font(IDWriteFactory *factory, const WCHAR *name, DWRITE_FONT_STYLE style) +{ + IDWriteFontCollection *collection; + IDWriteFontFamily *family; + IDWriteFont *font = NULL; + UINT32 index; + BOOL exists; + HRESULT hr; + + hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE); + ok(hr == S_OK, "got 0x%08x\n", hr); + + index = ~0; + exists = FALSE; + hr = IDWriteFontCollection_FindFamilyName(collection, name, &index, &exists); + ok(hr == S_OK, "got 0x%08x\n", hr); + if (!exists) goto not_found; + + hr = IDWriteFontCollection_GetFontFamily(collection, index, &family); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, style, &font); + ok(hr == S_OK, "got 0x%08x\n", hr); + + IDWriteFontFamily_Release(family); +not_found: + IDWriteFontCollection_Release(collection); + return font; +} + +static IDWriteFont *get_tahoma_instance(IDWriteFactory *factory, DWRITE_FONT_STYLE style) +{ + IDWriteFont *font = get_font(factory, tahomaW, style); + ok(font != NULL, "failed to get Tahoma\n"); + return font; +} + static WCHAR *create_testfontfile(const WCHAR *filename) { static WCHAR pathW[MAX_PATH]; @@ -628,8 +666,10 @@ /* null out parameter crashes this call */ hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, NULL, NULL); + font = (void*)0xdeadbeef; hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, NULL, &font); EXPECT_HR(hr, E_INVALIDARG); + ok(font == NULL, "got %p\n", font); memset(&logfont, 0, sizeof(logfont)); logfont.lfHeight = 12; @@ -1318,15 +1358,22 @@ todo_wine ok(hr == DWRITE_E_UNSUPPORTEDOPERATION || broken(hr == E_INVALIDARG) /* older versions */, "got 0x%08x\n", hr); + fontface = (void*)0xdeadbeef; hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TYPE1, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(fontface == NULL, "got %p\n", fontface); + fontface = (void*)0xdeadbeef; hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_VECTOR, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(fontface == NULL, "got %p\n", fontface); + fontface = (void*)0xdeadbeef; hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_BITMAP, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(fontface == NULL, "got %p\n", fontface); + fontface = NULL; hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_UNKNOWN, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface); todo_wine ok(hr == S_OK || broken(hr == E_INVALIDARG) /* < win10 */, "got 0x%08x\n", hr); @@ -1344,14 +1391,16 @@ static void test_GetMetrics(void) { + DWRITE_FONT_METRICS metrics, metrics2; IDWriteGdiInterop *interop; - DWRITE_FONT_METRICS metrics; IDWriteFontFace *fontface; IDWriteFactory *factory; OUTLINETEXTMETRICW otm; + IDWriteFontFile *file; IDWriteFont1 *font1; IDWriteFont *font; LOGFONTW logfont; + UINT32 count; HRESULT hr; HDC hdc; HFONT hfont; @@ -1481,9 +1530,47 @@ win_skip("DWRITE_FONT_METRICS1 is not supported.\n"); IDWriteFontFace_Release(fontface); - IDWriteFont_Release(font); IDWriteGdiInterop_Release(interop); + + /* bold simulation affects returned font metrics */ + font = get_tahoma_instance(factory, DWRITE_FONT_STYLE_NORMAL); + + /* create regulat Tahoma with bold simulation */ + hr = IDWriteFont_CreateFontFace(font, &fontface); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 1; + hr = IDWriteFontFace_GetFiles(fontface, &count, &file); + ok(hr == S_OK, "got 0x%08x\n", hr); + + IDWriteFontFace_GetMetrics(fontface, &metrics); + ok(IDWriteFontFace_GetSimulations(fontface) == 0, "wrong simulations flags\n"); + IDWriteFontFace_Release(fontface); + + hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &file, + 0, DWRITE_FONT_SIMULATIONS_BOLD, &fontface); + ok(hr == S_OK, "got 0x%08x\n", hr); + IDWriteFontFace_GetMetrics(fontface, &metrics2); + ok(IDWriteFontFace_GetSimulations(fontface) == DWRITE_FONT_SIMULATIONS_BOLD, "wrong simulations flags\n"); + + ok(metrics.ascent == metrics2.ascent, "got %u, %u\n", metrics2.ascent, metrics.ascent); + ok(metrics.descent == metrics2.descent, "got %u, %u\n", metrics2.descent, metrics.descent); + ok(metrics.lineGap == metrics2.lineGap, "got %d, %d\n", metrics2.lineGap, metrics.lineGap); + ok(metrics.capHeight == metrics2.capHeight, "got %u, %u\n", metrics2.capHeight, metrics.capHeight); + ok(metrics.xHeight == metrics2.xHeight, "got %u, %u\n", metrics2.xHeight, metrics.xHeight); + ok(metrics.underlinePosition == metrics2.underlinePosition, "got %d, %d\n", metrics2.underlinePosition, + metrics.underlinePosition); + ok(metrics.underlineThickness == metrics2.underlineThickness, "got %u, %u\n", metrics2.underlineThickness, + metrics.underlineThickness); + ok(metrics.strikethroughPosition == metrics2.strikethroughPosition, "got %d, %d\n", metrics2.strikethroughPosition, + metrics.strikethroughPosition); + ok(metrics.strikethroughThickness == metrics2.strikethroughThickness, "got %u, %u\n", metrics2.strikethroughThickness, + metrics.strikethroughThickness); + + IDWriteFontFile_Release(file); + IDWriteFont_Release(font); + IDWriteFactory_Release(factory); } @@ -1789,8 +1876,10 @@ hr = IDWriteFactory_RegisterFontCollectionLoader(factory, &resource_collection.IDWriteFontFileCollectionLoader_iface); ok(hr == S_OK, "got 0x%08x\n", hr); + font_collection = (void*)0xdeadbeef; hr = IDWriteFactory_CreateCustomFontCollection(factory, &collection3, "Billy", 6, &font_collection); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(font_collection == NULL, "got %p\n", font_collection); hr = IDWriteFactory_CreateCustomFontCollection(factory, &collection, "Billy", 6, &font_collection); ok(hr == S_OK, "got 0x%08x\n", hr); @@ -1800,8 +1889,10 @@ ok(hr == S_OK, "got 0x%08x\n", hr); IDWriteFontCollection_Release(font_collection); + font_collection = (void*)0xdeadbeef; hr = IDWriteFactory_CreateCustomFontCollection(factory, (IDWriteFontCollectionLoader*)0xdeadbeef, "Billy", 6, &font_collection); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(font_collection == NULL, "got %p\n", font_collection); font = FindResourceA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(1), (LPCSTR)RT_RCDATA); ok(font != NULL, "Failed to find font resource\n"); @@ -1980,11 +2071,15 @@ ok(hr == S_OK, "got 0x%08x\n", hr); IDWriteFontFile_Release(file); + file = (void*)0xdeadbeef; hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, &floader3, &file); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(file == NULL, "got %p\n", file); + file = (void*)0xdeadbeef; hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, NULL, &file); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(file == NULL, "got %p\n", file); file = NULL; hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, &floader, &file); @@ -2023,8 +2118,10 @@ ok(count == 1, "got %i\n", count); /* invalid index */ + face = (void*)0xdeadbeef; hr = IDWriteFactory_CreateFontFace(factory, face_type, 1, &file, 1, DWRITE_FONT_SIMULATIONS_NONE, &face); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(face == NULL, "got %p\n", face); hr = IDWriteFactory_CreateFontFace(factory, face_type, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &face); ok(hr == S_OK, "got 0x%08x\n", hr); @@ -2319,43 +2416,7 @@ DELETE_FONTFILE(path); } -static IDWriteFont *get_font(IDWriteFactory *factory, const WCHAR *name, DWRITE_FONT_STYLE style) -{ - IDWriteFontCollection *collection; - IDWriteFontFamily *family; - IDWriteFont *font = NULL; - UINT32 index; - BOOL exists; - HRESULT hr; - - hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE); - ok(hr == S_OK, "got 0x%08x\n", hr); - index = ~0; - exists = FALSE; - hr = IDWriteFontCollection_FindFamilyName(collection, name, &index, &exists); - ok(hr == S_OK, "got 0x%08x\n", hr); - if (!exists) goto not_found; - - hr = IDWriteFontCollection_GetFontFamily(collection, index, &family); - ok(hr == S_OK, "got 0x%08x\n", hr); - - hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL, - DWRITE_FONT_STRETCH_NORMAL, style, &font); - ok(hr == S_OK, "got 0x%08x\n", hr); - - IDWriteFontFamily_Release(family); -not_found: - IDWriteFontCollection_Release(collection); - return font; -} - -static IDWriteFont *get_tahoma_instance(IDWriteFactory *factory, DWRITE_FONT_STYLE style) -{ - IDWriteFont *font = get_font(factory, tahomaW, style); - ok(font != NULL, "failed to get Tahoma\n"); - return font; -} static void test_GetFirstMatchingFont(void) { @@ -2498,8 +2559,10 @@ hr = IDWriteFactory_GetGdiInterop(factory, &interop); ok(hr == S_OK, "got 0x%08x\n", hr); + fontface = (void*)0xdeadbeef; hr = IDWriteGdiInterop_CreateFontFaceFromHdc(interop, NULL, &fontface); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(fontface == NULL, "got %p\n", fontface); memset(&logfont, 0, sizeof(logfont)); logfont.lfHeight = 12; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/tests/layout.c wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/tests/layout.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/dwrite/tests/layout.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/dwrite/tests/layout.c 2016-02-08 19:32:34.000000000 +0000 @@ -1,7 +1,7 @@ /* * Text layout/format tests * - * Copyright 2012, 2014-2015 Nikolay Sivov for CodeWeavers + * Copyright 2012, 2014-2016 Nikolay Sivov for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,6 @@ #include #include "windows.h" -#include "dwrite.h" #include "dwrite_2.h" #include "wine/test.h" @@ -257,6 +256,7 @@ struct drawcall_entry { enum drawcall_kind kind; WCHAR string[10]; /* only meaningful for DrawGlyphRun() */ + WCHAR locale[LOCALE_NAME_MAX_LENGTH]; }; struct drawcall_sequence @@ -364,6 +364,18 @@ ok_(file, line) (cmp == 0, "%s: glyphrun string %s was expected, but got %s instead\n", context, wine_dbgstr_w(expected->string), wine_dbgstr_w(actual->string)); } + else if ((expected->kind & DRAW_KINDS_MASK) == DRAW_UNDERLINE) { + int cmp = lstrcmpW(expected->locale, actual->locale); + if (cmp != 0 && todo) { + failcount++; + todo_wine + ok_(file, line) (0, "%s: underline locale %s was expected, but got %s instead\n", + context, wine_dbgstr_w(expected->locale), wine_dbgstr_w(actual->locale)); + } + else + ok_(file, line) (cmp == 0, "%s: underline locale %s was expected, but got %s instead\n", + context, wine_dbgstr_w(expected->locale), wine_dbgstr_w(actual->locale)); + } expected++; actual++; } @@ -536,6 +548,7 @@ entry.kind = DRAW_UNDERLINE; if (effect) entry.kind |= DRAW_EFFECT; + lstrcpyW(entry.locale, underline->localeName); add_call(sequences, RENDERER_ID, &entry); return S_OK; } @@ -714,25 +727,44 @@ factory = create_factory(); + layout = (void*)0xdeadbeef; hr = IDWriteFactory_CreateTextLayout(factory, NULL, 0, NULL, 0.0, 0.0, &layout); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); + layout = (void*)0xdeadbeef; hr = IDWriteFactory_CreateTextLayout(factory, strW, 6, NULL, 0.0, 0.0, &layout); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); + layout = (void*)0xdeadbeef; hr = IDWriteFactory_CreateTextLayout(factory, strW, 6, NULL, 1.0, 0.0, &layout); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); + layout = (void*)0xdeadbeef; hr = IDWriteFactory_CreateTextLayout(factory, strW, 6, NULL, 0.0, 1.0, &layout); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); + layout = (void*)0xdeadbeef; hr = IDWriteFactory_CreateTextLayout(factory, strW, 6, NULL, 1000.0, 1000.0, &layout); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format); ok(hr == S_OK, "got 0x%08x\n", hr); + layout = (void*)0xdeadbeef; + hr = IDWriteFactory_CreateTextLayout(factory, NULL, 0, format, 100.0f, 100.0f, &layout); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); + + hr = IDWriteFactory_CreateTextLayout(factory, strW, 0, format, 0.0f, 0.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + IDWriteTextLayout_Release(layout); + EXPECT_REF(format, 1); hr = IDWriteFactory_CreateTextLayout(factory, strW, 6, format, 1000.0, 1000.0, &layout); ok(hr == S_OK, "got 0x%08x\n", hr); @@ -809,20 +841,30 @@ factory = create_factory(); + layout = (void*)0xdeadbeef; hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, NULL, 0, NULL, 0.0, 0.0, 0.0, NULL, FALSE, &layout); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); + layout = (void*)0xdeadbeef; hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, strW, 6, NULL, 0.0, 0.0, 0.0, NULL, FALSE, &layout); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); + layout = (void*)0xdeadbeef; hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, strW, 6, NULL, 1.0, 0.0, 0.0, NULL, FALSE, &layout); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); + layout = (void*)0xdeadbeef; hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, strW, 6, NULL, 1.0, 0.0, 1.0, NULL, FALSE, &layout); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); + layout = (void*)0xdeadbeef; hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, strW, 6, NULL, 1000.0, 1000.0, 1.0, NULL, FALSE, &layout); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); /* create with text format */ hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, @@ -830,6 +872,11 @@ ok(hr == S_OK, "got 0x%08x\n", hr); EXPECT_REF(format, 1); + layout = (void*)0xdeadbeef; + hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, NULL, 0, format, 100.0f, 100.0f, 1.0f, NULL, FALSE, &layout); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(layout == NULL, "got %p\n", layout); + hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, strW, 6, format, 100.0, 100.0, 1.0, NULL, FALSE, &layout); ok(hr == S_OK, "got 0x%08x\n", hr); EXPECT_REF(format, 1); @@ -1070,7 +1117,6 @@ metrics.supportsSideways = TRUE; hr = IDWriteInlineObject_GetMetrics(sign, &metrics); ok(hr == S_OK, "got 0x%08x\n", hr); -todo_wine ok(metrics.width > 0.0, "got %.2f\n", metrics.width); ok(metrics.height == 0.0, "got %.2f\n", metrics.height); ok(metrics.baseline == 0.0, "got %.2f\n", metrics.baseline); @@ -1348,7 +1394,7 @@ { DRAW_GLYPHRUN|DRAW_EFFECT, {'n',0} }, { DRAW_GLYPHRUN, {'g',0} }, { DRAW_INLINE }, - { DRAW_UNDERLINE }, + { DRAW_UNDERLINE, {0}, {'r','u',0} }, { DRAW_STRIKETHROUGH }, { DRAW_LAST_KIND } }; @@ -1364,7 +1410,7 @@ }; static const struct drawcall_entry draw_seq3[] = { - { DRAW_GLYPHRUN }, + { DRAW_GLYPHRUN, {0x202a,0x202c,0} }, { DRAW_GLYPHRUN, {'a','b',0} }, { DRAW_LAST_KIND } }; @@ -1447,7 +1493,7 @@ flush_sequence(sequences, RENDERER_ID); hr = IDWriteTextLayout_Draw(layout, &ctxt, &testrenderer, 0.0, 0.0); ok(hr == S_OK, "got 0x%08x\n", hr); - ok_sequence(sequences, RENDERER_ID, draw_seq, "draw test", TRUE); + ok_sequence(sequences, RENDERER_ID, draw_seq, "draw test", FALSE); IDWriteTextLayout_Release(layout); /* with reduced width DrawGlyphRun() is called for every line */ @@ -1647,14 +1693,19 @@ static void test_GetClusterMetrics(void) { + static const WCHAR str_white_spaceW[] = { + /* BK - FORM FEED, LINE TABULATION, LINE SEP, PARA SEP */ 0xc, 0xb, 0x2028, 0x2029, + /* ZW - ZERO WIDTH SPACE */ 0x200b, + /* SP - SPACE */ 0x20 + }; static const WCHAR str5W[] = {'a','\r','b','\n','c','\n','\r','d','\r','\n','e',0xb,'f',0xc, - 'g',0x0085,'h',0x2028,'i',0x2029,0}; + 'g',0x0085,'h',0x2028,'i',0x2029,0xad,0xa,0}; static const WCHAR str3W[] = {0x2066,')',')',0x661,'(',0x627,')',0}; static const WCHAR str2W[] = {0x202a,0x202c,'a',0}; static const WCHAR strW[] = {'a','b','c','d',0}; static const WCHAR str4W[] = {'a',' ',0}; DWRITE_INLINE_OBJECT_METRICS inline_metrics; - DWRITE_CLUSTER_METRICS metrics[20]; + DWRITE_CLUSTER_METRICS metrics[22]; IDWriteTextLayout1 *layout1; IDWriteInlineObject *trimm; IDWriteTextFormat *format; @@ -1772,7 +1823,6 @@ hr = IDWriteInlineObject_GetMetrics(trimm, &inline_metrics); ok(hr == S_OK, "got 0x%08x\n", hr); -todo_wine ok(inline_metrics.width > 0.0 && inline_metrics.width == metrics[0].width, "got %.2f, expected %.2f\n", inline_metrics.width, metrics[0].width); @@ -1890,6 +1940,7 @@ ok(hr == S_OK, "got 0x%08x\n", hr); ok(count == 2, "got %u\n", count); ok(metrics[0].isWhitespace == 0, "got %d\n", metrics[0].isWhitespace); + ok(metrics[0].canWrapLineAfter == 0, "got %d\n", metrics[0].canWrapLineAfter); ok(metrics[1].isWhitespace == 1, "got %d\n", metrics[1].isWhitespace); ok(metrics[1].canWrapLineAfter == 1, "got %d\n", metrics[1].canWrapLineAfter); IDWriteTextLayout_Release(layout); @@ -1938,16 +1989,15 @@ IDWriteTextLayout_Release(layout); /* isNewline tests */ - hr = IDWriteFactory_CreateTextLayout(factory, str5W, 20, format, 100.0, 200.0, &layout); + hr = IDWriteFactory_CreateTextLayout(factory, str5W, lstrlenW(str5W), format, 100.0f, 200.0f, &layout); ok(hr == S_OK, "got 0x%08x\n", hr); count = 0; memset(metrics, 0, sizeof(metrics)); - hr = IDWriteTextLayout_GetClusterMetrics(layout, metrics, 20, &count); + hr = IDWriteTextLayout_GetClusterMetrics(layout, metrics, sizeof(metrics)/sizeof(metrics[0]), &count); ok(hr == S_OK, "got 0x%08x\n", hr); - ok(count == 20, "got %u\n", count); + ok(count == 22, "got %u\n", count); -todo_wine { ok(metrics[1].isNewline == 1, "got %d\n", metrics[1].isNewline); ok(metrics[3].isNewline == 1, "got %d\n", metrics[3].isNewline); ok(metrics[5].isNewline == 1, "got %d\n", metrics[5].isNewline); @@ -1958,7 +2008,8 @@ ok(metrics[15].isNewline == 1, "got %d\n", metrics[15].isNewline); ok(metrics[17].isNewline == 1, "got %d\n", metrics[17].isNewline); ok(metrics[19].isNewline == 1, "got %d\n", metrics[19].isNewline); -} + ok(metrics[21].isNewline == 1, "got %d\n", metrics[21].isNewline); + ok(metrics[0].isNewline == 0, "got %d\n", metrics[0].isNewline); ok(metrics[2].isNewline == 0, "got %d\n", metrics[2].isNewline); ok(metrics[4].isNewline == 0, "got %d\n", metrics[4].isNewline); @@ -1969,12 +2020,43 @@ ok(metrics[14].isNewline == 0, "got %d\n", metrics[14].isNewline); ok(metrics[16].isNewline == 0, "got %d\n", metrics[16].isNewline); ok(metrics[18].isNewline == 0, "got %d\n", metrics[18].isNewline); + ok(metrics[20].isNewline == 0, "got %d\n", metrics[20].isNewline); - for (i = 0; i < count; i++) + for (i = 0; i < count; i++) { ok(metrics[i].length == 1, "%d: got %d\n", i, metrics[i].length); + ok(metrics[i].isSoftHyphen == (i == count - 2), "%d: got %d\n", i, metrics[i].isSoftHyphen); + if (metrics[i].isSoftHyphen) + ok(!metrics[i].isWhitespace, "%u: got %d\n", i, metrics[i].isWhitespace); + if (metrics[i].isNewline) { + if (i == 17 || i == 19) + todo_wine ok(metrics[i].width == 0.0f, "%u: got width %f\n", i, metrics[i].width); + else + ok(metrics[i].width == 0.0f, "%u: got width %f\n", i, metrics[i].width); + ok(metrics[i].isWhitespace == 1, "%u: got %d\n", i, metrics[i].isWhitespace); + ok(metrics[i].canWrapLineAfter == 1, "%u: got %d\n", i, metrics[i].canWrapLineAfter); + } + } IDWriteTextLayout_Release(layout); + /* Test whitespace resolution from linebreaking classes BK, ZW, and SP */ + hr = IDWriteFactory_CreateTextLayout(factory, str_white_spaceW, sizeof(str_white_spaceW)/sizeof(WCHAR), format, + 100.0f, 200.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 0; + memset(metrics, 0, sizeof(metrics)); + hr = IDWriteTextLayout_GetClusterMetrics(layout, metrics, 20, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 6, "got %u\n", count); + + ok(metrics[0].isWhitespace == 1, "got %d\n", metrics[0].isWhitespace); + ok(metrics[1].isWhitespace == 1, "got %d\n", metrics[1].isWhitespace); + ok(metrics[2].isWhitespace == 1, "got %d\n", metrics[2].isWhitespace); + ok(metrics[3].isWhitespace == 1, "got %d\n", metrics[3].isWhitespace); + ok(metrics[4].isWhitespace == 0, "got %d\n", metrics[4].isWhitespace); + ok(metrics[5].isWhitespace == 1, "got %d\n", metrics[5].isWhitespace); + IDWriteInlineObject_Release(trimm); IDWriteTextFormat_Release(format); IDWriteFactory_Release(factory); @@ -1985,7 +2067,7 @@ static const WCHAR eNuSW[] = {'e','N','-','u','S',0}; static const WCHAR strW[] = {'a','b','c','d',0}; WCHAR buffW[LOCALE_NAME_MAX_LENGTH+sizeof(strW)/sizeof(WCHAR)]; - IDWriteTextFormat *format; + IDWriteTextFormat *format, *format2; IDWriteTextLayout *layout; DWRITE_TEXT_RANGE range; IDWriteFactory *factory; @@ -1993,6 +2075,33 @@ factory = create_factory(); + /* create format with mixed case locale name, get it back */ + hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, 10.0, eNuSW, &format); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteTextFormat_GetLocaleName(format, buffW, sizeof(buffW)/sizeof(buffW[0])); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(buffW, enusW), "got %s\n", wine_dbgstr_w(buffW)); + + hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteTextLayout_QueryInterface(layout, &IID_IDWriteTextFormat, (void**)&format2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteTextFormat_GetLocaleName(format2, buffW, sizeof(buffW)/sizeof(buffW[0])); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(buffW, enusW), "got %s\n", wine_dbgstr_w(buffW)); + + hr = IDWriteTextLayout_GetLocaleName(layout, 0, buffW, sizeof(buffW)/sizeof(buffW[0]), NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(buffW, enusW), "got %s\n", wine_dbgstr_w(buffW)); + + IDWriteTextFormat_Release(format2); + IDWriteTextLayout_Release(layout); + IDWriteTextFormat_Release(format); + hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format); ok(hr == S_OK, "got 0x%08x\n", hr); @@ -2056,18 +2165,18 @@ range.length = 0; hr = IDWriteTextLayout_GetLocaleName(layout, 0, buffW, sizeof(buffW)/sizeof(WCHAR), &range); ok(hr == S_OK, "got 0x%08x\n", hr); -todo_wine ok(!lstrcmpW(buffW, enusW), "got %s\n", wine_dbgstr_w(buffW)); - ok(range.startPosition == 0 && range.length == ~0u, "got %u,%u\n", range.startPosition, range.length); + ok((range.startPosition == 0 && range.length == ~0u) || + broken(range.startPosition == 0 && range.length == 4) /* vista/win7 */, "got %u,%u\n", range.startPosition, range.length); /* check what's returned for positions after the text */ buffW[0] = 0; range.length = 0; hr = IDWriteTextLayout_GetLocaleName(layout, 100, buffW, sizeof(buffW)/sizeof(WCHAR), &range); ok(hr == S_OK, "got 0x%08x\n", hr); -todo_wine ok(!lstrcmpW(buffW, enusW), "got %s\n", wine_dbgstr_w(buffW)); - ok(range.startPosition == 0 && range.length == ~0u, "got %u,%u\n", range.startPosition, range.length); + ok((range.startPosition == 0 && range.length == ~0u) || + broken(range.startPosition == 4 && range.length == ~0u-4) /* vista/win7 */, "got %u,%u\n", range.startPosition, range.length); IDWriteTextLayout_Release(layout); IDWriteTextFormat_Release(format); @@ -2278,10 +2387,21 @@ static void test_DetermineMinWidth(void) { + struct minwidth_test { + const WCHAR text[10]; /* text to create a layout for */ + const WCHAR mintext[10]; /* text that represents sequence of minimal width */ + } minwidth_tests[] = { + { {' ','a','b',' ',0}, {'a','b',0} }, + { {'a','\n',' ',' ',0}, {'a',0} }, + { {'a','\n',' ',' ','b',0}, {'b',0} }, + { {'a','b','c','\n',' ',' ','b',0}, {'a','b','c',0} }, + }; static const WCHAR strW[] = {'a','b','c','d',0}; + DWRITE_CLUSTER_METRICS metrics[10]; IDWriteTextFormat *format; IDWriteTextLayout *layout; IDWriteFactory *factory; + UINT32 count, i, j; FLOAT minwidth; HRESULT hr; @@ -2296,13 +2416,44 @@ hr = IDWriteTextLayout_DetermineMinWidth(layout, NULL); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + IDWriteTextLayout_Release(layout); - minwidth = 0.0; - hr = IDWriteTextLayout_DetermineMinWidth(layout, &minwidth); + /* empty string */ + hr = IDWriteFactory_CreateTextLayout(factory, strW, 0, format, 100.0f, 100.0f, &layout); ok(hr == S_OK, "got 0x%08x\n", hr); - ok(minwidth > 0.0, "got %.2f\n", minwidth); + minwidth = 1.0f; + hr = IDWriteTextLayout_DetermineMinWidth(layout, &minwidth); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(minwidth == 0.0f, "got %f\n", minwidth); IDWriteTextLayout_Release(layout); + + for (i = 0; i < sizeof(minwidth_tests)/sizeof(minwidth_tests[0]); i++) { + FLOAT width = 0.0f; + + /* measure expected width */ + hr = IDWriteFactory_CreateTextLayout(factory, minwidth_tests[i].mintext, lstrlenW(minwidth_tests[i].mintext), format, 1000.0f, 1000.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteTextLayout_GetClusterMetrics(layout, metrics, sizeof(metrics)/sizeof(metrics[0]), &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + + for (j = 0; j < count; j++) + width += metrics[j].width; + + IDWriteTextLayout_Release(layout); + + hr = IDWriteFactory_CreateTextLayout(factory, minwidth_tests[i].text, lstrlenW(minwidth_tests[i].text), format, 1000.0f, 1000.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + minwidth = 0.0f; + hr = IDWriteTextLayout_DetermineMinWidth(layout, &minwidth); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(minwidth == width, "test %u: expected width %f, got %f\n", i, width, minwidth); + + IDWriteTextLayout_Release(layout); + } + IDWriteTextFormat_Release(format); IDWriteFactory_Release(factory); } @@ -2955,7 +3106,7 @@ flush_sequence(sequences, RENDERER_ID); hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0); ok(hr == S_OK, "got 0x%08x\n", hr); - ok_sequence(sequences, RENDERER_ID, draweffect2_seq, "effect draw test 2", TRUE); + ok_sequence(sequences, RENDERER_ID, draweffect2_seq, "effect draw test 2", FALSE); IDWriteTextLayout_Release(layout); /* Inline object - effect set for same range */ @@ -3056,18 +3207,41 @@ return fontface; } +static BOOL get_enus_string(IDWriteLocalizedStrings *strings, WCHAR *buff, UINT32 size) +{ + UINT32 index; + BOOL exists = FALSE; + HRESULT hr; + + hr = IDWriteLocalizedStrings_FindLocaleName(strings, enusW, &index, &exists); + ok(hr == S_OK, "got 0x%08x\n", hr); + + if (exists) { + hr = IDWriteLocalizedStrings_GetString(strings, index, buff, size); + ok(hr == S_OK, "got 0x%08x\n", hr); + } + else + *buff = 0; + + return exists; +} + static void test_GetLineMetrics(void) { static const WCHAR str3W[] = {'a','\r','b','\n','c','\n','\r','d','\r','\n',0}; static const WCHAR strW[] = {'a','b','c','d',' ',0}; static const WCHAR str2W[] = {'a','b','\r','c','d',0}; + static const WCHAR str4W[] = {'a','\r',0}; + IDWriteFontCollection *syscollection; DWRITE_FONT_METRICS fontmetrics; DWRITE_LINE_METRICS metrics[6]; + UINT32 count, i, familycount; IDWriteTextFormat *format; IDWriteTextLayout *layout; IDWriteFontFace *fontface; IDWriteFactory *factory; - UINT32 count; + DWRITE_TEXT_RANGE range; + WCHAR nameW[256]; HRESULT hr; factory = create_factory(); @@ -3093,31 +3267,130 @@ ok(metrics[0].newlineLength == 0, "got %u\n", metrics[0].newlineLength); ok(metrics[0].isTrimmed == FALSE, "got %d\n", metrics[0].isTrimmed); - /* Tahoma doesn't provide BASE table, so baseline is calculated from font metrics */ + IDWriteTextLayout_Release(layout); + + /* Test line height and baseline calculation */ + hr = IDWriteFactory_GetSystemFontCollection(factory, &syscollection, FALSE); + ok(hr == S_OK, "got 0x%08x\n", hr); + familycount = IDWriteFontCollection_GetFontFamilyCount(syscollection); + + for (i = 0; i < familycount; i++) { + static const WCHAR mvboliW[] = {'M','V',' ','B','o','l','i',0}; + IDWriteLocalizedStrings *names; + IDWriteFontFamily *family; + IDWriteFont *font; + BOOL exists; + + format = NULL; + layout = NULL; + + hr = IDWriteFontCollection_GetFontFamily(syscollection, i, &family); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, + DWRITE_FONT_STYLE_NORMAL, &font); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFont_CreateFontFace(font, &fontface); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFontFamily_GetFamilyNames(family, &names); + ok(hr == S_OK, "got 0x%08x\n", hr); + + if (!(exists = get_enus_string(names, nameW, sizeof(nameW)/sizeof(nameW[0])))) { + IDWriteLocalFontFileLoader *localloader; + IDWriteFontFileLoader *loader; + IDWriteFontFile *file; + const void *key; + UINT32 keysize; + UINT32 count; + + count = 1; + hr = IDWriteFontFace_GetFiles(fontface, &count, &file); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFontFile_GetLoader(file, &loader); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFontFileLoader_QueryInterface(loader, &IID_IDWriteLocalFontFileLoader, (void**)&localloader); + ok(hr == S_OK, "got 0x%08x\n", hr); + IDWriteFontFileLoader_Release(loader); + + hr = IDWriteFontFile_GetReferenceKey(file, &key, &keysize); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteLocalFontFileLoader_GetFilePathFromKey(localloader, key, keysize, nameW, sizeof(nameW)/sizeof(*nameW)); + ok(hr == S_OK, "got 0x%08x\n", hr); + + skip("Failed to get English family name, font file %s\n", wine_dbgstr_w(nameW)); + + IDWriteLocalFontFileLoader_Release(localloader); + IDWriteFontFile_Release(file); + } + + IDWriteLocalizedStrings_Release(names); + IDWriteFont_Release(font); + + if (!exists) + goto cleanup; + + /* This will effectively skip on Vista/2008 only, newer systems work just fine with this font. */ + if (!lstrcmpW(nameW, mvboliW)) { + skip("Skipping line metrics test for %s, gives inconsistent results\n", wine_dbgstr_w(nameW)); + goto cleanup; + } + + IDWriteFontFace_GetMetrics(fontface, &fontmetrics); + hr = IDWriteFactory_CreateTextFormat(factory, nameW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, fontmetrics.designUnitsPerEm, enusW, &format); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFactory_CreateTextLayout(factory, strW, 5, format, 30000.0f, 100.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + memset(metrics, 0, sizeof(metrics)); + count = 0; + hr = IDWriteTextLayout_GetLineMetrics(layout, metrics, 2, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 1, "got %u\n", count); + + ok(metrics[0].baseline == fontmetrics.ascent + fontmetrics.lineGap, "%s: got %.2f, expected %d, " + "linegap %d\n", wine_dbgstr_w(nameW), metrics[0].baseline, fontmetrics.ascent + fontmetrics.lineGap, + fontmetrics.lineGap); + ok(metrics[0].height == fontmetrics.ascent + fontmetrics.descent + fontmetrics.lineGap, + "%s: got %.2f, expected %d, linegap %d\n", wine_dbgstr_w(nameW), metrics[0].height, + fontmetrics.ascent + fontmetrics.descent + fontmetrics.lineGap, fontmetrics.lineGap); + + cleanup: + if (layout) + IDWriteTextLayout_Release(layout); + if (format) + IDWriteTextFormat_Release(format); + IDWriteFontFace_Release(fontface); + IDWriteFontFamily_Release(family); + } + IDWriteFontCollection_Release(syscollection); + + hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, 2048.0f, enusW, &format); + ok(hr == S_OK, "got 0x%08x\n", hr); + fontface = get_fontface_from_format(format); ok(fontface != NULL, "got %p\n", fontface); - IDWriteFontFace_GetMetrics(fontface, &fontmetrics); - - ok(metrics[0].baseline == fontmetrics.ascent, "got %.2f, expected %d\n", metrics[0].baseline, - fontmetrics.ascent); - ok(metrics[0].height == fontmetrics.ascent + fontmetrics.descent, "got %.2f, expected %d\n", - metrics[0].height, fontmetrics.ascent + fontmetrics.descent); - IDWriteTextLayout_Release(layout); /* force 2 lines */ hr = IDWriteFactory_CreateTextLayout(factory, str2W, 5, format, 10000.0, 1000.0, &layout); ok(hr == S_OK, "got 0x%08x\n", hr); memset(metrics, 0, sizeof(metrics)); - count = 2; - hr = IDWriteTextLayout_GetLineMetrics(layout, metrics, 2, &count); + count = 0; + hr = IDWriteTextLayout_GetLineMetrics(layout, metrics, sizeof(metrics)/sizeof(*metrics), &count); ok(hr == S_OK, "got 0x%08x\n", hr); -todo_wine { ok(count == 2, "got %u\n", count); /* baseline is relative to a line, and is not accumulated */ ok(metrics[0].baseline == metrics[1].baseline, "got %.2f, %.2f\n", metrics[0].baseline, metrics[1].baseline); -} + IDWriteTextLayout_Release(layout); IDWriteTextFormat_Release(format); @@ -3130,29 +3403,122 @@ ok(hr == S_OK, "got 0x%08x\n", hr); memset(metrics, 0xcc, sizeof(metrics)); - hr = IDWriteTextLayout_GetLineMetrics(layout, metrics, 6, &count); + count = 0; + hr = IDWriteTextLayout_GetLineMetrics(layout, metrics, sizeof(metrics)/sizeof(*metrics), &count); ok(hr == S_OK, "got 0x%08x\n", hr); -todo_wine ok(count == 6, "got %u\n", count); -todo_wine { ok(metrics[0].length == 2, "got %u\n", metrics[0].length); ok(metrics[1].length == 2, "got %u\n", metrics[1].length); ok(metrics[2].length == 2, "got %u\n", metrics[2].length); ok(metrics[3].length == 1, "got %u\n", metrics[3].length); ok(metrics[4].length == 3, "got %u\n", metrics[4].length); ok(metrics[5].length == 0, "got %u\n", metrics[5].length); -} -todo_wine { ok(metrics[0].newlineLength == 1, "got %u\n", metrics[0].newlineLength); ok(metrics[1].newlineLength == 1, "got %u\n", metrics[1].newlineLength); ok(metrics[2].newlineLength == 1, "got %u\n", metrics[2].newlineLength); ok(metrics[3].newlineLength == 1, "got %u\n", metrics[3].newlineLength); ok(metrics[4].newlineLength == 2, "got %u\n", metrics[4].newlineLength); ok(metrics[5].newlineLength == 0, "got %u\n", metrics[5].newlineLength); -} + + ok(metrics[0].trailingWhitespaceLength == 1, "got %u\n", metrics[0].newlineLength); + ok(metrics[1].trailingWhitespaceLength == 1, "got %u\n", metrics[1].newlineLength); + ok(metrics[2].trailingWhitespaceLength == 1, "got %u\n", metrics[2].newlineLength); + ok(metrics[3].trailingWhitespaceLength == 1, "got %u\n", metrics[3].newlineLength); + ok(metrics[4].trailingWhitespaceLength == 2, "got %u\n", metrics[4].newlineLength); + ok(metrics[5].trailingWhitespaceLength == 0, "got %u\n", metrics[5].newlineLength); + IDWriteTextLayout_Release(layout); + + /* empty text layout */ + hr = IDWriteFactory_CreateTextLayout(factory, strW, 0, format, 100.0f, 300.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 0; + memset(metrics, 0, sizeof(metrics)); + hr = IDWriteTextLayout_GetLineMetrics(layout, metrics, 1, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 1, "got %u\n", count); + ok(metrics[0].length == 0, "got %u\n", metrics[0].length); + ok(metrics[0].trailingWhitespaceLength == 0, "got %u\n", metrics[0].trailingWhitespaceLength); + ok(metrics[0].newlineLength == 0, "got %u\n", metrics[0].newlineLength); + ok(metrics[0].height > 0.0f, "got %f\n", metrics[0].height); + ok(metrics[0].baseline > 0.0f, "got %f\n", metrics[0].baseline); + ok(!metrics[0].isTrimmed, "got %d\n", metrics[0].isTrimmed); + + /* change font size at first position, see if metrics changed */ + range.startPosition = 0; + range.length = 1; + hr = IDWriteTextLayout_SetFontSize(layout, 80.0f, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 0; + hr = IDWriteTextLayout_GetLineMetrics(layout, metrics + 1, 1, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 1, "got %u\n", count); + ok(metrics[1].height > metrics[0].height, "got %f\n", metrics[1].height); + ok(metrics[1].baseline > metrics[0].baseline, "got %f\n", metrics[1].baseline); + + /* revert font size back to format value, set different size for position 1 */ + hr = IDWriteTextLayout_SetFontSize(layout, 12.0f, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + range.startPosition = 1; + range.length = 1; + hr = IDWriteTextLayout_SetFontSize(layout, 80.0f, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + memset(metrics + 1, 0, sizeof(*metrics)); + count = 0; + hr = IDWriteTextLayout_GetLineMetrics(layout, metrics + 1, 1, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 1, "got %u\n", count); + ok(metrics[1].height == metrics[0].height, "got %f\n", metrics[1].height); + ok(metrics[1].baseline == metrics[0].baseline, "got %f\n", metrics[1].baseline); + + IDWriteTextLayout_Release(layout); + + /* text is "a\r" */ + hr = IDWriteFactory_CreateTextLayout(factory, str4W, 2, format, 100.0f, 300.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 0; + memset(metrics, 0, sizeof(metrics)); + hr = IDWriteTextLayout_GetLineMetrics(layout, metrics, sizeof(metrics)/sizeof(*metrics), &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 2, "got %u\n", count); + ok(metrics[0].length == 2, "got %u\n", metrics[0].length); + ok(metrics[0].newlineLength == 1, "got %u\n", metrics[0].newlineLength); + ok(metrics[0].height > 0.0f, "got %f\n", metrics[0].height); + ok(metrics[0].baseline > 0.0f, "got %f\n", metrics[0].baseline); + ok(metrics[1].length == 0, "got %u\n", metrics[1].length); + ok(metrics[1].newlineLength == 0, "got %u\n", metrics[1].newlineLength); + ok(metrics[1].height > 0.0f, "got %f\n", metrics[1].height); + ok(metrics[1].baseline > 0.0f, "got %f\n", metrics[1].baseline); + + range.startPosition = 1; + range.length = 1; + hr = IDWriteTextLayout_SetFontSize(layout, 80.0f, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteTextLayout_GetLineMetrics(layout, metrics + 2, 2, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 2, "got %u\n", count); + ok(metrics[3].height > metrics[1].height, "got %f, old %f\n", metrics[3].height, metrics[1].height); + ok(metrics[3].baseline > metrics[1].baseline, "got %f, old %f\n", metrics[3].baseline, metrics[1].baseline); + + /* revert to original format */ + hr = IDWriteTextLayout_SetFontSize(layout, 12.0f, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IDWriteTextLayout_GetLineMetrics(layout, metrics + 2, 2, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 2, "got %u\n", count); + ok(metrics[3].height == metrics[1].height, "got %f, old %f\n", metrics[3].height, metrics[1].height); + ok(metrics[3].baseline == metrics[1].baseline, "got %f, old %f\n", metrics[3].baseline, metrics[1].baseline); + + IDWriteTextLayout_Release(layout); + IDWriteTextFormat_Release(format); IDWriteFontFace_Release(fontface); IDWriteFactory_Release(factory); @@ -3160,16 +3526,21 @@ static void test_SetTextAlignment(void) { - static const WCHAR str2W[] = {'a','a','a','a','a',0}; static const WCHAR strW[] = {'a',0}; - DWRITE_CLUSTER_METRICS clusters[1]; + + static const WCHAR stringsW[][10] = { + {'a',0}, + {0} + }; + + DWRITE_CLUSTER_METRICS clusters[10]; DWRITE_TEXT_METRICS metrics; IDWriteTextFormat1 *format1; IDWriteTextFormat *format; IDWriteTextLayout *layout; IDWriteFactory *factory; DWRITE_TEXT_ALIGNMENT v; - UINT32 count; + UINT32 count, i; HRESULT hr; factory = create_factory(); @@ -3218,80 +3589,101 @@ else win_skip("IDWriteTextFormat1 is not supported\n"); - count = 0; - hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 1, &count); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(count == 1, "got %u\n", count); + for (i = 0; i < sizeof(stringsW)/sizeof(stringsW[0]); i++) { + FLOAT text_width; - /* maxwidth is 500, leading alignment */ - hr = IDWriteTextLayout_SetTextAlignment(layout, DWRITE_TEXT_ALIGNMENT_LEADING); - ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IDWriteTextFormat_SetTextAlignment(format, DWRITE_TEXT_ALIGNMENT_LEADING); + ok(hr == S_OK, "got 0x%08x\n", hr); - hr = IDWriteTextLayout_GetMetrics(layout, &metrics); - ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IDWriteFactory_CreateTextLayout(factory, stringsW[i], lstrlenW(stringsW[i]), format, 500.0f, 100.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); - ok(metrics.left == 0.0, "got %.2f\n", metrics.left); - ok(metrics.width == clusters[0].width, "got %.2f\n", metrics.width); - ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth); - ok(metrics.lineCount == 1, "got %d\n", metrics.lineCount); + hr = IDWriteTextLayout_SetWordWrapping(layout, DWRITE_WORD_WRAPPING_NO_WRAP); + ok(hr == S_OK, "got 0x%08x\n", hr); - /* maxwidth is 500, trailing alignment */ - hr = IDWriteTextLayout_SetTextAlignment(layout, DWRITE_TEXT_ALIGNMENT_TRAILING); - ok(hr == S_OK, "got 0x%08x\n", hr); + count = 0; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, sizeof(clusters)/sizeof(*clusters), &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + if (lstrlenW(stringsW[i])) + ok(count > 0, "got %u\n", count); + else + ok(count == 0, "got %u\n", count); - hr = IDWriteTextLayout_GetMetrics(layout, &metrics); - ok(hr == S_OK, "got 0x%08x\n", hr); + text_width = 0.0f; + while (count) + text_width += clusters[--count].width; - ok(metrics.left == metrics.layoutWidth - metrics.width, "got %.2f\n", metrics.left); - ok(metrics.width == clusters[0].width, "got %.2f\n", metrics.width); - ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth); - ok(metrics.lineCount == 1, "got %d\n", metrics.lineCount); - IDWriteTextLayout_Release(layout); + /* maxwidth is 500, leading alignment */ + hr = IDWriteTextLayout_SetTextAlignment(layout, DWRITE_TEXT_ALIGNMENT_LEADING); + ok(hr == S_OK, "got 0x%08x\n", hr); - /* initially created with trailing alignment */ - hr = IDWriteTextFormat_SetTextAlignment(format, DWRITE_TEXT_ALIGNMENT_TRAILING); - ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + ok(hr == S_OK, "got 0x%08x\n", hr); - hr = IDWriteFactory_CreateTextLayout(factory, strW, 1, format, 500.0, 100.0, &layout); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(metrics.left == 0.0f, "got %.2f\n", metrics.left); + ok(metrics.width == text_width, "got %.2f\n", metrics.width); + ok(metrics.layoutWidth == 500.0f, "got %.2f\n", metrics.layoutWidth); + ok(metrics.lineCount == 1, "got %d\n", metrics.lineCount); - hr = IDWriteTextLayout_GetMetrics(layout, &metrics); - ok(hr == S_OK, "got 0x%08x\n", hr); + /* maxwidth is 500, trailing alignment */ + hr = IDWriteTextLayout_SetTextAlignment(layout, DWRITE_TEXT_ALIGNMENT_TRAILING); + ok(hr == S_OK, "got 0x%08x\n", hr); - ok(metrics.left == metrics.layoutWidth - metrics.width, "got %.2f\n", metrics.left); - ok(metrics.width == clusters[0].width, "got %.2f\n", metrics.width); - ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth); - ok(metrics.lineCount == 1, "got %d\n", metrics.lineCount); - IDWriteTextLayout_Release(layout); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + ok(hr == S_OK, "got 0x%08x\n", hr); - /* max width less than total run width, trailing alignment */ - hr = IDWriteTextFormat_SetWordWrapping(format, DWRITE_WORD_WRAPPING_NO_WRAP); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(metrics.left == metrics.layoutWidth - metrics.width, "got %.2f\n", metrics.left); + ok(metrics.width == text_width, "got %.2f\n", metrics.width); + ok(metrics.layoutWidth == 500.0f, "got %.2f\n", metrics.layoutWidth); + ok(metrics.lineCount == 1, "got %d\n", metrics.lineCount); + IDWriteTextLayout_Release(layout); - hr = IDWriteFactory_CreateTextLayout(factory, str2W, 5, format, 2*clusters[0].width, 100.0, &layout); - ok(hr == S_OK, "got 0x%08x\n", hr); - hr = IDWriteTextLayout_GetMetrics(layout, &metrics); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(metrics.left == metrics.layoutWidth - metrics.width, "got %.2f\n", metrics.left); -todo_wine - ok(metrics.width == 5*clusters[0].width, "got %.2f\n", metrics.width); - ok(metrics.lineCount == 1, "got %d\n", metrics.lineCount); - IDWriteTextLayout_Release(layout); + /* initially created with trailing alignment */ + hr = IDWriteTextFormat_SetTextAlignment(format, DWRITE_TEXT_ALIGNMENT_TRAILING); + ok(hr == S_OK, "got 0x%08x\n", hr); - /* maxwidth is 500, centered */ - hr = IDWriteTextFormat_SetTextAlignment(format, DWRITE_TEXT_ALIGNMENT_CENTER); - ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IDWriteFactory_CreateTextLayout(factory, stringsW[i], lstrlenW(stringsW[i]), format, 500.0f, 100.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); - hr = IDWriteFactory_CreateTextLayout(factory, str2W, 5, format, 500.0, 100.0, &layout); - ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + ok(hr == S_OK, "got 0x%08x\n", hr); - hr = IDWriteTextLayout_GetMetrics(layout, &metrics); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(metrics.left == (metrics.layoutWidth - metrics.width) / 2.0, "got %.2f\n", metrics.left); - ok(metrics.width == 5*clusters[0].width, "got %.2f\n", metrics.width); - ok(metrics.lineCount == 1, "got %d\n", metrics.lineCount); + ok(metrics.left == metrics.layoutWidth - metrics.width, "got %.2f\n", metrics.left); + ok(metrics.width == text_width, "got %.2f\n", metrics.width); + ok(metrics.layoutWidth == 500.0f, "got %.2f\n", metrics.layoutWidth); + ok(metrics.lineCount == 1, "got %d\n", metrics.lineCount); + IDWriteTextLayout_Release(layout); - IDWriteTextLayout_Release(layout); + if (lstrlenW(stringsW[i]) > 0) { + /* max width less than total run width, trailing alignment */ + hr = IDWriteTextFormat_SetWordWrapping(format, DWRITE_WORD_WRAPPING_NO_WRAP); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFactory_CreateTextLayout(factory, stringsW[i], lstrlenW(stringsW[i]), format, clusters[0].width, 100.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(metrics.left == metrics.layoutWidth - metrics.width, "got %.2f\n", metrics.left); + ok(metrics.width == text_width, "got %.2f\n", metrics.width); + ok(metrics.lineCount == 1, "got %d\n", metrics.lineCount); + IDWriteTextLayout_Release(layout); + } + + /* maxwidth is 500, centered */ + hr = IDWriteTextFormat_SetTextAlignment(format, DWRITE_TEXT_ALIGNMENT_CENTER); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFactory_CreateTextLayout(factory, stringsW[i], lstrlenW(stringsW[i]), format, 500.0f, 100.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(metrics.left == (metrics.layoutWidth - metrics.width) / 2.0f, "got %.2f\n", metrics.left); + ok(metrics.width == text_width, "got %.2f\n", metrics.width); + ok(metrics.lineCount == 1, "got %d\n", metrics.lineCount); + + IDWriteTextLayout_Release(layout); + } IDWriteTextFormat_Release(format); IDWriteFactory_Release(factory); @@ -3664,11 +4056,13 @@ static void test_SetWordWrapping(void) { - static const WCHAR strW[] = {'a',0}; + static const WCHAR strW[] = {'a',' ','s','o','m','e',' ','t','e','x','t',' ','a','n','d', + ' ','a',' ','b','i','t',' ','m','o','r','e','\n','b'}; IDWriteTextFormat *format; IDWriteTextLayout *layout; IDWriteFactory *factory; DWRITE_WORD_WRAPPING v; + UINT32 count; HRESULT hr; factory = create_factory(); @@ -3680,7 +4074,7 @@ v = IDWriteTextFormat_GetWordWrapping(format); ok(v == DWRITE_WORD_WRAPPING_WRAP, "got %d\n", v); - hr = IDWriteFactory_CreateTextLayout(factory, strW, 1, format, 500.0, 100.0, &layout); + hr = IDWriteFactory_CreateTextLayout(factory, strW, sizeof(strW)/sizeof(WCHAR), format, 10.0f, 100.0f, &layout); ok(hr == S_OK, "got 0x%08x\n", hr); v = IDWriteTextLayout_GetWordWrapping(layout); @@ -3695,6 +4089,23 @@ v = IDWriteTextFormat_GetWordWrapping(format); ok(v == DWRITE_WORD_WRAPPING_WRAP, "got %d\n", v); + /* disable wrapping, text has explicit newline */ + hr = IDWriteTextLayout_SetWordWrapping(layout, DWRITE_WORD_WRAPPING_NO_WRAP); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 0; + hr = IDWriteTextLayout_GetLineMetrics(layout, NULL, 0, &count); + ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr); + ok(count == 2, "got %u\n", count); + + hr = IDWriteTextLayout_SetWordWrapping(layout, DWRITE_WORD_WRAPPING_WRAP); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 0; + hr = IDWriteTextLayout_GetLineMetrics(layout, NULL, 0, &count); + ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr); + ok(count > 2, "got %u\n", count); + IDWriteTextLayout_Release(layout); IDWriteTextFormat_Release(format); IDWriteFactory_Release(factory); @@ -4271,6 +4682,139 @@ IDWriteFactory_Release(factory); } +static const struct drawcall_entry drawunderline_seq[] = { + { DRAW_GLYPHRUN, {'a','e',0x0300,0} }, /* reported runs can't mix different underline values */ + { DRAW_GLYPHRUN, {'d',0} }, + { DRAW_UNDERLINE, {0}, {'e','n','-','u','s',0} }, + { DRAW_LAST_KIND } +}; + +static const struct drawcall_entry drawunderline2_seq[] = { + { DRAW_GLYPHRUN, {'a',0} }, + { DRAW_GLYPHRUN, {'e',0} }, + { DRAW_UNDERLINE, {0}, {'e','n','-','u','s',0} }, + { DRAW_LAST_KIND } +}; + +static const struct drawcall_entry drawunderline3_seq[] = { + { DRAW_GLYPHRUN, {'a',0} }, + { DRAW_GLYPHRUN, {'e',0} }, + { DRAW_UNDERLINE, {0}, {'e','n','-','c','a',0} }, + { DRAW_UNDERLINE, {0}, {'e','n','-','u','s',0} }, + { DRAW_LAST_KIND } +}; + +static const struct drawcall_entry drawunderline4_seq[] = { + { DRAW_GLYPHRUN, {'a',0} }, + { DRAW_GLYPHRUN, {'e',0} }, + { DRAW_UNDERLINE, {0}, {'e','n','-','u','s',0} }, + { DRAW_STRIKETHROUGH }, + { DRAW_LAST_KIND } +}; + +static void test_SetUnderline(void) +{ + static const WCHAR encaW[] = {'e','n','-','C','A',0}; + static const WCHAR strW[] = {'a','e',0x0300,'d',0}; /* accent grave */ + DWRITE_CLUSTER_METRICS clusters[4]; + IDWriteTextFormat *format; + IDWriteTextLayout *layout; + DWRITE_TEXT_RANGE range; + IDWriteFactory *factory; + UINT32 count; + HRESULT hr; + + factory = create_factory(); + + hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 0; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, sizeof(clusters)/sizeof(clusters[0]), &count); + ok(hr == S_OK, "got 0x%08x\n", hr); +todo_wine + ok(count == 3, "got %u\n", count); + + range.startPosition = 0; + range.length = 2; + hr = IDWriteTextLayout_SetUnderline(layout, TRUE, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 0; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, sizeof(clusters)/sizeof(clusters[0]), &count); + ok(hr == S_OK, "got 0x%08x\n", hr); +todo_wine + ok(count == 3, "got %u\n", count); + + flush_sequence(sequences, RENDERER_ID); + hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok_sequence(sequences, RENDERER_ID, drawunderline_seq, "draw underline test", TRUE); + + IDWriteTextLayout_Release(layout); + + /* 2 characters, same font, significantly different font size. Set underline for both, see how many + underline drawing calls is there. */ + hr = IDWriteFactory_CreateTextLayout(factory, strW, 2, format, 1000.0f, 1000.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + range.startPosition = 0; + range.length = 2; + hr = IDWriteTextLayout_SetUnderline(layout, TRUE, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + range.startPosition = 0; + range.length = 1; + hr = IDWriteTextLayout_SetFontSize(layout, 100.0f, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + flush_sequence(sequences, RENDERER_ID); + hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0f, 0.0f); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok_sequence(sequences, RENDERER_ID, drawunderline2_seq, "draw underline test 2", FALSE); + + /* now set different locale for second char, draw again */ + range.startPosition = 0; + range.length = 1; + hr = IDWriteTextLayout_SetLocaleName(layout, encaW, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + flush_sequence(sequences, RENDERER_ID); + hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0f, 0.0f); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok_sequence(sequences, RENDERER_ID, drawunderline3_seq, "draw underline test 2", FALSE); + + IDWriteTextLayout_Release(layout); + + /* 2 characters, same font properties, first with strikethrough, both underlined */ + hr = IDWriteFactory_CreateTextLayout(factory, strW, 2, format, 1000.0f, 1000.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + range.startPosition = 0; + range.length = 1; + hr = IDWriteTextLayout_SetStrikethrough(layout, TRUE, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + range.startPosition = 0; + range.length = 2; + hr = IDWriteTextLayout_SetUnderline(layout, TRUE, range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + flush_sequence(sequences, RENDERER_ID); + hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0f, 0.0f); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok_sequence(sequences, RENDERER_ID, drawunderline4_seq, "draw underline test 4", FALSE); + + IDWriteTextLayout_Release(layout); + + IDWriteTextFormat_Release(format); + IDWriteFactory_Release(factory); +} + START_TEST(layout) { static const WCHAR ctrlstrW[] = {0x202a,0}; @@ -4321,6 +4865,7 @@ test_SetTypography(); test_SetLastLineWrapping(); test_SetOpticalAlignment(); + test_SetUnderline(); IDWriteFactory_Release(factory); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/gdi32/freetype.c wine-staging-1.9.3~ubuntu12.04.1/dlls/gdi32/freetype.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/gdi32/freetype.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/gdi32/freetype.c 2016-02-08 19:32:34.000000000 +0000 @@ -162,6 +162,7 @@ MAKE_FUNCPTR(FT_Select_Charmap); MAKE_FUNCPTR(FT_Set_Charmap); MAKE_FUNCPTR(FT_Set_Pixel_Sizes); +MAKE_FUNCPTR(FT_Vector_Length); MAKE_FUNCPTR(FT_Vector_Transform); MAKE_FUNCPTR(FT_Vector_Unit); static FT_Error (*pFT_Outline_Embolden)(FT_Outline *, FT_Pos); @@ -1942,9 +1943,17 @@ { DWORD flags = 0; FT_ULong table_size = 0; + FT_WinFNT_HeaderRec winfnt_header; if (ft_face->style_flags & FT_STYLE_FLAG_ITALIC) flags |= NTM_ITALIC; if (ft_face->style_flags & FT_STYLE_FLAG_BOLD) flags |= NTM_BOLD; + + /* fixup the flag for our fake-bold implementation. */ + if (!FT_IS_SCALABLE( ft_face ) && + !pFT_Get_WinFNT_Header( ft_face, &winfnt_header ) && + winfnt_header.weight > FW_NORMAL ) + flags |= NTM_BOLD; + if (flags == 0) flags = NTM_REGULAR; if (!pFT_Load_Sfnt_Table( ft_face, FT_MAKE_TAG( 'C','F','F',' ' ), 0, NULL, &table_size )) @@ -4076,6 +4085,7 @@ LOAD_FUNCPTR(FT_Select_Charmap) LOAD_FUNCPTR(FT_Set_Charmap) LOAD_FUNCPTR(FT_Set_Pixel_Sizes) + LOAD_FUNCPTR(FT_Vector_Length) LOAD_FUNCPTR(FT_Vector_Transform) LOAD_FUNCPTR(FT_Vector_Unit) #undef LOAD_FUNCPTR @@ -6376,42 +6386,46 @@ return !memcmp(matrix, &identity, sizeof(MAT2)); } -static void synthesize_bold_glyph(FT_GlyphSlot glyph, LONG ppem, FT_Glyph_Metrics *metrics) +static inline FT_Vector normalize_vector(FT_Vector *vec) { - FT_Error err; - static UINT once; + FT_Vector out; + FT_Fixed len; + len = pFT_Vector_Length(vec); + if (len) { + out.x = (vec->x << 6) / len; + out.y = (vec->y << 6) / len; + } + else + out.x = out.y = 0; + return out; +} - switch(glyph->format) { - case FT_GLYPH_FORMAT_OUTLINE: - { - FT_Pos strength; - FT_BBox bbox; - if(!pFT_Outline_Embolden) - break; +static BOOL get_bold_glyph_outline(FT_GlyphSlot glyph, LONG ppem, FT_Glyph_Metrics *metrics) +{ + FT_Error err; + FT_Pos strength; + FT_BBox bbox; - strength = MulDiv(ppem, 1 << 6, 24); - err = pFT_Outline_Embolden(&glyph->outline, strength); - if(err) { - TRACE("FT_Ouline_Embolden returns %d, ignored\n", err); - break; - } + if(glyph->format != FT_GLYPH_FORMAT_OUTLINE) + return FALSE; + if(!pFT_Outline_Embolden) + return FALSE; - pFT_Outline_Get_CBox(&glyph->outline, &bbox); - metrics->width = bbox.xMax - bbox.xMin; - metrics->height = bbox.yMax - bbox.yMin; - metrics->horiBearingX = bbox.xMin; - metrics->horiBearingY = bbox.yMax; - metrics->horiAdvance += (1 << 6); - metrics->vertAdvance += (1 << 6); - metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2; - metrics->vertBearingY = (metrics->vertAdvance - metrics->height) / 2; - break; - } - default: - if (!once++) - WARN("Emboldening format 0x%x is not supported\n", glyph->format); - return; + strength = MulDiv(ppem, 1 << 6, 24); + err = pFT_Outline_Embolden(&glyph->outline, strength); + if(err) { + TRACE("FT_Ouline_Embolden returns %d\n", err); + return FALSE; } + + pFT_Outline_Get_CBox(&glyph->outline, &bbox); + metrics->width = bbox.xMax - bbox.xMin; + metrics->height = bbox.yMax - bbox.yMin; + metrics->horiBearingX = bbox.xMin; + metrics->horiBearingY = bbox.yMax; + metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2; + metrics->vertBearingY = (metrics->vertAdvance - metrics->height) / 2; + return TRUE; } static inline BYTE get_max_level( UINT format ) @@ -6436,6 +6450,68 @@ return (orientation == 1 || orientation == 3); } +static FT_Vector get_advance_metric(GdiFont *incoming_font, GdiFont *font, + const FT_Glyph_Metrics *metrics, + const FT_Matrix *transMat, BOOL vertical_metrics) +{ + FT_Vector adv; + FT_Fixed base_advance, em_scale = 0; + BOOL fixed_pitch_full = FALSE; + + if (vertical_metrics) + base_advance = metrics->vertAdvance; + else + base_advance = metrics->horiAdvance; + + adv.x = base_advance; + adv.y = 0; + + /* In fixed-pitch font, we adjust the fullwidth character advance so that + they have double halfwidth character width. E.g. if the font is 19 ppem, + we return 20 (not 19) for fullwidth characters as we return 10 for + halfwidth characters. */ + if(FT_IS_SCALABLE(incoming_font->ft_face) && + (incoming_font->potm || get_outline_text_metrics(incoming_font)) && + !(incoming_font->potm->otmTextMetrics.tmPitchAndFamily & TMPF_FIXED_PITCH)) { + UINT avg_advance; + em_scale = MulDiv(incoming_font->ppem, 1 << 16, + incoming_font->ft_face->units_per_EM); + avg_advance = pFT_MulFix(incoming_font->ntmAvgWidth, em_scale); + fixed_pitch_full = (avg_advance > 0 && + (base_advance + 63) >> 6 == + pFT_MulFix(incoming_font->ntmAvgWidth*2, em_scale)); + if (fixed_pitch_full && !transMat) + adv.x = (avg_advance * 2) << 6; + } + + if (transMat) { + pFT_Vector_Transform(&adv, transMat); + if (fixed_pitch_full && adv.y == 0) { + FT_Vector vec; + vec.x = incoming_font->ntmAvgWidth; + vec.y = 0; + pFT_Vector_Transform(&vec, transMat); + adv.x = (pFT_MulFix(vec.x, em_scale) * 2) << 6; + } + } + + if (font->fake_bold) { + if (!transMat) + adv.x += 1 << 6; + else { + FT_Vector fake_bold_adv, vec = { 1 << 6, 0 }; + pFT_Vector_Transform(&vec, transMat); + fake_bold_adv = normalize_vector(&vec); + adv.x += fake_bold_adv.x; + adv.y += fake_bold_adv.y; + } + } + + adv.x = (adv.x + 63) & -64; + adv.y = -((adv.y + 63) & -64); + return adv; +} + static unsigned int get_native_glyph_outline(FT_Outline *outline, unsigned int buflen, char *buf) { TTPOLYGONHEADER *pph; @@ -6648,7 +6724,8 @@ DWORD width, height, pitch, needed = 0; FT_Bitmap ft_bitmap; FT_Error err; - INT left, right, top = 0, bottom = 0, adv; + INT left, right, top = 0, bottom = 0; + FT_Vector adv; INT origin_x = 0, origin_y = 0; FT_Angle angle = 0; FT_Int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; @@ -6660,8 +6737,6 @@ BOOL tategaki = (font->name[0] == '@'); BOOL vertical_metrics; UINT original_index; - LONG avgAdvance = 0; - FT_Fixed em_scale; TRACE("%p, %04x, %08x, %p, %08x, %p, %p\n", font, glyph, format, lpgm, buflen, buf, lpmat); @@ -6842,8 +6917,10 @@ } metrics = ft_face->glyph->metrics; - if(font->fake_bold) - synthesize_bold_glyph(ft_face->glyph, font->ppem, &metrics); + if(font->fake_bold) { + if (!get_bold_glyph_outline(ft_face->glyph, font->ppem, &metrics) && metrics.width) + metrics.width += 1 << 6; + } /* Some poorly-created fonts contain glyphs that exceed the boundaries set * by the text metrics. The proper behavior is to clip the glyph metrics to @@ -6860,32 +6937,13 @@ /* metrics.width = min( metrics.width, ptm->tmMaxCharWidth << 6 ); */ } - em_scale = MulDiv(incoming_font->ppem, 1 << 16, incoming_font->ft_face->units_per_EM); - - if(FT_IS_SCALABLE(incoming_font->ft_face) && !font->fake_bold) { - TEXTMETRICW tm; - if (get_text_metrics(incoming_font, &tm) && - !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH)) { - avgAdvance = pFT_MulFix(incoming_font->ntmAvgWidth, em_scale); - if (avgAdvance && - (metrics.horiAdvance+63) >> 6 == pFT_MulFix(incoming_font->ntmAvgWidth*2, em_scale)) - TRACE("Fixed-pitch full-width character detected\n"); - else - avgAdvance = 0; /* cancel this feature */ - } - } - if(!needsTransform) { left = (INT)(metrics.horiBearingX) & -64; right = (INT)((metrics.horiBearingX + metrics.width) + 63) & -64; - if (!avgAdvance) - adv = (INT)(metrics.horiAdvance + 63) >> 6; - else - adv = (INT)avgAdvance * 2; - top = (metrics.horiBearingY + 63) & -64; bottom = (metrics.horiBearingY - metrics.height) & -64; - gm.gmCellIncX = adv; + adv = get_advance_metric(incoming_font, font, &metrics, NULL, vertical_metrics); + gm.gmCellIncX = adv.x >> 6; gm.gmCellIncY = 0; origin_x = left; origin_y = top; @@ -6941,36 +6999,11 @@ } TRACE("transformed box: (%d,%d - %d,%d)\n", left, top, right, bottom); - if (vertical_metrics) - vec.x = metrics.vertAdvance; - else - vec.x = metrics.horiAdvance; - vec.y = 0; - pFT_Vector_Transform(&vec, &transMat); - gm.gmCellIncY = -((vec.y+63) >> 6); - if (!avgAdvance || vec.y) - gm.gmCellIncX = (vec.x+63) >> 6; - else { - vec.x = incoming_font->ntmAvgWidth; - vec.y = 0; - pFT_Vector_Transform(&vec, &transMat); - gm.gmCellIncX = pFT_MulFix(vec.x, em_scale) * 2; - } + adv = get_advance_metric(incoming_font, font, &metrics, &transMat, vertical_metrics); + gm.gmCellIncX = adv.x >> 6; + gm.gmCellIncY = adv.y >> 6; - if (vertical_metrics) - vec.x = metrics.vertAdvance; - else - vec.x = metrics.horiAdvance; - vec.y = 0; - pFT_Vector_Transform(&vec, &transMatUnrotated); - if (!avgAdvance || vec.y) - adv = (vec.x+63) >> 6; - else { - vec.x = incoming_font->ntmAvgWidth; - vec.y = 0; - pFT_Vector_Transform(&vec, &transMatUnrotated); - adv = pFT_MulFix(vec.x, em_scale) * 2; - } + adv = get_advance_metric(incoming_font, font, &metrics, &transMatUnrotated, vertical_metrics); vec.x = lsb; vec.y = 0; @@ -6993,7 +7026,7 @@ gm.gmptGlyphOrigin.x = origin_x >> 6; gm.gmptGlyphOrigin.y = origin_y >> 6; if (!abc->abcB) abc->abcB = 1; - abc->abcC = adv - abc->abcA - abc->abcB; + abc->abcC = (adv.x >> 6) - abc->abcA - abc->abcB; TRACE("%u,%u,%s,%d,%d\n", gm.gmBlackBoxX, gm.gmBlackBoxY, wine_dbgstr_point(&gm.gmptGlyphOrigin), @@ -7037,7 +7070,17 @@ INT w = min( pitch, (ft_face->glyph->bitmap.width + 7) >> 3 ); INT h = min( height, ft_face->glyph->bitmap.rows ); while(h--) { - memcpy(dst, src, w); + if (!font->fake_bold) + memcpy(dst, src, w); + else { + INT x; + dst[0] = 0; + for (x = 0; x < w; x++) { + dst[x ] = (dst[x] & 0x80) | (src[x] >> 1) | src[x]; + if (x+1 < pitch) + dst[x+1] = (src[x] & 0x01) << 7; + } + } src += ft_face->glyph->bitmap.pitch; dst += pitch; } @@ -7093,8 +7136,12 @@ INT x; memset( buf, 0, needed ); while(h--) { - for(x = 0; x < pitch && x < ft_face->glyph->bitmap.width; x++) - if (src[x / 8] & masks[x % 8]) dst[x] = max_level; + for(x = 0; x < pitch && x < ft_face->glyph->bitmap.width; x++) { + if (src[x / 8] & masks[x % 8]) { + dst[x] = max_level; + if (font->fake_bold && x+1 < pitch) dst[x+1] = max_level; + } + } src += ft_face->glyph->bitmap.pitch; dst += pitch; } @@ -7168,7 +7215,10 @@ for (x = 0; x < width && x < ft_face->glyph->bitmap.width; x++) { if ( src[x / 8] & masks[x % 8] ) + { ((unsigned int *)dst)[x] = ~0u; + if (font->fake_bold && x+1 < width) ((unsigned int *)dst)[x+1] = ~0u; + } } src += src_pitch; dst += pitch; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/gdi32/tests/font.c wine-staging-1.9.3~ubuntu12.04.1/dlls/gdi32/tests/font.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/gdi32/tests/font.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/gdi32/tests/font.c 2016-02-08 19:32:34.000000000 +0000 @@ -6303,13 +6303,18 @@ static void test_fake_bold_font(void) { + static const MAT2 x2_mat = { {0,2}, {0,0}, {0,0}, {0,2} }; HDC hdc; - HFONT hfont, hfont_old; LOGFONTA lf; BOOL ret; - TEXTMETRICA tm[2]; - ABC abc[2]; - INT w[2]; + struct glyph_data { + TEXTMETRICA tm; + ABC abc; + INT w; + GLYPHMETRICS gm; + } data[2]; + int i; + DWORD r; if (!pGetCharWidth32A || !pGetCharABCWidthsA) { win_skip("GetCharWidth32A/GetCharABCWidthA is not available on this platform\n"); @@ -6319,45 +6324,51 @@ /* Test outline font */ memset(&lf, 0, sizeof(lf)); strcpy(lf.lfFaceName, "Wingdings"); - lf.lfWeight = FW_NORMAL; lf.lfCharSet = SYMBOL_CHARSET; - hfont = CreateFontIndirectA(&lf); hdc = GetDC(NULL); - hfont_old = SelectObject(hdc, hfont); - /* base metrics */ - ret = GetTextMetricsA(hdc, &tm[0]); - ok(ret, "got %d\n", ret); - ret = pGetCharABCWidthsA(hdc, 0x76, 0x76, &abc[0]); - ok(ret, "got %d\n", ret); - - lf.lfWeight = FW_BOLD; - hfont = CreateFontIndirectA(&lf); - DeleteObject(SelectObject(hdc, hfont)); - - /* bold metrics */ - ret = GetTextMetricsA(hdc, &tm[1]); - ok(ret, "got %d\n", ret); - ret = pGetCharABCWidthsA(hdc, 0x76, 0x76, &abc[1]); - ok(ret, "got %d\n", ret); + for (i = 0; i <= 1; i++) + { + HFONT hfont, hfont_old; + + lf.lfWeight = i ? FW_BOLD : FW_NORMAL; + hfont = CreateFontIndirectA(&lf); + hfont_old = SelectObject(hdc, hfont); + + ret = GetTextMetricsA(hdc, &data[i].tm); + ok(ret, "got %d\n", ret); + ret = pGetCharABCWidthsA(hdc, 0x76, 0x76, &data[i].abc); + ok(ret, "got %d\n", ret); + data[i].w = data[i].abc.abcA + data[i].abc.abcB + data[i].abc.abcC; + r = GetGlyphOutlineA(hdc, 0x76, GGO_METRICS, &data[i].gm, 0, NULL, &x2_mat); + ok(r != GDI_ERROR, "got %d\n", ret); - DeleteObject(SelectObject(hdc, hfont_old)); + SelectObject(hdc, hfont_old); + DeleteObject(hfont); + } ReleaseDC(NULL, hdc); /* compare results (outline) */ - ok(tm[0].tmHeight == tm[1].tmHeight, "expected %d, got %d\n", tm[0].tmHeight, tm[1].tmHeight); - ok(tm[0].tmAscent == tm[1].tmAscent, "expected %d, got %d\n", tm[0].tmAscent, tm[1].tmAscent); - ok(tm[0].tmDescent == tm[1].tmDescent, "expected %d, got %d\n", tm[0].tmDescent, tm[1].tmDescent); - ok((tm[0].tmAveCharWidth + 1) == tm[1].tmAveCharWidth, - "expected %d, got %d\n", tm[0].tmAveCharWidth + 1, tm[1].tmAveCharWidth); - ok((tm[0].tmMaxCharWidth + 1) == tm[1].tmMaxCharWidth, - "expected %d, got %d\n", tm[0].tmMaxCharWidth + 1, tm[1].tmMaxCharWidth); - ok(tm[0].tmOverhang == tm[1].tmOverhang, "expected %d, got %d\n", tm[0].tmOverhang, tm[1].tmOverhang); - w[0] = abc[0].abcA + abc[0].abcB + abc[0].abcC; - w[1] = abc[1].abcA + abc[1].abcB + abc[1].abcC; - ok((w[0] + 1) == w[1], "expected %d, got %d\n", w[0] + 1, w[1]); - + ok(data[0].tm.tmHeight == data[1].tm.tmHeight, + "expected %d, got %d\n", data[0].tm.tmHeight, data[1].tm.tmHeight); + ok(data[0].tm.tmAscent == data[1].tm.tmAscent, + "expected %d, got %d\n", data[0].tm.tmAscent, data[1].tm.tmAscent); + ok(data[0].tm.tmDescent == data[1].tm.tmDescent, + "expected %d, got %d\n", data[0].tm.tmDescent, data[1].tm.tmDescent); + ok(data[0].tm.tmAveCharWidth + 1 == data[1].tm.tmAveCharWidth, + "expected %d, got %d\n", data[0].tm.tmAveCharWidth + 1, data[1].tm.tmAveCharWidth); + ok(data[0].tm.tmMaxCharWidth + 1 == data[1].tm.tmMaxCharWidth, + "expected %d, got %d\n", data[0].tm.tmMaxCharWidth + 1, data[1].tm.tmMaxCharWidth); + ok(data[0].tm.tmOverhang == data[1].tm.tmOverhang, + "expected %d, got %d\n", data[0].tm.tmOverhang, data[1].tm.tmOverhang); + ok(data[0].w + 1 == data[1].w, + "expected %d, got %d\n", data[0].w + 1, data[1].w); + + ok(data[0].gm.gmCellIncX + 1 == data[1].gm.gmCellIncX, + "expected %d, got %d\n", data[0].gm.gmCellIncX + 1, data[1].gm.gmCellIncX); + ok(data[0].gm.gmCellIncY == data[1].gm.gmCellIncY, + "expected %d, got %d\n", data[0].gm.gmCellIncY, data[1].gm.gmCellIncY); } static void test_bitmap_font_glyph_index(void) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/gdiplus/gdiplus_private.h wine-staging-1.9.3~ubuntu12.04.1/dlls/gdiplus/gdiplus_private.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/gdiplus/gdiplus_private.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/gdiplus/gdiplus_private.h 2016-02-08 19:32:34.000000000 +0000 @@ -197,6 +197,7 @@ REAL offset; /* dash offset */ GpBrush *brush; GpPenAlignment align; + GpMatrix transform; }; struct GpGraphics{ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/gdiplus/pen.c wine-staging-1.9.3~ubuntu12.04.1/dlls/gdiplus/pen.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/gdiplus/pen.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/gdiplus/pen.c 2016-02-08 19:32:34.000000000 +0000 @@ -171,6 +171,7 @@ gp_pen->offset = 0.0; gp_pen->customstart = NULL; gp_pen->customend = NULL; + GdipSetMatrixElements(&gp_pen->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); if(!((gp_pen->unit == UnitWorld) || (gp_pen->unit == UnitPixel))) { FIXME("UnitWorld, UnitPixel only supported units\n"); @@ -448,17 +449,14 @@ GpStatus WINGDIPAPI GdipGetPenTransform(GpPen *pen, GpMatrix *matrix) { - static int calls; - TRACE("(%p,%p)\n", pen, matrix); if(!pen || !matrix) return InvalidParameter; - if(!(calls++)) - FIXME("not implemented\n"); + *matrix = pen->transform; - return NotImplemented; + return Ok; } GpStatus WINGDIPAPI GdipTranslatePenTransform(GpPen *pen, REAL dx, REAL dy, GpMatrixOrder order) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/gdiplus/tests/pen.c wine-staging-1.9.3~ubuntu12.04.1/dlls/gdiplus/tests/pen.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/gdiplus/tests/pen.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/gdiplus/tests/pen.c 2016-02-08 19:32:34.000000000 +0000 @@ -366,6 +366,69 @@ GdipDeletePen(pen); } +static void test_transform(void) +{ + GpStatus status; + GpPen *pen; + GpMatrix *matrix, *matrix2; + REAL values[6]; + + status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen); + expect(Ok, status); + + status = GdipCreateMatrix(&matrix); + expect(Ok, status); + + status = GdipGetPenTransform(pen, matrix); + expect(Ok, status); + + status = GdipGetMatrixElements(matrix, values); + expect(Ok, status); + + expectf(1.0, values[0]); + expectf(0.0, values[1]); + expectf(0.0, values[2]); + expectf(1.0, values[3]); + expectf(0.0, values[4]); + expectf(0.0, values[5]); + + GdipCreateMatrix2(3.0, -2.0, 5.0, 2.0, 6.0, 3.0, &matrix2); + status = GdipSetPenTransform(pen, matrix2); + todo_wine expect(Ok, status); + GdipDeleteMatrix(matrix2); + + status = GdipGetPenTransform(pen, matrix); + expect(Ok, status); + status = GdipGetMatrixElements(matrix, values); + expect(Ok, status); +todo_wine { + expectf(3.0, values[0]); + expectf(-2.0, values[1]); + expectf(5.0, values[2]); + expectf(2.0, values[3]); + expectf(6.0, values[4]); + expectf(3.0, values[5]); +} + status = GdipResetPenTransform(pen); + todo_wine expect(Ok, status); + + status = GdipGetPenTransform(pen, matrix); + expect(Ok, status); + status = GdipGetMatrixElements(matrix, values); + expect(Ok, status); + + expectf(1.0, values[0]); + expectf(0.0, values[1]); + expectf(0.0, values[2]); + expectf(1.0, values[3]); + expectf(0.0, values[4]); + expectf(0.0, values[5]); + + GdipDeletePen(pen); + + GdipDeleteMatrix(matrix); +} + START_TEST(pen) { struct GdiplusStartupInput gdiplusStartupInput; @@ -387,6 +450,7 @@ test_customcap(); test_penfilltype(); test_compoundarray(); + test_transform(); GdiplusShutdown(gdiplusToken); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/hidclass.sys/device.c wine-staging-1.9.3~ubuntu12.04.1/dlls/hidclass.sys/device.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/hidclass.sys/device.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/hidclass.sys/device.c 2016-02-08 19:32:34.000000000 +0000 @@ -261,7 +261,7 @@ NTSTATUS ntrc; BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; - events[0] = CreateEventA(NULL, FALSE, FALSE, NULL); + events[0] = CreateEventA(NULL, TRUE, FALSE, NULL); events[1] = ext->halt_event; if (ext->information.Polled) @@ -336,12 +336,13 @@ if (ntrc == STATUS_PENDING) { - rc = WaitForMultipleObjects(2, events, FALSE, INFINITE); - - if (rc == WAIT_OBJECT_0 + 1) - exit_now = TRUE; + WaitForMultipleObjects(2, events, FALSE, INFINITE); } + rc = WaitForSingleObject(ext->halt_event, 0); + if (rc == WAIT_OBJECT_0) + exit_now = TRUE; + if (!exit_now && irp->IoStatus.u.Status == STATUS_SUCCESS) { packet->reportId = buffer[0]; @@ -368,7 +369,7 @@ void HID_StartDeviceThread(DEVICE_OBJECT *device) { BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; - ext->halt_event = CreateEventA(NULL, FALSE, FALSE, NULL); + ext->halt_event = CreateEventA(NULL, TRUE, FALSE, NULL); ext->thread = CreateThread(NULL, 0, hid_device_thread, device, 0, NULL); } @@ -430,6 +431,67 @@ return STATUS_SUCCESS; } +static NTSTATUS HID_get_feature(DEVICE_OBJECT *device, IRP *irp) +{ + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); + HID_XFER_PACKET *packet; + DWORD len; + NTSTATUS rc = STATUS_SUCCESS; + WCHAR *out_buffer; + + irp->IoStatus.Information = 0; + + out_buffer = (WCHAR*)(((BYTE*)irp->MdlAddress->StartVa) + irp->MdlAddress->ByteOffset); + TRACE_(hid_report)("Device %p Buffer length %i Buffer %p\n", device, irpsp->Parameters.DeviceIoControl.OutputBufferLength, out_buffer); + + len = sizeof(*packet) + irpsp->Parameters.DeviceIoControl.OutputBufferLength; + packet = HeapAlloc(GetProcessHeap(), 0, len); + packet->reportBufferLen = irpsp->Parameters.DeviceIoControl.OutputBufferLength; + packet->reportBuffer = ((BYTE*)packet) + sizeof(*packet); + packet->reportId = out_buffer[0]; + + TRACE_(hid_report)("(id %i, len %i buffer %p)\n", packet->reportId, packet->reportBufferLen, packet->reportBuffer); + + rc = call_minidriver(IOCTL_HID_GET_FEATURE, device, NULL, 0, packet, len); + + irp->IoStatus.u.Status = rc; + if (irp->IoStatus.u.Status == STATUS_SUCCESS) + irp->IoStatus.Information = irpsp->Parameters.DeviceIoControl.OutputBufferLength; + else + irp->IoStatus.Information = 0; + + TRACE_(hid_report)("Result 0x%x get %li bytes\n", rc, irp->IoStatus.Information); + + return rc; +} + +static NTSTATUS HID_set_feature(DEVICE_OBJECT *device, IRP *irp) +{ + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); + HID_XFER_PACKET packet; + NTSTATUS rc; + + irp->IoStatus.Information = 0; + + TRACE_(hid_report)("Device %p Buffer length %i Buffer %p\n", device, irpsp->Parameters.DeviceIoControl.InputBufferLength, irp->AssociatedIrp.SystemBuffer); + packet.reportBuffer = irp->AssociatedIrp.SystemBuffer; + packet.reportId = ((char*)irp->AssociatedIrp.SystemBuffer)[0]; + packet.reportBufferLen = irpsp->Parameters.DeviceIoControl.InputBufferLength; + TRACE_(hid_report)("(id %i, len %i buffer %p)\n", packet.reportId, packet.reportBufferLen, packet.reportBuffer); + + rc = call_minidriver(IOCTL_HID_SET_FEATURE, device, NULL, 0, &packet, sizeof(packet)); + + irp->IoStatus.u.Status = rc; + if (irp->IoStatus.u.Status == STATUS_SUCCESS) + irp->IoStatus.Information = irpsp->Parameters.DeviceIoControl.InputBufferLength; + else + irp->IoStatus.Information = 0; + + TRACE_(hid_report)("Result 0x%x set %li bytes\n", rc, irp->IoStatus.Information); + + return rc; +} + NTSTATUS WINAPI HID_Device_ioctl(DEVICE_OBJECT *device, IRP *irp) { NTSTATUS rc = STATUS_SUCCESS; @@ -545,6 +607,12 @@ } break; } + case IOCTL_HID_GET_FEATURE: + rc = HID_get_feature(device, irp); + break; + case IOCTL_HID_SET_FEATURE: + rc = HID_set_feature(device, irp); + break; default: { ULONG code = irpsp->Parameters.DeviceIoControl.IoControlCode; @@ -607,16 +675,29 @@ NTSTATUS WINAPI HID_Device_write(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); + HID_XFER_PACKET packet; + NTSTATUS rc; irp->IoStatus.Information = 0; - TRACE("Buffer length %i\n", irpsp->Parameters.Write.Length); + TRACE_(hid_report)("Device %p Buffer length %i Buffer %p\n", device, irpsp->Parameters.Write.Length, irp->AssociatedIrp.SystemBuffer); + packet.reportBuffer = irp->AssociatedIrp.SystemBuffer; + packet.reportId = ((char*)irp->AssociatedIrp.SystemBuffer)[0]; + packet.reportBufferLen = irpsp->Parameters.Write.Length; + TRACE_(hid_report)("(id %i, len %i buffer %p)\n", packet.reportId, packet.reportBufferLen, packet.reportBuffer); + + rc = call_minidriver(IOCTL_HID_WRITE_REPORT, device, NULL, 0, &packet, sizeof(packet)); + + irp->IoStatus.u.Status = rc; + if (irp->IoStatus.u.Status == STATUS_SUCCESS) + irp->IoStatus.Information = irpsp->Parameters.Write.Length; + else + irp->IoStatus.Information = 0; - FIXME("device %p\n", device); + TRACE_(hid_report)("Result 0x%x wrote %li bytes\n", rc, irp->IoStatus.Information); - irp->IoStatus.u.Status = STATUS_SUCCESS; IoCompleteRequest( irp, IO_NO_INCREMENT ); - return STATUS_SUCCESS; + return rc; } NTSTATUS WINAPI HID_Device_create(DEVICE_OBJECT *device, IRP *irp) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ieframe/intshcut.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ieframe/intshcut.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ieframe/intshcut.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ieframe/intshcut.c 2016-02-08 19:32:34.000000000 +0000 @@ -506,8 +506,7 @@ STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &pPropStg); - get_profile_string(str_header, str_iconfile, pszFileName, &iconfile); - if (iconfile != NULL) + if (get_profile_string(str_header, str_iconfile, pszFileName, &iconfile)) { PROPSPEC ps; PROPVARIANT pv; @@ -520,13 +519,10 @@ { TRACE("Failed to store the iconfile to our property storage. hr = 0x%x\n", hr); } - - CoTaskMemFree(iconfile); } + CoTaskMemFree(iconfile); - get_profile_string(str_header, str_iconindex, pszFileName, &iconindexstring); - - if (iconindexstring != NULL) + if (get_profile_string(str_header, str_iconindex, pszFileName, &iconindexstring)) { int iconindex; PROPSPEC ps; @@ -543,9 +539,8 @@ { TRACE("Failed to store the iconindex to our property storage. hr = 0x%x\n", hr); } - - CoTaskMemFree(iconindexstring); } + CoTaskMemFree(iconindexstring); IPropertyStorage_Release(pPropStg); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ieframe/tests/intshcut.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ieframe/tests/intshcut.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ieframe/tests/intshcut.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ieframe/tests/intshcut.c 2016-02-08 19:32:34.000000000 +0000 @@ -213,7 +213,7 @@ pv[0].vt = VT_LPWSTR; U(pv[0]).pwszVal = (void *) iconPath; pv[1].vt = VT_I4; - U(pv[1]).iVal = iconIndex; + U(pv[1]).lVal = iconIndex; hr = urlA->lpVtbl->QueryInterface(urlA, &IID_IPropertySetStorage, (void **) &pPropSetStg); ok(hr == S_OK, "Unable to get an IPropertySetStorage, hr=0x%x\n", hr); @@ -261,16 +261,16 @@ hr = IPropertySetStorage_Open(pPropSetStg, &FMTID_Intshcut, STGM_READ | STGM_SHARE_EXCLUSIVE, &pPropStgRead); ok(hr == S_OK, "Unable to get an IPropertyStorage for reading, hr=0x%x\n", hr); + memset(pvread, 0, sizeof(pvread)); hr = IPropertyStorage_ReadMultiple(pPropStgRead, 2, ps, pvread); + todo_wine /* Wine doesn't yet support setting properties after save */ + { ok(hr == S_OK, "Unable to read properties, hr=0x%x\n", hr); - - todo_wine /* Wine doesn't yet support setting properties after save */ - { - ok(U(pvread[1]).iVal == iconIndex, "Read wrong icon index: %d\n", U(pvread[1]).iVal); - - ok(lstrcmpW(U(pvread[0]).pwszVal, iconPath) == 0, "Wrong icon path read: %s\n", wine_dbgstr_w(U(pvread[0]).pwszVal)); - } - + ok(pvread[1].vt == VT_I4, "got %d\n", pvread[1].vt); + ok(U(pvread[1]).lVal == iconIndex, "Read wrong icon index: %d\n", U(pvread[1]).iVal); + ok(pvread[0].vt == VT_LPWSTR, "got %d\n", pvread[0].vt); + ok(lstrcmpW(U(pvread[0]).pwszVal, iconPath) == 0, "Wrong icon path read: %s\n", wine_dbgstr_w(U(pvread[0]).pwszVal)); + } PropVariantClear(&pvread[0]); PropVariantClear(&pvread[1]); IPropertyStorage_Release(pPropStgRead); @@ -335,6 +335,11 @@ lstrcatW(file_path, test_urlW); for(test = load_tests; test < load_tests + sizeof(load_tests)/sizeof(*load_tests); test++) { + IPropertySetStorage *propsetstorage; + IPropertyStorage *propstorage; + PROPVARIANT v; + PROPSPEC ps; + file = CreateFileW(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); ok(file != INVALID_HANDLE_VALUE, "could not create test file\n"); if(file == INVALID_HANDLE_VALUE) @@ -351,6 +356,29 @@ test_shortcut_url((IUnknown*)persist_file, test->url); + hres = IPersistFile_QueryInterface(persist_file, &IID_IPropertySetStorage, (void **)&propsetstorage); + ok(hres == S_OK, "Unable to get an IPropertySetStorage, hr=0x%x\n", hres); + + hres = IPropertySetStorage_Open(propsetstorage, &FMTID_Intshcut, STGM_READ | STGM_SHARE_EXCLUSIVE, &propstorage); + ok(hres == S_OK, "Unable to get an IPropertyStorage for reading, hr=0x%x\n", hres); + + ps.ulKind = PRSPEC_PROPID; + U(ps).propid = PID_IS_ICONFILE; + v.vt = VT_NULL; + hres = IPropertyStorage_ReadMultiple(propstorage, 1, &ps, &v); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + ok(v.vt == VT_EMPTY, "got %d\n", v.vt); + + ps.ulKind = PRSPEC_PROPID; + U(ps).propid = PID_IS_ICONINDEX; + v.vt = VT_EMPTY; + hres = IPropertyStorage_ReadMultiple(propstorage, 1, &ps, &v); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + ok(v.vt == VT_EMPTY, "got %d\n", v.vt); + + IPropertyStorage_Release(propstorage); + IPropertySetStorage_Release(propsetstorage); + IPersistFile_Release(persist_file); DeleteFileW(file_path); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/imm32/imm.c wine-staging-1.9.3~ubuntu12.04.1/dlls/imm32/imm.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/imm32/imm.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/imm32/imm.c 2016-02-08 19:32:34.000000000 +0000 @@ -439,6 +439,16 @@ PostMessageW(target, msg, wParam, lParam); } +/* for sending messages as the IME */ +static void ImmInternalSendIMEMessage(InputContextData *data, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND target = GetFocus(); + if (!target) + SendMessageW(data->IMC.hWnd,msg,wParam,lParam); + else + SendMessageW(target, msg, wParam, lParam); +} + static LRESULT ImmInternalSendIMENotify(InputContextData *data, WPARAM notify, LPARAM lParam) { HWND target; @@ -2887,7 +2897,7 @@ lpTransMsg = ImmLockIMCC(data->IMC.hMsgBuf); for (i = 0; i < data->IMC.dwNumMsgBuf; i++) - ImmInternalPostIMEMessage(data, lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam); + ImmInternalSendIMEMessage(data, lpTransMsg[i].message, lpTransMsg[i].wParam, lpTransMsg[i].lParam); ImmUnlockIMCC(data->IMC.hMsgBuf); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/imm32/tests/imm32.c wine-staging-1.9.3~ubuntu12.04.1/dlls/imm32/tests/imm32.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/imm32/tests/imm32.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/imm32/tests/imm32.c 2016-02-08 19:32:34.000000000 +0000 @@ -44,7 +44,7 @@ HWND hwnd; HHOOK get_msg_hook; HHOOK call_wnd_proc_hook; - imm_msgs msgs[32]; + imm_msgs msgs[64]; unsigned int i_msg; } msg_spy; @@ -59,6 +59,12 @@ } u; } TEST_INPUT; +typedef struct _tagTRANSMSG { + UINT message; + WPARAM wParam; + LPARAM lParam; +} TRANSMSG, *LPTRANSMSG; + static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t); static LRESULT CALLBACK get_msg_filter(int nCode, WPARAM wParam, LPARAM lParam) @@ -1015,6 +1021,9 @@ HIMC imc; UINT idx = 0; + LPINPUTCONTEXT lpIMC; + LPTRANSMSG lpTransMsg; + HWND hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "Wine imm32.dll test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, GetModuleHandleA(NULL), NULL); @@ -1032,6 +1041,64 @@ if (msg) ok(!msg->post, "Message should not be posted\n"); } while (msg); msg_spy_flush_msgs(); + + lpIMC = ImmLockIMC(imc); + lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) * sizeof(TRANSMSG)); + lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf); + lpTransMsg += lpIMC->dwNumMsgBuf; + lpTransMsg->message = WM_IME_STARTCOMPOSITION; + lpTransMsg->wParam = 0; + lpTransMsg->lParam = 0; + ImmUnlockIMCC(lpIMC->hMsgBuf); + lpIMC->dwNumMsgBuf++; + ImmUnlockIMC(imc); + ImmGenerateMessage(imc); + idx = 0; + do + { + msg = msg_spy_find_next_msg(WM_IME_STARTCOMPOSITION, &idx); + if (msg) ok(!msg->post, "Message should not be posted\n"); + } while (msg); + msg_spy_flush_msgs(); + + lpIMC = ImmLockIMC(imc); + lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) * sizeof(TRANSMSG)); + lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf); + lpTransMsg += lpIMC->dwNumMsgBuf; + lpTransMsg->message = WM_IME_COMPOSITION; + lpTransMsg->wParam = 0; + lpTransMsg->lParam = 0; + ImmUnlockIMCC(lpIMC->hMsgBuf); + lpIMC->dwNumMsgBuf++; + ImmUnlockIMC(imc); + ImmGenerateMessage(imc); + idx = 0; + do + { + msg = msg_spy_find_next_msg(WM_IME_COMPOSITION, &idx); + if (msg) ok(!msg->post, "Message should not be posted\n"); + } while (msg); + msg_spy_flush_msgs(); + + lpIMC = ImmLockIMC(imc); + lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) * sizeof(TRANSMSG)); + lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf); + lpTransMsg += lpIMC->dwNumMsgBuf; + lpTransMsg->message = WM_IME_ENDCOMPOSITION; + lpTransMsg->wParam = 0; + lpTransMsg->lParam = 0; + ImmUnlockIMCC(lpIMC->hMsgBuf); + lpIMC->dwNumMsgBuf++; + ImmUnlockIMC(imc); + ImmGenerateMessage(imc); + idx = 0; + do + { + msg = msg_spy_find_next_msg(WM_IME_ENDCOMPOSITION, &idx); + if (msg) ok(!msg->post, "Message should not be posted\n"); + } while (msg); + msg_spy_flush_msgs(); + ImmSetOpenStatus(imc, FALSE); ImmReleaseContext(hwnd, imc); DestroyWindow(hwnd); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/inetcomm/mimeole.c wine-staging-1.9.3~ubuntu12.04.1/dlls/inetcomm/mimeole.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/inetcomm/mimeole.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/inetcomm/mimeole.c 2016-02-08 19:32:34.000000000 +0000 @@ -2821,7 +2821,7 @@ static LPVOID WINAPI MimeAlloc_Alloc( IMimeAllocator* iface, - ULONG cb) + SIZE_T cb) { return CoTaskMemAlloc(cb); } @@ -2829,7 +2829,7 @@ static LPVOID WINAPI MimeAlloc_Realloc( IMimeAllocator* iface, LPVOID pv, - ULONG cb) + SIZE_T cb) { return CoTaskMemRealloc(pv, cb); } @@ -2841,7 +2841,7 @@ CoTaskMemFree(pv); } -static ULONG WINAPI MimeAlloc_GetSize( +static SIZE_T WINAPI MimeAlloc_GetSize( IMimeAllocator* iface, LPVOID pv) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/irprops.cpl/irprops.cpl.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/irprops.cpl/irprops.cpl.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/irprops.cpl/irprops.cpl.spec 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/irprops.cpl/irprops.cpl.spec 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,52 @@ +@ stub BluetoothAuthenticateDevice +@ stub BluetoothAuthenticateMultipleDevices +@ stub BluetoothAuthenticationAgent +@ stub BluetoothDisconnectDevice +@ stub BluetoothDisplayDeviceProperties +@ stub BluetoothEnableDiscovery +@ stub BluetoothEnableIncomingConnections +@ stub BluetoothEnumerateInstalledServices +@ stub BluetoothFindBrowseGroupClose +@ stub BluetoothFindClassIdClose +@ stub BluetoothFindDeviceClose +@ stub BluetoothFindFirstBrowseGroup +@ stub BluetoothFindFirstClassId +@ stub BluetoothFindFirstDevice +@ stub BluetoothFindFirstProfileDescriptor +@ stub BluetoothFindFirstProtocolDescriptorStack +@ stub BluetoothFindFirstProtocolEntry +@ stub BluetoothFindFirstRadio +@ stub BluetoothFindFirstService +@ stub BluetoothFindNextBrowseGroup +@ stub BluetoothFindNextClassId +@ stub BluetoothFindNextDevice +@ stub BluetoothFindNextProfileDescriptor +@ stub BluetoothFindNextProtocolDescriptorStack +@ stub BluetoothFindNextProtocolEntry +@ stub BluetoothFindNextRadio +@ stub BluetoothFindNextService +@ stub BluetoothFindProfileDescriptorClose +@ stub BluetoothFindProtocolDescriptorStackClose +@ stub BluetoothFindProtocolEntryClose +@ stub BluetoothFindRadioClose +@ stub BluetoothFindServiceClose +@ stub BluetoothGetDeviceInfo +@ stub BluetoothGetRadioInfo +@ stub BluetoothIsConnectable +@ stub BluetoothIsDiscoverable +@ stub BluetoothMapClassOfDeviceToImageIndex +@ stub BluetoothMapClassOfDeviceToString +@ stub BluetoothRegisterForAuthentication +@ stub BluetoothRemoveDevice +@ stub BluetoothSdpEnumAttributes +@ stub BluetoothSdpGetAttributeValue +@ stub BluetoothSdpGetContainerElementData +@ stub BluetoothSdpGetElementData +@ stub BluetoothSdpGetString +@ stub BluetoothSelectDevices +@ stub BluetoothSelectDevicesFree +@ stub BluetoothSendAuthenticationResponse +@ stub BluetoothSetServiceState +@ stub BluetoothUnregisterAuthentication +@ stub BluetoothUpdateDeviceRecord +#@ stub CPlApplet diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/irprops.cpl/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/irprops.cpl/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/irprops.cpl/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/irprops.cpl/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1 @@ +MODULE = irprops.cpl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/array.c wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/array.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/array.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/array.c 2016-02-08 19:32:34.000000000 +0000 @@ -20,6 +20,7 @@ #include "wine/port.h" #include +#include #include "jscript.h" @@ -64,6 +65,12 @@ return is_vclass(jsthis, JSCLASS_ARRAY) ? array_from_vdisp(jsthis) : NULL; } +unsigned array_get_length(jsdisp_t *array) +{ + assert(is_class(array, JSCLASS_ARRAY)); + return array_from_jsdisp(array)->length; +} + static HRESULT get_length(script_ctx_t *ctx, vdisp_t *vdisp, jsdisp_t **jsthis, DWORD *ret) { ArrayInstance *array; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/bool.c wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/bool.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/bool.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/bool.c 2016-02-08 19:32:34.000000000 +0000 @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #include "jscript.h" #include "wine/debug.h" @@ -37,6 +39,12 @@ return is_vclass(jsthis, JSCLASS_BOOLEAN) ? (BoolInstance*)jsthis->u.jsdisp : NULL; } +BOOL bool_obj_value(jsdisp_t *obj) +{ + assert(is_class(obj, JSCLASS_BOOLEAN)); + return ((BoolInstance*)obj)->val; +} + /* ECMA-262 3rd Edition 15.6.4.2 */ static HRESULT Bool_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/function.c wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/function.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/function.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/function.c 2016-02-08 19:32:34.000000000 +0000 @@ -821,6 +821,7 @@ TRACE("\n"); switch(flags) { + case DISPATCH_METHOD: case DISPATCH_CONSTRUCT: { IDispatch *ret; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/global.c wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/global.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/global.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/global.c 2016-02-08 19:32:34.000000000 +0000 @@ -67,6 +67,7 @@ {'S','c','r','i','p','t','E','n','g','i','n','e','B','u','i','l','d','V','e','r','s','i','o','n',0}; static const WCHAR CollectGarbageW[] = {'C','o','l','l','e','c','t','G','a','r','b','a','g','e',0}; static const WCHAR MathW[] = {'M','a','t','h',0}; +static const WCHAR JSONW[] = {'J','S','O','N',0}; static const WCHAR encodeURIW[] = {'e','n','c','o','d','e','U','R','I',0}; static const WCHAR decodeURIW[] = {'d','e','c','o','d','e','U','R','I',0}; static const WCHAR encodeURIComponentW[] = {'e','n','c','o','d','e','U','R','I','C','o','m','p','o','n','e','n','t',0}; @@ -264,8 +265,7 @@ if(FAILED(hres)) return hres; - if(!isinf(n) && !isnan(n)) - ret = TRUE; + ret = is_finite(n); } if(r) @@ -1108,6 +1108,19 @@ if(FAILED(hres)) return hres; + if(ctx->version >= 2) { + jsdisp_t *json; + + hres = create_json(ctx, &json); + if(FAILED(hres)) + return hres; + + hres = jsdisp_propput_dontenum(ctx->global, JSONW, jsval_obj(json)); + jsdisp_release(json); + if(FAILED(hres)) + return hres; + } + hres = create_activex_constr(ctx, &constr); if(FAILED(hres)) return hres; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/jscript.h wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/jscript.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/jscript.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/jscript.h 2016-02-08 19:32:34.000000000 +0000 @@ -117,7 +117,8 @@ JSCLASS_REGEXP, JSCLASS_STRING, JSCLASS_ARGUMENTS, - JSCLASS_VBARRAY + JSCLASS_VBARRAY, + JSCLASS_JSON } jsclass_t; jsdisp_t *iface_to_jsdisp(IUnknown*) DECLSPEC_HIDDEN; @@ -317,6 +318,7 @@ HRESULT create_bool(script_ctx_t*,BOOL,jsdisp_t**) DECLSPEC_HIDDEN; HRESULT create_number(script_ctx_t*,double,jsdisp_t**) DECLSPEC_HIDDEN; HRESULT create_vbarray(script_ctx_t*,SAFEARRAY*,jsdisp_t**) DECLSPEC_HIDDEN; +HRESULT create_json(script_ctx_t*,jsdisp_t**) DECLSPEC_HIDDEN; typedef enum { NO_HINT, @@ -339,6 +341,7 @@ HRESULT decode_source(WCHAR*) DECLSPEC_HIDDEN; HRESULT double_to_string(double,jsstr_t**) DECLSPEC_HIDDEN; +BOOL is_finite(double) DECLSPEC_HIDDEN; typedef struct named_item_t { IDispatch *disp; @@ -458,6 +461,9 @@ HRESULT parse_regexp_flags(const WCHAR*,DWORD,DWORD*) DECLSPEC_HIDDEN; HRESULT regexp_string_match(script_ctx_t*,jsdisp_t*,jsstr_t*,jsval_t*) DECLSPEC_HIDDEN; +BOOL bool_obj_value(jsdisp_t*) DECLSPEC_HIDDEN; +unsigned array_get_length(jsdisp_t*) DECLSPEC_HIDDEN; + static inline BOOL is_class(jsdisp_t *jsdisp, jsclass_t class) { return jsdisp->builtin_info->class == class; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/json.c wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/json.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/json.c 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/json.c 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,853 @@ +/* + * Copyright 2016 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "jscript.h" +#include "parser.h" + +#include "wine/debug.h" +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL(jscript); + +static const WCHAR parseW[] = {'p','a','r','s','e',0}; +static const WCHAR stringifyW[] = {'s','t','r','i','n','g','i','f','y',0}; + +static const WCHAR nullW[] = {'n','u','l','l',0}; +static const WCHAR trueW[] = {'t','r','u','e',0}; +static const WCHAR falseW[] = {'f','a','l','s','e',0}; + +static const WCHAR toJSONW[] = {'t','o','J','S','O','N',0}; + +typedef struct { + const WCHAR *ptr; + const WCHAR *end; + script_ctx_t *ctx; +} json_parse_ctx_t; + +static BOOL is_json_space(WCHAR c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; +} + +static WCHAR skip_spaces(json_parse_ctx_t *ctx) +{ + while(is_json_space(*ctx->ptr)) + ctx->ptr++; + return *ctx->ptr; +} + +static BOOL is_keyword(json_parse_ctx_t *ctx, const WCHAR *keyword) +{ + unsigned i; + for(i=0; keyword[i]; i++) { + if(!ctx->ptr[i] || keyword[i] != ctx->ptr[i]) + return FALSE; + } + if(is_identifier_char(ctx->ptr[i])) + return FALSE; + ctx->ptr += i; + return TRUE; +} + +/* ECMA-262 5.1 Edition 15.12.1.1 */ +static HRESULT parse_json_string(json_parse_ctx_t *ctx, WCHAR **r) +{ + const WCHAR *ptr = ++ctx->ptr; + size_t len; + WCHAR *buf; + + while(*ctx->ptr && *ctx->ptr != '"') { + if(*ctx->ptr++ == '\\') + ctx->ptr++; + } + if(!*ctx->ptr) { + FIXME("unterminated string\n"); + return E_FAIL; + } + + len = ctx->ptr-ptr; + buf = heap_alloc((len+1)*sizeof(WCHAR)); + if(!buf) + return E_OUTOFMEMORY; + if(len) + memcpy(buf, ptr, len*sizeof(WCHAR)); + buf[len] = 0; + + if(!unescape(buf)) { + FIXME("unescape failed\n"); + heap_free(buf); + return E_FAIL; + } + + ctx->ptr++; + *r = buf; + return S_OK; +} + +/* ECMA-262 5.1 Edition 15.12.1.2 */ +static HRESULT parse_json_value(json_parse_ctx_t *ctx, jsval_t *r) +{ + HRESULT hres; + + switch(skip_spaces(ctx)) { + + /* JSONNullLiteral */ + case 'n': + if(!is_keyword(ctx, nullW)) + break; + *r = jsval_null(); + return S_OK; + + /* JSONBooleanLiteral */ + case 't': + if(!is_keyword(ctx, trueW)) + break; + *r = jsval_bool(TRUE); + return S_OK; + case 'f': + if(!is_keyword(ctx, falseW)) + break; + *r = jsval_bool(FALSE); + return S_OK; + + /* JSONObject */ + case '{': { + WCHAR *prop_name; + jsdisp_t *obj; + jsval_t val; + + hres = create_object(ctx->ctx, NULL, &obj); + if(FAILED(hres)) + return hres; + + ctx->ptr++; + if(skip_spaces(ctx) == '}') { + ctx->ptr++; + *r = jsval_obj(obj); + return S_OK; + } + + while(1) { + if(*ctx->ptr != '"') + break; + hres = parse_json_string(ctx, &prop_name); + if(FAILED(hres)) + break; + + if(skip_spaces(ctx) != ':') { + FIXME("missing ':'\n"); + heap_free(prop_name); + break; + } + + ctx->ptr++; + hres = parse_json_value(ctx, &val); + if(SUCCEEDED(hres)) { + hres = jsdisp_propput_name(obj, prop_name, val); + jsval_release(val); + } + heap_free(prop_name); + if(FAILED(hres)) + break; + + if(skip_spaces(ctx) == '}') { + ctx->ptr++; + *r = jsval_obj(obj); + return S_OK; + } + + if(*ctx->ptr++ != ',') { + FIXME("expected ','\n"); + break; + } + skip_spaces(ctx); + } + + jsdisp_release(obj); + break; + } + + /* JSONString */ + case '"': { + WCHAR *string; + jsstr_t *str; + + hres = parse_json_string(ctx, &string); + if(FAILED(hres)) + return hres; + + /* FIXME: avoid reallocation */ + str = jsstr_alloc(string); + heap_free(string); + if(!str) + return E_OUTOFMEMORY; + + *r = jsval_string(str); + return S_OK; + } + + /* JSONArray */ + case '[': { + jsdisp_t *array; + unsigned i = 0; + jsval_t val; + + hres = create_array(ctx->ctx, 0, &array); + if(FAILED(hres)) + return hres; + + ctx->ptr++; + if(skip_spaces(ctx) == ']') { + ctx->ptr++; + *r = jsval_obj(array); + return S_OK; + } + + while(1) { + hres = parse_json_value(ctx, &val); + if(FAILED(hres)) + break; + + hres = jsdisp_propput_idx(array, i, val); + jsval_release(val); + if(FAILED(hres)) + break; + + if(skip_spaces(ctx) == ']') { + ctx->ptr++; + *r = jsval_obj(array); + return S_OK; + } + + if(*ctx->ptr != ',') { + FIXME("expected ','\n"); + break; + } + + ctx->ptr++; + i++; + } + + jsdisp_release(array); + break; + } + + /* JSONNumber */ + default: { + int sign = 1; + double n; + + if(*ctx->ptr == '-') { + sign = -1; + ctx->ptr++; + skip_spaces(ctx); + } + + if(!isdigitW(*ctx->ptr)) + break; + + if(*ctx->ptr == '0') { + ctx->ptr++; + n = 0; + if(is_identifier_char(*ctx->ptr)) + break; + }else { + hres = parse_decimal(&ctx->ptr, ctx->end, &n); + if(FAILED(hres)) + return hres; + } + + *r = jsval_number(sign*n); + return S_OK; + } + } + + FIXME("Syntax error at %s\n", debugstr_w(ctx->ptr)); + return E_FAIL; +} + +/* ECMA-262 5.1 Edition 15.12.2 */ +static HRESULT JSON_parse(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + json_parse_ctx_t parse_ctx; + const WCHAR *buf; + jsstr_t *str; + jsval_t ret; + HRESULT hres; + + if(argc != 1) { + FIXME("Unsupported args\n"); + return E_INVALIDARG; + } + + hres = to_flat_string(ctx, argv[0], &str, &buf); + if(FAILED(hres)) + return hres; + + TRACE("%s\n", debugstr_w(buf)); + + parse_ctx.ptr = buf; + parse_ctx.end = buf + jsstr_length(str); + parse_ctx.ctx = ctx; + hres = parse_json_value(&parse_ctx, &ret); + jsstr_release(str); + if(FAILED(hres)) + return hres; + + if(skip_spaces(&parse_ctx)) { + FIXME("syntax error\n"); + jsval_release(ret); + return E_FAIL; + } + + if(r) + *r = ret; + else + jsval_release(ret); + return S_OK; +} + +typedef struct { + script_ctx_t *ctx; + + WCHAR *buf; + size_t buf_size; + size_t buf_len; + + jsdisp_t **stack; + size_t stack_top; + size_t stack_size; + + WCHAR gap[11]; /* according to the spec, it's no longer than 10 chars */ +} stringify_ctx_t; + +static BOOL stringify_push_obj(stringify_ctx_t *ctx, jsdisp_t *obj) +{ + if(!ctx->stack_size) { + ctx->stack = heap_alloc(4*sizeof(*ctx->stack)); + if(!ctx->stack) + return FALSE; + ctx->stack_size = 4; + }else if(ctx->stack_top == ctx->stack_size) { + jsdisp_t **new_stack; + + new_stack = heap_realloc(ctx->stack, ctx->stack_size*2*sizeof(*ctx->stack)); + if(!new_stack) + return FALSE; + ctx->stack = new_stack; + ctx->stack_size *= 2; + } + + ctx->stack[ctx->stack_top++] = obj; + return TRUE; +} + +static void stringify_pop_obj(stringify_ctx_t *ctx) +{ + ctx->stack_top--; +} + +static BOOL is_on_stack(stringify_ctx_t *ctx, jsdisp_t *obj) +{ + size_t i = ctx->stack_top; + while(i--) { + if(ctx->stack[i] == obj) + return TRUE; + } + return FALSE; +} + +static BOOL append_string_len(stringify_ctx_t *ctx, const WCHAR *str, size_t len) +{ + if(!ctx->buf_size) { + ctx->buf = heap_alloc(len*2*sizeof(WCHAR)); + if(!ctx->buf) + return FALSE; + ctx->buf_size = len*2; + }else if(ctx->buf_len + len > ctx->buf_size) { + WCHAR *new_buf; + size_t new_size; + + new_size = ctx->buf_size * 2 + len; + new_buf = heap_realloc(ctx->buf, new_size*sizeof(WCHAR)); + if(!new_buf) + return FALSE; + ctx->buf = new_buf; + ctx->buf_size = new_size; + } + + if(len) + memcpy(ctx->buf + ctx->buf_len, str, len*sizeof(WCHAR)); + ctx->buf_len += len; + return TRUE; +} + +static inline BOOL append_string(stringify_ctx_t *ctx, const WCHAR *str) +{ + return append_string_len(ctx, str, strlenW(str)); +} + +static inline BOOL append_char(stringify_ctx_t *ctx, WCHAR c) +{ + return append_string_len(ctx, &c, 1); +} + +static inline BOOL append_simple_quote(stringify_ctx_t *ctx, WCHAR c) +{ + WCHAR str[] = {'\\',c}; + return append_string_len(ctx, str, 2); +} + +static HRESULT maybe_to_primitive(script_ctx_t *ctx, jsval_t val, jsval_t *r) +{ + jsdisp_t *obj; + HRESULT hres; + + if(!is_object_instance(val) || !get_object(val) || !(obj = iface_to_jsdisp((IUnknown*)get_object(val)))) + return jsval_copy(val, r); + + if(is_class(obj, JSCLASS_NUMBER)) { + double n; + hres = to_number(ctx, val, &n); + jsdisp_release(obj); + if(SUCCEEDED(hres)) + *r = jsval_number(n); + return hres; + } + + if(is_class(obj, JSCLASS_STRING)) { + jsstr_t *str; + hres = to_string(ctx, val, &str); + jsdisp_release(obj); + if(SUCCEEDED(hres)) + *r = jsval_string(str); + return hres; + } + + if(is_class(obj, JSCLASS_BOOLEAN)) { + *r = jsval_bool(bool_obj_value(obj)); + jsdisp_release(obj); + return S_OK; + } + + *r = jsval_obj(obj); + return S_OK; +} + +/* ECMA-262 5.1 Edition 15.12.3 (abstract operation Quote) */ +static HRESULT json_quote(stringify_ctx_t *ctx, const WCHAR *ptr, size_t len) +{ + if(!ptr || !append_char(ctx, '"')) + return E_OUTOFMEMORY; + + while(len--) { + switch(*ptr) { + case '"': + case '\\': + if(!append_simple_quote(ctx, *ptr)) + return E_OUTOFMEMORY; + break; + case '\b': + if(!append_simple_quote(ctx, 'b')) + return E_OUTOFMEMORY; + break; + case '\f': + if(!append_simple_quote(ctx, 'f')) + return E_OUTOFMEMORY; + break; + case '\n': + if(!append_simple_quote(ctx, 'n')) + return E_OUTOFMEMORY; + break; + case '\r': + if(!append_simple_quote(ctx, 'r')) + return E_OUTOFMEMORY; + break; + case '\t': + if(!append_simple_quote(ctx, 't')) + return E_OUTOFMEMORY; + break; + default: + if(*ptr < ' ') { + const WCHAR formatW[] = {'\\','u','%','0','4','x',0}; + WCHAR buf[7]; + sprintfW(buf, formatW, *ptr); + if(!append_string(ctx, buf)) + return E_OUTOFMEMORY; + }else { + if(!append_char(ctx, *ptr)) + return E_OUTOFMEMORY; + } + } + ptr++; + } + + return append_char(ctx, '"') ? S_OK : E_OUTOFMEMORY; +} + +static inline BOOL is_callable(jsdisp_t *obj) +{ + return is_class(obj, JSCLASS_FUNCTION); +} + +static HRESULT stringify(stringify_ctx_t *ctx, jsval_t val); + +/* ECMA-262 5.1 Edition 15.12.3 (abstract operation JA) */ +static HRESULT stringify_array(stringify_ctx_t *ctx, jsdisp_t *obj) +{ + unsigned length, i, j; + jsval_t val; + HRESULT hres; + + if(is_on_stack(ctx, obj)) { + FIXME("Found a cycle\n"); + return E_FAIL; + } + + if(!stringify_push_obj(ctx, obj)) + return E_OUTOFMEMORY; + + if(!append_char(ctx, '[')) + return E_OUTOFMEMORY; + + length = array_get_length(obj); + + for(i=0; i < length; i++) { + if(i && !append_char(ctx, ',')) + return E_OUTOFMEMORY; + + if(*ctx->gap) { + if(!append_char(ctx, '\n')) + return E_OUTOFMEMORY; + + for(j=0; j < ctx->stack_top; j++) { + if(!append_string(ctx, ctx->gap)) + return E_OUTOFMEMORY; + } + } + + hres = jsdisp_get_idx(obj, i, &val); + if(FAILED(hres)) + return hres; + + hres = stringify(ctx, val); + if(FAILED(hres)) + return hres; + + if(hres == S_FALSE && !append_string(ctx, nullW)) + return E_OUTOFMEMORY; + } + + if((length && *ctx->gap && !append_char(ctx, '\n')) || !append_char(ctx, ']')) + return E_OUTOFMEMORY; + + stringify_pop_obj(ctx); + return S_OK; +} + +/* ECMA-262 5.1 Edition 15.12.3 (abstract operation JO) */ +static HRESULT stringify_object(stringify_ctx_t *ctx, jsdisp_t *obj) +{ + DISPID dispid = DISPID_STARTENUM; + jsval_t val = jsval_undefined(); + unsigned prop_cnt = 0, i; + size_t stepback; + BSTR prop_name; + HRESULT hres; + + if(is_on_stack(ctx, obj)) { + FIXME("Found a cycle\n"); + return E_FAIL; + } + + if(!stringify_push_obj(ctx, obj)) + return E_OUTOFMEMORY; + + if(!append_char(ctx, '{')) + return E_OUTOFMEMORY; + + while((hres = IDispatchEx_GetNextDispID(&obj->IDispatchEx_iface, fdexEnumDefault, dispid, &dispid)) == S_OK) { + jsval_release(val); + hres = jsdisp_propget(obj, dispid, &val); + if(FAILED(hres)) + return hres; + + if(is_undefined(val)) + continue; + + stepback = ctx->buf_len; + + if(prop_cnt && !append_char(ctx, ',')) { + hres = E_OUTOFMEMORY; + break; + } + + if(*ctx->gap) { + if(!append_char(ctx, '\n')) { + hres = E_OUTOFMEMORY; + break; + } + + for(i=0; i < ctx->stack_top; i++) { + if(!append_string(ctx, ctx->gap)) { + hres = E_OUTOFMEMORY; + break; + } + } + } + + hres = IDispatchEx_GetMemberName(&obj->IDispatchEx_iface, dispid, &prop_name); + if(FAILED(hres)) + break; + + hres = json_quote(ctx, prop_name, SysStringLen(prop_name)); + SysFreeString(prop_name); + if(FAILED(hres)) + break; + + if(!append_char(ctx, ':') || (*ctx->gap && !append_char(ctx, ' '))) { + hres = E_OUTOFMEMORY; + break; + } + + hres = stringify(ctx, val); + if(FAILED(hres)) + break; + + if(hres == S_FALSE) { + ctx->buf_len = stepback; + continue; + } + + prop_cnt++; + } + jsval_release(val); + if(FAILED(hres)) + return hres; + + if(prop_cnt && *ctx->gap) { + if(!append_char(ctx, '\n')) + return E_OUTOFMEMORY; + + for(i=1; i < ctx->stack_top; i++) { + if(!append_string(ctx, ctx->gap)) { + hres = E_OUTOFMEMORY; + break; + } + } + } + + if(!append_char(ctx, '}')) + return E_OUTOFMEMORY; + + stringify_pop_obj(ctx); + return S_OK; +} + +/* ECMA-262 5.1 Edition 15.12.3 (abstract operation Str) */ +static HRESULT stringify(stringify_ctx_t *ctx, jsval_t val) +{ + jsval_t value; + HRESULT hres; + + if(is_object_instance(val) && get_object(val)) { + jsdisp_t *obj; + DISPID id; + + obj = iface_to_jsdisp((IUnknown*)get_object(val)); + if(!obj) + return S_FALSE; + + hres = jsdisp_get_id(obj, toJSONW, 0, &id); + jsdisp_release(obj); + if(hres == S_OK) + FIXME("Use toJSON.\n"); + } + + /* FIXME: Support replacer replacer. */ + + hres = maybe_to_primitive(ctx->ctx, val, &value); + if(FAILED(hres)) + return hres; + + switch(jsval_type(value)) { + case JSV_NULL: + if(!append_string(ctx, nullW)) + hres = E_OUTOFMEMORY; + break; + case JSV_BOOL: + if(!append_string(ctx, get_bool(value) ? trueW : falseW)) + hres = E_OUTOFMEMORY; + break; + case JSV_STRING: { + jsstr_t *str = get_string(value); + const WCHAR *ptr = jsstr_flatten(str); + if(ptr) + hres = json_quote(ctx, ptr, jsstr_length(str)); + else + hres = E_OUTOFMEMORY; + break; + } + case JSV_NUMBER: { + double n = get_number(value); + if(is_finite(n)) { + const WCHAR *ptr; + jsstr_t *str; + + /* FIXME: Optimize. There is no need for jsstr_t here. */ + hres = double_to_string(n, &str); + if(FAILED(hres)) + break; + + ptr = jsstr_flatten(str); + assert(ptr != NULL); + hres = ptr && !append_string_len(ctx, ptr, jsstr_length(str)) ? E_OUTOFMEMORY : S_OK; + jsstr_release(str); + }else { + if(!append_string(ctx, nullW)) + hres = E_OUTOFMEMORY; + } + break; + } + case JSV_OBJECT: { + jsdisp_t *obj; + + obj = iface_to_jsdisp((IUnknown*)get_object(value)); + if(!obj) { + hres = S_FALSE; + break; + } + + if(!is_callable(obj)) + hres = is_class(obj, JSCLASS_ARRAY) ? stringify_array(ctx, obj) : stringify_object(ctx, obj); + else + hres = S_FALSE; + + jsdisp_release(obj); + break; + } + case JSV_UNDEFINED: + hres = S_FALSE; + break; + case JSV_VARIANT: + FIXME("VARIANT\n"); + hres = E_NOTIMPL; + break; + } + + jsval_release(value); + return hres; +} + +/* ECMA-262 5.1 Edition 15.12.3 */ +static HRESULT JSON_stringify(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + stringify_ctx_t stringify_ctx = {ctx, NULL,0,0, NULL,0,0, {0}}; + HRESULT hres; + + TRACE("\n"); + + if(argc >= 2 && is_object_instance(argv[1])) { + FIXME("Replacer %s not yet supported\n", debugstr_jsval(argv[1])); + return E_NOTIMPL; + } + + if(argc >= 3) { + jsval_t space_val; + + hres = maybe_to_primitive(ctx, argv[2], &space_val); + if(FAILED(hres)) + return hres; + + if(is_number(space_val)) { + double n = get_number(space_val); + if(n >= 1) { + int i, len; + if(n > 10) + n = 10; + len = floor(n); + for(i=0; i < len; i++) + stringify_ctx.gap[i] = ' '; + stringify_ctx.gap[len] = 0; + } + }else if(is_string(space_val)) { + jsstr_t *space_str = get_string(space_val); + size_t len = jsstr_length(space_str); + if(len > 10) + len = 10; + jsstr_extract(space_str, 0, len, stringify_ctx.gap); + } + + jsval_release(space_val); + } + + hres = stringify(&stringify_ctx, argv[0]); + if(SUCCEEDED(hres) && r) { + assert(!stringify_ctx.stack_top); + + if(hres == S_OK) { + jsstr_t *ret = jsstr_alloc_len(stringify_ctx.buf, stringify_ctx.buf_len); + if(ret) + *r = jsval_string(ret); + else + hres = E_OUTOFMEMORY; + }else { + *r = jsval_undefined(); + } + } + + heap_free(stringify_ctx.buf); + heap_free(stringify_ctx.stack); + return hres; +} + +static const builtin_prop_t JSON_props[] = { + {parseW, JSON_parse, PROPF_METHOD|2}, + {stringifyW, JSON_stringify, PROPF_METHOD|3} +}; + +static const builtin_info_t JSON_info = { + JSCLASS_JSON, + {NULL, NULL, 0}, + sizeof(JSON_props)/sizeof(*JSON_props), + JSON_props, + NULL, + NULL +}; + +HRESULT create_json(script_ctx_t *ctx, jsdisp_t **ret) +{ + jsdisp_t *json; + HRESULT hres; + + json = heap_alloc_zero(sizeof(*json)); + if(!json) + return E_OUTOFMEMORY; + + hres = init_dispex_from_constr(json, ctx, &JSON_info, ctx->object_constr); + if(FAILED(hres)) { + heap_free(json); + return hres; + } + + *ret = json; + return S_OK; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/jsutils.c wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/jsutils.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/jsutils.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/jsutils.c 2016-02-08 19:32:34.000000000 +0000 @@ -53,6 +53,11 @@ return NULL; } +BOOL is_finite(double n) +{ + return !isnan(n) && !isinf(n); +} + #define MIN_BLOCK_SIZE 128 #define ARENA_FREE_FILLER 0xaa @@ -641,7 +646,7 @@ if(FAILED(hres)) return hres; - *ret = isnan(n) || isinf(n) ? 0 : n; + *ret = is_finite(n) ? n : 0; return S_OK; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/lex.c wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/lex.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/lex.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/lex.c 2016-02-08 19:32:34.000000000 +0000 @@ -109,7 +109,7 @@ } /* ECMA-262 3rd Edition 7.6 */ -static BOOL is_identifier_char(WCHAR c) +BOOL is_identifier_char(WCHAR c) { return isalnumW(c) || c == '$' || c == '_' || c == '\\'; } @@ -249,7 +249,7 @@ return ctx->ptr != ctx->end; } -static BOOL unescape(WCHAR *str) +BOOL unescape(WCHAR *str) { WCHAR *pd, *p, c; int i; @@ -406,14 +406,14 @@ return ret; } -static BOOL parse_double_literal(parser_ctx_t *ctx, LONG int_part, double *ret) +HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret) { - LONGLONG d, hlp; + const WCHAR *ptr = *iter; + LONGLONG d = 0, hlp; int exp = 0; - d = int_part; - while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) { - hlp = d*10 + *(ctx->ptr++) - '0'; + while(ptr < end && isdigitW(*ptr)) { + hlp = d*10 + *(ptr++) - '0'; if(d>MAXLONGLONG/10 || hlp<0) { exp++; break; @@ -421,51 +421,48 @@ else d = hlp; } - while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) { + while(ptr < end && isdigitW(*ptr)) { exp++; - ctx->ptr++; + ptr++; } - if(*ctx->ptr == '.') { - ctx->ptr++; + if(*ptr == '.') { + ptr++; - while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) { - hlp = d*10 + *(ctx->ptr++) - '0'; + while(ptr < end && isdigitW(*ptr)) { + hlp = d*10 + *(ptr++) - '0'; if(d>MAXLONGLONG/10 || hlp<0) break; d = hlp; exp--; } - while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) - ctx->ptr++; + while(ptr < end && isdigitW(*ptr)) + ptr++; } - if(ctx->ptr < ctx->end && (*ctx->ptr == 'e' || *ctx->ptr == 'E')) { + if(ptr < end && (*ptr == 'e' || *ptr == 'E')) { int sign = 1, e = 0; - ctx->ptr++; - if(ctx->ptr < ctx->end) { - if(*ctx->ptr == '+') { - ctx->ptr++; - }else if(*ctx->ptr == '-') { + if(++ptr < end) { + if(*ptr == '+') { + ptr++; + }else if(*ptr == '-') { sign = -1; - ctx->ptr++; - }else if(!isdigitW(*ctx->ptr)) { + ptr++; + }else if(!isdigitW(*ptr)) { WARN("Expected exponent part\n"); - lex_error(ctx, E_FAIL); - return FALSE; + return E_FAIL; } } - if(ctx->ptr == ctx->end) { + if(ptr == end) { WARN("unexpected end of file\n"); - lex_error(ctx, E_FAIL); - return FALSE; + return E_FAIL; } - while(ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) { - if(e > INT_MAX/10 || (e = e*10 + *ctx->ptr++ - '0')<0) + while(ptr < end && isdigitW(*ptr)) { + if(e > INT_MAX/10 || (e = e*10 + *ptr++ - '0')<0) e = INT_MAX; } e *= sign; @@ -475,22 +472,25 @@ else exp += e; } - if(is_identifier_char(*ctx->ptr)) { + if(is_identifier_char(*ptr)) { WARN("wrong char after zero\n"); - lex_error(ctx, JS_E_MISSING_SEMICOLON); - return FALSE; + return JS_E_MISSING_SEMICOLON; } *ret = exp>=0 ? d*pow(10, exp) : d/pow(10, -exp); - return TRUE; + *iter = ptr; + return S_OK; } static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret) { - LONG l, d; + HRESULT hres; + + if(*ctx->ptr == '0') { + LONG d, l = 0; + + ctx->ptr++; - l = *ctx->ptr++ - '0'; - if(!l) { if(*ctx->ptr == 'x' || *ctx->ptr == 'X') { if(++ctx->ptr == ctx->end) { ERR("unexpected end of file\n"); @@ -546,7 +546,13 @@ } } - return parse_double_literal(ctx, l, ret); + hres = parse_decimal(&ctx->ptr, ctx->end, ret); + if(FAILED(hres)) { + lex_error(ctx, hres); + return FALSE; + } + + return TRUE; } static int next_token(parser_ctx_t *ctx, void *lval) @@ -599,8 +605,12 @@ case '.': if(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr)) { double n; - if(!parse_double_literal(ctx, 0, &n)) + HRESULT hres; + hres = parse_decimal(&ctx->ptr, ctx->end, &n); + if(FAILED(hres)) { + lex_error(ctx, hres); return -1; + } *(literal_t**)lval = new_double_literal(ctx, n); return tNumericLiteral; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -15,6 +15,7 @@ global.c \ jscript.c \ jscript_main.c \ + json.c \ jsregexp.c \ jsstr.c \ jsutils.c \ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/number.c wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/number.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/number.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/number.c 2016-02-08 19:32:34.000000000 +0000 @@ -16,9 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" -#include "wine/port.h" - #include #include @@ -257,7 +254,7 @@ val = number->value; - if(radix==10 || isnan(val) || isinf(val)) { + if(radix==10 || !is_finite(val)) { hres = to_string(ctx, jsval_number(val), &str); if(FAILED(hres)) return hres; @@ -383,7 +380,7 @@ } val = number->value; - if(isinf(val) || isnan(val)) { + if(!is_finite(val)) { hres = to_string(ctx, jsval_number(val), &str); if(FAILED(hres)) return hres; @@ -424,7 +421,7 @@ } val = number->value; - if(isinf(val) || isnan(val)) { + if(!is_finite(val)) { hres = to_string(ctx, jsval_number(val), &str); if(FAILED(hres)) return hres; @@ -465,7 +462,7 @@ } val = number->value; - if(isinf(val) || isnan(val) || !prec) { + if(!is_finite(val) || !prec) { hres = to_string(ctx, jsval_number(val), &str); if(FAILED(hres)) return hres; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/object.c wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/object.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/object.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/object.c 2016-02-08 19:32:34.000000000 +0000 @@ -54,7 +54,7 @@ static const WCHAR stringW[] = {'S','t','r','i','n','g',0}; /* Keep in sync with jsclass_t enum */ static const WCHAR *names[] = {NULL, arrayW, booleanW, dateW, errorW, - functionW, NULL, mathW, numberW, objectW, regexpW, stringW, objectW, objectW}; + functionW, NULL, mathW, numberW, objectW, regexpW, stringW, objectW, objectW, objectW}; TRACE("\n"); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/parser.h wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/parser.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/parser.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/parser.h 2016-02-08 19:32:34.000000000 +0000 @@ -62,6 +62,10 @@ return heap_pool_alloc(&ctx->script->tmp_heap, size); } +BOOL is_identifier_char(WCHAR) DECLSPEC_HIDDEN; +BOOL unescape(WCHAR*) DECLSPEC_HIDDEN; +HRESULT parse_decimal(const WCHAR**,const WCHAR*,double*) DECLSPEC_HIDDEN; + typedef enum { LT_DOUBLE, LT_STRING, diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/tests/api.js wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/tests/api.js --- wine-staging-1.9.0~ubuntu12.04.1/dlls/jscript/tests/api.js 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/jscript/tests/api.js 2016-02-08 19:32:34.000000000 +0000 @@ -1766,6 +1766,89 @@ tmp = Math.tan(-Infinity); ok(isNaN(tmp), "Math.tan(-Infinity) is not NaN"); +(function() { + if(invokeVersion < 2) + return; + + var stringify_tests = [ + [[true], "true"], + [[false], "false"], + [[null], "null"], + [[1], "1"], + [["test"], "\"test\""], + [["test\"\\\b\f\n\r\t\u0002 !"], "\"test\\\"\\\\\\b\\f\\n\\r\\t\\u0002 !\""], + [[NaN], "null"], + [[Infinity], "null"], + [[-Infinity], "null"], + [[{prop1: true, prop2: "string"}], "{\"prop1\":true,\"prop2\":\"string\"}"], + [[{prop1: true, prop2: testObj, prop3: undefined}], "{\"prop1\":true}"], + [[{prop1: true, prop2: {prop: "string"}},undefined," "], + "{\n \"prop1\": true,\n \"prop2\": {\n \"prop\": \"string\"\n }\n}"], + [[{ },undefined," "], "{}"], + [[[,2,undefined,3,{ },]],"[null,2,null,3,{},null]"], + [[[,2,undefined,3,{prop:0},],undefined," "],"[\n null,\n 2,\n null,\n 3,\n {\n \"prop\": 0\n },\n null\n]"] + ]; + + var i, s, v; + + for(i=0; i < stringify_tests.length; i++) { + s = JSON.stringify.apply(null, stringify_tests[i][0]); + ok(s === stringify_tests[i][1], + "["+i+"] stringify(" + stringify_tests[i][0] + ") returned " + s + " expected " + stringify_tests[i][1]); + } + + s = JSON.stringify(testObj); + ok(s === undefined || s === "undefined" /* broken on some old versions */, + "stringify(testObj) returned " + s + " expected undfined"); + + s = JSON.stringify(undefined); + ok(s === undefined || s === "undefined" /* broken on some old versions */, + "stringify(undefined) returned " + s + " expected undfined"); + + var parse_tests = [ + ["true", true], + [" \nnull ", null], + ["{}", {}], + ["\"\\r\\n test\\u1111\"", "\r\n test\u1111"], + ["{\"x\" :\n true}", {x:true}], + ["{\"x y\": {}, \"z\": {\"x\":null}}", {"x y":{}, z:{x:null}}], + ["[]", []], + ["[false,{},{\"x\": []}]", [false,{},{x:[]}]], + ["0", 0], + ["- 1", -1], + ["1e2147483648", Infinity] + ]; + + function json_cmp(x, y) { + if(x === y) + return true; + + if(!(x instanceof Object) || !(y instanceof Object)) + return false; + + for(var prop in x) { + if(!x.hasOwnProperty(prop)) + continue; + if(!x.hasOwnProperty(prop)) + return false; + if(!json_cmp(x[prop], y[prop])) + return false; + } + + for(var prop in y) { + if(!x.hasOwnProperty(prop) && y.hasOwnProperty(prop)) + return false; + } + + return true; + } + + for(i=0; i < parse_tests.length; i++) { + v = JSON.parse(parse_tests[i][0]); + ok(json_cmp(v, parse_tests[i][1]), "parse[" + i + "] returned " + v + ", expected " + parse_tests[i][1]); + } +})(); + var func = function (a) { var a = 1; if(a) return; @@ -1869,6 +1952,16 @@ tmp = func.toString(); ok(tmp == "function anonymous() {\n\n}", "func.toString() = " + tmp); +// Function constructor called as function +func = Function("return 3;"); + +tmp = func(); +ok(tmp === 3, "func() = " + tmp); +ok(func.call() === 3, "func.call() = " + tmp); +ok(func.length === 0, "func.length = " + func.length); +tmp = func.toString(); +ok(tmp === "function anonymous() {\nreturn 3;\n}", "func.toString() = " + tmp); + func = (function() { var tmp = 3; return new Function("return tmp;"); @@ -2707,6 +2800,14 @@ ["lbound", 0], ["toArray", 0], ["ubound", 0] +]); + +if(invokeVersion < 2) + ok(typeof(JSON) === "undefined", "JSON is not undefined"); +else + testFunctions(JSON, [ + ["parse", 2], + ["stringify", 3] ]); ok(ActiveXObject.length == 1, "ActiveXObject.length = " + ActiveXObject.length); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/console.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/console.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/console.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/console.c 2016-02-08 19:32:34.000000000 +0000 @@ -1360,6 +1360,22 @@ return ret; } +static COORD get_largest_console_window_size(HANDLE hConsole) +{ + COORD c = {0,0}; + + SERVER_START_REQ(get_console_output_info) + { + req->handle = console_handle_unmap(hConsole); + if (!wine_server_call_err(req)) + { + c.X = reply->max_width; + c.Y = reply->max_height; + } + } + SERVER_END_REQ; + return c; +} /*********************************************************************** * GetLargestConsoleWindowSize (KERNEL32.@) @@ -1378,33 +1394,21 @@ COORD c; DWORD w; } x; - x.c.X = 80; - x.c.Y = 24; + x.c = get_largest_console_window_size(hConsoleOutput); TRACE("(%p), returning %dx%d (%x)\n", hConsoleOutput, x.c.X, x.c.Y, x.w); return x.w; } -#endif /* defined(__i386__) */ +#else -/*********************************************************************** - * GetLargestConsoleWindowSize (KERNEL32.@) - * - * NOTE - * This should return a COORD, but calling convention for returning - * structures is different between Windows and gcc on i386. - * - * VERSION: [!i386] - */ -#ifndef __i386__ COORD WINAPI GetLargestConsoleWindowSize(HANDLE hConsoleOutput) { COORD c; - c.X = 80; - c.Y = 24; + c = get_largest_console_window_size(hConsoleOutput); TRACE("(%p), returning %dx%d\n", hConsoleOutput, c.X, c.Y); return c; } -#endif /* defined(__i386__) */ +#endif /* !defined(__i386__) */ static WCHAR* S_EditString /* = NULL */; static unsigned S_EditStrPos /* = 0 */; @@ -2146,8 +2150,8 @@ csbi->srWindow.Right = reply->win_right; csbi->srWindow.Top = reply->win_top; csbi->srWindow.Bottom = reply->win_bottom; - csbi->dwMaximumWindowSize.X = reply->max_width; - csbi->dwMaximumWindowSize.Y = reply->max_height; + csbi->dwMaximumWindowSize.X = min(reply->width, reply->max_width); + csbi->dwMaximumWindowSize.Y = min(reply->height, reply->max_height); } } SERVER_END_REQ; @@ -3242,6 +3246,12 @@ return 1; } +BOOL WINAPI SetConsoleFont(HANDLE hConsole, DWORD index) +{ + FIXME("(%p, %u): stub!\n", hConsole, index); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} BOOL WINAPI SetConsoleKeyShortcuts(BOOL set, BYTE keys, VOID *a, DWORD b) { @@ -3257,20 +3267,21 @@ memset(fontinfo, 0, sizeof(CONSOLE_FONT_INFO)); - if (maxwindow) - { - FIXME(": (%p, %d, %p) stub!\n", hConsole, maxwindow, fontinfo); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; - } - SERVER_START_REQ(get_console_output_info) { req->handle = console_handle_unmap(hConsole); if ((ret = !wine_server_call_err(req))) { - fontinfo->dwFontSize.X = reply->win_right - reply->win_left + 1; - fontinfo->dwFontSize.Y = reply->win_bottom - reply->win_top + 1; + if (maxwindow) + { + fontinfo->dwFontSize.X = min(reply->width, reply->max_width); + fontinfo->dwFontSize.Y = min(reply->height, reply->max_height); + } + else + { + fontinfo->dwFontSize.X = reply->win_right - reply->win_left + 1; + fontinfo->dwFontSize.Y = reply->win_bottom - reply->win_top + 1; + } } } SERVER_END_REQ; @@ -3321,3 +3332,17 @@ return get_console_font_size(hConsole, index); } #endif /* !defined(__i386__) */ + +BOOL WINAPI GetConsoleScreenBufferInfoEx(HANDLE hConsole, CONSOLE_SCREEN_BUFFER_INFOEX *csbix) +{ + FIXME("(%p %p): stub!\n", hConsole, csbix); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SetConsoleScreenBufferInfoEx(HANDLE hConsole, CONSOLE_SCREEN_BUFFER_INFOEX *csbix) +{ + FIXME("(%p %p): stub!\n", hConsole, csbix); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/editline.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/editline.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/editline.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/editline.c 2016-02-08 19:32:34.000000000 +0000 @@ -916,6 +916,7 @@ void (*func)(struct WCEL_Context* ctx); DWORD mode, input_mode, ks; int use_emacs; + CONSOLE_SCREEN_BUFFER_INFO csbi; memset(&ctx, 0, sizeof(ctx)); ctx.hConIn = hConsoleIn; @@ -994,6 +995,10 @@ if (ctx.insertkey) ctx.insert = !ctx.insert; + GetConsoleScreenBufferInfo(ctx.hConOut, &csbi); + if (ctx.csbi.wAttributes != csbi.wAttributes) + ctx.csbi.wAttributes = csbi.wAttributes; + if (func) (func)(&ctx); else if (!(ir.Event.KeyEvent.dwControlKeyState & LEFT_ALT_PRESSED)) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/kernel32.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/kernel32.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/kernel32.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/kernel32.spec 2016-02-08 19:32:34.000000000 +0000 @@ -615,7 +615,7 @@ @ stdcall GetConsoleOutputCP() @ stdcall GetConsoleProcessList(ptr long) @ stdcall GetConsoleScreenBufferInfo(long ptr) -# @ stub GetConsoleScreenBufferInfoEx +@ stdcall GetConsoleScreenBufferInfoEx(long ptr) # @ stub GetConsoleSelectionInfo @ stdcall GetConsoleTitleA(ptr long) @ stdcall GetConsoleTitleW(ptr long) @@ -824,7 +824,7 @@ @ stdcall GetSystemFirmwareTable(long long ptr long) @ stdcall GetSystemInfo(ptr) @ stdcall GetSystemPowerStatus(ptr) -# @ stub GetSystemPreferredUILanguages +@ stdcall GetSystemPreferredUILanguages(long ptr ptr ptr) @ stdcall GetSystemRegistryQuota(ptr ptr) @ stdcall GetSystemTime(ptr) @ stdcall GetSystemTimeAdjustment(ptr ptr ptr) @@ -860,7 +860,7 @@ @ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long) @ stdcall GetTimeFormatW(long long ptr wstr ptr long) @ stdcall GetTimeZoneInformation(ptr) -# @ stub GetTimeZoneInformationForYear +@ stdcall GetTimeZoneInformationForYear(long ptr ptr) @ stdcall GetThreadUILanguage() # @ stub GetUILanguageInfo # @ stub -arch=x86_64 GetUmsCompletionListEvent @@ -1345,7 +1345,7 @@ @ stub SetConsoleCursorMode @ stdcall SetConsoleCursorPosition(long long) @ stdcall SetConsoleDisplayMode(long long ptr) -@ stub SetConsoleFont +@ stdcall SetConsoleFont(long long) @ stub SetConsoleHardwareState @ stdcall SetConsoleIcon(ptr) @ stdcall SetConsoleInputExeNameA(ptr) @@ -1361,7 +1361,7 @@ @ stub SetConsoleOS2OemFormat @ stdcall SetConsoleOutputCP(long) @ stub SetConsolePalette -# @ stub SetConsoleScreenBufferInfoEx +@ stdcall SetConsoleScreenBufferInfoEx(long ptr) @ stdcall SetConsoleScreenBufferSize(long long) @ stdcall SetConsoleTextAttribute(long long) @ stdcall SetConsoleTitleA(str) @@ -1429,7 +1429,7 @@ # @ stub SetProcessUserModeExceptionPolicy @ stdcall SetProcessWorkingSetSize(long long long) # @ stub SetProcessWorkingSetSizeEx -# @ stub SetSearchPathMode +@ stdcall SetSearchPathMode(long) @ stdcall SetStdHandle(long long) # @ stub SetStdHandleEx @ stdcall SetSystemFileCacheSize(long long long) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/locale.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/locale.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/locale.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/locale.c 2016-02-08 19:32:34.000000000 +0000 @@ -1049,6 +1049,32 @@ } /*********************************************************************** + * GetSystemPreferredUILanguages (KERNEL32.@) + */ +BOOL WINAPI GetSystemPreferredUILanguages(DWORD flags, ULONG* count, WCHAR* buffer, ULONG* size) +{ + if (flags & ~(MUI_LANGUAGE_NAME | MUI_LANGUAGE_ID | MUI_MACHINE_LANGUAGE_SETTINGS)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if ((flags & MUI_LANGUAGE_NAME) && (flags & MUI_LANGUAGE_ID)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (*size && !buffer) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + FIXME("(0x%x %p %p %p) stub\n", flags, count, buffer, size); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +/*********************************************************************** * GetUserDefaultUILanguage (KERNEL32.@) * * Get the default user interface language Id for the current user. @@ -2126,7 +2152,7 @@ const union cptable *table; int ret; - if (!src || !srclen || (!dst && dstlen)) + if (!src || !srclen || (!dst && dstlen) || dstlen < 0) { SetLastError( ERROR_INVALID_PARAMETER ); return 0; @@ -2342,7 +2368,7 @@ const union cptable *table; int ret, used_tmp; - if (!src || !srclen || (!dst && dstlen)) + if (!src || !srclen || (!dst && dstlen) || dstlen < 0) { SetLastError( ERROR_INVALID_PARAMETER ); return 0; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/path.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/path.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/path.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/path.c 2016-02-08 19:32:34.000000000 +0000 @@ -2088,3 +2088,10 @@ return TRUE; } + +BOOL WINAPI SetSearchPathMode(DWORD flags) +{ + FIXME("(%x): stub\n", flags); + SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); + return FALSE; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/process.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/process.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/process.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/process.c 2016-02-08 19:32:34.000000000 +0000 @@ -3836,11 +3836,31 @@ /*********************************************************************** * GetLogicalProcessorInformationEx (KERNEL32.@) */ -BOOL WINAPI GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP relationship, PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX buffer, PDWORD pBufLen) +BOOL WINAPI GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP relationship, SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buffer, DWORD *len) { - FIXME("(%u,%p,%p): stub\n", relationship, buffer, pBufLen); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + NTSTATUS status; + + TRACE("(%u,%p,%p)\n", relationship, buffer, len); + + if (!len) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &relationship, sizeof(relationship), + buffer, *len, len ); + if (status == STATUS_INFO_LENGTH_MISMATCH) + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + return FALSE; + } + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError( status ) ); + return FALSE; + } + return TRUE; } /*********************************************************************** diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/codepage.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/codepage.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/codepage.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/codepage.c 2016-02-08 19:32:34.000000000 +0000 @@ -28,6 +28,7 @@ #include "winbase.h" #include "winnls.h" +static const char foobarA[] = "foobar"; static const WCHAR foobarW[] = {'f','o','o','b','a','r',0}; static void test_destination_buffer(void) @@ -144,48 +145,57 @@ static void test_negative_dest_length(void) { int len, i; - static char buf[LONGBUFLEN]; + static WCHAR bufW[LONGBUFLEN]; + static char bufA[LONGBUFLEN]; static WCHAR originalW[LONGBUFLEN]; static char originalA[LONGBUFLEN]; DWORD theError; /* Test return on -1 dest length */ SetLastError( 0xdeadbeef ); - memset(buf,'x',sizeof(buf)); - len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buf, -1, NULL, NULL); - todo_wine { - ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, - "WideCharToMultiByte(destlen -1): len=%d error=%x\n", len, GetLastError()); - } + memset(bufA,'x',sizeof(bufA)); + len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, -1, NULL, NULL); + ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, + "WideCharToMultiByte(destlen -1): len=%d error=%x\n", len, GetLastError()); + + SetLastError( 0xdeadbeef ); + memset(bufW,'x',sizeof(bufW)); + len = MultiByteToWideChar(CP_ACP, 0, foobarA, -1, bufW, -1); + ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, + "MultiByteToWideChar(destlen -1): len=%d error=%x\n", len, GetLastError()); /* Test return on -1000 dest length */ SetLastError( 0xdeadbeef ); - memset(buf,'x',sizeof(buf)); - len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buf, -1000, NULL, NULL); - todo_wine { - ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, - "WideCharToMultiByte(destlen -1000): len=%d error=%x\n", len, GetLastError()); - } + memset(bufA,'x',sizeof(bufA)); + len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, -1000, NULL, NULL); + ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, + "WideCharToMultiByte(destlen -1000): len=%d error=%x\n", len, GetLastError()); + + SetLastError( 0xdeadbeef ); + memset(bufW,'x',sizeof(bufW)); + len = MultiByteToWideChar(CP_ACP, 0, foobarA, -1000, bufW, -1); + ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, + "MultiByteToWideChar(destlen -1000): len=%d error=%x\n", len, GetLastError()); /* Test return on INT_MAX dest length */ SetLastError( 0xdeadbeef ); - memset(buf,'x',sizeof(buf)); - len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buf, INT_MAX, NULL, NULL); - ok(len == 7 && !lstrcmpA(buf, "foobar") && GetLastError() == 0xdeadbeef, + memset(bufA,'x',sizeof(bufA)); + len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, INT_MAX, NULL, NULL); + ok(len == 7 && !lstrcmpA(bufA, "foobar") && GetLastError() == 0xdeadbeef, "WideCharToMultiByte(destlen INT_MAX): len=%d error=%x\n", len, GetLastError()); /* Test return on INT_MAX dest length and very long input */ SetLastError( 0xdeadbeef ); - memset(buf,'x',sizeof(buf)); + memset(bufA,'x',sizeof(bufA)); for (i=0; i < LONGBUFLEN - 1; i++) { originalW[i] = 'Q'; originalA[i] = 'Q'; } originalW[LONGBUFLEN-1] = 0; originalA[LONGBUFLEN-1] = 0; - len = WideCharToMultiByte(CP_ACP, 0, originalW, -1, buf, INT_MAX, NULL, NULL); + len = WideCharToMultiByte(CP_ACP, 0, originalW, -1, bufA, INT_MAX, NULL, NULL); theError = GetLastError(); - ok(len == LONGBUFLEN && !lstrcmpA(buf, originalA) && theError == 0xdeadbeef, + ok(len == LONGBUFLEN && !lstrcmpA(bufA, originalA) && theError == 0xdeadbeef, "WideCharToMultiByte(srclen %d, destlen INT_MAX): len %d error=%x\n", LONGBUFLEN, len, theError); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/console.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/console.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/console.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/console.c 2016-02-08 19:32:34.000000000 +0000 @@ -2606,6 +2606,14 @@ memset(&cfi, 0, sizeof(CONSOLE_FONT_INFO)); SetLastError(0xdeadbeef); + ret = GetCurrentConsoleFont(NULL, TRUE, &cfi); + ok(!ret, "got %d, expected 0\n", ret); + ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError()); + ok(!cfi.dwFontSize.X, "got %d, expected 0\n", cfi.dwFontSize.X); + ok(!cfi.dwFontSize.Y, "got %d, expected 0\n", cfi.dwFontSize.Y); + + memset(&cfi, 0, sizeof(CONSOLE_FONT_INFO)); + SetLastError(0xdeadbeef); ret = GetCurrentConsoleFont(GetStdHandle(STD_INPUT_HANDLE), FALSE, &cfi); ok(!ret, "got %d, expected 0\n", ret); ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError()); @@ -2614,6 +2622,14 @@ memset(&cfi, 0, sizeof(CONSOLE_FONT_INFO)); SetLastError(0xdeadbeef); + ret = GetCurrentConsoleFont(GetStdHandle(STD_INPUT_HANDLE), TRUE, &cfi); + ok(!ret, "got %d, expected 0\n", ret); + ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError()); + ok(!cfi.dwFontSize.X, "got %d, expected 0\n", cfi.dwFontSize.X); + ok(!cfi.dwFontSize.Y, "got %d, expected 0\n", cfi.dwFontSize.Y); + + memset(&cfi, 0, sizeof(CONSOLE_FONT_INFO)); + SetLastError(0xdeadbeef); ret = GetCurrentConsoleFont(std_output, FALSE, &cfi); ok(ret, "got %d, expected non-zero\n", ret); ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError()); @@ -2625,6 +2641,16 @@ "got %d, expected %d\n", cfi.dwFontSize.X, width); ok(cfi.dwFontSize.Y == height || cfi.dwFontSize.Y == c.Y /* Vista and higher */, "got %d, expected %d\n", cfi.dwFontSize.Y, height); + + memset(&cfi, 0, sizeof(CONSOLE_FONT_INFO)); + SetLastError(0xdeadbeef); + ret = GetCurrentConsoleFont(std_output, TRUE, &cfi); + ok(ret, "got %d, expected non-zero\n", ret); + ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError()); + ok(cfi.dwFontSize.X == csbi.dwMaximumWindowSize.X, + "got %d, expected %d\n", cfi.dwFontSize.X, csbi.dwMaximumWindowSize.X); + ok(cfi.dwFontSize.Y == csbi.dwMaximumWindowSize.Y, + "got %d, expected %d\n", cfi.dwFontSize.Y, csbi.dwMaximumWindowSize.Y); } static void test_GetConsoleFontSize(HANDLE std_output) @@ -2681,6 +2707,78 @@ ok(!c.Y, "got %d, expected 0\n", c.Y); } +static void test_GetLargestConsoleWindowSize(HANDLE std_output) +{ + COORD c, font; + RECT r; + LONG workarea_w, workarea_h, maxcon_w, maxcon_h; + CONSOLE_SCREEN_BUFFER_INFO sbi; + CONSOLE_FONT_INFO cfi; + DWORD index, i; + HMODULE hmod; + BOOL ret; + DWORD (WINAPI *pGetNumberOfConsoleFonts)(void); + BOOL (WINAPI *pSetConsoleFont)(HANDLE, DWORD); + + memset(&c, 10, sizeof(COORD)); + SetLastError(0xdeadbeef); + c = GetLargestConsoleWindowSize(NULL); + ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError()); + ok(!c.X, "got %d, expected 0\n", c.X); + ok(!c.Y, "got %d, expected 0\n", c.Y); + + memset(&c, 10, sizeof(COORD)); + SetLastError(0xdeadbeef); + c = GetLargestConsoleWindowSize(GetStdHandle(STD_INPUT_HANDLE)); + ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError()); + ok(!c.X, "got %d, expected 0\n", c.X); + ok(!c.Y, "got %d, expected 0\n", c.Y); + + SystemParametersInfoW(SPI_GETWORKAREA, 0, &r, 0); + workarea_w = r.right - r.left; + workarea_h = r.bottom - r.top - GetSystemMetrics(SM_CYCAPTION); + + GetCurrentConsoleFont(std_output, FALSE, &cfi); + index = cfi.nFont; /* save current font index */ + + hmod = GetModuleHandleA("kernel32.dll"); + pGetNumberOfConsoleFonts = (void *)GetProcAddress(hmod, "GetNumberOfConsoleFonts"); + if (!pGetNumberOfConsoleFonts) + { + win_skip("GetNumberOfConsoleFonts is not available\n"); + return; + } + pSetConsoleFont = (void *)GetProcAddress(hmod, "SetConsoleFont"); + if (!pSetConsoleFont) + { + win_skip("SetConsoleFont is not available\n"); + return; + } + + for (i = 0; i < pGetNumberOfConsoleFonts(); i++) + { + pSetConsoleFont(std_output, i); + memset(&c, 10, sizeof(COORD)); + SetLastError(0xdeadbeef); + c = GetLargestConsoleWindowSize(std_output); + ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError()); + GetCurrentConsoleFont(std_output, FALSE, &cfi); + font = GetConsoleFontSize(std_output, cfi.nFont); + maxcon_w = workarea_w / font.X; + maxcon_h = workarea_h / font.Y; + ok(c.X == maxcon_w || c.X == maxcon_w - 1 /* Win10 */, "got %d, expected %d\n", c.X, maxcon_w); + ok(c.Y == maxcon_h || c.Y == maxcon_h - 1 /* Win10 */, "got %d, expected %d\n", c.Y, maxcon_h); + + ret = GetConsoleScreenBufferInfo(std_output, &sbi); + ok(ret, "GetConsoleScreenBufferInfo failed %u\n", GetLastError()); + ok(sbi.dwMaximumWindowSize.X == min(c.X, sbi.dwSize.X), "got %d, expected %d\n", + sbi.dwMaximumWindowSize.X, min(c.X, sbi.dwSize.X)); + ok(sbi.dwMaximumWindowSize.Y == min(c.Y, sbi.dwSize.Y), "got %d, expected %d\n", + sbi.dwMaximumWindowSize.Y, min(c.Y, sbi.dwSize.Y)); + } + pSetConsoleFont(std_output, index); /* restore original font size */ +} + START_TEST(console) { static const char font_name[] = "Lucida Console"; @@ -2787,6 +2885,17 @@ testScroll(hConOut, sbi.dwSize); /* will test sb creation / modification / codepage handling */ testScreenBuffer(hConOut); + + /* clear duplicated console font table */ + CloseHandle(hConIn); + CloseHandle(hConOut); + FreeConsole(); + ok(AllocConsole(), "Couldn't alloc console\n"); + hConIn = CreateFileA("CONIN$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); + hConOut = CreateFileA("CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); + ok(hConIn != INVALID_HANDLE_VALUE, "Opening ConIn\n"); + ok(hConOut != INVALID_HANDLE_VALUE, "Opening ConOut\n"); + testCtrlHandler(); /* still to be done: access rights & access on objects */ @@ -2815,4 +2924,5 @@ test_ReadConsoleOutputAttribute(hConOut); test_GetCurrentConsoleFont(hConOut); test_GetConsoleFontSize(hConOut); + test_GetLargestConsoleWindowSize(hConOut); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/debugger.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/debugger.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/debugger.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/debugger.c 2016-02-08 19:32:34.000000000 +0000 @@ -30,12 +30,6 @@ #define STATUS_DEBUGGER_INACTIVE ((NTSTATUS) 0xC0000354) #endif -#ifdef __GNUC__ -#define PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args))) -#else -#define PRINTF_ATTR(fmt,args) -#endif - #define child_ok (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_child_ok static int myARGC; @@ -49,7 +43,7 @@ static LONG child_failures; -static void PRINTF_ATTR(2, 3) test_child_ok(int condition, const char *msg, ...) +static void WINETEST_PRINTF_ATTR(2, 3) test_child_ok(int condition, const char *msg, ...) { va_list valist; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/locale.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/locale.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/locale.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/locale.c 2016-02-08 19:32:34.000000000 +0000 @@ -97,6 +97,7 @@ static INT (WINAPI *pGetGeoInfoA)(GEOID, GEOTYPE, LPSTR, INT, LANGID); static INT (WINAPI *pGetGeoInfoW)(GEOID, GEOTYPE, LPWSTR, INT, LANGID); static BOOL (WINAPI *pEnumSystemGeoID)(GEOCLASS, GEOID, GEO_ENUMPROC); +static BOOL (WINAPI *pGetSystemPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*); static void InitFunctionPointers(void) { @@ -125,6 +126,7 @@ X(GetGeoInfoA); X(GetGeoInfoW); X(EnumSystemGeoID); + X(GetSystemPreferredUILanguages); #undef X } @@ -4559,6 +4561,204 @@ } } +static void test_GetSystemPreferredUILanguages(void) +{ + BOOL ret; + ULONG count, size, size_id, size_name, size_buffer; + WCHAR *buffer; + + + if (!pGetSystemPreferredUILanguages) + { + win_skip("GetSystemPreferredUILanguages is not available.\n"); + return; + } + + /* (in)valid first parameter */ + count = 0xdeadbeef; + size = 0; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(0, &count, NULL, &size); + todo_wine + ok(ret, "Expected GetSystemPreferredUILanguages to succeed\n"); + ok(count, "Expected count > 0\n"); + todo_wine + ok(size % 6 == 1, "Expected size (%d) %% 6 == 1\n", size); + + count = 0xdeadbeef; + size = 0; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_FULL_LANGUAGE, &count, NULL, &size); + ok(!ret, "Expected GetSystemPreferredUILanguages to fail\n"); + ok(ERROR_INVALID_PARAMETER == GetLastError(), + "Expected error ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + count = 0xdeadbeef; + size = 0; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID | MUI_FULL_LANGUAGE, &count, NULL, &size); + ok(!ret, "Expected GetSystemPreferredUILanguages to fail\n"); + ok(ERROR_INVALID_PARAMETER == GetLastError(), + "Expected error ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + count = 0xdeadbeef; + size = 0; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID | MUI_LANGUAGE_NAME, &count, NULL, &size); + ok(!ret, "Expected GetSystemPreferredUILanguages to fail\n"); + ok(ERROR_INVALID_PARAMETER == GetLastError(), + "Expected error ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + count = 0xdeadbeef; + size = 0; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID | MUI_MACHINE_LANGUAGE_SETTINGS, &count, NULL, &size); + todo_wine + ok(ret, "Expected GetSystemPreferredUILanguages to succeed\n"); + ok(count, "Expected count > 0\n"); + todo_wine + ok(size % 5 == 1, "Expected size (%d) %% 5 == 1\n", size); + + count = 0xdeadbeef; + size = 0; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_NAME | MUI_MACHINE_LANGUAGE_SETTINGS, &count, NULL, &size); + todo_wine + ok(ret, "Expected GetSystemPreferredUILanguages to succeed\n"); + ok(count, "Expected count > 0\n"); + todo_wine + ok(size % 6 == 1, "Expected size (%d) %% 6 == 1\n", size); + + /* second parameter + * ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID, NULL, NULL, &size); + * -> unhandled exception c0000005 + */ + + /* invalid third parameter */ + count = 0xdeadbeef; + size = 1; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID, &count, NULL, &size); + ok(!ret, "Expected GetSystemPreferredUILanguages to fail\n"); + ok(ERROR_INVALID_PARAMETER == GetLastError(), + "Expected error ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + /* fourth parameter + * ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID, &count, NULL, NULL); + * -> unhandled exception c0000005 + */ + + count = 0xdeadbeef; + size_id = 0; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID, &count, NULL, &size_id); + todo_wine + ok(ret, "Expected GetSystemPreferredUILanguages to succeed\n"); + ok(count, "Expected count > 0\n"); + todo_wine + ok(size_id % 5 == 1, "Expected size (%d) %% 5 == 1\n", size_id); + + count = 0xdeadbeef; + size_name = 0; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_NAME, &count, NULL, &size_name); + todo_wine + ok(ret, "Expected GetSystemPreferredUILanguages to succeed\n"); + ok(count, "Expected count > 0\n"); + todo_wine + ok(size_name % 6 == 1, "Expected size (%d) %% 6 == 1\n", size_name); + + size_buffer = max(size_id, size_name); + if(!size_buffer) + { + skip("No vaild buffer size\n"); + return; + } + + buffer = HeapAlloc(GetProcessHeap(), 0, size_buffer * sizeof(WCHAR)); + if (!buffer) + { + skip("Failed to allocate memory for %d chars\n", size_buffer); + return; + } + + count = 0xdeadbeef; + size = size_buffer; + memset(buffer, 0x5a, size_buffer * sizeof(WCHAR)); + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(0, &count, buffer, &size); + ok(ret, "Expected GetSystemPreferredUILanguages to succeed\n"); + ok(count, "Expected count > 0\n"); + ok(size % 6 == 1, "Expected size (%d) %% 6 == 1\n", size); + if (ret && size % 6 == 1) + ok(!buffer[size -2] && !buffer[size -1], + "Expected last two WCHARs being empty, got 0x%x 0x%x\n", + buffer[size -2], buffer[size -1]); + + count = 0xdeadbeef; + size = size_buffer; + memset(buffer, 0x5a, size_buffer * sizeof(WCHAR)); + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID, &count, buffer, &size); + ok(ret, "Expected GetSystemPreferredUILanguages to succeed\n"); + ok(count, "Expected count > 0\n"); + ok(size % 5 == 1, "Expected size (%d) %% 5 == 1\n", size); + if (ret && size % 5 == 1) + ok(!buffer[size -2] && !buffer[size -1], + "Expected last two WCHARs being empty, got 0x%x 0x%x\n", + buffer[size -2], buffer[size -1]); + + count = 0xdeadbeef; + size = size_buffer; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_NAME, &count, buffer, &size); + ok(ret, "Expected GetSystemPreferredUILanguages to succeed\n"); + ok(count, "Expected count > 0\n"); + ok(size % 6 == 1, "Expected size (%d) %% 6 == 1\n", size); + if (ret && size % 5 == 1) + ok(!buffer[size -2] && !buffer[size -1], + "Expected last two WCHARs being empty, got 0x%x 0x%x\n", + buffer[size -2], buffer[size -1]); + + count = 0xdeadbeef; + size = 0; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_MACHINE_LANGUAGE_SETTINGS, &count, NULL, &size); + ok(ret, "Expected GetSystemPreferredUILanguages to succeed\n"); + ok(count, "Expected count > 0\n"); + ok(size % 6 == 1, "Expected size (%d) %% 6 == 1\n", size); + if (ret && size % 6 == 1) + ok(!buffer[size -2] && !buffer[size -1], + "Expected last two WCHARs being empty, got 0x%x 0x%x\n", + buffer[size -2], buffer[size -1]); + + count = 0xdeadbeef; + size = 1; + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID, &count, buffer, &size); + ok(!ret, "Expected GetSystemPreferredUILanguages to fail\n"); + ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), + "Expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + + count = 0xdeadbeef; + size = size_id -1; + memset(buffer, 0x5a, size_buffer * sizeof(WCHAR)); + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID, &count, buffer, &size); + ok(!ret, "Expected GetSystemPreferredUILanguages to fail\n"); + ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), + "Expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + + count = 0xdeadbeef; + size = size_id -2; + memset(buffer, 0x5a, size_buffer * sizeof(WCHAR)); + SetLastError(0xdeadbeef); + ret = pGetSystemPreferredUILanguages(0, &count, buffer, &size); + ok(!ret, "Expected GetSystemPreferredUILanguages to fail\n"); + ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), + "Expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); +} + START_TEST(locale) { InitFunctionPointers(); @@ -4600,6 +4800,7 @@ test_GetGeoInfo(); test_EnumSystemGeoID(); test_invariant(); + test_GetSystemPreferredUILanguages(); /* this requires collation table patch to make it MS compatible */ if (0) test_sorting(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/process.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/process.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/process.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/process.c 2016-02-08 19:32:34.000000000 +0000 @@ -87,7 +87,7 @@ static BOOL (WINAPI *pProcess32Next)(HANDLE, PROCESSENTRY32*); static BOOL (WINAPI *pThread32First)(HANDLE, THREADENTRY32*); static BOOL (WINAPI *pThread32Next)(HANDLE, THREADENTRY32*); - +static BOOL (WINAPI *pGetLogicalProcessorInformationEx)(LOGICAL_PROCESSOR_RELATIONSHIP,SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*,DWORD*); /* ############################### */ static char base[MAX_PATH]; @@ -251,6 +251,7 @@ pProcess32Next = (void *)GetProcAddress(hkernel32, "Process32Next"); pThread32First = (void *)GetProcAddress(hkernel32, "Thread32First"); pThread32Next = (void *)GetProcAddress(hkernel32, "Thread32Next"); + pGetLogicalProcessorInformationEx = (void *)GetProcAddress(hkernel32, "GetLogicalProcessorInformationEx"); return TRUE; } @@ -274,7 +275,7 @@ * static void childPrintf * */ -static void childPrintf(HANDLE h, const char* fmt, ...) +static void WINETEST_PRINTF_ATTR(2,3) childPrintf(HANDLE h, const char* fmt, ...) { va_list valist; char buffer[1024+4*MAX_LISTED_ENV_VAR]; @@ -311,10 +312,10 @@ /* output of startup info (Ansi) */ GetStartupInfoA(&siA); childPrintf(hFile, - "[StartupInfoA]\ncb=%08ld\nlpDesktop=%s\nlpTitle=%s\n" - "dwX=%lu\ndwY=%lu\ndwXSize=%lu\ndwYSize=%lu\n" - "dwXCountChars=%lu\ndwYCountChars=%lu\ndwFillAttribute=%lu\n" - "dwFlags=%lu\nwShowWindow=%u\n" + "[StartupInfoA]\ncb=%08u\nlpDesktop=%s\nlpTitle=%s\n" + "dwX=%u\ndwY=%u\ndwXSize=%u\ndwYSize=%u\n" + "dwXCountChars=%u\ndwYCountChars=%u\ndwFillAttribute=%u\n" + "dwFlags=%u\nwShowWindow=%u\n" "hStdInput=%lu\nhStdOutput=%lu\nhStdError=%lu\n\n", siA.cb, encodeA(siA.lpDesktop), encodeA(siA.lpTitle), siA.dwX, siA.dwY, siA.dwXSize, siA.dwYSize, @@ -338,10 +339,10 @@ memset(&siW, 0, sizeof(siW)); GetStartupInfoW(&siW); childPrintf(hFile, - "[StartupInfoW]\ncb=%08ld\nlpDesktop=%s\nlpTitle=%s\n" - "dwX=%lu\ndwY=%lu\ndwXSize=%lu\ndwYSize=%lu\n" - "dwXCountChars=%lu\ndwYCountChars=%lu\ndwFillAttribute=%lu\n" - "dwFlags=%lu\nwShowWindow=%u\n" + "[StartupInfoW]\ncb=%08u\nlpDesktop=%s\nlpTitle=%s\n" + "dwX=%u\ndwY=%u\ndwXSize=%u\ndwYSize=%u\n" + "dwXCountChars=%u\ndwYCountChars=%u\ndwFillAttribute=%u\n" + "dwFlags=%u\nwShowWindow=%u\n" "hStdInput=%lu\nhStdOutput=%lu\nhStdError=%lu\n\n", siW.cb, encodeW(siW.lpDesktop), encodeW(siW.lpTitle), siW.dwX, siW.dwY, siW.dwXSize, siW.dwYSize, @@ -444,9 +445,9 @@ childPrintf(hFile, "InputCP=%d\nOutputCP=%d\n", GetConsoleCP(), GetConsoleOutputCP()); if (GetConsoleMode(hConIn, &modeIn)) - childPrintf(hFile, "InputMode=%ld\n", modeIn); + childPrintf(hFile, "InputMode=%u\n", modeIn); if (GetConsoleMode(hConOut, &modeOut)) - childPrintf(hFile, "OutputMode=%ld\n", modeOut); + childPrintf(hFile, "OutputMode=%u\n", modeOut); /* now that we have written all relevant information, let's change it */ SetLastError(0xdeadbeef); @@ -3107,6 +3108,38 @@ CloseHandle(hproc); } +static void test_GetLogicalProcessorInformationEx(void) +{ + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *info; + DWORD len; + BOOL ret; + + if (!pGetLogicalProcessorInformationEx) + { + win_skip("GetLogicalProcessorInformationEx() is not supported\n"); + return; + } + + ret = pGetLogicalProcessorInformationEx(RelationAll, NULL, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %d\n", ret, GetLastError()); + + len = 0; + ret = pGetLogicalProcessorInformationEx(RelationProcessorCore, NULL, &len); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d, error %d\n", ret, GetLastError()); + ok(len > 0, "got %u\n", len); + + len = 0; + ret = pGetLogicalProcessorInformationEx(RelationAll, NULL, &len); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d, error %d\n", ret, GetLastError()); + ok(len > 0, "got %u\n", len); + + info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); + ret = pGetLogicalProcessorInformationEx(RelationAll, info, &len); + ok(ret, "got %d, error %d\n", ret, GetLastError()); + ok(info->Size > 0, "got %u\n", info->Size); + HeapFree(GetProcessHeap(), 0, info); +} + START_TEST(process) { HANDLE job; @@ -3153,6 +3186,7 @@ ok(0, "Unexpected command %s\n", myARGV[2]); return; } + test_process_info(); test_TerminateProcess(); test_Startup(); @@ -3177,6 +3211,7 @@ test_StartupNoConsole(); test_GetNumaProcessorNode(); test_session_info(); + test_GetLogicalProcessorInformationEx(); /* things that can be tested: * lookup: check the way program to be executed is searched diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/time.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/time.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/tests/time.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/tests/time.c 2016-02-08 19:32:34.000000000 +0000 @@ -31,6 +31,7 @@ static int (WINAPI *pGetCalendarInfoW)(LCID,CALID,CALTYPE,LPWSTR,int,LPDWORD); static DWORD (WINAPI *pGetDynamicTimeZoneInformation)(DYNAMIC_TIME_ZONE_INFORMATION*); static void (WINAPI *pGetSystemTimePreciseAsFileTime)(LPFILETIME); +static BOOL (WINAPI *pGetTimeZoneInformationForYear)(USHORT, PDYNAMIC_TIME_ZONE_INFORMATION, LPTIME_ZONE_INFORMATION); #define SECSPERMIN 60 #define SECSPERDAY 86400 @@ -869,6 +870,123 @@ HeapFree(GetProcessHeap(), 0, sppi); } +static WORD day_of_month(const SYSTEMTIME* systemtime, WORD year) +{ + SYSTEMTIME first_of_month = {0}; + FILETIME filetime; + WORD result; + + if (systemtime->wYear != 0) + return systemtime->wDay; + + first_of_month.wYear = year; + first_of_month.wMonth = systemtime->wMonth; + first_of_month.wDay = 1; + + /* round-trip conversion sets day of week field */ + SystemTimeToFileTime(&first_of_month, &filetime); + FileTimeToSystemTime(&filetime, &first_of_month); + + result = 1 + ((systemtime->wDayOfWeek - first_of_month.wDayOfWeek + 7) % 7) + + (7 * (systemtime->wDay - 1)); + + if (systemtime->wDay == 5) + { + /* make sure this isn't in the next month */ + SYSTEMTIME result_date; + + result_date = first_of_month; + result_date.wDay = result; + + SystemTimeToFileTime(&result_date, &filetime); + FileTimeToSystemTime(&filetime, &result_date); + + if (result_date.wDay != result) + result = 1 + ((systemtime->wDayOfWeek - first_of_month.wDayOfWeek + 7) % 7) + + (7 * (4 - 1)); + } + + return result; +} + +static void test_GetTimeZoneInformationForYear(void) +{ + BOOL ret; + SYSTEMTIME systemtime; + TIME_ZONE_INFORMATION local_tzinfo, tzinfo; + DYNAMIC_TIME_ZONE_INFORMATION dyn_tzinfo; + static const WCHAR std_tzname[] = {'G','r','e','e','n','l','a','n','d',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e',0}; + static const WCHAR dlt_tzname[] = {'G','r','e','e','n','l','a','n','d',' ','D','a','y','l','i','g','h','t',' ','T','i','m','e',0}; + WORD std_day, dlt_day; + + if (!pGetTimeZoneInformationForYear || !pGetDynamicTimeZoneInformation) + { + win_skip("GetTimeZoneInformationForYear not available\n"); + return; + } + + GetLocalTime(&systemtime); + + GetTimeZoneInformation(&local_tzinfo); + + ret = pGetTimeZoneInformationForYear(systemtime.wYear, NULL, &tzinfo); + ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %u\n", GetLastError()); + ok(tzinfo.Bias == local_tzinfo.Bias, "Expected Bias %d, got %d\n", local_tzinfo.Bias, tzinfo.Bias); + ok(!lstrcmpW(tzinfo.StandardName, local_tzinfo.StandardName), + "Expected StandardName %s, got %s\n", wine_dbgstr_w(local_tzinfo.StandardName), wine_dbgstr_w(tzinfo.StandardName)); + ok(!memcmp(&tzinfo.StandardDate, &local_tzinfo.StandardDate, sizeof(SYSTEMTIME)), "StandardDate does not match\n"); + ok(tzinfo.StandardBias == local_tzinfo.StandardBias, "Expected StandardBias %d, got %d\n", local_tzinfo.StandardBias, tzinfo.StandardBias); + ok(!lstrcmpW(tzinfo.DaylightName, local_tzinfo.DaylightName), + "Expected DaylightName %s, got %s\n", wine_dbgstr_w(local_tzinfo.DaylightName), wine_dbgstr_w(tzinfo.DaylightName)); + ok(!memcmp(&tzinfo.DaylightDate, &local_tzinfo.DaylightDate, sizeof(SYSTEMTIME)), "DaylightDate does not match\n"); + ok(tzinfo.DaylightBias == local_tzinfo.DaylightBias, "Expected DaylightBias %d, got %d\n", local_tzinfo.DaylightBias, tzinfo.DaylightBias); + + pGetDynamicTimeZoneInformation(&dyn_tzinfo); + + ret = pGetTimeZoneInformationForYear(systemtime.wYear, &dyn_tzinfo, &tzinfo); + ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %u\n", GetLastError()); + ok(tzinfo.Bias == local_tzinfo.Bias, "Expected Bias %d, got %d\n", local_tzinfo.Bias, tzinfo.Bias); + ok(!lstrcmpW(tzinfo.StandardName, local_tzinfo.StandardName), + "Expected StandardName %s, got %s\n", wine_dbgstr_w(local_tzinfo.StandardName), wine_dbgstr_w(tzinfo.StandardName)); + ok(!memcmp(&tzinfo.StandardDate, &local_tzinfo.StandardDate, sizeof(SYSTEMTIME)), "StandardDate does not match\n"); + ok(tzinfo.StandardBias == local_tzinfo.StandardBias, "Expected StandardBias %d, got %d\n", local_tzinfo.StandardBias, tzinfo.StandardBias); + ok(!lstrcmpW(tzinfo.DaylightName, local_tzinfo.DaylightName), + "Expected DaylightName %s, got %s\n", wine_dbgstr_w(local_tzinfo.DaylightName), wine_dbgstr_w(tzinfo.DaylightName)); + ok(!memcmp(&tzinfo.DaylightDate, &local_tzinfo.DaylightDate, sizeof(SYSTEMTIME)), "DaylightDate does not match\n"); + ok(tzinfo.DaylightBias == local_tzinfo.DaylightBias, "Expected DaylightBias %d, got %d\n", local_tzinfo.DaylightBias, tzinfo.DaylightBias); + + memset(&dyn_tzinfo, 0xaa, sizeof(dyn_tzinfo)); + lstrcpyW(dyn_tzinfo.TimeZoneKeyName, std_tzname); + dyn_tzinfo.DynamicDaylightTimeDisabled = FALSE; + + ret = pGetTimeZoneInformationForYear(2015, &dyn_tzinfo, &tzinfo); + ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %u\n", GetLastError()); + ok(tzinfo.Bias == 180, "Expected Bias 180, got %d\n", tzinfo.Bias); + ok(!lstrcmpW(tzinfo.StandardName, std_tzname) || broken(!tzinfo.StandardName[0]) /* vista,7 */, + "Expected StandardName %s, got %s\n", + wine_dbgstr_w(std_tzname), wine_dbgstr_w(tzinfo.StandardName)); + ok(tzinfo.StandardDate.wMonth == 10, "Expected standard month 10, got %d\n", tzinfo.StandardDate.wMonth); + std_day = day_of_month(&tzinfo.StandardDate, 2015); + ok(std_day == 24, "Expected standard day 24, got %d\n", std_day); + ok(tzinfo.StandardBias == 0, "Expected StandardBias 0, got %d\n", tzinfo.StandardBias); + ok(!lstrcmpW(tzinfo.DaylightName, dlt_tzname) || broken(!tzinfo.DaylightName[0]) /* vista,7 */, + "Expected DaylightName %s, got %s\n", + wine_dbgstr_w(dlt_tzname), wine_dbgstr_w(tzinfo.DaylightName)); + ok(tzinfo.DaylightDate.wMonth == 3, "Expected daylight month 3, got %d\n", tzinfo.DaylightDate.wMonth); + dlt_day = day_of_month(&tzinfo.DaylightDate, 2015); + ok(dlt_day == 28, "Expected daylight day 28, got %d\n", dlt_day); + ok(tzinfo.DaylightBias == -60, "Expected DaylightBias -60, got %d\n", tzinfo.DaylightBias); + + memset(&dyn_tzinfo, 0xaa, sizeof(dyn_tzinfo)); + lstrcpyW(dyn_tzinfo.TimeZoneKeyName, dlt_tzname); + + SetLastError(0xdeadbeef); + ret = pGetTimeZoneInformationForYear(2015, &dyn_tzinfo, &tzinfo); + ok((ret == FALSE && GetLastError() == ERROR_FILE_NOT_FOUND) || + broken(ret == TRUE) /* vista,7 */, + "GetTimeZoneInformationForYear err %u\n", GetLastError()); +} + START_TEST(time) { HMODULE hKernel = GetModuleHandleA("kernel32"); @@ -879,6 +997,7 @@ pGetCalendarInfoW = (void *)GetProcAddress(hKernel, "GetCalendarInfoW"); pGetDynamicTimeZoneInformation = (void *)GetProcAddress(hKernel, "GetDynamicTimeZoneInformation"); pGetSystemTimePreciseAsFileTime = (void *)GetProcAddress(hKernel, "GetSystemTimePreciseAsFileTime"); + pGetTimeZoneInformationForYear = (void *)GetProcAddress(hKernel, "GetTimeZoneInformationForYear"); test_conversions(); test_invalid_arg(); @@ -891,4 +1010,5 @@ test_GetCalendarInfo(); test_GetDynamicTimeZoneInformation(); test_GetSystemTimePreciseAsFileTime(); + test_GetTimeZoneInformationForYear(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/time.c wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/time.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/kernel32/time.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/kernel32/time.c 2016-02-08 19:32:34.000000000 +0000 @@ -282,6 +282,179 @@ return TRUE; } +/*********************************************************************** + * TIME_GetSpecificTimeZoneKey + * + * Opens the registry key for the time zone with the given name. + * + * PARAMS + * key_name [in] The time zone name. + * result [out] The open registry key handle. + * + * RETURNS + * TRUE if successful. + */ +static BOOL TIME_GetSpecificTimeZoneKey( const WCHAR *key_name, HANDLE *result ) +{ + static const WCHAR Time_ZonesW[] = { '\\','R','E','G','I','S','T','R','Y','\\', + 'M','a','c','h','i','n','e','\\', + 'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\', + 'W','i','n','d','o','w','s',' ','N','T','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', + 'T','i','m','e',' ','Z','o','n','e','s',0 }; + HANDLE time_zones_key; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + NTSTATUS status; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + RtlInitUnicodeString( &nameW, Time_ZonesW ); + status = NtOpenKey( &time_zones_key, KEY_READ, &attr ); + if (status) + { + WARN("Unable to open the time zones key\n"); + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + + attr.RootDirectory = time_zones_key; + RtlInitUnicodeString( &nameW, key_name ); + status = NtOpenKey( result, KEY_READ, &attr ); + + NtClose( time_zones_key ); + + if (status) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + + return TRUE; +} + +static BOOL reg_query_value(HKEY hkey, LPCWSTR name, DWORD type, void *data, DWORD count) +{ + UNICODE_STRING nameW; + char buf[256]; + KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buf; + NTSTATUS status; + + if (count > sizeof(buf) - sizeof(KEY_VALUE_PARTIAL_INFORMATION)) + return FALSE; + + RtlInitUnicodeString(&nameW, name); + + if ((status = NtQueryValueKey(hkey, &nameW, KeyValuePartialInformation, + buf, sizeof(buf), &count))) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + + if (info->Type != type) + { + SetLastError( ERROR_DATATYPE_MISMATCH ); + return FALSE; + } + + memcpy(data, info->Data, info->DataLength); + return TRUE; +} + +/*********************************************************************** + * TIME_GetSpecificTimeZoneInfo + * + * Returns time zone information for the given time zone and year. + * + * PARAMS + * key_name [in] The time zone name. + * year [in] The year, if Dynamic DST is used. + * dynamic [in] Whether to use Dynamic DST. + * result [out] The time zone information. + * + * RETURNS + * TRUE if successful. + */ +static BOOL TIME_GetSpecificTimeZoneInfo( const WCHAR *key_name, WORD year, + BOOL dynamic, DYNAMIC_TIME_ZONE_INFORMATION *tzinfo ) +{ + static const WCHAR Dynamic_DstW[] = { 'D','y','n','a','m','i','c',' ','D','S','T',0 }; + static const WCHAR fmtW[] = { '%','d',0 }; + static const WCHAR stdW[] = { 'S','t','d',0 }; + static const WCHAR dltW[] = { 'D','l','t',0 }; + static const WCHAR tziW[] = { 'T','Z','I',0 }; + HANDLE time_zone_key, dynamic_dst_key; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + WCHAR yearW[16]; + BOOL got_reg_data = FALSE; + struct tz_reg_data + { + LONG bias; + LONG std_bias; + LONG dlt_bias; + SYSTEMTIME std_date; + SYSTEMTIME dlt_date; + } tz_data; + + if (!TIME_GetSpecificTimeZoneKey( key_name, &time_zone_key )) + return FALSE; + + if (!reg_query_value( time_zone_key, stdW, REG_SZ, tzinfo->StandardName, sizeof(tzinfo->StandardName)) || + !reg_query_value( time_zone_key, dltW, REG_SZ, tzinfo->DaylightName, sizeof(tzinfo->DaylightName))) + { + NtClose( time_zone_key ); + return FALSE; + } + + lstrcpyW(tzinfo->TimeZoneKeyName, key_name); + + if (dynamic) + { + attr.Length = sizeof(attr); + attr.RootDirectory = time_zone_key; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + RtlInitUnicodeString( &nameW, Dynamic_DstW ); + if (!NtOpenKey( &dynamic_dst_key, KEY_READ, &attr )) + { + sprintfW( yearW, fmtW, year ); + got_reg_data = reg_query_value( dynamic_dst_key, yearW, REG_BINARY, &tz_data, sizeof(tz_data) ); + + NtClose( dynamic_dst_key ); + } + } + + if (!got_reg_data) + { + if (!reg_query_value( time_zone_key, tziW, REG_BINARY, &tz_data, sizeof(tz_data) )) + { + NtClose( time_zone_key ); + return FALSE; + } + } + + tzinfo->Bias = tz_data.bias; + tzinfo->StandardBias = tz_data.std_bias; + tzinfo->DaylightBias = tz_data.dlt_bias; + tzinfo->StandardDate = tz_data.std_date; + tzinfo->DaylightDate = tz_data.dlt_date; + + tzinfo->DynamicDaylightTimeDisabled = !dynamic; + + NtClose( time_zone_key ); + + return TRUE; +} + /*********************************************************************** * SetLocalTime (KERNEL32.@) @@ -418,6 +591,30 @@ } /*********************************************************************** + * GetTimeZoneInformationForYear (KERNEL32.@) + */ +BOOL WINAPI GetTimeZoneInformationForYear( USHORT wYear, + PDYNAMIC_TIME_ZONE_INFORMATION pdtzi, LPTIME_ZONE_INFORMATION ptzi ) +{ + DYNAMIC_TIME_ZONE_INFORMATION local_dtzi, result; + + if (!pdtzi) + { + if (GetDynamicTimeZoneInformation(&local_dtzi) == TIME_ZONE_ID_INVALID) + return FALSE; + pdtzi = &local_dtzi; + } + + if (!TIME_GetSpecificTimeZoneInfo(pdtzi->TimeZoneKeyName, wYear, + !pdtzi->DynamicDaylightTimeDisabled, &result)) + return FALSE; + + memcpy(ptzi, &result, sizeof(*ptzi)); + + return TRUE; +} + +/*********************************************************************** * SetTimeZoneInformation (KERNEL32.@) * * Change the settings of the current local time zone. diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mapi32/imalloc.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mapi32/imalloc.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mapi32/imalloc.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mapi32/imalloc.c 2016-02-08 19:32:34.000000000 +0000 @@ -112,9 +112,9 @@ /************************************************************************** * IMAPIMalloc_Alloc */ -static LPVOID WINAPI IMAPIMalloc_fnAlloc(LPMALLOC iface, DWORD cb) +static LPVOID WINAPI IMAPIMalloc_fnAlloc(LPMALLOC iface, SIZE_T cb) { - TRACE("(%p)->(%d)\n", iface, cb); + TRACE("(%p)->(%ld)\n", iface, cb); return LocalAlloc(LMEM_FIXED, cb); } @@ -122,9 +122,9 @@ /************************************************************************** * IMAPIMalloc_Realloc */ -static LPVOID WINAPI IMAPIMalloc_fnRealloc(LPMALLOC iface, LPVOID pv, DWORD cb) +static LPVOID WINAPI IMAPIMalloc_fnRealloc(LPMALLOC iface, LPVOID pv, SIZE_T cb) { - TRACE("(%p)->(%p, %d)\n", iface, pv, cb); + TRACE("(%p)->(%p, %ld)\n", iface, pv, cb); if (!pv) return LocalAlloc(LMEM_FIXED, cb); @@ -148,7 +148,7 @@ /************************************************************************** * IMAPIMalloc_GetSize */ -static DWORD WINAPI IMAPIMalloc_fnGetSize(LPMALLOC iface, LPVOID pv) +static SIZE_T WINAPI IMAPIMalloc_fnGetSize(LPMALLOC iface, LPVOID pv) { TRACE("(%p)->(%p)\n", iface, pv); return LocalSize(pv); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mciqtz32/mciqtz.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mciqtz32/mciqtz.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mciqtz32/mciqtz.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mciqtz32/mciqtz.c 2016-02-08 19:32:34.000000000 +0000 @@ -936,6 +936,53 @@ return 0; } +/*************************************************************************** + * MCIQTZ_mciPut [internal] + */ +static DWORD MCIQTZ_mciPut(UINT wDevID, DWORD dwFlags, MCI_GENERIC_PARMS *lpParms) +{ + WINE_MCIQTZ *wma = MCIQTZ_mciGetOpenDev(wDevID); + MCI_DGV_RECT_PARMS *rectparms; + HRESULT hr; + + TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); + + if (!wma) + return MCIERR_INVALID_DEVICE_ID; + + if (!(dwFlags & MCI_DGV_RECT)) { + FIXME("No support for non-RECT MCI_PUT\n"); + return 1; + } + + if (dwFlags & MCI_TEST) + return 0; + + dwFlags &= ~MCI_DGV_RECT; + rectparms = (MCI_DGV_RECT_PARMS*)lpParms; + + if (dwFlags & MCI_DGV_PUT_DESTINATION) { + hr = IVideoWindow_SetWindowPosition(wma->vidwin, + rectparms->rc.left, rectparms->rc.top, + rectparms->rc.right - rectparms->rc.left, + rectparms->rc.bottom - rectparms->rc.top); + if(FAILED(hr)) + WARN("IVideoWindow_SetWindowPosition failed: 0x%x\n", hr); + + dwFlags &= ~MCI_DGV_PUT_DESTINATION; + } + + if (dwFlags & MCI_NOTIFY) { + MCIQTZ_mciNotify(lpParms->dwCallback, wma, MCI_NOTIFY_SUCCESSFUL); + dwFlags &= ~MCI_NOTIFY; + } + + if (dwFlags) + FIXME("No support for some flags: 0x%x\n", dwFlags); + + return 0; +} + /****************************************************************************** * MCIAVI_mciUpdate [internal] */ @@ -1099,6 +1146,9 @@ case MCI_WINDOW: task->res = MCIQTZ_mciWindow(task->devid, task->flags, (LPMCI_DGV_WINDOW_PARMSW)task->parms); break; + case MCI_PUT: + task->res = MCIQTZ_mciPut(task->devid, task->flags, (MCI_GENERIC_PARMS*)task->parms); + break; case MCI_CLOSE: /* Special internal message */ SetEvent(task->done); @@ -1163,9 +1213,9 @@ case MCI_SETAUDIO: case MCI_UPDATE: case MCI_WINDOW: + case MCI_PUT: if (!dwParam2) return MCIERR_NULL_PARAMETER_BLOCK; return MCIQTZ_relayTaskMessage(dwDevID, wMsg, dwParam1, dwParam2); - case MCI_PUT: case MCI_RECORD: case MCI_RESUME: case MCI_INFO: diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mpr/tests/mpr.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mpr/tests/mpr.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mpr/tests/mpr.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mpr/tests/mpr.c 2016-02-08 19:32:34.000000000 +0000 @@ -164,6 +164,7 @@ static DWORD (WINAPI *pWNetGetCachedPassword)( LPSTR, WORD, LPSTR, LPWORD, BYTE ); static UINT (WINAPI *pWNetEnumCachedPasswords)( LPSTR, WORD, BYTE, ENUMPASSWORDPROC, DWORD); static UINT (WINAPI *pWNetRemoveCachedPassword)( LPSTR, WORD, BYTE ); +static DWORD (WINAPI *pWNetUseConnectionA)( HWND, LPNETRESOURCEA, LPCSTR, LPCSTR, DWORD, LPSTR, LPDWORD, LPDWORD ); #define MPR_GET_PROC(func) \ p ## func = (void*)GetProcAddress(hmpr, #func) @@ -176,6 +177,7 @@ MPR_GET_PROC(WNetGetCachedPassword); MPR_GET_PROC(WNetEnumCachedPasswords); MPR_GET_PROC(WNetRemoveCachedPassword); + MPR_GET_PROC(WNetUseConnectionA); } static const char* m_resource = "wine-test-resource"; @@ -257,9 +259,62 @@ } } +static void test_WNetUseConnection(void) +{ + DWORD ret; + DWORD bufSize; + DWORD outRes; + LPNETRESOURCEA netRes; + CHAR outBuf[4]; + + if (pWNetUseConnectionA) + { + netRes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NETRESOURCEA) + sizeof("\\\\127.0.0.1\\c$") + sizeof("J:")); + netRes->dwType = RESOURCETYPE_DISK; + netRes->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE; + netRes->dwUsage = RESOURCEUSAGE_CONNECTABLE; + netRes->lpLocalName = (LPSTR)((LPBYTE)netRes + sizeof(NETRESOURCEA)); + netRes->lpRemoteName = (LPSTR)((LPBYTE)netRes + sizeof(NETRESOURCEA) + sizeof("J:")); + strcpy(netRes->lpLocalName, "J:"); + strcpy(netRes->lpRemoteName, "\\\\127.0.0.1\\c$"); + bufSize = 0; + ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, NULL, &bufSize, &outRes); + todo_wine + ok(ret == WN_SUCCESS, "Unexpected return: %u\n", ret); + ok(bufSize == 0, "Unexpected buffer size: %u\n", bufSize); + if (ret == WN_SUCCESS) + WNetCancelConnectionA("J:", TRUE); + bufSize = 0; + ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); + todo_wine + ok(ret == ERROR_INVALID_PARAMETER, "Unexpected return: %u\n", ret); + ok(bufSize == 0, "Unexpected buffer size: %u\n", bufSize); + if (ret == WN_SUCCESS) + WNetCancelConnectionA("J:", TRUE); + bufSize = 1; + todo_wine { + ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); + ok(ret == ERROR_MORE_DATA, "Unexpected return: %u\n", ret); + ok(bufSize == 3, "Unexpected buffer size: %u\n", bufSize); + if (ret == WN_SUCCESS) + WNetCancelConnectionA("J:", TRUE); + bufSize = 4; + ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); + ok(ret == WN_SUCCESS, "Unexpected return: %u\n", ret); + } + ok(bufSize == 4, "Unexpected buffer size: %u\n", bufSize); + if (ret == WN_SUCCESS) + WNetCancelConnectionA("J:", TRUE); + HeapFree(GetProcessHeap(), 0, netRes); + } else { + win_skip("WNetUseConnection() is not supported.\n"); + } +} + START_TEST(mpr) { test_WNetGetUniversalName(); test_WNetGetRemoteName(); test_WNetCachePassword(); + test_WNetUseConnection(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mpr/wnet.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mpr/wnet.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mpr/wnet.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mpr/wnet.c 2016-02-08 19:32:34.000000000 +0000 @@ -133,11 +133,17 @@ DWORD type, size = sizeof(providerPath); if (RegQueryValueExW(hKey, szProviderPath, NULL, &type, - (LPBYTE)providerPath, &size) == ERROR_SUCCESS && type == REG_SZ) + (LPBYTE)providerPath, &size) == ERROR_SUCCESS && (type == REG_SZ || type == REG_EXPAND_SZ)) { static const WCHAR szProviderName[] = { 'N','a','m','e',0 }; PWSTR name = NULL; - + + if (type == REG_EXPAND_SZ) + { + WCHAR path[MAX_PATH]; + if (ExpandEnvironmentStringsW(providerPath, path, MAX_PATH)) lstrcpyW( providerPath, path ); + } + size = 0; RegQueryValueExW(hKey, szProviderName, NULL, NULL, NULL, &size); if (size) @@ -1487,11 +1493,12 @@ DWORD WINAPI WNetAddConnectionA( LPCSTR lpRemoteName, LPCSTR lpPassword, LPCSTR lpLocalName ) { - FIXME( "(%s, %p, %s): stub\n", - debugstr_a(lpRemoteName), lpPassword, debugstr_a(lpLocalName) ); + NETRESOURCEA resourcesA; - SetLastError(WN_NO_NETWORK); - return WN_NO_NETWORK; + memset(&resourcesA, 0, sizeof(resourcesA)); + resourcesA.lpRemoteName = (LPSTR)lpRemoteName; + resourcesA.lpLocalName = (LPSTR)lpLocalName; + return WNetUseConnectionA(NULL, &resourcesA, lpPassword, NULL, 0, NULL, 0, NULL); } /********************************************************************* @@ -1500,11 +1507,12 @@ DWORD WINAPI WNetAddConnectionW( LPCWSTR lpRemoteName, LPCWSTR lpPassword, LPCWSTR lpLocalName ) { - FIXME( "(%s, %p, %s): stub\n", - debugstr_w(lpRemoteName), lpPassword, debugstr_w(lpLocalName) ); + NETRESOURCEW resourcesW; - SetLastError(WN_NO_NETWORK); - return WN_NO_NETWORK; + memset(&resourcesW, 0, sizeof(resourcesW)); + resourcesW.lpRemoteName = (LPWSTR)lpRemoteName; + resourcesW.lpLocalName = (LPWSTR)lpLocalName; + return WNetUseConnectionW(NULL, &resourcesW, lpPassword, NULL, 0, NULL, 0, NULL); } /********************************************************************* @@ -1514,11 +1522,8 @@ LPCSTR lpPassword, LPCSTR lpUserID, DWORD dwFlags ) { - FIXME( "(%p, %p, %s, 0x%08X): stub\n", - lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags ); - - SetLastError(WN_NO_NETWORK); - return WN_NO_NETWORK; + return WNetUseConnectionA(NULL, lpNetResource, lpPassword, lpUserID, dwFlags, + NULL, 0, NULL); } /********************************************************************* @@ -1528,11 +1533,8 @@ LPCWSTR lpPassword, LPCWSTR lpUserID, DWORD dwFlags ) { - FIXME( "(%p, %p, %s, 0x%08X): stub\n", - lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags ); - - SetLastError(WN_NO_NETWORK); - return WN_NO_NETWORK; + return WNetUseConnectionW(NULL, lpNetResource, lpPassword, lpUserID, dwFlags, + NULL, 0, NULL); } /********************************************************************* @@ -1542,11 +1544,8 @@ LPCSTR lpPassword, LPCSTR lpUserID, DWORD dwFlags ) { - FIXME( "(%p, %p, %p, %s, 0x%08X), stub\n", - hwndOwner, lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags ); - - SetLastError(WN_NO_NETWORK); - return WN_NO_NETWORK; + return WNetUseConnectionA(hwndOwner, lpNetResource, lpPassword, lpUserID, + dwFlags, NULL, 0, NULL); } /********************************************************************* @@ -1556,11 +1555,8 @@ LPCWSTR lpPassword, LPCWSTR lpUserID, DWORD dwFlags ) { - FIXME( "(%p, %p, %p, %s, 0x%08X), stub\n", - hwndOwner, lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags ); - - SetLastError(WN_NO_NETWORK); - return WN_NO_NETWORK; + return WNetUseConnectionW(hwndOwner, lpNetResource, lpPassword, lpUserID, + dwFlags, NULL, 0, NULL); } /***************************************************************** diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msacm32.drv/wavemap.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msacm32.drv/wavemap.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msacm32.drv/wavemap.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msacm32.drv/wavemap.c 2016-02-08 19:32:34.000000000 +0000 @@ -520,6 +520,7 @@ WAVE_FORMAT_2M08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_2M16 | WAVE_FORMAT_2S16 | WAVE_FORMAT_1M08 | WAVE_FORMAT_1S08 | WAVE_FORMAT_1M16 | WAVE_FORMAT_1S16; woc.wChannels = 2; + woc.wReserved1 = 0; woc.dwSupport = WAVECAPS_VOLUME | WAVECAPS_LRVOLUME; memcpy(lpWaveCaps, &woc, min(dwParam2, sizeof(woc))); @@ -1075,6 +1076,7 @@ WAVE_FORMAT_2M08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_2M16 | WAVE_FORMAT_2S16 | WAVE_FORMAT_1M08 | WAVE_FORMAT_1S08 | WAVE_FORMAT_1M16 | WAVE_FORMAT_1S16; wic.wChannels = 2; + wic.wReserved1 = 0; memcpy(lpWaveCaps, &wic, min(dwParam2, sizeof(wic))); return MMSYSERR_NOERROR; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mscoree/assembly.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mscoree/assembly.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mscoree/assembly.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mscoree/assembly.c 2016-02-08 19:32:34.000000000 +0000 @@ -314,3 +314,17 @@ return S_OK; } + +HRESULT assembly_get_native_entrypoint(ASSEMBLY *assembly, NativeEntryPointFunc *func) +{ + if (assembly->corhdr->Flags & COMIMAGE_FLAGS_NATIVE_ENTRYPOINT) + { + *func = assembly_rva_to_va(assembly, assembly->corhdr->EntryPointRVA); + return S_OK; + } + else + { + *func = NULL; + return S_FALSE; + } +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mscoree/corruntimehost.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mscoree/corruntimehost.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mscoree/corruntimehost.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mscoree/corruntimehost.c 2016-02-08 19:32:34.000000000 +0000 @@ -104,8 +104,11 @@ return res; } -static HRESULT RuntimeHost_GetDefaultDomain(RuntimeHost *This, MonoDomain **result) +static HRESULT RuntimeHost_GetDefaultDomain(RuntimeHost *This, const WCHAR *config_path, MonoDomain **result) { + WCHAR config_dir[MAX_PATH]; + WCHAR base_dir[MAX_PATH]; + char *base_dirA, *config_pathA, *slash; HRESULT res=S_OK; EnterCriticalSection(&This->lock); @@ -114,6 +117,48 @@ res = RuntimeHost_AddDomain(This, &This->default_domain); + if (!config_path) + { + DWORD len = sizeof(config_dir)/sizeof(*config_dir); + + static const WCHAR machine_configW[] = {'\\','C','O','N','F','I','G','\\','m','a','c','h','i','n','e','.','c','o','n','f','i','g',0}; + + res = ICLRRuntimeInfo_GetRuntimeDirectory(&This->version->ICLRRuntimeInfo_iface, + config_dir, &len); + if (FAILED(res)) + goto end; + + lstrcatW(config_dir, machine_configW); + + config_path = config_dir; + } + + config_pathA = WtoA(config_path); + if (!config_pathA) + { + res = E_OUTOFMEMORY; + goto end; + } + + GetModuleFileNameW(NULL, base_dir, sizeof(base_dir) / sizeof(*base_dir)); + base_dirA = WtoA(base_dir); + if (!base_dirA) + { + HeapFree(GetProcessHeap(), 0, config_pathA); + res = E_OUTOFMEMORY; + goto end; + } + + slash = strrchr(base_dirA, '\\'); + if (slash) + *slash = 0; + + TRACE("setting base_dir: %s, config_path: %s\n", base_dirA, config_pathA); + mono_domain_set_config(This->default_domain, base_dirA, config_pathA); + + HeapFree(GetProcessHeap(), 0, config_pathA); + HeapFree(GetProcessHeap(), 0, base_dirA); + end: *result = This->default_domain; @@ -241,7 +286,7 @@ MonoDomain *domain; MonoObject *dummy; - hr = RuntimeHost_GetDefaultDomain(This, &domain); + hr = RuntimeHost_GetDefaultDomain(This, NULL, &domain); if (FAILED(hr)) { ERR("Cannot get domain, hr=%x\n", hr); @@ -371,7 +416,7 @@ TRACE("%p\n", This); - return RuntimeHost_GetDefaultDomain(This, &dummy); + return RuntimeHost_GetDefaultDomain(This, NULL, &dummy); } static HRESULT WINAPI corruntimehost_Stop( @@ -401,7 +446,7 @@ TRACE("(%p)\n", iface); - hr = RuntimeHost_GetDefaultDomain(This, &domain); + hr = RuntimeHost_GetDefaultDomain(This, NULL, &domain); if (SUCCEEDED(hr)) { @@ -459,7 +504,7 @@ TRACE("(%p)\n", iface); - hr = RuntimeHost_GetDefaultDomain(This, &domain); + hr = RuntimeHost_GetDefaultDomain(This, NULL, &domain); if (SUCCEEDED(hr)) hr = RuntimeHost_CreateManagedInstance(This, classnameW, domain, &obj); @@ -625,7 +670,7 @@ TRACE("(%p,%s,%s,%s,%s)\n", iface, debugstr_w(pwzAssemblyPath), debugstr_w(pwzTypeName), debugstr_w(pwzMethodName), debugstr_w(pwzArgument)); - hr = RuntimeHost_GetDefaultDomain(This, &domain); + hr = RuntimeHost_GetDefaultDomain(This, NULL, &domain); if (SUCCEEDED(hr)) { @@ -717,7 +762,7 @@ MonoObject *obj; if (!domain) - hr = RuntimeHost_GetDefaultDomain(This, &domain); + hr = RuntimeHost_GetDefaultDomain(This, NULL, &domain); if (SUCCEEDED(hr)) { @@ -874,7 +919,75 @@ #include "poppack.h" -#else /* !defined(__i386__) */ +#elif __x86_64__ /* !__i386__ */ + +# define CAN_FIXUP_VTABLE 1 + +#include "pshpack1.h" + +struct vtable_fixup_thunk +{ + /* push %rbp; + mov %rsp, %rbp + sub $0x80, %rsp ; 0x8*4 + 0x10*4 + 0x20 + */ + BYTE i1[11]; + /* + mov %rcx, 0x60(%rsp); mov %rdx, 0x68(%rsp); mov %r8, 0x70(%rsp); mov %r9, 0x78(%rsp); + movaps %xmm0,0x20(%rsp); ...; movaps %xmm3,0x50(%esp) + */ + BYTE i2[40]; + /* mov function,%rax */ + BYTE i3[2]; + void (CDECL *function)(struct dll_fixup *); + /* mov fixup,%rcx */ + BYTE i4[2]; + struct dll_fixup *fixup; + /* call *%rax */ + BYTE i5[2]; + /* + mov 0x60(%rsp),%rcx; mov 0x68(%rsp),%rdx; mov 0x70(%rsp),%r8; mov 0x78(%rsp),%r9; + movaps 0x20(%rsp),xmm0; ...; movaps 0x50(%esp),xmm3 + */ + BYTE i6[40]; + /* mov %rbp, %rsp + pop %rbp + */ + BYTE i7[4]; + /* mov vtable_entry, %rax */ + BYTE i8[2]; + void *vtable_entry; + /* mov [%rax],%rax + jmp %rax */ + BYTE i9[5]; +}; + +static const struct vtable_fixup_thunk thunk_template = { + {0x55,0x48,0x89,0xE5, 0x48,0x81,0xEC,0x80,0x00,0x00,0x00}, + {0x48,0x89,0x4C,0x24,0x60, 0x48,0x89,0x54,0x24,0x68, + 0x4C,0x89,0x44,0x24,0x70, 0x4C,0x89,0x4C,0x24,0x78, + 0x0F,0x29,0x44,0x24,0x20, 0x0F,0x29,0x4C,0x24,0x30, + 0x0F,0x29,0x54,0x24,0x40, 0x0F,0x29,0x5C,0x24,0x50, + }, + {0x48,0xB8}, + NULL, + {0x48,0xB9}, + NULL, + {0xFF,0xD0}, + {0x48,0x8B,0x4C,0x24,0x60, 0x48,0x8B,0x54,0x24,0x68, + 0x4C,0x8B,0x44,0x24,0x70, 0x4C,0x8B,0x4C,0x24,0x78, + 0x0F,0x28,0x44,0x24,0x20, 0x0F,0x28,0x4C,0x24,0x30, + 0x0F,0x28,0x54,0x24,0x40, 0x0F,0x28,0x5C,0x24,0x50, + }, + {0x48,0x89,0xEC, 0x5D}, + {0x48,0xB8}, + NULL, + {0x48,0x8B,0x00,0xFF,0xE0} +}; + +#include "poppack.h" + +#else /* !__i386__ && !__x86_64__ */ # define CAN_FIXUP_VTABLE 0 @@ -921,7 +1034,7 @@ hr = ICLRRuntimeInfo_GetRuntimeHost(info, &host); if (SUCCEEDED(hr)) - hr = RuntimeHost_GetDefaultDomain(host, &domain); + hr = RuntimeHost_GetDefaultDomain(host, NULL, &domain); if (SUCCEEDED(hr)) { @@ -937,15 +1050,19 @@ /* Mono needs an image that belongs to an assembly. */ image = mono_assembly_get_image(assembly); +#if __x86_64__ + if (fixup->fixup->type & COR_VTABLE_64BIT) +#else if (fixup->fixup->type & COR_VTABLE_32BIT) +#endif { - DWORD *vtable = fixup->vtable; - DWORD *tokens = fixup->tokens; + void **vtable = fixup->vtable; + ULONG_PTR *tokens = fixup->tokens; for (i=0; ifixup->count; i++) { - TRACE("%x\n", tokens[i]); - vtable[i] = PtrToUint(mono_marshal_get_vtfixup_ftnptr( - image, tokens[i], fixup->fixup->type)); + TRACE("%#lx\n", tokens[i]); + vtable[i] = mono_marshal_get_vtfixup_ftnptr( + image, tokens[i], fixup->fixup->type); } } @@ -984,16 +1101,18 @@ fixup->vtable = (BYTE*)hmodule + vtable_fixup->rva; fixup->done = FALSE; + TRACE("vtable_fixup->type=0x%x\n",vtable_fixup->type); +#if __x86_64__ + if (vtable_fixup->type & COR_VTABLE_64BIT) +#else if (vtable_fixup->type & COR_VTABLE_32BIT) +#endif { - DWORD *vtable = fixup->vtable; - DWORD *tokens; + void **vtable = fixup->vtable; + ULONG_PTR *tokens; int i; struct vtable_fixup_thunk *thunks = fixup->thunk_code; - if (sizeof(void*) > 4) - ERR("32-bit fixup in 64-bit mode; broken image?\n"); - tokens = fixup->tokens = HeapAlloc(GetProcessHeap(), 0, sizeof(*tokens) * vtable_fixup->count); memcpy(tokens, vtable, sizeof(*tokens) * vtable_fixup->count); for (i=0; icount; i++) @@ -1002,7 +1121,7 @@ thunks[i].fixup = fixup; thunks[i].function = ReallyFixupVTable; thunks[i].vtable_entry = &vtable[i]; - vtable[i] = PtrToUint(&thunks[i]); + vtable[i] = &thunks[i]; } } else @@ -1016,23 +1135,28 @@ list_add_tail(&dll_fixups, &fixup->entry); } +static void FixupVTable_Assembly(HMODULE hmodule, ASSEMBLY *assembly) +{ + VTableFixup *vtable_fixups; + ULONG vtable_fixup_count, i; + + assembly_get_vtable_fixups(assembly, &vtable_fixups, &vtable_fixup_count); + if (CAN_FIXUP_VTABLE) + for (i=0; i + +#include "windef.h" +#include "winbase.h" + +BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) +{ + switch (reason) + { + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(instance); + break; + } + + return TRUE; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msdrm/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/msdrm/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msdrm/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msdrm/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,4 @@ +MODULE = msdrm.dll + +C_SRCS = \ + main.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msdrm/msdrm.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msdrm/msdrm.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msdrm/msdrm.spec 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msdrm/msdrm.spec 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,89 @@ +@ stub DRMAcquireAdvisories +@ stub DRMAcquireIssuanceLicenseTemplate +@ stub DRMAcquireLicense +@ stub DRMActivate +@ stub DRMAddLicense +@ stub DRMAddRightWithUser +@ stub DRMAttest +@ stub DRMCheckSecurity +@ stub DRMClearAllRights +@ stub DRMCloseEnvironmentHandle +@ stub DRMCloseHandle +@ stub DRMClosePubHandle +@ stub DRMCloseQueryHandle +@ stub DRMCloseSession +@ stub DRMConstructCertificateChain +@ stub DRMCreateBoundLicense +@ stub DRMCreateClientSession +@ stub DRMCreateEnablingBitsDecryptor +@ stub DRMCreateEnablingBitsEncryptor +@ stub DRMCreateEnablingPrincipal +@ stub DRMCreateIssuanceLicense +@ stub DRMCreateLicenseStorageSession +@ stub DRMCreateRight +@ stub DRMCreateUser +@ stub DRMDecode +@ stub DRMDeconstructCertificateChain +@ stub DRMDecrypt +@ stub DRMDeleteLicense +@ stub DRMDuplicateEnvironmentHandle +@ stub DRMDuplicateHandle +@ stub DRMDuplicatePubHandle +@ stub DRMDuplicateSession +@ stub DRMEncode +@ stub DRMEncrypt +@ stub DRMEnumerateLicense +@ stub DRMGetApplicationSpecificData +@ stub DRMGetBoundLicenseAttribute +@ stub DRMGetBoundLicenseAttributeCount +@ stub DRMGetBoundLicenseObject +@ stub DRMGetBoundLicenseObjectCount +@ stub DRMGetCertificateChainCount +@ stub DRMGetClientVersion +@ stub DRMGetEnvironmentInfo +@ stub DRMGetInfo +@ stub DRMGetIntervalTime +@ stub DRMGetIssuanceLicenseInfo +@ stub DRMGetIssuanceLicenseTemplate +@ stub DRMGetMetaData +@ stub DRMGetNameAndDescription +@ stub DRMGetOwnerLicense +@ stub DRMGetProcAddress +@ stub DRMGetRevocationPoint +@ stub DRMGetRightExtendedInfo +@ stub DRMGetRightInfo +@ stub DRMGetSecurityProvider +@ stub DRMGetServiceLocation +@ stub DRMGetSignedIssuanceLicense +@ stub DRMGetSignedIssuanceLicenseEx +@ stub DRMGetTime +@ stub DRMGetUnboundLicenseAttribute +@ stub DRMGetUnboundLicenseAttributeCount +@ stub DRMGetUnboundLicenseObject +@ stub DRMGetUnboundLicenseObjectCount +@ stub DRMGetUsagePolicy +@ stub DRMGetUserInfo +@ stub DRMGetUserRights +@ stub DRMGetUsers +@ stub DRMInitEnvironment +@ stub DRMIsActivated +@ stub DRMIsWindowProtected +@ stub DRMLoadLibrary +@ stub DRMParseUnboundLicense +@ stub DRMRegisterContent +@ stub DRMRegisterProtectedWindow +@ stub DRMRegisterRevocationList +@ stub DRMRepair +@ stub DRMSetApplicationSpecificData +@ stub DRMSetGlobalOptions +@ stub DRMSetIntervalTime +@ stub DRMSetMetaData +@ stub DRMSetNameAndDescription +@ stub DRMSetRevocationPoint +@ stub DRMSetUsagePolicy +@ stub DRMVerify +@ stub DllCanUnloadNow +@ stub DllGetClassObject +@ stub DllRegisterServer +@ stub DllUnregisterServer +@ stub __AddMachineCertToLicenseStore diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/dispex.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/dispex.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/dispex.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/dispex.c 2016-02-08 19:32:34.000000000 +0000 @@ -617,6 +617,7 @@ static HRESULT typeinfo_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei) { + DISPPARAMS params = {dp->rgvarg+dp->cNamedArgs, NULL, dp->cArgs-dp->cNamedArgs, 0}; ITypeInfo *ti; IUnknown *unk; UINT argerr=0; @@ -634,7 +635,7 @@ return E_FAIL; } - hres = ITypeInfo_Invoke(ti, unk, func->id, flags, dp, res, ei, &argerr); + hres = ITypeInfo_Invoke(ti, unk, func->id, flags, ¶ms, res, ei, &argerr); IUnknown_Release(unk); return hres; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlanchor.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlanchor.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlanchor.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlanchor.c 2016-02-08 19:32:34.000000000 +0000 @@ -801,7 +801,6 @@ static const tid_t HTMLAnchorElement_iface_tids[] = { IHTMLAnchorElement_tid, HTMLELEMENT_TIDS, - IHTMLUniqueName_tid, 0 }; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlbody.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlbody.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlbody.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlbody.c 2016-02-08 19:32:34.000000000 +0000 @@ -871,7 +871,6 @@ IHTMLBodyElement2_tid, HTMLELEMENT_TIDS, IHTMLTextContainer_tid, - IHTMLUniqueName_tid, 0 }; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlcurstyle.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlcurstyle.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlcurstyle.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlcurstyle.c 2016-02-08 19:32:34.000000000 +0000 @@ -163,8 +163,10 @@ static HRESULT WINAPI HTMLCurrentStyle_get_styleFloat(IHTMLCurrentStyle *iface, BSTR *p) { HTMLCurrentStyle *This = impl_from_IHTMLCurrentStyle(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr(This->nsstyle, STYLEID_FLOAT, p, 0); } static HRESULT WINAPI HTMLCurrentStyle_get_color(IHTMLCurrentStyle *iface, VARIANT *p) @@ -779,15 +781,15 @@ static HRESULT WINAPI HTMLCurrentStyle_get_overflowX(IHTMLCurrentStyle *iface, BSTR *p) { HTMLCurrentStyle *This = impl_from_IHTMLCurrentStyle(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + return get_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW_X, p, 0); } static HRESULT WINAPI HTMLCurrentStyle_get_overflowY(IHTMLCurrentStyle *iface, BSTR *p) { HTMLCurrentStyle *This = impl_from_IHTMLCurrentStyle(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + return get_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW_Y, p, 0); } static HRESULT WINAPI HTMLCurrentStyle_get_textTransform(IHTMLCurrentStyle *iface, BSTR *p) @@ -1279,8 +1281,8 @@ static HRESULT WINAPI HTMLCurrentStyle4_get_minWidth(IHTMLCurrentStyle4 *iface, VARIANT *p) { HTMLCurrentStyle *This = impl_from_IHTMLCurrentStyle4(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + return get_nsstyle_attr_var(This->nsstyle, STYLEID_MIN_WIDTH, p, 0); } static HRESULT WINAPI HTMLCurrentStyle4_get_maxWidth(IHTMLCurrentStyle4 *iface, VARIANT *p) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmldoc.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmldoc.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmldoc.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmldoc.c 2016-02-08 19:32:34.000000000 +0000 @@ -921,8 +921,11 @@ static HRESULT WINAPI HTMLDocument_get_defaultCharset(IHTMLDocument2 *iface, BSTR *p) { HTMLDocument *This = impl_from_IHTMLDocument2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + *p = charset_string_from_cp(GetACP()); + return *p ? S_OK : E_OUTOFMEMORY; } static HRESULT WINAPI HTMLDocument_get_mimeType(IHTMLDocument2 *iface, BSTR *p) @@ -2018,11 +2021,13 @@ return hres; } -static HRESULT WINAPI HTMLDocument3_uniqueID(IHTMLDocument3 *iface, BSTR *p) +static HRESULT WINAPI HTMLDocument3_get_uniqueID(IHTMLDocument3 *iface, BSTR *p) { HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return elem_unique_id(++This->doc_node->unique_id, p); } static HRESULT WINAPI HTMLDocument3_attachEvent(IHTMLDocument3 *iface, BSTR event, @@ -2428,7 +2433,7 @@ HTMLDocument3_recalc, HTMLDocument3_createTextNode, HTMLDocument3_get_documentElement, - HTMLDocument3_uniqueID, + HTMLDocument3_get_uniqueID, HTMLDocument3_attachEvent, HTMLDocument3_detachEvent, HTMLDocument3_put_onrowsdelete, @@ -2549,8 +2554,21 @@ static HRESULT WINAPI HTMLDocument4_hasFocus(IHTMLDocument4 *iface, VARIANT_BOOL *pfFocus) { HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%p)\n", This, pfFocus); - return E_NOTIMPL; + cpp_bool has_focus; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, pfFocus); + + if(!This->doc_node->nsdoc) { + FIXME("Unimplemented for fragments.\n"); + return E_NOTIMPL; + } + + nsres = nsIDOMHTMLDocument_HasFocus(This->doc_node->nsdoc, &has_focus); + assert(nsres == NS_OK); + + *pfFocus = has_focus ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } static HRESULT WINAPI HTMLDocument4_put_onselectionchange(IHTMLDocument4 *iface, VARIANT v) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlelem.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlelem.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlelem.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlelem.c 2016-02-08 19:32:34.000000000 +0000 @@ -644,6 +644,8 @@ EXCEPINFO excep; HRESULT hres; + static const WCHAR nullW[] = {'n','u','l','l',0}; + hres = IDispatchEx_InvokeEx(&elem->node.event_target.dispex.IDispatchEx_iface, dispid, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, ret, &excep, NULL); if(FAILED(hres)) @@ -653,6 +655,12 @@ switch(V_VT(ret)) { case VT_BSTR: break; + case VT_NULL: + V_BSTR(ret) = SysAllocString(nullW); + if(!V_BSTR(ret)) + return E_OUTOFMEMORY; + V_VT(ret) = VT_BSTR; + break; case VT_DISPATCH: IDispatch_Release(V_DISPATCH(ret)); V_VT(ret) = VT_BSTR; @@ -1265,15 +1273,43 @@ static HRESULT WINAPI HTMLElement_put_lang(IHTMLElement *iface, BSTR v) { HTMLElement *This = impl_from_IHTMLElement(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString nsstr; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + if(!This->nselem) { + FIXME("NULL nselem\n"); + return E_NOTIMPL; + } + + nsAString_InitDepend(&nsstr, v); + nsres = nsIDOMHTMLElement_SetLang(This->nselem, &nsstr); + nsAString_Finish(&nsstr); + if(NS_FAILED(nsres)) { + ERR("SetLang failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLElement_get_lang(IHTMLElement *iface, BSTR *p) { HTMLElement *This = impl_from_IHTMLElement(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString nsstr; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + if(!This->nselem) { + FIXME("NULL nselem\n"); + return E_NOTIMPL; + } + + nsAString_Init(&nsstr, NULL); + nsres = nsIDOMHTMLElement_GetLang(This->nselem, &nsstr); + return return_nsstr(nsres, &nsstr, p); } static HRESULT WINAPI HTMLElement_get_offsetLeft(IHTMLElement *iface, LONG *p) @@ -3755,6 +3791,108 @@ HTMLElement4_get_onfocusout }; +static inline HTMLElement *impl_from_IHTMLUniqueName(IHTMLUniqueName *iface) +{ + return CONTAINING_RECORD(iface, HTMLElement, IHTMLUniqueName_iface); +} + +static HRESULT WINAPI HTMLUniqueName_QueryInterface(IHTMLUniqueName *iface, REFIID riid, void **ppv) +{ + HTMLElement *This = impl_from_IHTMLUniqueName(iface); + return IHTMLElement_QueryInterface(&This->IHTMLElement_iface, riid, ppv); +} + +static ULONG WINAPI HTMLUniqueName_AddRef(IHTMLUniqueName *iface) +{ + HTMLElement *This = impl_from_IHTMLUniqueName(iface); + return IHTMLElement_AddRef(&This->IHTMLElement_iface); +} + +static ULONG WINAPI HTMLUniqueName_Release(IHTMLUniqueName *iface) +{ + HTMLElement *This = impl_from_IHTMLUniqueName(iface); + return IHTMLElement_Release(&This->IHTMLElement_iface); +} + +static HRESULT WINAPI HTMLUniqueName_GetTypeInfoCount(IHTMLUniqueName *iface, UINT *pctinfo) +{ + HTMLElement *This = impl_from_IHTMLUniqueName(iface); + return IDispatchEx_GetTypeInfoCount(&This->node.event_target.dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI HTMLUniqueName_GetTypeInfo(IHTMLUniqueName *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLElement *This = impl_from_IHTMLUniqueName(iface); + return IDispatchEx_GetTypeInfo(&This->node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLUniqueName_GetIDsOfNames(IHTMLUniqueName *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + HTMLElement *This = impl_from_IHTMLUniqueName(iface); + return IDispatchEx_GetIDsOfNames(&This->node.event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames, + lcid, rgDispId); +} + +static HRESULT WINAPI HTMLUniqueName_Invoke(IHTMLUniqueName *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLElement *This = impl_from_IHTMLUniqueName(iface); + return IDispatchEx_Invoke(&This->node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +HRESULT elem_unique_id(unsigned id, BSTR *p) +{ + WCHAR buf[32]; + + static const WCHAR formatW[] = {'m','s','_','_','i','d','%','u',0}; + + sprintfW(buf, formatW, id); + *p = SysAllocString(buf); + return *p ? S_OK : E_OUTOFMEMORY; +} + +static void ensure_unique_id(HTMLElement *elem) +{ + if(!elem->unique_id) + elem->unique_id = ++elem->node.doc->unique_id; +} + +static HRESULT WINAPI HTMLUniqueName_get_uniqueNumber(IHTMLUniqueName *iface, LONG *p) +{ + HTMLElement *This = impl_from_IHTMLUniqueName(iface); + + TRACE("(%p)->(%p)\n", This, p); + + ensure_unique_id(This); + *p = This->unique_id; + return S_OK; +} + +static HRESULT WINAPI HTMLUniqueName_get_uniqueID(IHTMLUniqueName *iface, BSTR *p) +{ + HTMLElement *This = impl_from_IHTMLUniqueName(iface); + + TRACE("(%p)->(%p)\n", This, p); + + ensure_unique_id(This); + return elem_unique_id(This->unique_id, p); +} + +static const IHTMLUniqueNameVtbl HTMLUniqueNameVtbl = { + HTMLUniqueName_QueryInterface, + HTMLUniqueName_AddRef, + HTMLUniqueName_Release, + HTMLUniqueName_GetTypeInfoCount, + HTMLUniqueName_GetTypeInfo, + HTMLUniqueName_GetIDsOfNames, + HTMLUniqueName_Invoke, + HTMLUniqueName_get_uniqueNumber, + HTMLUniqueName_get_uniqueID +}; + static inline HTMLElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface) { return CONTAINING_RECORD(iface, HTMLElement, node); @@ -3776,6 +3914,8 @@ *ppv = &This->IHTMLElement3_iface; }else if(IsEqualGUID(&IID_IHTMLElement4, riid)) { *ppv = &This->IHTMLElement4_iface; + }else if(IsEqualGUID(&IID_IHTMLUniqueName, riid)) { + *ppv = &This->IHTMLUniqueName_iface; }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) { *ppv = &This->cp_container.IConnectionPointContainer_iface; }else { @@ -4036,6 +4176,7 @@ This->IHTMLElement2_iface.lpVtbl = &HTMLElement2Vtbl; This->IHTMLElement3_iface.lpVtbl = &HTMLElement3Vtbl; This->IHTMLElement4_iface.lpVtbl = &HTMLElement4Vtbl; + This->IHTMLUniqueName_iface.lpVtbl = &HTMLUniqueNameVtbl; if(dispex_data && !dispex_data->vtbl) dispex_data->vtbl = &HTMLElement_dispex_vtbl; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlevent.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlevent.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlevent.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlevent.c 2016-02-08 19:32:34.000000000 +0000 @@ -1468,8 +1468,10 @@ HRESULT hres; hres = dispex_get_dprop_ref(&event_target->dispex, event_info[eid].attr_name, FALSE, &v); - if(SUCCEEDED(hres) && V_VT(v) != VT_EMPTY) + if(SUCCEEDED(hres) && V_VT(v) != VT_EMPTY) { + V_VT(var) = VT_EMPTY; return VariantCopy(var, v); + } data = get_event_target_data(event_target, FALSE); if(data && data->event_table[eid] && data->event_table[eid]->handler_prop) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlstyle2.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlstyle2.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlstyle2.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlstyle2.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,637 +0,0 @@ -/* - * Copyright 2008 Jacek Caban for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "ole2.h" - -#include "mshtml_private.h" -#include "htmlstyle.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(mshtml); - -static inline HTMLStyle *impl_from_IHTMLStyle2(IHTMLStyle2 *iface) -{ - return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle2_iface); -} - -static HRESULT WINAPI HTMLStyle2_QueryInterface(IHTMLStyle2 *iface, REFIID riid, void **ppv) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - return IHTMLStyle_QueryInterface(&This->IHTMLStyle_iface, riid, ppv); -} - -static ULONG WINAPI HTMLStyle2_AddRef(IHTMLStyle2 *iface) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - return IHTMLStyle_AddRef(&This->IHTMLStyle_iface); -} - -static ULONG WINAPI HTMLStyle2_Release(IHTMLStyle2 *iface) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - return IHTMLStyle_Release(&This->IHTMLStyle_iface); -} - -static HRESULT WINAPI HTMLStyle2_GetTypeInfoCount(IHTMLStyle2 *iface, UINT *pctinfo) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); -} - -static HRESULT WINAPI HTMLStyle2_GetTypeInfo(IHTMLStyle2 *iface, UINT iTInfo, - LCID lcid, ITypeInfo **ppTInfo) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); -} - -static HRESULT WINAPI HTMLStyle2_GetIDsOfNames(IHTMLStyle2 *iface, REFIID riid, - LPOLESTR *rgszNames, UINT cNames, - LCID lcid, DISPID *rgDispId) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, - lcid, rgDispId); -} - -static HRESULT WINAPI HTMLStyle2_Invoke(IHTMLStyle2 *iface, DISPID dispIdMember, - REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, - VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, - wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); -} - -static HRESULT WINAPI HTMLStyle2_put_tableLayout(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_w(v)); - - return set_nsstyle_attr(This->nsstyle, STYLEID_TABLE_LAYOUT, v, 0); -} - -static HRESULT WINAPI HTMLStyle2_get_tableLayout(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr(This->nsstyle, STYLEID_TABLE_LAYOUT, p, 0); -} - -static HRESULT WINAPI HTMLStyle2_put_borderCollapse(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_borderCollapse(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_direction(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_w(v)); - - return set_nsstyle_attr(This->nsstyle, STYLEID_DIRECTION, v, 0); -} - -static HRESULT WINAPI HTMLStyle2_get_direction(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr(This->nsstyle, STYLEID_DIRECTION, p, 0); -} - -static HRESULT WINAPI HTMLStyle2_put_behavior(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_behavior(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_setExpression(IHTMLStyle2 *iface, BSTR propname, BSTR expression, BSTR language) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s %s %s)\n", This, debugstr_w(propname), debugstr_w(expression), debugstr_w(language)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_getExpression(IHTMLStyle2 *iface, BSTR propname, VARIANT *expression) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s %p)\n", This, debugstr_w(propname), expression); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_removeExpression(IHTMLStyle2 *iface, BSTR propname, VARIANT_BOOL *pfSuccess) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s %p)\n", This, debugstr_w(propname), pfSuccess); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_position(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_w(v)); - - return set_nsstyle_attr(This->nsstyle, STYLEID_POSITION, v, 0); -} - -static HRESULT WINAPI HTMLStyle2_get_position(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr(This->nsstyle, STYLEID_POSITION, p, 0); -} - -static HRESULT WINAPI HTMLStyle2_put_unicodeBidi(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_unicodeBidi(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_bottom(IHTMLStyle2 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); - - return set_nsstyle_attr_var(This->nsstyle, STYLEID_BOTTOM, &v, ATTR_FIX_PX); -} - -static HRESULT WINAPI HTMLStyle2_get_bottom(IHTMLStyle2 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr_var(This->nsstyle, STYLEID_BOTTOM, p, 0); -} - -static HRESULT WINAPI HTMLStyle2_put_right(IHTMLStyle2 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); - - return set_nsstyle_attr_var(This->nsstyle, STYLEID_RIGHT, &v, 0); -} - -static HRESULT WINAPI HTMLStyle2_get_right(IHTMLStyle2 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr_var(This->nsstyle, STYLEID_RIGHT, p, 0); -} - -static HRESULT WINAPI HTMLStyle2_put_pixelBottom(IHTMLStyle2 *iface, LONG v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%d)\n", This, v); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_pixelBottom(IHTMLStyle2 *iface, LONG *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_pixelRight(IHTMLStyle2 *iface, LONG v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%d)\n", This, v); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_pixelRight(IHTMLStyle2 *iface, LONG *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_posBottom(IHTMLStyle2 *iface, float v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%f)\n", This, v); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_posBottom(IHTMLStyle2 *iface, float *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_posRight(IHTMLStyle2 *iface, float v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%f)\n", This, v); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_posRight(IHTMLStyle2 *iface, float *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_imeMode(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_imeMode(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_rubyAlign(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_rubyAlign(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_rubyPosition(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_rubyPosition(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_rubyOverhang(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_rubyOverhang(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_layoutGridChar(IHTMLStyle2 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_layoutGridChar(IHTMLStyle2 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_layoutGridLine(IHTMLStyle2 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_layoutGridLine(IHTMLStyle2 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_layoutGridMode(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_layoutGridMode(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_layoutGridType(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_layoutGridType(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_layoutGrid(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_layoutGrid(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_wordBreak(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_wordBreak(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_lineBreak(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_lineBreak(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_textJustify(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_textJustify(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_textJustifyTrim(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_textJustifyTrim(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_textKashida(IHTMLStyle2 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_textKashida(IHTMLStyle2 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_textAutospace(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_textAutospace(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_put_overflowX(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_w(v)); - - return set_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW_X, v, 0); -} - -static HRESULT WINAPI HTMLStyle2_get_overflowX(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW_X, p, 0); -} - -static HRESULT WINAPI HTMLStyle2_put_overflowY(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_w(v)); - - return set_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW_Y, v, 0); -} - -static HRESULT WINAPI HTMLStyle2_get_overflowY(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW_Y, p, 0); -} - -static HRESULT WINAPI HTMLStyle2_put_accelerator(IHTMLStyle2 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle2_get_accelerator(IHTMLStyle2 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static const IHTMLStyle2Vtbl HTMLStyle2Vtbl = { - HTMLStyle2_QueryInterface, - HTMLStyle2_AddRef, - HTMLStyle2_Release, - HTMLStyle2_GetTypeInfoCount, - HTMLStyle2_GetTypeInfo, - HTMLStyle2_GetIDsOfNames, - HTMLStyle2_Invoke, - HTMLStyle2_put_tableLayout, - HTMLStyle2_get_tableLayout, - HTMLStyle2_put_borderCollapse, - HTMLStyle2_get_borderCollapse, - HTMLStyle2_put_direction, - HTMLStyle2_get_direction, - HTMLStyle2_put_behavior, - HTMLStyle2_get_behavior, - HTMLStyle2_setExpression, - HTMLStyle2_getExpression, - HTMLStyle2_removeExpression, - HTMLStyle2_put_position, - HTMLStyle2_get_position, - HTMLStyle2_put_unicodeBidi, - HTMLStyle2_get_unicodeBidi, - HTMLStyle2_put_bottom, - HTMLStyle2_get_bottom, - HTMLStyle2_put_right, - HTMLStyle2_get_right, - HTMLStyle2_put_pixelBottom, - HTMLStyle2_get_pixelBottom, - HTMLStyle2_put_pixelRight, - HTMLStyle2_get_pixelRight, - HTMLStyle2_put_posBottom, - HTMLStyle2_get_posBottom, - HTMLStyle2_put_posRight, - HTMLStyle2_get_posRight, - HTMLStyle2_put_imeMode, - HTMLStyle2_get_imeMode, - HTMLStyle2_put_rubyAlign, - HTMLStyle2_get_rubyAlign, - HTMLStyle2_put_rubyPosition, - HTMLStyle2_get_rubyPosition, - HTMLStyle2_put_rubyOverhang, - HTMLStyle2_get_rubyOverhang, - HTMLStyle2_put_layoutGridChar, - HTMLStyle2_get_layoutGridChar, - HTMLStyle2_put_layoutGridLine, - HTMLStyle2_get_layoutGridLine, - HTMLStyle2_put_layoutGridMode, - HTMLStyle2_get_layoutGridMode, - HTMLStyle2_put_layoutGridType, - HTMLStyle2_get_layoutGridType, - HTMLStyle2_put_layoutGrid, - HTMLStyle2_get_layoutGrid, - HTMLStyle2_put_wordBreak, - HTMLStyle2_get_wordBreak, - HTMLStyle2_put_lineBreak, - HTMLStyle2_get_lineBreak, - HTMLStyle2_put_textJustify, - HTMLStyle2_get_textJustify, - HTMLStyle2_put_textJustifyTrim, - HTMLStyle2_get_textJustifyTrim, - HTMLStyle2_put_textKashida, - HTMLStyle2_get_textKashida, - HTMLStyle2_put_textAutospace, - HTMLStyle2_get_textAutospace, - HTMLStyle2_put_overflowX, - HTMLStyle2_get_overflowX, - HTMLStyle2_put_overflowY, - HTMLStyle2_get_overflowY, - HTMLStyle2_put_accelerator, - HTMLStyle2_get_accelerator -}; - -void HTMLStyle2_Init(HTMLStyle *This) -{ - This->IHTMLStyle2_iface.lpVtbl = &HTMLStyle2Vtbl; -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlstyle3.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlstyle3.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlstyle3.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlstyle3.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,958 +0,0 @@ -/* - * Copyright 2009 Alistair Leslie-Hughes - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "ole2.h" - -#include "mshtml_private.h" -#include "htmlstyle.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(mshtml); - -static inline HTMLStyle *impl_from_IHTMLStyle3(IHTMLStyle3 *iface) -{ - return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle3_iface); -} - -static HRESULT WINAPI HTMLStyle3_QueryInterface(IHTMLStyle3 *iface, REFIID riid, void **ppv) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - - return IHTMLStyle_QueryInterface(&This->IHTMLStyle_iface, riid, ppv); -} - -static ULONG WINAPI HTMLStyle3_AddRef(IHTMLStyle3 *iface) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - - return IHTMLStyle_AddRef(&This->IHTMLStyle_iface); -} - -static ULONG WINAPI HTMLStyle3_Release(IHTMLStyle3 *iface) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - - return IHTMLStyle_Release(&This->IHTMLStyle_iface); -} - -static HRESULT WINAPI HTMLStyle3_GetTypeInfoCount(IHTMLStyle3 *iface, UINT *pctinfo) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); -} - -static HRESULT WINAPI HTMLStyle3_GetTypeInfo(IHTMLStyle3 *iface, UINT iTInfo, - LCID lcid, ITypeInfo **ppTInfo) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); -} - -static HRESULT WINAPI HTMLStyle3_GetIDsOfNames(IHTMLStyle3 *iface, REFIID riid, - LPOLESTR *rgszNames, UINT cNames, - LCID lcid, DISPID *rgDispId) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, - lcid, rgDispId); -} - -static HRESULT WINAPI HTMLStyle3_Invoke(IHTMLStyle3 *iface, DISPID dispIdMember, - REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, - VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, - wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); -} - -static HRESULT WINAPI HTMLStyle3_put_layoutFlow(IHTMLStyle3 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_layoutFlow(IHTMLStyle3 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static const WCHAR zoomW[] = {'z','o','o','m',0}; - -static HRESULT WINAPI HTMLStyle3_put_zoom(IHTMLStyle3 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - VARIANT *var; - HRESULT hres; - - TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); - - /* zoom property is IE CSS extension that is mostly used as a hack to workaround IE bugs. - * The value is set to 1 then. We can safely ignore setting zoom to 1. */ - if(V_VT(&v) != VT_I4 || V_I4(&v) != 1) - WARN("stub for %s\n", debugstr_variant(&v)); - - hres = dispex_get_dprop_ref(&This->dispex, zoomW, TRUE, &var); - if(FAILED(hres)) - return hres; - - return VariantChangeType(var, &v, 0, VT_BSTR); -} - -static HRESULT WINAPI HTMLStyle3_get_zoom(IHTMLStyle3 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - VARIANT *var; - HRESULT hres; - - TRACE("(%p)->(%p)\n", This, p); - - hres = dispex_get_dprop_ref(&This->dispex, zoomW, FALSE, &var); - if(hres == DISP_E_UNKNOWNNAME) { - V_VT(p) = VT_BSTR; - V_BSTR(p) = NULL; - return S_OK; - } - if(FAILED(hres)) - return hres; - - return VariantCopy(p, var); -} - -static HRESULT WINAPI HTMLStyle3_put_wordWrap(IHTMLStyle3 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_w(v)); - - return set_nsstyle_attr(This->nsstyle, STYLEID_WORD_WRAP, v, 0); -} - -static HRESULT WINAPI HTMLStyle3_get_wordWrap(IHTMLStyle3 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr(This->nsstyle, STYLEID_WORD_WRAP, p, 0); -} - -static HRESULT WINAPI HTMLStyle3_put_textUnderlinePosition(IHTMLStyle3 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_textUnderlinePosition(IHTMLStyle3 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_put_scrollbarBaseColor(IHTMLStyle3 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_scrollbarBaseColor(IHTMLStyle3 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_put_scrollbarFaceColor(IHTMLStyle3 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_scrollbarFaceColor(IHTMLStyle3 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_put_scrollbar3dLightColor(IHTMLStyle3 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_scrollbar3dLightColor(IHTMLStyle3 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_put_scrollbarShadowColor(IHTMLStyle3 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_scrollbarShadowColor(IHTMLStyle3 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_put_scrollbarHighlightColor(IHTMLStyle3 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_scrollbarHighlightColor(IHTMLStyle3 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_put_scrollbarDarkShadowColor(IHTMLStyle3 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_scrollbarDarkShadowColor(IHTMLStyle3 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_put_scrollbarArrowColor(IHTMLStyle3 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_scrollbarArrowColor(IHTMLStyle3 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_put_scrollbarTrackColor(IHTMLStyle3 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_scrollbarTrackColor(IHTMLStyle3 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_put_writingMode(IHTMLStyle3 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_writingMode(IHTMLStyle3 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_put_textAlignLast(IHTMLStyle3 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_textAlignLast(IHTMLStyle3 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_put_textKashidaSpace(IHTMLStyle3 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle3_get_textKashidaSpace(IHTMLStyle3 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static const IHTMLStyle3Vtbl HTMLStyle3Vtbl = { - HTMLStyle3_QueryInterface, - HTMLStyle3_AddRef, - HTMLStyle3_Release, - HTMLStyle3_GetTypeInfoCount, - HTMLStyle3_GetTypeInfo, - HTMLStyle3_GetIDsOfNames, - HTMLStyle3_Invoke, - HTMLStyle3_put_layoutFlow, - HTMLStyle3_get_layoutFlow, - HTMLStyle3_put_zoom, - HTMLStyle3_get_zoom, - HTMLStyle3_put_wordWrap, - HTMLStyle3_get_wordWrap, - HTMLStyle3_put_textUnderlinePosition, - HTMLStyle3_get_textUnderlinePosition, - HTMLStyle3_put_scrollbarBaseColor, - HTMLStyle3_get_scrollbarBaseColor, - HTMLStyle3_put_scrollbarFaceColor, - HTMLStyle3_get_scrollbarFaceColor, - HTMLStyle3_put_scrollbar3dLightColor, - HTMLStyle3_get_scrollbar3dLightColor, - HTMLStyle3_put_scrollbarShadowColor, - HTMLStyle3_get_scrollbarShadowColor, - HTMLStyle3_put_scrollbarHighlightColor, - HTMLStyle3_get_scrollbarHighlightColor, - HTMLStyle3_put_scrollbarDarkShadowColor, - HTMLStyle3_get_scrollbarDarkShadowColor, - HTMLStyle3_put_scrollbarArrowColor, - HTMLStyle3_get_scrollbarArrowColor, - HTMLStyle3_put_scrollbarTrackColor, - HTMLStyle3_get_scrollbarTrackColor, - HTMLStyle3_put_writingMode, - HTMLStyle3_get_writingMode, - HTMLStyle3_put_textAlignLast, - HTMLStyle3_get_textAlignLast, - HTMLStyle3_put_textKashidaSpace, - HTMLStyle3_get_textKashidaSpace -}; - -/* - * IHTMLStyle4 Interface - */ -static inline HTMLStyle *impl_from_IHTMLStyle4(IHTMLStyle4 *iface) -{ - return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle4_iface); -} - -static HRESULT WINAPI HTMLStyle4_QueryInterface(IHTMLStyle4 *iface, REFIID riid, void **ppv) -{ - HTMLStyle *This = impl_from_IHTMLStyle4(iface); - - return IHTMLStyle_QueryInterface(&This->IHTMLStyle_iface, riid, ppv); -} - -static ULONG WINAPI HTMLStyle4_AddRef(IHTMLStyle4 *iface) -{ - HTMLStyle *This = impl_from_IHTMLStyle4(iface); - - return IHTMLStyle_AddRef(&This->IHTMLStyle_iface); -} - -static ULONG WINAPI HTMLStyle4_Release(IHTMLStyle4 *iface) -{ - HTMLStyle *This = impl_from_IHTMLStyle4(iface); - - return IHTMLStyle_Release(&This->IHTMLStyle_iface); -} - -static HRESULT WINAPI HTMLStyle4_GetTypeInfoCount(IHTMLStyle4 *iface, UINT *pctinfo) -{ - HTMLStyle *This = impl_from_IHTMLStyle4(iface); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); -} - -static HRESULT WINAPI HTMLStyle4_GetTypeInfo(IHTMLStyle4 *iface, UINT iTInfo, - LCID lcid, ITypeInfo **ppTInfo) -{ - HTMLStyle *This = impl_from_IHTMLStyle4(iface); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); -} - -static HRESULT WINAPI HTMLStyle4_GetIDsOfNames(IHTMLStyle4 *iface, REFIID riid, - LPOLESTR *rgszNames, UINT cNames, - LCID lcid, DISPID *rgDispId) -{ - HTMLStyle *This = impl_from_IHTMLStyle4(iface); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, - lcid, rgDispId); -} - -static HRESULT WINAPI HTMLStyle4_Invoke(IHTMLStyle4 *iface, DISPID dispIdMember, - REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, - VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) -{ - HTMLStyle *This = impl_from_IHTMLStyle4(iface); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, - wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); -} - -static HRESULT WINAPI HTMLStyle4_put_textOverflow(IHTMLStyle4 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle4(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle4_get_textOverflow(IHTMLStyle4 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle4(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle4_put_minHeight(IHTMLStyle4 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle4(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); - - return set_nsstyle_attr_var(This->nsstyle, STYLEID_MIN_HEIGHT, &v, 0); -} - -static HRESULT WINAPI HTMLStyle4_get_minHeight(IHTMLStyle4 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle4(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr_var(This->nsstyle, STYLEID_MIN_HEIGHT, p, 0); -} - -static const IHTMLStyle4Vtbl HTMLStyle4Vtbl = { - HTMLStyle4_QueryInterface, - HTMLStyle4_AddRef, - HTMLStyle4_Release, - HTMLStyle4_GetTypeInfoCount, - HTMLStyle4_GetTypeInfo, - HTMLStyle4_GetIDsOfNames, - HTMLStyle4_Invoke, - HTMLStyle4_put_textOverflow, - HTMLStyle4_get_textOverflow, - HTMLStyle4_put_minHeight, - HTMLStyle4_get_minHeight -}; - -static inline HTMLStyle *impl_from_IHTMLStyle5(IHTMLStyle5 *iface) -{ - return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle5_iface); -} - -static HRESULT WINAPI HTMLStyle5_QueryInterface(IHTMLStyle5 *iface, REFIID riid, void **ppv) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - - return IHTMLStyle_QueryInterface(&This->IHTMLStyle_iface, riid, ppv); -} - -static ULONG WINAPI HTMLStyle5_AddRef(IHTMLStyle5 *iface) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - - return IHTMLStyle_AddRef(&This->IHTMLStyle_iface); -} - -static ULONG WINAPI HTMLStyle5_Release(IHTMLStyle5 *iface) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - - return IHTMLStyle_Release(&This->IHTMLStyle_iface); -} - -static HRESULT WINAPI HTMLStyle5_GetTypeInfoCount(IHTMLStyle5 *iface, UINT *pctinfo) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); -} - -static HRESULT WINAPI HTMLStyle5_GetTypeInfo(IHTMLStyle5 *iface, UINT iTInfo, - LCID lcid, ITypeInfo **ppTInfo) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); -} - -static HRESULT WINAPI HTMLStyle5_GetIDsOfNames(IHTMLStyle5 *iface, REFIID riid, - LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, - lcid, rgDispId); -} - -static HRESULT WINAPI HTMLStyle5_Invoke(IHTMLStyle5 *iface, DISPID dispIdMember, - REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, - VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, - wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); -} - -static HRESULT WINAPI HTMLStyle5_put_msInterpolationMode(IHTMLStyle5 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle5_get_msInterpolationMode(IHTMLStyle5 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle5_put_maxHeight(IHTMLStyle5 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); - - return set_nsstyle_attr_var(This->nsstyle, STYLEID_MAX_HEIGHT, &v, ATTR_FIX_PX); -} - -static HRESULT WINAPI HTMLStyle5_get_maxHeight(IHTMLStyle5 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_variant(p)); - - return get_nsstyle_attr_var(This->nsstyle, STYLEID_MAX_HEIGHT, p, 0); -} - -static HRESULT WINAPI HTMLStyle5_put_minWidth(IHTMLStyle5 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); - - return set_nsstyle_attr_var(This->nsstyle, STYLEID_MIN_WIDTH, &v, ATTR_FIX_PX); -} - -static HRESULT WINAPI HTMLStyle5_get_minWidth(IHTMLStyle5 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr_var(This->nsstyle, STYLEID_MIN_WIDTH, p, 0); -} - -static HRESULT WINAPI HTMLStyle5_put_maxWidth(IHTMLStyle5 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); - - return set_nsstyle_attr_var(This->nsstyle, STYLEID_MAX_WIDTH, &v, ATTR_FIX_PX); -} - -static HRESULT WINAPI HTMLStyle5_get_maxWidth(IHTMLStyle5 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle5(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr_var(This->nsstyle, STYLEID_MAX_WIDTH, p, 0); -} - -static const IHTMLStyle5Vtbl HTMLStyle5Vtbl = { - HTMLStyle5_QueryInterface, - HTMLStyle5_AddRef, - HTMLStyle5_Release, - HTMLStyle5_GetTypeInfoCount, - HTMLStyle5_GetTypeInfo, - HTMLStyle5_GetIDsOfNames, - HTMLStyle5_Invoke, - HTMLStyle5_put_msInterpolationMode, - HTMLStyle5_get_msInterpolationMode, - HTMLStyle5_put_maxHeight, - HTMLStyle5_get_maxHeight, - HTMLStyle5_put_minWidth, - HTMLStyle5_get_minWidth, - HTMLStyle5_put_maxWidth, - HTMLStyle5_get_maxWidth -}; - -static inline HTMLStyle *impl_from_IHTMLStyle6(IHTMLStyle6 *iface) -{ - return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle6_iface); -} - -static HRESULT WINAPI HTMLStyle6_QueryInterface(IHTMLStyle6 *iface, REFIID riid, void **ppv) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - - return IHTMLStyle_QueryInterface(&This->IHTMLStyle_iface, riid, ppv); -} - -static ULONG WINAPI HTMLStyle6_AddRef(IHTMLStyle6 *iface) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - - return IHTMLStyle_AddRef(&This->IHTMLStyle_iface); -} - -static ULONG WINAPI HTMLStyle6_Release(IHTMLStyle6 *iface) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - - return IHTMLStyle_Release(&This->IHTMLStyle_iface); -} - -static HRESULT WINAPI HTMLStyle6_GetTypeInfoCount(IHTMLStyle6 *iface, UINT *pctinfo) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); -} - -static HRESULT WINAPI HTMLStyle6_GetTypeInfo(IHTMLStyle6 *iface, UINT iTInfo, - LCID lcid, ITypeInfo **ppTInfo) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); -} - -static HRESULT WINAPI HTMLStyle6_GetIDsOfNames(IHTMLStyle6 *iface, REFIID riid, - LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, - lcid, rgDispId); -} - -static HRESULT WINAPI HTMLStyle6_Invoke(IHTMLStyle6 *iface, DISPID dispIdMember, - REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, - VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, - wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); -} - -static HRESULT WINAPI HTMLStyle6_put_content(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_content(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_contentSide(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_contentSide(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_counterIncrement(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_counterIncrement(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_counterReset(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_counterReset(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_outline(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_w(v)); - - return set_nsstyle_attr(This->nsstyle, STYLEID_OUTLINE, v, 0); -} - -static HRESULT WINAPI HTMLStyle6_get_outline(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr(This->nsstyle, STYLEID_OUTLINE, p, ATTR_NO_NULL); -} - -static HRESULT WINAPI HTMLStyle6_put_outlineWidth(IHTMLStyle6 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_outlineWidth(IHTMLStyle6 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_outlineStyle(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_outlineStyle(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_outlineColor(IHTMLStyle6 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_outlineColor(IHTMLStyle6 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_boxSizing(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - - TRACE("(%p)->(%s)\n", This, debugstr_w(v)); - - return set_nsstyle_attr(This->nsstyle, STYLEID_BOX_SIZING, v, 0); -} - -static HRESULT WINAPI HTMLStyle6_get_boxSizing(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_nsstyle_attr(This->nsstyle, STYLEID_BOX_SIZING, p, 0); -} - -static HRESULT WINAPI HTMLStyle6_put_boxSpacing(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_boxSpacing(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_orphans(IHTMLStyle6 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_orphans(IHTMLStyle6 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_windows(IHTMLStyle6 *iface, VARIANT v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_windows(IHTMLStyle6 *iface, VARIANT *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_pageBreakInside(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_pageBreakInside(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_emptyCells(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_emptyCells(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_msBlockProgression(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_msBlockProgression(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_put_quotes(IHTMLStyle6 *iface, BSTR v) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLStyle6_get_quotes(IHTMLStyle6 *iface, BSTR *p) -{ - HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static const IHTMLStyle6Vtbl HTMLStyle6Vtbl = { - HTMLStyle6_QueryInterface, - HTMLStyle6_AddRef, - HTMLStyle6_Release, - HTMLStyle6_GetTypeInfoCount, - HTMLStyle6_GetTypeInfo, - HTMLStyle6_GetIDsOfNames, - HTMLStyle6_Invoke, - HTMLStyle6_put_content, - HTMLStyle6_get_content, - HTMLStyle6_put_contentSide, - HTMLStyle6_get_contentSide, - HTMLStyle6_put_counterIncrement, - HTMLStyle6_get_counterIncrement, - HTMLStyle6_put_counterReset, - HTMLStyle6_get_counterReset, - HTMLStyle6_put_outline, - HTMLStyle6_get_outline, - HTMLStyle6_put_outlineWidth, - HTMLStyle6_get_outlineWidth, - HTMLStyle6_put_outlineStyle, - HTMLStyle6_get_outlineStyle, - HTMLStyle6_put_outlineColor, - HTMLStyle6_get_outlineColor, - HTMLStyle6_put_boxSizing, - HTMLStyle6_get_boxSizing, - HTMLStyle6_put_boxSpacing, - HTMLStyle6_get_boxSpacing, - HTMLStyle6_put_orphans, - HTMLStyle6_get_orphans, - HTMLStyle6_put_windows, - HTMLStyle6_get_windows, - HTMLStyle6_put_pageBreakInside, - HTMLStyle6_get_pageBreakInside, - HTMLStyle6_put_emptyCells, - HTMLStyle6_get_emptyCells, - HTMLStyle6_put_msBlockProgression, - HTMLStyle6_get_msBlockProgression, - HTMLStyle6_put_quotes, - HTMLStyle6_get_quotes -}; - -void HTMLStyle3_Init(HTMLStyle *This) -{ - This->IHTMLStyle3_iface.lpVtbl = &HTMLStyle3Vtbl; - This->IHTMLStyle4_iface.lpVtbl = &HTMLStyle4Vtbl; - This->IHTMLStyle5_iface.lpVtbl = &HTMLStyle5Vtbl; - This->IHTMLStyle6_iface.lpVtbl = &HTMLStyle6Vtbl; -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlstyle.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlstyle.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlstyle.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlstyle.c 2016-02-08 19:32:34.000000000 +0000 @@ -3142,6 +3142,1522 @@ HTMLStyle_toString }; +static inline HTMLStyle *impl_from_IHTMLStyle2(IHTMLStyle2 *iface) +{ + return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle2_iface); +} + +static HRESULT WINAPI HTMLStyle2_QueryInterface(IHTMLStyle2 *iface, REFIID riid, void **ppv) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + return IHTMLStyle_QueryInterface(&This->IHTMLStyle_iface, riid, ppv); +} + +static ULONG WINAPI HTMLStyle2_AddRef(IHTMLStyle2 *iface) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + return IHTMLStyle_AddRef(&This->IHTMLStyle_iface); +} + +static ULONG WINAPI HTMLStyle2_Release(IHTMLStyle2 *iface) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + return IHTMLStyle_Release(&This->IHTMLStyle_iface); +} + +static HRESULT WINAPI HTMLStyle2_GetTypeInfoCount(IHTMLStyle2 *iface, UINT *pctinfo) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI HTMLStyle2_GetTypeInfo(IHTMLStyle2 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLStyle2_GetIDsOfNames(IHTMLStyle2 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, + lcid, rgDispId); +} + +static HRESULT WINAPI HTMLStyle2_Invoke(IHTMLStyle2 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLStyle2_put_tableLayout(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_nsstyle_attr(This->nsstyle, STYLEID_TABLE_LAYOUT, v, 0); +} + +static HRESULT WINAPI HTMLStyle2_get_tableLayout(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr(This->nsstyle, STYLEID_TABLE_LAYOUT, p, 0); +} + +static HRESULT WINAPI HTMLStyle2_put_borderCollapse(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_borderCollapse(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_direction(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_nsstyle_attr(This->nsstyle, STYLEID_DIRECTION, v, 0); +} + +static HRESULT WINAPI HTMLStyle2_get_direction(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr(This->nsstyle, STYLEID_DIRECTION, p, 0); +} + +static HRESULT WINAPI HTMLStyle2_put_behavior(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_behavior(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_setExpression(IHTMLStyle2 *iface, BSTR propname, BSTR expression, BSTR language) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s %s %s)\n", This, debugstr_w(propname), debugstr_w(expression), debugstr_w(language)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_getExpression(IHTMLStyle2 *iface, BSTR propname, VARIANT *expression) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(propname), expression); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_removeExpression(IHTMLStyle2 *iface, BSTR propname, VARIANT_BOOL *pfSuccess) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(propname), pfSuccess); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_position(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_nsstyle_attr(This->nsstyle, STYLEID_POSITION, v, 0); +} + +static HRESULT WINAPI HTMLStyle2_get_position(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr(This->nsstyle, STYLEID_POSITION, p, 0); +} + +static HRESULT WINAPI HTMLStyle2_put_unicodeBidi(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_unicodeBidi(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_bottom(IHTMLStyle2 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + return set_nsstyle_attr_var(This->nsstyle, STYLEID_BOTTOM, &v, ATTR_FIX_PX); +} + +static HRESULT WINAPI HTMLStyle2_get_bottom(IHTMLStyle2 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr_var(This->nsstyle, STYLEID_BOTTOM, p, 0); +} + +static HRESULT WINAPI HTMLStyle2_put_right(IHTMLStyle2 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + return set_nsstyle_attr_var(This->nsstyle, STYLEID_RIGHT, &v, 0); +} + +static HRESULT WINAPI HTMLStyle2_get_right(IHTMLStyle2 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr_var(This->nsstyle, STYLEID_RIGHT, p, 0); +} + +static HRESULT WINAPI HTMLStyle2_put_pixelBottom(IHTMLStyle2 *iface, LONG v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%d)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_pixelBottom(IHTMLStyle2 *iface, LONG *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_pixelRight(IHTMLStyle2 *iface, LONG v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%d)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_pixelRight(IHTMLStyle2 *iface, LONG *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_posBottom(IHTMLStyle2 *iface, float v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%f)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_posBottom(IHTMLStyle2 *iface, float *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_posRight(IHTMLStyle2 *iface, float v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%f)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_posRight(IHTMLStyle2 *iface, float *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_imeMode(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_imeMode(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_rubyAlign(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_rubyAlign(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_rubyPosition(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_rubyPosition(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_rubyOverhang(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_rubyOverhang(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_layoutGridChar(IHTMLStyle2 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_layoutGridChar(IHTMLStyle2 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_layoutGridLine(IHTMLStyle2 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_layoutGridLine(IHTMLStyle2 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_layoutGridMode(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_layoutGridMode(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_layoutGridType(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_layoutGridType(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_layoutGrid(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_layoutGrid(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_wordBreak(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_wordBreak(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_lineBreak(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_lineBreak(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_textJustify(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_textJustify(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_textJustifyTrim(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_textJustifyTrim(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_textKashida(IHTMLStyle2 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_textKashida(IHTMLStyle2 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_textAutospace(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_textAutospace(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_put_overflowX(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW_X, v, 0); +} + +static HRESULT WINAPI HTMLStyle2_get_overflowX(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW_X, p, 0); +} + +static HRESULT WINAPI HTMLStyle2_put_overflowY(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW_Y, v, 0); +} + +static HRESULT WINAPI HTMLStyle2_get_overflowY(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW_Y, p, 0); +} + +static HRESULT WINAPI HTMLStyle2_put_accelerator(IHTMLStyle2 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle2_get_accelerator(IHTMLStyle2 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle2(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static const IHTMLStyle2Vtbl HTMLStyle2Vtbl = { + HTMLStyle2_QueryInterface, + HTMLStyle2_AddRef, + HTMLStyle2_Release, + HTMLStyle2_GetTypeInfoCount, + HTMLStyle2_GetTypeInfo, + HTMLStyle2_GetIDsOfNames, + HTMLStyle2_Invoke, + HTMLStyle2_put_tableLayout, + HTMLStyle2_get_tableLayout, + HTMLStyle2_put_borderCollapse, + HTMLStyle2_get_borderCollapse, + HTMLStyle2_put_direction, + HTMLStyle2_get_direction, + HTMLStyle2_put_behavior, + HTMLStyle2_get_behavior, + HTMLStyle2_setExpression, + HTMLStyle2_getExpression, + HTMLStyle2_removeExpression, + HTMLStyle2_put_position, + HTMLStyle2_get_position, + HTMLStyle2_put_unicodeBidi, + HTMLStyle2_get_unicodeBidi, + HTMLStyle2_put_bottom, + HTMLStyle2_get_bottom, + HTMLStyle2_put_right, + HTMLStyle2_get_right, + HTMLStyle2_put_pixelBottom, + HTMLStyle2_get_pixelBottom, + HTMLStyle2_put_pixelRight, + HTMLStyle2_get_pixelRight, + HTMLStyle2_put_posBottom, + HTMLStyle2_get_posBottom, + HTMLStyle2_put_posRight, + HTMLStyle2_get_posRight, + HTMLStyle2_put_imeMode, + HTMLStyle2_get_imeMode, + HTMLStyle2_put_rubyAlign, + HTMLStyle2_get_rubyAlign, + HTMLStyle2_put_rubyPosition, + HTMLStyle2_get_rubyPosition, + HTMLStyle2_put_rubyOverhang, + HTMLStyle2_get_rubyOverhang, + HTMLStyle2_put_layoutGridChar, + HTMLStyle2_get_layoutGridChar, + HTMLStyle2_put_layoutGridLine, + HTMLStyle2_get_layoutGridLine, + HTMLStyle2_put_layoutGridMode, + HTMLStyle2_get_layoutGridMode, + HTMLStyle2_put_layoutGridType, + HTMLStyle2_get_layoutGridType, + HTMLStyle2_put_layoutGrid, + HTMLStyle2_get_layoutGrid, + HTMLStyle2_put_wordBreak, + HTMLStyle2_get_wordBreak, + HTMLStyle2_put_lineBreak, + HTMLStyle2_get_lineBreak, + HTMLStyle2_put_textJustify, + HTMLStyle2_get_textJustify, + HTMLStyle2_put_textJustifyTrim, + HTMLStyle2_get_textJustifyTrim, + HTMLStyle2_put_textKashida, + HTMLStyle2_get_textKashida, + HTMLStyle2_put_textAutospace, + HTMLStyle2_get_textAutospace, + HTMLStyle2_put_overflowX, + HTMLStyle2_get_overflowX, + HTMLStyle2_put_overflowY, + HTMLStyle2_get_overflowY, + HTMLStyle2_put_accelerator, + HTMLStyle2_get_accelerator +}; + +static inline HTMLStyle *impl_from_IHTMLStyle3(IHTMLStyle3 *iface) +{ + return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle3_iface); +} + +static HRESULT WINAPI HTMLStyle3_QueryInterface(IHTMLStyle3 *iface, REFIID riid, void **ppv) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + + return IHTMLStyle_QueryInterface(&This->IHTMLStyle_iface, riid, ppv); +} + +static ULONG WINAPI HTMLStyle3_AddRef(IHTMLStyle3 *iface) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + + return IHTMLStyle_AddRef(&This->IHTMLStyle_iface); +} + +static ULONG WINAPI HTMLStyle3_Release(IHTMLStyle3 *iface) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + + return IHTMLStyle_Release(&This->IHTMLStyle_iface); +} + +static HRESULT WINAPI HTMLStyle3_GetTypeInfoCount(IHTMLStyle3 *iface, UINT *pctinfo) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI HTMLStyle3_GetTypeInfo(IHTMLStyle3 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLStyle3_GetIDsOfNames(IHTMLStyle3 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, + lcid, rgDispId); +} + +static HRESULT WINAPI HTMLStyle3_Invoke(IHTMLStyle3 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLStyle3_put_layoutFlow(IHTMLStyle3 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_layoutFlow(IHTMLStyle3 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static const WCHAR zoomW[] = {'z','o','o','m',0}; + +static HRESULT WINAPI HTMLStyle3_put_zoom(IHTMLStyle3 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + VARIANT *var; + HRESULT hres; + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + /* zoom property is IE CSS extension that is mostly used as a hack to workaround IE bugs. + * The value is set to 1 then. We can safely ignore setting zoom to 1. */ + if(V_VT(&v) != VT_I4 || V_I4(&v) != 1) + WARN("stub for %s\n", debugstr_variant(&v)); + + hres = dispex_get_dprop_ref(&This->dispex, zoomW, TRUE, &var); + if(FAILED(hres)) + return hres; + + return VariantChangeType(var, &v, 0, VT_BSTR); +} + +static HRESULT WINAPI HTMLStyle3_get_zoom(IHTMLStyle3 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + VARIANT *var; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + hres = dispex_get_dprop_ref(&This->dispex, zoomW, FALSE, &var); + if(hres == DISP_E_UNKNOWNNAME) { + V_VT(p) = VT_BSTR; + V_BSTR(p) = NULL; + return S_OK; + } + if(FAILED(hres)) + return hres; + + return VariantCopy(p, var); +} + +static HRESULT WINAPI HTMLStyle3_put_wordWrap(IHTMLStyle3 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_nsstyle_attr(This->nsstyle, STYLEID_WORD_WRAP, v, 0); +} + +static HRESULT WINAPI HTMLStyle3_get_wordWrap(IHTMLStyle3 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr(This->nsstyle, STYLEID_WORD_WRAP, p, 0); +} + +static HRESULT WINAPI HTMLStyle3_put_textUnderlinePosition(IHTMLStyle3 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_textUnderlinePosition(IHTMLStyle3 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_put_scrollbarBaseColor(IHTMLStyle3 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_scrollbarBaseColor(IHTMLStyle3 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_put_scrollbarFaceColor(IHTMLStyle3 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_scrollbarFaceColor(IHTMLStyle3 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_put_scrollbar3dLightColor(IHTMLStyle3 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_scrollbar3dLightColor(IHTMLStyle3 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_put_scrollbarShadowColor(IHTMLStyle3 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_scrollbarShadowColor(IHTMLStyle3 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_put_scrollbarHighlightColor(IHTMLStyle3 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_scrollbarHighlightColor(IHTMLStyle3 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_put_scrollbarDarkShadowColor(IHTMLStyle3 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_scrollbarDarkShadowColor(IHTMLStyle3 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_put_scrollbarArrowColor(IHTMLStyle3 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_scrollbarArrowColor(IHTMLStyle3 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_put_scrollbarTrackColor(IHTMLStyle3 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_scrollbarTrackColor(IHTMLStyle3 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_put_writingMode(IHTMLStyle3 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_writingMode(IHTMLStyle3 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_put_textAlignLast(IHTMLStyle3 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_textAlignLast(IHTMLStyle3 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_put_textKashidaSpace(IHTMLStyle3 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle3_get_textKashidaSpace(IHTMLStyle3 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static const IHTMLStyle3Vtbl HTMLStyle3Vtbl = { + HTMLStyle3_QueryInterface, + HTMLStyle3_AddRef, + HTMLStyle3_Release, + HTMLStyle3_GetTypeInfoCount, + HTMLStyle3_GetTypeInfo, + HTMLStyle3_GetIDsOfNames, + HTMLStyle3_Invoke, + HTMLStyle3_put_layoutFlow, + HTMLStyle3_get_layoutFlow, + HTMLStyle3_put_zoom, + HTMLStyle3_get_zoom, + HTMLStyle3_put_wordWrap, + HTMLStyle3_get_wordWrap, + HTMLStyle3_put_textUnderlinePosition, + HTMLStyle3_get_textUnderlinePosition, + HTMLStyle3_put_scrollbarBaseColor, + HTMLStyle3_get_scrollbarBaseColor, + HTMLStyle3_put_scrollbarFaceColor, + HTMLStyle3_get_scrollbarFaceColor, + HTMLStyle3_put_scrollbar3dLightColor, + HTMLStyle3_get_scrollbar3dLightColor, + HTMLStyle3_put_scrollbarShadowColor, + HTMLStyle3_get_scrollbarShadowColor, + HTMLStyle3_put_scrollbarHighlightColor, + HTMLStyle3_get_scrollbarHighlightColor, + HTMLStyle3_put_scrollbarDarkShadowColor, + HTMLStyle3_get_scrollbarDarkShadowColor, + HTMLStyle3_put_scrollbarArrowColor, + HTMLStyle3_get_scrollbarArrowColor, + HTMLStyle3_put_scrollbarTrackColor, + HTMLStyle3_get_scrollbarTrackColor, + HTMLStyle3_put_writingMode, + HTMLStyle3_get_writingMode, + HTMLStyle3_put_textAlignLast, + HTMLStyle3_get_textAlignLast, + HTMLStyle3_put_textKashidaSpace, + HTMLStyle3_get_textKashidaSpace +}; + +/* + * IHTMLStyle4 Interface + */ +static inline HTMLStyle *impl_from_IHTMLStyle4(IHTMLStyle4 *iface) +{ + return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle4_iface); +} + +static HRESULT WINAPI HTMLStyle4_QueryInterface(IHTMLStyle4 *iface, REFIID riid, void **ppv) +{ + HTMLStyle *This = impl_from_IHTMLStyle4(iface); + + return IHTMLStyle_QueryInterface(&This->IHTMLStyle_iface, riid, ppv); +} + +static ULONG WINAPI HTMLStyle4_AddRef(IHTMLStyle4 *iface) +{ + HTMLStyle *This = impl_from_IHTMLStyle4(iface); + + return IHTMLStyle_AddRef(&This->IHTMLStyle_iface); +} + +static ULONG WINAPI HTMLStyle4_Release(IHTMLStyle4 *iface) +{ + HTMLStyle *This = impl_from_IHTMLStyle4(iface); + + return IHTMLStyle_Release(&This->IHTMLStyle_iface); +} + +static HRESULT WINAPI HTMLStyle4_GetTypeInfoCount(IHTMLStyle4 *iface, UINT *pctinfo) +{ + HTMLStyle *This = impl_from_IHTMLStyle4(iface); + return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI HTMLStyle4_GetTypeInfo(IHTMLStyle4 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLStyle *This = impl_from_IHTMLStyle4(iface); + return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLStyle4_GetIDsOfNames(IHTMLStyle4 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + HTMLStyle *This = impl_from_IHTMLStyle4(iface); + return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, + lcid, rgDispId); +} + +static HRESULT WINAPI HTMLStyle4_Invoke(IHTMLStyle4 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLStyle *This = impl_from_IHTMLStyle4(iface); + return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLStyle4_put_textOverflow(IHTMLStyle4 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle4(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle4_get_textOverflow(IHTMLStyle4 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle4(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle4_put_minHeight(IHTMLStyle4 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle4(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + return set_nsstyle_attr_var(This->nsstyle, STYLEID_MIN_HEIGHT, &v, 0); +} + +static HRESULT WINAPI HTMLStyle4_get_minHeight(IHTMLStyle4 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle4(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr_var(This->nsstyle, STYLEID_MIN_HEIGHT, p, 0); +} + +static const IHTMLStyle4Vtbl HTMLStyle4Vtbl = { + HTMLStyle4_QueryInterface, + HTMLStyle4_AddRef, + HTMLStyle4_Release, + HTMLStyle4_GetTypeInfoCount, + HTMLStyle4_GetTypeInfo, + HTMLStyle4_GetIDsOfNames, + HTMLStyle4_Invoke, + HTMLStyle4_put_textOverflow, + HTMLStyle4_get_textOverflow, + HTMLStyle4_put_minHeight, + HTMLStyle4_get_minHeight +}; + +static inline HTMLStyle *impl_from_IHTMLStyle5(IHTMLStyle5 *iface) +{ + return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle5_iface); +} + +static HRESULT WINAPI HTMLStyle5_QueryInterface(IHTMLStyle5 *iface, REFIID riid, void **ppv) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + + return IHTMLStyle_QueryInterface(&This->IHTMLStyle_iface, riid, ppv); +} + +static ULONG WINAPI HTMLStyle5_AddRef(IHTMLStyle5 *iface) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + + return IHTMLStyle_AddRef(&This->IHTMLStyle_iface); +} + +static ULONG WINAPI HTMLStyle5_Release(IHTMLStyle5 *iface) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + + return IHTMLStyle_Release(&This->IHTMLStyle_iface); +} + +static HRESULT WINAPI HTMLStyle5_GetTypeInfoCount(IHTMLStyle5 *iface, UINT *pctinfo) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI HTMLStyle5_GetTypeInfo(IHTMLStyle5 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLStyle5_GetIDsOfNames(IHTMLStyle5 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, + lcid, rgDispId); +} + +static HRESULT WINAPI HTMLStyle5_Invoke(IHTMLStyle5 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLStyle5_put_msInterpolationMode(IHTMLStyle5 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle5_get_msInterpolationMode(IHTMLStyle5 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle5_put_maxHeight(IHTMLStyle5 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + return set_nsstyle_attr_var(This->nsstyle, STYLEID_MAX_HEIGHT, &v, ATTR_FIX_PX); +} + +static HRESULT WINAPI HTMLStyle5_get_maxHeight(IHTMLStyle5 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_variant(p)); + + return get_nsstyle_attr_var(This->nsstyle, STYLEID_MAX_HEIGHT, p, 0); +} + +static HRESULT WINAPI HTMLStyle5_put_minWidth(IHTMLStyle5 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + return set_nsstyle_attr_var(This->nsstyle, STYLEID_MIN_WIDTH, &v, ATTR_FIX_PX); +} + +static HRESULT WINAPI HTMLStyle5_get_minWidth(IHTMLStyle5 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr_var(This->nsstyle, STYLEID_MIN_WIDTH, p, 0); +} + +static HRESULT WINAPI HTMLStyle5_put_maxWidth(IHTMLStyle5 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + return set_nsstyle_attr_var(This->nsstyle, STYLEID_MAX_WIDTH, &v, ATTR_FIX_PX); +} + +static HRESULT WINAPI HTMLStyle5_get_maxWidth(IHTMLStyle5 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle5(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr_var(This->nsstyle, STYLEID_MAX_WIDTH, p, 0); +} + +static const IHTMLStyle5Vtbl HTMLStyle5Vtbl = { + HTMLStyle5_QueryInterface, + HTMLStyle5_AddRef, + HTMLStyle5_Release, + HTMLStyle5_GetTypeInfoCount, + HTMLStyle5_GetTypeInfo, + HTMLStyle5_GetIDsOfNames, + HTMLStyle5_Invoke, + HTMLStyle5_put_msInterpolationMode, + HTMLStyle5_get_msInterpolationMode, + HTMLStyle5_put_maxHeight, + HTMLStyle5_get_maxHeight, + HTMLStyle5_put_minWidth, + HTMLStyle5_get_minWidth, + HTMLStyle5_put_maxWidth, + HTMLStyle5_get_maxWidth +}; + +static inline HTMLStyle *impl_from_IHTMLStyle6(IHTMLStyle6 *iface) +{ + return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle6_iface); +} + +static HRESULT WINAPI HTMLStyle6_QueryInterface(IHTMLStyle6 *iface, REFIID riid, void **ppv) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + + return IHTMLStyle_QueryInterface(&This->IHTMLStyle_iface, riid, ppv); +} + +static ULONG WINAPI HTMLStyle6_AddRef(IHTMLStyle6 *iface) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + + return IHTMLStyle_AddRef(&This->IHTMLStyle_iface); +} + +static ULONG WINAPI HTMLStyle6_Release(IHTMLStyle6 *iface) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + + return IHTMLStyle_Release(&This->IHTMLStyle_iface); +} + +static HRESULT WINAPI HTMLStyle6_GetTypeInfoCount(IHTMLStyle6 *iface, UINT *pctinfo) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI HTMLStyle6_GetTypeInfo(IHTMLStyle6 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLStyle6_GetIDsOfNames(IHTMLStyle6 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, + lcid, rgDispId); +} + +static HRESULT WINAPI HTMLStyle6_Invoke(IHTMLStyle6 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLStyle6_put_content(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_content(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_contentSide(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_contentSide(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_counterIncrement(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_counterIncrement(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_counterReset(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_counterReset(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_outline(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_nsstyle_attr(This->nsstyle, STYLEID_OUTLINE, v, 0); +} + +static HRESULT WINAPI HTMLStyle6_get_outline(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr(This->nsstyle, STYLEID_OUTLINE, p, ATTR_NO_NULL); +} + +static HRESULT WINAPI HTMLStyle6_put_outlineWidth(IHTMLStyle6 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_outlineWidth(IHTMLStyle6 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_outlineStyle(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_outlineStyle(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_outlineColor(IHTMLStyle6 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_outlineColor(IHTMLStyle6 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_boxSizing(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_nsstyle_attr(This->nsstyle, STYLEID_BOX_SIZING, v, 0); +} + +static HRESULT WINAPI HTMLStyle6_get_boxSizing(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr(This->nsstyle, STYLEID_BOX_SIZING, p, 0); +} + +static HRESULT WINAPI HTMLStyle6_put_boxSpacing(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_boxSpacing(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_orphans(IHTMLStyle6 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_orphans(IHTMLStyle6 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_windows(IHTMLStyle6 *iface, VARIANT v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_windows(IHTMLStyle6 *iface, VARIANT *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_pageBreakInside(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_pageBreakInside(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_emptyCells(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_emptyCells(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_msBlockProgression(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_msBlockProgression(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_put_quotes(IHTMLStyle6 *iface, BSTR v) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLStyle6_get_quotes(IHTMLStyle6 *iface, BSTR *p) +{ + HTMLStyle *This = impl_from_IHTMLStyle6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static const IHTMLStyle6Vtbl HTMLStyle6Vtbl = { + HTMLStyle6_QueryInterface, + HTMLStyle6_AddRef, + HTMLStyle6_Release, + HTMLStyle6_GetTypeInfoCount, + HTMLStyle6_GetTypeInfo, + HTMLStyle6_GetIDsOfNames, + HTMLStyle6_Invoke, + HTMLStyle6_put_content, + HTMLStyle6_get_content, + HTMLStyle6_put_contentSide, + HTMLStyle6_get_contentSide, + HTMLStyle6_put_counterIncrement, + HTMLStyle6_get_counterIncrement, + HTMLStyle6_put_counterReset, + HTMLStyle6_get_counterReset, + HTMLStyle6_put_outline, + HTMLStyle6_get_outline, + HTMLStyle6_put_outlineWidth, + HTMLStyle6_get_outlineWidth, + HTMLStyle6_put_outlineStyle, + HTMLStyle6_get_outlineStyle, + HTMLStyle6_put_outlineColor, + HTMLStyle6_get_outlineColor, + HTMLStyle6_put_boxSizing, + HTMLStyle6_get_boxSizing, + HTMLStyle6_put_boxSpacing, + HTMLStyle6_get_boxSpacing, + HTMLStyle6_put_orphans, + HTMLStyle6_get_orphans, + HTMLStyle6_put_windows, + HTMLStyle6_get_windows, + HTMLStyle6_put_pageBreakInside, + HTMLStyle6_get_pageBreakInside, + HTMLStyle6_put_emptyCells, + HTMLStyle6_get_emptyCells, + HTMLStyle6_put_msBlockProgression, + HTMLStyle6_get_msBlockProgression, + HTMLStyle6_put_quotes, + HTMLStyle6_get_quotes +}; + static HRESULT HTMLStyle_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid) { const style_tbl_entry_t *style_entry; @@ -3219,11 +4735,15 @@ } style->IHTMLStyle_iface.lpVtbl = &HTMLStyleVtbl; + style->IHTMLStyle2_iface.lpVtbl = &HTMLStyle2Vtbl; + style->IHTMLStyle3_iface.lpVtbl = &HTMLStyle3Vtbl; + style->IHTMLStyle4_iface.lpVtbl = &HTMLStyle4Vtbl; + style->IHTMLStyle5_iface.lpVtbl = &HTMLStyle5Vtbl; + style->IHTMLStyle6_iface.lpVtbl = &HTMLStyle6Vtbl; + style->ref = 1; style->nsstyle = nsstyle; style->elem = elem; - HTMLStyle2_Init(style); - HTMLStyle3_Init(style); nsIDOMCSSStyleDeclaration_AddRef(nsstyle); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlstyle.h wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlstyle.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/htmlstyle.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/htmlstyle.h 2016-02-08 19:32:34.000000000 +0000 @@ -122,8 +122,6 @@ } styleid_t; HRESULT HTMLStyle_Create(HTMLElement*,HTMLStyle**) DECLSPEC_HIDDEN; -void HTMLStyle2_Init(HTMLStyle*) DECLSPEC_HIDDEN; -void HTMLStyle3_Init(HTMLStyle*) DECLSPEC_HIDDEN; HRESULT get_nsstyle_attr(nsIDOMCSSStyleDeclaration*,styleid_t,BSTR*,DWORD) DECLSPEC_HIDDEN; HRESULT set_nsstyle_attr(nsIDOMCSSStyleDeclaration*,styleid_t,LPCWSTR,DWORD) DECLSPEC_HIDDEN; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/main.c 2016-02-08 19:32:34.000000000 +0000 @@ -54,25 +54,35 @@ static WCHAR *status_strings[IDS_STATUS_LAST-IDS_STATUS_FIRST+1]; static IMultiLanguage2 *mlang; -UINT cp_from_charset_string(BSTR charset) +static BOOL ensure_mlang(void) { - MIMECSETINFO info; + IMultiLanguage2 *new_mlang; HRESULT hres; - if(!mlang) { - IMultiLanguage2 *new_mlang; - - hres = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, - &IID_IMultiLanguage2, (void**)&new_mlang); - if(FAILED(hres)) { - ERR("Could not create CMultiLanguage instance\n"); - return CP_UTF8; - } + if(mlang) + return TRUE; - if(InterlockedCompareExchangePointer((void**)&mlang, new_mlang, NULL)) - IMultiLanguage2_Release(new_mlang); + hres = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, + &IID_IMultiLanguage2, (void**)&new_mlang); + if(FAILED(hres)) { + ERR("Could not create CMultiLanguage instance\n"); + return FALSE; } + if(InterlockedCompareExchangePointer((void**)&mlang, new_mlang, NULL)) + IMultiLanguage2_Release(new_mlang); + + return TRUE; +} + +UINT cp_from_charset_string(BSTR charset) +{ + MIMECSETINFO info; + HRESULT hres; + + if(!ensure_mlang()) + return CP_UTF8; + hres = IMultiLanguage2_GetCharsetInfo(mlang, charset, &info); if(FAILED(hres)) { FIXME("GetCharsetInfo failed: %08x\n", hres); @@ -82,6 +92,23 @@ return info.uiInternetEncoding; } +BSTR charset_string_from_cp(UINT cp) +{ + MIMECPINFO info; + HRESULT hres; + + if(!ensure_mlang()) + return SysAllocString(NULL); + + hres = IMultiLanguage2_GetCodePageInfo(mlang, cp, GetUserDefaultUILanguage(), &info); + if(FAILED(hres)) { + ERR("GetCodePageInfo failed: %08x\n", hres); + return SysAllocString(NULL); + } + + return SysAllocString(info.wszWebCharset); +} + static void thread_detach(void) { thread_data_t *thread_data; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -38,8 +38,6 @@ htmlselect.c \ htmlstorage.c \ htmlstyle.c \ - htmlstyle2.c \ - htmlstyle3.c \ htmlstyleelem.c \ htmlstylesheet.c \ htmltable.c \ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/mshtml_private.h wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/mshtml_private.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/mshtml_private.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/mshtml_private.h 2016-02-08 19:32:34.000000000 +0000 @@ -41,6 +41,8 @@ #define NS_ERROR_GENERATE_FAILURE(module,code) \ ((nsresult) (((UINT32)(1u<<31)) | ((UINT32)(module+0x45)<<16) | ((UINT32)(code)))) +#define NS_ERROR_GENERATE_SUCCESS(module,code) \ + ((nsresult) (((UINT32)(module+0x45)<<16) | ((UINT32)(code)))) #define NS_OK ((nsresult)0x00000000L) #define NS_ERROR_FAILURE ((nsresult)0x80004005L) @@ -57,6 +59,7 @@ #define NS_BINDING_ABORTED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 2) #define NS_ERROR_UNKNOWN_PROTOCOL NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 18) +#define NS_SUCCESS_DEFAULT_ACTION NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_NETWORK, 66) #define NS_FAILED(res) ((res) & 0x80000000) #define NS_SUCCEEDED(res) (!NS_FAILED(res)) @@ -706,12 +709,14 @@ IHTMLElement2 IHTMLElement2_iface; IHTMLElement3 IHTMLElement3_iface; IHTMLElement4 IHTMLElement4_iface; + IHTMLUniqueName IHTMLUniqueName_iface; nsIDOMHTMLElement *nselem; HTMLStyle *style; HTMLStyle *runtime_style; HTMLAttributeCollection *attrs; WCHAR *filter; + unsigned unique_id; } HTMLElement; #define HTMLELEMENT_TIDS \ @@ -720,7 +725,8 @@ IHTMLElement_tid, \ IHTMLElement2_tid, \ IHTMLElement3_tid, \ - IHTMLElement4_tid + IHTMLElement4_tid, \ + IHTMLUniqueName_tid extern cp_static_data_t HTMLElementEvents2_data DECLSPEC_HIDDEN; #define HTMLELEMENT_CPC {&DIID_HTMLElementEvents2, &HTMLElementEvents2_data} @@ -776,6 +782,8 @@ UINT charset; + unsigned unique_id; + struct list selection_list; struct list range_list; struct list plugin_hosts; @@ -841,7 +849,7 @@ BOOL load_gecko(void) DECLSPEC_HIDDEN; void close_gecko(void) DECLSPEC_HIDDEN; void register_nsservice(nsIComponentRegistrar*,nsIServiceManager*) DECLSPEC_HIDDEN; -void init_nsio(nsIComponentManager*,nsIComponentRegistrar*) DECLSPEC_HIDDEN; +void init_nsio(nsIComponentManager*) DECLSPEC_HIDDEN; void release_nsio(void) DECLSPEC_HIDDEN; BOOL is_gecko_path(const char*) DECLSPEC_HIDDEN; void set_viewer_zoom(NSContainer*,float) DECLSPEC_HIDDEN; @@ -1016,6 +1024,8 @@ HRESULT elem_string_attr_getter(HTMLElement*,const WCHAR*,BOOL,BSTR*) DECLSPEC_HIDDEN; HRESULT elem_string_attr_setter(HTMLElement*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN; +HRESULT elem_unique_id(unsigned id, BSTR *p) DECLSPEC_HIDDEN; + /* commands */ typedef struct { DWORD id; @@ -1264,6 +1274,7 @@ } UINT cp_from_charset_string(BSTR) DECLSPEC_HIDDEN; +BSTR charset_string_from_cp(UINT) DECLSPEC_HIDDEN; HDC get_display_dc(void) DECLSPEC_HIDDEN; HINSTANCE get_shdoclc(void) DECLSPEC_HIDDEN; void set_statustext(HTMLDocumentObj*,INT,LPCWSTR) DECLSPEC_HIDDEN; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/mutation.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/mutation.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/mutation.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/mutation.c 2016-02-08 19:32:34.000000000 +0000 @@ -526,12 +526,17 @@ } static void NSAPI nsDocumentObserver_AttributeWillChange(nsIDocumentObserver *iface, nsIDocument *aDocument, - nsIContent *aContent, LONG aNameSpaceID, nsIAtom *aAttribute, LONG aModType) + void *aElement, LONG aNameSpaceID, nsIAtom *aAttribute, LONG aModType, const nsAttrValue *aNewValue) { } static void NSAPI nsDocumentObserver_AttributeChanged(nsIDocumentObserver *iface, nsIDocument *aDocument, - nsIContent *aContent, LONG aNameSpaceID, nsIAtom *aAttribute, LONG aModType) + void *aElement, LONG aNameSpaceID, nsIAtom *aAttribute, LONG aModType, const nsAttrValue *aOldValue) +{ +} + +static void NSAPI nsDocumentObserver_NativeAnonymousChildListChange(nsIDocumentObserver *iface, nsIDocument *aDocument, + nsIContent *aContent, cpp_bool aIsRemove) { } @@ -722,6 +727,7 @@ nsDocumentObserver_CharacterDataChanged, nsDocumentObserver_AttributeWillChange, nsDocumentObserver_AttributeChanged, + nsDocumentObserver_NativeAnonymousChildListChange, nsDocumentObserver_AttributeSetToCurrentValue, nsDocumentObserver_ContentAppended, nsDocumentObserver_ContentInserted, diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/nsembed.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/nsembed.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/nsembed.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/nsembed.c 2016-02-08 19:32:34.000000000 +0000 @@ -458,9 +458,9 @@ if(TRACE_ON(gecko)) debug_level = 5; else if(WARN_ON(gecko)) - debug_level = 3; - else if(ERR_ON(gecko)) debug_level = 2; + else if(ERR_ON(gecko)) + debug_level = 1; sprintfW(buf, debug_formatW, debug_level); SetEnvironmentVariableW(nspr_log_modulesW, buf); @@ -721,12 +721,7 @@ if(NS_FAILED(nsres)) ERR("Could not get nsIComponentManager: %08x\n", nsres); - nsres = NS_GetComponentRegistrar(®istrar); - if(NS_SUCCEEDED(nsres)) - init_nsio(pCompMgr, registrar); - else - ERR("NS_GetComponentRegistrar failed: %08x\n", nsres); - + init_nsio(pCompMgr); init_mutation(pCompMgr); set_preferences(); @@ -735,9 +730,12 @@ if(NS_FAILED(nsres)) ERR("Could not get category manager service: %08x\n", nsres); - if(registrar) { + nsres = NS_GetComponentRegistrar(®istrar); + if(NS_SUCCEEDED(nsres)) { register_nsservice(registrar, pServMgr); nsIComponentRegistrar_Release(registrar); + }else { + ERR("NS_GetComponentRegistrar failed: %08x\n", nsres); } init_node_cc(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/nsiface.idl wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/nsiface.idl --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/nsiface.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/nsiface.idl 2016-02-08 19:32:34.000000000 +0000 @@ -25,7 +25,7 @@ #pragma makedep header -cpp_quote("#define GECKO_VERSION \"2.40\"") +cpp_quote("#define GECKO_VERSION \"2.44\"") cpp_quote("#define GECKO_VERSION_STRING \"Wine Gecko \" GECKO_VERSION") import "wtypes.idl"; @@ -191,7 +191,6 @@ typedef nsISupports nsIPrivacyTransitionObserver; typedef nsISupports nsIDOMHTMLPropertiesCollection; typedef nsISupports mozIDOMApplication; -typedef nsISupports nsILoadGroupConnectionInfo; typedef nsISupports nsIDOMCrypto; typedef nsISupports nsIDOMPkcs11; typedef nsISupports nsIDocShellTreeOwner; @@ -398,7 +397,7 @@ [ object, - uuid(395fe045-7d18-4adb-a3fd-af98c8a1af11), + uuid(92073a54-6d78-4f30-913a-b871813208c6), local ] interface nsIURI : nsISupports @@ -427,6 +426,7 @@ nsresult Clone(nsIURI **_retval); nsresult Resolve(const nsACString *relativePath, nsACString *_retval); nsresult GetAsciiSpec(nsACString *aAsciiSpec); + nsresult GetAsciiHostPort(nsACString *aAsciiHostPort); nsresult GetAsciiHost(nsACString *aAsciiHost); nsresult GetOriginCharset(nsACString *aOriginCharset); nsresult GetRef(nsACString *aRef); @@ -439,7 +439,7 @@ [ object, - uuid(1419aa16-f134-4154-9886-00c7c5147a13), + uuid(86adcd89-0b70-47a2-b0fe-5bb2c5f37e31), local ] interface nsIURL : nsIURI @@ -462,7 +462,7 @@ [ object, - uuid(7750029c-1b0a-414e-8359-a77f24a2a0a6), + uuid(e91ac988-27c2-448b-b1a1-3822e1ef1987), local ] interface nsIFileURL : nsIURL @@ -535,7 +535,7 @@ [ object, - uuid(afb57ac2-bce5-4ee3-bb34-385089a9ba5c), + uuid(f0c87725-7a35-463c-9ceb-2c07f23406cc), local ] interface nsILoadGroup : nsIRequest @@ -550,14 +550,14 @@ nsresult GetActiveCount(uint32_t *aActiveCount); nsresult GetNotificationCallbacks(nsIInterfaceRequestor **aNotificationCallbacks); nsresult SetNotificationCallbacks(nsIInterfaceRequestor *aNotificationCallbacks); - nsresult GetConnectionInfo(nsILoadGroupConnectionInfo **aConnectionInfo); + nsresult GetSchedulingContextID(nsID *aSchedulingContextID); nsresult GetDefaultLoadFlags(nsLoadFlags *aDefaultLoadFlags); nsresult SetDefaultLoadFlags(nsLoadFlags aDefaultLoadFlags); } [ object, - uuid(1bc48693-c45d-45f4-8ab1-46e323037fe1), + uuid(2c389865-23db-4aa7-9fe5-60cc7b00697e), local ] interface nsIChannel : nsIRequest @@ -571,6 +571,7 @@ const UINT LOAD_CLASSIFY_URI = 1 << 22; const UINT LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE = 1 << 23; const UINT LOAD_EXPLICIT_CREDENTIALS = 1 << 24; + const UINT LOAD_BYPASS_SERVICE_WORKER = 1 << 25; nsresult GetOriginalURI(nsIURI **aOriginalURI); nsresult SetOriginalURI(nsIURI *aOriginalURI); @@ -587,7 +588,9 @@ nsresult GetContentLength(int64_t *aContentLength); nsresult SetContentLength(int64_t aContentLength); nsresult Open(nsIInputStream **_retval); + nsresult Open2(nsIInputStream **_retval); nsresult AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext); + nsresult AsyncOpen2(nsIStreamListener *aListener); nsresult GetContentDisposition(uint32_t *aContentDisposition); nsresult SetContentDisposition(uint32_t aContentDisposition); nsresult GetContentDispositionFilename(nsAString *aContentDispositionFilename); @@ -609,7 +612,7 @@ [ object, - uuid(86ad7e1f-3a64-4e0f-a104-395ebecd7d5c), + uuid(e90acf2d-eaf2-41d8-97b2-c8d99f6437a1), local ] interface nsIHttpChannel : nsIChannel @@ -622,7 +625,9 @@ nsresult SetReferrerWithPolicy(nsIURI *referrer, uint32_t referrerPolicy); nsresult GetRequestHeader(const nsACString *aHeader, nsACString *_retval); nsresult SetRequestHeader(const nsACString *aHeader, const nsACString *aValue, bool aMerge); + nsresult SetEmptyRequestHeader(const nsACString *aHeader); nsresult VisitRequestHeaders(nsIHttpHeaderVisitor *aVisitor); + nsresult VisitNonDefaultRequestHeaders(nsIHttpHeaderVisitor *aVisitor); nsresult GetAllowPipelining(bool *aAllowPipelining); nsresult SetAllowPipelining(bool aAllowPipelining); nsresult GetAllowSTS(bool *aAllowSTS); @@ -632,6 +637,8 @@ nsresult GetResponseStatus(uint32_t *aResponseStatus); nsresult GetResponseStatusText(nsACString *aResponseStatusText); nsresult GetRequestSucceeded(bool *aRequestSucceeded); + nsresult GetIsMainDocumentChannel(bool *aIsMainDocumentChannel); + nsresult SetIsMainDocumentChannel(bool aIsMainDocumentChannel); nsresult GetResponseHeader(const nsACString *header, nsACString *_retval); nsresult SetResponseHeader(const nsACString *header, const nsACString *value, bool merge); nsresult VisitResponseHeaders(nsIHttpHeaderVisitor *aVisitor); @@ -639,11 +646,13 @@ nsresult IsNoCacheResponse(bool *_retval); nsresult IsPrivateResponse(bool *_retval); nsresult RedirectTo(nsIURI *aNewURI); + nsresult GetSchedulingContextID(nsID *aSchedulingContextID); + nsresult SetSchedulingContextID(const nsID aSchedulingContextID); } [ object, - uuid(26833ec7-4555-4f23-9281-3a12d4b76db1), + uuid(9eabaac6-cc7c-4ca1-9430-65f2daaa578f), local ] interface nsIHttpChannelInternal : nsISupports @@ -672,21 +681,26 @@ nsresult SetAllowSpdy(bool aAllowSpdy); nsresult GetResponseTimeoutEnabled(bool *aResponseTimeoutEnabled); nsresult SetResponseTimeoutEnabled(bool aResponseTimeoutEnabled); + nsresult GetInitialRwin(uint32_t *aInitialRwin) ; + nsresult SetInitialRwin(uint32_t aInitialRwin); nsresult GetApiRedirectToURI(nsIURI **aApiRedirectToURI); nsresult GetAllowAltSvc(bool *aAllowAltSvc); nsresult SetAllowAltSvc(bool aAllowAltSvc); - nsresult AddRedirect(nsIPrincipal *aPrincipal); nsresult GetLastModifiedTime(PRTime *aLastModifiedTime); - nsresult ForceNoIntercept(); + nsresult ForceIntercepted(uint64_t aInterceptionID); + nsresult GetResponseSynthesized(bool *aResponseSynthesized); nsresult GetCorsIncludeCredentials(bool *aCorsIncludeCredentials); nsresult SetCorsIncludeCredentials(bool aCorsIncludeCredentials); nsresult GetCorsMode(uint32_t *aCorsMode); nsresult SetCorsMode(uint32_t aCorsMode); + nsresult GetRedirectMode(uint32_t *aRedirectMode); + nsresult SetRedirectMode(uint32_t aRedirectMode); nsresult GetTopWindowURI(nsIURI **aTopWindowURI); nsresult GetNetworkInterfaceId(nsACString *aNetworkInterfaceId); nsresult SetNetworkInterfaceId(const nsACString *aNetworkInterfaceId); - nsresult ContinueBeginConnect(); nsresult GetProxyURI(nsIURI **aProxyURI); + nsresult SetCorsPreflightParameters(const void /*nsTArray*/ *unsafeHeaders, + bool withCredentials, nsIPrincipal *preflightPrincipal); } [ @@ -1392,57 +1406,32 @@ [ object, - uuid(8146f3fc-9fc1-47c5-85ef-95d686e4ca6d), + uuid(ab30b7cc-f7f9-4b9b-befb-7dbf6cf86d46), local ] interface nsIDOMWindow : nsISupports { - nsresult GetWindow(nsIDOMWindow **aWindow); - nsresult GetSelf(nsIDOMWindow **aSelf); nsresult GetDocument(nsIDOMDocument **aDocument); nsresult GetName(nsAString *aName); nsresult SetName(const nsAString *aName); nsresult GetLocation(nsIDOMLocation **aLocation); - nsresult GetHistory(nsISupports **aHistory); - nsresult GetLocationbar(nsISupports **aLocationbar); - nsresult GetMenubar(nsISupports **aMenubar); - nsresult GetPersonalbar(nsISupports **aPersonalbar); - nsresult GetScrollbars(nsISupports **aScrollbars); - nsresult GetStatusbar(nsISupports **aStatusbar); - nsresult GetToolbar(nsISupports **aToolbar); - nsresult GetStatus(nsAString *aStatus); - nsresult SetStatus(const nsAString *aStatus); nsresult Close(); nsresult Stop(); nsresult Focus(); nsresult Blur(); nsresult GetLength(uint32_t *aLength); - nsresult GetScriptableTop(nsIDOMWindow **aTop); nsresult GetRealTop(nsIDOMWindow **aTop); - nsresult GetScriptableParent(nsIDOMWindow **aParent); nsresult GetRealParent(nsIDOMWindow **aParent); - nsresult GetScriptableOpener(JSContext* cx, int /* JS::MutableHandleValue */ aOpener); - nsresult SetScriptableOpener(JSContext* cx, int /* JS::HandleValue */ aOpener); nsresult GetOpener(nsIDOMWindow **aOpenerWindow); nsresult SetOpener(nsIDOMWindow *aOpenerWindow); - nsresult GetScriptableFrameElement(nsIDOMElement **aFrameElement); nsresult GetRealFrameElement(nsIDOMElement **aFrameElement); nsresult GetNavigator(nsIDOMNavigator **aNavigator); - nsresult GetApplicationCache(nsIDOMOfflineResourceList **aApplicationCache); - nsresult Alert(const nsAString *text); - nsresult Confirm(const nsAString *text, bool *_retval); - nsresult Prompt(const nsAString *aMessage, const nsAString *aInitial, nsAString *_retval); nsresult Print(); - nsresult ShowModalDialog(const nsAString *aURI, nsIVariant *aArgs, const nsAString *aOptions, uint8_t _argc, nsIVariant **_retval); - nsresult PostMessageMoz(const long /*jsval*/ *message, const nsAString *targetOrigin, const /*JS::Value*/ void *transfer, JSContext *cx); - nsresult Atob(const nsAString *aAsciiString, nsAString *_retval); - nsresult Btoa(const nsAString *aBase64Data, nsAString *_retval); nsresult GetSessionStorage(nsISupports **aSessionStorage); nsresult GetLocalStorage(nsISupports **aLocalStorage); nsresult GetIndexedDB(nsISupports **aIndexedDB); nsresult GetSelection(nsISelection **_retval); nsresult MatchMedia(const nsAString *media_query_list, nsISupports **_retval); - nsresult GetScreen(nsIDOMScreen **aScreen); nsresult GetInnerWidth(int32_t *aInnerWidth); nsresult SetInnerWidth(int32_t aInnerWidth); nsresult GetInnerHeight(int32_t *aInnerHeight); @@ -1464,18 +1453,11 @@ nsresult SetOuterHeight(int32_t aOuterHeight); nsresult GetComputedStyle(nsIDOMElement *elt, const nsAString *pseudoElt, nsIDOMCSSStyleDeclaration **_retval); nsresult GetDefaultComputedStyle(nsIDOMElement *elt, const nsAString *pseudoElt, nsIDOMCSSStyleDeclaration **_retval); - nsresult GetWindowRoot(nsIDOMEventTarget **aWindowRoot); nsresult GetFrames(nsIDOMWindowCollection **aFrames); nsresult GetTextZoom(float *aTextZoom); nsresult SetTextZoom(float aTextZoom); nsresult ScrollByLines(int32_t numLines); nsresult ScrollByPages(int32_t numPages); - nsresult SizeToContent(); - nsresult GetContent(nsIDOMWindow **aContent); - nsresult GetPrompter(nsIPrompt **aPrompter); - nsresult GetClosed(bool *aClosed); - nsresult GetCrypto(nsIDOMCrypto **aCrypto); - nsresult GetControllers(nsIControllers **aControllers); nsresult GetMozInnerScreenX(float *aMozInnerScreenX); nsresult GetMozInnerScreenY(float *aMozInnerScreenY); nsresult GetDevicePixelRatio(float *aDevicePixelRatio); @@ -1486,25 +1468,9 @@ nsresult Back(); nsresult Forward(); nsresult Home(); - nsresult MoveTo(int32_t xPos, int32_t yPos); - nsresult MoveBy(int32_t xDif, int32_t yDif); - nsresult ResizeTo(int32_t width, int32_t height); - nsresult ResizeBy(int32_t widthDif, int32_t heightDif); nsresult Open(const nsAString *url, const nsAString *name, const nsAString *options, nsIDOMWindow **_retval); - nsresult OpenDialog(const nsAString *url, const nsAString *name, const nsAString *options, nsISupports *aExtraArgument, - nsIDOMWindow **_retval); - nsresult UpdateCommands(const nsAString *action, nsISelection *sel, int16_t reason); nsresult Find(const nsAString *str, bool caseSensitive, bool backwards, bool wrapAround, bool wholeWord, bool searchInFrames, bool showDialog, bool *_retval); - nsresult GetMozPaintCount(uint64_t *aMozPaintCount); - nsresult MozRequestAnimationFrame(nsIFrameRequestCallback *aCallback, int32_t *_retval); - nsresult RequestAnimationFrame(void /*const JS::Value*/ *aCallback, JSContext* cx, int32_t *_retval); - nsresult MozCancelAnimationFrame(int32_t aHandle); - nsresult MozCancelRequestAnimationFrame(int32_t aHandle); - nsresult CancelAnimationFrame(int32_t aHandle); - nsresult GetMozAnimationStartTime(int64_t *aMozAnimationStartTime); - nsresult GetConsole(JSContext *cx, jsval *aConsole); - nsresult SetConsole(JSContext *cx, const jsval *aConsole); } [ @@ -2348,7 +2314,7 @@ [ object, - uuid(0e92d522-53a5-4af6-9a24-4eccdcbf4f91), + uuid(3ade79d4-8cb9-4952-b18d-4f9b63ca0d31), local ] interface nsIWebNavigation : nsISupports @@ -2370,6 +2336,7 @@ const UINT LOAD_FLAGS_BYPASS_CLASSIFIER = 0x10000; const UINT LOAD_FLAGS_FORCE_ALLOW_COOKIES = 0x20000; const UINT LOAD_FLAGS_DISALLOW_INHERIT_OWNER = 0x40000; + const UINT LOAD_FLAGS_ERROR_LOAD_CHANGES_RV = 0x80000; nsresult GetCanGoBack(bool *aCanGoBack); nsresult GetCanGoForward(bool *aCanGoForward); @@ -2407,7 +2374,7 @@ [ object, - uuid(1bcfc611-8941-4c39-9e06-7116e564a1ce), + uuid(04dd3a01-a74e-44aa-8d49-2c30478fd7b8), local ] interface nsIPrintSettings : nsISupports @@ -2417,6 +2384,7 @@ nsresult SetPrintOptions(int32_t aType, bool aTurnOnOff); nsresult GetPrintOptions(int32_t aType, bool *_retval); nsresult GetPrintOptionsBits(int32_t *_retval); + nsresult SetPrintOptionsBits(int32_t bits); nsresult GetEffectivePageSize(double *aWidth, double *aHeight); nsresult Clone(nsIPrintSettings **_retval); nsresult Assign(nsIPrintSettings *aPS); @@ -2500,22 +2468,12 @@ nsresult SetPaperHeight(double aPaperHeight); nsresult GetPaperSizeUnit(int16_t *aPaperSizeUnit); nsresult SetPaperSizeUnit(int16_t aPaperSizeUnit); - nsresult GetPlexName(PRUnichar **aPlexName); - nsresult SetPlexName(const PRUnichar *aPlexName); - nsresult GetColorspace(PRUnichar **aColorspace); - nsresult SetColorspace(const PRUnichar *aColorspace); - nsresult GetResolutionName(PRUnichar **aResolutionName); - nsresult SetResolutionName(const PRUnichar aResolutionName); - nsresult GetDownloadFonts(bool *aDownloadFonts); - nsresult SetDownloadFonts(bool aDownloadFonts); nsresult GetPrintReversed(bool *aPrintReversed); nsresult SetPrintReversed(bool aPrintReversed); nsresult GetPrintInColor(bool *aPrintInColor); nsresult SetPrintInColor(bool aPrintInColor); nsresult GetOrientation(int32_t *aOrientation); nsresult SetOrientation(int32_t aOrientation); - nsresult GetPrintCommand(PRUnichar **aPrintCommand); - nsresult SetPrintCommand(const PRUnichar *aPrintCommand); nsresult GetNumCopies(int32_t *aNumCopies); nsresult SetNumCopies(int32_t aNumCopies); nsresult GetPrinterName(PRUnichar **aPrinterName); @@ -2599,7 +2557,7 @@ [ object, - uuid(dfb5a307-7ecf-41dd-aee2-f1d623459c44), + uuid(2fa6884a-ae65-412a-9d4c-ce6e34544ba1), local ] interface nsIFile : nsISupports @@ -2625,6 +2583,7 @@ nsresult MoveTo(nsIFile *newParentDir, const nsAString *newName); nsresult MoveToNative(nsIFile *newParentDir, const nsAString *newName); nsresult RenameTo(nsIFile *newParentDir, const nsAString *newName); + nsresult RenameToNative(nsIFile *newParentDir, const nsACString *newName); nsresult Remove(bool recursive); nsresult GetPermissions(uint32_t *aPermissions); nsresult SetPermissions(uint32_t pPermissions); @@ -2673,6 +2632,8 @@ nsresult Launch(); nsresult GetRelativeDescriptor(nsIFile *fromFile, nsACString *_retval); nsresult SetRelativeDescriptor(nsIFile *fromFile, const nsACString *relativeDesc); + nsresult GetRelativePath(nsIFile *fromFile, nsACString *_retval); + nsresult SetRelativePath(nsIFile *fromFile, const nsACString *relativeDesc); } [ @@ -2745,7 +2706,7 @@ [ object, - uuid(a7aad716-e72c-435d-82f1-7582dffae661), + uuid(a87210e6-7c8c-41f7-864d-df809015193e), local ] interface nsIProtocolHandler : nsISupports @@ -2770,6 +2731,7 @@ const unsigned long URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM = (1<<16); const unsigned long URI_SYNC_LOAD_IS_OK = (1<<17); const unsigned long URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT = (1<<18); + const unsigned long URI_FETCHABLE_BY_ANYONE = (1 << 19); nsresult GetScheme(nsACString *aScheme); nsresult GetDefaultPort(int32_t *aDefaultPort); @@ -2793,6 +2755,20 @@ [ object, + uuid(d13c21ca-7329-45a5-8912-9d2e2fef1231), + local +] +interface nsIIOServiceHook : nsISupports +{ + nsresult NewChannel(nsIURI *aURI, nsILoadInfo *aLoadInfo, nsIChannel **_retval); + nsresult GetProtocolHandler(nsIProtocolHandler *aHandler, nsIProtocolHandler **_retval); + nsresult NewURI(const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval); + nsresult ProtocolHasFlags(nsIURI *aURI, uint32_t aFlag, bool *_retval); + nsresult URIChainHasFlags(nsIURI *aURI, uint32_t aFlags, bool *_retval); +} + +[ + object, uuid(4286de5a-b2ea-446f-8f70-e2a461f42694), local ] @@ -2821,28 +2797,7 @@ nsresult GetAppOfflineState(uint32_t appId, int32_t *_retval); nsresult AllowPort(int32_t aPort, const char *aScheme, bool *_retval); nsresult ExtractScheme(const nsACString *urlString, nsACString *_retval); - nsresult NewLoadInfo(nsIPrincipal *aLoadingPrincipal, nsIPrincipal *aTriggeringPrincipal, - nsIDOMNode *aLoadingNode, uint32_t aSecurityFlags, uint32_t aContentPolicyType, nsILoadInfo **_retval); -} - -[ - object, - uuid(ca68c485-9db3-4c12-82a6-4fab7948e2d5), - local, -] -interface nsINetUtil : nsISupports -{ - nsresult ParseContentType(const nsACString *aTypeHeader, nsACString *aCharset, - bool *aHadCharset, nsACString *_retval); - nsresult ProtocolHasFlags(nsIURI *aURI, uint32_t aFlag, bool *_retval); - nsresult URIChainHasFlags(nsIURI *aURI, uint32_t aFlags, bool *_retval); - nsresult ToImmutableURI(nsIURI *aURI, nsIURI **_retval); - nsresult NewSimpleNestedURI(nsIURI *aURI, nsIURI **_retval); - nsresult EscapeString(const nsACString *aString, uint32_t aEscapeType, nsACString *_retval); - nsresult EscapeURL(const nsACString *aStr, uint32_t aFlags, nsACString *_retval); - nsresult UnescapeString(const nsACString *aStr, uint32_t aFlags, nsACString *_retval); - nsresult ExtractCharsetFromContentType(const nsACString *aTypeHeader, nsACString *aCharset, - int32_t *aCharsetStart, int32_t *aCharsetEnd, bool *_retval); + nsresult SetHook(nsIIOServiceHook *aHook); } [ @@ -2909,7 +2864,7 @@ [ object, - uuid(02d54f52-a1f5-4ad2-b560-36f14012935e), + uuid(63857daf-c084-4ea6-a8b9-6812e3176991), local ] interface nsIDOMEvent : nsISupports @@ -2939,11 +2894,12 @@ bool Deserialize(const /*IPC::Message*/ void *aMsg, void **aIter); void SetOwner(void /*mozilla::dom::EventTarget*/ *aOwner); void /*nsDOMEvent*/ *InternalDOMEvent(); + nsresult StopCrossProcessForwarding(); } [ object, - uuid(1a75c351-d115-4d51-94df-731dd1723a1f), + uuid(a30a95ac-3b95-4251-88dc-8efa89ba9f9c), local ] interface nsIDOMWindowUtils : nsISupports @@ -2955,13 +2911,12 @@ nsresult GetDocumentMetadata(const nsAString *aName, nsAString *_retval); nsresult Redraw(uint32_t aCount, uint32_t *_retval); nsresult UpdateLayerTree(); - nsresult SetCSSViewport(float aWidthPx, float aHeightPx); nsresult GetViewportInfo(uint32_t aDisplayWidth, uint32_t aDisplayHeight, double *aDefaultZoom, bool *aAllowZoom, double *aMinZoom, double *aMaxZoom, uint32_t *aWidth, uint32_t *aHeight, bool *aAutoSize); nsresult SetDisplayPortForElement(float aXPx, float aYPx, float aWidthPx, float aHeightPx, nsIDOMElement *aElement, uint32_t aPriority); nsresult SetDisplayPortMarginsForElement(float aLeftMargin, float aTopMargin, float aRightMargin, float aBottomMargin, - uint32_t aAlignmentX, uint32_t aAlignmentY, nsIDOMElement *aElement, uint32_t aPriority); + nsIDOMElement *aElement, uint32_t aPriority); nsresult SetDisplayPortBaseForElement(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, nsIDOMElement *aElement); nsresult SetResolution(float aResolution); nsresult GetResolution(float *aResolution); @@ -3037,8 +2992,9 @@ nsresult SendContentCommandEvent(const nsAString *aType, nsITransferable *aTransferable); nsresult SendQueryContentEvent(uint32_t aType, uint32_t aOffset, uint32_t aLength, int32_t aX, int32_t aY, uint32_t aAdditionalFlags, nsIQueryContentEventResult **_retval); - nsresult RemoteFrameFullscreenChanged(nsIDOMElement *aFrameElement, const nsAString *aNewOrigin); + nsresult RemoteFrameFullscreenChanged(nsIDOMElement *aFrameElement); nsresult RemoteFrameFullscreenReverted(); + nsresult HandleFullscreenRequests(bool *_retval); nsresult ExitFullscreen(); nsresult SendSelectionSetEvent(uint32_t aOffset, uint32_t aLength, uint32_t aAdditionalFlags, bool *_retval); nsresult SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior, bool *_retval); @@ -3054,7 +3010,7 @@ nsresult ResumeTimeouts(); nsresult GetLayerManagerType(nsAString *aLayerManagerType); nsresult GetLayerManagerRemote(bool *aLayerManagerRemote); - nsresult GetSupportsHardwareH264Decoding(bool *aSupportsHardwareH264Decoding); + nsresult GetSupportsHardwareH264Decoding(nsAString *aSupportsHardwareH264Decoding); nsresult StartFrameTimeRecording(uint32_t *startIndex); nsresult StopFrameTimeRecording(uint32_t startIndex, uint32_t *frameCount, float **frameIntervals); nsresult BeginTabSwitch(); @@ -3066,10 +3022,13 @@ nsresult AdvanceTimeAndRefresh(int64_t aMilliseconds); nsresult RestoreNormalRefresh(); nsresult GetIsTestControllingRefreshes(bool *aIsTestControllingRefreshes); + nsresult GetAsyncPanZoomEnabled(bool *aAsyncPanZoomEnabled); nsresult SetAsyncScrollOffset(nsIDOMNode *aNode, int32_t aX, int32_t aY); + nsresult SetAsyncZoom(nsIDOMNode *aRootElement, float aValue); + nsresult FlushApzRepaints(bool *_retval); nsresult ComputeAnimationDistance(nsIDOMElement *element, const nsAString *property, const nsAString *value1, const nsAString *value2, double *_retval); - nsresult WrapDOMFile(nsIFile *aFile, nsIDOMFile **_retval); + nsresult WrapDOMFile(nsIFile *aFile, nsISupports **_retval); nsresult GetFocusedInputType(char **aFocusedInputType); nsresult FindElementWithViewId(long /*nsViewID*/ aId, nsIDOMElement **_retval); nsresult GetViewId(nsIDOMElement *aElement, long /*nsViewID*/ *_retval); @@ -3081,6 +3040,7 @@ nsresult GetFilePath(void /*JS::HandleValue*/ *aFile, JSContext *cx, nsAString *_retval); nsresult GetFileReferences(const nsAString *aDatabaseName, int64_t aId, void /*JS::HandleValue*/ *aOptions, int32_t *aRefCnt, int32_t *aDBRefCnt, int32_t *aSliceRefCnt, JSContext* cx, bool *_retval); + nsresult FlushPendingFileDeletions(); nsresult IsIncrementalGCEnabled(JSContext *cx, bool *_retval); nsresult StartPCCountProfiling(JSContext *cx); nsresult StopPCCountProfiling(JSContext *cx); @@ -3091,7 +3051,6 @@ nsresult GetPaintingSuppressed(bool *aPaintingSuppressed); nsresult GetPlugins(JSContext *cx, /*JS::Value*/ void *aPlugins); nsresult SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight); - nsresult SetContentDocumentFixedPositionMargins(float aTop, float aRight, float aBottom, float aLeft); nsresult DisableDialogs(); nsresult EnableDialogs(); nsresult AreDialogsEnabled(bool *_retval); @@ -3106,9 +3065,8 @@ nsresult IsNodeDisabledForEvents(nsIDOMNode *aNode, bool *_retval); nsresult GetPaintFlashing(bool *aPaintFlashing); nsresult SetPaintFlashing(bool aPaintFlashing); - nsresult RunInStableState(nsIRunnable *runnable); - nsresult RunBeforeNextEvent(nsIRunnable *runnable); - nsresult GetOMTAStyle(nsIDOMElement *aElement, const nsAString *aProperty, nsAString *_retval); + nsresult GetOMTAStyle(nsIDOMElement *aElement, const nsAString *aProperty, + const nsAString *aPseudoElement, nsAString *_retval); nsresult RequestCompositorProperty(const nsAString *aProperty, float *_retval); nsresult SetHandlingUserInput(bool aHandlingInput, void /*nsIJSRAIIHelper*/ **_retval); nsresult GetContentAPZTestData(JSContext *cx, int /*JS::MutableHandleValue*/ _retval); @@ -3125,6 +3083,12 @@ nsresult SetChromeMargin(int32_t aTop, int32_t aRight, int32_t aBottom, int32_t aLeft); nsresult GetServiceWorkersTestingEnabled(bool *aServiceWorkersTestingEnabled); nsresult SetServiceWorkersTestingEnabled(bool aServiceWorkersTestingEnabled); + nsresult GetFrameUniformityTestData(JSContext* cx, int /*JS::MutableHandleValue*/ *_retval); + nsresult EnterChaosMode(); + nsresult LeaveChaosMode(); + nsresult HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType, bool *_retval); + nsresult ForceUseCounterFlush(nsIDOMNode *aNode); + nsresult SetNextPaintSyncId(int32_t aSyncId); } cpp_quote("#define CONTEXT_NONE 0x00") @@ -3416,7 +3380,7 @@ [ object, - uuid(70f7e9ea-a9bf-48cc-ad9d-8acaeed29b68), + uuid(8e1bab9d-8815-4d2c-a24d-7aba5239dc22), local ] interface nsIContent : nsISupports @@ -3426,7 +3390,7 @@ [ object, - uuid(0b78eabe-8b94-4ea1-9331-5d48e83ada95), + uuid(5f51e18c-9e0e-4dc0-9f08-7a326552ea11), local ] interface nsIDocument : nsISupports @@ -3739,7 +3703,7 @@ [ object, - uuid(c63e9d64-490d-48bf-8013-b5d8ee4dbc25), + uuid(e7570e5a-f1d6-452d-b4f8-b35fdc63aa03), local ] interface nsIDocShellLoadInfo : nsISupports @@ -3749,6 +3713,10 @@ nsresult GetReferrer(nsIURI **aReferrer); nsresult SetReferrer(nsIURI *aReferrer); + nsresult GetOriginalURI(nsIURI **aOriginalURI); + nsresult SetOriginalURI(nsIURI *aOriginalURI); + nsresult GetLoadReplace(bool *aLoadReplace); + nsresult SetLoadReplace(bool aLoadReplace); nsresult GetOwner(nsISupports **aOwner); nsresult SetOwner(nsISupports *aOwner); nsresult GetInheritOwner(bool *aInheritOwner); @@ -3780,7 +3748,7 @@ [ object, - uuid(696b32a1-3cf1-4909-b501-474b25fc7954), + uuid(44aca825-0080-49f1-8407-df62183e5ec1), local ] interface nsIDocShell : nsIDocShellTreeItem @@ -3788,11 +3756,12 @@ nsresult LoadURI(nsIURI *uri, nsIDocShellLoadInfo *loadInfo, uint32_t aLoadFlags, bool firstParty); nsresult LoadStream(nsIInputStream *aStream, nsIURI *aURI, const nsACString *aContentType, const nsACString *aContentCharset, nsIDocShellLoadInfo *aLoadInfo); - nsresult InternalLoad(nsIURI *aURI, nsIURI *aReferrer, uint32_t aReferrerPolicy, nsISupports *aOwner, - uint32_t aFlags, const PRUnichar *aWindowTarget, const char *aTypeHint, nsACString *aFileName, - nsIInputStream *aPostDataStream, nsIInputStream *aHeadersStream, uint32_t aLoadFlags, - nsISHEntry *aSHEntry, bool firstParty, const nsAString *aSrcdoc, nsIDocShell *aSourceDocShell, - nsIURI *aBaseURI, nsIDocShell **aDocShell, nsIRequest **aRequest); + nsresult InternalLoad(nsIURI *aURI, nsIURI *aOriginalURI, bool aLoadReplace, nsIURI *aReferrer, + uint32_t aReferrerPolicy, nsISupports *aOwner, uint32_t aFlags, const PRUnichar *aWindowTarget, + const char *aTypeHint, nsACString *aFileName, nsIInputStream *aPostDataStream, + nsIInputStream *aHeadersStream, uint32_t aLoadFlags, nsISHEntry *aSHEntry, bool firstParty, + const nsAString *aSrcdoc, nsIDocShell *aSourceDocShell, nsIURI *aBaseURI, nsIDocShell **aDocShell, + nsIRequest **aRequest); nsresult AddState(jsval *aData, const nsAString *aTitle, const nsAString *aURL, bool aReplace, JSContext *cx); nsresult CreateLoadInfo(nsIDocShellLoadInfo **loadInfo); nsresult PrepareForNewContentModel(); @@ -3837,7 +3806,7 @@ nsresult SetMarginWidth(int32_t aMarginWidth); nsresult GetMarginHeight(int32_t *aMarginHeight); nsresult SetMarginHeight(int32_t aMarginHeight); - nsresult TabToTreeOwner(bool forward, bool *tookFocus); + nsresult TabToTreeOwner(bool forward, bool forDocumentNavigation, bool *_retval); nsresult GetBusyFlags(uint32_t *aBusyFlags); nsresult GetLoadType(uint32_t *aLoadType); nsresult SetLoadType(uint32_t aLoadType); @@ -3857,7 +3826,7 @@ nsresult GetRestoringDocument(bool *aRestoringDocument); nsresult GetUseErrorPages(bool *aUseErrorPages); nsresult SetUseErrorPages(bool aUseErrorPages); - nsresult DisplayLoadError(nsresult aError, nsIURI *aURI, const PRUnichar *aURL, nsIChannel *aFailedChannel); + nsresult DisplayLoadError(nsresult aError, nsIURI *aURI, const PRUnichar *aURL, nsIChannel *aFailedChannel, bool *_retval); nsresult GetFailedChannel(nsIChannel **aFailedChannel); nsresult GetPreviousTransIndex(int32_t *aPreviousTransIndex); nsresult GetLoadedTransIndex(int32_t *aLoadedTransIndex); @@ -3893,8 +3862,8 @@ nsresult GatherCharsetMenuTelemetry(); nsresult GetForcedCharset(nsIAtom **aForcedCharset); nsresult SetForcedCharset(nsIAtom *aForcedCharset); - void SetParentCharset(const nsACString *parentCharset, int32_t parentCharsetSource, nsIPrincipal *parentCharsetPrincipal); - void GetParentCharset(nsACString *parentCharset, int32_t *parentCharsetSource, nsIPrincipal **parentCharsetPrincipal); + void /* thiscall */ SetParentCharset(const nsACString *parentCharset, int32_t parentCharsetSource, nsIPrincipal *parentCharsetPrincipal); + void /* thiscall */ GetParentCharset(nsACString *parentCharset, int32_t *parentCharsetSource, nsIPrincipal **parentCharsetPrincipal); nsresult GetRecordProfileTimelineMarkers(bool *aRecordProfileTimelineMarkers); nsresult SetRecordProfileTimelineMarkers(bool aRecordProfileTimelineMarkers); nsresult Now(int /* DOMHighResTimeStamp */ *_retval); @@ -3916,18 +3885,21 @@ nsresult GetAppId(uint32_t *aAppId); nsresult GetAppManifestURL(nsAString *aAppManifestURL); nsresult GetSameTypeParentIgnoreBrowserAndAppBoundaries(nsIDocShell **_retval); + nsresult GetSameTypeRootTreeItemIgnoreBrowserAndAppBoundaries(nsIDocShell **_retval); nsresult GetAsyncPanZoomEnabled(bool *aAsyncPanZoomEnabled); nsresult GetSandboxFlags(uint32_t *aSandboxFlags); nsresult SetSandboxFlags(uint32_t aSandboxFlags); nsresult GetOnePermittedSandboxedNavigator(nsIDocShell **aOnePermittedSandboxedNavigator); nsresult SetOnePermittedSandboxedNavigator(nsIDocShell *aOnePermittedSandboxedNavigator); - bool IsSandboxedFrom(nsIDocShell *aTargetDocShell); + bool /* thiscall */ IsSandboxedFrom(nsIDocShell *aTargetDocShell); nsresult GetMixedContentChannel(nsIChannel **aMixedContentChannel); nsresult SetMixedContentChannel(nsIChannel *aMixedContentChannel); nsresult GetAllowMixedContentAndConnectionData(bool *rootHasSecureConnection, bool *allowMixedContent, bool *isRootDocShell); bool PluginsAllowedInCurrentDoc(); nsresult GetFullscreenAllowed(bool *aFullscreenAllowed); nsresult SetFullscreenAllowed(bool allowed); + uint32_t OrientationLock(); + void SetOrientationLock(uint32_t orientationLock); nsresult GetAffectPrivateSessionLifetime(bool *aAffectPrivateSessionLifetime); nsresult SetAffectPrivateSessionLifetime(bool aAffectPrivateSessionLifetime); nsresult GetMayEnableCharacterEncodingMenu(bool *aMayEnableCharacterEncodingMenu); @@ -3953,7 +3925,6 @@ nsresult SetDeviceSizeIsPageSize(bool aDeviceSizeIsPageSize); void /* thiscall */ SetOpener(void /*nsITabParent*/ *aOpener); void /* thiscall nsITabParent */ *GetOpener(); - void /*mozilla::dom::URLSearchParams */ *GetURLSearchParams(); void /* thiscall */ NotifyJSRunToCompletionStart(const char *aReason, const char16_t *functionName, const char16_t *fileName, uint32_t lineNumber); void /* thiscall */ NotifyJSRunToCompletionStop(); @@ -3966,19 +3937,22 @@ [ object, - uuid(16fe5e3e-eadc-4312-9d44-b6bedd6b5474), + uuid(6d674c17-0fbc-4633-8f46-734e87ebf0c7), local ] interface nsIMutationObserver : nsISupports { + typedef struct {} nsAttrValue; + void CharacterDataWillChange(nsIDocument *aDocument, nsIContent *aContent, void /*CharacterDataChangeInfo*/ *aInfo); void CharacterDataChanged(nsIDocument *aDocument, nsIContent *aContent, void /*CharacterDataChangeInfo*/ *aInfo); - void AttributeWillChange(nsIDocument *aDocument, nsIContent *aContent, int32_t aNameSpaceID, - nsIAtom *aAttribute, int32_t aModType); - void AttributeChanged(nsIDocument *aDocument, nsIContent *aContent, int32_t aNameSpaceID, - nsIAtom *aAttribute, int32_t aModType); + void AttributeWillChange(nsIDocument *aDocument, /*mozilla::dom::Element*/ void *aElement, int32_t aNameSpaceID, + nsIAtom *aAttribute, int32_t aModType, const nsAttrValue *aNewValue); + void AttributeChanged(nsIDocument *aDocument, /*mozilla::dom::Element*/ void *aElement, int32_t aNameSpaceID, + nsIAtom *aAttribute, int32_t aModType, const nsAttrValue *aOldValue); + void NativeAnonymousChildListChange(nsIDocument *aDocument, nsIContent *aContent, bool aIsRemove); void AttributeSetToCurrentValue(nsIDocument *aDocument, /*mozilla::dom::Element*/ void *aElement, int32_t aNameSpaceID, nsIAtom *aAttribute); void ContentAppended(nsIDocument *aDocument, nsIContent *aContainer, nsIContent *aFirstNewContent, @@ -4083,10 +4057,21 @@ [ object, + uuid(5fe83b24-38b9-4901-a4a1-d1bd57d3fe18), + local +] +interface nsIAudioChannelAgentCallback : nsISupports +{ + nsresult WindowVolumeChanged(float aVolume, bool aMuted); + nsresult WindowAudioCaptureChanged(); +} + +[ + object, uuid(8f672000-bab9-4c60-aaaf-2673c4e2a4c6), local ] -interface nsIPluginInstance : nsISupports +interface nsIPluginInstance : nsIAudioChannelAgentCallback { nsresult GetDOMElement(nsIDOMElement **aDOMElement); } @@ -4139,7 +4124,7 @@ [ object, - uuid(ba602ca6-dc7a-457e-a57a-ee5b343fd863), + uuid(b7ae2310-576e-11e5-a837-0800200c9a66), local ] interface nsIScriptSecurityManager : nsISupports { @@ -4149,7 +4134,7 @@ nsresult CheckLoadURIFromScript(JSContext *cx, nsIURI *uri); nsresult CheckLoadURIWithPrincipal(nsIPrincipal *aPrincipal, nsIURI *uri, uint32_t flags); nsresult CheckLoadURIStrWithPrincipal(nsIPrincipal *aPrincipal, const nsACString *uri, uint32_t flags); - nsresult ScriptAllowed(JSObject *aGlobal); + bool ScriptAllowed(JSObject *aGlobal); nsresult GetSystemPrincipal(nsIPrincipal **_retval); nsresult GetSimpleCodebasePrincipal(nsIURI *aURI, nsIPrincipal **_retval); nsresult GetAppCodebasePrincipal(nsIURI *uri, uint32_t appId, bool inMozBrowser, nsIPrincipal **_retval); @@ -4157,6 +4142,10 @@ nsresult GetDocShellCodebasePrincipal(nsIURI *uri, nsIDocShell *docShell, nsIPrincipal **_retval); nsresult GetNoAppCodebasePrincipal(nsIURI *uri, nsIPrincipal **_retval); nsresult GetCodebasePrincipal(nsIURI *uri, nsIPrincipal **_retval); + nsresult CreateCodebasePrincipal(nsIURI *uri, int /*JS::HandleValue*/ originAttributes, JSContext* cx, nsIPrincipal **_retval); + nsresult CreateCodebasePrincipalFromOrigin(const nsACString *origin, nsIPrincipal **_retval); + nsresult CreateNullPrincipal(int /*JS::HandleValue*/ originAttributes, JSContext *cx, nsIPrincipal **_retval); + nsresult CreateExpandedPrincipal(nsIPrincipal **aPrincipalArray, uint32_t aLength, nsIPrincipal **_retval); nsresult CheckSameOriginURI(nsIURI *aSourceURI, nsIURI *aTargetURI, bool reportError); nsresult GetChannelResultPrincipal(nsIChannel *aChannel, nsIPrincipal **_retval); nsresult GetChannelURIPrincipal(nsIChannel *aChannel, nsIPrincipal **_retval); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/nsio.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/nsio.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/nsio.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/nsio.c 2016-02-08 19:32:34.000000000 +0000 @@ -48,7 +48,6 @@ {0x5088272e, 0x900b, 0x11da, {0xc6,0x87, 0x00,0x0f,0xea,0x57,0xf2,0x1a}}; static nsIIOService *nsio = NULL; -static nsINetUtil *net_util; static const char *request_method_strings[] = {"GET", "PUT", "POST"}; @@ -897,6 +896,15 @@ return NS_ERROR_NOT_IMPLEMENTED; } +static nsresult NSAPI nsChannel_Open2(nsIHttpChannel *iface, nsIInputStream **_retval) +{ + nsChannel *This = impl_from_nsIHttpChannel(iface); + + FIXME("(%p)->(%p)\n", This, _retval); + + return NS_ERROR_NOT_IMPLEMENTED; +} + static HTMLOuterWindow *get_window_from_load_group(nsChannel *This) { HTMLOuterWindow *window; @@ -1163,6 +1171,13 @@ return nsres; } +static nsresult NSAPI nsChannel_AsyncOpen2(nsIHttpChannel *iface, nsIStreamListener *aListener) +{ + nsChannel *This = impl_from_nsIHttpChannel(iface); + FIXME("(%p)->(%p)\n", This, aListener); + return nsIHttpChannel_AsyncOpen(&This->nsIHttpChannel_iface, aListener, NULL); +} + static nsresult NSAPI nsChannel_GetContentDisposition(nsIHttpChannel *iface, UINT32 *aContentDisposition) { nsChannel *This = impl_from_nsIHttpChannel(iface); @@ -1318,6 +1333,13 @@ return set_channel_http_header(&This->request_headers, aHeader, aValue); } +static nsresult NSAPI nsChannel_SetEmptyRequestHeader(nsIHttpChannel *iface, const nsACString *aHeader) +{ + nsChannel *This = impl_from_nsIHttpChannel(iface); + FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aHeader)); + return NS_ERROR_NOT_IMPLEMENTED; +} + static nsresult NSAPI nsChannel_VisitRequestHeaders(nsIHttpChannel *iface, nsIHttpHeaderVisitor *aVisitor) { @@ -1328,6 +1350,13 @@ return NS_ERROR_NOT_IMPLEMENTED; } +static nsresult NSAPI nsChannel_VisitNonDefaultRequestHeaders(nsIHttpChannel *iface, nsIHttpHeaderVisitor *aVisitor) +{ + nsChannel *This = impl_from_nsIHttpChannel(iface); + FIXME("(%p)->(%p)\n", This, aVisitor); + return NS_ERROR_NOT_IMPLEMENTED; +} + static nsresult NSAPI nsChannel_GetAllowPipelining(nsIHttpChannel *iface, cpp_bool *aAllowPipelining) { nsChannel *This = impl_from_nsIHttpChannel(iface); @@ -1419,6 +1448,20 @@ return NS_OK; } +static nsresult NSAPI nsChannel_GetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool *aIsMainDocumentChannel) +{ + nsChannel *This = impl_from_nsIHttpChannel(iface); + FIXME("(%p)->(%p)\n", This, aIsMainDocumentChannel); + return NS_ERROR_NOT_IMPLEMENTED; +} + +static nsresult NSAPI nsChannel_SetIsMainDocumentChannel(nsIHttpChannel *iface, cpp_bool aIsMainDocumentChannel) +{ + nsChannel *This = impl_from_nsIHttpChannel(iface); + FIXME("(%p)->(%x)\n", This, aIsMainDocumentChannel); + return NS_ERROR_NOT_IMPLEMENTED; +} + static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface, const nsACString *header, nsACString *_retval) { @@ -1491,6 +1534,24 @@ return NS_ERROR_NOT_IMPLEMENTED; } +static nsresult NSAPI nsHttpChannel_GetSchedulingContextID(nsIHttpChannel *iface, nsIID *aSchedulingContextID) +{ + nsChannel *This = impl_from_nsIHttpChannel(iface); + + FIXME("(%p)->(%p)\n", This, aSchedulingContextID); + + return NS_ERROR_NOT_IMPLEMENTED; +} + +static nsresult NSAPI nsHttpChannel_SetSchedulingContextID(nsIHttpChannel *iface, const nsIID aSchedulingContextID) +{ + nsChannel *This = impl_from_nsIHttpChannel(iface); + + FIXME("(%p)->(%s)\n", This, debugstr_guid(&aSchedulingContextID)); + + return NS_ERROR_NOT_IMPLEMENTED; +} + static const nsIHttpChannelVtbl nsChannelVtbl = { nsChannel_QueryInterface, nsChannel_AddRef, @@ -1520,7 +1581,9 @@ nsChannel_GetContentLength, nsChannel_SetContentLength, nsChannel_Open, + nsChannel_Open2, nsChannel_AsyncOpen, + nsChannel_AsyncOpen2, nsChannel_GetContentDisposition, nsChannel_SetContentDisposition, nsChannel_GetContentDispositionFilename, @@ -1536,7 +1599,9 @@ nsChannel_SetReferrerWithPolicy, nsChannel_GetRequestHeader, nsChannel_SetRequestHeader, + nsChannel_SetEmptyRequestHeader, nsChannel_VisitRequestHeaders, + nsChannel_VisitNonDefaultRequestHeaders, nsChannel_GetAllowPipelining, nsChannel_SetAllowPipelining, nsChannel_GetAllowTLS, @@ -1546,13 +1611,17 @@ nsChannel_GetResponseStatus, nsChannel_GetResponseStatusText, nsChannel_GetRequestSucceeded, + nsChannel_GetIsMainDocumentChannel, + nsChannel_SetIsMainDocumentChannel, nsChannel_GetResponseHeader, nsChannel_SetResponseHeader, nsChannel_VisitResponseHeaders, nsChannel_IsNoStoreResponse, nsChannel_IsNoCacheResponse, nsChannel_IsPrivateResponse, - nsChannel_RedirectTo + nsChannel_RedirectTo, + nsHttpChannel_GetSchedulingContextID, + nsHttpChannel_SetSchedulingContextID }; static inline nsChannel *impl_from_nsIUploadChannel(nsIUploadChannel *iface) @@ -1872,6 +1941,22 @@ return NS_ERROR_NOT_IMPLEMENTED; } +static nsresult NSAPI nsHttpChannelInternal_GetInitialRwin(nsIHttpChannelInternal *iface, + UINT32 *aInitialRwin) +{ + nsChannel *This = impl_from_nsIHttpChannelInternal(iface); + FIXME("(%p)->(%p)\n", This, aInitialRwin); + return NS_ERROR_NOT_IMPLEMENTED; +} + +static nsresult NSAPI nsHttpChannelInternal_SetInitialRwin(nsIHttpChannelInternal *iface, + UINT32 aInitialRwin) +{ + nsChannel *This = impl_from_nsIHttpChannelInternal(iface); + FIXME("(%p)->(%x)\n", This, aInitialRwin); + return NS_ERROR_NOT_IMPLEMENTED; +} + static nsresult NSAPI nsHttpChannelInternal_GetApiRedirectToURI(nsIHttpChannelInternal *iface, nsIURI **aApiRedirectToURI) { nsChannel *This = impl_from_nsIHttpChannelInternal(iface); @@ -1893,24 +1978,24 @@ return NS_ERROR_NOT_IMPLEMENTED; } -static nsresult NSAPI nsHttpChannelInternal_AddRedirect(nsIHttpChannelInternal *iface, nsIPrincipal *aPrincipal) +static nsresult NSAPI nsHttpChannelInternal_GetLastModifiedTime(nsIHttpChannelInternal *iface, PRTime *aLastModifiedTime) { nsChannel *This = impl_from_nsIHttpChannelInternal(iface); - FIXME("(%p)->(%p)\n", This, aPrincipal); + FIXME("(%p)->(%p)\n", This, aLastModifiedTime); return NS_ERROR_NOT_IMPLEMENTED; } -static nsresult NSAPI nsHttpChannelInternal_GetLastModifiedTime(nsIHttpChannelInternal *iface, PRTime *aLastModifiedTime) +static nsresult NSAPI nsHttpChannelInternal_ForceIntercepted(nsIHttpChannelInternal *iface, UINT64 aInterceptionID) { nsChannel *This = impl_from_nsIHttpChannelInternal(iface); - FIXME("(%p)->(%p)\n", This, aLastModifiedTime); + FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aInterceptionID)); return NS_ERROR_NOT_IMPLEMENTED; } -static nsresult NSAPI nsHttpChannelInternal_ForceNoIntercept(nsIHttpChannelInternal *iface) +static nsresult NSAPI nsHttpChannelInternal_GetResponseSynthesized(nsIHttpChannelInternal *iface, cpp_bool *ResponseSynthesized) { nsChannel *This = impl_from_nsIHttpChannelInternal(iface); - FIXME("(%p)\n", This); + FIXME("(%p, %p)\n", This, ResponseSynthesized); return NS_ERROR_NOT_IMPLEMENTED; } @@ -1944,6 +2029,20 @@ return NS_OK; } +static nsresult NSAPI nsHttpChannelInternal_GetRedirectMode(nsIHttpChannelInternal *iface, UINT32 *aRedirectMode) +{ + nsChannel *This = impl_from_nsIHttpChannelInternal(iface); + FIXME("(%p)->(%p)\n", This, aRedirectMode); + return NS_ERROR_NOT_IMPLEMENTED; +} + +static nsresult NSAPI nsHttpChannelInternal_SetRedirectMode(nsIHttpChannelInternal *iface, UINT32 aRedirectMode) +{ + nsChannel *This = impl_from_nsIHttpChannelInternal(iface); + FIXME("(%p)->(%d)\n", This, aRedirectMode); + return NS_ERROR_NOT_IMPLEMENTED; +} + static nsresult NSAPI nsHttpChannelInternal_GetTopWindowURI(nsIHttpChannelInternal *iface, nsIURI **aTopWindowURI) { nsChannel *This = impl_from_nsIHttpChannelInternal(iface); @@ -1967,17 +2066,18 @@ return NS_ERROR_NOT_IMPLEMENTED; } -static nsresult NSAPI nsHttpChannelInternal_ContinueBeginConnect(nsIHttpChannelInternal *iface) +static nsresult NSAPI nsHttpChannelInternal_GetProxyURI(nsIHttpChannelInternal *iface, nsIURI **aProxyURI) { nsChannel *This = impl_from_nsIHttpChannelInternal(iface); - FIXME("(%p)\n", This); + FIXME("(%p)->(%p)\n", This, aProxyURI); return NS_ERROR_NOT_IMPLEMENTED; } -static nsresult NSAPI nsHttpChannelInternal_GetProxyURI(nsIHttpChannelInternal *iface, nsIURI **aProxyURI) +static nsresult NSAPI nsHttpChannelInternal_SetCorsPreflightParameters(nsIHttpChannelInternal *iface, + const void /*nsTArray*/ *unsafeHeaders, cpp_bool withCredentials, nsIPrincipal *preflightPrincipal) { nsChannel *This = impl_from_nsIHttpChannelInternal(iface); - FIXME("(%p)->(%p)\n", This, aProxyURI); + FIXME("(%p %p %x %p)\n", This, unsafeHeaders, withCredentials, preflightPrincipal); return NS_ERROR_NOT_IMPLEMENTED; } @@ -2009,21 +2109,25 @@ nsHttpChannelInternal_SetAllowSpdy, nsHttpChannelInternal_GetResponseTimeoutEnabled, nsHttpChannelInternal_SetResponseTimeoutEnabled, + nsHttpChannelInternal_GetInitialRwin, + nsHttpChannelInternal_SetInitialRwin, nsHttpChannelInternal_GetApiRedirectToURI, nsHttpChannelInternal_GetAllowAltSvc, nsHttpChannelInternal_SetAllowAltSvc, - nsHttpChannelInternal_AddRedirect, nsHttpChannelInternal_GetLastModifiedTime, - nsHttpChannelInternal_ForceNoIntercept, + nsHttpChannelInternal_ForceIntercepted, + nsHttpChannelInternal_GetResponseSynthesized, nsHttpChannelInternal_GetCorsIncludeCredentials, nsHttpChannelInternal_SetCorsIncludeCredentials, nsHttpChannelInternal_GetCorsMode, nsHttpChannelInternal_SetCorsMode, + nsHttpChannelInternal_GetRedirectMode, + nsHttpChannelInternal_SetRedirectMode, nsHttpChannelInternal_GetTopWindowURI, nsHttpChannelInternal_GetNetworkInterfaceId, nsHttpChannelInternal_SetNetworkInterfaceId, - nsHttpChannelInternal_ContinueBeginConnect, - nsHttpChannelInternal_GetProxyURI + nsHttpChannelInternal_GetProxyURI, + nsHttpChannelInternal_SetCorsPreflightParameters }; @@ -2711,6 +2815,15 @@ return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aAsciiSpec); } +static nsresult NSAPI nsURI_GetAsciiHostPort(nsIFileURL *iface, nsACString *aAsciiHostPort) +{ + nsWineURI *This = impl_from_nsIFileURL(iface); + + WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHostPort); + + return nsIFileURL_GetAsciiHostPort(&This->nsIFileURL_iface, aAsciiHostPort); +} + static nsresult NSAPI nsURI_GetAsciiHost(nsIFileURL *iface, nsACString *aAsciiHost) { nsWineURI *This = impl_from_nsIFileURL(iface); @@ -3123,6 +3236,7 @@ nsURI_Clone, nsURI_Resolve, nsURI_GetAsciiSpec, + nsURI_GetAsciiHostPort, nsURI_GetAsciiHost, nsURI_GetOriginCharset, nsURL_GetRef, @@ -3506,38 +3620,78 @@ nsProtocolHandler_AllowPort }; -static nsresult NSAPI nsIOService_QueryInterface(nsIIOService*,nsIIDRef,void**); +static nsresult NSAPI nsIOServiceHook_QueryInterface(nsIIOServiceHook *iface, nsIIDRef riid, + void **result) +{ + if(IsEqualGUID(&IID_nsISupports, riid)) { + TRACE("(IID_nsISupports %p)\n", result); + *result = iface; + }else if(IsEqualGUID(&IID_nsIIOServiceHook, riid)) { + TRACE("(IID_nsIIOServiceHook %p)\n", result); + *result = iface; + }else { + ERR("(%s %p)\n", debugstr_guid(riid), result); + *result = NULL; + return NS_NOINTERFACE; + } + + nsISupports_AddRef((nsISupports*)*result); + return NS_OK; +} -static nsrefcnt NSAPI nsIOService_AddRef(nsIIOService *iface) +static nsrefcnt NSAPI nsIOServiceHook_AddRef(nsIIOServiceHook *iface) { return 2; } -static nsrefcnt NSAPI nsIOService_Release(nsIIOService *iface) +static nsrefcnt NSAPI nsIOServiceHook_Release(nsIIOServiceHook *iface) { return 1; } -static nsresult NSAPI nsIOService_GetProtocolHandler(nsIIOService *iface, const char *aScheme, - nsIProtocolHandler **_retval) +static nsresult NSAPI nsIOServiceHook_NewChannel(nsIIOServiceHook *iface, nsIURI *aURI, + nsILoadInfo *aLoadInfo, nsIChannel **_retval) { - nsIExternalProtocolHandler *nsexthandler; - nsIProtocolHandler *nshandler; - nsProtocolHandler *ret; + nsWineURI *wine_uri; + nsChannel *ret; nsresult nsres; - TRACE("(%s %p)\n", debugstr_a(aScheme), _retval); + TRACE("(%p %p %p)\n", aURI, aLoadInfo, _retval); - nsres = nsIIOService_GetProtocolHandler(nsio, aScheme, &nshandler); + nsres = nsIURI_QueryInterface(aURI, &IID_nsWineURI, (void**)&wine_uri); if(NS_FAILED(nsres)) { - WARN("GetProtocolHandler failed: %08x\n", nsres); - return nsres; + TRACE("Could not get nsWineURI: %08x\n", nsres); + return NS_SUCCESS_DEFAULT_ACTION; } - nsres = nsIProtocolHandler_QueryInterface(nshandler, &IID_nsIExternalProtocolHandler, - (void**)&nsexthandler); + nsres = create_nschannel(wine_uri, &ret); + nsIFileURL_Release(&wine_uri->nsIFileURL_iface); + if(NS_FAILED(nsres)) + return nsres; + + nsIURI_AddRef(aURI); + ret->original_uri = aURI; + + if(aLoadInfo) + nsIHttpChannel_SetLoadInfo(&ret->nsIHttpChannel_iface, aLoadInfo); + + *_retval = (nsIChannel*)&ret->nsIHttpChannel_iface; + return NS_OK; +} + +static nsresult NSAPI nsIOServiceHook_GetProtocolHandler(nsIIOServiceHook *iface, nsIProtocolHandler *aHandler, + nsIProtocolHandler **_retval) +{ + nsIExternalProtocolHandler *nsexthandler; + nsProtocolHandler *ret; + nsresult nsres; + + TRACE("(%p %p)\n", aHandler, _retval); + + nsres = nsIProtocolHandler_QueryInterface(aHandler, &IID_nsIExternalProtocolHandler, (void**)&nsexthandler); if(NS_FAILED(nsres)) { - *_retval = nshandler; + nsIProtocolHandler_AddRef(aHandler); + *_retval = aHandler; return NS_OK; } @@ -3549,20 +3703,15 @@ ret->nsIProtocolHandler_iface.lpVtbl = &nsProtocolHandlerVtbl; ret->ref = 1; - ret->nshandler = nshandler; - *_retval = &ret->nsIProtocolHandler_iface; + nsIProtocolHandler_AddRef(aHandler); + ret->nshandler = aHandler; + + *_retval = &ret->nsIProtocolHandler_iface; TRACE("return %p\n", *_retval); return NS_OK; } -static nsresult NSAPI nsIOService_GetProtocolFlags(nsIIOService *iface, const char *aScheme, - UINT32 *_retval) -{ - TRACE("(%s %p)\n", debugstr_a(aScheme), _retval); - return nsIIOService_GetProtocolFlags(nsio, aScheme, _retval); -} - static BOOL is_gecko_special_uri(const char *spec) { static const char *special_schemes[] = {"chrome:", "data:", "jar:", "moz-safe-about", "resource:", "javascript:", "wyciwyg:"}; @@ -3583,7 +3732,7 @@ return FALSE; } -static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString *aSpec, +static nsresult NSAPI nsIOServiceHook_NewURI(nsIIOServiceHook *iface, const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval) { nsWineURI *wine_uri, *base_wine_uri = NULL; @@ -3600,7 +3749,7 @@ nsACString_GetData(aSpec, &spec); if(is_gecko_special_uri(spec)) - return nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, _retval); + return NS_SUCCESS_DEFAULT_ACTION; if(!strncmp(spec, "wine:", 5)) spec += 5; @@ -3643,7 +3792,7 @@ } if(FAILED(hres)) - return nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, _retval); + return NS_SUCCESS_DEFAULT_ACTION; nsres = create_nsuri(urlmon_uri, window, NULL, NULL, &wine_uri); IUri_Release(urlmon_uri); @@ -3656,192 +3805,6 @@ return nsres; } -static nsresult NSAPI nsIOService_NewFileURI(nsIIOService *iface, nsIFile *aFile, - nsIURI **_retval) -{ - TRACE("(%p %p)\n", aFile, _retval); - return nsIIOService_NewFileURI(nsio, aFile, _retval); -} - -static nsresult new_channel_from_uri(nsIURI *uri, nsILoadInfo *load_info, nsIChannel **_retval) -{ - nsWineURI *wine_uri; - nsChannel *ret; - nsresult nsres; - - nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri); - if(NS_FAILED(nsres)) { - TRACE("Could not get nsWineURI: %08x\n", nsres); - return nsIIOService_NewChannelFromURI(nsio, uri, _retval); - } - - nsres = create_nschannel(wine_uri, &ret); - nsIFileURL_Release(&wine_uri->nsIFileURL_iface); - if(NS_FAILED(nsres)) - return nsres; - - nsIURI_AddRef(uri); - ret->original_uri = uri; - - if(load_info) - nsIHttpChannel_SetLoadInfo(&ret->nsIHttpChannel_iface, load_info); - - *_retval = (nsIChannel*)&ret->nsIHttpChannel_iface; - return NS_OK; -} - -static nsresult NSAPI nsIOService_NewChannelFromURI2(nsIIOService *iface, nsIURI *aURI, - nsIDOMNode *aLoadingNode, nsIPrincipal *aLoadingPrincipal, nsIPrincipal *aTriggeringPrincipal, - UINT32 aSecurityFlags, UINT32 aContentPolicyType, nsIChannel **_retval) -{ - nsILoadInfo *load_info = NULL; - nsresult nsres; - - TRACE("(%p %p %p %p %x %d %p)\n", aURI, aLoadingNode, aLoadingPrincipal, aTriggeringPrincipal, - aSecurityFlags, aContentPolicyType, _retval); - - if(aLoadingNode || aLoadingPrincipal) { - nsres = nsIIOService_NewLoadInfo(nsio, aLoadingPrincipal, aTriggeringPrincipal, aLoadingNode, - aSecurityFlags, aContentPolicyType, &load_info); - assert(nsres == NS_OK); - } - - nsres = new_channel_from_uri(aURI, load_info, _retval); - if(load_info) - nsISupports_Release(load_info); - return nsres; -} - -static nsresult NSAPI nsIOService_NewChannelFromURIWithLoadInfo(nsIIOService *iface, nsIURI *aURI, - nsILoadInfo *aLoadInfo, nsIChannel **_retval) -{ - TRACE("(%p %p %p)\n", aURI, aLoadInfo, _retval); - return new_channel_from_uri(aURI, aLoadInfo, _retval); -} - -static nsresult NSAPI nsIOService_NewChannelFromURI(nsIIOService *iface, nsIURI *aURI, - nsIChannel **_retval) -{ - TRACE("(%p %p)\n", aURI, _retval); - return new_channel_from_uri(aURI, NULL, _retval); -} - -static nsresult NSAPI nsIOService_NewChannel2(nsIIOService *iface, const nsACString *aSpec, - const char *aOriginCharset, nsIURI *aBaseURI, nsIDOMNode *aLoadingNode, nsIPrincipal *aLoadingPrincipal, - nsIPrincipal *aTriggeringPrincipal, UINT32 aSecurityFlags, UINT32 aContentPolicyType, nsIChannel **_retval) -{ - TRACE("(%s %s %p %p %p %p %x %d %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI, - aLoadingNode, aLoadingPrincipal, aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, _retval); - return nsIIOService_NewChannel2(nsio, aSpec, aOriginCharset, aBaseURI, aLoadingNode, aLoadingPrincipal, - aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, _retval); -} - -static nsresult NSAPI nsIOService_NewChannel(nsIIOService *iface, const nsACString *aSpec, - const char *aOriginCharset, nsIURI *aBaseURI, nsIChannel **_retval) -{ - TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI, _retval); - return nsIIOService_NewChannel(nsio, aSpec, aOriginCharset, aBaseURI, _retval); -} - -static nsresult NSAPI nsIOService_GetOffline(nsIIOService *iface, cpp_bool *aOffline) -{ - TRACE("(%p)\n", aOffline); - return nsIIOService_GetOffline(nsio, aOffline); -} - -static nsresult NSAPI nsIOService_SetOffline(nsIIOService *iface, cpp_bool aOffline) -{ - TRACE("(%x)\n", aOffline); - return nsIIOService_SetOffline(nsio, aOffline); -} - -static nsresult NSAPI nsIOService_GetConnectivity(nsIIOService *iface, cpp_bool *aConnectivity) -{ - TRACE("(%p)\n", aConnectivity); - return nsIIOService_GetConnectivity(nsio, aConnectivity); -} - -static nsresult NSAPI nsIOService_SetAppOffline(nsIIOService *iface, UINT32 appId, INT32 state) -{ - TRACE("(%d %x)\n", appId, state); - return nsIIOService_SetAppOffline(nsio, appId, state); -} - -static nsresult NSAPI nsIOService_IsAppOffline(nsIIOService *iface, UINT32 appId, cpp_bool *_retval) -{ - TRACE("(%u %p)\n", appId, _retval); - return nsIIOService_IsAppOffline(nsio, appId, _retval); -} - -static nsresult NSAPI nsIOService_GetAppOfflineState(nsIIOService *iface, UINT32 appId, INT32 *_retval) -{ - TRACE("(%d %p)\n", appId, _retval); - return nsIIOService_GetAppOfflineState(nsio, appId, _retval); -} - -static nsresult NSAPI nsIOService_AllowPort(nsIIOService *iface, LONG aPort, - const char *aScheme, cpp_bool *_retval) -{ - TRACE("(%d %s %p)\n", aPort, debugstr_a(aScheme), _retval); - return nsIIOService_AllowPort(nsio, aPort, debugstr_a(aScheme), _retval); -} - -static nsresult NSAPI nsIOService_ExtractScheme(nsIIOService *iface, const nsACString *urlString, - nsACString * _retval) -{ - TRACE("(%s %p)\n", debugstr_nsacstr(urlString), _retval); - return nsIIOService_ExtractScheme(nsio, urlString, _retval); -} - -static const nsIIOServiceVtbl nsIOServiceVtbl = { - nsIOService_QueryInterface, - nsIOService_AddRef, - nsIOService_Release, - nsIOService_GetProtocolHandler, - nsIOService_GetProtocolFlags, - nsIOService_NewURI, - nsIOService_NewFileURI, - nsIOService_NewChannelFromURI2, - nsIOService_NewChannelFromURIWithLoadInfo, - nsIOService_NewChannelFromURI, - nsIOService_NewChannel2, - nsIOService_NewChannel, - nsIOService_GetOffline, - nsIOService_SetOffline, - nsIOService_GetConnectivity, - nsIOService_SetAppOffline, - nsIOService_IsAppOffline, - nsIOService_GetAppOfflineState, - nsIOService_AllowPort, - nsIOService_ExtractScheme -}; - -static nsIIOService nsIOService = { &nsIOServiceVtbl }; - -static nsresult NSAPI nsNetUtil_QueryInterface(nsINetUtil *iface, nsIIDRef riid, - void **result) -{ - return nsIIOService_QueryInterface(&nsIOService, riid, result); -} - -static nsrefcnt NSAPI nsNetUtil_AddRef(nsINetUtil *iface) -{ - return 2; -} - -static nsrefcnt NSAPI nsNetUtil_Release(nsINetUtil *iface) -{ - return 1; -} - -static nsresult NSAPI nsNetUtil_ParseContentType(nsINetUtil *iface, const nsACString *aTypeHeader, - nsACString *aCharset, cpp_bool *aHadCharset, nsACString *aContentType) -{ - TRACE("(%s %p %p %p)\n", debugstr_nsacstr(aTypeHeader), aCharset, aHadCharset, aContentType); - - return nsINetUtil_ParseContentType(net_util, aTypeHeader, aCharset, aHadCharset, aContentType); -} - static const char *debugstr_protocol_flags(UINT32 flags) { switch(flags) { @@ -3866,169 +3829,43 @@ X(URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM); X(URI_SYNC_LOAD_IS_OK); X(URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT); + X(URI_FETCHABLE_BY_ANYONE); #undef X default: return wine_dbg_sprintf("%08x", flags); } } -static nsresult NSAPI nsNetUtil_ProtocolHasFlags(nsINetUtil *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval) +static nsresult NSAPI nsIOServiceHook_ProtocolHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval) { TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval); - - return nsINetUtil_ProtocolHasFlags(net_util, aURI, aFlags, _retval); + return NS_SUCCESS_DEFAULT_ACTION; } -static nsresult NSAPI nsNetUtil_URIChainHasFlags(nsINetUtil *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval) +static nsresult NSAPI nsIOServiceHook_URIChainHasFlags(nsIIOServiceHook *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval) { TRACE("(%p %s %p)\n", aURI, debugstr_protocol_flags(aFlags), _retval); if(aFlags == URI_DOES_NOT_RETURN_DATA) { *_retval = FALSE; - return NS_OK; - } - - return nsINetUtil_URIChainHasFlags(net_util, aURI, aFlags, _retval); -} - -static nsresult NSAPI nsNetUtil_ToImmutableURI(nsINetUtil *iface, nsIURI *aURI, nsIURI **_retval) -{ - TRACE("(%p %p)\n", aURI, _retval); - - return nsINetUtil_ToImmutableURI(net_util, aURI, _retval); -} - -static nsresult NSAPI nsNetUtil_NewSimpleNestedURI(nsINetUtil *iface, nsIURI *aURI, nsIURI **_retval) -{ - TRACE("(%p %p)\n", aURI, _retval); - - return nsINetUtil_NewSimpleNestedURI(net_util, aURI, _retval); -} - -static nsresult NSAPI nsNetUtil_EscapeString(nsINetUtil *iface, const nsACString *aString, - UINT32 aEscapeType, nsACString *_retval) -{ - TRACE("(%s %x %p)\n", debugstr_nsacstr(aString), aEscapeType, _retval); - - return nsINetUtil_EscapeString(net_util, aString, aEscapeType, _retval); -} - -static nsresult NSAPI nsNetUtil_EscapeURL(nsINetUtil *iface, const nsACString *aStr, UINT32 aFlags, - nsACString *_retval) -{ - TRACE("(%s %08x %p)\n", debugstr_nsacstr(aStr), aFlags, _retval); - - return nsINetUtil_EscapeURL(net_util, aStr, aFlags, _retval); -} - -static nsresult NSAPI nsNetUtil_UnescapeString(nsINetUtil *iface, const nsACString *aStr, - UINT32 aFlags, nsACString *_retval) -{ - TRACE("(%s %08x %p)\n", debugstr_nsacstr(aStr), aFlags, _retval); - - return nsINetUtil_UnescapeString(net_util, aStr, aFlags, _retval); -} - -static nsresult NSAPI nsNetUtil_ExtractCharsetFromContentType(nsINetUtil *iface, const nsACString *aTypeHeader, - nsACString *aCharset, LONG *aCharsetStart, LONG *aCharsetEnd, cpp_bool *_retval) -{ - TRACE("(%s %p %p %p %p)\n", debugstr_nsacstr(aTypeHeader), aCharset, aCharsetStart, - aCharsetEnd, _retval); - - return nsINetUtil_ExtractCharsetFromContentType(net_util, aTypeHeader, aCharset, aCharsetStart, aCharsetEnd, _retval); -} - -static const nsINetUtilVtbl nsNetUtilVtbl = { - nsNetUtil_QueryInterface, - nsNetUtil_AddRef, - nsNetUtil_Release, - nsNetUtil_ParseContentType, - nsNetUtil_ProtocolHasFlags, - nsNetUtil_URIChainHasFlags, - nsNetUtil_ToImmutableURI, - nsNetUtil_NewSimpleNestedURI, - nsNetUtil_EscapeString, - nsNetUtil_EscapeURL, - nsNetUtil_UnescapeString, - nsNetUtil_ExtractCharsetFromContentType -}; - -static nsINetUtil nsNetUtil = { &nsNetUtilVtbl }; - -static nsresult NSAPI nsIOService_QueryInterface(nsIIOService *iface, nsIIDRef riid, - void **result) -{ - *result = NULL; - - if(IsEqualGUID(&IID_nsISupports, riid)) - *result = &nsIOService; - else if(IsEqualGUID(&IID_nsIIOService, riid)) - *result = &nsIOService; - else if(IsEqualGUID(&IID_nsINetUtil, riid)) - *result = &nsNetUtil; - - if(*result) { - nsISupports_AddRef((nsISupports*)*result); - return NS_OK; - } - - FIXME("(%s %p)\n", debugstr_guid(riid), result); - return NS_NOINTERFACE; -} - -static nsresult NSAPI nsIOServiceFactory_QueryInterface(nsIFactory *iface, nsIIDRef riid, - void **result) -{ - *result = NULL; - - if(IsEqualGUID(&IID_nsISupports, riid)) { - TRACE("(IID_nsISupports %p)\n", result); - *result = iface; - }else if(IsEqualGUID(&IID_nsIFactory, riid)) { - TRACE("(IID_nsIFactory %p)\n", result); - *result = iface; - } - - if(*result) { - nsIFactory_AddRef(iface); - return NS_OK; + return S_OK; } - WARN("(%s %p)\n", debugstr_guid(riid), result); - return NS_NOINTERFACE; -} - -static nsrefcnt NSAPI nsIOServiceFactory_AddRef(nsIFactory *iface) -{ - return 2; -} - -static nsrefcnt NSAPI nsIOServiceFactory_Release(nsIFactory *iface) -{ - return 1; -} - -static nsresult NSAPI nsIOServiceFactory_CreateInstance(nsIFactory *iface, - nsISupports *aOuter, const nsIID *iid, void **result) -{ - return nsIIOService_QueryInterface(&nsIOService, iid, result); + return NS_SUCCESS_DEFAULT_ACTION; } -static nsresult NSAPI nsIOServiceFactory_LockFactory(nsIFactory *iface, cpp_bool lock) -{ - WARN("(%x)\n", lock); - return NS_OK; -} - -static const nsIFactoryVtbl nsIOServiceFactoryVtbl = { - nsIOServiceFactory_QueryInterface, - nsIOServiceFactory_AddRef, - nsIOServiceFactory_Release, - nsIOServiceFactory_CreateInstance, - nsIOServiceFactory_LockFactory +static const nsIIOServiceHookVtbl nsIOServiceHookVtbl = { + nsIOServiceHook_QueryInterface, + nsIOServiceHook_AddRef, + nsIOServiceHook_Release, + nsIOServiceHook_NewChannel, + nsIOServiceHook_GetProtocolHandler, + nsIOServiceHook_NewURI, + nsIOServiceHook_ProtocolHasFlags, + nsIOServiceHook_URIChainHasFlags }; -static nsIFactory nsIOServiceFactory = { &nsIOServiceFactoryVtbl }; +static nsIIOServiceHook nsIOServiceHook = { &nsIOServiceHookVtbl }; static BOOL translate_url(HTMLDocumentObj *doc, nsWineURI *uri) { @@ -4086,7 +3923,7 @@ return NS_OK; } -void init_nsio(nsIComponentManager *component_manager, nsIComponentRegistrar *registrar) +void init_nsio(nsIComponentManager *component_manager) { nsIFactory *old_factory = NULL; nsresult nsres; @@ -4105,31 +3942,12 @@ return; } - nsres = nsIIOService_QueryInterface(nsio, &IID_nsINetUtil, (void**)&net_util); - if(NS_FAILED(nsres)) { - WARN("Could not get nsINetUtil interface: %08x\n", nsres); - nsIIOService_Release(nsio); - return; - } - - nsres = nsIComponentRegistrar_UnregisterFactory(registrar, &NS_IOSERVICE_CID, old_factory); - nsIFactory_Release(old_factory); - if(NS_FAILED(nsres)) - ERR("UnregisterFactory failed: %08x\n", nsres); - - nsres = nsIComponentRegistrar_RegisterFactory(registrar, &NS_IOSERVICE_CID, - NS_IOSERVICE_CLASSNAME, NS_IOSERVICE_CONTRACTID, &nsIOServiceFactory); - if(NS_FAILED(nsres)) - ERR("RegisterFactory failed: %08x\n", nsres); + nsres = nsIIOService_SetHook(nsio, &nsIOServiceHook); + assert(nsres == NS_OK); } void release_nsio(void) { - if(net_util) { - nsINetUtil_Release(net_util); - net_util = NULL; - } - if(nsio) { nsIIOService_Release(nsio); nsio = NULL; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/script.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/script.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/script.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/script.c 2016-02-08 19:32:34.000000000 +0000 @@ -110,6 +110,26 @@ WARN("SetProperty(%x) failed: %08x\n", property, hres); } +static BOOL is_quirks_mode(HTMLDocumentNode *doc) +{ + const WCHAR *compat_mode; + nsAString nsstr; + nsresult nsres; + BOOL ret = FALSE; + + static const WCHAR BackCompatW[] = {'B','a','c','k','C','o','m','p','a','t',0}; + + nsAString_Init(&nsstr, NULL); + nsres = nsIDOMHTMLDocument_GetCompatMode(doc->nsdoc, &nsstr); + if(NS_SUCCEEDED(nsres)) { + nsAString_GetData(&nsstr, &compat_mode); + if(!strcmpW(compat_mode, BackCompatW)) + ret = TRUE; + } + nsAString_Finish(&nsstr); + return ret; +} + static BOOL init_script_engine(ScriptHost *script_host) { IObjectSafety *safety; @@ -148,7 +168,7 @@ return FALSE; V_VT(&var) = VT_I4; - V_I4(&var) = 1; + V_I4(&var) = is_quirks_mode(script_host->window->doc) ? 1 : 2; set_script_prop(script_host, SCRIPTPROP_INVOKEVERSIONING, &var); V_VT(&var) = VT_BOOL; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/tests/dom.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/tests/dom.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/tests/dom.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/tests/dom.c 2016-02-08 19:32:34.000000000 +0000 @@ -179,6 +179,7 @@ &IID_IHTMLElement2, \ &IID_IHTMLElement3, \ &IID_IHTMLElement4, \ + &IID_IHTMLUniqueName, \ &IID_IDispatchEx static const IID * const elem_iids[] = { @@ -1411,8 +1412,19 @@ ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val)); ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val)); VariantClear(&val); - SysFreeString(bstr); + /* overwrite the attribute with null */ + V_VT(&val) = VT_NULL; + hres = IHTMLElement_setAttribute(elem, bstr, val, 0); + ok(hres == S_OK, "setAttribute failed: %08x\n", hres); + + hres = IHTMLElement_getAttribute(elem, bstr, 2, &val); + ok(hres == S_OK, "getAttribute failed: %08x\n", hres); + ok(V_VT(&val) == VT_BSTR, "V_VT(val) = %u, expected VT_BSTR\n", V_VT(&val)); + ok(!strcmp_wa(V_BSTR(&val), "null"), "V_BSTR(val) = %s, expected \"null\"\n", wine_dbgstr_w(V_BSTR(&val))); + VariantClear(&val); + + SysFreeString(bstr); IHTMLElement_Release(elem); } @@ -3586,6 +3598,36 @@ _test_elem_language(line, elem, lang); } +#define test_elem_lang(e,i) _test_elem_lang(__LINE__,e,i) +static void _test_elem_lang(unsigned line, IHTMLElement *elem, const char *exlang) +{ + BSTR lang = (void*)0xdeadbeef; + HRESULT hres; + + hres = IHTMLElement_get_lang(elem, &lang); + ok_(__FILE__,line) (hres == S_OK, "get_lang failed: %08x\n", hres); + + if(exlang) + ok_(__FILE__,line) (!strcmp_wa(lang, exlang), "unexpected lang %s\n", wine_dbgstr_w(lang)); + else + ok_(__FILE__,line) (!lang, "lang=%s\n", wine_dbgstr_w(lang)); + + SysFreeString(lang); +} + +#define set_elem_lang(e,i) _set_elem_lang(__LINE__,e,i) +static void _set_elem_lang(unsigned line, IHTMLElement *elem, const char *lang) +{ + BSTR str = a2bstr(lang); + HRESULT hres; + + hres = IHTMLElement_put_lang(elem, str); + ok_(__FILE__,line) (hres == S_OK, "get_lang failed: %08x\n", hres); + SysFreeString(str); + + _test_elem_lang(line, elem, lang); +} + #define test_elem_put_id(u,i) _test_elem_put_id(__LINE__,u,i) static void _test_elem_put_id(unsigned line, IUnknown *unk, const char *new_id) { @@ -6167,6 +6209,62 @@ IHTMLTxtRange_Release(range); } +static void test_unique_id(IHTMLDocument2 *doc, IHTMLElement *elem) +{ + IHTMLDocument3 *doc3 = get_doc3_iface(doc); + IHTMLUniqueName *unique_name; + char buf[32]; + BSTR id, id2; + LONG num; + HRESULT hres; + + static const WCHAR prefixW[] = {'m','s','_','_','i','d',0}; + + hres = IHTMLDocument3_get_uniqueID(doc3, &id); + ok(hres == S_OK, "get_uniqueID failed: %08x\n", hres); + ok(SysStringLen(id) >= sizeof(prefixW)/sizeof(*prefixW), "id %s too short\n", wine_dbgstr_w(id)); + + hres = IHTMLDocument3_get_uniqueID(doc3, &id2); + ok(hres == S_OK, "get_uniqueID failed: %08x\n", hres); + ok(SysStringLen(id2) >= sizeof(prefixW)/sizeof(*prefixW), "id %s too short\n", wine_dbgstr_w(id2)); + + ok(lstrcmpW(id, id2), "same unique ids %s\n", wine_dbgstr_w(id)); + + id[sizeof(prefixW)/sizeof(*prefixW)-1] = 0; + ok(!lstrcmpW(id, prefixW), "unexpected prefix %s\n", wine_dbgstr_w(id)); + id2[sizeof(prefixW)/sizeof(*prefixW)-1] = 0; + ok(!lstrcmpW(id2, prefixW), "unexpected prefix %s\n", wine_dbgstr_w(id2)); + + SysFreeString(id); + SysFreeString(id2); + + hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLUniqueName, (void**)&unique_name); + ok(hres == S_OK, "Could not get IHTMLUniqueName iface: %08x\n", hres); + + hres = IHTMLUniqueName_get_uniqueID(unique_name, &id); + ok(hres == S_OK, "get_uniqueName failed: %08x\n", hres); + trace("id %s\n", wine_dbgstr_w(id)); + + hres = IHTMLUniqueName_get_uniqueID(unique_name, &id2); + ok(hres == S_OK, "get_uniqueName failed: %08x\n", hres); + ok(!lstrcmpW(id, id2), "unique names differ\n"); + trace("id %s\n", wine_dbgstr_w(id2)); + + hres = IHTMLUniqueName_get_uniqueNumber(unique_name, &num); + ok(hres == S_OK, "get_uniqueName failed: %08x\n", hres); + ok(num, "num = 0\n"); + + sprintf(buf, "ms__id%u", num); + ok(!strcmp_wa(id, buf), "unexpected id %s\n", wine_dbgstr_w(id)); + trace("num %d\n", num); + + SysFreeString(id); + SysFreeString(id2); + + IHTMLUniqueName_Release(unique_name); + IHTMLDocument3_Release(doc3); +} + static void test_doc_elem(IHTMLDocument2 *doc) { IHTMLDocument2 *doc_node, *owner_doc; @@ -6201,6 +6299,7 @@ IHTMLDocument2_Release(doc_node); test_elem_client_rect((IUnknown*)elem); + test_unique_id(doc, elem); IHTMLElement_Release(elem); } @@ -8034,6 +8133,9 @@ test_input_readOnly(input, VARIANT_TRUE); test_input_readOnly(input, VARIANT_FALSE); + test_elem_lang(elem, NULL); + set_elem_lang(elem, "en-us"); + IHTMLInputElement_Release(input); IHTMLElement_Release(elem); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/tests/htmllocation.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/tests/htmllocation.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/tests/htmllocation.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/tests/htmllocation.c 2016-02-08 19:32:34.000000000 +0000 @@ -215,7 +215,8 @@ hres = IHTMLLocation_get_port(loc, &str); ok(hres == S_OK, "%s: get_port failed: 0x%08x\n", test->name, hres); if(hres == S_OK) - ok(str_eq_wa(str, test->port), + ok(str_eq_wa(str, test->port) + || (!str && !*test->port), /* IE11 */ "%s: expected retrieved port to be L\"%s\", was: %s\n", test->name, test->port, wine_dbgstr_w(str)); SysFreeString(str); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/tests/script.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/tests/script.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/tests/script.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/tests/script.c 2016-02-08 19:32:34.000000000 +0000 @@ -1926,6 +1926,23 @@ hres = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, &var, &ei, NULL); ok(hres == S_OK || broken(E_ACCESSDENIED), "InvokeEx failed: %08x\n", hres); if(SUCCEEDED(hres)) { + DISPID named_args[2] = { DISPID_THIS, 0xdeadbeef }; + VARIANT args[2]; + + ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var)); + ok(!strcmp_wa(V_BSTR(&var), "[object]"), "V_BSTR(var) = %s\n", wine_dbgstr_w(V_BSTR(&var))); + VariantClear(&var); + + dp.rgdispidNamedArgs = named_args; + dp.cNamedArgs = 2; + dp.cArgs = 2; + dp.rgvarg = &var; + V_VT(args) = VT_DISPATCH; + V_DISPATCH(args) = (IDispatch*)obj; + V_VT(args+1) = VT_I4; + V_I4(args+1) = 3; + hres = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, &var, &ei, NULL); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var)); ok(!strcmp_wa(V_BSTR(&var), "[object]"), "V_BSTR(var) = %s\n", wine_dbgstr_w(V_BSTR(&var))); VariantClear(&var); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/tests/style.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/tests/style.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/tests/style.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/tests/style.c 2016-02-08 19:32:34.000000000 +0000 @@ -2634,6 +2634,7 @@ { IHTMLCurrentStyle2 *current_style2; IHTMLCurrentStyle3 *current_style3; + IHTMLCurrentStyle4 *current_style4; VARIANT_BOOL b; BSTR str; HRESULT hres; @@ -2899,6 +2900,21 @@ ok(hres == S_OK, "get_textTransform failed: %08x\n", hres); SysFreeString(str); + hres = IHTMLCurrentStyle_get_styleFloat(current_style, &str); + ok(hres == S_OK, "get_styleFloat failed: %08x\n", hres); + ok(!strcmp_wa(str, "none"), "styleFloat = %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + hres = IHTMLCurrentStyle_get_overflowX(current_style, &str); + ok(hres == S_OK, "get_overflowX failed: %08x\n", hres); + ok(!strcmp_wa(str, "hidden"), "overflowX = %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + hres = IHTMLCurrentStyle_get_overflowY(current_style, &str); + ok(hres == S_OK, "get_overflowY failed: %08x\n", hres); + ok(!strcmp_wa(str, "hidden"), "overflowY = %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + current_style2 = get_current_style2_iface((IUnknown*)current_style); b = 100; @@ -2917,6 +2933,16 @@ SysFreeString(str); IHTMLCurrentStyle3_Release(current_style3); + + hres = IHTMLCurrentStyle_QueryInterface(current_style, &IID_IHTMLCurrentStyle4, (void**)¤t_style4); + ok(hres == S_OK, "Could not get IHTMLCurrentStyle4 iface: %08x\n", hres); + + hres = IHTMLCurrentStyle4_get_minWidth(current_style4, &v); + ok(hres == S_OK, "get_minWidth failed: %08x\n", hres); + ok(V_VT(&v) == VT_BSTR, "V_VT(minWidth) = %d\n", V_VT(&v)); + VariantClear(&v); + + IHTMLCurrentStyle4_Release(current_style4); } static const char basic_test_str[] = "
"; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/tests/xmlhttprequest.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/tests/xmlhttprequest.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/tests/xmlhttprequest.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/tests/xmlhttprequest.c 2016-02-08 19:32:34.000000000 +0000 @@ -20,11 +20,13 @@ #include #include +#include #include "windef.h" #include "winbase.h" #include "ole2.h" #include "mshtml.h" +#include "objsafe.h" static BSTR a2bstr(const char *str) { @@ -454,6 +456,109 @@ } } +static const char *debugstr_variant(const VARIANT *var) +{ + static char buf[400]; + + if (!var) + return "(null)"; + + switch (V_VT(var)) + { + case VT_EMPTY: + return "{VT_EMPTY}"; + case VT_BSTR: + sprintf(buf, "{VT_BSTR: %s}", wine_dbgstr_w(V_BSTR(var))); + break; + case VT_BOOL: + sprintf(buf, "{VT_BOOL: %x}", V_BOOL(var)); + break; + case VT_UI4: + sprintf(buf, "{VT_UI4: %u}", V_UI4(var)); + break; + default: + sprintf(buf, "{vt %d}", V_VT(var)); + break; + } + + return buf; +} + +static void test_illegal_xml(IXMLDOMDocument *xmldom) +{ + IXMLDOMNode *first, *last; + VARIANT variant; + HRESULT hres; + BSTR bstr; + + hres = IXMLDOMDocument_get_baseName(xmldom, NULL); + ok(hres == E_INVALIDARG, "Expect E_INVALIDARG, got %08x\n", hres); + hres = IXMLDOMDocument_get_baseName(xmldom, &bstr); + ok(hres == S_FALSE, "get_baseName failed: %08x\n", hres); + ok(bstr == NULL, "bstr(%p): %s\n", bstr, wine_dbgstr_w(bstr)); + SysFreeString(bstr); + + hres = IXMLDOMDocument_get_dataType(xmldom, NULL); + ok(hres == E_INVALIDARG, "Expect E_INVALIDARG, got %08x\n", hres); + hres = IXMLDOMDocument_get_dataType(xmldom, &variant); + ok(hres == S_FALSE, "get_dataType failed: %08x\n", hres); + ok(V_VT(&variant) == VT_NULL, "got %s\n", debugstr_variant(&variant)); + VariantClear(&variant); + + hres = IXMLDOMDocument_get_text(xmldom, &bstr); + ok(!strcmp_wa(bstr, ""), "text = %s\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + + hres = IXMLDOMDocument_get_firstChild(xmldom, NULL); + ok(hres == E_INVALIDARG, "Expect E_INVALIDARG, got %08x\n", hres); + + first = (void*)0xdeadbeef; + hres = IXMLDOMDocument_get_firstChild(xmldom, &first); + ok(hres == S_FALSE, "get_firstChild failed: %08x\n", hres); + ok(first == NULL, "first != NULL\n"); + + last = (void*)0xdeadbeef; + hres = IXMLDOMDocument_get_lastChild(xmldom, &last); + ok(hres == S_FALSE, "get_lastChild failed: %08x\n", hres); + ok(last == NULL, "last != NULL\n"); +} + +static void test_responseXML(const char *expect_text) +{ + IDispatch *disp; + IXMLDOMDocument *xmldom; + IObjectSafety *safety; + DWORD enabled = 0, supported = 0; + HRESULT hres; + + disp = NULL; + hres = IHTMLXMLHttpRequest_get_responseXML(xhr, &disp); + ok(hres == S_OK, "get_responseXML failed: %08x\n", hres); + ok(disp != NULL, "disp == NULL\n"); + + xmldom = NULL; + hres = IDispatch_QueryInterface(disp, &IID_IXMLDOMDocument, (void**)&xmldom); + ok(hres == S_OK, "QueryInterface(IXMLDOMDocument) failed: %08x\n", hres); + ok(xmldom != NULL, "xmldom == NULL\n"); + + hres = IXMLDOMDocument_QueryInterface(xmldom, &IID_IObjectSafety, (void**)&safety); + ok(hres == S_OK, "QueryInterface IObjectSafety failed: %08x\n", hres); + hres = IObjectSafety_GetInterfaceSafetyOptions(safety, NULL, &supported, &enabled); + ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres); + ok(broken(supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA)) || + supported == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER) /* msxml3 SP8+ */, + "Expected supported: (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), got %08x\n", supported); + ok(enabled == (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), + "Expected enabled: (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), got 0x%08x\n", enabled); + IObjectSafety_Release(safety); + + if(!expect_text) + test_illegal_xml(xmldom); + + IXMLDOMDocument_Release(xmldom); + IDispatch_Release(disp); +} + static void test_sync_xhr(IHTMLDocument2 *doc, const char *xml_url, const char *expect_text) { VARIANT vbool, vempty, var; @@ -468,6 +573,8 @@ {"Content-Type", "application/xml"} }; + trace("test_sync_xhr\n"); + create_xmlhttprequest(doc); if(!xhr) return; @@ -612,6 +719,8 @@ expect_text, wine_dbgstr_w(text)); SysFreeString(text); + test_responseXML(expect_text); + IHTMLXMLHttpRequest_Release(xhr); xhr = NULL; } @@ -786,6 +895,8 @@ expect_text, wine_dbgstr_w(text)); SysFreeString(text); + test_responseXML(expect_text); + IHTMLXMLHttpRequest_Release(xhr); xhr = NULL; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/xmlhttprequest.c wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/xmlhttprequest.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/mshtml/xmlhttprequest.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/mshtml/xmlhttprequest.c 2016-02-08 19:32:34.000000000 +0000 @@ -30,6 +30,9 @@ #include "mshtml_private.h" #include "htmlevent.h" +#include "initguid.h" +#include "msxml6.h" +#include "objsafe.h" WINE_DEFAULT_DEBUG_CHANNEL(mshtml); @@ -334,8 +337,42 @@ static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *iface, IDispatch **p) { HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + IXMLDOMDocument *xmldoc = NULL; + BSTR str; + HRESULT hres; + VARIANT_BOOL vbool; + IObjectSafety *safety; + + TRACE("(%p)->(%p)\n", This, p); + + hres = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&xmldoc); + if(FAILED(hres)) { + ERR("CoCreateInstance failed: %08x\n", hres); + return hres; + } + + hres = IHTMLXMLHttpRequest_get_responseText(iface, &str); + if(FAILED(hres)) { + IXMLDOMDocument_Release(xmldoc); + ERR("get_responseText failed: %08x\n", hres); + return hres; + } + + hres = IXMLDOMDocument_loadXML(xmldoc, str, &vbool); + SysFreeString(str); + if(hres != S_OK || vbool != VARIANT_TRUE) + WARN("loadXML failed: %08x, returning an empty xmldoc\n", hres); + + hres = IXMLDOMDocument_QueryInterface(xmldoc, &IID_IObjectSafety, (void**)&safety); + assert(SUCCEEDED(hres)); + hres = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL, + INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER, + INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER); + assert(SUCCEEDED(hres)); + IObjectSafety_Release(safety); + + *p = (IDispatch*)xmldoc; + return S_OK; } static HRESULT WINAPI HTMLXMLHttpRequest_get_status(IHTMLXMLHttpRequest *iface, LONG *p) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msi/action.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msi/action.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msi/action.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msi/action.c 2016-02-08 19:32:34.000000000 +0000 @@ -4135,7 +4135,6 @@ if (rc != ERROR_SUCCESS) { ERR("Failed to get stream\n"); - CloseHandle(the_file); DeleteFileW(FilePath); break; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msi/dialog.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msi/dialog.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msi/dialog.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msi/dialog.c 2016-02-08 19:32:34.000000000 +0000 @@ -556,6 +556,17 @@ } } +static void msi_dialog_update_all_controls( msi_dialog *dialog ) +{ + msi_control *control; + + LIST_FOR_EACH_ENTRY( control, &dialog->controls, msi_control, entry ) + { + if ( control->property && control->update ) + control->update( dialog, control ); + } +} + static void msi_dialog_set_property( MSIPACKAGE *package, LPCWSTR property, LPCWSTR value ) { UINT r = msi_set_property( package->db, property, value, -1 ); @@ -693,11 +704,13 @@ { struct subscriber *sub; - TRACE("event %s control %s attribute %s\n", debugstr_w(event), debugstr_w(control), debugstr_w(attribute)); + TRACE("dialog %s event %s control %s attribute %s\n", debugstr_w(dialog->name), debugstr_w(event), + debugstr_w(control), debugstr_w(attribute)); LIST_FOR_EACH_ENTRY( sub, &dialog->package->subscriptions, struct subscriber, entry ) { - if (!strcmpiW( sub->event, event ) && + if (sub->dialog == dialog && + !strcmpiW( sub->event, event ) && !strcmpiW( sub->control, control ) && !strcmpiW( sub->attribute, attribute )) { @@ -2229,6 +2242,7 @@ control->attributes = MSI_RecordGetInteger( rec, 8 ); prop = MSI_RecordGetString( rec, 9 ); control->property = msi_dialog_dup_property( dialog, prop, FALSE ); + control->update = msi_dialog_update_pathedit; info->dialog = dialog; info->control = control; @@ -4388,7 +4402,11 @@ { /* don't destroy a modeless dialogs that might be our parent */ event_do_dialog( dialog->package, argument, dialog, FALSE ); - if (dialog->package->CurrentInstallState != ERROR_SUCCESS) msi_dialog_end_dialog( dialog ); + if (dialog->package->CurrentInstallState != ERROR_SUCCESS) + msi_dialog_end_dialog( dialog ); + else + msi_dialog_update_all_controls(dialog); + return ERROR_SUCCESS; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msi/media.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msi/media.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msi/media.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msi/media.c 2016-02-08 19:32:34.000000000 +0000 @@ -476,7 +476,7 @@ { TRACE("removing read-only attribute on %s\n", debugstr_w(path)); SetFileAttributesW( path, attrs2 & ~FILE_ATTRIBUTE_READONLY ); - handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs2, NULL); + handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL); if (handle != INVALID_HANDLE_VALUE) goto done; err = GetLastError(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp100/msvcp100.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp100/msvcp100.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp100/msvcp100.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp100/msvcp100.spec 2016-02-08 19:32:34.000000000 +0000 @@ -2113,22 +2113,22 @@ @ cdecl -arch=win64 ?length@?$codecvt@GDH@std@@QEBAHAEBHPEBD1_K@Z(ptr ptr str str long) codecvt_wchar_length @ thiscall -arch=win32 ?length@?$codecvt@_WDH@std@@QBEHABHPBD1I@Z(ptr ptr str str long) codecvt_wchar_length @ cdecl -arch=win64 ?length@?$codecvt@_WDH@std@@QEBAHAEBHPEBD1_K@Z(ptr ptr str str long) codecvt_wchar_length -@ stub ?lowest@?$numeric_limits@C@std@@SACXZ -@ stub ?lowest@?$numeric_limits@D@std@@SADXZ -@ stub ?lowest@?$numeric_limits@E@std@@SAEXZ -@ stub ?lowest@?$numeric_limits@F@std@@SAFXZ -@ stub ?lowest@?$numeric_limits@G@std@@SAGXZ -@ stub ?lowest@?$numeric_limits@H@std@@SAHXZ -@ stub ?lowest@?$numeric_limits@I@std@@SAIXZ -@ stub ?lowest@?$numeric_limits@J@std@@SAJXZ -@ stub ?lowest@?$numeric_limits@K@std@@SAKXZ -@ stub ?lowest@?$numeric_limits@M@std@@SAMXZ -@ stub ?lowest@?$numeric_limits@N@std@@SANXZ -@ stub ?lowest@?$numeric_limits@O@std@@SAOXZ -@ stub ?lowest@?$numeric_limits@_J@std@@SA_JXZ -@ stub ?lowest@?$numeric_limits@_K@std@@SA_KXZ -@ stub ?lowest@?$numeric_limits@_N@std@@SA_NXZ -@ stub ?lowest@?$numeric_limits@_W@std@@SA_WXZ +@ cdecl ?lowest@?$numeric_limits@C@std@@SACXZ() std_numeric_limits_signed_char_lowest +@ cdecl ?lowest@?$numeric_limits@D@std@@SADXZ() std_numeric_limits_char_lowest +@ cdecl ?lowest@?$numeric_limits@E@std@@SAEXZ() std_numeric_limits_unsigned_char_lowest +@ cdecl ?lowest@?$numeric_limits@F@std@@SAFXZ() std_numeric_limits_short_lowest +@ cdecl ?lowest@?$numeric_limits@G@std@@SAGXZ() std_numeric_limits_unsigned_short_lowest +@ cdecl ?lowest@?$numeric_limits@H@std@@SAHXZ() std_numeric_limits_int_lowest +@ cdecl ?lowest@?$numeric_limits@I@std@@SAIXZ() std_numeric_limits_unsigned_int_lowest +@ cdecl ?lowest@?$numeric_limits@J@std@@SAJXZ() std_numeric_limits_long_lowest +@ cdecl ?lowest@?$numeric_limits@K@std@@SAKXZ() std_numeric_limits_unsigned_long_lowest +@ cdecl ?lowest@?$numeric_limits@M@std@@SAMXZ() std_numeric_limits_float_lowest +@ cdecl ?lowest@?$numeric_limits@N@std@@SANXZ() std_numeric_limits_double_lowest +@ cdecl ?lowest@?$numeric_limits@O@std@@SAOXZ() std_numeric_limits_long_double_lowest +@ cdecl -ret64 ?lowest@?$numeric_limits@_J@std@@SA_JXZ() std_numeric_limits_int64_lowest +@ cdecl -ret64 ?lowest@?$numeric_limits@_K@std@@SA_KXZ() std_numeric_limits_unsigned_int64_lowest +@ cdecl ?lowest@?$numeric_limits@_N@std@@SA_NXZ() std_numeric_limits_bool_lowest +@ cdecl ?lowest@?$numeric_limits@_W@std@@SA_WXZ() std_numeric_limits_wchar_t_lowest @ cdecl ?max@?$numeric_limits@C@std@@SACXZ() std_numeric_limits_signed_char_max @ cdecl ?max@?$numeric_limits@D@std@@SADXZ() std_numeric_limits_char_max @ cdecl ?max@?$numeric_limits@E@std@@SAEXZ() std_numeric_limits_unsigned_char_max diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp100/tests/misc.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp100/tests/misc.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp100/tests/misc.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp100/tests/misc.c 2016-02-08 19:32:34.000000000 +0000 @@ -195,6 +195,41 @@ ok(p2.head == (void*)0xdeadbeef, "p2.head = %p, expected 0xdeadbeef\n", p2.head); } +static struct { + int value[2]; + const char* export_name; +} vbtable_size_exports_list[] = { + {{0x18, 0x18}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"}, + {{ 0x8, 0x8}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"}, + {{0x18, 0x18}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"}, + {{ 0x8, 0x8}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"}, + {{0x18, 0x18}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"}, + {{ 0x8, 0x8}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"}, + {{0x10, 0x10}, "??_8?$basic_istream@DU?$char_traits@D@std@@@std@@7B@"}, + {{0x10, 0x10}, "??_8?$basic_istream@GU?$char_traits@G@std@@@std@@7B@"}, + {{0x10, 0x10}, "??_8?$basic_istream@_WU?$char_traits@_W@std@@@std@@7B@"}, + {{ 0x8, 0x8}, "??_8?$basic_ostream@DU?$char_traits@D@std@@@std@@7B@"}, + {{ 0x8, 0x8}, "??_8?$basic_ostream@GU?$char_traits@G@std@@@std@@7B@"}, + {{ 0x8, 0x8}, "??_8?$basic_ostream@_WU?$char_traits@_W@std@@@std@@7B@"}, + {{ 0x0, 0x0}, 0} +}; + +static void test_vbtable_size_exports(void) +{ + int i; + const int *p_vbtable; + int arch_idx = (sizeof(void*) == 8); + + for (i = 0; vbtable_size_exports_list[i].export_name; i++) + { + SET(p_vbtable, vbtable_size_exports_list[i].export_name); + + ok(p_vbtable[0] == 0, "vbtable[0] wrong, got 0x%x\n", p_vbtable[0]); + ok(p_vbtable[1] == vbtable_size_exports_list[i].value[arch_idx], + "%d: %s[1] wrong, got 0x%x\n", i, vbtable_size_exports_list[i].export_name, p_vbtable[1]); + } +} + START_TEST(misc) { if(!init()) @@ -202,5 +237,7 @@ test__Container_base12(); + test_vbtable_size_exports(); + FreeLibrary(msvcp); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp110/msvcp110.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp110/msvcp110.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp110/msvcp110.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp110/msvcp110.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1570,8 +1570,8 @@ @ stub -arch=arm ?_Launch@_Pad@std@@QAAXPAU_Thrd_imp_t@@@Z @ stub -arch=i386 ?_Launch@_Pad@std@@QAEXPAU_Thrd_imp_t@@@Z @ stub -arch=win64 ?_Launch@_Pad@std@@QEAAXPEAU_Thrd_imp_t@@@Z -@ stub -arch=win32 ?_Link@sys@tr2@std@@YAHPBD0@Z -@ stub -arch=win64 ?_Link@sys@tr2@std@@YAHPEBD0@Z +@ cdecl -arch=win32 ?_Link@sys@tr2@std@@YAHPBD0@Z(str str) tr2_sys__Link +@ cdecl -arch=win64 ?_Link@sys@tr2@std@@YAHPEBD0@Z(str str) tr2_sys__Link @ stub -arch=win32 ?_Link@sys@tr2@std@@YAHPB_W0@Z @ stub -arch=win64 ?_Link@sys@tr2@std@@YAHPEB_W0@Z @ cdecl -arch=win32 ?_Locimp_Addfac@_Locimp@locale@std@@CAXPAV123@PAVfacet@23@I@Z(ptr ptr long) locale__Locimp__Locimp_Addfac diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp110/tests/msvcp110.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp110/tests/msvcp110.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp110/tests/msvcp110.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp110/tests/msvcp110.c 2016-02-08 19:32:34.000000000 +0000 @@ -155,9 +155,45 @@ ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret); } +static struct { + int value[2]; + const char* export_name; +} vbtable_size_exports_list[] = { + {{0x20, 0x20}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"}, + {{0x10, 0x10}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"}, + {{0x20, 0x20}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"}, + {{0x10, 0x10}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"}, + {{0x20, 0x20}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"}, + {{0x10, 0x10}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"}, + {{0x18, 0x18}, "??_8?$basic_istream@DU?$char_traits@D@std@@@std@@7B@"}, + {{0x18, 0x18}, "??_8?$basic_istream@GU?$char_traits@G@std@@@std@@7B@"}, + {{0x18, 0x18}, "??_8?$basic_istream@_WU?$char_traits@_W@std@@@std@@7B@"}, + {{ 0x8, 0x10}, "??_8?$basic_ostream@DU?$char_traits@D@std@@@std@@7B@"}, + {{ 0x8, 0x10}, "??_8?$basic_ostream@GU?$char_traits@G@std@@@std@@7B@"}, + {{ 0x8, 0x10}, "??_8?$basic_ostream@_WU?$char_traits@_W@std@@@std@@7B@"}, + {{ 0x0, 0x0}, 0} +}; + +static void test_vbtable_size_exports(void) +{ + int i; + const int *p_vbtable; + int arch_idx = (sizeof(void*) == 8); + + for (i = 0; vbtable_size_exports_list[i].export_name; i++) + { + SET(p_vbtable, vbtable_size_exports_list[i].export_name); + + ok(p_vbtable[0] == 0, "vbtable[0] wrong, got 0x%x\n", p_vbtable[0]); + ok(p_vbtable[1] == vbtable_size_exports_list[i].value[arch_idx], + "%d: %s[1] wrong, got 0x%x\n", i, vbtable_size_exports_list[i].export_name, p_vbtable[1]); + } +} + START_TEST(msvcp110) { if(!init()) return; test_tr2_sys__Last_write_time(); + test_vbtable_size_exports(); FreeLibrary(msvcp); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp120/msvcp120.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp120/msvcp120.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp120/msvcp120.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp120/msvcp120.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1531,8 +1531,8 @@ @ stub -arch=arm ?_Launch@_Pad@std@@QAAXPAU_Thrd_imp_t@@@Z @ stub -arch=i386 ?_Launch@_Pad@std@@QAEXPAU_Thrd_imp_t@@@Z @ stub -arch=win64 ?_Launch@_Pad@std@@QEAAXPEAU_Thrd_imp_t@@@Z -@ stub -arch=win32 ?_Link@sys@tr2@std@@YAHPBD0@Z -@ stub -arch=win64 ?_Link@sys@tr2@std@@YAHPEBD0@Z +@ cdecl -arch=win32 ?_Link@sys@tr2@std@@YAHPBD0@Z(str str) tr2_sys__Link +@ cdecl -arch=win64 ?_Link@sys@tr2@std@@YAHPEBD0@Z(str str) tr2_sys__Link @ stub -arch=win32 ?_Link@sys@tr2@std@@YAHPB_W0@Z @ stub -arch=win64 ?_Link@sys@tr2@std@@YAHPEB_W0@Z @ cdecl -arch=win32 ?_Locimp_Addfac@_Locimp@locale@std@@CAXPAV123@PAVfacet@23@I@Z(ptr ptr long) locale__Locimp__Locimp_Addfac diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp120/tests/msvcp120.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp120/tests/msvcp120.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp120/tests/msvcp120.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp120/tests/msvcp120.c 2016-02-08 19:32:34.000000000 +0000 @@ -132,6 +132,7 @@ static void* (__cdecl *p_tr2_sys__Open_dir)(char*, char const*, int *, enum file_type*); static char* (__cdecl *p_tr2_sys__Read_dir)(char*, void*, enum file_type*); static void (__cdecl *p_tr2_sys__Close_dir)(void*); +static int (__cdecl *p_tr2_sys__Link)(char const*, char const*); /* thrd */ typedef struct @@ -265,6 +266,8 @@ "?_Read_dir@sys@tr2@std@@YAPEADAEAY0BAE@DPEAXAEAW4file_type@123@@Z"); SET(p_tr2_sys__Close_dir, "?_Close_dir@sys@tr2@std@@YAXPEAX@Z"); + SET(p_tr2_sys__Link, + "?_Link@sys@tr2@std@@YAHPEBD0@Z"); SET(p__Thrd_current, "_Thrd_current"); } else { @@ -318,6 +321,8 @@ "?_Read_dir@sys@tr2@std@@YAPADAAY0BAE@DPAXAAW4file_type@123@@Z"); SET(p_tr2_sys__Close_dir, "?_Close_dir@sys@tr2@std@@YAXPAX@Z"); + SET(p_tr2_sys__Link, + "?_Link@sys@tr2@std@@YAHPBD0@Z"); #ifdef __i386__ SET(p_i386_Thrd_current, "_Thrd_current"); @@ -1319,6 +1324,90 @@ ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n"); } +static void test_tr2_sys__Link(void) +{ + int ret, i; + HANDLE file, h1, h2; + BY_HANDLE_FILE_INFORMATION info1, info2; + char temp_path[MAX_PATH], current_path[MAX_PATH]; + LARGE_INTEGER file_size; + struct { + char const *existing_path; + char const *new_path; + MSVCP_bool fail_if_exists; + int last_error; + } tests[] = { + { "f1", "f1_link", TRUE, ERROR_SUCCESS }, + { "f1", "tr2_test_dir\\f1_link", TRUE, ERROR_SUCCESS }, + { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", TRUE, ERROR_SUCCESS }, + { "tr2_test_dir", "dir_link", TRUE, ERROR_ACCESS_DENIED }, + { NULL, "NULL_link", TRUE, ERROR_INVALID_PARAMETER }, + { "f1", NULL, TRUE, ERROR_INVALID_PARAMETER }, + { "not_exist", "not_exist_link", TRUE, ERROR_FILE_NOT_FOUND }, + { "f1", "not_exist_dir\\f1_link", TRUE, ERROR_PATH_NOT_FOUND } + }; + + memset(current_path, 0, MAX_PATH); + GetCurrentDirectoryA(MAX_PATH, current_path); + memset(temp_path, 0, MAX_PATH); + GetTempPathA(MAX_PATH, temp_path); + ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n"); + + ret = p_tr2_sys__Make_dir("tr2_test_dir"); + ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret); + file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n"); + file_size.QuadPart = 7; + ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n"); + ok(SetEndOfFile(file), "SetEndOfFile failed\n"); + CloseHandle(file); + + for(i=0; i= 100 -#define VBTABLE_ALIGN 8 +#if _MSVCP_VER >= 110 +#define BASIC_IOS_VTORDISP 1 +#define INIT_BASIC_IOS_VTORDISP(basic_ios) ((int*)basic_ios)[-1] = 0 #else -#define VBTABLE_ALIGN 4 +#define BASIC_IOS_VTORDISP 0 +#define INIT_BASIC_IOS_VTORDISP(basic_ios) #endif +#define VBTABLE_ENTRY(class, offset, vbase, vtordisp) ALIGNED_SIZE(sizeof(class)+vtordisp*sizeof(int), TYPE_ALIGNMENT(vbase))-offset +#define VBTABLE_BASIC_IOS_ENTRY(class, offset) VBTABLE_ENTRY(class, offset, basic_ios_char, BASIC_IOS_VTORDISP) + extern const vtable_ptr MSVCP_iosb_vtable; /* ??_7ios_base@std@@6B@ */ @@ -384,162 +389,195 @@ extern const vtable_ptr MSVCP_basic_stringbuf_short_vtable; /* ??_8?$basic_ostream@DU?$char_traits@D@std@@@std@@7B@ */ -const int basic_ostream_char_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_ostream_char), VBTABLE_ALIGN)}; +const int basic_ostream_char_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ostream_char, 0)}; /* ??_7?$basic_ostream@DU?$char_traits@D@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ostream_char_vtable; /* ??_8?$basic_ostream@_WU?$char_traits@_W@std@@@std@@7B@ */ -const int basic_ostream_wchar_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_ostream_wchar), VBTABLE_ALIGN)}; +const int basic_ostream_wchar_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ostream_wchar, 0)}; /* ??_7?$basic_ostream@_WU?$char_traits@_W@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ostream_wchar_vtable; /* ??_8?$basic_ostream@GU?$char_traits@G@std@@@std@@7B@ */ -const int basic_ostream_short_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_ostream_wchar), VBTABLE_ALIGN)}; +const int basic_ostream_short_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ostream_wchar, 0)}; /* ??_7?$basic_ostream@GU?$char_traits@G@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ostream_short_vtable; /* ??_8?$basic_istream@DU?$char_traits@D@std@@@std@@7B@ */ -const int basic_istream_char_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_istream_char), VBTABLE_ALIGN)}; +const int basic_istream_char_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_istream_char, 0)}; /* ??_7?$basic_istream@DU?$char_traits@D@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_istream_char_vtable; /* ??_8?$basic_istream@_WU?$char_traits@_W@std@@@std@@7B@ */ -const int basic_istream_wchar_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_istream_wchar), VBTABLE_ALIGN)}; +const int basic_istream_wchar_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_istream_wchar, 0)}; /* ??_7?$basic_istream@_WU?$char_traits@_W@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_istream_wchar_vtable; /* ??_8?$basic_istream@GU?$char_traits@G@std@@@std@@7B@ */ -const int basic_istream_short_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_istream_wchar), VBTABLE_ALIGN)}; +const int basic_istream_short_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_istream_wchar, 0)}; /* ??_7?$basic_istream@GU?$char_traits@G@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_istream_short_vtable; /* ??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@ */ -const int basic_iostream_char_vbtable1[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_char), VBTABLE_ALIGN)}; +const int basic_iostream_char_vbtable1[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_iostream_char, 0)}; /* ??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@ */ -const int basic_iostream_char_vbtable2[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_char), VBTABLE_ALIGN)-FIELD_OFFSET(basic_iostream_char, base2)}; +const int basic_iostream_char_vbtable2[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_iostream_char, FIELD_OFFSET(basic_iostream_char, base2))}; /* ??_7?$basic_iostream@DU?$char_traits@D@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_iostream_char_vtable; /* ??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@ */ /* ??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@ */ -const int basic_iostream_wchar_vbtable1[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_wchar), VBTABLE_ALIGN)}; +const int basic_iostream_wchar_vbtable1[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_iostream_wchar, 0)}; /* ??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@ */ /* ??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@ */ -const int basic_iostream_wchar_vbtable2[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_wchar), VBTABLE_ALIGN)-FIELD_OFFSET(basic_iostream_wchar, base2)}; +const int basic_iostream_wchar_vbtable2[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_iostream_wchar, FIELD_OFFSET(basic_iostream_wchar, base2))}; /* ??_7?$basic_iostream@_WU?$char_traits@_W@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_iostream_wchar_vtable; /* ??_7?$basic_iostream@GU?$char_traits@G@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_iostream_short_vtable; /* ??_8?$basic_ofstream@DU?$char_traits@D@std@@@std@@7B@ */ -const int basic_ofstream_char_vbtable[] = {0, sizeof(basic_ofstream_char)}; +const int basic_ofstream_char_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ofstream_char, 0)}; /* ??_7?$basic_ofstream@DU?$char_traits@D@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ofstream_char_vtable; /* ??_8?$basic_ofstream@_WU?$char_traits@_W@std@@@std@@7B@ */ -const int basic_ofstream_wchar_vbtable[] = {0, sizeof(basic_ofstream_wchar)}; +const int basic_ofstream_wchar_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ofstream_wchar, 0)}; /* ??_7?$basic_ofstream@_WU?$char_traits@_W@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ofstream_wchar_vtable; /* ??_8?$basic_ofstream@GU?$char_traits@G@std@@@std@@7B@ */ -const int basic_ofstream_short_vbtable[] = {0, sizeof(basic_ofstream_wchar)}; +const int basic_ofstream_short_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ofstream_wchar, 0)}; /* ??_7?$basic_ofstream@GU?$char_traits@G@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ofstream_short_vtable; /* ??_8?$basic_ifstream@DU?$char_traits@D@std@@@std@@7B@ */ -const int basic_ifstream_char_vbtable[] = {0, sizeof(basic_ifstream_char)}; +const int basic_ifstream_char_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ifstream_char, 0)}; /* ??_7?$basic_ifstream@DU?$char_traits@D@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ifstream_char_vtable; /* ??_8?$basic_ifstream@_WU?$char_traits@_W@std@@@std@@7B@ */ -const int basic_ifstream_wchar_vbtable[] = {0, sizeof(basic_ifstream_wchar)}; +const int basic_ifstream_wchar_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ifstream_wchar, 0)}; /* ??_7?$basic_ifstream@_WU?$char_traits@_W@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ifstream_wchar_vtable; /* ??_8?$basic_ifstream@GU?$char_traits@G@std@@@std@@7B@ */ -const int basic_ifstream_short_vbtable[] = {0, sizeof(basic_ifstream_wchar)}; +const int basic_ifstream_short_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ifstream_wchar, 0)}; /* ??_7?$basic_ifstream@GU?$char_traits@G@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ifstream_short_vtable; /* ??_8?$basic_fstream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@ */ -const int basic_fstream_char_vbtable1[] = {0, sizeof(basic_fstream_char)}; +const int basic_fstream_char_vbtable1[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_fstream_char, 0)}; /* ??_8?$basic_fstream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@ */ -const int basic_fstream_char_vbtable2[] = {0, sizeof(basic_fstream_char)-FIELD_OFFSET(basic_fstream_char, base.base2)}; +const int basic_fstream_char_vbtable2[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_fstream_char, FIELD_OFFSET(basic_fstream_char, base.base2))}; /* ??_7?$basic_fstream@DU?$char_traits@D@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_fstream_char_vtable; /* ??_8?$basic_fstream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@ */ /* ??_8?$basic_fstream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@ */ -const int basic_fstream_wchar_vbtable1[] = {0, sizeof(basic_fstream_wchar)}; +const int basic_fstream_wchar_vbtable1[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_fstream_wchar, 0)}; /* ??_8?$basic_fstream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@ */ /* ??_8?$basic_fstream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@ */ -const int basic_fstream_wchar_vbtable2[] = {0, sizeof(basic_fstream_wchar)-FIELD_OFFSET(basic_fstream_wchar, base.base2)}; +const int basic_fstream_wchar_vbtable2[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_fstream_wchar, FIELD_OFFSET(basic_fstream_wchar, base.base2))}; /* ??_7?$basic_fstream@_WU?$char_traits@_W@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_fstream_wchar_vtable; /* ??_7?$basic_fstream@GU?$char_traits@G@std@@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_fstream_short_vtable; /* ??_8?$basic_ostringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@7B@ */ -const int basic_ostringstream_char_vbtable[] = {0, sizeof(basic_ostringstream_char)}; +const int basic_ostringstream_char_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ostringstream_char, 0)}; /* ??_7?$basic_ostringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ostringstream_char_vtable; /* ??_8?$basic_ostringstream@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@7B@ */ -const int basic_ostringstream_wchar_vbtable[] = {0, sizeof(basic_ostringstream_wchar)}; +const int basic_ostringstream_wchar_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ostringstream_wchar, 0)}; /* ??_7?$basic_ostringstream@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ostringstream_wchar_vtable; /* ??_8?$basic_ostringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@7B@ */ -const int basic_ostringstream_short_vbtable[] = {0, sizeof(basic_ostringstream_wchar)}; +const int basic_ostringstream_short_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_ostringstream_wchar, 0)}; /* ??_7?$basic_ostringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_ostringstream_short_vtable; /* ??_8?$basic_istringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@7B@ */ -const int basic_istringstream_char_vbtable[] = {0, sizeof(basic_istringstream_char)}; +const int basic_istringstream_char_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_istringstream_char, 0)}; /* ??_7?$basic_istringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_istringstream_char_vtable; /* ??_8?$basic_istringstream@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@7B@ */ -const int basic_istringstream_wchar_vbtable[] = {0, sizeof(basic_istringstream_wchar)}; +const int basic_istringstream_wchar_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_istringstream_wchar, 0)}; /* ??_7?$basic_istringstream@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_istringstream_wchar_vtable; /* ??_8?$basic_istringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@7B@ */ -const int basic_istringstream_short_vbtable[] = {0, sizeof(basic_istringstream_wchar)}; +const int basic_istringstream_short_vbtable[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_istringstream_wchar, 0)}; /* ??_7?$basic_istringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_istringstream_short_vtable; /* ??_8?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@ */ -const int basic_stringstream_char_vbtable1[] = {0, sizeof(basic_stringstream_char)}; +const int basic_stringstream_char_vbtable1[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_stringstream_char, 0)}; /* ??_8?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@ */ -const int basic_stringstream_char_vbtable2[] = {0, sizeof(basic_stringstream_char)-FIELD_OFFSET(basic_stringstream_char, base.base2)}; +const int basic_stringstream_char_vbtable2[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_stringstream_char, FIELD_OFFSET(basic_stringstream_char, base.base2))}; /* ??_7?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_stringstream_char_vtable; /* ??_8?$basic_stringstream@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@ */ -const int basic_stringstream_wchar_vbtable1[] = {0, sizeof(basic_stringstream_wchar)}; +const int basic_stringstream_wchar_vbtable1[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_stringstream_wchar, 0)}; /* ??_8?$basic_stringstream@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@ */ -const int basic_stringstream_wchar_vbtable2[] = {0, sizeof(basic_stringstream_wchar)-FIELD_OFFSET(basic_stringstream_wchar, base.base2)}; +const int basic_stringstream_wchar_vbtable2[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_stringstream_wchar, FIELD_OFFSET(basic_stringstream_wchar, base.base2))}; /* ??_7?$basic_stringstream@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_stringstream_wchar_vtable; /* ??_8?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@ */ -const int basic_stringstream_short_vbtable1[] = {0, sizeof(basic_stringstream_wchar)}; +const int basic_stringstream_short_vbtable1[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_stringstream_wchar, 0)}; /* ??_8?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@ */ -const int basic_stringstream_short_vbtable2[] = {0, sizeof(basic_stringstream_wchar)-FIELD_OFFSET(basic_stringstream_wchar, base.base2)}; +const int basic_stringstream_short_vbtable2[] = {0, + VBTABLE_BASIC_IOS_ENTRY(basic_stringstream_wchar, FIELD_OFFSET(basic_stringstream_wchar, base.base2))}; /* ??_7?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@6B@ */ extern const vtable_ptr MSVCP_basic_stringstream_short_vtable; /* ??_7strstreambuf@std@@6B */ extern const vtable_ptr MSVCP_strstreambuf_vtable; -static const int ostrstream_vbtable[] = {0, sizeof(ostrstream)}; +static const int ostrstream_vbtable[] = {0, VBTABLE_BASIC_IOS_ENTRY(ostrstream, 0)}; extern const vtable_ptr MSVCP_ostrstream_vtable; -static const int istrstream_vbtable[] = {0, sizeof(istrstream)}; +static const int istrstream_vbtable[] = {0, VBTABLE_BASIC_IOS_ENTRY(istrstream, 0)}; -static const int strstream_vbtable1[] = {0, sizeof(strstream)}; -static const int strstream_vbtable2[] = {0, sizeof(strstream)-FIELD_OFFSET(strstream, base.base2)}; +static const int strstream_vbtable1[] = {0, VBTABLE_BASIC_IOS_ENTRY(strstream, 0)}; +static const int strstream_vbtable2[] = {0, + VBTABLE_BASIC_IOS_ENTRY(strstream, FIELD_OFFSET(strstream, base.base2))}; extern const vtable_ptr MSVCP_strstream_vtable; DEFINE_RTTI_DATA0(iosb, 0, ".?AV?$_Iosb@H@std@@") @@ -709,11 +747,26 @@ __ASM_VTABLE(ios_base, VTABLE_ADD_FUNC(ios_base_vector_dtor)); __ASM_VTABLE(basic_ios_char, - VTABLE_ADD_FUNC(basic_ios_char_vector_dtor)); + VTABLE_ADD_FUNC(basic_ios_char_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ios_wchar, - VTABLE_ADD_FUNC(basic_ios_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_ios_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ios_short, - VTABLE_ADD_FUNC(basic_ios_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_ios_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_streambuf_char, VTABLE_ADD_FUNC(basic_streambuf_char_vector_dtor) #if _MSVCP_VER >= 100 @@ -892,59 +945,194 @@ VTABLE_ADD_FUNC(basic_streambuf_wchar_sync) VTABLE_ADD_FUNC(basic_streambuf_wchar_imbue)); __ASM_VTABLE(basic_ostream_char, - VTABLE_ADD_FUNC(basic_ostream_char_vector_dtor)); + VTABLE_ADD_FUNC(basic_ostream_char_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ostream_wchar, - VTABLE_ADD_FUNC(basic_ostream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_ostream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ostream_short, - VTABLE_ADD_FUNC(basic_ostream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_ostream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_istream_char, - VTABLE_ADD_FUNC(basic_istream_char_vector_dtor)); + VTABLE_ADD_FUNC(basic_istream_char_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_istream_wchar, - VTABLE_ADD_FUNC(basic_istream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_istream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_istream_short, - VTABLE_ADD_FUNC(basic_istream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_istream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_iostream_char, - VTABLE_ADD_FUNC(basic_iostream_char_vector_dtor)); + VTABLE_ADD_FUNC(basic_iostream_char_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_iostream_wchar, - VTABLE_ADD_FUNC(basic_iostream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_iostream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_iostream_short, - VTABLE_ADD_FUNC(basic_iostream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_iostream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ofstream_char, - VTABLE_ADD_FUNC(basic_ofstream_char_vector_dtor)); + VTABLE_ADD_FUNC(basic_ofstream_char_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ofstream_wchar, - VTABLE_ADD_FUNC(basic_ofstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_ofstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ofstream_short, - VTABLE_ADD_FUNC(basic_ofstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_ofstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ifstream_char, - VTABLE_ADD_FUNC(basic_ifstream_char_vector_dtor)); + VTABLE_ADD_FUNC(basic_ifstream_char_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ifstream_wchar, - VTABLE_ADD_FUNC(basic_ifstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_ifstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ifstream_short, - VTABLE_ADD_FUNC(basic_ifstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_ifstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_fstream_char, - VTABLE_ADD_FUNC(basic_fstream_char_vector_dtor)); + VTABLE_ADD_FUNC(basic_fstream_char_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_fstream_wchar, - VTABLE_ADD_FUNC(basic_fstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_fstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_fstream_short, - VTABLE_ADD_FUNC(basic_fstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_fstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ostringstream_char, - VTABLE_ADD_FUNC(basic_ostringstream_char_vector_dtor)); + VTABLE_ADD_FUNC(basic_ostringstream_char_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ostringstream_wchar, - VTABLE_ADD_FUNC(basic_ostringstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_ostringstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_ostringstream_short, - VTABLE_ADD_FUNC(basic_ostringstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_ostringstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_istringstream_char, - VTABLE_ADD_FUNC(basic_istringstream_char_vector_dtor)); + VTABLE_ADD_FUNC(basic_istringstream_char_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_istringstream_wchar, - VTABLE_ADD_FUNC(basic_istringstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_istringstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_istringstream_short, - VTABLE_ADD_FUNC(basic_istringstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_istringstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_stringstream_char, - VTABLE_ADD_FUNC(basic_stringstream_char_vector_dtor)); + VTABLE_ADD_FUNC(basic_stringstream_char_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_stringstream_wchar, - VTABLE_ADD_FUNC(basic_stringstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_stringstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(basic_stringstream_short, - VTABLE_ADD_FUNC(basic_stringstream_wchar_vector_dtor)); + VTABLE_ADD_FUNC(basic_stringstream_wchar_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(strstreambuf, VTABLE_ADD_FUNC(strstreambuf_vector_dtor) VTABLE_ADD_FUNC(strstreambuf_overflow) @@ -963,9 +1151,19 @@ VTABLE_ADD_FUNC(basic_streambuf_char_sync) VTABLE_ADD_FUNC(basic_streambuf_char_imbue)); __ASM_VTABLE(ostrstream, - VTABLE_ADD_FUNC(ostrstream_vector_dtor)); + VTABLE_ADD_FUNC(ostrstream_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); __ASM_VTABLE(strstream, - VTABLE_ADD_FUNC(strstream_vector_dtor)); + VTABLE_ADD_FUNC(strstream_vector_dtor) +#if _MSVCP_VER >= 110 + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp1) + VTABLE_ADD_FUNC(basic_ios__Add_vtordisp2) +#endif + ); #ifndef __GNUC__ } #endif @@ -5441,6 +5639,18 @@ *r = tmp; } +DEFINE_THISCALL_WRAPPER(basic_ios__Add_vtordisp1, 4) +void __thiscall basic_ios__Add_vtordisp1(void *this) +{ + WARN("should not be called (%p)\n", this); +} + +DEFINE_THISCALL_WRAPPER(basic_ios__Add_vtordisp2, 4) +void __thiscall basic_ios__Add_vtordisp2(void *this) +{ + WARN("should not be called (%p)\n", this); +} + /* ??0?$basic_ios@DU?$char_traits@D@std@@@std@@IAE@XZ */ /* ??0?$basic_ios@DU?$char_traits@D@std@@@std@@IEAA@XZ */ DEFINE_THISCALL_WRAPPER(basic_ios_char_ctor, 4) @@ -6013,6 +6223,7 @@ if(virt_init) { this->vbtable = basic_ostream_char_vbtable; base = basic_ostream_char_get_basic_ios(this); + INIT_BASIC_IOS_VTORDISP(base); basic_ios_char_ctor(base); }else { base = basic_ostream_char_get_basic_ios(this); @@ -6036,6 +6247,7 @@ if(virt_init) { this->vbtable = basic_ostream_char_vbtable; base = basic_ostream_char_get_basic_ios(this); + INIT_BASIC_IOS_VTORDISP(base); basic_ios_char_ctor(base); }else { base = basic_ostream_char_get_basic_ios(this); @@ -6836,6 +7048,7 @@ if(virt_init) { this->vbtable = basic_ostream_wchar_vbtable; base = basic_ostream_wchar_get_basic_ios(this); + INIT_BASIC_IOS_VTORDISP(base); basic_ios_wchar_ctor(base); }else { base = basic_ostream_wchar_get_basic_ios(this); @@ -6870,6 +7083,7 @@ if(virt_init) { this->vbtable = basic_ostream_wchar_vbtable; base = basic_ostream_wchar_get_basic_ios(this); + INIT_BASIC_IOS_VTORDISP(base); basic_ios_wchar_ctor(base); }else { base = basic_ostream_wchar_get_basic_ios(this); @@ -7882,6 +8096,7 @@ if(virt_init) { this->vbtable = basic_istream_char_vbtable; base = basic_istream_char_get_basic_ios(this); + INIT_BASIC_IOS_VTORDISP(base); basic_ios_char_ctor(base); }else { base = basic_istream_char_get_basic_ios(this); @@ -7914,6 +8129,7 @@ if(virt_init) { this->vbtable = basic_istream_char_vbtable; base = basic_istream_char_get_basic_ios(this); + INIT_BASIC_IOS_VTORDISP(base); basic_ios_char_ctor(base); }else { base = basic_istream_char_get_basic_ios(this); @@ -9317,6 +9533,7 @@ if(virt_init) { this->vbtable = basic_istream_wchar_vbtable; base = basic_istream_wchar_get_basic_ios(this); + INIT_BASIC_IOS_VTORDISP(base); basic_ios_wchar_ctor(base); }else { base = basic_istream_wchar_get_basic_ios(this); @@ -9371,6 +9588,7 @@ if(virt_init) { this->vbtable = basic_istream_wchar_vbtable; base = basic_istream_wchar_get_basic_ios(this); + INIT_BASIC_IOS_VTORDISP(base); basic_ios_wchar_ctor(base); }else { base = basic_istream_wchar_get_basic_ios(this); @@ -10860,6 +11078,7 @@ this->base1.vbtable = basic_iostream_char_vbtable1; this->base2.vbtable = basic_iostream_char_vbtable2; basic_ios = basic_istream_char_get_basic_ios(&this->base1); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_istream_char_get_basic_ios(&this->base1); @@ -10955,6 +11174,7 @@ this->base1.vbtable = basic_iostream_wchar_vbtable1; this->base2.vbtable = basic_iostream_wchar_vbtable2; basic_ios = basic_istream_wchar_get_basic_ios(&this->base1); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_istream_wchar_get_basic_ios(&this->base1); @@ -11065,6 +11285,7 @@ if(virt_init) { this->base.vbtable = basic_ofstream_char_vbtable; basic_ios = basic_ostream_char_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_ostream_char_get_basic_ios(&this->base); @@ -11089,6 +11310,7 @@ if(virt_init) { this->base.vbtable = basic_ofstream_char_vbtable; basic_ios = basic_ostream_char_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_ostream_char_get_basic_ios(&this->base); @@ -11286,6 +11508,7 @@ if(virt_init) { this->base.vbtable = basic_ofstream_wchar_vbtable; basic_ios = basic_ostream_wchar_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_ostream_wchar_get_basic_ios(&this->base); @@ -11320,6 +11543,7 @@ if(virt_init) { this->base.vbtable = basic_ofstream_wchar_vbtable; basic_ios = basic_ostream_wchar_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_ostream_wchar_get_basic_ios(&this->base); @@ -11574,6 +11798,7 @@ if(virt_init) { this->base.vbtable = basic_ifstream_char_vbtable; basic_ios = basic_istream_char_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_istream_char_get_basic_ios(&this->base); @@ -11598,6 +11823,7 @@ if(virt_init) { this->base.vbtable = basic_ifstream_char_vbtable; basic_ios = basic_istream_char_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_istream_char_get_basic_ios(&this->base); @@ -11804,6 +12030,7 @@ if(virt_init) { this->base.vbtable = basic_ifstream_wchar_vbtable; basic_ios = basic_istream_wchar_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_istream_wchar_get_basic_ios(&this->base); @@ -11838,6 +12065,7 @@ if(virt_init) { this->base.vbtable = basic_ifstream_wchar_vbtable; basic_ios = basic_istream_wchar_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_istream_wchar_get_basic_ios(&this->base); @@ -12111,6 +12339,7 @@ this->base.base1.vbtable = basic_fstream_char_vbtable1; this->base.base2.vbtable = basic_fstream_char_vbtable2; basic_ios = basic_istream_char_get_basic_ios(&this->base.base1); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_istream_char_get_basic_ios(&this->base.base1); @@ -12136,6 +12365,7 @@ this->base.base1.vbtable = basic_fstream_char_vbtable1; this->base.base2.vbtable = basic_fstream_char_vbtable2; basic_ios = basic_istream_char_get_basic_ios(&this->base.base1); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_istream_char_get_basic_ios(&this->base.base1); @@ -12343,6 +12573,7 @@ this->base.base1.vbtable = basic_fstream_wchar_vbtable1; this->base.base2.vbtable = basic_fstream_wchar_vbtable2; basic_ios = basic_istream_wchar_get_basic_ios(&this->base.base1); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_istream_wchar_get_basic_ios(&this->base.base1); @@ -12378,6 +12609,7 @@ this->base.base1.vbtable = basic_fstream_wchar_vbtable1; this->base.base2.vbtable = basic_fstream_wchar_vbtable2; basic_ios = basic_istream_wchar_get_basic_ios(&this->base.base1); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_istream_wchar_get_basic_ios(&this->base.base1); @@ -12650,6 +12882,7 @@ if(virt_init) { this->base.vbtable = basic_ostringstream_char_vbtable; basic_ios = basic_ostream_char_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_ostream_char_get_basic_ios(&this->base); @@ -12674,6 +12907,7 @@ if(virt_init) { this->base.vbtable = basic_ostringstream_char_vbtable; basic_ios = basic_ostream_char_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_ostream_char_get_basic_ios(&this->base); @@ -12791,6 +13025,7 @@ if(virt_init) { this->base.vbtable = basic_ostringstream_wchar_vbtable; basic_ios = basic_ostream_wchar_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_ostream_wchar_get_basic_ios(&this->base); @@ -12826,6 +13061,7 @@ if(virt_init) { this->base.vbtable = basic_ostringstream_wchar_vbtable; basic_ios = basic_ostream_wchar_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_ostream_wchar_get_basic_ios(&this->base); @@ -12973,6 +13209,7 @@ if(virt_init) { this->base.vbtable = basic_istringstream_char_vbtable; basic_ios = basic_istream_char_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_istream_char_get_basic_ios(&this->base); @@ -12997,6 +13234,7 @@ if(virt_init) { this->base.vbtable = basic_istringstream_char_vbtable; basic_ios = basic_istream_char_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_istream_char_get_basic_ios(&this->base); @@ -13114,6 +13352,7 @@ if(virt_init) { this->base.vbtable = basic_istringstream_wchar_vbtable; basic_ios = basic_istream_wchar_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_istream_wchar_get_basic_ios(&this->base); @@ -13149,6 +13388,7 @@ if(virt_init) { this->base.vbtable = basic_istringstream_wchar_vbtable; basic_ios = basic_istream_wchar_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_istream_wchar_get_basic_ios(&this->base); @@ -13297,6 +13537,7 @@ this->base.base1.vbtable = basic_stringstream_char_vbtable1; this->base.base2.vbtable = basic_stringstream_char_vbtable2; basic_ios = basic_istream_char_get_basic_ios(&this->base.base1); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_istream_char_get_basic_ios(&this->base.base1); @@ -13322,6 +13563,7 @@ this->base.base1.vbtable = basic_stringstream_char_vbtable1; this->base.base2.vbtable = basic_stringstream_char_vbtable2; basic_ios = basic_istream_char_get_basic_ios(&this->base.base1); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_istream_char_get_basic_ios(&this->base.base1); @@ -13441,6 +13683,7 @@ this->base.base1.vbtable = basic_stringstream_wchar_vbtable1; this->base.base2.vbtable = basic_stringstream_wchar_vbtable2; basic_ios = basic_istream_wchar_get_basic_ios(&this->base.base1); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_istream_wchar_get_basic_ios(&this->base.base1); @@ -13477,6 +13720,7 @@ this->base.base1.vbtable = basic_stringstream_wchar_vbtable1; this->base.base2.vbtable = basic_stringstream_wchar_vbtable2; basic_ios = basic_istream_wchar_get_basic_ios(&this->base.base1); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_wchar_ctor(basic_ios); }else { basic_ios = basic_istream_wchar_get_basic_ios(&this->base.base1); @@ -14022,6 +14266,7 @@ if(virt_init) { this->base.vbtable = ostrstream_vbtable; basic_ios = basic_ostream_char_get_basic_ios(&this->base); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_ostream_char_get_basic_ios(&this->base); @@ -14511,6 +14756,19 @@ FindClose(handle); } +/* ?_Link@sys@tr2@std@@YAHPBD0@Z */ +/* ?_Link@sys@tr2@std@@YAHPEBD0@Z */ +int __cdecl tr2_sys__Link(char const* existing_path, char const* new_path) +{ + TRACE("(%s %s)\n", debugstr_a(existing_path), debugstr_a(new_path)); + if(!existing_path || !new_path) + return ERROR_INVALID_PARAMETER; + + if(CreateHardLinkA(new_path, existing_path, NULL)) + return ERROR_SUCCESS; + return GetLastError(); +} + /* ??0strstream@std@@QAE@PADHH@Z */ /* ??0strstream@std@@QEAA@PEAD_JH@Z */ #if STREAMSIZE_BITS == 64 @@ -14528,6 +14786,7 @@ this->base.base1.vbtable = strstream_vbtable1; this->base.base2.vbtable = strstream_vbtable2; basic_ios = basic_istream_char_get_basic_ios(&this->base.base1); + INIT_BASIC_IOS_VTORDISP(basic_ios); basic_ios_char_ctor(basic_ios); }else { basic_ios = basic_istream_char_get_basic_ios(&this->base.base1); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp90/math.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp90/math.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp90/math.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp90/math.c 2016-02-08 19:32:34.000000000 +0000 @@ -659,6 +659,54 @@ /* ?min@?$numeric_limits@_W@std@@SA_WXZ -> public: static wchar_t __cdecl std::numeric_limits::min(void) */ WCHAR __cdecl std_numeric_limits_wchar_t_min(void) { return 0; } +/* ?lowest@?$numeric_limits@C@std@@SACXZ */ +signed char __cdecl std_numeric_limits_signed_char_lowest(void) { return SCHAR_MIN; } + +/* ?lowest@?$numeric_limits@D@std@@SADXZ */ +char __cdecl std_numeric_limits_char_lowest(void) { return CHAR_MIN; } + +/* ?lowest@?$numeric_limits@E@std@@SAEXZ */ +unsigned char __cdecl std_numeric_limits_unsigned_char_lowest(void) { return 0; } + +/* ?lowest@?$numeric_limits@F@std@@SAFXZ */ +short __cdecl std_numeric_limits_short_lowest(void) { return SHRT_MIN; } + +/* ?lowest@?$numeric_limits@G@std@@SAGXZ */ +unsigned short __cdecl std_numeric_limits_unsigned_short_lowest(void) { return 0; } + +/* ?lowest@?$numeric_limits@H@std@@SAHXZ */ +int __cdecl std_numeric_limits_int_lowest(void) { return INT_MIN; } + +/* ?lowest@?$numeric_limits@I@std@@SAIXZ */ +unsigned int __cdecl std_numeric_limits_unsigned_int_lowest(void) { return 0; } + +/* ?lowest@?$numeric_limits@J@std@@SAJXZ */ +LONG __cdecl std_numeric_limits_long_lowest(void) { return LONG_MIN; } + +/* ?lowest@?$numeric_limits@K@std@@SAKXZ */ +ULONG __cdecl std_numeric_limits_unsigned_long_lowest(void) { return 0; } + +/* ?lowest@?$numeric_limits@M@std@@SAMXZ */ +float __cdecl std_numeric_limits_float_lowest(void) { return -FLT_MAX; } + +/* ?lowest@?$numeric_limits@N@std@@SANXZ */ +double __cdecl std_numeric_limits_double_lowest(void) { return -DBL_MAX; } + +/* ?lowest@?$numeric_limits@O@std@@SAOXZ */ +LDOUBLE __cdecl std_numeric_limits_long_double_lowest(void) { return -LDBL_MAX; } + +/* ?lowest@?$numeric_limits@_J@std@@SA_JXZ */ +__int64 __cdecl std_numeric_limits_int64_lowest(void) { return I64_MIN; } + +/* ?lowest@?$numeric_limits@_K@std@@SA_KXZ */ +unsigned __int64 __cdecl std_numeric_limits_unsigned_int64_lowest(void) { return 0; } + +/* ?lowest@?$numeric_limits@_N@std@@SA_NXZ */ +BOOLEAN __cdecl std_numeric_limits_bool_lowest(void) { return FALSE; } + +/* ?lowest@?$numeric_limits@_W@std@@SA_WXZ */ +WCHAR __cdecl std_numeric_limits_wchar_t_lowest(void) { return 0; } + /* ?quiet_NaN@?$numeric_limits@C@std@@SACXZ -> public: static signed char __cdecl std::numeric_limits::quiet_NaN(void) */ signed char __cdecl std_numeric_limits_signed_char_quiet_NaN(void) { return 0; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp90/tests/misc.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp90/tests/misc.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcp90/tests/misc.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcp90/tests/misc.c 2016-02-08 19:32:34.000000000 +0000 @@ -991,6 +991,65 @@ ok(almost_eq(c2.imag, 0.00035447), "c2.imag = %g\n", c2.imag); } +static struct { + int value[2]; + const char* export_name; +} vbtable_size_exports_list[] = { + {{0x5c, 0xa8}, "??_8?$basic_fstream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"}, + {{0x54, 0x98}, "??_8?$basic_fstream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"}, + {{0x5c, 0xa8}, "??_8?$basic_fstream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"}, + {{0x54, 0x98}, "??_8?$basic_fstream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"}, + {{0x5c, 0xa8}, "??_8?$basic_fstream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"}, + {{0x54, 0x98}, "??_8?$basic_fstream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"}, + {{0x58, 0xa0}, "??_8?$basic_ifstream@DU?$char_traits@D@std@@@std@@7B@"}, + {{0x58, 0xa0}, "??_8?$basic_ifstream@GU?$char_traits@G@std@@@std@@7B@"}, + {{0x58, 0xa0}, "??_8?$basic_ifstream@_WU?$char_traits@_W@std@@@std@@7B@"}, + {{ 0xc, 0x18}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"}, + {{ 0x4, 0x8}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"}, + {{ 0xc, 0x18}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"}, + {{ 0x4, 0x8}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"}, + {{ 0xc, 0x18}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"}, + {{ 0x4, 0x8}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"}, + {{ 0x8, 0x10}, "??_8?$basic_istream@DU?$char_traits@D@std@@@std@@7B@"}, + {{ 0x8, 0x10}, "??_8?$basic_istream@GU?$char_traits@G@std@@@std@@7B@"}, + {{ 0x8, 0x10}, "??_8?$basic_istream@_WU?$char_traits@_W@std@@@std@@7B@"}, + {{0x50, 0x90}, "??_8?$basic_istringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@7B@"}, + {{0x50, 0x90}, "??_8?$basic_istringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@7B@"}, + {{0x50, 0x90}, "??_8?$basic_istringstream@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@7B@"}, + {{0x54, 0x98}, "??_8?$basic_ofstream@DU?$char_traits@D@std@@@std@@7B@"}, + {{0x54, 0x98}, "??_8?$basic_ofstream@GU?$char_traits@G@std@@@std@@7B@"}, + {{0x54, 0x98}, "??_8?$basic_ofstream@_WU?$char_traits@_W@std@@@std@@7B@"}, + {{ 0x4, 0x8}, "??_8?$basic_ostream@DU?$char_traits@D@std@@@std@@7B@"}, + {{ 0x4, 0x8}, "??_8?$basic_ostream@GU?$char_traits@G@std@@@std@@7B@"}, + {{ 0x4, 0x8}, "??_8?$basic_ostream@_WU?$char_traits@_W@std@@@std@@7B@"}, + {{0x4c, 0x88}, "??_8?$basic_ostringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@7B@"}, + {{0x4c, 0x88}, "??_8?$basic_ostringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@7B@"}, + {{0x4c, 0x88}, "??_8?$basic_ostringstream@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@7B@"}, + {{0x54, 0x98}, "??_8?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"}, + {{0x4c, 0x88}, "??_8?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"}, + {{0x54, 0x98}, "??_8?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"}, + {{0x4c, 0x88}, "??_8?$basic_stringstream@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"}, + {{0x54, 0x98}, "??_8?$basic_stringstream@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"}, + {{0x4c, 0x88}, "??_8?$basic_stringstream@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"}, + {{ 0x0, 0x0}, 0} +}; + +static void test_vbtable_size_exports(void) +{ + int i; + const int *p_vbtable; + int arch_idx = (sizeof(void*) == 8); + + for (i = 0; vbtable_size_exports_list[i].export_name; i++) + { + SET(p_vbtable, vbtable_size_exports_list[i].export_name); + + ok(p_vbtable[0] == 0, "vbtable[0] wrong, got 0x%x\n", p_vbtable[0]); + ok(p_vbtable[1] == vbtable_size_exports_list[i].value[arch_idx], + "%d: %s[1] wrong, got 0x%x\n", i, vbtable_size_exports_list[i].export_name, p_vbtable[1]); + } +} + START_TEST(misc) { if(!init()) @@ -1008,6 +1067,7 @@ test_allocator_char(); test_Ctraits_math_functions(); test_complex(); + test_vbtable_size_exports(); ok(!invalid_parameter, "invalid_parameter_handler was invoked too many times\n"); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr100/msvcr100.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr100/msvcr100.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr100/msvcr100.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr100/msvcr100.spec 2016-02-08 19:32:34.000000000 +0000 @@ -745,7 +745,8 @@ @ cdecl _cputws(wstr) @ cdecl _creat(str long) MSVCRT__creat @ cdecl _create_locale(long str) MSVCRT__create_locale -@ stub _crt_debugger_hook +@ cdecl -arch=i386 _crt_debugger_hook(long) MSVCRT__crt_debugger_hook +@ cdecl -arch=arm,win64 __crt_debugger_hook(long) MSVCRT__crt_debugger_hook @ varargs _cscanf(str) @ varargs _cscanf_l(str ptr) @ varargs _cscanf_s(str) @@ -1635,7 +1636,7 @@ @ cdecl -arch=arm,x86_64 atanf(float) MSVCRT_atanf @ cdecl atan2(double double) MSVCRT_atan2 @ cdecl -arch=arm,x86_64 atan2f(float float) MSVCRT_atan2f -@ cdecl atexit(ptr) MSVCRT_atexit +@ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw @ cdecl atof(str) MSVCRT_atof @ cdecl atoi(str) MSVCRT_atoi @ cdecl atol(str) ntdll.atol diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr110/msvcr110.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr110/msvcr110.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr110/msvcr110.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr110/msvcr110.spec 2016-02-08 19:32:34.000000000 +0000 @@ -866,7 +866,7 @@ @ stub _Unlock_shared_ptr_spin_lock @ cdecl _W_Getdays() @ cdecl _W_Getmonths() -@ stub _W_Gettnames +@ cdecl _W_Gettnames() @ stub _Wcsftime @ cdecl _XcptFilter(long ptr) @ cdecl __AdjustPointer(ptr ptr) @@ -1093,8 +1093,8 @@ @ cdecl _cputws(wstr) @ cdecl _creat(str long) MSVCRT__creat @ cdecl _create_locale(long str) MSVCRT__create_locale -@ stub -arch=i386 _crt_debugger_hook -@ stub -arch=arm,win64 __crt_debugger_hook +@ cdecl -arch=i386 _crt_debugger_hook(long) MSVCRT__crt_debugger_hook +@ cdecl -arch=arm,win64 __crt_debugger_hook(long) MSVCRT__crt_debugger_hook @ varargs _cscanf(str) @ varargs _cscanf_l(str ptr) @ varargs _cscanf_s(str) @@ -1993,7 +1993,7 @@ @ cdecl -arch=arm,x86_64 atanf(float) MSVCRT_atanf @ cdecl atan2(double double) MSVCRT_atan2 @ cdecl -arch=arm,x86_64 atan2f(float float) MSVCRT_atan2f -@ cdecl atexit(ptr) MSVCRT_atexit +@ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw @ cdecl atof(str) MSVCRT_atof @ cdecl atoi(str) MSVCRT_atoi @ cdecl atol(str) ntdll.atol diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr120/msvcr120.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr120/msvcr120.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr120/msvcr120.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr120/msvcr120.spec 2016-02-08 19:32:34.000000000 +0000 @@ -850,7 +850,7 @@ @ cdecl _Strftime(str long str ptr ptr) @ cdecl _W_Getdays() @ cdecl _W_Getmonths() -@ stub _W_Gettnames +@ cdecl _W_Gettnames() @ stub _Wcsftime @ cdecl _XcptFilter(long ptr) @ cdecl __AdjustPointer(ptr ptr) @@ -1084,8 +1084,8 @@ @ cdecl _cputws(wstr) @ cdecl _creat(str long) MSVCRT__creat @ cdecl _create_locale(long str) MSVCRT__create_locale -@ stub -arch=i386 _crt_debugger_hook -@ stub -arch=arm,win64 __crt_debugger_hook +@ cdecl -arch=i386 _crt_debugger_hook(long) MSVCRT__crt_debugger_hook +@ cdecl -arch=arm,win64 __crt_debugger_hook(long) MSVCRT__crt_debugger_hook @ varargs _cscanf(str) @ varargs _cscanf_l(str ptr) @ varargs _cscanf_s(str) @@ -1110,7 +1110,7 @@ @ cdecl _difftime32(long long) MSVCRT__difftime32 @ cdecl _difftime64(long long) MSVCRT__difftime64 @ stub _dosmaperr -@ stub _dpcomp +@ cdecl _dpcomp(double double) MSVCR120__dpcomp @ cdecl _dsign(double) MSVCR120__dsign @ extern _dstbias MSVCRT__dstbias @ cdecl _dtest(ptr) MSVCR120__dtest @@ -1144,7 +1144,7 @@ @ cdecl _fcvt_s(ptr long double long ptr ptr) MSVCRT__fcvt_s @ cdecl _fdclass(float) MSVCR120__fdclass @ cdecl _fdopen(long str) MSVCRT__fdopen -@ stub _fdpcomp +@ cdecl _fdpcomp(float float) MSVCR120__fdpcomp @ cdecl _fdsign(float) MSVCR120__fdsign @ cdecl _fdtest(ptr) MSVCR120__fdtest @ cdecl _fflush_nolock(ptr) MSVCRT__fflush_nolock @@ -1392,7 +1392,7 @@ @ cdecl _jn(long double) MSVCRT__jn @ cdecl _kbhit() @ cdecl _ldclass(double) MSVCR120__ldclass -@ stub _ldpcomp +@ cdecl _ldpcomp(double double) MSVCR120__dpcomp @ cdecl _ldsign(double) MSVCR120__dsign @ cdecl _ldtest(ptr) MSVCR120__ldtest @ cdecl _lfind(ptr ptr ptr long ptr) @@ -1639,7 +1639,7 @@ @ stdcall -arch=i386 _seh_longjmp_unwind4(ptr) @ stdcall -arch=i386 _seh_longjmp_unwind(ptr) @ cdecl -arch=i386 _set_SSE2_enable(long) MSVCRT__set_SSE2_enable -@ stub -arch=win64 _set_FMA3_enable +@ cdecl -arch=win64 _set_FMA3_enable(long) MSVCRT__set_FMA3_enable @ cdecl _set_abort_behavior(long long) MSVCRT__set_abort_behavior @ cdecl _set_controlfp(long long) @ cdecl _set_doserrno(long) @@ -2028,7 +2028,7 @@ @ stub atanh @ stub atanhf @ stub atanhl -@ cdecl atexit(ptr) MSVCRT_atexit +@ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw @ cdecl atof(str) MSVCRT_atof @ cdecl atoi(str) MSVCRT_atoi @ cdecl atol(str) ntdll.atol @@ -2299,9 +2299,9 @@ @ stub nearbyint @ stub nearbyintf @ stub nearbyintl -@ stub nextafter -@ stub nextafterf -@ stub nextafterl +@ cdecl nextafter(double double) MSVCRT__nextafter +@ cdecl nextafterf(float float) MSVCRT__nextafterf +@ cdecl nextafterl(double double) MSVCRT__nextafter @ stub nexttoward @ stub nexttowardf @ stub nexttowardl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr120/tests/msvcr120.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr120/tests/msvcr120.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr120/tests/msvcr120.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr120/tests/msvcr120.c 2016-02-08 19:32:34.000000000 +0000 @@ -24,10 +24,25 @@ #include #include +#include #include "wine/test.h" #include +static inline float __port_infinity(void) +{ + static const unsigned __inf_bytes = 0x7f800000; + return *(const float *)&__inf_bytes; +} +#define INFINITY __port_infinity() + +static inline float __port_nan(void) +{ + static const unsigned __nan_bytes = 0x7fc00000; + return *(const float *)&__nan_bytes; +} +#define NAN __port_nan() + struct MSVCRT_lconv { char* decimal_point; @@ -63,8 +78,11 @@ static size_t (CDECL *p_wcstombs_s)(size_t *ret, char* dest, size_t sz, const wchar_t* src, size_t max); static int (CDECL *p__dsign)(double); static int (CDECL *p__fdsign)(float); +static int (__cdecl *p__dpcomp)(double x, double y); static wchar_t** (CDECL *p____lc_locale_name_func)(void); static unsigned int (CDECL *p__GetConcurrency)(void); +static void* (CDECL *p__W_Gettnames)(void); +static void (CDECL *p_free)(void*); static BOOL init(void) { @@ -82,8 +100,11 @@ p_wcstombs_s = (void*)GetProcAddress(module, "wcstombs_s"); p__dsign = (void*)GetProcAddress(module, "_dsign"); p__fdsign = (void*)GetProcAddress(module, "_fdsign"); + p__dpcomp = (void*)GetProcAddress(module, "_dpcomp"); p____lc_locale_name_func = (void*)GetProcAddress(module, "___lc_locale_name_func"); p__GetConcurrency = (void*)GetProcAddress(module,"?_GetConcurrency@details@Concurrency@@YAIXZ"); + p__W_Gettnames = (void*)GetProcAddress(module, "_W_Gettnames"); + p_free = (void*)GetProcAddress(module, "free"); return TRUE; } @@ -175,6 +196,26 @@ ok(ret == 0x8000, "p_fdsign(-1) = %x\n", ret); } +static void test__dpcomp(void) +{ + struct { + double x, y; + int ret; + } tests[] = { + {0, 0, 2}, {1, 1, 2}, {-1, -1, 2}, + {-2, -1, 1}, {-1, 1, 1}, {1, 2, 1}, + {1, -1, 4}, {2, 1, 4}, {-1, -2, 4}, + {NAN, NAN, 0}, {NAN, 1, 0}, {1, NAN, 0}, + {INFINITY, INFINITY, 2}, {-1, INFINITY, 1}, {1, INFINITY, 1}, + }; + int i, ret; + + for(i=0; istr[0]-(char*)ret; + if(sizeof(void*) == 8) + ok(size==0x2c0, "structure size: %x\n", size); + else + ok(size==0x164, "structure size: %x\n", size); + + for(i=0; istr[i], str[i]), "ret->str[%d] = %s, expected %s\n", + i, ret->str[i], str[i]); + + MultiByteToWideChar(CP_ACP, 0, str[i], strlen(str[i])+1, + buf, sizeof(buf)/sizeof(*buf)); + ok(!lstrcmpW(ret->wstr[i], buf), "ret->wstr[%d] = %s, expected %s\n", + i, wine_dbgstr_w(ret->wstr[i]), wine_dbgstr_w(buf)); + } + p_free(ret); + + p_setlocale(LC_ALL, "C"); +} + START_TEST(msvcr120) { if (!init()) return; test_lconv(); test__dsign(); + test__dpcomp(); test____lc_locale_name_func(); test__GetConcurrency(); + test__W_Gettnames(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr120_app/msvcr120_app.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr120_app/msvcr120_app.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr120_app/msvcr120_app.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr120_app/msvcr120_app.spec 2016-02-08 19:32:34.000000000 +0000 @@ -844,7 +844,7 @@ @ cdecl _Strftime(str long str ptr ptr) msvcr120._Strftime @ cdecl _W_Getdays() msvcr120._W_Getdays @ cdecl _W_Getmonths() msvcr120._W_Getmonths -@ stub _W_Gettnames +@ cdecl _W_Gettnames() msvcr120._W_Gettnames @ stub _Wcsftime @ cdecl _XcptFilter(long ptr) msvcr120._XcptFilter @ cdecl __AdjustPointer(ptr ptr) msvcr120.__AdjustPointer @@ -1038,8 +1038,8 @@ @ cdecl _copysignf(float float) msvcr120._copysignf @ cdecl _creat(str long) msvcr120._creat @ cdecl _create_locale(long str) msvcr120._create_locale -@ stub -arch=i386 _crt_debugger_hook -@ stub -arch=arm,win64 __crt_debugger_hook +@ cdecl -arch=i386 _crt_debugger_hook(long) msvcr120._crt_debugger_hook +@ cdecl -arch=arm,win64 __crt_debugger_hook(long) msvcr120.__crt_debugger_hook @ cdecl _ctime32(ptr) msvcr120._ctime32 @ cdecl _ctime32_s(str long ptr) msvcr120._ctime32_s @ cdecl _ctime64(ptr) msvcr120._ctime64 @@ -1049,7 +1049,7 @@ @ cdecl _difftime32(long long) msvcr120._difftime32 @ cdecl _difftime64(long long) msvcr120._difftime64 @ stub _dosmaperr -@ stub _dpcomp +@ cdecl _dpcomp(double double) msvcr120._dpcomp @ cdecl _dsign(double) msvcr120._dsign @ extern _dstbias msvcr120._dstbias @ cdecl _dtest(ptr) msvcr120._dtest @@ -1072,7 +1072,7 @@ @ cdecl _fcvt_s(ptr long double long ptr ptr) msvcr120._fcvt_s @ cdecl _fdclass(float) msvcr120._fdclass @ cdecl _fdopen(long str) msvcr120._fdopen -@ stub _fdpcomp +@ cdecl _fdpcomp(float float) msvcr120._fdpcomp @ cdecl _fdsign(float) msvcr120._fdsign @ cdecl _fdtest(ptr) msvcr120._fdtest @ cdecl _fflush_nolock(ptr) msvcr120._fflush_nolock @@ -1256,7 +1256,7 @@ @ cdecl _j1(double) msvcr120._j1 @ cdecl _jn(long double) msvcr120._jn @ cdecl _ldclass(double) msvcr120._ldclass -@ stub _ldpcomp +@ cdecl _ldpcomp(double double) msvcr120._ldpcomp @ cdecl _ldsign(double) msvcr120._ldsign @ cdecl _ldtest(ptr) msvcr120._ldtest @ cdecl _lfind(ptr ptr ptr long ptr) msvcr120._lfind @@ -1694,7 +1694,7 @@ @ stub atanh @ stub atanhf @ stub atanhl -@ cdecl atexit(ptr) msvcr120.atexit +@ cdecl -private atexit(ptr) msvcr120.atexit @ cdecl atof(str) msvcr120.atof @ cdecl atoi(str) msvcr120.atoi @ cdecl atol(str) msvcr120.atol @@ -1962,9 +1962,9 @@ @ stub nearbyint @ stub nearbyintf @ stub nearbyintl -@ stub nextafter -@ stub nextafterf -@ stub nextafterl +@ cdecl nextafter(double double) msvcr120.nextafter +@ cdecl nextafterf(float float) msvcr120.nextafterf +@ cdecl nextafterl(double double) msvcr120.nextafterl @ stub nexttoward @ stub nexttowardf @ stub nexttowardl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr70/msvcr70.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr70/msvcr70.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr70/msvcr70.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr70/msvcr70.spec 2016-02-08 19:32:34.000000000 +0000 @@ -686,7 +686,7 @@ @ cdecl asin(double) MSVCRT_asin @ cdecl atan(double) MSVCRT_atan @ cdecl atan2(double double) MSVCRT_atan2 -@ cdecl atexit(ptr) MSVCRT_atexit +@ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw @ cdecl atof(str) MSVCRT_atof @ cdecl atoi(str) MSVCRT_atoi @ cdecl atol(str) ntdll.atol diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr71/msvcr71.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr71/msvcr71.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr71/msvcr71.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr71/msvcr71.spec 2016-02-08 19:32:34.000000000 +0000 @@ -682,7 +682,7 @@ @ cdecl asin(double) MSVCRT_asin @ cdecl atan(double) MSVCRT_atan @ cdecl atan2(double double) MSVCRT_atan2 -@ cdecl atexit(ptr) MSVCRT_atexit +@ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw @ cdecl atof(str) MSVCRT_atof @ cdecl atoi(str) MSVCRT_atoi @ cdecl atol(str) ntdll.atol diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr80/msvcr80.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr80/msvcr80.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr80/msvcr80.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr80/msvcr80.spec 2016-02-08 19:32:34.000000000 +0000 @@ -409,8 +409,8 @@ @ cdecl _cputws(wstr) @ cdecl _creat(str long) MSVCRT__creat @ cdecl _create_locale(long str) MSVCRT__create_locale -@ stub -arch=i386 _crt_debugger_hook -@ stub -arch=arm,win64 __crt_debugger_hook +@ cdecl -arch=i386 _crt_debugger_hook(long) MSVCRT__crt_debugger_hook +@ cdecl -arch=arm,win64 __crt_debugger_hook(long) MSVCRT__crt_debugger_hook @ varargs _cscanf(str) @ varargs _cscanf_l(str ptr) @ varargs _cscanf_s(str) @@ -1318,7 +1318,7 @@ @ cdecl -arch=arm,x86_64 atanf(float) MSVCRT_atanf @ cdecl atan2(double double) MSVCRT_atan2 @ cdecl -arch=arm,x86_64 atan2f(float float) MSVCRT_atan2f -@ cdecl atexit(ptr) MSVCRT_atexit +@ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw @ cdecl atof(str) MSVCRT_atof @ cdecl atoi(str) MSVCRT_atoi @ cdecl atol(str) ntdll.atol diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr90/msvcr90.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr90/msvcr90.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcr90/msvcr90.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcr90/msvcr90.spec 2016-02-08 19:32:34.000000000 +0000 @@ -392,7 +392,8 @@ @ cdecl _cputws(wstr) @ cdecl _creat(str long) MSVCRT__creat @ cdecl _create_locale(long str) MSVCRT__create_locale -@ stub _crt_debugger_hook +@ cdecl -arch=i386 _crt_debugger_hook(long) MSVCRT__crt_debugger_hook +@ cdecl -arch=arm,win64 __crt_debugger_hook(long) MSVCRT__crt_debugger_hook @ varargs _cscanf(str) @ varargs _cscanf_l(str ptr) @ varargs _cscanf_s(str) @@ -1290,7 +1291,7 @@ @ cdecl -arch=arm,x86_64 asinf(float) MSVCRT_asinf @ cdecl -arch=arm,x86_64 atan2f(float float) MSVCRT_atan2f @ cdecl -arch=arm,x86_64 atanf(float) MSVCRT_atanf -@ cdecl atexit(ptr) MSVCRT_atexit +@ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw @ cdecl atof(str) MSVCRT_atof @ cdecl atoi(str) MSVCRT_atoi @ cdecl atol(str) ntdll.atol diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/locale.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/locale.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/locale.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/locale.c 2016-02-08 19:32:34.000000000 +0000 @@ -580,6 +580,14 @@ } /********************************************************************* + * _W_Gettnames (MSVCR110.@) + */ +void* CDECL _W_Gettnames(void) +{ + return _Gettnames(); +} + +/********************************************************************* * __crtLCMapStringA (MSVCRT.@) */ int CDECL __crtLCMapStringA( @@ -1528,6 +1536,9 @@ size += ret*sizeof(MSVCRT_wchar_t); } } +#if _MSVCR_VER >= 110 + size += LCIDToLocaleName(lcid[MSVCRT_LC_TIME], NULL, 0, 0)*sizeof(MSVCRT_wchar_t); +#endif locinfo->lc_time_curr = MSVCRT_malloc(size); if(!locinfo->lc_time_curr) { @@ -1568,7 +1579,13 @@ (MSVCRT_wchar_t*)&locinfo->lc_time_curr->data[ret], size-ret)*sizeof(MSVCRT_wchar_t); } } +#if _MSVCR_VER >= 110 + locinfo->lc_time_curr->locname = (MSVCRT_wchar_t*)&locinfo->lc_time_curr->data[ret]; + LCIDToLocaleName(lcid[MSVCRT_LC_TIME], locinfo->lc_time_curr->locname, + (size-ret)/sizeof(MSVCRT_wchar_t), 0); +#else locinfo->lc_time_curr->lcid = lcid[MSVCRT_LC_TIME]; +#endif } return locinfo; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/main.c 2016-02-08 19:32:34.000000000 +0000 @@ -67,7 +67,6 @@ if (tls) { - CloseHandle(tls->handle); MSVCRT_free(tls->efcvt_buffer); MSVCRT_free(tls->asctime_buffer); MSVCRT_free(tls->wasctime_buffer); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/math.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/math.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/math.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/math.c 2016-02-08 19:32:34.000000000 +0000 @@ -73,6 +73,17 @@ return sse2_enabled; } +#ifdef _WIN64 +/********************************************************************* + * _set_FMA3_enable (MSVCR120.@) + */ +int CDECL MSVCRT__set_FMA3_enable(int flag) +{ + FIXME("(%x) stub\n", flag); + return 0; +} +#endif + #if defined(__x86_64__) || defined(__arm__) || _MSVCR_VER>=120 /********************************************************************* @@ -94,6 +105,15 @@ return signbit(num) ? -num : num; } +/********************************************************************* + * _nextafterf (MSVCRT.@) + */ +float CDECL MSVCRT__nextafterf( float num, float next ) +{ + if (!finitef(num) || !finitef(next)) *MSVCRT__errno() = MSVCRT_EDOM; + return nextafterf( num, next ); +} + #endif #if defined(__x86_64__) || defined(__arm__) @@ -126,15 +146,6 @@ } /********************************************************************* - * _nextafterf (MSVCRT.@) - */ -float CDECL MSVCRT__nextafterf( float num, float next ) -{ - if (!finitef(num) || !finitef(next)) *MSVCRT__errno() = MSVCRT_EDOM; - return nextafterf( num, next ); -} - -/********************************************************************* * MSVCRT_acosf (MSVCRT.@) */ float CDECL MSVCRT_acosf( float x ) @@ -331,7 +342,7 @@ /********************************************************************* * modff (MSVCRT.@) */ -double CDECL MSVCRT_modff( float x, float *iptr ) +float CDECL MSVCRT_modff( float x, float *iptr ) { return modff( x, iptr ); } @@ -2684,6 +2695,27 @@ return signbit(x) ? 0x8000 : 0; } + +/********************************************************************* + * _dpcomp (MSVCR120.@) + */ +int CDECL MSVCR120__dpcomp(double x, double y) +{ + if(isnan(x) || isnan(y)) + return 0; + + if(x == y) return 2; + return x < y ? 1 : 4; +} + +/********************************************************************* + * _fdpcomp (MSVCR120.@) + */ +int CDECL MSVCR120__fdpcomp(float x, float y) +{ + return MSVCR120__dpcomp(x, y); +} + /********************************************************************* * fminf (MSVCR120.@) */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/misc.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/misc.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/misc.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/misc.c 2016-02-08 19:32:34.000000000 +0000 @@ -498,3 +498,11 @@ { __ms_va_copy(*dest, src); } + +/********************************************************************* + * _crt_debugger_hook (MSVCR80.@) + */ +void CDECL MSVCRT__crt_debugger_hook(int reserved) +{ + WARN("(%x)\n", reserved); +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/msvcrt.h wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/msvcrt.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/msvcrt.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/msvcrt.h 2016-02-08 19:32:34.000000000 +0000 @@ -132,7 +132,9 @@ char *time; } names; } str; +#if _MSVCR_VER < 110 LCID lcid; +#endif int unk[2]; union { MSVCRT_wchar_t *wstr[43]; @@ -148,6 +150,9 @@ MSVCRT_wchar_t *time; } names; } wstr; +#if _MSVCR_VER >= 110 + MSVCRT_wchar_t *locname; +#endif char data[1]; } MSVCRT___lc_time_data; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/msvcrt.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/msvcrt.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/msvcrt.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/msvcrt.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1253,7 +1253,7 @@ @ cdecl -arch=arm,x86_64 asinf(float) MSVCRT_asinf @ cdecl -arch=arm,x86_64 atanf(float) MSVCRT_atanf @ cdecl -arch=arm,x86_64 atan2f(float float) MSVCRT_atan2f -@ cdecl atexit(ptr) MSVCRT_atexit +@ cdecl -private atexit(ptr) MSVCRT_atexit # not imported to avoid conflicts with Mingw @ cdecl atof(str) MSVCRT_atof @ cdecl atoi(str) MSVCRT_atoi @ cdecl atol(str) ntdll.atol diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/tests/cpp.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/tests/cpp.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/tests/cpp.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/tests/cpp.c 2016-02-08 19:32:34.000000000 +0000 @@ -452,8 +452,7 @@ { /* Check the rtti */ type_info *ti = p__RTtypeid(&e); - ok (ti && ti->mangled && - !strcmp(ti->mangled, ".?AVexception@@"), "bad rtti for e\n"); + ok (ti && !strcmp(ti->mangled, ".?AVexception@@"), "bad rtti for e\n"); if (ti) { @@ -1036,15 +1035,13 @@ child_class_sig0_rtti.object_locator.type_hierarchy = RTTI_REF_SIG0(child_class_sig0_rtti, object_hierarchy, base); ti = p__RTtypeid(&simple_class_sig0); - ok (ti && ti->mangled && !strcmp(ti->mangled, "simple_class"), - "incorrect rtti data\n"); + ok (ti && !strcmp(ti->mangled, "simple_class"), "incorrect rtti data\n"); casted = p__RTCastToVoid(&simple_class_sig0); ok (casted == (void*)&simple_class_sig0, "failed cast to void\n"); ti = p__RTtypeid(&child_class_sig0); - ok (ti && ti->mangled && !strcmp(ti->mangled, "child_class"), - "incorrect rtti data\n"); + ok (ti && !strcmp(ti->mangled, "child_class"), "incorrect rtti data\n"); casted = p__RTCastToVoid(&child_class_sig0); ok (casted == (void*)&child_class_sig0, "failed cast to void\n"); @@ -1064,15 +1061,13 @@ } ti = p__RTtypeid(&simple_class); - ok (ti && ti->mangled && !strcmp(ti->mangled, "simple_class"), - "incorrect rtti data\n"); + ok (ti && !strcmp(ti->mangled, "simple_class"), "incorrect rtti data\n"); casted = p__RTCastToVoid(&simple_class); ok (casted == (void*)&simple_class, "failed cast to void\n"); ti = p__RTtypeid(&child_class); - ok (ti && ti->mangled && !strcmp(ti->mangled, "child_class"), - "incorrect rtti data\n"); + ok (ti && !strcmp(ti->mangled, "child_class"), "incorrect rtti data\n"); casted = p__RTCastToVoid(&child_class); ok (casted == (void*)&child_class, "failed cast to void\n"); @@ -1323,6 +1318,11 @@ /* 128 */ {"??Xstd@@YAAEAV?$complex@M@0@AEAV10@AEBV10@@Z", "class std::complex & std::operator*=(class std::complex &,class std::complex const &)", "??Xstd@@YAAEAV?$complex@M@0@AEAV10@AEBV10@@Z", 2}, +/* 129 */ {"??$run@XVTask_Render_Preview@@@QtConcurrent@@YA?AV?$QFuture@X@@PEAVTask_Render_Preview@@P82@EAAXXZ@Z", + "class QFuture __cdecl QtConcurrent::run(class Task_Render_Preview * __ptr64,void (__cdecl Task_Render_Preview::*)(void) __ptr64)", + "??$run@XVTask_Render_Preview@@@QtConcurrent@@YA?AV?$QFuture@X@@PEAVTask_Render_Preview@@P82@EAAXXZ@Z"}, +/* 130 */ {"??_E?$TStrArray@$$BY0BAA@D$0BA@@@UAEPAXI@Z", + "public: virtual void * __thiscall TStrArray::`vector deleting destructor'(unsigned int)"}, }; int i, num_test = (sizeof(test)/sizeof(test[0])); char* name; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/tests/locale.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/tests/locale.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/tests/locale.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/tests/locale.c 2016-02-08 19:32:34.000000000 +0000 @@ -671,12 +671,12 @@ return; ret = _Gettnames(); - size = ret->data-(char*)ret; + size = ret->str[0]-(char*)ret; /* Newer version of the structure stores both ascii and unicode strings. * Unicode strings are only initialized on Windows 7 */ if(sizeof(void*) == 8) - ok(size==0x2c0 || broken(size==0x170), "structure size: %x\n", size); + ok(size==0x2c0 || broken(size==0x168), "structure size: %x\n", size); else ok(size==0x164 || broken(size==0xb8), "structure size: %x\n", size); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/tests/misc.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/tests/misc.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/tests/misc.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/tests/misc.c 2016-02-08 19:32:34.000000000 +0000 @@ -23,6 +23,7 @@ #include #include #include "msvcrt.h" +#include static inline float __port_infinity(void) { @@ -540,6 +541,66 @@ ok(errno == 0xdeadbeef, "errno = %d\n", errno); } +static void __cdecl test_thread_func(void *end_thread_type) +{ + if (end_thread_type == (void*)1) + _endthread(); + else if (end_thread_type == (void*)2) + ExitThread(0); + else if (end_thread_type == (void*)3) + _endthreadex(0); +} + +static unsigned __stdcall test_thread_func_ex(void *arg) +{ + _endthread(); + return 0; +} + +static void test_thread_handle_close(void) +{ + HANDLE hThread; + DWORD ret; + + /* _beginthread: handle is not closed on ExitThread and _endthreadex */ + hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)0); + ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno); + WaitForSingleObject(hThread, INFINITE); + ret = CloseHandle(hThread); + ok(!ret, "ret = %d\n", ret); + + hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)1); + ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno); + WaitForSingleObject(hThread, INFINITE); + ret = CloseHandle(hThread); + ok(!ret, "ret = %d\n", ret); + + hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)2); + ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno); + Sleep(150); + ret = WaitForSingleObject(hThread, INFINITE); + ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret); + ret = CloseHandle(hThread); + ok(ret, "ret = %d\n", ret); + + hThread = (HANDLE)_beginthread(test_thread_func, 0, (void*)3); + ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno); + Sleep(150); + ret = WaitForSingleObject(hThread, INFINITE); + ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret); + ret = CloseHandle(hThread); + ok(ret, "ret = %d\n", ret); + + /* _beginthreadex: handle is not closed on _endthread */ + hThread = (HANDLE)_beginthreadex(NULL,0, test_thread_func_ex, NULL, 0, NULL); + ok(hThread != NULL, "_beginthreadex failed (%d)\n", errno); + Sleep(150); + ret = WaitForSingleObject(hThread, INFINITE); + ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret); + ret = CloseHandle(hThread); + ok(ret, "ret = %d\n", ret); +} + START_TEST(misc) { int arg_c; @@ -568,4 +629,5 @@ test__invalid_parameter(); test_qsort_s(); test_math_functions(); + test_thread_handle_close(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/thread.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/thread.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/thread.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/thread.c 2016-02-08 19:32:34.000000000 +0000 @@ -55,6 +55,38 @@ return ptr; } +/********************************************************************* + * _endthread (MSVCRT.@) + */ +void CDECL _endthread(void) +{ + thread_data_t *tls; + + TRACE("(void)\n"); + + tls = TlsGetValue(msvcrt_tls_index); + if (tls && tls->handle != INVALID_HANDLE_VALUE) + { + CloseHandle(tls->handle); + tls->handle = INVALID_HANDLE_VALUE; + } else + WARN("tls=%p tls->handle=%p\n", tls, tls ? tls->handle : INVALID_HANDLE_VALUE); + + /* FIXME */ + ExitThread(0); +} + +/********************************************************************* + * _endthreadex (MSVCRT.@) + */ +void CDECL _endthreadex( + unsigned int retval) /* [in] Thread exit code */ +{ + TRACE("(%d)\n", retval); + + /* FIXME */ + ExitThread(retval); +} /********************************************************************* * _beginthread_trampoline @@ -69,6 +101,7 @@ MSVCRT_free(arg); local_trampoline.start_address(local_trampoline.arglist); + _endthread(); return 0; } @@ -132,29 +165,6 @@ } /********************************************************************* - * _endthread (MSVCRT.@) - */ -void CDECL _endthread(void) -{ - TRACE("(void)\n"); - - /* FIXME */ - ExitThread(0); -} - -/********************************************************************* - * _endthreadex (MSVCRT.@) - */ -void CDECL _endthreadex( - unsigned int retval) /* [in] Thread exit code */ -{ - TRACE("(%d)\n", retval); - - /* FIXME */ - ExitThread(retval); -} - -/********************************************************************* * _getptd (MSVCR80.@) */ thread_data_t* CDECL _getptd(void) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/time.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/time.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/time.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/time.c 2016-02-08 19:32:34.000000000 +0000 @@ -946,6 +946,7 @@ char *format; SYSTEMTIME st; MSVCRT_size_t ret; + LCID lcid; st.wYear = mstm->tm_year + 1900; st.wMonth = mstm->tm_mon + 1; @@ -956,10 +957,16 @@ st.wSecond = mstm->tm_sec; st.wMilliseconds = 0; +#if _MSVCR_VER < 110 + lcid = time_data->lcid; +#else + lcid = LocaleNameToLCID(time_data->locname, 0); +#endif + format = alternate ? time_data->str.names.date : time_data->str.names.short_date; - ret = GetDateFormatA(time_data->lcid, 0, &st, format, NULL, 0); + ret = GetDateFormatA(lcid, 0, &st, format, NULL, 0); if(ret && retlcid, 0, &st, format, str+*pos, max-*pos); + ret = GetDateFormatA(lcid, 0, &st, format, str+*pos, max-*pos); if(!ret) { *str = 0; *MSVCRT__errno() = MSVCRT_EINVAL; @@ -978,6 +985,7 @@ { SYSTEMTIME st; MSVCRT_size_t ret; + LCID lcid; st.wYear = mstm->tm_year + 1900; st.wMonth = mstm->tm_mon + 1; @@ -988,9 +996,15 @@ st.wSecond = mstm->tm_sec; st.wMilliseconds = 0; - ret = GetTimeFormatA(time_data->lcid, 0, &st, time_data->str.names.time, NULL, 0); +#if _MSVCR_VER < 110 + lcid = time_data->lcid; +#else + lcid = LocaleNameToLCID(time_data->locname, 0); +#endif + + ret = GetTimeFormatA(lcid, 0, &st, time_data->str.names.time, NULL, 0); if(ret && retlcid, 0, &st, time_data->str.names.time, + ret = GetTimeFormatA(lcid, 0, &st, time_data->str.names.time, str+*pos, max-*pos); if(!ret) { *str = 0; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/undname.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/undname.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt/undname.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt/undname.c 2016-02-08 19:32:34.000000000 +0000 @@ -859,14 +859,55 @@ case 'P': /* Pointer */ if (isdigit(*sym->current)) { - /* FIXME: P6 = Function pointer, others who knows.. */ - if (*sym->current++ == '6') + /* FIXME: + * P6 = Function pointer + * P8 = Member function pointer + * others who knows.. */ + if (*sym->current == '8') { char* args = NULL; const char* call_conv; const char* exported; struct datatype_t sub_ct; unsigned mark = sym->stack.num; + const char* class; + const char* modifier; + const char* ptr_modif; + + sym->current++; + + if (!(class = get_class_name(sym))) + goto done; + if (!get_modifier(sym, &modifier, &ptr_modif)) + goto done; + if (modifier) + modifier = str_printf(sym, "%s %s", modifier, ptr_modif); + else if(ptr_modif[0]) + modifier = str_printf(sym, " %s", ptr_modif); + if (!get_calling_convention(*sym->current++, + &call_conv, &exported, + sym->flags & ~UNDNAME_NO_ALLOCATION_LANGUAGE)) + goto done; + if (!demangle_datatype(sym, &sub_ct, pmt_ref, FALSE)) + goto done; + + args = get_args(sym, pmt_ref, TRUE, '(', ')'); + if (!args) goto done; + sym->stack.num = mark; + + ct->left = str_printf(sym, "%s%s (%s %s::*", + sub_ct.left, sub_ct.right, call_conv, class); + ct->right = str_printf(sym, ")%s%s", args, modifier); + } + else if (*sym->current == '6') + { + char* args = NULL; + const char* call_conv; + const char* exported; + struct datatype_t sub_ct; + unsigned mark = sym->stack.num; + + sym->current++; if (!get_calling_convention(*sym->current++, &call_conv, &exported, @@ -950,7 +991,37 @@ } break; case '$': - if (*sym->current == 'C') + if (*sym->current == 'B') + { + unsigned mark = sym->stack.num; + struct datatype_t sub_ct; + const char* arr = NULL; + sym->current++; + + /* multidimensional arrays */ + if (*sym->current == 'Y') + { + const char* n1; + int num; + + sym->current++; + if (!(n1 = get_number(sym))) goto done; + num = atoi(n1); + + while (num--) + arr = str_printf(sym, "%s[%s]", arr, get_number(sym)); + } + + if (!demangle_datatype(sym, &sub_ct, pmt_ref, FALSE)) goto done; + + if (arr) + ct->left = str_printf(sym, "%s %s", sub_ct.left, arr); + else + ct->left = sub_ct.left; + ct->right = sub_ct.right; + sym->stack.num = mark; + } + else if (*sym->current == 'C') { const char *ptr, *ptr_modif; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt20/msvcrt20.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt20/msvcrt20.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt20/msvcrt20.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt20/msvcrt20.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1274,7 +1274,7 @@ @ cdecl asin(double) msvcrt.asin @ cdecl atan(double) msvcrt.atan @ cdecl atan2(double double) msvcrt.atan2 -@ cdecl atexit(ptr) msvcrt.atexit +@ cdecl -private atexit(ptr) msvcrt.atexit @ cdecl atof(str) msvcrt.atof @ cdecl atoi(str) msvcrt.atoi @ cdecl atol(str) msvcrt.atol diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt40/msvcrt40.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt40/msvcrt40.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrt40/msvcrt40.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrt40/msvcrt40.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1342,7 +1342,7 @@ @ cdecl asin(double) msvcrt.asin @ cdecl atan(double) msvcrt.atan @ cdecl atan2(double double) msvcrt.atan2 -@ cdecl atexit(ptr) msvcrt.atexit +@ cdecl -private atexit(ptr) msvcrt.atexit @ cdecl atof(str) msvcrt.atof @ cdecl atoi(str) msvcrt.atoi @ cdecl atol(str) msvcrt.atol diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrtd/msvcrtd.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrtd/msvcrtd.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msvcrtd/msvcrtd.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msvcrtd/msvcrtd.spec 2016-02-08 19:32:34.000000000 +0000 @@ -638,7 +638,7 @@ @ cdecl asin(double) msvcrt.asin @ cdecl atan(double) msvcrt.atan @ cdecl atan2(double double) msvcrt.atan2 -@ cdecl atexit(ptr) msvcrt.atexit +@ cdecl -private atexit(ptr) msvcrt.atexit @ cdecl atof(str) msvcrt.atof @ cdecl atoi(str) msvcrt.atoi @ cdecl atol(str) msvcrt.atol diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/domdoc.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/domdoc.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/domdoc.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/domdoc.c 2016-02-08 19:32:34.000000000 +0000 @@ -1244,8 +1244,31 @@ IXMLDOMNode** outNode) { domdoc *This = impl_from_IXMLDOMDocument3( iface ); + xmlNodePtr clone; + TRACE("(%p)->(%d %p)\n", This, deep, outNode); - return node_clone( &This->node, deep, outNode ); + + if (!outNode) + return E_INVALIDARG; + + *outNode = NULL; + + clone = xmlCopyNode((xmlNodePtr)get_doc(This), deep ? 1 : 2); + if (!clone) + return E_FAIL; + + clone->doc->_private = create_priv(); + xmldoc_add_orphan(clone->doc, clone); + xmldoc_add_ref(clone->doc); + + priv_from_xmlDocPtr(clone->doc)->properties = copy_properties(This->properties); + if (!(*outNode = (IXMLDOMNode*)create_domdoc(clone))) + { + xmldoc_release(clone->doc); + return E_FAIL; + } + + return S_OK; } @@ -3640,16 +3663,16 @@ IUnknown* create_domdoc( xmlNodePtr document ) { - void* pObj = NULL; + IUnknown *obj = NULL; HRESULT hr; TRACE("(%p)\n", document); - hr = get_domdoc_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&pObj); + hr = get_domdoc_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&obj); if (FAILED(hr)) return NULL; - return pObj; + return obj; } #else diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/node.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/node.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/node.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/node.c 2016-02-08 19:32:34.000000000 +0000 @@ -778,8 +778,8 @@ xmlFree(tmp); tmp = NULL; } - break; } + break; case XML_CDATA_SECTION_NODE: case XML_ENTITY_REF_NODE: case XML_ENTITY_NODE: diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/tests/domdoc.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/tests/domdoc.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/tests/domdoc.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/tests/domdoc.c 2016-02-08 19:32:34.000000000 +0000 @@ -4821,7 +4821,8 @@ static void test_cloneNode(void ) { - IXMLDOMDocument *doc, *doc2; + IXMLDOMDocument2 *doc, *doc_clone; + IXMLDOMDocument *doc2; VARIANT_BOOL b; IXMLDOMNodeList *pList; IXMLDOMNamedNodeMap *mapAttr; @@ -4830,14 +4831,52 @@ IXMLDOMNode *node, *attr; IXMLDOMNode *node_clone; IXMLDOMNode *node_first; + VARIANT v; HRESULT hr; - doc = create_document(&IID_IXMLDOMDocument); + doc = create_document(&IID_IXMLDOMDocument2); - ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b)); + hr = IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b); + ok(hr == S_OK, "got 0x%08x\n", hr); ok(b == VARIANT_TRUE, "failed to load XML string\n"); - hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc/pr"), &node); + hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &v); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(V_BSTR(&v), _bstr_("XSLPattern")), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + V_BSTR(&v) = _bstr_("XPath"); + V_VT(&v) = VT_BSTR; + hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), v); + ok(hr == S_OK, "got 0x%08x\n", hr); + VariantClear(&v); + + /* clone document node */ + hr = IXMLDOMDocument2_cloneNode(doc, VARIANT_TRUE, &node); + ok( hr == S_OK, "ret %08x\n", hr ); + ok( node != NULL, "node %p\n", node ); + + hr = IXMLDOMNode_get_childNodes(node, &pList); + ok( hr == S_OK, "ret %08x\n", hr ); + length = 0; + hr = IXMLDOMNodeList_get_length(pList, &length); + ok( hr == S_OK, "ret %08x\n", hr ); + ok(length == 2, "got %d\n", length); + IXMLDOMNodeList_Release(pList); + + hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocument2, (void**)&doc_clone); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* cloned document inherits properties */ + hr = IXMLDOMDocument2_getProperty(doc_clone, _bstr_("SelectionLanguage"), &v); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(V_BSTR(&v), _bstr_("XPath")), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + IXMLDOMDocument2_Release(doc_clone); + IXMLDOMNode_Release(node); + + hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("lc/pr"), &node); ok( hr == S_OK, "ret %08x\n", hr ); ok( node != NULL, "node %p\n", node ); @@ -4925,7 +4964,7 @@ IXMLDOMNode_Release(node_clone); IXMLDOMNode_Release(node); - IXMLDOMDocument_Release(doc); + IXMLDOMDocument2_Release(doc); free_bstrs(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/tests/httpreq.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/tests/httpreq.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/tests/httpreq.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/tests/httpreq.c 2016-02-08 19:32:34.000000000 +0000 @@ -1684,6 +1684,7 @@ hr = GetHGlobalFromStream((IStream*)V_UNKNOWN(&varbody), &g); EXPECT_HR(hr, S_OK); ok(g != NULL, "got %p\n", g); + VariantClear(&varbody); IDispatch_Release(event); @@ -1751,6 +1752,7 @@ test_open(xhr, "GET", "http://www.test.winehq.org/tests/hello.html", E_ACCESSDENIED); IXMLHttpRequest_Release(xhr); + free_bstrs(); } START_TEST(httpreq) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/tests/saxreader.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/tests/saxreader.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/tests/saxreader.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/tests/saxreader.c 2016-02-08 19:32:34.000000000 +0000 @@ -298,7 +298,10 @@ SysFreeString(call_seq->sequence[i].attributes[j].uriW); SysFreeString(call_seq->sequence[i].attributes[j].localW); SysFreeString(call_seq->sequence[i].attributes[j].qnameW); + SysFreeString(call_seq->sequence[i].attributes[j].valueW); } + HeapFree(GetProcessHeap(), 0, call_seq->sequence[i].attributes); + call_seq->sequence[i].attr_count = 0; SysFreeString(call_seq->sequence[i].arg1W); SysFreeString(call_seq->sequence[i].arg2W); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/tests/schema.c wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/tests/schema.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/msxml3/tests/schema.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/msxml3/tests/schema.c 2016-02-08 19:32:34.000000000 +0000 @@ -1316,6 +1316,7 @@ EXPECT_HR(hr, S_FALSE); ok(V_VT(&type) == VT_NULL, "%s: got type %i\n", ptr->query, V_VT(&type)); } + VariantClear(&type); VariantClear(&v); hr = IXMLDOMNode_get_nodeTypedValue(node, &v); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ndis.sys/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ndis.sys/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ndis.sys/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ndis.sys/main.c 2016-02-08 19:32:34.000000000 +0000 @@ -26,6 +26,7 @@ #include "winbase.h" #include "winternl.h" #include "ddk/wdm.h" +#include "ddk/ndis.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ndis); @@ -36,3 +37,14 @@ return STATUS_SUCCESS; } + +NDIS_STATUS WINAPI NdisAllocateMemoryWithTag(void **address, UINT length, ULONG tag) +{ + FIXME("(%p, %u, %u): stub\n", address, length, tag); + return NDIS_STATUS_FAILURE; +} + +void WINAPI NdisAllocateSpinLock(NDIS_SPIN_LOCK *lock) +{ + FIXME("(%p): stub\n", lock); +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ndis.sys/ndis.sys.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/ndis.sys/ndis.sys.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ndis.sys/ndis.sys.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ndis.sys/ndis.sys.spec 2016-02-08 19:32:34.000000000 +0000 @@ -12,11 +12,11 @@ @ stub NdisAllocateBufferPool @ stub NdisAllocateFromBlockPool @ stub NdisAllocateMemory -@ stub NdisAllocateMemoryWithTag +@ stdcall NdisAllocateMemoryWithTag(ptr long long) @ stub NdisAllocatePacket @ stub NdisAllocatePacketPool @ stub NdisAllocatePacketPoolEx -@ stub NdisAllocateSpinLock +@ stdcall NdisAllocateSpinLock(ptr) @ stub NdisAnsiStringToUnicodeString @ stub NdisBufferLength @ stub NdisBufferVirtualAddress diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/cdrom.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/cdrom.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/cdrom.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/cdrom.c 2016-02-08 19:32:34.000000000 +0000 @@ -667,7 +667,7 @@ NTSTATUS ret = STATUS_SUCCESS; int empty = -1; - fstat(fd, &st); + if (fstat(fd, &st) == -1) return FILE_GetNtStatus(); RtlEnterCriticalSection( &cache_section ); for (*dev = 0; *dev < MAX_CACHE_ENTRIES; (*dev)++) @@ -748,8 +748,8 @@ static NTSTATUS CDROM_GetDriveGeometry(int dev, int fd, DISK_GEOMETRY* dg) { CDROM_TOC toc; - NTSTATUS ret = 0; - int fsize = 0; + NTSTATUS ret; + int fsize; if ((ret = CDROM_ReadTOC(dev, fd, &toc)) != 0) return ret; @@ -2432,7 +2432,7 @@ static NTSTATUS DVD_GetRegion(int fd, PDVD_REGION region) { #if defined(linux) - NTSTATUS ret = STATUS_NOT_SUPPORTED; + NTSTATUS ret; dvd_struct dvd; dvd_authinfo auth_info; @@ -2460,7 +2460,7 @@ dk_dvd_read_structure_t dvd; DVDRegionPlaybackControlInfo rpc; DVDCopyrightInfo copy; - NTSTATUS ret = STATUS_NOT_SUPPORTED; + NTSTATUS ret; key.format = kDVDKeyFormatRegionState; key.keyClass = kDVDKeyClassCSS_CPPM_CPRM; @@ -2636,7 +2636,7 @@ break; } #elif defined(__APPLE__) - NTSTATUS ret = STATUS_NOT_SUPPORTED; + NTSTATUS ret; dk_dvd_read_structure_t dvdrs; union { @@ -2771,7 +2771,7 @@ static NTSTATUS GetInquiryData(int fd, PSCSI_ADAPTER_BUS_INFO BufferOut, DWORD OutBufferSize) { #ifdef HAVE_SG_IO_HDR_T_INTERFACE_ID - PSCSI_INQUIRY_DATA pInquiryData = NULL; + PSCSI_INQUIRY_DATA pInquiryData; UCHAR sense_buffer[32]; int iochk, version; sg_io_hdr_t iocmd; @@ -2834,7 +2834,7 @@ { DWORD sz = 0; NTSTATUS status = STATUS_SUCCESS; - int fd, needs_close, dev; + int fd, needs_close, dev = 0; TRACE("%p %s %p %d %p %d %p\n", hDevice, iocodex(dwIoControlCode), lpInBuffer, nInBufferSize, diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/debugbuffer.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/debugbuffer.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/debugbuffer.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/debugbuffer.c 2016-02-08 19:32:34.000000000 +0000 @@ -91,7 +91,7 @@ PDEBUG_BUFFER WINAPI RtlCreateQueryDebugBuffer(IN ULONG iSize, IN BOOLEAN iEventPair) { - PDEBUG_BUFFER oBuf = NULL; + PDEBUG_BUFFER oBuf; FIXME("(%d, %d): stub\n", iSize, iEventPair); if (iSize < sizeof(DEBUG_BUFFER)) { iSize = sizeof(DEBUG_BUFFER); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/directory.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/directory.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/directory.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/directory.c 2016-02-08 19:32:34.000000000 +0000 @@ -993,7 +993,7 @@ */ static int get_dir_case_sensitivity_attr( const char *dir ) { - char *mntpoint = NULL; + char *mntpoint; struct attrlist attr; struct vol_caps caps; struct get_fsid get_fsid; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/file.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/file.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/file.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/file.c 2016-02-08 19:32:34.000000000 +0000 @@ -218,13 +218,13 @@ if (io->u.Status == STATUS_SUCCESS) { - struct security_descriptor *sd; - struct object_attributes objattr; + static UNICODE_STRING empty_string; + OBJECT_ATTRIBUTES unix_attr = *attr; + data_size_t len; + struct object_attributes *objattr; - objattr.rootdir = wine_server_obj_handle( attr->RootDirectory ); - objattr.name_len = 0; - io->u.Status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); - if (io->u.Status != STATUS_SUCCESS) + unix_attr.ObjectName = &empty_string; /* we send the unix name instead */ + if ((io->u.Status = alloc_object_attributes( &unix_attr, &objattr, &len ))) { RtlFreeAnsiString( &unix_name ); return io->u.Status; @@ -233,19 +233,17 @@ SERVER_START_REQ( create_file ) { req->access = access; - req->attributes = attr->Attributes; req->sharing = sharing; req->create = disposition; req->options = options; req->attrs = attributes; - wine_server_add_data( req, &objattr, sizeof(objattr) ); - if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); + wine_server_add_data( req, objattr, len ); wine_server_add_data( req, unix_name.Buffer, unix_name.Length ); io->u.Status = wine_server_call( req ); *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; - NTDLL_free_struct_sd( sd ); + RtlFreeHeap( GetProcessHeap(), 0, objattr ); RtlFreeAnsiString( &unix_name ); } else WARN("%s not found (%x)\n", debugstr_us(attr->ObjectName), io->u.Status ); @@ -523,13 +521,7 @@ if (fileio->already >= fileio->count || fileio->avail_mode) status = STATUS_SUCCESS; else - { - /* if we only have to read the available data, and none is available, - * simply cancel the request. If data was available, it has been read - * while in by previous call (NtDelayExecution) - */ - status = (fileio->avail_mode) ? STATUS_SUCCESS : STATUS_PENDING; - } + status = STATUS_PENDING; } break; @@ -3512,30 +3504,26 @@ ULONG inbound_quota, ULONG outbound_quota, PLARGE_INTEGER timeout) { - struct security_descriptor *sd = NULL; - struct object_attributes objattr; NTSTATUS status; + data_size_t len; + struct object_attributes *objattr; TRACE("(%p %x %s %p %x %d %x %d %d %d %d %d %d %p)\n", handle, access, debugstr_w(attr->ObjectName->Buffer), iosb, sharing, dispo, options, pipe_type, read_mode, completion_mode, max_inst, inbound_quota, outbound_quota, timeout); + if (!attr) return STATUS_INVALID_PARAMETER; + /* assume we only get relative timeout */ if (timeout->QuadPart > 0) FIXME("Wrong time %s\n", wine_dbgstr_longlong(timeout->QuadPart)); - objattr.rootdir = wine_server_obj_handle( attr->RootDirectory ); - objattr.sd_len = 0; - objattr.name_len = attr->ObjectName->Length; - - status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); - if (status != STATUS_SUCCESS) return status; + if ((status = alloc_object_attributes( attr, &objattr, &len ))) return status; SERVER_START_REQ( create_named_pipe ) { req->access = access; - req->attributes = attr->Attributes; req->options = options; req->sharing = sharing; req->flags = @@ -3546,15 +3534,13 @@ req->outsize = outbound_quota; req->insize = inbound_quota; req->timeout = timeout->QuadPart; - wine_server_add_data( req, &objattr, sizeof(objattr) ); - if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); - wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); + wine_server_add_data( req, objattr, len ); status = wine_server_call( req ); if (!status) *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; - NTDLL_free_struct_sd( sd ); + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return status; } @@ -3644,6 +3630,8 @@ { LARGE_INTEGER timeout; NTSTATUS ret; + data_size_t len; + struct object_attributes *objattr; TRACE("%p %08x %p %p %08x %08x %08x %p\n", pHandle, DesiredAccess, attr, IoStatusBlock, @@ -3651,7 +3639,8 @@ if (!pHandle) return STATUS_ACCESS_VIOLATION; if (!attr) return STATUS_INVALID_PARAMETER; - if (!attr->ObjectName) return STATUS_OBJECT_PATH_SYNTAX_BAD; + + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; /* * For a NULL TimeOut pointer set the default timeout value @@ -3664,17 +3653,15 @@ SERVER_START_REQ( create_mailslot ) { req->access = DesiredAccess; - req->attributes = attr->Attributes; - req->rootdir = wine_server_obj_handle( attr->RootDirectory ); req->max_msgsize = MaxMessageSize; req->read_timeout = timeout.QuadPart; - wine_server_add_data( req, attr->ObjectName->Buffer, - attr->ObjectName->Length ); + wine_server_add_data( req, objattr, len ); ret = wine_server_call( req ); if( ret == STATUS_SUCCESS ) *pHandle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; - + + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return ret; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/loader.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/loader.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/loader.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/loader.c 2016-02-08 19:32:34.000000000 +0000 @@ -1865,7 +1865,7 @@ char error[256], dllname[MAX_PATH]; const WCHAR *name, *p; DWORD len, i; - void *handle = NULL; + void *handle; struct builtin_load_info info, *prev_info; /* Fix the name in case we have a full path and extension */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/nt.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/nt.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/nt.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/nt.c 2016-02-08 19:32:34.000000000 +0000 @@ -1243,77 +1243,255 @@ cached_sci.Architecture, cached_sci.Level, cached_sci.Revision, cached_sci.FeatureSet); } -#ifdef linux -static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMATION *data, - DWORD *len, DWORD max_len, LOGICAL_PROCESSOR_RELATIONSHIP rel, DWORD id, DWORD proc) +static BOOL grow_logical_proc_buf(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **pdata, + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, DWORD *max_len) { - DWORD i; + if (pdata) + { + SYSTEM_LOGICAL_PROCESSOR_INFORMATION *new_data; - for(i=0; i<*len; i++) + *max_len *= 2; + new_data = RtlReAllocateHeap(GetProcessHeap(), 0, *pdata, *max_len*sizeof(*new_data)); + if (!new_data) + return FALSE; + + *pdata = new_data; + } + else { - if(data[i].Relationship!=rel || data[i].u.Reserved[1]!=id) - continue; + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *new_dataex; + + *max_len *= 2; + new_dataex = RtlReAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, *pdataex, *max_len*sizeof(*new_dataex)); + if (!new_dataex) + return FALSE; - data[i].ProcessorMask |= (ULONG_PTR)1<Relationship == rel && dataex->u.Processor.Reserved[1] == id) + { + dataex->u.Processor.GroupMask[0].Mask |= mask; + return TRUE; + } + ofs += dataex->Size; + } + + /* TODO: For now, just one group. If more than 64 processors, then we + * need another group. */ + + while (ofs + log_proc_ex_size_plus(sizeof(PROCESSOR_RELATIONSHIP)) > *pmax_len) + { + if (!grow_logical_proc_buf(NULL, pdataex, pmax_len)) + return FALSE; + } + + dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*pdataex) + ofs); + + dataex->Relationship = rel; + dataex->Size = log_proc_ex_size_plus(sizeof(PROCESSOR_RELATIONSHIP)); + dataex->u.Processor.Flags = 0; /* TODO */ + dataex->u.Processor.EfficiencyClass = 0; + dataex->u.Processor.GroupCount = 1; + dataex->u.Processor.GroupMask[0].Mask = mask; + dataex->u.Processor.GroupMask[0].Group = 0; + /* mark for future lookup */ + dataex->u.Processor.Reserved[0] = 0; + dataex->u.Processor.Reserved[1] = id; + + *len += dataex->Size; + } - data[i].Relationship = rel; - data[i].ProcessorMask = (ULONG_PTR)1<Level && (*pdata)[i].u.Cache.Type==cache->Type) + return TRUE; + } + + while (*len == *pmax_len) + if (!grow_logical_proc_buf(pdata, NULL, pmax_len)) + return FALSE; + + (*pdata)[i].Relationship = RelationCache; + (*pdata)[i].ProcessorMask = mask; + (*pdata)[i].u.Cache = *cache; + *len = i+1; + } + else + { + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *dataex = *pdataex; + DWORD ofs; + + for (ofs = 0; ofs < *len; ) + { + dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*pdataex) + ofs); + if (dataex->Relationship == RelationCache && dataex->u.Cache.GroupMask.Mask == mask && + dataex->u.Cache.Level == cache->Level && dataex->u.Cache.Type == cache->Type) + return TRUE; + ofs += dataex->Size; + } + + while (ofs + log_proc_ex_size_plus(sizeof(CACHE_RELATIONSHIP)) > *pmax_len) + { + if (!grow_logical_proc_buf(NULL, pdataex, pmax_len)) + return FALSE; + } + + dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*pdataex) + ofs); + + dataex->Relationship = RelationCache; + dataex->Size = log_proc_ex_size_plus(sizeof(CACHE_RELATIONSHIP)); + dataex->u.Cache.Level = cache->Level; + dataex->u.Cache.Associativity = cache->Associativity; + dataex->u.Cache.LineSize = cache->LineSize; + dataex->u.Cache.CacheSize = cache->Size; + dataex->u.Cache.Type = cache->Type; + dataex->u.Cache.GroupMask.Mask = mask; + dataex->u.Cache.GroupMask.Group = 0; + + *len += dataex->Size; + } + + return TRUE; +} - for(i=0; i<*len; i++) +static inline BOOL logical_proc_info_add_numa_node(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **pdata, + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, DWORD *len, DWORD *pmax_len, ULONG_PTR mask, + DWORD node_id) +{ + if (pdata) { - if(data[i].Relationship==RelationCache && data[i].ProcessorMask==mask - && data[i].u.Cache.Level==cache->Level && data[i].u.Cache.Type==cache->Type) - return TRUE; + while (*len == *pmax_len) + if (!grow_logical_proc_buf(pdata, NULL, pmax_len)) + return FALSE; + + (*pdata)[*len].Relationship = RelationNumaNode; + (*pdata)[*len].ProcessorMask = mask; + (*pdata)[*len].u.NumaNode.NodeNumber = node_id; + (*len)++; } + else + { + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *dataex; + + while (*len + log_proc_ex_size_plus(sizeof(NUMA_NODE_RELATIONSHIP)) > *pmax_len) + { + if (!grow_logical_proc_buf(NULL, pdataex, pmax_len)) + return FALSE; + } + + dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*pdataex) + *len); - if(*len == max_len) - return FALSE; + dataex->Relationship = RelationNumaNode; + dataex->Size = log_proc_ex_size_plus(sizeof(NUMA_NODE_RELATIONSHIP)); + dataex->u.NumaNode.NodeNumber = node_id; + dataex->u.NumaNode.GroupMask.Mask = mask; + dataex->u.NumaNode.GroupMask.Group = 0; + + *len += dataex->Size; + } - data[i].Relationship = RelationCache; - data[i].ProcessorMask = mask; - data[i].u.Cache = *cache; - *len = i+1; return TRUE; } -static inline BOOL logical_proc_info_add_numa_node(SYSTEM_LOGICAL_PROCESSOR_INFORMATION *data, - DWORD *len, DWORD max_len, ULONG_PTR mask, DWORD node_id) +static inline BOOL logical_proc_info_add_group(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, + DWORD *len, DWORD *pmax_len, DWORD num_cpus, ULONG_PTR mask) { - if(*len == max_len) - return FALSE; + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *dataex; + + while (*len + log_proc_ex_size_plus(sizeof(GROUP_RELATIONSHIP)) > *pmax_len) + { + if (!grow_logical_proc_buf(NULL, pdataex, pmax_len)) + return FALSE; + } + + dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*pdataex) + *len); + + dataex->Relationship = RelationGroup; + dataex->Size = log_proc_ex_size_plus(sizeof(GROUP_RELATIONSHIP)); + dataex->u.Group.MaximumGroupCount = 1; + dataex->u.Group.ActiveGroupCount = 1; + dataex->u.Group.GroupInfo[0].MaximumProcessorCount = num_cpus; + dataex->u.Group.GroupInfo[0].ActiveProcessorCount = num_cpus; + dataex->u.Group.GroupInfo[0].ActiveProcessorMask = mask; + + *len += dataex->Size; - data[*len].Relationship = RelationNumaNode; - data[*len].ProcessorMask = mask; - data[*len].u.NumaNode.NodeNumber = node_id; - (*len)++; return TRUE; } -static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data, DWORD *max_len) +#ifdef linux +/* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */ +static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data, + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, DWORD *max_len) { static const char core_info[] = "/sys/devices/system/cpu/cpu%u/%s"; static const char cache_info[] = "/sys/devices/system/cpu/cpu%u/cache/index%u/%s"; static const char numa_info[] = "/sys/devices/system/node/node%u/cpumap"; FILE *fcpu_list, *fnuma_list, *f; - DWORD len = 0, beg, end, i, j, r; + DWORD len = 0, beg, end, i, j, r, num_cpus = 0; char op, name[MAX_PATH]; + ULONG_PTR all_cpus_mask = 0; fcpu_list = fopen("/sys/devices/system/cpu/online", "r"); if(!fcpu_list) @@ -1334,52 +1512,32 @@ continue; } - sprintf(name, core_info, i, "core_id"); + sprintf(name, core_info, i, "physical_package_id"); f = fopen(name, "r"); if(f) { fscanf(f, "%u", &r); fclose(f); } - else r = i; - if(!logical_proc_info_add_by_id(*data, &len, *max_len, RelationProcessorCore, r, i)) + else r = 0; + if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorPackage, r, 1 << i)) { - SYSTEM_LOGICAL_PROCESSOR_INFORMATION *new_data; - - *max_len *= 2; - new_data = RtlReAllocateHeap(GetProcessHeap(), 0, *data, *max_len*sizeof(*new_data)); - if(!new_data) - { - fclose(fcpu_list); - return STATUS_NO_MEMORY; - } - - *data = new_data; - logical_proc_info_add_by_id(*data, &len, *max_len, RelationProcessorCore, r, i); + fclose(fcpu_list); + return STATUS_NO_MEMORY; } - sprintf(name, core_info, i, "physical_package_id"); + sprintf(name, core_info, i, "core_id"); f = fopen(name, "r"); if(f) { fscanf(f, "%u", &r); fclose(f); } - else r = 0; - if(!logical_proc_info_add_by_id(*data, &len, *max_len, RelationProcessorPackage, r, i)) + else r = i; + if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, r, 1 << i)) { - SYSTEM_LOGICAL_PROCESSOR_INFORMATION *new_data; - - *max_len *= 2; - new_data = RtlReAllocateHeap(GetProcessHeap(), 0, *data, *max_len*sizeof(*new_data)); - if(!new_data) - { - fclose(fcpu_list); - return STATUS_NO_MEMORY; - } - - *data = new_data; - logical_proc_info_add_by_id(*data, &len, *max_len, RelationProcessorPackage, r, i); + fclose(fcpu_list); + return STATUS_NO_MEMORY; } for(j=0; j<4; j++) @@ -1440,47 +1598,39 @@ else cache.Type = CacheUnified; - if(!logical_proc_info_add_cache(*data, &len, *max_len, mask, &cache)) + if(!logical_proc_info_add_cache(data, dataex, &len, max_len, mask, &cache)) { - SYSTEM_LOGICAL_PROCESSOR_INFORMATION *new_data; - - *max_len *= 2; - new_data = RtlReAllocateHeap(GetProcessHeap(), 0, *data, *max_len*sizeof(*new_data)); - if(!new_data) - { - fclose(fcpu_list); - return STATUS_NO_MEMORY; - } - - *data = new_data; - logical_proc_info_add_cache(*data, &len, *max_len, mask, &cache); + fclose(fcpu_list); + return STATUS_NO_MEMORY; } } } } fclose(fcpu_list); + if(data){ + for(i=0; iRelationship == RelationProcessorCore){ + all_cpus_mask |= infoex->u.Processor.GroupMask[0].Mask; + ++num_cpus; + } + i += infoex->Size; + } + } + fnuma_list = fopen("/sys/devices/system/node/online", "r"); if(!fnuma_list) { - ULONG_PTR mask = 0; - - for(i=0; iPeb->NumberOfProcessors; + size = sizeof(pkgs_no); + if(sysctlbyname("hw.packages", &pkgs_no, &size, NULL, 0)) + pkgs_no = 1; + size = sizeof(cores_no); - if(sysctlbyname("machdep.cpu.core_count", &cores_no, &size, NULL, 0)) + if(sysctlbyname("hw.physicalcpu", &cores_no, &size, NULL, 0)) cores_no = lcpu_no; - lcpu_per_core = lcpu_no/cores_no; - for(i=0; i 0){ + mask = 0; + for(k = 0; k < cache_sharing[i]; ++k) + mask |= (ULONG_PTR)1 << (j * lcpu_per_core + k); + + if(!logical_proc_info_add_cache(data, dataex, &len, max_len, mask, &cache[i])) + return STATUS_NO_MEMORY; } - (*data)[len].Relationship = RelationCache; - (*data)[len].ProcessorMask = mask; - (*data)[len].u.Cache = cache[i]; - len++; + cache_ctrs[i] += lcpu_per_core; + + if(cache_ctrs[i] == cache_sharing[i]) + cache_ctrs[i] = 0; } } } - mask = 0; - for(i=0; i= len) + if (!SystemInformation) { - if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION; - else memcpy( SystemInformation, &shi, len); + ret = STATUS_ACCESS_VIOLATION; + break; } - else ret = STATUS_INFO_LENGTH_MISMATCH; - FIXME("info_class SYSTEM_HANDLE_INFORMATION\n"); + + num_handles = (Length - FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION, Handle )) / sizeof(SYSTEM_HANDLE_ENTRY); + if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*info) * num_handles ))) + return STATUS_NO_MEMORY; + + SERVER_START_REQ( get_system_handles ) + { + wine_server_set_reply( req, info, sizeof(*info) * num_handles ); + if (!(ret = wine_server_call( req ))) + { + SYSTEM_HANDLE_INFORMATION *shi = SystemInformation; + shi->Count = wine_server_reply_size( req ) / sizeof(*info); + len = FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION, Handle[shi->Count] ); + for (i = 0; i < shi->Count; i++) + { + memset( &shi->Handle[i], 0, sizeof(shi->Handle[i]) ); + shi->Handle[i].OwnerPid = info[i].owner; + shi->Handle[i].HandleValue = info[i].handle; + shi->Handle[i].AccessMask = info[i].access; + /* FIXME: Fill out ObjectType, HandleFlags, ObjectPointer */ + } + } + else if (ret == STATUS_BUFFER_TOO_SMALL) + { + len = FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION, Handle[reply->count] ); + ret = STATUS_INFO_LENGTH_MISMATCH; + } + } + SERVER_END_REQ; + + RtlFreeHeap( GetProcessHeap(), 0, info ); } break; case SystemCacheInformation: @@ -2106,7 +2301,7 @@ break; } - ret = create_logical_proc_info(&buf, &len); + ret = create_logical_proc_info(&buf, NULL, &len); if( ret != STATUS_SUCCESS ) { RtlFreeHeap(GetProcessHeap(), 0, buf); @@ -2137,6 +2332,74 @@ return ret; } + +/****************************************************************************** + * NtQuerySystemInformationEx [NTDLL.@] + * ZwQuerySystemInformationEx [NTDLL.@] + */ +NTSTATUS WINAPI NtQuerySystemInformationEx(SYSTEM_INFORMATION_CLASS SystemInformationClass, + void *Query, ULONG QueryLength, void *SystemInformation, ULONG Length, ULONG *ResultLength) +{ + ULONG len; + NTSTATUS ret = STATUS_NOT_IMPLEMENTED; + + TRACE("(0x%08x,%p,%u,%p,%u,%p) stub\n", SystemInformationClass, Query, QueryLength, SystemInformation, + Length, ResultLength); + + switch (SystemInformationClass) { + case SystemLogicalProcessorInformationEx: + { + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buf; + + if (!Query || QueryLength < sizeof(DWORD)) + { + ret = STATUS_INVALID_PARAMETER; + break; + } + + if (*(DWORD*)Query != RelationAll) + FIXME("Relationship filtering not implemented: 0x%x\n", *(DWORD*)Query); + + len = 3 * sizeof(*buf); + buf = RtlAllocateHeap(GetProcessHeap(), 0, len); + if (!buf) + { + ret = STATUS_NO_MEMORY; + break; + } + + ret = create_logical_proc_info(NULL, &buf, &len); + if (ret != STATUS_SUCCESS) + { + RtlFreeHeap(GetProcessHeap(), 0, buf); + break; + } + + if (Length >= len) + { + if (!SystemInformation) + ret = STATUS_ACCESS_VIOLATION; + else + memcpy( SystemInformation, buf, len); + } + else + ret = STATUS_INFO_LENGTH_MISMATCH; + + RtlFreeHeap(GetProcessHeap(), 0, buf); + + break; + } + default: + FIXME("(0x%08x,%p,%u,%p,%u,%p) stub\n", SystemInformationClass, Query, QueryLength, SystemInformation, + Length, ResultLength); + break; + } + + if (ResultLength) + *ResultLength = len; + + return ret; +} /****************************************************************************** * NtSetSystemInformation [NTDLL.@] diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/ntdll_misc.h wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/ntdll_misc.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/ntdll_misc.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/ntdll_misc.h 2016-02-08 19:32:34.000000000 +0000 @@ -97,11 +97,9 @@ extern int server_get_unix_fd( HANDLE handle, unsigned int access, int *unix_fd, int *needs_close, enum server_fd_type *type, unsigned int *options ) DECLSPEC_HIDDEN; extern int server_pipe( int fd[2] ) DECLSPEC_HIDDEN; - -/* security descriptors */ -NTSTATUS NTDLL_create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_descriptor **server_sd, - data_size_t *server_sd_len) DECLSPEC_HIDDEN; -void NTDLL_free_struct_sd(struct security_descriptor *server_sd) DECLSPEC_HIDDEN; +extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret, + data_size_t *ret_len ) DECLSPEC_HIDDEN; +extern NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN; /* module handling */ extern LIST_ENTRY tls_links DECLSPEC_HIDDEN; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/ntdll.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/ntdll.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/ntdll.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/ntdll.spec 2016-02-08 19:32:34.000000000 +0000 @@ -274,6 +274,7 @@ @ stdcall NtQuerySystemEnvironmentValue(ptr ptr long ptr) @ stdcall NtQuerySystemEnvironmentValueEx(ptr ptr ptr ptr ptr) @ stdcall NtQuerySystemInformation(long long long long) +@ stdcall NtQuerySystemInformationEx(long ptr long ptr long ptr) @ stdcall NtQuerySystemTime(ptr) @ stdcall NtQueryTimer(ptr long ptr long ptr) @ stdcall NtQueryTimerResolution(long long long) @@ -505,7 +506,7 @@ @ stdcall RtlCreateTimerQueue(ptr) @ stdcall RtlCreateUnicodeString(ptr wstr) @ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str) -@ stub RtlCreateUserProcess +@ stdcall RtlCreateUserProcess(ptr long ptr ptr ptr long long long long ptr) @ stub RtlCreateUserSecurityObject @ stdcall RtlCreateUserThread(long ptr long ptr long long ptr ptr ptr ptr) @ stub RtlCustomCPToUnicodeN @@ -1193,6 +1194,7 @@ @ stdcall ZwQuerySystemEnvironmentValue(ptr ptr long ptr) NtQuerySystemEnvironmentValue @ stdcall ZwQuerySystemEnvironmentValueEx(ptr ptr ptr ptr ptr) NtQuerySystemEnvironmentValueEx @ stdcall ZwQuerySystemInformation(long long long long) NtQuerySystemInformation +@ stdcall ZwQuerySystemInformationEx(long ptr long ptr long ptr) NtQuerySystemInformationEx @ stdcall ZwQuerySystemTime(ptr) NtQuerySystemTime @ stdcall ZwQueryTimer(ptr long ptr long ptr) NtQueryTimer @ stdcall ZwQueryTimerResolution(long long long) NtQueryTimerResolution diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/om.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/om.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/om.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/om.c 2016-02-08 19:32:34.000000000 +0000 @@ -429,34 +429,24 @@ * Success: ERROR_SUCCESS. * Failure: An NTSTATUS error code. */ -NTSTATUS WINAPI NtOpenDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes) +NTSTATUS WINAPI NtOpenDirectoryObject( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr) { NTSTATUS ret; - if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION; - if (!ObjectAttributes) return STATUS_INVALID_PARAMETER; - TRACE("(%p,0x%08x,%s)\n", DirectoryHandle, DesiredAccess, debugstr_ObjectAttributes(ObjectAttributes)); - /* Have to test it here because server won't know difference between - * ObjectName == NULL and ObjectName == "" */ - if (!ObjectAttributes->ObjectName) - { - if (ObjectAttributes->RootDirectory) - return STATUS_OBJECT_NAME_INVALID; - else - return STATUS_OBJECT_PATH_SYNTAX_BAD; - } + if (!handle) return STATUS_ACCESS_VIOLATION; + if ((ret = validate_open_object_attributes( attr ))) return ret; + + TRACE("(%p,0x%08x,%s)\n", handle, access, debugstr_ObjectAttributes(attr)); SERVER_START_REQ(open_directory) { - req->access = DesiredAccess; - req->attributes = ObjectAttributes->Attributes; - req->rootdir = wine_server_obj_handle( ObjectAttributes->RootDirectory ); - if (ObjectAttributes->ObjectName) - wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer, - ObjectAttributes->ObjectName->Length); + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); ret = wine_server_call( req ); - *DirectoryHandle = wine_server_ptr_handle( reply->handle ); + *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return ret; @@ -478,25 +468,27 @@ * Failure: An NTSTATUS error code. */ NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes) + OBJECT_ATTRIBUTES *attr ) { NTSTATUS ret; + data_size_t len; + struct object_attributes *objattr; if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION; - TRACE("(%p,0x%08x,%s)\n", DirectoryHandle, DesiredAccess, debugstr_ObjectAttributes(ObjectAttributes)); + TRACE("(%p,0x%08x,%s)\n", DirectoryHandle, DesiredAccess, debugstr_ObjectAttributes(attr)); + + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; SERVER_START_REQ(create_directory) { req->access = DesiredAccess; - req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0; - req->rootdir = wine_server_obj_handle( ObjectAttributes ? ObjectAttributes->RootDirectory : 0 ); - if (ObjectAttributes && ObjectAttributes->ObjectName) - wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer, - ObjectAttributes->ObjectName->Length); + wine_server_add_data( req, objattr, len ); ret = wine_server_call( req ); *DirectoryHandle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; + + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return ret; } @@ -584,34 +576,25 @@ * Success: ERROR_SUCCESS. * Failure: An NTSTATUS error code. */ -NTSTATUS WINAPI NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes) +NTSTATUS WINAPI NtOpenSymbolicLinkObject( HANDLE *handle, ACCESS_MASK access, + const OBJECT_ATTRIBUTES *attr) { NTSTATUS ret; - TRACE("(%p,0x%08x,%s)\n",LinkHandle, DesiredAccess, debugstr_ObjectAttributes(ObjectAttributes)); - if (!LinkHandle) return STATUS_ACCESS_VIOLATION; - if (!ObjectAttributes) return STATUS_INVALID_PARAMETER; - /* Have to test it here because server won't know difference between - * ObjectName == NULL and ObjectName == "" */ - if (!ObjectAttributes->ObjectName) - { - if (ObjectAttributes->RootDirectory) - return STATUS_OBJECT_NAME_INVALID; - else - return STATUS_OBJECT_PATH_SYNTAX_BAD; - } + TRACE("(%p,0x%08x,%s)\n", handle, access, debugstr_ObjectAttributes(attr)); + + if (!handle) return STATUS_ACCESS_VIOLATION; + if ((ret = validate_open_object_attributes( attr ))) return ret; SERVER_START_REQ(open_symlink) { - req->access = DesiredAccess; - req->attributes = ObjectAttributes->Attributes; - req->rootdir = wine_server_obj_handle( ObjectAttributes->RootDirectory ); - if (ObjectAttributes->ObjectName) - wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer, - ObjectAttributes->ObjectName->Length); + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); ret = wine_server_call( req ); - *LinkHandle = wine_server_ptr_handle( reply->handle ); + *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return ret; @@ -634,35 +617,31 @@ * Failure: An NTSTATUS error code. */ NTSTATUS WINAPI NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle,IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN PUNICODE_STRING TargetName) + POBJECT_ATTRIBUTES attr, PUNICODE_STRING TargetName) { NTSTATUS ret; + data_size_t len; + struct object_attributes *objattr; - if (!SymbolicLinkHandle || !TargetName) return STATUS_ACCESS_VIOLATION; + if (!SymbolicLinkHandle || !attr || !TargetName) return STATUS_ACCESS_VIOLATION; if (!TargetName->Buffer) return STATUS_INVALID_PARAMETER; TRACE("(%p,0x%08x,%s -> %s)\n", SymbolicLinkHandle, DesiredAccess, - debugstr_ObjectAttributes(ObjectAttributes), debugstr_us(TargetName)); + debugstr_ObjectAttributes(attr), debugstr_us(TargetName)); + + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; SERVER_START_REQ(create_symlink) { req->access = DesiredAccess; - req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0; - req->rootdir = wine_server_obj_handle( ObjectAttributes ? ObjectAttributes->RootDirectory : 0 ); - if (ObjectAttributes && ObjectAttributes->ObjectName) - { - req->name_len = ObjectAttributes->ObjectName->Length; - wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer, - ObjectAttributes->ObjectName->Length); - } - else - req->name_len = 0; + wine_server_add_data( req, objattr, len ); wine_server_add_data(req, TargetName->Buffer, TargetName->Length); ret = wine_server_call( req ); *SymbolicLinkHandle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; + + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return ret; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/process.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/process.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/process.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/process.c 2016-02-08 19:32:34.000000000 +0000 @@ -40,6 +40,10 @@ #include "ntdll_misc.h" #include "wine/server.h" +#ifdef HAVE_MACH_MACH_H +#include +#endif + WINE_DEFAULT_DEBUG_CHANNEL(ntdll); static ULONG execute_flags = MEM_EXECUTE_OPTION_DISABLE; @@ -110,6 +114,32 @@ return ((ULONG_PTR)1 << num_cpus) - 1; } +#if defined(HAVE_MACH_MACH_H) + +static void fill_VM_COUNTERS(VM_COUNTERS* pvmi) +{ +#if defined(MACH_TASK_BASIC_INFO) + struct mach_task_basic_info info; + mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; + if(task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) + { + pvmi->VirtualSize = info.resident_size + info.virtual_size; + pvmi->PagefileUsage = info.virtual_size; + pvmi->WorkingSetSize = info.resident_size; + pvmi->PeakWorkingSetSize = info.resident_size_max; + } +#endif +} + +#else + +static void fill_VM_COUNTERS(VM_COUNTERS* pvmi) +{ + /* FIXME : real data */ +} + +#endif + /****************************************************************************** * NtQueryInformationProcess [NTDLL.@] * ZwQueryInformationProcess [NTDLL.@] @@ -240,8 +270,8 @@ ret = STATUS_INVALID_HANDLE; else { - /* FIXME : real data */ memset(&pvmi, 0 , sizeof(VM_COUNTERS)); + fill_VM_COUNTERS(&pvmi); len = ProcessInformationLength; if (len != FIELD_OFFSET(VM_COUNTERS,PrivatePageCount)) len = sizeof(VM_COUNTERS); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/reg.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/reg.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/reg.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/reg.c 2016-02-08 19:32:34.000000000 +0000 @@ -42,8 +42,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(reg); -/* maximum length of a key name in bytes (without terminating null) */ -#define MAX_NAME_LENGTH (255 * sizeof(WCHAR)) /* maximum length of a value name in bytes (without terminating null) */ #define MAX_VALUE_LENGTH (16383 * sizeof(WCHAR)) @@ -56,22 +54,22 @@ PULONG dispos ) { NTSTATUS ret; + data_size_t len; + struct object_attributes *objattr; if (!retkey || !attr) return STATUS_ACCESS_VIOLATION; if (attr->Length > sizeof(OBJECT_ATTRIBUTES)) return STATUS_INVALID_PARAMETER; - if (attr->ObjectName->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW; TRACE( "(%p,%s,%s,%x,%x,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName), debugstr_us(class), options, access, retkey ); + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; + SERVER_START_REQ( create_key ) { - req->parent = wine_server_obj_handle( attr->RootDirectory ); req->access = access; - req->attributes = attr->Attributes; req->options = options; - req->namelen = attr->ObjectName->Length; - wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); + wine_server_add_data( req, objattr, len ); if (class) wine_server_add_data( req, class->Buffer, class->Length ); if (!(ret = wine_server_call( req ))) { @@ -80,7 +78,9 @@ } } SERVER_END_REQ; + TRACE("<- %p\n", *retkey); + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return ret; } @@ -127,24 +127,21 @@ NTSTATUS WINAPI NtOpenKeyEx( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, ULONG options ) { NTSTATUS ret; - DWORD len; - if (!retkey || !attr) return STATUS_ACCESS_VIOLATION; - if (attr->Length > sizeof(OBJECT_ATTRIBUTES)) return STATUS_INVALID_PARAMETER; - len = attr->ObjectName->Length; + if (!retkey || !attr || !attr->ObjectName) return STATUS_ACCESS_VIOLATION; + if ((ret = validate_open_object_attributes( attr ))) return ret; + TRACE( "(%p,%s,%x,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName), access, retkey ); if (options) FIXME("options %x not implemented\n", options); - if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW; - SERVER_START_REQ( open_key ) { req->parent = wine_server_obj_handle( attr->RootDirectory ); req->access = access; req->attributes = attr->Attributes; - wine_server_add_data( req, attr->ObjectName->Buffer, len ); + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); ret = wine_server_call( req ); *retkey = wine_server_ptr_handle( reply->hkey ); } @@ -536,7 +533,7 @@ { NTSTATUS ret; UCHAR *data_ptr; - unsigned int fixed_size = 0, min_size = 0; + unsigned int fixed_size, min_size; TRACE( "(%p,%s,%d,%p,%d)\n", handle, debugstr_us(name), info_class, info, length ); @@ -657,6 +654,8 @@ NTSTATUS ret; HANDLE hive; IO_STATUS_BLOCK io; + data_size_t len; + struct object_attributes *objattr; TRACE("(%p,%p)\n", attr, file); @@ -664,17 +663,18 @@ FILE_OPEN, 0, NULL, 0); if (ret) return ret; + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; + SERVER_START_REQ( load_registry ) { - req->hkey = wine_server_obj_handle( attr->RootDirectory ); req->file = wine_server_obj_handle( hive ); - wine_server_add_data(req, attr->ObjectName->Buffer, attr->ObjectName->Length); + wine_server_add_data( req, objattr, len ); ret = wine_server_call( req ); } SERVER_END_REQ; NtClose(hive); - + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return ret; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/rtl.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/rtl.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/rtl.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/rtl.c 2016-02-08 19:32:34.000000000 +0000 @@ -1613,3 +1613,16 @@ { FIXME("%p %p %u %p: stub\n", table, buffer, size, element); } + +/********************************************************************** + * RtlCreateUserProcess [NTDLL.@] + */ +NTSTATUS WINAPI RtlCreateUserProcess(UNICODE_STRING *path, ULONG attributes, RTL_USER_PROCESS_PARAMETERS *parameters, + SECURITY_DESCRIPTOR *process_descriptor, SECURITY_DESCRIPTOR *thread_descriptor, + HANDLE parent, BOOLEAN inherit, HANDLE debug, HANDLE exception, + RTL_USER_PROCESS_INFORMATION *info) +{ + FIXME("(%p %u %p %p %p %p %d %p %p %p): stub\n", path, attributes, parameters, process_descriptor, thread_descriptor, + parent, inherit, debug, exception, info); + return STATUS_NOT_IMPLEMENTED; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/signal_x86_64.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/signal_x86_64.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/signal_x86_64.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/signal_x86_64.c 2016-02-08 19:32:34.000000000 +0000 @@ -1800,11 +1800,12 @@ "ret" ); /*********************************************************************** - * set_cpu_context + * set_full_cpu_context * * Set the new CPU context. */ -__ASM_GLOBAL_FUNC( set_cpu_context, +extern void set_full_cpu_context( const CONTEXT *context ); +__ASM_GLOBAL_FUNC( set_full_cpu_context, "subq $40,%rsp\n\t" __ASM_CFI(".cfi_adjust_cfa_offset 40\n\t") "ldmxcsr 0x34(%rdi)\n\t" /* context->MxCsr */ @@ -1852,6 +1853,25 @@ "movq 0xb0(%rdi),%rdi\n\t" /* context->Rdi */ "iretq" ); + +/*********************************************************************** + * set_cpu_context + * + * Set the new CPU context. Used by NtSetContextThread. + */ +void set_cpu_context( const CONTEXT *context ) +{ + DWORD flags = context->ContextFlags & ~CONTEXT_AMD64; + if (flags & CONTEXT_FULL) + { + if (!(flags & CONTEXT_CONTROL)) + FIXME( "setting partial context (%x) not supported\n", flags ); + else + set_full_cpu_context( context ); + } +} + + /*********************************************************************** * copy_context * diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/sync.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/sync.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/sync.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/sync.c 2016-02-08 19:32:34.000000000 +0000 @@ -73,73 +73,97 @@ } /* creates a struct security_descriptor and contained information in one contiguous piece of memory */ -NTSTATUS NTDLL_create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_descriptor **server_sd, - data_size_t *server_sd_len) +NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret, + data_size_t *ret_len ) { - unsigned int len; + unsigned int len = sizeof(**ret); PSID owner, group; ACL *dacl, *sacl; - BOOLEAN owner_present, group_present, dacl_present, sacl_present; - BOOLEAN defaulted; + BOOLEAN owner_present, group_present, dacl_present, sacl_present, defaulted; + PSECURITY_DESCRIPTOR sd; NTSTATUS status; - unsigned char *ptr; - if (!nt_sd) + *ret = NULL; + *ret_len = 0; + + if (!attr) return STATUS_SUCCESS; + + if (attr->Length != sizeof(*attr)) return STATUS_INVALID_PARAMETER; + + if ((sd = attr->SecurityDescriptor)) + { + len += sizeof(struct security_descriptor); + + if ((status = RtlGetOwnerSecurityDescriptor( sd, &owner, &owner_present ))) return status; + if ((status = RtlGetGroupSecurityDescriptor( sd, &group, &group_present ))) return status; + if ((status = RtlGetSaclSecurityDescriptor( sd, &sacl_present, &sacl, &defaulted ))) return status; + if ((status = RtlGetDaclSecurityDescriptor( sd, &dacl_present, &dacl, &defaulted ))) return status; + if (owner_present) len += RtlLengthSid( owner ); + if (group_present) len += RtlLengthSid( group ); + if (sacl_present && sacl) len += sacl->AclSize; + if (dacl_present && dacl) len += dacl->AclSize; + + /* fix alignment for the Unicode name that follows the structure */ + len = (len + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1); + } + + if (attr->ObjectName) { - *server_sd = NULL; - *server_sd_len = 0; - return STATUS_SUCCESS; - } - - len = sizeof(struct security_descriptor); - - status = RtlGetOwnerSecurityDescriptor(nt_sd, &owner, &owner_present); - if (status != STATUS_SUCCESS) return status; - status = RtlGetGroupSecurityDescriptor(nt_sd, &group, &group_present); - if (status != STATUS_SUCCESS) return status; - status = RtlGetSaclSecurityDescriptor(nt_sd, &sacl_present, &sacl, &defaulted); - if (status != STATUS_SUCCESS) return status; - status = RtlGetDaclSecurityDescriptor(nt_sd, &dacl_present, &dacl, &defaulted); - if (status != STATUS_SUCCESS) return status; - - if (owner_present) - len += RtlLengthSid(owner); - if (group_present) - len += RtlLengthSid(group); - if (sacl_present && sacl) - len += sacl->AclSize; - if (dacl_present && dacl) - len += dacl->AclSize; - - /* fix alignment for the Unicode name that follows the structure */ - len = (len + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1); - *server_sd = RtlAllocateHeap(GetProcessHeap(), 0, len); - if (!*server_sd) return STATUS_NO_MEMORY; - - (*server_sd)->control = ((SECURITY_DESCRIPTOR *)nt_sd)->Control & ~SE_SELF_RELATIVE; - (*server_sd)->owner_len = owner_present ? RtlLengthSid(owner) : 0; - (*server_sd)->group_len = group_present ? RtlLengthSid(group) : 0; - (*server_sd)->sacl_len = (sacl_present && sacl) ? sacl->AclSize : 0; - (*server_sd)->dacl_len = (dacl_present && dacl) ? dacl->AclSize : 0; - - ptr = (unsigned char *)(*server_sd + 1); - memcpy(ptr, owner, (*server_sd)->owner_len); - ptr += (*server_sd)->owner_len; - memcpy(ptr, group, (*server_sd)->group_len); - ptr += (*server_sd)->group_len; - memcpy(ptr, sacl, (*server_sd)->sacl_len); - ptr += (*server_sd)->sacl_len; - memcpy(ptr, dacl, (*server_sd)->dacl_len); + if (attr->ObjectName->Length & (sizeof(WCHAR) - 1)) return STATUS_OBJECT_NAME_INVALID; + len += attr->ObjectName->Length; + } + else if (attr->RootDirectory) return STATUS_OBJECT_NAME_INVALID; + + *ret = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, len ); + if (!*ret) return STATUS_NO_MEMORY; - *server_sd_len = len; + (*ret)->rootdir = wine_server_obj_handle( attr->RootDirectory ); + (*ret)->attributes = attr->Attributes; + if (attr->SecurityDescriptor) + { + struct security_descriptor *descr = (struct security_descriptor *)(*ret + 1); + unsigned char *ptr = (unsigned char *)(descr + 1); + + descr->control = ((SECURITY_DESCRIPTOR *)sd)->Control & ~SE_SELF_RELATIVE; + if (owner_present) descr->owner_len = RtlLengthSid( owner ); + if (group_present) descr->group_len = RtlLengthSid( group ); + if (sacl_present && sacl) descr->sacl_len = sacl->AclSize; + if (dacl_present && dacl) descr->dacl_len = dacl->AclSize; + + memcpy( ptr, owner, descr->owner_len ); + ptr += descr->owner_len; + memcpy( ptr, group, descr->group_len ); + ptr += descr->group_len; + memcpy( ptr, sacl, descr->sacl_len ); + ptr += descr->sacl_len; + memcpy( ptr, dacl, descr->dacl_len ); + (*ret)->sd_len = (sizeof(*descr) + descr->owner_len + descr->group_len + descr->sacl_len + + descr->dacl_len + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1); + } + + if (attr->ObjectName) + { + unsigned char *ptr = (unsigned char *)(*ret + 1) + (*ret)->sd_len; + (*ret)->name_len = attr->ObjectName->Length; + memcpy( ptr, attr->ObjectName->Buffer, (*ret)->name_len ); + } + + *ret_len = len; return STATUS_SUCCESS; } -/* frees a struct security_descriptor allocated by NTDLL_create_struct_sd */ -void NTDLL_free_struct_sd(struct security_descriptor *server_sd) +NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr ) { - RtlFreeHeap(GetProcessHeap(), 0, server_sd); + if (!attr || attr->Length != sizeof(*attr)) return STATUS_INVALID_PARAMETER; + + if (attr->ObjectName) + { + if (attr->ObjectName->Length & (sizeof(WCHAR) - 1)) return STATUS_OBJECT_NAME_INVALID; + } + else if (attr->RootDirectory) return STATUS_OBJECT_NAME_INVALID; + + return STATUS_SUCCESS; } /* @@ -155,63 +179,48 @@ IN LONG InitialCount, IN LONG MaximumCount ) { - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; - struct object_attributes objattr; - struct security_descriptor *sd = NULL; + data_size_t len; + struct object_attributes *objattr; if (MaximumCount <= 0 || InitialCount < 0 || InitialCount > MaximumCount) return STATUS_INVALID_PARAMETER; - if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; - objattr.rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); - objattr.sd_len = 0; - objattr.name_len = len; - if (attr) - { - ret = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); - if (ret != STATUS_SUCCESS) return ret; - } + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; SERVER_START_REQ( create_semaphore ) { req->access = access; - req->attributes = (attr) ? attr->Attributes : 0; req->initial = InitialCount; req->max = MaximumCount; - wine_server_add_data( req, &objattr, sizeof(objattr) ); - if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + wine_server_add_data( req, objattr, len ); ret = wine_server_call( req ); *SemaphoreHandle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; - NTDLL_free_struct_sd( sd ); - + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return ret; } /****************************************************************************** * NtOpenSemaphore (NTDLL.@) */ -NTSTATUS WINAPI NtOpenSemaphore( OUT PHANDLE SemaphoreHandle, - IN ACCESS_MASK access, - IN const OBJECT_ATTRIBUTES *attr ) +NTSTATUS WINAPI NtOpenSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; - if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + if ((ret = validate_open_object_attributes( attr ))) return ret; SERVER_START_REQ( open_semaphore ) { - req->access = access; - req->attributes = (attr) ? attr->Attributes : 0; - req->rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); ret = wine_server_call( req ); - *SemaphoreHandle = wine_server_ptr_handle( reply->handle ); + *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return ret; @@ -279,38 +288,24 @@ NTSTATUS WINAPI NtCreateEvent( PHANDLE EventHandle, ACCESS_MASK DesiredAccess, const OBJECT_ATTRIBUTES *attr, EVENT_TYPE type, BOOLEAN InitialState) { - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; - struct security_descriptor *sd = NULL; - struct object_attributes objattr; + data_size_t len; + struct object_attributes *objattr; - if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; - - objattr.rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); - objattr.sd_len = 0; - objattr.name_len = len; - if (attr) - { - ret = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); - if (ret != STATUS_SUCCESS) return ret; - } + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; SERVER_START_REQ( create_event ) { req->access = DesiredAccess; - req->attributes = (attr) ? attr->Attributes : 0; req->manual_reset = (type == NotificationEvent); req->initial_state = InitialState; - wine_server_add_data( req, &objattr, sizeof(objattr) ); - if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + wine_server_add_data( req, objattr, len ); ret = wine_server_call( req ); *EventHandle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; - NTDLL_free_struct_sd( sd ); - + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return ret; } @@ -318,24 +313,21 @@ * NtOpenEvent (NTDLL.@) * ZwOpenEvent (NTDLL.@) */ -NTSTATUS WINAPI NtOpenEvent( - OUT PHANDLE EventHandle, - IN ACCESS_MASK DesiredAccess, - IN const OBJECT_ATTRIBUTES *attr ) +NTSTATUS WINAPI NtOpenEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; - if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + if ((ret = validate_open_object_attributes( attr ))) return ret; SERVER_START_REQ( open_event ) { - req->access = DesiredAccess; - req->attributes = (attr) ? attr->Attributes : 0; - req->rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); ret = wine_server_call( req ); - *EventHandle = wine_server_ptr_handle( reply->handle ); + *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return ret; @@ -463,36 +455,22 @@ IN BOOLEAN InitialOwner) { NTSTATUS status; - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; - struct security_descriptor *sd = NULL; - struct object_attributes objattr; - - if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; - - objattr.rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); - objattr.sd_len = 0; - objattr.name_len = len; - if (attr) - { - status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); - if (status != STATUS_SUCCESS) return status; - } + data_size_t len; + struct object_attributes *objattr; + + if ((status = alloc_object_attributes( attr, &objattr, &len ))) return status; SERVER_START_REQ( create_mutex ) { req->access = access; - req->attributes = (attr) ? attr->Attributes : 0; req->owned = InitialOwner; - wine_server_add_data( req, &objattr, sizeof(objattr) ); - if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + wine_server_add_data( req, objattr, len ); status = wine_server_call( req ); *MutantHandle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; - NTDLL_free_struct_sd( sd ); - + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return status; } @@ -500,23 +478,21 @@ * NtOpenMutant [NTDLL.@] * ZwOpenMutant [NTDLL.@] */ -NTSTATUS WINAPI NtOpenMutant(OUT HANDLE* MutantHandle, - IN ACCESS_MASK access, - IN const OBJECT_ATTRIBUTES* attr ) +NTSTATUS WINAPI NtOpenMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { NTSTATUS status; - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; - if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + if ((status = validate_open_object_attributes( attr ))) return status; SERVER_START_REQ( open_mutex ) { req->access = access; - req->attributes = (attr) ? attr->Attributes : 0; - req->rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); status = wine_server_call( req ); - *MutantHandle = wine_server_ptr_handle( reply->handle ); + *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return status; @@ -565,35 +541,22 @@ */ NTSTATUS WINAPI NtCreateJobObject( PHANDLE handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; - struct security_descriptor *sd = NULL; - struct object_attributes objattr; + data_size_t len; + struct object_attributes *objattr; - if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; - - objattr.rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); - objattr.sd_len = 0; - objattr.name_len = len; - if (attr) - { - ret = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); - if (ret != STATUS_SUCCESS) return ret; - } + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; SERVER_START_REQ( create_job ) { req->access = access; - req->attributes = attr ? attr->Attributes : 0; - wine_server_add_data( req, &objattr, sizeof(objattr) ); - if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + wine_server_add_data( req, objattr, len ); ret = wine_server_call( req ); *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; - NTDLL_free_struct_sd( sd ); + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return ret; } @@ -601,10 +564,24 @@ * NtOpenJobObject [NTDLL.@] * ZwOpenJobObject [NTDLL.@] */ -NTSTATUS WINAPI NtOpenJobObject( PHANDLE handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) +NTSTATUS WINAPI NtOpenJobObject( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { - FIXME( "stub: %p %x %s\n", handle, access, attr ? debugstr_us(attr->ObjectName) : "" ); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS ret; + + if ((ret = validate_open_object_attributes( attr ))) return ret; + + SERVER_START_REQ( open_job ) + { + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); + ret = wine_server_call( req ); + *handle = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + return ret; } /****************************************************************************** @@ -791,25 +768,26 @@ IN const OBJECT_ATTRIBUTES *attr OPTIONAL, IN TIMER_TYPE timer_type) { - DWORD len = (attr && attr->ObjectName) ? attr->ObjectName->Length : 0; - NTSTATUS status; - - if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + NTSTATUS status; + data_size_t len; + struct object_attributes *objattr; if (timer_type != NotificationTimer && timer_type != SynchronizationTimer) return STATUS_INVALID_PARAMETER; + if ((status = alloc_object_attributes( attr, &objattr, &len ))) return status; + SERVER_START_REQ( create_timer ) { req->access = access; - req->attributes = (attr) ? attr->Attributes : 0; - req->rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); req->manual = (timer_type == NotificationTimer); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + wine_server_add_data( req, objattr, len ); status = wine_server_call( req ); *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; + + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return status; } @@ -818,21 +796,19 @@ * NtOpenTimer [NTDLL.@] * ZwOpenTimer [NTDLL.@] */ -NTSTATUS WINAPI NtOpenTimer(OUT PHANDLE handle, - IN ACCESS_MASK access, - IN const OBJECT_ATTRIBUTES* attr ) +NTSTATUS WINAPI NtOpenTimer( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { - DWORD len = (attr && attr->ObjectName) ? attr->ObjectName->Length : 0; - NTSTATUS status; + NTSTATUS status; - if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + if ((status = validate_open_object_attributes( attr ))) return status; SERVER_START_REQ( open_timer ) { - req->access = access; - req->attributes = (attr) ? attr->Attributes : 0; - req->rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); + if (attr->ObjectName) + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); status = wine_server_call( req ); *handle = wine_server_ptr_handle( reply->handle ); } @@ -1108,35 +1084,22 @@ NTSTATUS WINAPI NtCreateKeyedEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, ULONG flags ) { - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; - struct security_descriptor *sd = NULL; - struct object_attributes objattr; + data_size_t len; + struct object_attributes *objattr; - if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; - - objattr.rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); - objattr.sd_len = 0; - objattr.name_len = len; - if (attr) - { - ret = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); - if (ret != STATUS_SUCCESS) return ret; - } + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; SERVER_START_REQ( create_keyed_event ) { req->access = access; - req->attributes = attr ? attr->Attributes : 0; - wine_server_add_data( req, &objattr, sizeof(objattr) ); - if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + wine_server_add_data( req, objattr, len ); ret = wine_server_call( req ); *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; - NTDLL_free_struct_sd( sd ); + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return ret; } @@ -1145,17 +1108,17 @@ */ NTSTATUS WINAPI NtOpenKeyedEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; - if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + if ((ret = validate_open_object_attributes( attr ))) return ret; SERVER_START_REQ( open_keyed_event ) { - req->access = access; - req->attributes = attr ? attr->Attributes : 0; - req->rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); ret = wine_server_call( req ); *handle = wine_server_ptr_handle( reply->handle ); } @@ -1211,29 +1174,30 @@ * */ NTSTATUS WINAPI NtCreateIoCompletion( PHANDLE CompletionPort, ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, ULONG NumberOfConcurrentThreads ) + POBJECT_ATTRIBUTES attr, ULONG NumberOfConcurrentThreads ) { NTSTATUS status; + data_size_t len; + struct object_attributes *objattr; - TRACE("(%p, %x, %p, %d)\n", CompletionPort, DesiredAccess, - ObjectAttributes, NumberOfConcurrentThreads); + TRACE("(%p, %x, %p, %d)\n", CompletionPort, DesiredAccess, attr, NumberOfConcurrentThreads); if (!CompletionPort) return STATUS_INVALID_PARAMETER; + if ((status = alloc_object_attributes( attr, &objattr, &len ))) return status; + SERVER_START_REQ( create_completion ) { req->access = DesiredAccess; - req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0; - req->rootdir = wine_server_obj_handle( ObjectAttributes ? ObjectAttributes->RootDirectory : 0 ); req->concurrent = NumberOfConcurrentThreads; - if (ObjectAttributes && ObjectAttributes->ObjectName) - wine_server_add_data( req, ObjectAttributes->ObjectName->Buffer, - ObjectAttributes->ObjectName->Length ); + wine_server_add_data( req, objattr, len ); if (!(status = wine_server_call( req ))) *CompletionPort = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; + + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return status; } @@ -1329,24 +1293,22 @@ * ObjectAttributes [I] completion object name * */ -NTSTATUS WINAPI NtOpenIoCompletion( PHANDLE CompletionPort, ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes ) +NTSTATUS WINAPI NtOpenIoCompletion( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { NTSTATUS status; - TRACE("(%p, 0x%x, %p)\n", CompletionPort, DesiredAccess, ObjectAttributes); - - if (!CompletionPort || !ObjectAttributes || !ObjectAttributes->ObjectName) - return STATUS_INVALID_PARAMETER; + if (!handle) return STATUS_INVALID_PARAMETER; + if ((status = validate_open_object_attributes( attr ))) return status; SERVER_START_REQ( open_completion ) { - req->access = DesiredAccess; - req->rootdir = wine_server_obj_handle( ObjectAttributes->RootDirectory ); - wine_server_add_data( req, ObjectAttributes->ObjectName->Buffer, - ObjectAttributes->ObjectName->Length ); - if (!(status = wine_server_call( req ))) - *CompletionPort = wine_server_ptr_handle( reply->handle ); + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); + status = wine_server_call( req ); + *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return status; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/tests/exception.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/tests/exception.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/tests/exception.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/tests/exception.c 2016-02-08 19:32:34.000000000 +0000 @@ -1723,6 +1723,50 @@ #endif /* __x86_64__ */ #if defined(__i386__) || defined(__x86_64__) + +static void test_debug_registers(void) +{ + static const struct + { + ULONG_PTR dr0, dr1, dr2, dr3, dr6, dr7; + } + tests[] = + { + { 0x42424240, 0, 0x126bb070, 0x0badbad0, 0, 0xffff0115 }, + { 0x42424242, 0, 0x100f0fe7, 0x0abebabe, 0, 0x115 }, + }; + NTSTATUS status; + CONTEXT ctx; + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + memset(&ctx, 0, sizeof(ctx)); + ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; + ctx.Dr0 = tests[i].dr0; + ctx.Dr1 = tests[i].dr1; + ctx.Dr2 = tests[i].dr2; + ctx.Dr3 = tests[i].dr3; + ctx.Dr6 = tests[i].dr6; + ctx.Dr7 = tests[i].dr7; + + status = pNtSetContextThread(GetCurrentThread(), &ctx); + ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %08x\n", status); + + memset(&ctx, 0, sizeof(ctx)); + ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; + + status = pNtGetContextThread(GetCurrentThread(), &ctx); + ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %08x\n", status); + ok(ctx.Dr0 == tests[i].dr0, "test %d: expected %lx, got %lx\n", i, tests[i].dr0, (DWORD_PTR)ctx.Dr0); + ok(ctx.Dr1 == tests[i].dr1, "test %d: expected %lx, got %lx\n", i, tests[i].dr1, (DWORD_PTR)ctx.Dr1); + ok(ctx.Dr2 == tests[i].dr2, "test %d: expected %lx, got %lx\n", i, tests[i].dr2, (DWORD_PTR)ctx.Dr2); + ok(ctx.Dr3 == tests[i].dr3, "test %d: expected %lx, got %lx\n", i, tests[i].dr3, (DWORD_PTR)ctx.Dr3); + ok((ctx.Dr6 & 0xf00f) == tests[i].dr6, "test %d: expected %lx, got %lx\n", i, tests[i].dr6, (DWORD_PTR)ctx.Dr6); + ok((ctx.Dr7 & ~0xdc00) == tests[i].dr7, "test %d: expected %lx, got %lx\n", i, tests[i].dr7, (DWORD_PTR)ctx.Dr7); + } +} + static DWORD outputdebugstring_exceptions; static LONG CALLBACK outputdebugstring_vectored_handler(EXCEPTION_POINTERS *ExceptionInfo) @@ -1946,6 +1990,7 @@ test_unwind(); test_exceptions(); test_rtlraiseexception(); + test_debug_registers(); test_outputdebugstring(1, FALSE); test_ripevent(1); test_vectored_continue_handler(); @@ -1965,6 +2010,7 @@ pRtlLookupFunctionEntry = (void *)GetProcAddress( hntdll, "RtlLookupFunctionEntry" ); + test_debug_registers(); test_outputdebugstring(1, FALSE); test_ripevent(1); test_vectored_continue_handler(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/tests/file.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/tests/file.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/tests/file.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/tests/file.c 2016-02-08 19:32:34.000000000 +0000 @@ -677,7 +677,7 @@ apc_count = 0; U(iosb).Status = 0xdeadbabe; iosb.Information = 0xdeadbeef; - ok( !is_signaled( read ), "read handle is not signaled\n" ); + ok( !is_signaled( read ), "read handle is signaled\n" ); status = pNtReadFile( read, 0, apc, &apc_count, &iosb, buffer, 1, NULL, NULL ); ok( status == STATUS_PENDING, "wrong status %x\n", status ); ok( !is_signaled( read ), "read handle is signaled\n" ); @@ -690,7 +690,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == 0, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 1, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( read ), "read handle is signaled\n" ); + ok( is_signaled( read ), "read handle is not signaled\n" ); ok( !apc_count, "apc was called\n" ); apc_count = 0; SleepEx( 1, FALSE ); /* non-alertable sleep */ @@ -731,7 +731,7 @@ ok(ret && written == 1, "WriteFile error %d\n", GetLastError()); /* partial read is good enough */ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( U(iosb).Status == 0, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 1, "wrong info %lu\n", iosb.Information ); ok( !apc_count, "apc was called\n" ); @@ -762,7 +762,7 @@ ok( status == STATUS_INVALID_HANDLE, "wrong status %x\n", status ); ok( U(iosb).Status == 0xdeadbabe, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0xdeadbeef, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); /* not reset on invalid handle */ + ok( is_signaled( event ), "event is not signaled\n" ); /* not reset on invalid handle */ ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( !apc_count, "apc was called\n" ); @@ -782,7 +782,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == STATUS_PIPE_BROKEN, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -807,7 +807,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == STATUS_CANCELLED, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -833,7 +833,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == STATUS_CANCELLED, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -859,7 +859,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == STATUS_CANCELLED, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -885,7 +885,7 @@ Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == STATUS_CANCELLED, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 2, "apc was not called\n" ); @@ -906,7 +906,7 @@ if (status == STATUS_PENDING) WaitForSingleObject( event, 1000 ); ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -923,7 +923,7 @@ if (status == STATUS_PENDING) WaitForSingleObject( event, 1000 ); ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -940,7 +940,7 @@ WaitForSingleObject( event, 1000 ); ok( U(iosb).Status == STATUS_END_OF_FILE, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -961,7 +961,7 @@ if (status == STATUS_PENDING) WaitForSingleObject( event, 1000 ); ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ ok( apc_count == 1, "apc was not called\n" ); @@ -975,7 +975,7 @@ ok( status == STATUS_SUCCESS, "wrong status %x\n", status ); ok( U(iosb).Status == STATUS_SUCCESS, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == strlen(text), "wrong info %lu\n", iosb.Information ); - ok( is_signaled( event ), "event is signaled\n" ); + ok( is_signaled( event ), "event is not signaled\n" ); ok( !apc_count, "apc was called\n" ); SleepEx( 1, TRUE ); /* alertable sleep */ todo_wine ok( !apc_count, "apc was called\n" ); @@ -1139,39 +1139,6 @@ if ( rc == STATUS_SUCCESS ) pNtClose(hslot); /* - * Test that the length field is checked properly - */ - attr.Length = 0; - rc = pNtCreateMailslotFile(&hslot, DesiredAccess, - &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize, - &TimeOut); - todo_wine ok( rc == STATUS_INVALID_PARAMETER, "rc = %x not c000000d STATUS_INVALID_PARAMETER\n", rc); - - if (rc == STATUS_SUCCESS) pNtClose(hslot); - - attr.Length = sizeof(OBJECT_ATTRIBUTES)+1; - rc = pNtCreateMailslotFile(&hslot, DesiredAccess, - &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize, - &TimeOut); - todo_wine ok( rc == STATUS_INVALID_PARAMETER, "rc = %x not c000000d STATUS_INVALID_PARAMETER\n", rc); - - if (rc == STATUS_SUCCESS) pNtClose(hslot); - - /* - * Test handling of a NULL unicode string in ObjectName - */ - InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); - attr.ObjectName = NULL; - rc = pNtCreateMailslotFile(&hslot, DesiredAccess, - &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize, - &TimeOut); - ok( rc == STATUS_OBJECT_PATH_SYNTAX_BAD || - rc == STATUS_INVALID_PARAMETER, - "rc = %x not STATUS_OBJECT_PATH_SYNTAX_BAD or STATUS_INVALID_PARAMETER\n", rc); - - if (rc == STATUS_SUCCESS) pNtClose(hslot); - - /* * Test a valid call */ InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/tests/info.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/tests/info.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/tests/info.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/tests/info.c 2016-02-08 19:32:34.000000000 +0000 @@ -23,6 +23,7 @@ #include static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); +static NTSTATUS (WINAPI * pNtQuerySystemInformationEx)(SYSTEM_INFORMATION_CLASS, void*, ULONG, void*, ULONG, ULONG*); static NTSTATUS (WINAPI * pNtPowerInformation)(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG); static NTSTATUS (WINAPI * pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); static NTSTATUS (WINAPI * pNtQueryInformationThread)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG); @@ -36,6 +37,7 @@ static NTSTATUS (WINAPI * pNtClose)(HANDLE); static ULONG (WINAPI * pNtGetCurrentProcessorNumber)(void); static BOOL (WINAPI * pIsWow64Process)(HANDLE, PBOOL); +static BOOL (WINAPI * pGetLogicalProcessorInformationEx)(LOGICAL_PROCESSOR_RELATIONSHIP,SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*,DWORD*); static BOOL is_wow64; @@ -56,6 +58,8 @@ { /* All needed functions are NT based, so using GetModuleHandle is a good check */ HMODULE hntdll = GetModuleHandleA("ntdll"); + HMODULE hkernel32 = GetModuleHandleA("kernel32"); + if (!hntdll) { win_skip("Not running on NT\n"); @@ -78,8 +82,16 @@ /* not present before XP */ pNtGetCurrentProcessorNumber = (void *) GetProcAddress(hntdll, "NtGetCurrentProcessorNumber"); - pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); + pIsWow64Process = (void *)GetProcAddress(hkernel32, "IsWow64Process"); if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE; + + /* starting with Win7 */ + pNtQuerySystemInformationEx = (void *) GetProcAddress(hntdll, "NtQuerySystemInformationEx"); + if (!pNtQuerySystemInformationEx) + win_skip("NtQuerySystemInformationEx() is not supported, some tests will be skipped.\n"); + + pGetLogicalProcessorInformationEx = (void *) GetProcAddress(hkernel32, "GetLogicalProcessorInformationEx"); + return TRUE; } @@ -487,7 +499,7 @@ /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */ ReturnLength = 0xdeadbeef; status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength); - todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); ok( ReturnLength != 0xdeadbeef, "Expected valid ReturnLength\n" ); SystemInformationLength = ReturnLength; @@ -503,13 +515,13 @@ } ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status ); ExpectedLength = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION, Handle[shi->Count]); - todo_wine ok( ReturnLength == ExpectedLength || broken(ReturnLength == ExpectedLength - sizeof(DWORD)), /* Vista / 2008 */ - "Expected length %u, got %u\n", ExpectedLength, ReturnLength ); - todo_wine ok( shi->Count > 1, "Expected more than 1 handle, got %u\n", shi->Count ); + ok( ReturnLength == ExpectedLength || broken(ReturnLength == ExpectedLength - sizeof(DWORD)), /* Vista / 2008 */ + "Expected length %u, got %u\n", ExpectedLength, ReturnLength ); + ok( shi->Count > 1, "Expected more than 1 handle, got %u\n", shi->Count ); for (i = 0, found = FALSE; i < shi->Count && !found; i++) found = (shi->Handle[i].OwnerPid == GetCurrentProcessId()) && ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle); - todo_wine ok( found, "Expected to find event handle in handle list\n" ); + ok( found, "Expected to find event handle in handle list\n" ); CloseHandle(EventHandle); @@ -696,6 +708,108 @@ HeapFree(GetProcessHeap(), 0, slpi); } +static void test_query_logicalprocex(void) +{ + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infoex, *infoex2; + DWORD relationship, len2, len; + NTSTATUS status; + BOOL ret; + + if (!pNtQuerySystemInformationEx) + return; + + len = 0; + relationship = RelationProcessorCore; + status = pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx, &relationship, sizeof(relationship), NULL, 0, &len); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "got 0x%08x\n", status); + ok(len > 0, "got %u\n", len); + + len = 0; + relationship = RelationAll; + status = pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx, &relationship, sizeof(relationship), NULL, 0, &len); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "got 0x%08x\n", status); + ok(len > 0, "got %u\n", len); + + len2 = 0; + ret = pGetLogicalProcessorInformationEx(RelationAll, NULL, &len2); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d, error %d\n", ret, GetLastError()); + ok(len == len2, "got %u, expected %u\n", len2, len); + + if (len && len == len2) { + int j, i; + + infoex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); + infoex2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); + + status = pNtQuerySystemInformationEx(SystemLogicalProcessorInformationEx, &relationship, sizeof(relationship), infoex, len, &len); + ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); + + ret = pGetLogicalProcessorInformationEx(RelationAll, infoex2, &len2); + ok(ret, "got %d, error %d\n", ret, GetLastError()); + ok(!memcmp(infoex, infoex2, len), "returned info data mismatch\n"); + + for(i = 0; status == STATUS_SUCCESS && i < len; ){ + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *ex = (void*)(((char *)infoex) + i); + + ok(ex->Relationship >= RelationProcessorCore && ex->Relationship <= RelationGroup, + "Got invalid relationship value: 0x%x\n", ex->Relationship); + if (!ex->Size) + { + ok(0, "got infoex[%u].Size=0\n", i); + break; + } + + trace("infoex[%u].Size: %u\n", i, ex->Size); + switch(ex->Relationship){ + case RelationProcessorCore: + case RelationProcessorPackage: + trace("infoex[%u].Relationship: 0x%x (Core == 0x0 or Package == 0x3)\n", i, ex->Relationship); + trace("infoex[%u].Processor.Flags: 0x%x\n", i, ex->Processor.Flags); + trace("infoex[%u].Processor.EfficiencyClass: 0x%x\n", i, ex->Processor.EfficiencyClass); + trace("infoex[%u].Processor.GroupCount: 0x%x\n", i, ex->Processor.GroupCount); + for(j = 0; j < ex->Processor.GroupCount; ++j){ + trace("infoex[%u].Processor.GroupMask[%u].Mask: 0x%lx\n", i, j, ex->Processor.GroupMask[j].Mask); + trace("infoex[%u].Processor.GroupMask[%u].Group: 0x%x\n", i, j, ex->Processor.GroupMask[j].Group); + } + break; + case RelationNumaNode: + trace("infoex[%u].Relationship: 0x%x (NumaNode)\n", i, ex->Relationship); + trace("infoex[%u].NumaNode.NodeNumber: 0x%x\n", i, ex->NumaNode.NodeNumber); + trace("infoex[%u].NumaNode.GroupMask.Mask: 0x%lx\n", i, ex->NumaNode.GroupMask.Mask); + trace("infoex[%u].NumaNode.GroupMask.Group: 0x%x\n", i, ex->NumaNode.GroupMask.Group); + break; + case RelationCache: + trace("infoex[%u].Relationship: 0x%x (Cache)\n", i, ex->Relationship); + trace("infoex[%u].Cache.Level: 0x%x\n", i, ex->Cache.Level); + trace("infoex[%u].Cache.Associativity: 0x%x\n", i, ex->Cache.Associativity); + trace("infoex[%u].Cache.LineSize: 0x%x\n", i, ex->Cache.LineSize); + trace("infoex[%u].Cache.CacheSize: 0x%x\n", i, ex->Cache.CacheSize); + trace("infoex[%u].Cache.Type: 0x%x\n", i, ex->Cache.Type); + trace("infoex[%u].Cache.GroupMask.Mask: 0x%lx\n", i, ex->Cache.GroupMask.Mask); + trace("infoex[%u].Cache.GroupMask.Group: 0x%x\n", i, ex->Cache.GroupMask.Group); + break; + case RelationGroup: + trace("infoex[%u].Relationship: 0x%x (Group)\n", i, ex->Relationship); + trace("infoex[%u].Group.MaximumGroupCount: 0x%x\n", i, ex->Group.MaximumGroupCount); + trace("infoex[%u].Group.ActiveGroupCount: 0x%x\n", i, ex->Group.ActiveGroupCount); + for(j = 0; j < ex->Group.ActiveGroupCount; ++j){ + trace("infoex[%u].Group.GroupInfo[%u].MaximumProcessorCount: 0x%x\n", i, j, ex->Group.GroupInfo[j].MaximumProcessorCount); + trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorCount: 0x%x\n", i, j, ex->Group.GroupInfo[j].ActiveProcessorCount); + trace("infoex[%u].Group.GroupInfo[%u].ActiveProcessorMask: 0x%lx\n", i, j, ex->Group.GroupInfo[j].ActiveProcessorMask); + } + break; + default: + break; + } + + i += ex->Size; + } + + HeapFree(GetProcessHeap(), 0, infoex); + HeapFree(GetProcessHeap(), 0, infoex2); + } +} + static void test_query_processor_power_info(void) { NTSTATUS status; @@ -1934,6 +2048,7 @@ /* 0x49 SystemLogicalProcessorInformation */ trace("Starting test_query_logicalproc()\n"); test_query_logicalproc(); + test_query_logicalprocex(); /* NtPowerInformation */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/tests/om.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/tests/om.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/tests/om.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/tests/om.c 2016-02-08 19:32:34.000000000 +0000 @@ -33,12 +33,23 @@ static NTSTATUS (WINAPI *pNtOpenEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES); static NTSTATUS (WINAPI *pNtPulseEvent) ( HANDLE, PULONG ); static NTSTATUS (WINAPI *pNtQueryEvent) ( HANDLE, EVENT_INFORMATION_CLASS, PVOID, ULONG, PULONG ); +static NTSTATUS (WINAPI *pNtCreateJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); +static NTSTATUS (WINAPI *pNtOpenJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); +static NTSTATUS (WINAPI *pNtCreateKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG, + const UNICODE_STRING *, ULONG, PULONG ); +static NTSTATUS (WINAPI *pNtOpenKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); +static NTSTATUS (WINAPI *pNtDeleteKey)( HANDLE ); +static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, + ULONG, ULONG, ULONG, PLARGE_INTEGER ); static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN ); static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES ); static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG ); +static NTSTATUS (WINAPI *pNtOpenSemaphore)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES ); static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE ); +static NTSTATUS (WINAPI *pNtOpenTimer)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES ); static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER, ULONG, ULONG, HANDLE ); +static NTSTATUS (WINAPI *pNtOpenSection)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG ); static NTSTATUS (WINAPI *pNtClose) ( HANDLE ); static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, @@ -55,6 +66,7 @@ static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * ); static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * ); static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG); +static NTSTATUS (WINAPI *pNtOpenIoCompletion)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); #define KEYEDEVENT_WAIT 0x0001 #define KEYEDEVENT_WAKE 0x0002 @@ -356,6 +368,514 @@ pNtClose(dir); } +static void test_all_kernel_objects( UINT line, OBJECT_ATTRIBUTES *attr, + NTSTATUS create_expect, NTSTATUS open_expect ) +{ + UNICODE_STRING target; + LARGE_INTEGER size; + NTSTATUS status, status2; + HANDLE ret, ret2; + + pRtlCreateUnicodeStringFromAsciiz( &target, "\\DosDevices" ); + size.QuadPart = 4096; + + status = pNtCreateMutant( &ret, GENERIC_ALL, attr, FALSE ); + ok( status == create_expect, "%u: NtCreateMutant failed %x\n", line, status ); + status2 = pNtOpenMutant( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenMutant failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateSemaphore( &ret, GENERIC_ALL, attr, 1, 2 ); + ok( status == create_expect, "%u: NtCreateSemaphore failed %x\n", line, status ); + status2 = pNtOpenSemaphore( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenSemaphore failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateEvent( &ret, GENERIC_ALL, attr, 1, 0 ); + ok( status == create_expect, "%u: NtCreateEvent failed %x\n", line, status ); + status2 = pNtOpenEvent( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenEvent failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, attr, 0 ); + ok( status == create_expect, "%u: NtCreateKeyedEvent failed %x\n", line, status ); + status2 = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenKeyedEvent failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateTimer( &ret, GENERIC_ALL, attr, NotificationTimer ); + ok( status == create_expect, "%u: NtCreateTimer failed %x\n", line, status ); + status2 = pNtOpenTimer( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenTimer failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateIoCompletion( &ret, GENERIC_ALL, attr, 0 ); + ok( status == create_expect, "%u: NtCreateCompletion failed %x\n", line, status ); + status2 = pNtOpenIoCompletion( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenCompletion failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateJobObject( &ret, GENERIC_ALL, attr ); + ok( status == create_expect, "%u: NtCreateJobObject failed %x\n", line, status ); + status2 = pNtOpenJobObject( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenJobObject failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, attr ); + ok( status == create_expect, "%u: NtCreateDirectoryObject failed %x\n", line, status ); + status2 = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenDirectoryObject failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, attr, &target ); + ok( status == create_expect, "%u: NtCreateSymbolicLinkObject failed %x\n", line, status ); + status2 = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, attr ); + ok( status2 == open_expect, "%u: NtOpenSymbolicLinkObject failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + status = pNtCreateSection( &ret, SECTION_MAP_WRITE, attr, &size, PAGE_READWRITE, SEC_COMMIT, 0 ); + ok( status == create_expect, "%u: NtCreateSection failed %x\n", line, status ); + status2 = pNtOpenSection( &ret2, SECTION_MAP_WRITE, attr ); + ok( status2 == open_expect, "%u: NtOpenSection failed %x\n", line, status2 ); + if (!status) pNtClose( ret ); + if (!status2) pNtClose( ret2 ); + pRtlFreeUnicodeString( &target ); +} + +static void test_name_limits(void) +{ + static const WCHAR pipeW[] = {'\\','D','e','v','i','c','e','\\','N','a','m','e','d','P','i','p','e','\\'}; + static const WCHAR mailslotW[] = {'\\','D','e','v','i','c','e','\\','M','a','i','l','S','l','o','t','\\'}; + static const WCHAR registryW[] = {'\\','R','E','G','I','S','T','R','Y','\\','M','a','c','h','i','n','e','\\','S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\'}; + OBJECT_ATTRIBUTES attr, attr2, attr3; + IO_STATUS_BLOCK iosb; + LARGE_INTEGER size, timeout; + UNICODE_STRING str, target; + NTSTATUS status; + HANDLE ret, ret2; + DWORD i; + + InitializeObjectAttributes( &attr, &str, 0, 0, NULL ); + InitializeObjectAttributes( &attr2, &str, 0, (HANDLE)0xdeadbeef, NULL ); + InitializeObjectAttributes( &attr3, &str, 0, 0, NULL ); + str.Buffer = HeapAlloc( GetProcessHeap(), 0, 65536 + sizeof(registryW)); + str.MaximumLength = 65534; + for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i] = 'a'; + size.QuadPart = 4096; + pRtlCreateUnicodeStringFromAsciiz( &target, "\\DosDevices" ); + + if (!(attr.RootDirectory = get_base_dir())) + { + win_skip( "couldn't find the BaseNamedObjects dir\n" ); + return; + } + + str.Length = 0; + status = pNtCreateMutant( &ret, GENERIC_ALL, &attr2, FALSE ); + ok( status == STATUS_SUCCESS, "%u: NtCreateMutant failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenMutant failed %x\n", str.Length, status ); + status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenMutant failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateSemaphore( &ret, GENERIC_ALL, &attr2, 1, 2 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateSemaphore failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSemaphore failed %x\n", str.Length, status ); + status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenSemaphore failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateEvent( &ret, GENERIC_ALL, &attr2, 1, 0 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateEvent failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenEvent failed %x\n", str.Length, status ); + status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenEvent failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, &attr2, 0 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateKeyedEvent failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenKeyedEvent failed %x\n", str.Length, status ); + status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenKeyedEvent failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateTimer( &ret, GENERIC_ALL, &attr2, NotificationTimer ); + ok( status == STATUS_SUCCESS, "%u: NtCreateTimer failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenTimer failed %x\n", str.Length, status ); + status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenTimer failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateIoCompletion( &ret, GENERIC_ALL, &attr2, 0 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateCompletion failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenCompletion failed %x\n", str.Length, status ); + status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenCompletion failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateJobObject( &ret, GENERIC_ALL, &attr2 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateJobObject failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenJobObject failed %x\n", str.Length, status ); + status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenJobObject failed %x\n", str.Length, status ); + pNtClose( ret ); + status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, &attr2 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateDirectoryObject failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_DENIED), /* winxp */ + "%u: NtOpenDirectoryObject failed %x\n", str.Length, status ); + if (!status) pNtClose( ret2 ); + status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr3 ); + ok( status == STATUS_SUCCESS, "%u: NtOpenDirectoryObject failed %x\n", str.Length, status ); + pNtClose( ret2 ); + pNtClose( ret ); + status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, &attr2, &target ); + ok( status == STATUS_SUCCESS, "%u: NtCreateSymbolicLinkObject failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSymbolicLinkObject failed %x\n", str.Length, status ); + status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr3 ); + todo_wine + ok( status == STATUS_SUCCESS, "%u: NtOpenSymbolicLinkObject failed %x\n", str.Length, status ); + pNtClose( ret2 ); + pNtClose( ret ); + status = pNtCreateSection( &ret, SECTION_MAP_WRITE, &attr2, &size, PAGE_READWRITE, SEC_COMMIT, 0 ); + ok( status == STATUS_SUCCESS, "%u: NtCreateSection failed %x\n", str.Length, status ); + attr3.RootDirectory = ret; + status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSection failed %x\n", str.Length, status ); + status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr3 ); + ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, + "%u: NtOpenSection failed %x\n", str.Length, status ); + pNtClose( ret ); + + str.Length = 67; + test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID ); + + str.Length = 65532; + test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS ); + + str.Length = 65534; + test_all_kernel_objects( __LINE__, &attr, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID ); + + str.Length = 128; + for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++) + { + if (attr.Length == sizeof(attr)) + test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS ); + else + test_all_kernel_objects( __LINE__, &attr, STATUS_INVALID_PARAMETER, STATUS_INVALID_PARAMETER ); + } + attr.Length = sizeof(attr); + + /* null attributes or ObjectName, with or without RootDirectory */ + attr3.RootDirectory = 0; + attr2.ObjectName = attr3.ObjectName = NULL; + test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID ); + test_all_kernel_objects( __LINE__, &attr3, STATUS_SUCCESS, STATUS_OBJECT_PATH_SYNTAX_BAD ); + + status = pNtCreateMutant( &ret, GENERIC_ALL, NULL, FALSE ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateMutant failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenMutant( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenMutant failed %x\n", status ); + status = pNtCreateSemaphore( &ret, GENERIC_ALL, NULL, 1, 2 ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateSemaphore failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenSemaphore( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSemaphore failed %x\n", status ); + status = pNtCreateEvent( &ret, GENERIC_ALL, NULL, 1, 0 ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateEvent failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenEvent( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenEvent failed %x\n", status ); + status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, NULL, 0 ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateKeyedEvent failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenKeyedEvent( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenKeyedEvent failed %x\n", status ); + status = pNtCreateTimer( &ret, GENERIC_ALL, NULL, NotificationTimer ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateTimer failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenTimer( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenTimer failed %x\n", status ); + status = pNtCreateIoCompletion( &ret, GENERIC_ALL, NULL, 0 ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateCompletion failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenIoCompletion( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenCompletion failed %x\n", status ); + status = pNtCreateJobObject( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateJobObject failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenJobObject( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenJobObject failed %x\n", status ); + status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateDirectoryObject failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenDirectoryObject( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenDirectoryObject failed %x\n", status ); + status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, NULL, &target ); + ok( status == STATUS_ACCESS_VIOLATION || broken( status == STATUS_SUCCESS), /* winxp */ + "NULL: NtCreateSymbolicLinkObject failed %x\n", status ); + if (!status) pNtClose( ret ); + status = pNtOpenSymbolicLinkObject( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSymbolicLinkObject failed %x\n", status ); + status = pNtCreateSection( &ret, SECTION_MAP_WRITE, NULL, &size, PAGE_READWRITE, SEC_COMMIT, 0 ); + ok( status == STATUS_SUCCESS, "NULL: NtCreateSection failed %x\n", status ); + pNtClose( ret ); + status = pNtOpenSection( &ret, SECTION_MAP_WRITE, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtOpenSection failed %x\n", status ); + attr2.ObjectName = attr3.ObjectName = &str; + + /* named pipes */ + memcpy( str.Buffer, pipeW, sizeof(pipeW) ); + for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(pipeW)/sizeof(WCHAR)] = 'a'; + str.Length = 0; + attr.RootDirectory = 0; + attr.Attributes = OBJ_CASE_INSENSITIVE; + timeout.QuadPart = -10000; + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + str.Length = 67; + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + str.Length = 128; + for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++) + { + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + if (attr.Length == sizeof(attr)) + { + ok( status == STATUS_SUCCESS, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + pNtClose( ret ); + } + else ok( status == STATUS_INVALID_PARAMETER, + "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + } + attr.Length = sizeof(attr); + str.Length = 65532; + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_SUCCESS, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + pNtClose( ret ); + str.Length = 65534; + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); + attr3.RootDirectory = 0; + attr2.ObjectName = attr3.ObjectName = NULL; + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateNamedPipeFile failed %x\n", status ); + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr3, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateNamedPipeFile failed %x\n", status ); + status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, NULL, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateNamedPipeFile failed %x\n", status ); + attr2.ObjectName = attr3.ObjectName = &str; + + /* mailslots */ + memcpy( str.Buffer, mailslotW, sizeof(mailslotW) ); + for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(mailslotW)/sizeof(WCHAR)] = 'a'; + str.Length = 0; + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + str.Length = 67; + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + str.Length = 128; + for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++) + { + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL ); + if (attr.Length == sizeof(attr)) + { + ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + pNtClose( ret ); + } + else ok( status == STATUS_INVALID_PARAMETER, + "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + } + attr.Length = sizeof(attr); + str.Length = 65532; + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_SUCCESS, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + pNtClose( ret ); + str.Length = 65534; + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); + attr3.RootDirectory = 0; + attr2.ObjectName = attr3.ObjectName = NULL; + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateMailslotFile failed %x\n", status ); + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr3, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateMailslotFile failed %x\n", status ); + status = pNtCreateMailslotFile( &ret, GENERIC_ALL, NULL, &iosb, 0, 0, 0, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateMailslotFile failed %x\n", status ); + attr2.ObjectName = attr3.ObjectName = &str; + + /* registry keys */ + memcpy( str.Buffer, registryW, sizeof(registryW) ); + for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(registryW)/sizeof(WCHAR)] = 'a'; + str.Length = 0; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + todo_wine + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL ); + ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 ); + ok( status == STATUS_INVALID_HANDLE, "%u: NtOpenKey failed %x\n", str.Length, status ); + str.Length = sizeof(registryW) + 250 * sizeof(WCHAR) + 1; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID || + status == STATUS_INVALID_PARAMETER || + broken( status == STATUS_SUCCESS ), /* wow64 */ + "%u: NtCreateKey failed %x\n", str.Length, status ); + if (!status) + { + pNtDeleteKey( ret ); + pNtClose( ret ); + } + str.Length = sizeof(registryW) + 256 * sizeof(WCHAR); + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, + "%u: NtCreateKey failed %x\n", str.Length, status ); + if (!status) + { + status = pNtOpenKey( &ret2, KEY_READ, &attr ); + ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %x\n", str.Length, status ); + pNtClose( ret2 ); + attr3.RootDirectory = ret; + str.Length = 0; + status = pNtOpenKey( &ret2, KEY_READ, &attr3 ); + ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %x\n", str.Length, status ); + pNtClose( ret2 ); + pNtDeleteKey( ret ); + pNtClose( ret ); + + str.Length = sizeof(registryW) + 256 * sizeof(WCHAR); + for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++) + { + if (attr.Length == sizeof(attr)) + { + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_SUCCESS, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret2, KEY_READ, &attr ); + ok( status == STATUS_SUCCESS, "%u: NtOpenKey failed %x\n", str.Length, status ); + pNtClose( ret2 ); + pNtDeleteKey( ret ); + pNtClose( ret ); + } + else + { + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret2, KEY_READ, &attr ); + ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %x\n", str.Length, status ); + } + } + attr.Length = sizeof(attr); + } + str.Length = sizeof(registryW) + 256 * sizeof(WCHAR) + 1; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID || + status == STATUS_INVALID_PARAMETER || + broken( status == STATUS_SUCCESS ), /* win7 */ + "%u: NtCreateKey failed %x\n", str.Length, status ); + if (!status) + { + pNtDeleteKey( ret ); + pNtClose( ret ); + } + status = pNtOpenKey( &ret, GENERIC_ALL, &attr ); + ok( status == STATUS_OBJECT_NAME_INVALID || + status == STATUS_INVALID_PARAMETER || + broken( status == STATUS_OBJECT_NAME_NOT_FOUND ), /* wow64 */ + "%u: NtOpenKey failed %x\n", str.Length, status ); + str.Length++; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr ); + todo_wine + ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %x\n", str.Length, status ); + str.Length = 2000; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_INVALID_PARAMETER, "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr ); + todo_wine + ok( status == STATUS_INVALID_PARAMETER, "%u: NtOpenKey failed %x\n", str.Length, status ); + /* some Windows versions change the error past 2050 chars, others past 4066 chars, some don't */ + str.Length = 5000; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_BUFFER_OVERFLOW || + status == STATUS_BUFFER_TOO_SMALL || + status == STATUS_INVALID_PARAMETER, + "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr ); + todo_wine + ok( status == STATUS_BUFFER_OVERFLOW || + status == STATUS_BUFFER_TOO_SMALL || + status == STATUS_INVALID_PARAMETER, + "%u: NtOpenKey failed %x\n", str.Length, status ); + str.Length = 65534; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL ); + ok( status == STATUS_OBJECT_NAME_INVALID || + status == STATUS_BUFFER_OVERFLOW || + status == STATUS_BUFFER_TOO_SMALL, + "%u: NtCreateKey failed %x\n", str.Length, status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr ); + todo_wine + ok( status == STATUS_OBJECT_NAME_INVALID || + status == STATUS_BUFFER_OVERFLOW || + status == STATUS_BUFFER_TOO_SMALL, + "%u: NtOpenKey failed %x\n", str.Length, status ); + attr3.RootDirectory = 0; + attr2.ObjectName = attr3.ObjectName = NULL; + status = pNtCreateKey( &ret, GENERIC_ALL, &attr2, 0, NULL, 0, NULL ); + todo_wine + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE, + "NULL: NtCreateKey failed %x\n", status ); + status = pNtCreateKey( &ret, GENERIC_ALL, &attr3, 0, NULL, 0, NULL ); + todo_wine + ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %x\n", status ); + status = pNtCreateKey( &ret, GENERIC_ALL, NULL, 0, NULL, 0, NULL ); + ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtCreateKey failed %x\n", status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr2 ); + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE, + "NULL: NtOpenKey failed %x\n", status ); + status = pNtOpenKey( &ret, GENERIC_ALL, &attr3 ); + ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %x\n", status ); + status = pNtOpenKey( &ret, GENERIC_ALL, NULL ); + ok( status == STATUS_ACCESS_VIOLATION, "NULL: NtOpenKey failed %x\n", status ); + attr2.ObjectName = attr3.ObjectName = &str; + + pRtlFreeUnicodeString( &str ); + pRtlFreeUnicodeString( &target ); +} + static void test_directory(void) { NTSTATUS status; @@ -682,10 +1202,13 @@ char buffer[1024]; NTSTATUS status; ULONG len, expected_len; - UNICODE_STRING *str; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING path, *str; char dir[MAX_PATH], tmp_path[MAX_PATH], file1[MAX_PATH + 16]; LARGE_INTEGER size; + InitializeObjectAttributes( &attr, &path, 0, 0, 0 ); + handle = CreateEventA( NULL, FALSE, FALSE, "test_event" ); len = 0; @@ -715,9 +1238,12 @@ str = (UNICODE_STRING *)buffer; ok( sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR) == len, "unexpected len %u\n", len ); ok( str->Length >= sizeof(name), "unexpected len %u\n", str->Length ); + ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_event") * sizeof(WCHAR), + "name too short %s\n", wine_dbgstr_w(str->Buffer) ); /* there can be a \\Sessions prefix in the name */ ok( !memcmp( str->Buffer + (str->Length - sizeof(name)) / sizeof(WCHAR), name, sizeof(name) ), "wrong name %s\n", wine_dbgstr_w(str->Buffer) ); + trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); len -= sizeof(WCHAR); status = pNtQueryObject( handle, ObjectNameInformation, buffer, len, &len ); @@ -851,6 +1377,67 @@ ok( str->Buffer && !memcmp( str->Buffer, type_section, sizeof(type_section) ), "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer ); pNtClose( handle ); + + handle = CreateMailslotA( "\\\\.\\mailslot\\test_mailslot", 100, 1000, NULL ); + ok( handle != INVALID_HANDLE_VALUE, "CreateMailslot failed err %u\n", GetLastError() ); + len = 0; + status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status ); + str = (UNICODE_STRING *)buffer; + ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); + str = (UNICODE_STRING *)buffer; + expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR); + ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */ + "unexpected len %u\n", len ); + ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_mailslot") * sizeof(WCHAR), + "name too short %s\n", wine_dbgstr_w(str->Buffer) ); + trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); + pNtClose( handle ); + + handle = CreateNamedPipeA( "\\\\.\\pipe\\test_pipe", PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE, + 1, 1000, 1000, 1000, NULL ); + ok( handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed err %u\n", GetLastError() ); + len = 0; + status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status ); + str = (UNICODE_STRING *)buffer; + todo_wine + ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); + str = (UNICODE_STRING *)buffer; + expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR); + todo_wine + ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */ + "unexpected len %u\n", len ); + todo_wine + ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_pipe") * sizeof(WCHAR), + "name too short %s\n", wine_dbgstr_w(str->Buffer) ); + trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); + pNtClose( handle ); + + pRtlCreateUnicodeStringFromAsciiz( &path, "\\REGISTRY\\Machine\\Software\\Classes" ); + status = pNtCreateKey( &handle, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 ); + ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, + "NtCreateKey failed status %x\n", status ); + pRtlFreeUnicodeString( &path ); + if (status == STATUS_SUCCESS) + { + len = 0; + status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status ); + str = (UNICODE_STRING *)buffer; + todo_wine + ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); + str = (UNICODE_STRING *)buffer; + expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR); + todo_wine + ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */ + "unexpected len %u\n", len ); + todo_wine + ok( len > sizeof(UNICODE_STRING) + sizeof("\\Classes") * sizeof(WCHAR), + "name too short %s\n", wine_dbgstr_w(str->Buffer) ); + trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); + pNtClose( handle ); + } } static void test_type_mismatch(void) @@ -1206,6 +1793,12 @@ pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz"); pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent"); + pNtCreateJobObject = (void *)GetProcAddress(hntdll, "NtCreateJobObject"); + pNtOpenJobObject = (void *)GetProcAddress(hntdll, "NtOpenJobObject"); + pNtCreateKey = (void *)GetProcAddress(hntdll, "NtCreateKey"); + pNtOpenKey = (void *)GetProcAddress(hntdll, "NtOpenKey"); + pNtDeleteKey = (void *)GetProcAddress(hntdll, "NtDeleteKey"); + pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile"); pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant"); pNtOpenEvent = (void *)GetProcAddress(hntdll, "NtOpenEvent"); pNtQueryEvent = (void *)GetProcAddress(hntdll, "NtQueryEvent"); @@ -1221,8 +1814,11 @@ pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject"); pNtQuerySymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject"); pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore"); + pNtOpenSemaphore = (void *)GetProcAddress(hntdll, "NtOpenSemaphore"); pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer"); + pNtOpenTimer = (void *)GetProcAddress(hntdll, "NtOpenTimer"); pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection"); + pNtOpenSection = (void *)GetProcAddress(hntdll, "NtOpenSection"); pNtQueryObject = (void *)GetProcAddress(hntdll, "NtQueryObject"); pNtReleaseSemaphore = (void *)GetProcAddress(hntdll, "NtReleaseSemaphore"); pNtCreateKeyedEvent = (void *)GetProcAddress(hntdll, "NtCreateKeyedEvent"); @@ -1230,10 +1826,12 @@ pNtWaitForKeyedEvent = (void *)GetProcAddress(hntdll, "NtWaitForKeyedEvent"); pNtReleaseKeyedEvent = (void *)GetProcAddress(hntdll, "NtReleaseKeyedEvent"); pNtCreateIoCompletion = (void *)GetProcAddress(hntdll, "NtCreateIoCompletion"); + pNtOpenIoCompletion = (void *)GetProcAddress(hntdll, "NtOpenIoCompletion"); test_case_sensitive(); test_namespace_pipe(); test_name_collisions(); + test_name_limits(); test_directory(); test_symboliclink(); test_query_object(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/thread.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/thread.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/thread.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/thread.c 2016-02-08 19:32:34.000000000 +0000 @@ -463,7 +463,7 @@ pthread_t pthread_id; pthread_attr_t attr; struct ntdll_thread_data *thread_data; - struct startup_info *info = NULL; + struct startup_info *info; HANDLE handle = 0, actctx = 0; TEB *teb = NULL; DWORD tid = 0; @@ -732,7 +732,7 @@ { NTSTATUS ret; DWORD dummy, i; - BOOL self = FALSE; + BOOL self; #ifdef __i386__ /* on i386 debug registers always require a server call */ @@ -746,6 +746,8 @@ ntdll_get_thread_data()->dr6 == context->Dr6 && ntdll_get_thread_data()->dr7 == context->Dr7); } +#else + self = FALSE; #endif if (!self) @@ -830,9 +832,11 @@ DWORD needed_flags = context->ContextFlags; BOOL self = (handle == GetCurrentThread()); + /* on i386/amd64 debug registers always require a server call */ #ifdef __i386__ - /* on i386 debug registers always require a server call */ if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386)) self = FALSE; +#elif defined(__x86_64__) + if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_AMD64)) self = FALSE; #endif if (!self) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/virtual.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/virtual.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ntdll/virtual.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ntdll/virtual.c 2016-02-08 19:32:34.000000000 +0000 @@ -2460,24 +2460,13 @@ { NTSTATUS ret; unsigned int vprot; - DWORD len = (attr && attr->ObjectName) ? attr->ObjectName->Length : 0; - struct security_descriptor *sd = NULL; - struct object_attributes objattr; + data_size_t len; + struct object_attributes *objattr; /* Check parameters */ - if (len > MAX_PATH*sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; - if ((ret = get_vprot_flags( protect, &vprot, sec_flags & SEC_IMAGE ))) return ret; - - objattr.rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); - objattr.sd_len = 0; - objattr.name_len = len; - if (attr) - { - ret = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); - if (ret != STATUS_SUCCESS) return ret; - } + if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret; if (!(sec_flags & SEC_RESERVE)) vprot |= VPROT_COMMITTED; if (sec_flags & SEC_NOCACHE) vprot |= VPROT_NOCACHE; @@ -2488,20 +2477,16 @@ SERVER_START_REQ( create_mapping ) { req->access = access; - req->attributes = (attr) ? attr->Attributes : 0; req->file_handle = wine_server_obj_handle( file ); req->size = size ? size->QuadPart : 0; req->protect = vprot; - wine_server_add_data( req, &objattr, sizeof(objattr) ); - if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + wine_server_add_data( req, objattr, len ); ret = wine_server_call( req ); *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; - NTDLL_free_struct_sd( sd ); - + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return ret; } @@ -2513,17 +2498,18 @@ NTSTATUS WINAPI NtOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { NTSTATUS ret; - DWORD len = attr->ObjectName->Length; - if (len > MAX_PATH*sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + if ((ret = validate_open_object_attributes( attr ))) return ret; SERVER_START_REQ( open_mapping ) { - req->access = access; + req->access = access; req->attributes = attr->Attributes; - req->rootdir = wine_server_obj_handle( attr->RootDirectory ); - wine_server_add_data( req, attr->ObjectName->Buffer, len ); - if (!(ret = wine_server_call( req ))) *handle = wine_server_ptr_handle( reply->handle ); + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); + ret = wine_server_call( req ); + *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return ret; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.c 2016-02-08 19:32:34.000000000 +0000 @@ -30,6 +30,7 @@ #include "ole2.h" #include "oleauto.h" #include "winerror.h" +#include "wownt32.h" #include "wine/windef16.h" #include "wine/winbase16.h" @@ -39,6 +40,200 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); +#define E_OUTOFMEMORY16 MAKE_SCODE(SEVERITY_ERROR, FACILITY_NULL, 2) +#define E_INVALIDARG16 MAKE_SCODE(SEVERITY_ERROR, FACILITY_NULL, 3) + +/* 16-bit SAFEARRAY implementation */ +typedef struct tagSAFEARRAYBOUND16 +{ + ULONG cElements; + LONG lLbound; +} SAFEARRAYBOUND16; + +typedef struct tagSAFEARRAY16 +{ + USHORT cDims; + USHORT fFeatures; + USHORT cbElements; + USHORT cLocks; + ULONG handle; + SEGPTR pvData; + SAFEARRAYBOUND16 rgsabound[1]; +} SAFEARRAY16; + +static SEGPTR safearray_alloc(ULONG size) +{ + HANDLE16 h; + return WOWGlobalAllocLock16(GPTR, size, &h); +} + +static void safearray_free(SEGPTR ptr) +{ + WOWGlobalUnlockFree16(ptr); +} + +static ULONG safearray_getcellcount(const SAFEARRAY16 *sa) +{ + const SAFEARRAYBOUND16 *sab = sa->rgsabound; + USHORT count = sa->cDims; + ULONG cells = 1; + + while (count--) + { + if (!sab->cElements) + return 0; + cells *= sab->cElements; + sab++; + } + + return cells; +} + +static HRESULT safearray_lock(SAFEARRAY16 *sa) +{ + if (sa->cLocks == 0xffff) + return E_UNEXPECTED; + + sa->cLocks++; + return S_OK; +} + +/****************************************************************************** + * SafeArrayGetDim [OLE2DISP.17] + */ +USHORT WINAPI SafeArrayGetDim16(SAFEARRAY16 *sa) +{ + TRACE("(%p)\n", sa); + return sa->cDims; +} + +/****************************************************************************** + * SafeArrayGetElemsize [OLE2DISP.18] + */ +USHORT WINAPI SafeArrayGetElemsize16(SAFEARRAY16 *sa) +{ + TRACE("(%p)\n", sa); + return sa->cbElements; +} + +/****************************************************************************** + * SafeArrayLock [OLE2DISP.21] + */ +HRESULT WINAPI SafeArrayLock16(SAFEARRAY16 *sa) +{ + TRACE("(%p)\n", sa); + + if (!sa) + return E_INVALIDARG16; + + return safearray_lock(sa); +} + +/****************************************************************************** + * SafeArrayUnlock [OLE2DISP.22] + */ +HRESULT WINAPI SafeArrayUnlock16(SAFEARRAY16 *sa) +{ + TRACE("(%p)\n", sa); + + if (!sa) + return E_INVALIDARG16; + + if (sa->cLocks == 0) + return E_UNEXPECTED; + + sa->cLocks--; + return S_OK; +} + +/****************************************************************************** + * SafeArrayAccessData [OLE2DISP.23] + */ +HRESULT WINAPI SafeArrayAccessData16(SAFEARRAY16 *sa, SEGPTR *data) +{ + HRESULT hr; + + TRACE("(%p, %p)\n", sa, data); + + /* arguments are not tested, it crashes if any of them is NULL */ + + hr = safearray_lock(sa); + if (FAILED(hr)) + return hr; + + *data = sa->pvData; + return S_OK; +} + +/****************************************************************************** + * SafeArrayUnaccessData [OLE2DISP.24] + */ +HRESULT WINAPI SafeArrayUnaccessData16(SAFEARRAY16 *sa) +{ + TRACE("(%p)\n", sa); + return SafeArrayUnlock16(sa); +} + +/****************************************************************************** + * SafeArrayAllocDescriptor [OLE2DISP.38] + */ +HRESULT WINAPI SafeArrayAllocDescriptor16(UINT16 dims, SEGPTR *ret) +{ + SAFEARRAY16 *sa; + ULONG size; + + TRACE("%u, %p\n", dims, ret); + + if (!dims) + return E_INVALIDARG16; + + size = sizeof(SAFEARRAY16) + sizeof(SAFEARRAYBOUND16) * (dims - 1); + *ret = safearray_alloc(size); + if (!*ret) + return E_OUTOFMEMORY16; + + sa = MapSL(*ret); + sa->cDims = dims; + return S_OK; +} + +/****************************************************************************** + * SafeArrayAllocData [OLE2DISP.39] + */ +HRESULT WINAPI SafeArrayAllocData16(SAFEARRAY16 *sa) +{ + ULONG size; + + TRACE("%p\n", sa); + + if (!sa) + return E_INVALIDARG16; + + size = safearray_getcellcount(sa); + sa->pvData = safearray_alloc(size * sa->cbElements); + return sa->pvData ? S_OK : E_OUTOFMEMORY16; +} + +/****************************************************************************** + * SafeArrayDestroyDescriptor [OLE2DISP.40] + */ +HRESULT WINAPI SafeArrayDestroyDescriptor16(SEGPTR s) +{ + TRACE("0x%08x\n", s); + + if (s) + { + SAFEARRAY16 *sa = MapSL(s); + + if (sa->cLocks) + return DISP_E_ARRAYISLOCKED; + + safearray_free(s); + } + + return S_OK; +} + /* This implementation of the BSTR API is 16-bit only. It represents BSTR as a 16:16 far pointer, and the strings as ISO-8859 */ @@ -276,3 +471,12 @@ FIXME("stub: (%d, %p)\n", dwReserved, perrinfo); return E_INVALIDARG; } + +/****************************************************************************** + * VariantInit [OLE2DISP.8] + */ +void WINAPI VariantInit16(VARIANTARG16 *v) +{ + TRACE("(%p)\n", v); + v->vt = VT_EMPTY; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.dll16.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.dll16.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.dll16.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.dll16.spec 2016-02-08 19:32:34.000000000 +0000 @@ -5,7 +5,7 @@ 5 pascal SysReAllocStringLen(ptr str word) SysReAllocStringLen16 6 pascal SysFreeString(segstr) SysFreeString16 7 pascal SysStringLen(segstr) SysStringLen16 -8 stub VARIANTINIT +8 pascal VariantInit(ptr) VariantInit16 9 stub VARIANTCLEAR 10 stub VARIANTCOPY 11 stub VARIANTCOPYIND @@ -14,14 +14,14 @@ 14 stub DOSDATETIMETOVARIANTTIME 15 stub SAFEARRAYCREATE 16 stub SAFEARRAYDESTROY -17 stub SAFEARRAYGETDIM -18 stub SAFEARRAYGETELEMSIZE +17 pascal -ret16 SafeArrayGetDim(ptr) SafeArrayGetDim16 +18 pascal -ret16 SafeArrayGetElemsize(ptr) SafeArrayGetElemsize16 19 stub SAFEARRAYGETUBOUND 20 stub SAFEARRAYGETLBOUND -21 stub SAFEARRAYLOCK -22 stub SAFEARRAYUNLOCK -23 stub SAFEARRAYACCESSDATA -24 stub SAFEARRAYUNACCESSDATA +21 pascal SafeArrayLock(ptr) SafeArrayLock16 +22 pascal SafeArrayUnlock(ptr) SafeArrayUnlock16 +23 pascal SafeArrayAccessData(ptr ptr) SafeArrayAccessData16 +24 pascal SafeArrayUnaccessData(ptr) SafeArrayUnaccessData16 25 stub SAFEARRAYGETELEMENT 26 stub SAFEARRAYPUTELEMENT 27 stub SAFEARRAYCOPY @@ -35,9 +35,9 @@ 35 pascal RegisterActiveObject(ptr ptr long ptr) RegisterActiveObject16 36 stub REVOKEACTIVEOBJECT 37 stub GETACTIVEOBJECT -38 stub SAFEARRAYALLOCDESCRIPTOR -39 stub SAFEARRAYALLOCDATA -40 stub SAFEARRAYDESTROYDESCRIPTOR +38 pascal SafeArrayAllocDescriptor(word ptr) SafeArrayAllocDescriptor16 +39 pascal SafeArrayAllocData(ptr) SafeArrayAllocData16 +40 pascal SafeArrayDestroyDescriptor(segptr) SafeArrayDestroyDescriptor16 41 stub SAFEARRAYDESTROYDATA 42 stub SAFEARRAYREDIM 43 stub VARI2FROMI4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.h wine-staging-1.9.3~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole2disp.dll16/ole2disp.h 2016-02-08 19:32:34.000000000 +0000 @@ -39,4 +39,43 @@ int WINAPI SysReAllocStringLen16(BSTR16*, const char*, int); int WINAPI SysStringLen16(BSTR16); +typedef struct tagVARIANT16 { + VARTYPE vt; + WORD wReserved1; + WORD wReserved2; + WORD wReserved3; + union { + BYTE bVal; + SHORT iVal; + LONG lVal; + FLOAT fltVal; + DOUBLE dblVal; + VARIANT_BOOL boolVal; + SCODE scode; + DATE date; +/* BSTR16 */ SEGPTR bstrVal; + CY cyVal; +/* IUnknown* */ SEGPTR punkVal; +/* IDispatch* */ SEGPTR pdispVal; +/* SAFEARRAY* */ SEGPTR parray; +/* BYTE* */ SEGPTR pbVal; +/* SHORT* */ SEGPTR piVal; +/* LONG* */ SEGPTR plVal; +/* FLOAT* */ SEGPTR pfltVal; +/* DOUBLE* */ SEGPTR pdblVal; +/* VARIANT_BOOL* */ SEGPTR pboolVal; +/* SCODE* */ SEGPTR pscode; +/* DATE* */ SEGPTR pdate; +/* BSTR16* */ SEGPTR pbstrVal; +/* VARIANT16* */ SEGPTR pvarVal; +/* void* */ SEGPTR byref; +/* CY* */ SEGPTR pcyVal; +/* IUnknown** */ SEGPTR ppunkVal; +/* IDispatch** */ SEGPTR ppdispVal; +/* SAFEARRAY** */ SEGPTR pparray; + } u; +} VARIANT16; + +typedef VARIANT16 VARIANTARG16; + #endif /* !defined(__WINE_OLEAUT32_OLE2DISP_H) */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole2.dll16/ole2.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ole2.dll16/ole2.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole2.dll16/ole2.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole2.dll16/ole2.c 2016-02-08 19:32:34.000000000 +0000 @@ -46,6 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); +#define E_INVALIDARG16 MAKE_SCODE(SEVERITY_ERROR, FACILITY_NULL, 3) static HICON convert_icon_to_32( HICON16 icon16 ) { @@ -273,6 +274,9 @@ return OleFlushClipboard(); } +#define GET_SEGPTR_METHOD_ADDR(ifacename,segptr,methodname) \ + ((SEGPTR)((const ifacename##Vtbl*)MapSL((SEGPTR)((ifacename*)MapSL(segptr))->lpVtbl))->methodname) + /*********************************************************************** * ReadClassStg (OLE2.18) * @@ -296,22 +300,26 @@ TRACE("(%x, %p)\n", pstg, pclsid); - if(pclsid==NULL) - return E_POINTER; + if (!pclsid) + return E_INVALIDARG16; + + memset(pclsid, 0, sizeof(*pclsid)); + + if (!pstg) + return E_INVALIDARG16; + /* * read a STATSTG structure (contains the clsid) from the storage */ - args[0] = (DWORD)pstg; /* iface */ + args[0] = pstg; /* iface */ args[1] = WOWGlobalAllocLock16( 0, sizeof(STATSTG16), &hstatstg ); args[2] = STATFLAG_DEFAULT; if (!WOWCallback16Ex( - (DWORD)((const IStorage16Vtbl*)MapSL( - (SEGPTR)((LPSTORAGE16)MapSL(pstg))->lpVtbl) - )->Stat, + GET_SEGPTR_METHOD_ADDR(IStorage16, pstg, Stat), WCB16_PASCAL, 3*sizeof(DWORD), - (LPVOID)args, + args, (LPDWORD)&hres )) { WOWGlobalUnlockFree16(args[1]); @@ -329,6 +337,58 @@ } /*********************************************************************** + * ReadClassStm (OLE2.20) + */ +HRESULT WINAPI ReadClassStm16(SEGPTR stream, CLSID *clsid) +{ + HANDLE16 hclsid, hread; + HRESULT hres; + DWORD args[4]; + + TRACE("(0x%x, %p)\n", stream, clsid); + + if (!clsid) + return E_INVALIDARG16; + + memset(clsid, 0, sizeof(*clsid)); + + if (!stream) + return E_INVALIDARG16; + + args[0] = stream; /* iface */ + args[1] = WOWGlobalAllocLock16( 0, sizeof(CLSID), &hclsid ); + args[2] = sizeof(CLSID); + args[3] = WOWGlobalAllocLock16( 0, sizeof(ULONG), &hread ); + + if (WOWCallback16Ex( + GET_SEGPTR_METHOD_ADDR(IStream16, stream, Read), + WCB16_PASCAL, + 4*sizeof(DWORD), + args, + (DWORD*)&hres)) + { + ULONG readlen; + + memcpy(&readlen, MapSL(args[3]), sizeof(readlen)); + if (readlen == sizeof(CLSID)) + memcpy(clsid, MapSL(args[1]), sizeof(CLSID)); + else + hres = STG_E_READFAULT; + + TRACE("clsid is %s\n", debugstr_guid(clsid)); + } + else + { + ERR("CallTo16 IStream16::Read() failed, hres %x\n", hres); + hres = E_FAIL; + } + WOWGlobalUnlockFree16(args[1]); + WOWGlobalUnlockFree16(args[3]); + + return hres; +} + +/*********************************************************************** * GetConvertStg (OLE2.82) */ HRESULT WINAPI GetConvertStg16(LPSTORAGE stg) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole2.dll16/ole2.dll16.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/ole2.dll16/ole2.dll16.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole2.dll16/ole2.dll16.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole2.dll16/ole2.dll16.spec 2016-02-08 19:32:34.000000000 +0000 @@ -17,7 +17,7 @@ 17 stub OLELOCKRUNNING 18 pascal ReadClassStg(segptr ptr) ReadClassStg16 19 pascal WriteClassStg(segptr ptr) WriteClassStg16 -20 stub READCLASSSTM +20 pascal ReadClassStm(segptr ptr) ReadClassStm16 21 stub WRITECLASSSTM 22 stub BINDMONIKER 23 stub MKPARSEDISPLAYNAME diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/clipboard.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/clipboard.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/clipboard.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/clipboard.c 2016-02-08 19:32:34.000000000 +0000 @@ -174,6 +174,15 @@ */ static ole_clipbrd* theOleClipboard; +static CRITICAL_SECTION latest_snapshot_cs; +static CRITICAL_SECTION_DEBUG latest_snapshot_cs_debug = +{ + 0, 0, &latest_snapshot_cs, + { &latest_snapshot_cs_debug.ProcessLocksList, &latest_snapshot_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": clipboard last snapshot") } +}; +static CRITICAL_SECTION latest_snapshot_cs = { &latest_snapshot_cs_debug, -1, 0, 0, 0, 0 }; + static inline HRESULT get_ole_clipbrd(ole_clipbrd **clipbrd) { struct oletls *info = COM_CurrentInfo(); @@ -1042,13 +1051,17 @@ if (ref == 0) { - ole_clipbrd *clipbrd; - HRESULT hr = get_ole_clipbrd(&clipbrd); + EnterCriticalSection(&latest_snapshot_cs); + if (This->ref) + { + LeaveCriticalSection(&latest_snapshot_cs); + return ref; + } + if (theOleClipboard->latest_snapshot == This) + theOleClipboard->latest_snapshot = NULL; + LeaveCriticalSection(&latest_snapshot_cs); if(This->data) IDataObject_Release(This->data); - - if(SUCCEEDED(hr) && clipbrd->latest_snapshot == This) - clipbrd->latest_snapshot = NULL; HeapFree(GetProcessHeap(), 0, This); } @@ -2188,21 +2201,28 @@ TRACE("(%p)\n", obj); if(!obj) return E_INVALIDARG; + *obj = NULL; if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr; seq_no = GetClipboardSequenceNumber(); + EnterCriticalSection(&latest_snapshot_cs); if(clipbrd->latest_snapshot && clipbrd->latest_snapshot->seq_no != seq_no) clipbrd->latest_snapshot = NULL; if(!clipbrd->latest_snapshot) { clipbrd->latest_snapshot = snapshot_construct(seq_no); - if(!clipbrd->latest_snapshot) return E_OUTOFMEMORY; + if(!clipbrd->latest_snapshot) + { + LeaveCriticalSection(&latest_snapshot_cs); + return E_OUTOFMEMORY; + } } *obj = &clipbrd->latest_snapshot->IDataObject_iface; IDataObject_AddRef(*obj); + LeaveCriticalSection(&latest_snapshot_cs); return S_OK; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/compobj.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/compobj.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/compobj.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/compobj.c 2016-02-08 19:32:34.000000000 +0000 @@ -1972,6 +1972,8 @@ if (!--info->inits) { + if (info->ole_inits) + WARN("uninitializing apartment while Ole is still initialized\n"); apartment_release(info->apt); info->apt = NULL; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/ifs.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/ifs.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/ifs.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/ifs.c 2016-02-08 19:32:34.000000000 +0000 @@ -143,8 +143,8 @@ /****************************************************************************** * IMalloc32_QueryInterface [VTABLE] */ -static HRESULT WINAPI IMalloc_fnQueryInterface(LPMALLOC iface,REFIID refiid,LPVOID *obj) { - +static HRESULT WINAPI IMalloc_fnQueryInterface(IMalloc *iface, REFIID refiid, void **obj) +{ TRACE("(%s,%p)\n",debugstr_guid(refiid),obj); if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMalloc,refiid)) { @@ -157,21 +157,22 @@ /****************************************************************************** * IMalloc32_AddRefRelease [VTABLE] */ -static ULONG WINAPI IMalloc_fnAddRefRelease (LPMALLOC iface) { +static ULONG WINAPI IMalloc_fnAddRefRelease(IMalloc *iface) +{ return 1; } /****************************************************************************** * IMalloc32_Alloc [VTABLE] */ -static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface, DWORD cb) { - - LPVOID addr; +static void * WINAPI IMalloc_fnAlloc(IMalloc *iface, SIZE_T cb) +{ + void *addr; - TRACE("(%d)\n",cb); + TRACE("(%ld)\n",cb); if(Malloc32.pSpy) { - DWORD preAllocResult; + SIZE_T preAllocResult; EnterCriticalSection(&IMalloc32_SpyCS); preAllocResult = IMallocSpy_PreAlloc(Malloc32.pSpy, cb); @@ -198,14 +199,14 @@ /****************************************************************************** * IMalloc32_Realloc [VTABLE] */ -static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,DWORD cb) { - - LPVOID pNewMemory; +static void * WINAPI IMalloc_fnRealloc(IMalloc *iface, void *pv, SIZE_T cb) +{ + void *pNewMemory; - TRACE("(%p,%d)\n",pv,cb); + TRACE("(%p,%ld)\n",pv,cb); if(Malloc32.pSpy) { - LPVOID pRealMemory; + void *pRealMemory; BOOL fSpyed; EnterCriticalSection(&IMalloc32_SpyCS); @@ -250,8 +251,8 @@ /****************************************************************************** * IMalloc32_Free [VTABLE] */ -static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) { - +static void WINAPI IMalloc_fnFree(IMalloc *iface, void *pv) +{ BOOL fSpyed = FALSE; TRACE("(%p)\n",pv); @@ -286,9 +287,9 @@ * win95: size allocated (4 byte boundarys) * win2k: size originally requested !!! (allocated on 8 byte boundarys) */ -static DWORD WINAPI IMalloc_fnGetSize(LPMALLOC iface,LPVOID pv) { - - DWORD cb; +static SIZE_T WINAPI IMalloc_fnGetSize(IMalloc *iface, void *pv) +{ + SIZE_T cb; BOOL fSpyed = FALSE; TRACE("(%p)\n",pv); @@ -311,8 +312,8 @@ /****************************************************************************** * IMalloc32_DidAlloc [VTABLE] */ -static INT WINAPI IMalloc_fnDidAlloc(LPMALLOC iface,LPVOID pv) { - +static INT WINAPI IMalloc_fnDidAlloc(IMalloc *iface, void *pv) +{ BOOL fSpyed = FALSE; int didAlloc; @@ -335,7 +336,8 @@ /****************************************************************************** * IMalloc32_HeapMinimize [VTABLE] */ -static VOID WINAPI IMalloc_fnHeapMinimize(LPMALLOC iface) { +static void WINAPI IMalloc_fnHeapMinimize(IMalloc *iface) +{ TRACE("()\n"); if(Malloc32.pSpy) { @@ -398,7 +400,7 @@ * Success: Pointer to newly allocated memory block. * Failure: NULL. */ -LPVOID WINAPI CoTaskMemAlloc(ULONG size) +LPVOID WINAPI CoTaskMemAlloc(SIZE_T size) { return IMalloc_Alloc(&Malloc32.IMalloc_iface,size); } @@ -432,7 +434,7 @@ * Success: Pointer to newly allocated memory block. * Failure: NULL. */ -LPVOID WINAPI CoTaskMemRealloc(LPVOID pvOld, ULONG size) +LPVOID WINAPI CoTaskMemRealloc(LPVOID pvOld, SIZE_T size) { return IMalloc_Realloc(&Malloc32.IMalloc_iface, pvOld, size); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/ole2.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/ole2.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/ole2.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/ole2.c 2016-02-08 19:32:34.000000000 +0000 @@ -120,11 +120,6 @@ static const WCHAR prop_marshalleddroptarget[] = {'W','i','n','e','M','a','r','s','h','a','l','l','e','d','D','r','o','p','T','a','r','g','e','t',0}; -static const WCHAR clsidfmtW[] = - {'C','L','S','I','D','\\','{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-', - '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x', - '%','0','2','x','%','0','2','x','}','\\',0}; - static const WCHAR emptyW[] = { 0 }; /****************************************************************************** @@ -191,6 +186,8 @@ if (!COM_CurrentInfo()->ole_inits) hr = S_OK; + else + hr = S_FALSE; /* * Then, it has to initialize the OLE specific modules. @@ -234,6 +231,11 @@ { TRACE("()\n"); + if (COM_CurrentInfo()->ole_inits == 0) + { + WARN("ole_inits is already 0\n"); + return ; + } /* * If we hit the bottom of the lock stack, free the libraries. */ @@ -666,69 +668,73 @@ /*********************************************************************** * OleRegGetUserType (OLE32.@) - * - * This implementation of OleRegGetUserType ignores the dwFormOfType - * parameter and always returns the full name of the object. This is - * not too bad since this is the case for many objects because of the - * way they are registered. - */ -HRESULT WINAPI OleRegGetUserType( - REFCLSID clsid, - DWORD dwFormOfType, - LPOLESTR* pszUserType) -{ - DWORD dwKeyType; - DWORD cbData; - HKEY clsidKey; + */ +HRESULT WINAPI OleRegGetUserType(REFCLSID clsid, DWORD form, LPOLESTR *usertype) +{ + static const WCHAR auxusertypeW[] = {'A','u','x','U','s','e','r','T','y','p','e','\\','%','d',0}; + DWORD valuetype, valuelen; + WCHAR auxkeynameW[16]; + HKEY usertypekey; HRESULT hres; LONG ret; - TRACE("(%s, %d, %p)\n", debugstr_guid(clsid), dwFormOfType, pszUserType); + TRACE("(%s, %u, %p)\n", debugstr_guid(clsid), form, usertype); - if (!pszUserType) + if (!usertype) return E_INVALIDARG; - *pszUserType = NULL; + *usertype = NULL; - hres = COM_OpenKeyForCLSID(clsid, NULL, KEY_READ, &clsidKey); + /* Return immediately if it's not registered. */ + hres = COM_OpenKeyForCLSID(clsid, NULL, KEY_READ, &usertypekey); if (FAILED(hres)) return hres; - /* - * Retrieve the size of the name string. - */ - cbData = 0; + valuelen = 0; - if (RegQueryValueExW(clsidKey, emptyW, NULL, &dwKeyType, NULL, &cbData)) + /* Try additional types if requested. If they don't exist fall back to USERCLASSTYPE_FULL. */ + if (form != USERCLASSTYPE_FULL) { - RegCloseKey(clsidKey); - return REGDB_E_READREGDB; + HKEY auxkey; + + sprintfW(auxkeynameW, auxusertypeW, form); + if (COM_OpenKeyForCLSID(clsid, auxkeynameW, KEY_READ, &auxkey) == S_OK) + { + if (!RegQueryValueExW(auxkey, emptyW, NULL, &valuetype, NULL, &valuelen) && valuelen) + { + RegCloseKey(usertypekey); + usertypekey = auxkey; + } + else + RegCloseKey(auxkey); + } } - /* - * Allocate a buffer for the registry value. - */ - *pszUserType = CoTaskMemAlloc(cbData); + valuelen = 0; + if (RegQueryValueExW(usertypekey, emptyW, NULL, &valuetype, NULL, &valuelen)) + { + RegCloseKey(usertypekey); + return REGDB_E_READREGDB; + } - if (*pszUserType==NULL) + *usertype = CoTaskMemAlloc(valuelen); + if (!*usertype) { - RegCloseKey(clsidKey); + RegCloseKey(usertypekey); return E_OUTOFMEMORY; } - ret = RegQueryValueExW(clsidKey, + ret = RegQueryValueExW(usertypekey, emptyW, NULL, - &dwKeyType, - (LPBYTE) *pszUserType, - &cbData); - - RegCloseKey(clsidKey); - + &valuetype, + (LPBYTE)*usertype, + &valuelen); + RegCloseKey(usertypekey); if (ret != ERROR_SUCCESS) { - CoTaskMemFree(*pszUserType); - *pszUserType = NULL; + CoTaskMemFree(*usertype); + *usertype = NULL; return REGDB_E_READREGDB; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/tests/clipboard.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/tests/clipboard.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/tests/clipboard.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/tests/clipboard.c 2016-02-08 19:32:34.000000000 +0000 @@ -455,6 +455,17 @@ return S_OK; } +static void test_get_clipboard_unitialized(void) +{ + HRESULT hr; + IDataObject *pDObj; + + pDObj = (IDataObject *)0xdeadbeef; + hr = OleGetClipboard(&pDObj); + todo_wine ok(hr == S_OK, "OleGetClipboard() got 0x%08x instead of 0x%08x\n", hr, S_OK); + if (pDObj && pDObj != (IDataObject *)0xdeadbeef) IDataObject_Release(pDObj); +} + static void test_get_clipboard(void) { HRESULT hr; @@ -1539,11 +1550,65 @@ } +static DWORD CALLBACK test_data_obj(void *arg) +{ + IDataObject *data_obj = arg; + + IDataObject_Release(data_obj); + return 0; +} + +static void test_multithreaded_clipboard(void) +{ + IDataObject *data_obj; + HANDLE thread; + HRESULT hr; + DWORD ret; + + OleInitialize(NULL); + + hr = OleGetClipboard(&data_obj); + ok(hr == S_OK, "OleGetClipboard returned %x\n", hr); + + thread = CreateThread(NULL, 0, test_data_obj, data_obj, 0, NULL); + ok(thread != NULL, "CreateThread failed (%d)\n", GetLastError()); + ret = WaitForSingleObject(thread, 5000); + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", ret); + + hr = OleGetClipboard(&data_obj); + ok(hr == S_OK, "OleGetClipboard returned %x\n", hr); + IDataObject_Release(data_obj); + + OleUninitialize(); +} + +static void test_get_clipboard_locked(void) +{ + HRESULT hr; + IDataObject *pDObj; + + OleInitialize(NULL); + + pDObj = (IDataObject *)0xdeadbeef; + /* lock clipboard */ + OpenClipboard(NULL); + hr = OleGetClipboard(&pDObj); + todo_wine ok(hr == CLIPBRD_E_CANT_OPEN, "OleGetClipboard() got 0x%08x instead of 0x%08x\n", hr, CLIPBRD_E_CANT_OPEN); + todo_wine ok(pDObj == NULL, "OleGetClipboard() got 0x%p instead of NULL\n",pDObj); + if (pDObj) IDataObject_Release(pDObj); + CloseClipboard(); + + OleUninitialize(); +} + START_TEST(clipboard) { + test_get_clipboard_unitialized(); test_set_clipboard(); test_consumer_refs(); test_flushed_getdata(); test_nonole_clipboard(); test_getdatahere(); + test_multithreaded_clipboard(); + test_get_clipboard_locked(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/tests/compobj.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/tests/compobj.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/tests/compobj.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/tests/compobj.c 2016-02-08 19:32:34.000000000 +0000 @@ -2181,6 +2181,73 @@ OleUninitialize(); } +static void test_OleInitialize_InitCounting(void) +{ + HRESULT hr; + IUnknown *pUnk; + REFCLSID rclsid = &CLSID_InternetZoneManager; + + /* 1. OleInitialize fails but OleUnintialize is still called: apartment stays inited */ + hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED); + ok(hr == S_OK, "CoInitializeEx(COINIT_MULTITHREADED) failed with error 0x%08x\n", hr); + + hr = OleInitialize(NULL); + ok(hr == RPC_E_CHANGED_MODE, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", RPC_E_CHANGED_MODE, hr); + OleUninitialize(); + + pUnk = (IUnknown *)0xdeadbeef; + hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk); + ok(hr == S_OK, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK, hr); + if (pUnk) IUnknown_Release(pUnk); + + CoUninitialize(); + + /* 2. Extra multiple OleUninitialize: apartment stays inited until CoUnitialize */ + hr = CoInitialize(NULL); + ok(hr == S_OK, "CoInitialize() failed with error 0x%08x\n", hr); + + hr = OleInitialize(NULL); + ok(hr == S_OK, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK, hr); + OleUninitialize(); + OleUninitialize(); + OleUninitialize(); + + pUnk = (IUnknown *)0xdeadbeef; + hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk); + ok(hr == S_OK, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK, hr); + if (pUnk) IUnknown_Release(pUnk); + + CoUninitialize(); + + pUnk = (IUnknown *)0xdeadbeef; + hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk); + ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED, hr); + if (pUnk) IUnknown_Release(pUnk); + + /* 3. CoUninitialize does not formally deinit Ole */ + hr = CoInitialize(NULL); + ok(hr == S_OK, "CoInitialize() failed with error 0x%08x\n", hr); + + hr = OleInitialize(NULL); + ok(hr == S_OK, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK, hr); + + CoUninitialize(); + CoUninitialize(); + + pUnk = (IUnknown *)0xdeadbeef; + hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk); + ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED, hr); + /* COM is not initialized anymore */ + if (pUnk) IUnknown_Release(pUnk); + + hr = OleInitialize(NULL); + ok(hr == S_FALSE, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_FALSE, hr); + /* ... but native OleInit returns S_FALSE as if Ole is considered initialized */ + + OleUninitialize(); + +} + static void test_OleRegGetMiscStatus(void) { ULONG_PTR cookie; @@ -2229,11 +2296,29 @@ { static const WCHAR stdfont_usertypeW[] = {'S','t','a','n','d','a','r','d',' ','F','o','n','t',0}; static const WCHAR stdfont2_usertypeW[] = {'C','L','S','I','D','_','S','t','d','F','o','n','t',0}; + static const WCHAR clsidkeyW[] = {'C','L','S','I','D',0}; + static const WCHAR defvalueW[] = {'D','e','f','a','u','l','t',' ','N','a','m','e',0}; + static const WCHAR auxvalue0W[] = {'A','u','x',' ','N','a','m','e',' ','0',0}; + static const WCHAR auxvalue2W[] = {'A','u','x',' ','N','a','m','e',' ','2',0}; + static const WCHAR auxvalue3W[] = {'A','u','x',' ','N','a','m','e',' ','3',0}; + static const WCHAR auxvalue4W[] = {'A','u','x',' ','N','a','m','e',' ','4',0}; + + static const char auxvalues[][16] = { + "Aux Name 0", + "Aux Name 1", + "Aux Name 2", + "Aux Name 3", + "Aux Name 4" + }; + + HKEY clsidhkey, hkey, auxhkey, classkey; + DWORD form, ret, disposition; + WCHAR clsidW[39]; ULONG_PTR cookie; HANDLE handle; HRESULT hr; WCHAR *str; - DWORD form; + int i; for (form = 0; form <= USERCLASSTYPE_APPNAME+1; form++) { hr = OleRegGetUserType(&CLSID_Testclass, form, NULL); @@ -2273,7 +2358,93 @@ pDeactivateActCtx(0, cookie); pReleaseActCtx(handle); } + + /* test using registered CLSID */ + StringFromGUID2(&CLSID_non_existent, clsidW, sizeof(clsidW)/sizeof(clsidW[0])); + + ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsidkeyW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &clsidhkey, &disposition); + if (ret == ERROR_ACCESS_DENIED) + { + skip("Failed to create test key, skipping some of OleRegGetUserType() tests.\n"); + return; + } + + ok(!ret, "failed to create a key %d, error %d\n", ret, GetLastError()); + + ret = RegCreateKeyExW(clsidhkey, clsidW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &classkey, NULL); + ok(!ret, "failed to create a key %d, error %d\n", ret, GetLastError()); + + ret = RegSetValueExW(classkey, NULL, 0, REG_SZ, (const BYTE*)defvalueW, sizeof(defvalueW)); + ok(!ret, "got %d, error %d\n", ret, GetLastError()); + + ret = RegCreateKeyExA(classkey, "AuxUserType", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &auxhkey, NULL); + ok(!ret, "got %d, error %d\n", ret, GetLastError()); + + /* populate AuxUserType */ + for (i = 0; i <= 4; i++) { + char name[16]; + + sprintf(name, "AuxUserType\\%d", i); + ret = RegCreateKeyExA(classkey, name, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL); + ok(!ret, "got %d, error %d\n", ret, GetLastError()); + + ret = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE*)auxvalues[i], strlen(auxvalues[i])); + ok(!ret, "got %d, error %d\n", ret, GetLastError()); + RegCloseKey(hkey); + } + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, 0, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, auxvalue0W), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_FULL, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, defvalueW), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_SHORT, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, auxvalue2W), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, auxvalue3W), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME+1, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, auxvalue4W), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME+2, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, defvalueW), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + /* registry cleanup */ + for (i = 0; i <= 4; i++) + { + char name[2]; + sprintf(name, "%d", i); + RegDeleteKeyA(auxhkey, name); + } + RegCloseKey(auxhkey); + RegDeleteKeyA(classkey, "AuxUserType"); + RegCloseKey(classkey); + RegDeleteKeyW(clsidhkey, clsidW); + RegCloseKey(clsidhkey); + if (disposition == REG_CREATED_NEW_KEY) + RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID"); } + static void test_CoCreateGuid(void) { HRESULT hr; @@ -2767,6 +2938,7 @@ test_CoGetContextToken(); test_TreatAsClass(); test_CoInitializeEx(); + test_OleInitialize_InitCounting(); test_OleRegGetMiscStatus(); test_CoCreateGuid(); test_CoWaitForMultipleHandles(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/tests/storage32.c wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/tests/storage32.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ole32/tests/storage32.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ole32/tests/storage32.c 2016-02-08 19:32:34.000000000 +0000 @@ -1176,7 +1176,7 @@ { IStorage *stg = NULL; HRESULT r; - CLSID temp_cls; + CLSID temp_cls, cls2; DeleteFileA(filenameA); @@ -1188,6 +1188,12 @@ r = ReadClassStg( NULL, NULL ); ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r); + memset(&temp_cls, 0xcc, sizeof(temp_cls)); + memset(&cls2, 0xcc, sizeof(cls2)); + r = ReadClassStg( NULL, &temp_cls ); + ok(r == E_INVALIDARG, "got 0x%08x\n", r); + ok(IsEqualCLSID(&temp_cls, &cls2), "got wrong clsid\n"); + r = ReadClassStg( stg, NULL ); ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r); @@ -1957,7 +1963,7 @@ static void test_ReadClassStm(void) { - CLSID clsid; + CLSID clsid, clsid2; HRESULT hr; IStream *pStream; static const LARGE_INTEGER llZero; @@ -1973,6 +1979,12 @@ hr = ReadClassStm(pStream, NULL); ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr); + memset(&clsid, 0xcc, sizeof(clsid)); + memset(&clsid2, 0xcc, sizeof(clsid2)); + hr = ReadClassStm(NULL, &clsid); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(IsEqualCLSID(&clsid, &clsid2), "got wrong clsid\n"); + /* test not rewound stream */ hr = ReadClassStm(pStream, &clsid); ok(hr == STG_E_READFAULT, "ReadClassStm should have returned STG_E_READFAULT instead of 0x%08x\n", hr); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/oleaut.c wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/oleaut.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/oleaut.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/oleaut.c 2016-02-08 19:32:34.000000000 +0000 @@ -84,6 +84,9 @@ static CRITICAL_SECTION cs_bstr_cache = { &cs_bstr_cache_dbg, -1, 0, 0, 0, 0 }; typedef struct { +#ifdef _WIN64 + DWORD pad; +#endif DWORD size; union { char ptr[1]; @@ -117,24 +120,37 @@ return CONTAINING_RECORD(str, bstr_t, u.str); } -static inline bstr_cache_entry_t *get_cache_entry(size_t size) +static inline bstr_cache_entry_t *get_cache_entry_from_idx(unsigned cache_idx) { - unsigned cache_idx = FIELD_OFFSET(bstr_t, u.ptr[size-1])/BUCKET_SIZE; return bstr_cache_enabled && cache_idx < sizeof(bstr_cache)/sizeof(*bstr_cache) ? bstr_cache + cache_idx : NULL; } +static inline bstr_cache_entry_t *get_cache_entry(size_t size) +{ + unsigned cache_idx = FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)-1])/BUCKET_SIZE; + return get_cache_entry_from_idx(cache_idx); +} + +static inline bstr_cache_entry_t *get_cache_entry_from_alloc_size(SIZE_T alloc_size) +{ + unsigned cache_idx; + if (alloc_size < BUCKET_SIZE) return NULL; + cache_idx = (alloc_size - BUCKET_SIZE) / BUCKET_SIZE; + return get_cache_entry_from_idx(cache_idx); +} + static bstr_t *alloc_bstr(size_t size) { - bstr_cache_entry_t *cache_entry = get_cache_entry(size+sizeof(WCHAR)); + bstr_cache_entry_t *cache_entry = get_cache_entry(size); bstr_t *ret; if(cache_entry) { EnterCriticalSection(&cs_bstr_cache); if(!cache_entry->cnt) { - cache_entry = get_cache_entry(size+sizeof(WCHAR)+BUCKET_SIZE); + cache_entry = get_cache_entry(size+BUCKET_SIZE); if(cache_entry && !cache_entry->cnt) cache_entry = NULL; } @@ -149,19 +165,16 @@ if(cache_entry) { if(WARN_ON(heap)) { - size_t tail; - - memset(ret, ARENA_INUSE_FILLER, FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)])); - tail = bstr_alloc_size(size) - FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)]); - if(tail) - memset(ret->u.ptr+size+sizeof(WCHAR), ARENA_TAIL_FILLER, tail); + size_t fill_size = (FIELD_OFFSET(bstr_t, u.ptr[size])+2*sizeof(WCHAR)-1) & ~(sizeof(WCHAR)-1); + memset(ret, ARENA_INUSE_FILLER, fill_size); + memset((char *)ret+fill_size, ARENA_TAIL_FILLER, bstr_alloc_size(size)-fill_size); } ret->size = size; return ret; } } - ret = HeapAlloc(GetProcessHeap(), 0, bstr_alloc_size(size)); + ret = CoTaskMemAlloc(bstr_alloc_size(size)); if(ret) ret->size = size; return ret; @@ -234,6 +247,16 @@ return SysAllocStringLen(str, lstrlenW(str)); } +static inline IMalloc *get_malloc(void) +{ + static IMalloc *malloc; + + if (!malloc) + CoGetMalloc(1, &malloc); + + return malloc; +} + /****************************************************************************** * SysFreeString [OLEAUT32.6] * @@ -253,12 +276,19 @@ { bstr_cache_entry_t *cache_entry; bstr_t *bstr; + IMalloc *malloc = get_malloc(); + SIZE_T alloc_size; if(!str) return; bstr = bstr_from_str(str); - cache_entry = get_cache_entry(bstr->size+sizeof(WCHAR)); + + alloc_size = IMalloc_GetSize(malloc, bstr); + if (alloc_size == ~0UL) + return; + + cache_entry = get_cache_entry_from_alloc_size(alloc_size); if(cache_entry) { unsigned i; @@ -279,8 +309,7 @@ cache_entry->cnt++; if(WARN_ON(heap)) { - unsigned n = bstr_alloc_size(bstr->size) / sizeof(DWORD) - 1; - bstr->size = ARENA_FREE_FILLER; + unsigned n = (alloc_size-FIELD_OFFSET(bstr_t, u.ptr))/sizeof(DWORD); for(i=0; iu.dwptr[i] = ARENA_FREE_FILLER; } @@ -292,7 +321,7 @@ LeaveCriticalSection(&cs_bstr_cache); } - HeapFree(GetProcessHeap(), 0, bstr); + CoTaskMemFree(bstr); } /****************************************************************************** @@ -359,29 +388,25 @@ { /* Detect integer overflow. */ if (len >= ((UINT_MAX-sizeof(WCHAR)-sizeof(DWORD))/sizeof(WCHAR))) - return 0; + return FALSE; if (*old!=NULL) { - BSTR old_copy = *old; DWORD newbytelen = len*sizeof(WCHAR); - bstr_t *bstr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,bstr_alloc_size(newbytelen)); + bstr_t *old_bstr = bstr_from_str(*old); + bstr_t *bstr = CoTaskMemRealloc(old_bstr, bstr_alloc_size(newbytelen)); + + if (!bstr) return FALSE; + *old = bstr->u.str; bstr->size = newbytelen; - /* Subtle hidden feature: The old string data is still there - * when 'in' is NULL! - * Some Microsoft program needs it. - * FIXME: Is it a sideeffect of BSTR caching? - */ - if (str && old_copy!=str) memmove(*old, str, newbytelen); - (*old)[len] = 0; + /* The old string data is still there when str is NULL */ + if (str && old_bstr->u.str != str) memmove(bstr->u.str, str, newbytelen); + bstr->u.str[len] = 0; } else { - /* - * Allocate the new string - */ *old = SysAllocStringLen(str, len); } - return 1; + return TRUE; } /****************************************************************************** @@ -418,10 +443,11 @@ if(str) { memcpy(bstr->u.ptr, str, len); - bstr->u.ptr[len] = bstr->u.ptr[len+1] = 0; + bstr->u.ptr[len] = 0; }else { - memset(bstr->u.ptr, 0, len+sizeof(WCHAR)); + memset(bstr->u.ptr, 0, len+1); } + bstr->u.str[(len+sizeof(WCHAR)-1)/sizeof(WCHAR)] = 0; return bstr->u.str; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/tests/test_reg.idl wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/tests/test_reg.idl --- wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/tests/test_reg.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/tests/test_reg.idl 2016-02-08 19:32:34.000000000 +0000 @@ -141,6 +141,8 @@ LONG testprop([in] LONG *i); [propputref, id(2)] LONG testprop2([in] IUnknown *i); + [id(3)] + HRESULT testfunc([in] int i, [out, retval] int *p); } /* uuid is same as for test_struct2 in test_tlb.idl, fields are different */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/tests/typelib.c wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/tests/typelib.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/tests/typelib.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/tests/typelib.c 2016-02-08 19:32:34.000000000 +0000 @@ -37,6 +37,7 @@ #include "ocidl.h" #include "shlwapi.h" #include "tmarshal.h" +#include "olectl.h" #include "test_reg.h" #include "test_tlb.h" @@ -156,6 +157,12 @@ return 6; } +static HRESULT WINAPI invoketest_testfunc(IInvokeTest *iface, int i, int *p) +{ + *p = i+1; + return S_OK; +} + static const IInvokeTestVtbl invoketestvtbl = { invoketest_QueryInterface, invoketest_AddRef, @@ -166,7 +173,8 @@ invoketest_Invoke, invoketest_get_test, invoketest_putref_testprop, - invoketest_putref_testprop2 + invoketest_putref_testprop2, + invoketest_testfunc }; static IInvokeTest invoketest = { &invoketestvtbl }; @@ -667,6 +675,33 @@ CloseHandle( file ); } +static void test_invoke_func(ITypeInfo *typeinfo) +{ + DISPID named_args[3] = { DISPID_THIS }; + VARIANT args[3], res; + DISPPARAMS dp = {args, named_args, 1, 0}; + UINT i; + HRESULT hres; + + V_VT(args) = VT_INT; + V_INT(args) = 3; + V_VT(&res) = VT_ERROR; + hres = ITypeInfo_Invoke(typeinfo, &invoketest, 3, DISPATCH_METHOD, &dp, &res, NULL, &i); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(V_VT(&res) == VT_I4, "got %d\n", V_VT(&res)); + ok(V_I4(&res) == 4, "got %d\n", V_I4(&res)); + + V_VT(args) = VT_DISPATCH; + V_DISPATCH(args) = (IDispatch*)&invoketest; + V_VT(args+1) = VT_INT; + V_INT(args+1) = 3; + V_VT(&res) = VT_ERROR; + dp.cNamedArgs = 1; + dp.cArgs = 2; + hres = ITypeInfo_Invoke(typeinfo, &invoketest, 3, DISPATCH_METHOD, &dp, &res, NULL, &i); + ok(hres == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hres); +} + static const char *create_test_typelib(int res_no) { static char filename[MAX_PATH]; @@ -959,6 +994,8 @@ hr = ITypeInfo_Invoke(pTypeInfo, &invoketest, 2, DISPATCH_PROPERTYPUT, &dispparams, &res, NULL, &i); ok(hr == DISP_E_MEMBERNOTFOUND, "got 0x%08x, %d\n", hr, i); + test_invoke_func(pTypeInfo); + ITypeInfo_Release(pTypeInfo); ITypeLib_Release(pTypeLib); DeleteFileA(filenameA); @@ -1619,7 +1656,6 @@ static OLECHAR dualW[] = {'d','u','a','l',0}; static OLECHAR coclassW[] = {'c','o','c','l','a','s','s',0}; static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0x3213,0}; - static const WCHAR defaultQW[] = {'d','e','f','a','u','l','t','?',0}; static OLECHAR func1W[] = {'f','u','n','c','1',0}; static OLECHAR func2W[] = {'f','u','n','c','2',0}; static OLECHAR prop1W[] = {'P','r','o','p','1',0}; @@ -1631,6 +1667,7 @@ static OLECHAR *names1[] = {func1W, param1W, param2W}; static OLECHAR *names2[] = {func2W, param1W, param2W}; static OLECHAR *propname[] = {prop1W, param1W}; + static const GUID tlcustguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x69}}; static const GUID custguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x70}}; static const GUID bogusguid = {0xbf611abe,0x5b38,0x11df,{0x91,0x5c,0x08,0x02,0x79,0x79,0x94,0x71}}; static const GUID interfaceguid = {0x3b9ff02f,0x9675,0x4861,{0xb7,0x81,0xce,0xae,0xa4,0x78,0x2a,0xcc}}; @@ -1642,6 +1679,7 @@ ICreateTypeInfo *createti; ICreateTypeInfo2 *createti2; ITypeLib *tl, *stdole; + ITypeLib2 *tl2; ITypeInfo *interface1, *interface2, *dual, *unknown, *dispatch, *ti; ITypeInfo *tinfos[2]; ITypeInfo2 *ti2; @@ -1664,6 +1702,8 @@ TYPEKIND kind; DESCKIND desckind; BINDPTR bindptr; + char nameA[16]; + WCHAR nameW[16]; switch(sys){ case SYS_WIN32: @@ -1758,6 +1798,23 @@ SysFreeString(name); SysFreeString(helpfile); + V_VT(&cust_data) = VT_I4; + V_I4(&cust_data) = 1; + hres = ICreateTypeLib2_SetCustData(createtl, &tlcustguid, &cust_data); + ok(hres == S_OK, "got %08x\n", hres); + + hres = ITypeLib_QueryInterface(tl, &IID_ITypeLib2, (void**)&tl2); + ok(hres == S_OK, "no ITypeLib2 interface (%x)\n", hres); + + V_VT(&cust_data) = VT_EMPTY; + V_I4(&cust_data) = 0; + hres = ITypeLib2_GetCustData(tl2, &tlcustguid, &cust_data); + ok(hres == S_OK, "got %08x\n", hres); + ok(V_VT(&cust_data) == VT_I4, "V_VT(&cust_data) = %d\n", V_VT(&cust_data)); + ok(V_I4(&cust_data) == 1, "V_I4(&cust_data) = %d\n", V_I4(&cust_data)); + + ITypeLib2_Release(tl2); + /* invalid parameters */ hres = ICreateTypeLib2_CreateTypeInfo(createtl, NULL, TKIND_INTERFACE, &createti); ok(hres == E_INVALIDARG, "got %08x\n", hres); @@ -2160,6 +2217,9 @@ ok(hres == S_OK, "got %08x\n", hres); SysFreeString(V_BSTR(¶mdescex.varDefaultValue)); + WideCharToMultiByte(CP_ACP, 0, defaultW, -1, nameA, sizeof(nameA), NULL, NULL); + MultiByteToWideChar(CP_ACP, 0, nameA, -1, nameW, sizeof(nameW)/sizeof(nameW[0])); + hres = ITypeInfo2_GetFuncDesc(ti2, 3, &pfuncdesc); ok(hres == S_OK, "got %08x\n", hres); @@ -2185,7 +2245,7 @@ U(*edesc).paramdesc.pparamdescex->cBytes); ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n", V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)); - ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW), + ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), nameW), "got: %s\n", wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue))); @@ -2197,7 +2257,7 @@ U(*edesc).paramdesc.pparamdescex->cBytes); ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n", V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)); - ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW), + ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), nameW), "got: %s\n", wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue))); @@ -2819,6 +2879,16 @@ SysFreeString(name); SysFreeString(helpfile); + hres = ITypeLib_QueryInterface(tl, &IID_ITypeLib2, (void**)&tl2); + ok(hres == S_OK, "no ITypeLib2 interface (%x)\n", hres); + V_VT(&cust_data) = VT_EMPTY; + V_I4(&cust_data) = 0; + hres = ITypeLib2_GetCustData(tl2, &tlcustguid, &cust_data); + ok(hres == S_OK, "got %08x\n", hres); + ok(V_VT(&cust_data) == VT_I4, "V_VT(&cust_data) = %d\n", V_VT(&cust_data)); + ok(V_I4(&cust_data) == 1, "V_I4(&cust_data) = %d\n", V_I4(&cust_data)); + ITypeLib2_Release(tl2); + hres = ITypeLib_GetTypeInfo(tl, 0, &ti); ok(hres == S_OK, "got %08x\n", hres); @@ -2983,7 +3053,7 @@ U(*edesc).paramdesc.pparamdescex->cBytes); ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n", V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)); - ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW), + ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), nameW), "got: %s\n", wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue))); @@ -2995,7 +3065,7 @@ U(*edesc).paramdesc.pparamdescex->cBytes); ok(V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue) == VT_BSTR, "got: %d\n", V_VT(&U(*edesc).paramdesc.pparamdescex->varDefaultValue)); - ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), defaultQW), + ok(!lstrcmpW(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue), nameW), "got: %s\n", wine_dbgstr_w(V_BSTR(&U(*edesc).paramdesc.pparamdescex->varDefaultValue))); @@ -5589,6 +5659,11 @@ ok(hr == TYPE_E_LIBNOTREGISTERED || broken(hr == S_OK) /* winxp */, "got 0x%08x\n", hr); SysFreeString(path); + path = NULL; + hr = QueryPathOfRegTypeLib(&LIBID_TestTypelib, 0xffff, 0xffff, LOCALE_NEUTRAL, &path); + ok(hr == S_OK, "got 0x%08x\n", hr); + SysFreeString(path); + /* manifest version is 2.0, actual is 1.0 */ hr = LoadRegTypeLib(&LIBID_register_test, 1, 0, LOCALE_NEUTRAL, &tl); ok(hr == TYPE_E_LIBNOTREGISTERED || broken(hr == S_OK) /* winxp */, "got 0x%08x\n", hr); @@ -5634,6 +5709,20 @@ hr = LoadRegTypeLib(&LIBID_TestTypelib, 1, 7, LOCALE_NEUTRAL, &tl); ok(hr == TYPE_E_LIBNOTREGISTERED, "got 0x%08x\n", hr); + hr = LoadRegTypeLib(&LIBID_TestTypelib, 0xffff, 0xffff, LOCALE_NEUTRAL, &tl); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITypeLib_GetLibAttr(tl, &attr); + ok(hr == S_OK, "got 0x%08x\n", hr); + + ok(attr->lcid == 0, "got %x\n", attr->lcid); + ok(attr->wMajorVerNum == 2, "got %d\n", attr->wMajorVerNum); + ok(attr->wMinorVerNum == 5, "got %d\n", attr->wMinorVerNum); + ok(attr->wLibFlags == LIBFLAG_FHASDISKIMAGE, "got %x\n", attr->wLibFlags); + + ITypeLib_ReleaseTLibAttr(tl, attr); + ITypeLib_Release(tl); + DeleteFileA("test_actctx_tlb.tlb"); DeleteFileA("test_actctx_tlb2.tlb"); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/tests/usrmarshal.c wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/tests/usrmarshal.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/tests/usrmarshal.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/tests/usrmarshal.c 2016-02-08 19:32:34.000000000 +0000 @@ -277,6 +277,7 @@ ok(lpsa2->cLocks == 0, "got lock count %u, expected 0\n", lpsa2->cLocks); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE); LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2); + ok(!lpsa2, "lpsa2 was not set to 0 by LPSAFEARRAY_UserFree\n"); HeapFree(GetProcessHeap(), 0, buffer); lpsa->cLocks = 0; hr = SafeArrayDestroy(lpsa); @@ -766,10 +767,10 @@ double d; void *mem; DWORD *wirev; - BSTR b; + BSTR b, b2; WCHAR str[] = {'m','a','r','s','h','a','l',' ','t','e','s','t',0}; SAFEARRAYBOUND sab; - LPSAFEARRAY lpsa; + LPSAFEARRAY lpsa, lpsa2, lpsa_copy; DECIMAL dec, dec2; HeapUnknown *heap_unknown; DWORD expected; @@ -1236,15 +1237,21 @@ ok(*wirev, "wv[6] %08x\n", *wirev); /* win2k: this is b. winxp: this is (char*)b + 1 */ wirev++; check_bstr(wirev, b); + b2 = SysAllocString(str); + b2[0] = 0; + V_VT(&v2) = VT_BSTR | VT_BYREF; + V_BSTRREF(&v2) = &b2; + mem = b2; VariantInit(&v2); stubMsg.Buffer = buffer; next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2); ok(next == buffer + stubMsg.BufferLength, "got %p expect %p\n", next, buffer + stubMsg.BufferLength); + ok(mem == b2, "BSTR should be reused\n"); ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2)); ok(SysStringByteLen(*V_BSTRREF(&v)) == SysStringByteLen(*V_BSTRREF(&v2)), "bstr string lens differ\n"); ok(!memcmp(*V_BSTRREF(&v), *V_BSTRREF(&v2), SysStringByteLen(*V_BSTRREF(&v))), "bstrs differ\n"); - VARIANT_UserFree(&umcb.Flags, &v2); + SysFreeString(b2); HeapFree(GetProcessHeap(), 0, oldbuffer); SysFreeString(b); @@ -1336,6 +1343,59 @@ } VARIANT_UserFree(&umcb.Flags, &v2); HeapFree(GetProcessHeap(), 0, oldbuffer); + + /*** ARRAY BYREF ***/ + VariantInit(&v); + V_VT(&v) = VT_UI4 | VT_ARRAY | VT_BYREF; + V_ARRAYREF(&v) = &lpsa; + lpsa->fFeatures |= FADF_STATIC; + + rpcMsg.BufferLength = stubMsg.BufferLength = VARIANT_UserSize(&umcb.Flags, 0, &v); + expected = 152; + ok(stubMsg.BufferLength == expected || stubMsg.BufferLength == expected + 16, /* win64 */ + "size %u instead of %u\n", stubMsg.BufferLength, expected); + buffer = rpcMsg.Buffer = stubMsg.Buffer = stubMsg.BufferStart = alloc_aligned(stubMsg.BufferLength, &oldbuffer); + stubMsg.BufferEnd = stubMsg.Buffer + stubMsg.BufferLength; + next = VARIANT_UserMarshal(&umcb.Flags, buffer, &v); + ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected); + wirev = (DWORD*)buffer; + + wirev = check_variant_header(wirev, &v, expected); + ok(*wirev == 4, "wv[5] %08x\n", *wirev); + wirev++; + ok(*wirev, "wv[6] %08x\n", *wirev); /* win2k: this is lpsa. winxp: this is (char*)lpsa + 1 */ + wirev++; + check_safearray(wirev, lpsa); + lpsa_copy = lpsa2 = SafeArrayCreate(VT_I8, 1, &sab); + /* set FADF_STATIC feature to make sure lpsa2->pvData pointer changes if new data buffer is allocated */ + lpsa2->fFeatures |= FADF_STATIC; + mem = lpsa2->pvData; + V_VT(&v2) = VT_UI4 | VT_ARRAY | VT_BYREF; + V_ARRAYREF(&v2) = &lpsa2; + stubMsg.Buffer = buffer; + next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v2); + ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected); + ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2)); + ok(lpsa2 == lpsa_copy, "safearray should be reused\n"); + ok(mem == lpsa2->pvData, "safearray data should be reused\n"); + ok(SafeArrayGetDim(*V_ARRAYREF(&v)) == SafeArrayGetDim(*V_ARRAYREF(&v2)), "array dims differ\n"); + SafeArrayGetLBound(*V_ARRAYREF(&v), 1, &bound); + SafeArrayGetLBound(*V_ARRAYREF(&v2), 1, &bound2); + ok(bound == bound2, "array lbounds differ\n"); + SafeArrayGetUBound(*V_ARRAYREF(&v), 1, &bound); + SafeArrayGetUBound(*V_ARRAYREF(&v2), 1, &bound2); + ok(bound == bound2, "array ubounds differ\n"); + if (pSafeArrayGetVartype) + { + pSafeArrayGetVartype(*V_ARRAYREF(&v), &vt); + pSafeArrayGetVartype(*V_ARRAYREF(&v2), &vt2); + ok(vt == vt2, "array vts differ %x %x\n", vt, vt2); + } + lpsa2->fFeatures &= ~FADF_STATIC; + hr = SafeArrayDestroy(*V_ARRAYREF(&v2)); + ok(hr == S_OK, "got 0x%08x\n", hr); + HeapFree(GetProcessHeap(), 0, oldbuffer); + lpsa->fFeatures &= ~FADF_STATIC; hr = SafeArrayDestroy(lpsa); ok(hr == S_OK, "got 0x%08x\n", hr); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/tests/vartype.c wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/tests/vartype.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/tests/vartype.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/tests/vartype.c 2016-02-08 19:32:34.000000000 +0000 @@ -5398,9 +5398,12 @@ if (str) { LPINTERNAL_BSTR bstr = Get(str); + DWORD_PTR p = (DWORD_PTR)str; + int align = sizeof(void *); ok (bstr->dwLen == 8, "Expected 8, got %d\n", bstr->dwLen); ok (!lstrcmpW(bstr->szString, szTest), "String different\n"); + ok ((p & ~(align-1)) == p, "Not aligned to %d\n", align); SysFreeString(str); } } @@ -5444,7 +5447,9 @@ { const OLECHAR szTest[10] = { 'T','e','s','t','\0' }; const CHAR szTestA[6] = { 'T','e','s','t','\0','?' }; + char *buf; BSTR str; + int i; if (sizeof(void *) == 4) /* not limited to 0x80000000 on Win64 */ { @@ -5487,6 +5492,7 @@ ok (bstr->dwLen == 3, "Expected 3, got %d\n", bstr->dwLen); ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n"); + ok (!bstr->szString[2], "String not terminated\n"); SysFreeString(str); } @@ -5500,6 +5506,32 @@ ok (!lstrcmpW(bstr->szString, szTest), "String different\n"); SysFreeString(str); } + + /* Make sure terminating null is aligned properly */ + buf = HeapAlloc(GetProcessHeap(), 0, 1025); + ok (buf != NULL, "Expected non-NULL\n"); + for (i = 0; i < 1024; i++) + { + LPINTERNAL_BSTR bstr; + + str = SysAllocStringByteLen(NULL, i); + ok (str != NULL, "Expected non-NULL\n"); + bstr = Get(str); + ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen); + ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n"); + SysFreeString(str); + + memset(buf, 0xaa, 1025); + str = SysAllocStringByteLen(buf, i); + ok (str != NULL, "Expected non-NULL\n"); + bstr = Get(str); + ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen); + buf[i] = 0; + ok (!lstrcmpA((LPCSTR)bstr->szString, buf), "String different\n"); + ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n"); + SysFreeString(str); + } + HeapFree(GetProcessHeap(), 0, buf); } static void test_SysReAllocString(void) @@ -6337,9 +6369,15 @@ ok(str == str2, "str != str2\n"); SysFreeString(str2); - /* Fill the bucket with cached entries. */ + /* Fill the bucket with cached entries. + We roll our own, to show that the cache doesn't use + the bstr length field to determine bucket allocation. */ for(i=0; i < sizeof(strs)/sizeof(*strs); i++) - strs[i] = SysAllocStringLen(NULL, 24); + { + DWORD_PTR *ptr = CoTaskMemAlloc(64); + ptr[0] = 0; + strs[i] = (BSTR)(ptr + 1); + } for(i=0; i < sizeof(strs)/sizeof(*strs); i++) SysFreeString(strs[i]); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/typelib.c wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/typelib.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/typelib.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/typelib.c 2016-02-08 19:32:34.000000000 +0000 @@ -323,7 +323,7 @@ WCHAR *nameW; DWORD len; - if (tlib->major_version != wMaj || tlib->minor_version < wMin) + if ((wMaj != 0xffff || wMin != 0xffff) && (tlib->major_version != wMaj || tlib->minor_version < wMin)) return TYPE_E_LIBNOTREGISTERED; nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset); @@ -536,7 +536,7 @@ res= LoadTypeLib(bstr, ppTLib); SysFreeString(bstr); - if (*ppTLib) + if ((wVerMajor!=0xffff || wVerMinor!=0xffff) && *ppTLib) { TLIBATTR *attr; @@ -9280,7 +9280,7 @@ { WMSFT_SegContents *cdguids_seg = &file->cdguids_seg; DWORD ret = cdguids_seg->len, offs; - MSFT_CDGuid *cdguid = cdguids_seg->data; + MSFT_CDGuid *cdguid; TLBCustData *cd; if(list_empty(custdata_list)) @@ -9289,8 +9289,10 @@ cdguids_seg->len += sizeof(MSFT_CDGuid) * list_count(custdata_list); if(!cdguids_seg->data){ cdguid = cdguids_seg->data = heap_alloc(cdguids_seg->len); - }else + }else { cdguids_seg->data = heap_realloc(cdguids_seg->data, cdguids_seg->len); + cdguid = (MSFT_CDGuid*)((char*)cdguids_seg->data + ret); + } offs = ret + sizeof(MSFT_CDGuid); LIST_FOR_EACH_ENTRY(cd, custdata_list, TLBCustData, entry){ @@ -9982,7 +9984,7 @@ else file.header.NameOffset = -1; - file.header.CustomDataOffset = -1; /* TODO SetCustData not impl yet */ + file.header.CustomDataOffset = WMSFT_compile_custdata(&This->custdata_list, &file); if(This->guid) file.header.posguid = This->guid->offset; @@ -10132,8 +10134,16 @@ REFGUID guid, VARIANT *varVal) { ITypeLibImpl *This = impl_from_ICreateTypeLib2(iface); - FIXME("%p %s %p - stub\n", This, debugstr_guid(guid), varVal); - return E_NOTIMPL; + TLBGuid *tlbguid; + + TRACE("%p %s %p\n", This, debugstr_guid(guid), varVal); + + if (!guid || !varVal) + return E_INVALIDARG; + + tlbguid = TLB_append_guid(&This->guid_list, guid, -1); + + return TLB_set_custdata(&This->custdata_list, tlbguid, varVal); } static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 *iface, diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/usrmarshal.c wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/usrmarshal.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/oleaut32/usrmarshal.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/oleaut32/usrmarshal.c 2016-02-08 19:32:34.000000000 +0000 @@ -349,10 +349,6 @@ ptr = *(DWORD*)Buffer; Buffer += sizeof(DWORD); - /* Clear any existing interface which WdtpInterfacePointer_UserUnmarshal() - would try to release. This has been done already with a VariantClear(). */ - *ppunk = NULL; - if(!ptr) return Buffer; @@ -520,10 +516,22 @@ { VariantClear(pvar); V_BYREF(pvar) = CoTaskMemAlloc(mem_size); + memset(V_BYREF(pvar), 0, mem_size); } else if (!V_BYREF(pvar)) + { V_BYREF(pvar) = CoTaskMemAlloc(mem_size); - memcpy(V_BYREF(pvar), Pos, type_size); + memset(V_BYREF(pvar), 0, mem_size); + } + + if(!(header->vt & VT_ARRAY) + && (header->vt & VT_TYPEMASK) != VT_BSTR + && (header->vt & VT_TYPEMASK) != VT_VARIANT + && (header->vt & VT_TYPEMASK) != VT_UNKNOWN + && (header->vt & VT_TYPEMASK) != VT_DISPATCH + && (header->vt & VT_TYPEMASK) != VT_RECORD) + memcpy(V_BYREF(pvar), Pos, type_size); + if((header->vt & VT_TYPEMASK) != VT_VARIANT) Pos += type_size; else @@ -532,7 +540,17 @@ else { VariantClear(pvar); - if((header->vt & VT_TYPEMASK) == VT_DECIMAL) + if(header->vt & VT_ARRAY) + V_ARRAY(pvar) = NULL; + else if((header->vt & VT_TYPEMASK) == VT_BSTR) + V_BSTR(pvar) = NULL; + else if((header->vt & VT_TYPEMASK) == VT_UNKNOWN) + V_UNKNOWN(pvar) = NULL; + else if((header->vt & VT_TYPEMASK) == VT_DISPATCH) + V_DISPATCH(pvar) = NULL; + else if((header->vt & VT_TYPEMASK) == VT_RECORD) + V_RECORD(pvar) = NULL; + else if((header->vt & VT_TYPEMASK) == VT_DECIMAL) memcpy(pvar, Pos, type_size); else memcpy(&pvar->n1.n2.n3, Pos, type_size); @@ -556,11 +574,9 @@ switch (header->vt) { case VT_BSTR: - V_BSTR(pvar) = NULL; Pos = BSTR_UserUnmarshal(pFlags, Pos, &V_BSTR(pvar)); break; case VT_BSTR | VT_BYREF: - *V_BSTRREF(pvar) = NULL; Pos = BSTR_UserUnmarshal(pFlags, Pos, V_BSTRREF(pvar)); break; case VT_VARIANT | VT_BYREF: @@ -963,6 +979,7 @@ if (!ptr) { + SafeArrayDestroy(*ppsa); *ppsa = NULL; TRACE("NULL safe array unmarshaled\n"); @@ -999,13 +1016,34 @@ wiresab = (SAFEARRAYBOUND *)Buffer; Buffer += sizeof(wiresab[0]) * wiresa->cDims; - if(vt) + if(*ppsa && (*ppsa)->cDims==wiresa->cDims) + { + if(((*ppsa)->fFeatures & ~FADF_AUTOSETFLAGS) != (wiresa->fFeatures & ~FADF_AUTOSETFLAGS)) + RpcRaiseException(DISP_E_BADCALLEE); + + if(SAFEARRAY_GetCellCount(*ppsa)*(*ppsa)->cbElements != cell_count*elem_mem_size(wiresa, sftype)) + { + if((*ppsa)->fFeatures & (FADF_AUTO|FADF_STATIC|FADF_EMBEDDED|FADF_FIXEDSIZE)) + RpcRaiseException(DISP_E_BADCALLEE); + + hr = SafeArrayDestroyData(*ppsa); + if(FAILED(hr)) + RpcRaiseException(hr); + } + memcpy((*ppsa)->rgsabound, wiresab, sizeof(*wiresab)*wiresa->cDims); + + if((*ppsa)->fFeatures & FADF_HAVEVARTYPE) + ((DWORD*)(*ppsa))[-1] = vt; + } + else if(vt) { + SafeArrayDestroy(*ppsa); *ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL); if (!*ppsa) RpcRaiseException(E_OUTOFMEMORY); } else { + SafeArrayDestroy(*ppsa); if (FAILED(SafeArrayAllocDescriptor(wiresa->cDims, ppsa))) RpcRaiseException(E_OUTOFMEMORY); memcpy((*ppsa)->rgsabound, wiresab, sizeof(SAFEARRAYBOUND) * wiresa->cDims); @@ -1017,11 +1055,10 @@ (*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS)); /* FIXME: there should be a limit on how large wiresa->cbElements can be */ (*ppsa)->cbElements = elem_mem_size(wiresa, sftype); - (*ppsa)->cLocks = 0; /* SafeArrayCreateEx allocates the data for us, but * SafeArrayAllocDescriptor doesn't */ - if(!vt) + if(!(*ppsa)->pvData) { hr = SafeArrayAllocData(*ppsa); if (FAILED(hr)) @@ -1091,6 +1128,7 @@ TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n", *ppsa); SafeArrayDestroy(*ppsa); + *ppsa = NULL; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/olepro32/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/olepro32/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/olepro32/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/olepro32/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -4,4 +4,6 @@ C_SRCS = olepro32stubs.c +IDL_SRCS = olepro.idl + RC_SRCS = version.rc diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/olepro32/olepro.idl wine-staging-1.9.3~ubuntu12.04.1/dlls/olepro32/olepro.idl --- wine-staging-1.9.0~ubuntu12.04.1/dlls/olepro32/olepro.idl 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/olepro32/olepro.idl 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2003 Robert Shearman + * 2005 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#pragma makedep regtypelib + +import "oaidl.idl"; + +#include + +[ + uuid(bef6e001-a874-101a-8bba-00aa00300cab), + version(2.0), + helpstring("Standard OLE Types") +] +library StdType +{ + importlib("stdole2.tlb"); + + typedef [uuid(66504301-BE0F-101A-8BBB-00AA00300CAB), public] + unsigned long OLE_COLOR; + + typedef [uuid(66504302-BE0F-101A-8BBB-00AA00300CAB), public] + long OLE_XPOS_PIXELS; + + typedef [uuid(66504303-BE0F-101A-8BBB-00AA00300CAB), public] + long OLE_YPOS_PIXELS; + + typedef [uuid(66504304-BE0F-101A-8BBB-00AA00300CAB), public] + long OLE_XSIZE_PIXELS; + + typedef [uuid(66504305-BE0F-101A-8BBB-00AA00300CAB), public] + long OLE_YSIZE_PIXELS; + + typedef [uuid(66504306-BE0F-101A-8BBB-00AA00300CAB), public] + long OLE_XPOS_HIMETRIC; + + typedef [uuid(66504307-BE0F-101A-8BBB-00AA00300CAB), public] + long OLE_YPOS_HIMETRIC; + + typedef [uuid(66504308-BE0F-101A-8BBB-00AA00300CAB), public] + long OLE_XSIZE_HIMETRIC; + + typedef [uuid(66504309-BE0F-101A-8BBB-00AA00300CAB), public] + long OLE_YSIZE_HIMETRIC; + + typedef [uuid(BF030640-9069-101B-AE2D-08002B2EC713), public] + float OLE_XPOS_CONTAINER; + + typedef [uuid(BF030641-9069-101B-AE2D-08002B2EC713), public] + float OLE_YPOS_CONTAINER; + + typedef [uuid(BF030642-9069-101B-AE2D-08002B2EC713), public] + float OLE_XSIZE_CONTAINER; + + typedef [uuid(BF030643-9069-101B-AE2D-08002B2EC713), public] + float OLE_YSIZE_CONTAINER; + + typedef [uuid(66504313-BE0F-101A-8BBB-00AA00300CAB), public] + int OLE_HANDLE; + + typedef [uuid(6650430B-BE0F-101A-8BBB-00AA00300CAB), public] + VARIANT_BOOL OLE_OPTEXCLUSIVE; + + typedef [uuid(BF030644-9069-101B-AE2D-08002B2EC713), public] + VARIANT_BOOL OLE_CANCELBOOL; + + typedef [uuid(BF030645-9069-101B-AE2D-08002B2EC713), public] + VARIANT_BOOL OLE_ENABLEDEFAULTBOOL; + + [ + uuid(6650430A-BE0F-101A-8BBB-00AA00300CAB) + ] + enum OLE_TRISTATE { + Unchecked = 0, + Checked = 1, + Gray = 2 + }; + + typedef [uuid(6650430D-BE0F-101A-8BBB-00AA00300CAB), public] + BSTR FONTNAME; + + typedef [uuid(6650430E-BE0F-101A-8BBB-00AA00300CAB), public] + CURRENCY FONTSIZE; + + typedef [uuid(6650430F-BE0F-101A-8BBB-00AA00300CAB), public] + VARIANT_BOOL FONTBOLD; + + typedef [uuid(66504310-BE0F-101A-8BBB-00AA00300CAB), public] + VARIANT_BOOL FONTITALIC; + + typedef [uuid(66504311-BE0F-101A-8BBB-00AA00300CAB), public] + VARIANT_BOOL FONTUNDERSCORE; + + typedef [uuid(66504312-BE0F-101A-8BBB-00AA00300CAB), public] + VARIANT_BOOL FONTSTRIKETHROUGH; + + + [ + odl, + uuid(BEF6E002-A874-101A-8BBA-00AA00300CAB), + helpstring("Font Object"), + hidden + ] + interface IFont : IUnknown { + [propget] HRESULT Name([out, retval] BSTR *pname); + [propput] HRESULT Name([in] BSTR pname); + + [propget] HRESULT Size([out, retval] CURRENCY *psize); + [propput] HRESULT Size([in] CURRENCY psize); + + [propget] HRESULT Bold([out, retval] VARIANT_BOOL *pbold); + [propput] HRESULT Bold([in] VARIANT_BOOL pbold); + + [propget] HRESULT Italic([out, retval] VARIANT_BOOL *pitalic); + [propput] HRESULT Italic([in] VARIANT_BOOL pitalic); + + [propget] HRESULT Underline([out, retval] VARIANT_BOOL *punderline); + [propput] HRESULT Underline([in] VARIANT_BOOL punderline); + + [propget] HRESULT Strikethrough([out, retval] VARIANT_BOOL *pstrikethrough); + [propput] HRESULT Strikethrough([in] VARIANT_BOOL pstrikethrough); + + [propget] HRESULT Weight([out, retval] short *pweight); + [propput] HRESULT Weight([in] short pweight); + + [propget] HRESULT Charset([out, retval] short *pcharset); + [propput] HRESULT Charset([in] short pcharset); + + [propget] HRESULT hFont([out, retval] OLE_HANDLE *phfont); + + HRESULT Clone([out] IFont **ppfont); + + HRESULT IsEqual([in] IFont *pfontOther); + + HRESULT SetRatio([in] long cyLogical, [in] long cyHimetric); + + HRESULT AddRefHfont([in] OLE_HANDLE hFont); + + HRESULT ReleaseHfont([in] OLE_HANDLE hFont); + }; + + + [ + odl, + uuid(BEF6E003-A874-101A-8BBA-00AA00300CAB) + ] + dispinterface Font { + properties: + [id(DISPID_FONT_NAME)] BSTR Name; + [id(DISPID_FONT_SIZE)] CURRENCY Size; + [id(DISPID_FONT_BOLD)] VARIANT_BOOL Bold; + [id(DISPID_FONT_ITALIC)] VARIANT_BOOL Italic; + [id(DISPID_FONT_UNDER)] VARIANT_BOOL Underline; + [id(DISPID_FONT_STRIKE)] VARIANT_BOOL Strikethrough; + [id(DISPID_FONT_WEIGHT)] short Weight; + [id(DISPID_FONT_CHARSET)] short Charset; + methods: + } + + typedef [public] Font IFontDisp; + + [ + uuid(0BE35203-8F91-11CE-9DE3-00AA004BB851) + ] + coclass StdFont { + [default] dispinterface Font; + interface IFont; + }; + + [ + odl, + uuid(7BF80980-BF32-101A-8BBB-00AA00300CAB), + helpstring("Picture Object"), + hidden + ] + interface IPicture : IUnknown { + [propget] HRESULT Handle([out, retval] OLE_HANDLE *phandle); + + [propget] HRESULT hPal([out, retval] OLE_HANDLE *phpal); + + [propget] HRESULT Type([out, retval] short *ptype); + + [propget] HRESULT Width([out, retval] OLE_XSIZE_HIMETRIC *pwidth); + + [propget] HRESULT Height([out, retval] OLE_YSIZE_HIMETRIC *pheight); + + HRESULT Render([in] int hdc, + [in] long x, + [in] long y, + [in] long cx, + [in] long cy, + [in] OLE_XPOS_HIMETRIC xSrc, + [in] OLE_YPOS_HIMETRIC ySrc, + [in] OLE_XSIZE_HIMETRIC cxSrc, + [in] OLE_YSIZE_HIMETRIC cySrc, + [in] void *prcWBounds); + + [propput] HRESULT hPal([in] OLE_HANDLE phpal); + + [propget] HRESULT CurDC([out, retval] int *phdcOut); + + HRESULT SelectPicture([in] int hdcIn, + [out] int *phdcOut, + [out] OLE_HANDLE *phbmpOut); + + [propget] HRESULT KeepOriginalFormat([out, retval] VARIANT_BOOL *pfkeep); + [propput] HRESULT KeepOriginalFormat([in] VARIANT_BOOL pfkeep); + + HRESULT PictureChanged(); + + HRESULT SaveAsFile([in] void *pstm, + [in] VARIANT_BOOL fSaveMemCopy, + [out] long *pcbSize); + + [propget] HRESULT Attributes([out, retval] long *pdwAttr); + + HRESULT SetHdc([in] OLE_HANDLE hdc); + }; + + [ + uuid(7BF80981-BF32-101A-8BBB-00AA00300CAB) + ] + dispinterface Picture { + properties: + [id(DISPID_PICT_HANDLE), readonly] OLE_HANDLE Handle; + [id(DISPID_PICT_HPAL)] OLE_HANDLE hPal; + [id(DISPID_PICT_TYPE), readonly] short Type; + [id(DISPID_PICT_WIDTH), readonly] OLE_XSIZE_HIMETRIC Width; + [id(DISPID_PICT_HEIGHT), readonly] OLE_YSIZE_HIMETRIC Height; + methods: + [id(DISPID_PICT_RENDER)] + void Render(int hdc, + long x, + long y, + long cx, + long cy, + OLE_XPOS_HIMETRIC xSrc, + OLE_YPOS_HIMETRIC ySrc, + OLE_XSIZE_HIMETRIC cxSrc, + OLE_YSIZE_HIMETRIC cySrc, + void *prcWBounds); + }; + + typedef [public] Picture IPictureDisp; + + [ + uuid(0BE35204-8F91-11CE-9DE3-00AA004BB851) + ] + coclass StdPicture { + [default] dispinterface Picture; + interface IPicture; + }; +}; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/opengl32/version.rc wine-staging-1.9.3~ubuntu12.04.1/dlls/opengl32/version.rc --- wine-staging-1.9.0~ubuntu12.04.1/dlls/opengl32/version.rc 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/opengl32/version.rc 2016-02-08 19:32:34.000000000 +0000 @@ -20,7 +20,7 @@ #define WINE_FILENAME_STR "opengl32.dll" #define WINE_FILEVERSION 5,1,2600,2082 #define WINE_FILEVERSION_STR "5.1.2600.2082" -#define WINE_LEGALCOPYRIGHT "Copyright (c) 1993-2015 the Wine project. Not Microsoft" /* CATIA needs 'Microsoft' in both CompanyName _and_ LegalCopyright */ +#define WINE_LEGALCOPYRIGHT "Copyright (c) 1993-2016 the Wine project. Not Microsoft" /* CATIA needs 'Microsoft' in both CompanyName _and_ LegalCopyright */ #define WINE_PRODUCTVERSION 5,1,2600,2082 #define WINE_PRODUCTVERSION_STR "5.1" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/pdh/pdh_main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/pdh/pdh_main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/pdh/pdh_main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/pdh/pdh_main.c 2016-02-08 19:32:34.000000000 +0000 @@ -1287,3 +1287,21 @@ FIXME("%s, %p: stub\n", debugstr_w(log), type); return PDH_NOT_IMPLEMENTED; } + +/*********************************************************************** + * PdhBindInputDataSourceA (PDH.@) + */ +PDH_STATUS WINAPI PdhBindInputDataSourceA(PDH_HLOG *source, const char *filenamelist) +{ + FIXME("%p %s: stub\n", source, debugstr_a(filenamelist)); + return PDH_NOT_IMPLEMENTED; +} + +/*********************************************************************** + * PdhBindInputDataSourceW (PDH.@) + */ +PDH_STATUS WINAPI PdhBindInputDataSourceW(PDH_HLOG *source, const WCHAR *filenamelist) +{ + FIXME("%p %s: stub\n", source, debugstr_w(filenamelist)); + return PDH_NOT_IMPLEMENTED; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/pdh/pdh.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/pdh/pdh.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/pdh/pdh.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/pdh/pdh.spec 2016-02-08 19:32:34.000000000 +0000 @@ -5,8 +5,8 @@ @ stdcall PdhAddCounterW(ptr wstr long ptr) @ stdcall PdhAddEnglishCounterA(ptr str long ptr) @ stdcall PdhAddEnglishCounterW(ptr wstr long ptr) -@ stub PdhBindInputDataSourceA -@ stub PdhBindInputDataSourceW +@ stdcall PdhBindInputDataSourceA(ptr str) +@ stdcall PdhBindInputDataSourceW(ptr wstr) @ stub PdhBrowseCountersA @ stub PdhBrowseCountersHA @ stub PdhBrowseCountersHW diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/quartz/enumfilters.c wine-staging-1.9.3~ubuntu12.04.1/dlls/quartz/enumfilters.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/quartz/enumfilters.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/quartz/enumfilters.c 2016-02-08 19:32:34.000000000 +0000 @@ -185,7 +185,7 @@ This->uIndex = 0; hr = IGraphVersion_QueryVersion(This->pVersionSource, ¤tVersion); - if (!hr) + if (hr == S_OK) This->Version = currentVersion; return S_OK; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/quartz/filtergraph.c wine-staging-1.9.3~ubuntu12.04.1/dlls/quartz/filtergraph.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/quartz/filtergraph.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/quartz/filtergraph.c 2016-02-08 19:32:34.000000000 +0000 @@ -176,7 +176,6 @@ IUnknown *outer_unk; LONG ref; IUnknown *punkFilterMapper2; - IFilterMapper2 * pFilterMapper2; IBaseFilter ** ppFiltersInGraph; LPWSTR * pFilterNames; ULONG nFilters; @@ -265,11 +264,11 @@ TRACE(" requesting IFilterMapper interface from aggregated filtermapper (%p)\n", *ppvObj); return IUnknown_QueryInterface(This->punkFilterMapper2, riid, ppvObj); } else if (IsEqualGUID(&IID_IFilterMapper2, riid)) { - *ppvObj = This->pFilterMapper2; TRACE(" returning IFilterMapper2 interface from aggregated filtermapper (%p)\n", *ppvObj); + return IUnknown_QueryInterface(This->punkFilterMapper2, riid, ppvObj); } else if (IsEqualGUID(&IID_IFilterMapper3, riid)) { - *ppvObj = This->pFilterMapper2; TRACE(" returning IFilterMapper3 interface from aggregated filtermapper (%p)\n", *ppvObj); + return IUnknown_QueryInterface(This->punkFilterMapper2, riid, ppvObj); } else if (IsEqualGUID(&IID_IGraphVersion, riid)) { *ppvObj = &This->IGraphConfig_iface; TRACE(" returning IGraphConfig interface (%p)\n", *ppvObj); @@ -319,9 +318,6 @@ IUnknown_Release(This->ItfCacheEntries[i].iface); } - /* AddRef on controlling IUnknown, to compensate for Release of cached IFilterMapper2 */ - IUnknown_AddRef(This->outer_unk); - IFilterMapper2_Release(This->pFilterMapper2); IUnknown_Release(This->punkFilterMapper2); if (This->pSite) IUnknown_Release(This->pSite); @@ -910,6 +906,7 @@ CLSID FilterCLSID; PIN_DIRECTION dir; unsigned int i = 0; + IFilterMapper2 *pFilterMapper2 = NULL; TRACE("(%p/%p)->(%p, %p)\n", This, iface, ppinOut, ppinIn); @@ -999,10 +996,16 @@ TRACE("MajorType %s\n", debugstr_guid(&mt->majortype)); TRACE("SubType %s\n", debugstr_guid(&mt->subtype)); + hr = IUnknown_QueryInterface(This->punkFilterMapper2, &IID_IFilterMapper2, (void**)&pFilterMapper2); + if (FAILED(hr)) { + WARN("Unable to get IFilterMapper2 (%x)\n", hr); + goto out; + } + /* Try to find a suitable filter that can connect to the pin to render */ tab[0] = mt->majortype; tab[1] = mt->subtype; - hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL); + hr = IFilterMapper2_EnumMatchingFilters(pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL); if (FAILED(hr)) { WARN("Unable to enum filters (%x)\n", hr); goto out; @@ -1172,6 +1175,8 @@ IEnumMoniker_Release(pEnumMoniker); out: + if (pFilterMapper2) + IFilterMapper2_Release(pFilterMapper2); if (penummt) IEnumMediaTypes_Release(penummt); if (mt) @@ -1267,6 +1272,7 @@ ULONG nb; IMoniker* pMoniker; INT x; + IFilterMapper2 *pFilterMapper2 = NULL; TRACE("(%p/%p)->(%p)\n", This, iface, ppinOut); @@ -1376,10 +1382,20 @@ continue; } + if (pFilterMapper2 == NULL) + { + hr = IUnknown_QueryInterface(This->punkFilterMapper2, &IID_IFilterMapper2, (void**)&pFilterMapper2); + if (FAILED(hr)) + { + WARN("Unable to query IFilterMapper2 (%x)\n", hr); + break; + } + } + /* Try to find a suitable renderer with the same media type */ tab[0] = mt->majortype; tab[1] = mt->subtype; - hr = IFilterMapper2_EnumMatchingFilters(This->pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL); + hr = IFilterMapper2_EnumMatchingFilters(pFilterMapper2, &pEnumMoniker, 0, FALSE, MERIT_UNLIKELY, TRUE, 1, tab, NULL, NULL, FALSE, FALSE, 0, NULL, NULL, NULL); if (FAILED(hr)) { WARN("Unable to enum filters (%x)\n", hr); @@ -1493,6 +1509,9 @@ hr = S_OK; } + if (pFilterMapper2) + IFilterMapper2_Release(pFilterMapper2); + IEnumMediaTypes_Release(penummt); return hr; } @@ -1599,7 +1618,7 @@ /* Try to find a match without reading the file first */ hr = GetClassMediaFile(NULL, pszFileName, NULL, NULL, &clsid); - if (!hr) + if (hr == S_OK) return CreateFilterInstanceAndLoadFile(&clsid, pszFileName, filter); /* Now create a AyncReader instance, to check for signature bytes in the file */ @@ -1641,7 +1660,7 @@ hr = GetClassMediaFile(pReader, pszFileName, NULL, NULL, &clsid); IAsyncReader_Release(pReader); - if (!hr) + if (hr == S_OK) { /* Release the AsyncReader filter and create the matching one */ IBaseFilter_Release(*filter); @@ -2511,6 +2530,9 @@ if (!pSourceFormat) pSourceFormat = &This->timeformatseek; + if (!pTargetFormat) + pTargetFormat = &This->timeformatseek; + if (IsEqualGUID(pTargetFormat, pSourceFormat)) *pTarget = Source; else @@ -5708,14 +5730,6 @@ hr = CoCreateInstance(&CLSID_FilterMapper2, fimpl->outer_unk, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&fimpl->punkFilterMapper2); - if (SUCCEEDED(hr)) - hr = IUnknown_QueryInterface(fimpl->punkFilterMapper2, &IID_IFilterMapper2, - (void**)&fimpl->pFilterMapper2); - - if (SUCCEEDED(hr)) - /* Release controlling IUnknown - compensate refcount increase from caching IFilterMapper2 interface. */ - IUnknown_Release(fimpl->outer_unk); - if (FAILED(hr)) { ERR("Unable to create filter mapper (%x)\n", hr); if (fimpl->punkFilterMapper2) IUnknown_Release(fimpl->punkFilterMapper2); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/quartz/tests/filtergraph.c wine-staging-1.9.3~ubuntu12.04.1/dlls/quartz/tests/filtergraph.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/quartz/tests/filtergraph.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/quartz/tests/filtergraph.c 2016-02-08 19:32:34.000000000 +0000 @@ -255,6 +255,7 @@ { HRESULT hr; LONGLONG pos = 0xdeadbeef; + GUID format = GUID_NULL; IMediaSeeking *seeking = NULL; IMediaFilter *filter = NULL; IMediaControl *control = NULL; @@ -282,6 +283,26 @@ return; } + format = GUID_NULL; + hr = IMediaSeeking_GetTimeFormat(seeking, &format); + ok(hr == S_OK, "GetTimeFormat failed: %08x\n", hr); + ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "GetTimeFormat: unexpected format %s\n", wine_dbgstr_guid(&format)); + + pos = 0xdeadbeef; + hr = IMediaSeeking_ConvertTimeFormat(seeking, &pos, NULL, 0x123456789a, NULL); + ok(hr == S_OK, "ConvertTimeFormat failed: %08x\n", hr); + ok(pos == 0x123456789a, "ConvertTimeFormat: expected 123456789a, got (%x%08x)\n", (DWORD)(pos >> 32), (DWORD)pos); + + pos = 0xdeadbeef; + hr = IMediaSeeking_ConvertTimeFormat(seeking, &pos, &TIME_FORMAT_MEDIA_TIME, 0x123456789a, NULL); + ok(hr == S_OK, "ConvertTimeFormat failed: %08x\n", hr); + ok(pos == 0x123456789a, "ConvertTimeFormat: expected 123456789a, got (%x%08x)\n", (DWORD)(pos >> 32), (DWORD)pos); + + pos = 0xdeadbeef; + hr = IMediaSeeking_ConvertTimeFormat(seeking, &pos, NULL, 0x123456789a, &TIME_FORMAT_MEDIA_TIME); + ok(hr == S_OK, "ConvertTimeFormat failed: %08x\n", hr); + ok(pos == 0x123456789a, "ConvertTimeFormat: expected 123456789a, got (%x%08x)\n", (DWORD)(pos >> 32), (DWORD)pos); + hr = IMediaSeeking_GetCurrentPosition(seeking, &pos); ok(hr == S_OK, "GetCurrentPosition failed: %08x\n", hr); ok(pos == 0, "Position != 0 (%x%08x)\n", (DWORD)(pos >> 32), (DWORD)pos); @@ -1942,9 +1963,7 @@ ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface); IUnknown_Release(punk); -todo_wine ok(unk_outer.AddRef_called == 0, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called); -todo_wine ok(unk_outer.Release_called == 0, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called); unk_outer.AddRef_called = 0; unk_outer.Release_called = 0; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/rasapi32/rasapi32.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/rasapi32/rasapi32.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/rasapi32/rasapi32.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/rasapi32/rasapi32.spec 2016-02-08 19:32:34.000000000 +0000 @@ -64,6 +64,8 @@ @ stdcall RasSetAutodialParamW(long ptr long) @ stub RasSetCredentialsA @ stub RasSetCredentialsW +@ stdcall RasSetCustomAuthDataA(str str ptr long) +@ stdcall RasSetCustomAuthDataW(wstr wstr ptr long) @ stdcall RasSetEntryDialParamsA(str ptr long) @ stdcall RasSetEntryDialParamsW(wstr ptr long) @ stdcall RasSetEntryPropertiesA(str str ptr long ptr long) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/rasapi32/rasapi.c wine-staging-1.9.3~ubuntu12.04.1/dlls/rasapi32/rasapi.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/rasapi32/rasapi.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/rasapi32/rasapi.c 2016-02-08 19:32:34.000000000 +0000 @@ -494,6 +494,18 @@ return 0; } +DWORD WINAPI RasSetCustomAuthDataA(const char *phonebook, const char *entry, BYTE *authdata, DWORD size) +{ + FIXME("(%s,%s,%p,0x%08x), stub!\n", debugstr_a(phonebook), debugstr_a(entry), authdata, size); + return 0; +} + +DWORD WINAPI RasSetCustomAuthDataW(const WCHAR *phonebook, const WCHAR *entry, BYTE *authdata, DWORD size) +{ + FIXME("(%s,%s,%p,0x%08x), stub!\n", debugstr_w(phonebook), debugstr_w(entry), authdata, size); + return 0; +} + DWORD WINAPI RasSetEntryDialParamsA(LPCSTR lpszPhonebook, LPRASDIALPARAMSA lprasdialparams, BOOL fRemovePassword) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/riched20/editor.c wine-staging-1.9.3~ubuntu12.04.1/dlls/riched20/editor.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/riched20/editor.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/riched20/editor.c 2016-02-08 19:32:34.000000000 +0000 @@ -547,7 +547,8 @@ PARAFORMAT2 fmt; fmt.cbSize = sizeof(fmt); fmt.dwMask = 0; - + fmt.wEffects = 0; + switch(info->rtfMinor) { case rtfParDef: /* restores default paragraph attributes */ @@ -942,7 +943,7 @@ ME_DisplayItem *para = info->editor->pCursors[0].pPara; PARAFORMAT2 *pFmt = para->member.para.pFmt; pFmt->rgxTabs[cellNum] &= ~0x00FFFFFF; - pFmt->rgxTabs[cellNum] = 0x00FFFFFF & info->rtfParam; + pFmt->rgxTabs[cellNum] |= 0x00FFFFFF & info->rtfParam; } info->tableDef->numCellsDefined++; break; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/riched20/run.c wine-staging-1.9.3~ubuntu12.04.1/dlls/riched20/run.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/riched20/run.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/riched20/run.c 2016-02-08 19:32:34.000000000 +0000 @@ -102,6 +102,8 @@ { ME_DisplayItem *p = editor->pBuffer->pFirst; int ofs = 0, ofsp = 0; + + TRACE_(richedit_check)("Checking begin\n"); if(TRACE_ON(richedit_lists)) { TRACE_(richedit_lists)("---\n"); @@ -113,6 +115,7 @@ case diTextEnd: TRACE_(richedit_check)("tend, real ofsp = %d, counted = %d\n", p->member.para.nCharOfs, ofsp+ofs); assert(ofsp+ofs == p->member.para.nCharOfs); + TRACE_(richedit_check)("Checking finished\n"); return; case diParagraph: TRACE_(richedit_check)("para, real ofsp = %d, counted = %d\n", p->member.para.nCharOfs, ofsp+ofs); @@ -137,6 +140,7 @@ assert(0); } } while(1); + TRACE_(richedit_check)("Checking finished\n"); } /****************************************************************************** @@ -234,12 +238,8 @@ ME_Remove(pNext); ME_DestroyDisplayItem(pNext); ME_UpdateRunFlags(editor, &p->member.run); - if(TRACE_ON(richedit)) - { - TRACE("Before check after join\n"); + if(TRACE_ON(richedit_check)) ME_CheckCharOffsets(editor); - TRACE("After check after join\n"); - } } /****************************************************************************** diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/riched20/wrap.c wine-staging-1.9.3~ubuntu12.04.1/dlls/riched20/wrap.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/riched20/wrap.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/riched20/wrap.c 2016-02-08 19:32:34.000000000 +0000 @@ -23,6 +23,7 @@ #include "editor.h" WINE_DEFAULT_DEBUG_CHANNEL(richedit); +WINE_DECLARE_DEBUG_CHANNEL(richedit_check); /* * Unsolved problems: @@ -123,12 +124,8 @@ ME_Cursor cursor = {wc->pPara, item, nVChar}; assert(item->member.run.nCharOfs != -1); - if(TRACE_ON(richedit)) - { - TRACE("Before check before split\n"); + if(TRACE_ON(richedit_check)) ME_CheckCharOffsets(editor); - TRACE("After check before split\n"); - } run = &item->member.run; @@ -147,15 +144,12 @@ run2->pt.x = run->pt.x+run->nWidth; run2->pt.y = run->pt.y; - if(TRACE_ON(richedit)) - { - TRACE("Before check after split\n"); + if(TRACE_ON(richedit_check)) ME_CheckCharOffsets(editor); - TRACE("After check after split\n"); - TRACE("After split: %s(%d, %d), %s(%d, %d)\n", - debugstr_run( run ), run->pt.x, run->pt.y, - debugstr_run( run2 ), run2->pt.x, run2->pt.y); - } + + TRACE("After split: %s(%d, %d), %s(%d, %d)\n", + debugstr_run( run ), run->pt.x, run->pt.y, + debugstr_run( run2 ), run2->pt.x, run2->pt.y); return cursor.pRun; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/rpcrt4/rpc_binding.c wine-staging-1.9.3~ubuntu12.04.1/dlls/rpcrt4/rpc_binding.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/rpcrt4/rpc_binding.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/rpcrt4/rpc_binding.c 2016-02-08 19:32:34.000000000 +0000 @@ -1634,6 +1634,16 @@ } /*********************************************************************** + * RpcBindingServerFromClient (RPCRT4.@) + */ + +RPC_STATUS RPC_ENTRY RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding, RPC_BINDING_HANDLE *ServerBinding) +{ + FIXME("%p %p: stub\n", ClientBinding, ServerBinding); + return RPC_S_INVALID_BINDING; +} + +/*********************************************************************** * RpcBindingSetAuthInfoExA (RPCRT4.@) */ RPCRTAPI RPC_STATUS RPC_ENTRY diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/rpcrt4/rpcrt4.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/rpcrt4/rpcrt4.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/rpcrt4/rpcrt4.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/rpcrt4/rpcrt4.spec 2016-02-08 19:32:34.000000000 +0000 @@ -352,7 +352,7 @@ @ stdcall RpcBindingInqObject(ptr ptr) @ stub RpcBindingInqOption @ stdcall RpcBindingReset(ptr) -@ stub RpcBindingServerFromClient +@ stdcall RpcBindingServerFromClient(ptr ptr) @ stdcall RpcBindingSetAuthInfoA(ptr str long long ptr long) @ stdcall RpcBindingSetAuthInfoExA(ptr str long long ptr long ptr) @ stdcall RpcBindingSetAuthInfoExW(ptr wstr long long ptr long ptr) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/scrrun/filesystem.c wine-staging-1.9.3~ubuntu12.04.1/dlls/scrrun/filesystem.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/scrrun/filesystem.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/scrrun/filesystem.c 2016-02-08 19:32:34.000000000 +0000 @@ -3221,9 +3221,27 @@ static HRESULT WINAPI filesys_DriveExists(IFileSystem3 *iface, BSTR DriveSpec, VARIANT_BOOL *pfExists) { - FIXME("%p %s %p\n", iface, debugstr_w(DriveSpec), pfExists); + UINT len; + WCHAR driveletter; + TRACE("%p %s %p\n", iface, debugstr_w(DriveSpec), pfExists); + + if (!pfExists) return E_POINTER; + + *pfExists = VARIANT_FALSE; + len = SysStringLen(DriveSpec); + + if (len >= 1) { + driveletter = toupperW(DriveSpec[0]); + if (driveletter >= 'A' && driveletter <= 'Z' + && (len < 2 || DriveSpec[1] == ':') + && (len < 3 || DriveSpec[2] == '\\')) { + const WCHAR root[] = {driveletter, ':', '\\', 0}; + UINT drivetype = GetDriveTypeW(root); + *pfExists = drivetype != DRIVE_NO_ROOT_DIR && drivetype != DRIVE_UNKNOWN ? VARIANT_TRUE : VARIANT_FALSE; + } + } - return E_NOTIMPL; + return S_OK; } static HRESULT WINAPI filesys_FileExists(IFileSystem3 *iface, BSTR path, VARIANT_BOOL *ret) @@ -3254,9 +3272,40 @@ static HRESULT WINAPI filesys_GetDrive(IFileSystem3 *iface, BSTR DriveSpec, IDrive **ppdrive) { - FIXME("%p %s %p\n", iface, debugstr_w(DriveSpec), ppdrive); - - return E_NOTIMPL; + UINT len; + HRESULT hr; + WCHAR driveletter; + VARIANT_BOOL drive_exists; + + TRACE("%p %s %p\n", iface, debugstr_w(DriveSpec), ppdrive); + + if (!ppdrive) + return E_POINTER; + + *ppdrive = NULL; + + /* DriveSpec may be one of: 'x', 'x:', 'x:\', '\\computer\share' */ + len = SysStringLen(DriveSpec); + if (!len) + return E_INVALIDARG; + else if (len <= 3) { + driveletter = toupperW(DriveSpec[0]); + if (driveletter < 'A' || driveletter > 'Z' + || (len >= 2 && DriveSpec[1] != ':') + || (len == 3 && DriveSpec[2] != '\\')) + return E_INVALIDARG; + hr = IFileSystem3_DriveExists(iface, DriveSpec, &drive_exists); + if (FAILED(hr)) + return hr; + if (drive_exists == VARIANT_FALSE) + return CTL_E_DEVICEUNAVAILABLE; + return create_drive(driveletter, ppdrive); + } else { + if (DriveSpec[0] != '\\' || DriveSpec[1] != '\\') + return E_INVALIDARG; + FIXME("%s not implemented yet\n", debugstr_w(DriveSpec)); + return E_NOTIMPL; + } } static HRESULT WINAPI filesys_GetFile(IFileSystem3 *iface, BSTR FilePath, diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/scrrun/tests/filesystem.c wine-staging-1.9.3~ubuntu12.04.1/dlls/scrrun/tests/filesystem.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/scrrun/tests/filesystem.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/scrrun/tests/filesystem.c 2016-02-08 19:32:34.000000000 +0000 @@ -59,6 +59,47 @@ DeleteFileW(path); } +static IDrive *get_fixed_drive(void) +{ + IDriveCollection *drives; + IEnumVARIANT *iter; + IDrive *drive; + HRESULT hr; + + hr = IFileSystem3_get_Drives(fs3, &drives); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDriveCollection_get__NewEnum(drives, (IUnknown**)&iter); + ok(hr == S_OK, "got 0x%08x\n", hr); + IDriveCollection_Release(drives); + + while (1) { + DriveTypeConst type; + VARIANT var; + + hr = IEnumVARIANT_Next(iter, 1, &var, NULL); + if (hr == S_FALSE) { + drive = NULL; + break; + } + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDrive, (void**)&drive); + ok(hr == S_OK, "got 0x%08x\n", hr); + VariantClear(&var); + + hr = IDrive_get_DriveType(drive, &type); + ok(hr == S_OK, "got 0x%08x\n", hr); + if (type == Fixed) + break; + + IDrive_Release(drive); + } + + IEnumVARIANT_Release(iter); + return drive; +} + static void test_interfaces(void) { static const WCHAR nonexistent_dirW[] = { @@ -1790,6 +1831,83 @@ SysFreeString(nameW); } +struct driveexists_test { + const WCHAR drivespec[10]; + const INT drivetype; + const VARIANT_BOOL expected_ret; +}; + +/* If 'drivetype' != -1, the first character of 'drivespec' will be replaced + * with the drive letter of a drive of this type. If such a drive does not exist, + * the test will be skipped. */ +static const struct driveexists_test driveexiststestdata[] = { + { {'N',':','\\',0}, DRIVE_NO_ROOT_DIR, VARIANT_FALSE }, + { {'R',':','\\',0}, DRIVE_REMOVABLE, VARIANT_TRUE }, + { {'F',':','\\',0}, DRIVE_FIXED, VARIANT_TRUE }, + { {'F',':',0}, DRIVE_FIXED, VARIANT_TRUE }, + { {'F','?',0}, DRIVE_FIXED, VARIANT_FALSE }, + { {'F',0}, DRIVE_FIXED, VARIANT_TRUE }, + { {'?',0}, -1, VARIANT_FALSE }, + { { 0 } } +}; + +static void test_DriveExists(void) +{ + const struct driveexists_test *ptr = driveexiststestdata; + HRESULT hr; + VARIANT_BOOL ret; + BSTR drivespec; + WCHAR root[] = {'?',':','\\',0}; + + hr = IFileSystem3_DriveExists(fs3, NULL, NULL); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + + ret = VARIANT_TRUE; + hr = IFileSystem3_DriveExists(fs3, NULL, &ret); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(ret == VARIANT_FALSE, "got %x\n", ret); + + drivespec = SysAllocString(root); + hr = IFileSystem3_DriveExists(fs3, drivespec, NULL); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + SysFreeString(drivespec); + + for (; *ptr->drivespec; ptr++) { + drivespec = SysAllocString(ptr->drivespec); + if (ptr->drivetype != -1) { + for (root[0] = 'A'; root[0] <= 'Z'; root[0]++) + if (GetDriveTypeW(root) == ptr->drivetype) + break; + if (root[0] > 'Z') { + skip("No drive with type 0x%x found, skipping test %s.\n", + ptr->drivetype, wine_dbgstr_w(ptr->drivespec)); + SysFreeString(drivespec); + continue; + } + + /* Test both upper and lower case drive letters. */ + drivespec[0] = root[0]; + ret = ptr->expected_ret == VARIANT_TRUE ? VARIANT_FALSE : VARIANT_TRUE; + hr = IFileSystem3_DriveExists(fs3, drivespec, &ret); + ok(hr == S_OK, "got 0x%08x for drive spec %s (%s)\n", + hr, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec)); + ok(ret == ptr->expected_ret, "got %d, expected %d for drive spec %s (%s)\n", + ret, ptr->expected_ret, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec)); + + drivespec[0] = tolower(root[0]); + } + + ret = ptr->expected_ret == VARIANT_TRUE ? VARIANT_FALSE : VARIANT_TRUE; + hr = IFileSystem3_DriveExists(fs3, drivespec, &ret); + ok(hr == S_OK, "got 0x%08x for drive spec %s (%s)\n", + hr, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec)); + ok(ret == ptr->expected_ret, "got %d, expected %d for drive spec %s (%s)\n", + ret, ptr->expected_ret, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec)); + + SysFreeString(drivespec); + } +} + struct getdrivename_test { const WCHAR path[10]; const WCHAR drive[5]; @@ -1835,44 +1953,105 @@ } } -static void test_SerialNumber(void) +struct getdrive_test { + const WCHAR drivespec[12]; + HRESULT res; + const WCHAR driveletter[2]; +}; + +static void test_GetDrive(void) { - IDriveCollection *drives; - IEnumVARIANT *iter; - IDrive *drive; - LONG serial; HRESULT hr; - BSTR name; + IDrive *drive_fixed, *drive; + BSTR dl_fixed, drivespec; + WCHAR root[] = {'?',':','\\',0}; - hr = IFileSystem3_get_Drives(fs3, &drives); - ok(hr == S_OK, "got 0x%08x\n", hr); + drive = (void*)0xdeadbeef; + hr = IFileSystem3_GetDrive(fs3, NULL, NULL); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + ok(drive == (void*)0xdeadbeef, "got %p\n", drive); - hr = IDriveCollection_get__NewEnum(drives, (IUnknown**)&iter); - ok(hr == S_OK, "got 0x%08x\n", hr); - IDriveCollection_Release(drives); + for (root[0] = 'A'; root[0] <= 'Z'; root[0]++) + if (GetDriveTypeW(root) == DRIVE_NO_ROOT_DIR) + break; - while (1) { - DriveTypeConst type; - VARIANT var; + if (root[0] > 'Z') + skip("All drive letters are occupied, skipping test for nonexisting drive.\n"); + else { + drivespec = SysAllocString(root); + drive = (void*)0xdeadbeef; + hr = IFileSystem3_GetDrive(fs3, drivespec, &drive); + ok(hr == CTL_E_DEVICEUNAVAILABLE, "got 0x%08x\n", hr); + ok(drive == NULL, "got %p\n", drive); + SysFreeString(drivespec); + } - hr = IEnumVARIANT_Next(iter, 1, &var, NULL); - if (hr == S_FALSE) { - skip("No fixed drive found, skipping test.\n"); - IEnumVARIANT_Release(iter); - return; - } - ok(hr == S_OK, "got 0x%08x\n", hr); + drive_fixed = get_fixed_drive(); + if (!drive_fixed) { + skip("No fixed drive found, skipping test.\n"); + return; + } - hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDrive, (void**)&drive); - ok(hr == S_OK, "got 0x%08x\n", hr); - VariantClear(&var); + hr = IDrive_get_DriveLetter(drive_fixed, &dl_fixed); + ok(hr == S_OK, "got 0x%08x\n", hr); - hr = IDrive_get_DriveType(drive, &type); - ok(hr == S_OK, "got 0x%08x\n", hr); - if (type == Fixed) - break; + if (FAILED(hr)) + skip("Could not retrieve drive letter of fixed drive, skipping test.\n"); + else { + WCHAR dl_upper = toupper(dl_fixed[0]); + WCHAR dl_lower = tolower(dl_fixed[0]); + struct getdrive_test testdata[] = { + { {dl_upper,0}, S_OK, {dl_upper,0} }, + { {dl_upper,':',0}, S_OK, {dl_upper,0} }, + { {dl_upper,':','\\',0}, S_OK, {dl_upper,0} }, + { {dl_lower,':','\\',0}, S_OK, {dl_upper,0} }, + { {dl_upper,'\\',0}, E_INVALIDARG, { 0 } }, + { {dl_lower,'\\',0}, E_INVALIDARG, { 0 } }, + { {'$',':','\\',0}, E_INVALIDARG, { 0 } }, + { {'\\','h','o','s','t','\\','s','h','a','r','e',0}, E_INVALIDARG, { 0 } }, + { {'h','o','s','t','\\','s','h','a','r','e',0}, E_INVALIDARG, { 0 } }, + { { 0 } }, + }; + struct getdrive_test *ptr = &testdata[0]; + + for (; *ptr->drivespec; ptr++) { + drivespec = SysAllocString(ptr->drivespec); + drive = (void*)0xdeadbeef; + hr = IFileSystem3_GetDrive(fs3, drivespec, &drive); + ok(hr == ptr->res, "got 0x%08x, expected 0x%08x for drive spec %s\n", + hr, ptr->res, wine_dbgstr_w(ptr->drivespec)); + ok(!lstrcmpW(ptr->drivespec, drivespec), "GetDrive modified its DriveSpec argument\n"); + SysFreeString(drivespec); + + if (*ptr->driveletter) { + BSTR driveletter; + hr = IDrive_get_DriveLetter(drive, &driveletter); + ok(hr == S_OK, "got 0x%08x for drive spec %s\n", hr, wine_dbgstr_w(ptr->drivespec)); + if (SUCCEEDED(hr)) { + ok(!lstrcmpW(ptr->driveletter, driveletter), "got %s, expected %s for drive spec %s\n", + wine_dbgstr_w(driveletter), wine_dbgstr_w(ptr->driveletter), + wine_dbgstr_w(ptr->drivespec)); + SysFreeString(driveletter); + } + IDrive_Release(drive); + } else + ok(drive == NULL, "got %p for drive spec %s\n", drive, wine_dbgstr_w(ptr->drivespec)); + } + SysFreeString(dl_fixed); + } +} - IDrive_Release(drive); +static void test_SerialNumber(void) +{ + IDrive *drive; + LONG serial; + HRESULT hr; + BSTR name; + + drive = get_fixed_drive(); + if (!drive) { + skip("No fixed drive found, skipping test.\n"); + return; } hr = IDrive_get_SerialNumber(drive, NULL); @@ -1902,7 +2081,6 @@ SysFreeString(name); IDrive_Release(drive); - IEnumVARIANT_Release(iter); } static const struct extension_test { @@ -2019,7 +2197,9 @@ test_WriteLine(); test_ReadAll(); test_Read(); + test_DriveExists(); test_GetDriveName(); + test_GetDrive(); test_SerialNumber(); test_GetExtensionName(); test_GetSpecialFolder(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/shell32/shfldr_unixfs.c wine-staging-1.9.3~ubuntu12.04.1/dlls/shell32/shfldr_unixfs.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/shell32/shfldr_unixfs.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/shell32/shfldr_unixfs.c 2016-02-08 19:32:34.000000000 +0000 @@ -1123,24 +1123,24 @@ } static HRESULT WINAPI ShellFolder2_GetAttributesOf(IShellFolder2* iface, UINT cidl, - LPCITEMIDLIST* apidl, SFGAOF* rgfInOut) + LPCITEMIDLIST* apidl, SFGAOF* attrs) { UnixFolder *This = impl_from_IShellFolder2(iface); HRESULT hr = S_OK; - TRACE("(%p)->(%u %p %p)\n", This, cidl, apidl, rgfInOut); + TRACE("(%p)->(%u %p %p)\n", This, cidl, apidl, attrs); - if (!rgfInOut || (cidl && !apidl)) + if (!attrs || (cidl && !apidl)) return E_INVALIDARG; if (cidl == 0) { - *rgfInOut &= This->m_dwAttributes; + *attrs &= This->m_dwAttributes; } else { char szAbsolutePath[FILENAME_MAX], *pszRelativePath; UINT i; - *rgfInOut = SFGAO_CANCOPY|SFGAO_CANMOVE|SFGAO_CANLINK|SFGAO_CANRENAME|SFGAO_CANDELETE| - SFGAO_HASPROPSHEET|SFGAO_DROPTARGET|SFGAO_FILESYSTEM; + *attrs = SFGAO_CANCOPY | SFGAO_CANMOVE | SFGAO_CANLINK | SFGAO_CANRENAME | SFGAO_CANDELETE | + SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | SFGAO_FILESYSTEM; lstrcpyA(szAbsolutePath, This->m_pszPath); pszRelativePath = szAbsolutePath + lstrlenA(szAbsolutePath); for (i=0; i= sizeof(encoded)/2) { - if (str[strlen(str)-1] == '"') - strcat(str, ", "); - strcat(str, name); - strcat(str, "=\""); - strcat(str, param); - strcat(str, "\""); + fprintf(stderr, "string is too long!\n"); + assert(0); } + ptr = encoded; + for (i = 0; i < len; i++) + sprintf(&ptr[i * 2], "%02x", (unsigned char)str[i]); + ptr[2 * len] = '\0'; + return ptr; } -static int _todo_wait = 0; -#define todo_wait for (_todo_wait = 1; _todo_wait; _todo_wait = 0) - -static char shell_call[2048]=""; -static int bad_shellexecute = 0; -static INT_PTR shell_execute(LPCSTR verb, LPCSTR file, LPCSTR parameters, LPCSTR directory) +static unsigned decode_char(char c) { - INT_PTR rc, rcEmpty = 0; - - if(!verb) - rcEmpty = shell_execute("", file, parameters, directory); - - strcpy(shell_call, "ShellExecute("); - strcat_param(shell_call, "verb", verb); - strcat_param(shell_call, "file", file); - strcat_param(shell_call, "params", parameters); - strcat_param(shell_call, "dir", directory); - strcat(shell_call, ")"); - if (winetest_debug > 1) - trace("%s\n", shell_call); - - DeleteFileA(child_file); - SetLastError(0xcafebabe); - - /* FIXME: We cannot use ShellExecuteEx() here because if there is no - * association it displays the 'Open With' dialog and I could not find - * a flag to prevent this. - */ - rc=(INT_PTR)ShellExecuteA(NULL, verb, file, parameters, directory, SW_HIDE); - - if (rc > 32) - { - int wait_rc; - wait_rc=WaitForSingleObject(hEvent, 5000); - if (wait_rc == WAIT_TIMEOUT) - { - HWND wnd = FindWindowA("#32770", "Windows"); - if (!wnd) - wnd = FindWindowA("Shell_Flyout", ""); - if (wnd != NULL) - { - SendMessageA(wnd, WM_CLOSE, 0, 0); - win_skip("Skipping shellexecute of file with unassociated extension\n"); - skip_noassoc_tests = TRUE; - rc = SE_ERR_NOASSOC; - } - } - if (!_todo_wait) - ok(wait_rc==WAIT_OBJECT_0 || rc <= 32, "%s WaitForSingleObject returned %d\n", shell_call, wait_rc); - else todo_wine - ok(wait_rc==WAIT_OBJECT_0 || rc <= 32, "%s WaitForSingleObject returned %d\n", shell_call, wait_rc); - } - /* The child process may have changed the result file, so let profile - * functions know about it - */ - WritePrivateProfileStringA(NULL, NULL, NULL, child_file); - if (rc > 32) - dump_child(); - - if(!verb) - { - if (rc != rcEmpty && rcEmpty == SE_ERR_NOASSOC) /* NT4 */ - bad_shellexecute = 1; - ok(rc == rcEmpty || broken(rc != rcEmpty && rcEmpty == SE_ERR_NOASSOC) /* NT4 */, - "%s Got different return value with empty string: %lu %lu\n", shell_call, rc, rcEmpty); - } - - return rc; + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + assert(c >= 'A' && c <= 'F'); + return c - 'A' + 10; } -static INT_PTR shell_execute_ex(DWORD mask, LPCSTR verb, LPCSTR file, - LPCSTR parameters, LPCSTR directory, - LPCSTR class) +static char* decodeA(const char* str) { - SHELLEXECUTEINFOA sei; - BOOL success; - INT_PTR rc; + static char decoded[1024]; + char* ptr; + size_t len,i; - strcpy(shell_call, "ShellExecuteEx("); - if (mask) + len = strlen(str) / 2; + if (!len--) return NULL; + if (len >= sizeof(decoded)) { - char smask[11]; - sprintf(smask, "0x%x", mask); - strcat_param(shell_call, "mask", smask); + fprintf(stderr, "string is too long!\n"); + assert(0); } - strcat_param(shell_call, "verb", verb); - strcat_param(shell_call, "file", file); - strcat_param(shell_call, "params", parameters); - strcat_param(shell_call, "dir", directory); - strcat_param(shell_call, "class", class); - strcat(shell_call, ")"); - if (winetest_debug > 1) - trace("%s\n", shell_call); + ptr = decoded; + for (i = 0; i < len; i++) + ptr[i] = (decode_char(str[2 * i]) << 4) | decode_char(str[2 * i + 1]); + ptr[len] = '\0'; + return ptr; +} - sei.cbSize=sizeof(sei); - sei.fMask=SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE | mask; - sei.hwnd=NULL; - sei.lpVerb=verb; - sei.lpFile=file; - sei.lpParameters=parameters; - sei.lpDirectory=directory; - sei.nShow=SW_SHOWNORMAL; - sei.hInstApp=NULL; /* Out */ - sei.lpIDList=NULL; - sei.lpClass=class; - sei.hkeyClass=NULL; - sei.dwHotKey=0; - U(sei).hIcon=NULL; - sei.hProcess=NULL; /* Out */ +static void WINETEST_PRINTF_ATTR(2,3) childPrintf(HANDLE h, const char* fmt, ...) +{ + va_list valist; + char buffer[1024]; + DWORD w; - DeleteFileA(child_file); - SetLastError(0xcafebabe); - success=ShellExecuteExA(&sei); - rc=(INT_PTR)sei.hInstApp; - ok((success && rc > 32) || (!success && rc <= 32), - "%s rc=%d and hInstApp=%ld is not allowed\n", shell_call, success, rc); + va_start(valist, fmt); + vsprintf(buffer, fmt, valist); + va_end(valist); + WriteFile(h, buffer, strlen(buffer), &w, NULL); +} - if (rc > 32) - { - int wait_rc; - if (sei.hProcess!=NULL) - { - wait_rc=WaitForSingleObject(sei.hProcess, 5000); - ok(wait_rc==WAIT_OBJECT_0, "WaitForSingleObject(hProcess) returned %d\n", wait_rc); - } - wait_rc=WaitForSingleObject(hEvent, 5000); - if (!_todo_wait) - ok(wait_rc==WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", wait_rc); - else todo_wine - ok(wait_rc==WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", wait_rc); - } - /* The child process may have changed the result file, so let profile - * functions know about it - */ - WritePrivateProfileStringA(NULL, NULL, NULL, child_file); - if (rc > 32) - dump_child(); +static char* getChildString(const char* sect, const char* key) +{ + char buf[1024]; + char* ret; - return rc; + GetPrivateProfileStringA(sect, key, "-", buf, sizeof(buf), child_file); + if (buf[0] == '\0' || (buf[0] == '-' && buf[1] == '\0')) return NULL; + assert(!(strlen(buf) & 1)); + ret = decodeA(buf); + return ret; } - /*** * - * Functions to create / delete associations wrappers + * Child code * ***/ -static BOOL create_test_association(const char* extension) -{ - HKEY hkey, hkey_shell; - char class[MAX_PATH]; - LONG rc; - - sprintf(class, "shlexec%s", extension); - rc=RegCreateKeyExA(HKEY_CLASSES_ROOT, extension, 0, NULL, 0, KEY_SET_VALUE, - NULL, &hkey, NULL); - if (rc != ERROR_SUCCESS) - return FALSE; +static DWORD ddeInst; +static HSZ hszTopic; +static char ddeExec[MAX_PATH], ddeApplication[MAX_PATH]; +static BOOL post_quit_on_execute; - rc=RegSetValueExA(hkey, NULL, 0, REG_SZ, (LPBYTE) class, strlen(class)+1); - ok(rc==ERROR_SUCCESS, "RegSetValueEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc); - CloseHandle(hkey); +/* Handle DDE for doChild() and test_dde_default_app() */ +static HDDEDATA CALLBACK ddeCb(UINT uType, UINT uFmt, HCONV hConv, + HSZ hsz1, HSZ hsz2, HDDEDATA hData, + ULONG_PTR dwData1, ULONG_PTR dwData2) +{ + DWORD size = 0; - rc=RegCreateKeyExA(HKEY_CLASSES_ROOT, class, 0, NULL, 0, - KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS, NULL, &hkey, NULL); - ok(rc==ERROR_SUCCESS, "RegCreateKeyEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc); + if (winetest_debug > 2) + trace("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n", + uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2); - rc=RegCreateKeyExA(hkey, "shell", 0, NULL, 0, - KEY_CREATE_SUB_KEY, NULL, &hkey_shell, NULL); - ok(rc==ERROR_SUCCESS, "RegCreateKeyEx 'shell' failed, expected ERROR_SUCCESS, got %d\n", rc); + switch (uType) + { + case XTYP_CONNECT: + if (!DdeCmpStringHandles(hsz1, hszTopic)) + { + size = DdeQueryStringA(ddeInst, hsz2, ddeApplication, MAX_PATH, CP_WINANSI); + ok(size < MAX_PATH, "got size %d\n", size); + assert(size < MAX_PATH); + return (HDDEDATA)TRUE; + } + return (HDDEDATA)FALSE; - CloseHandle(hkey); - CloseHandle(hkey_shell); + case XTYP_EXECUTE: + size = DdeGetData(hData, (LPBYTE)ddeExec, MAX_PATH, 0); + ok(size < MAX_PATH, "got size %d\n", size); + assert(size < MAX_PATH); + DdeFreeDataHandle(hData); + if (post_quit_on_execute) + PostQuitMessage(0); + return (HDDEDATA)DDE_FACK; - return TRUE; + default: + return NULL; + } } -/* Based on RegDeleteTreeW from dlls/advapi32/registry.c */ -static LSTATUS myRegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey) +static HANDLE hEvent; +static void init_event(const char* child_file) { - LONG ret; - DWORD dwMaxSubkeyLen, dwMaxValueLen; - DWORD dwMaxLen, dwSize; - CHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf; - HKEY hSubKey = hKey; + char* event_name; + event_name=strrchr(child_file, '\\')+1; + hEvent=CreateEventA(NULL, FALSE, FALSE, event_name); +} - if(lpszSubKey) - { - ret = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); - if (ret) return ret; - } +/* + * This is just to make sure the child won't run forever stuck in a + * GetMessage() loop when DDE fails for some reason. + */ +static void CALLBACK childTimeout(HWND wnd, UINT msg, UINT_PTR timer, DWORD time) +{ + trace("childTimeout called\n"); - /* Get highest length for keys, values */ - ret = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, NULL, - &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL); - if (ret) goto cleanup; + PostQuitMessage(0); +} - dwMaxSubkeyLen++; - dwMaxValueLen++; - dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen); - if (dwMaxLen > sizeof(szNameBuf)/sizeof(CHAR)) +static void doChild(int argc, char** argv) +{ + char *filename, buffer[MAX_PATH]; + HANDLE hFile, map; + int i; + UINT_PTR timer; + + filename=argv[2]; + hFile=CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + if (hFile == INVALID_HANDLE_VALUE) + return; + + /* Arguments */ + childPrintf(hFile, "[Child]\r\n"); + if (winetest_debug > 2) { - /* Name too big: alloc a buffer for it */ - if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(CHAR)))) - { - ret = ERROR_NOT_ENOUGH_MEMORY; - goto cleanup; - } + trace("cmdlineA='%s'\n", GetCommandLineA()); + trace("argcA=%d\n", argc); + } + childPrintf(hFile, "cmdlineA=%s\r\n", encodeA(GetCommandLineA())); + childPrintf(hFile, "argcA=%d\r\n", argc); + for (i = 0; i < argc; i++) + { + if (winetest_debug > 2) + trace("argvA%d='%s'\n", i, argv[i]); + childPrintf(hFile, "argvA%d=%s\r\n", i, encodeA(argv[i])); } + GetModuleFileNameA(GetModuleHandleA(NULL), buffer, sizeof(buffer)); + childPrintf(hFile, "longPath=%s\r\n", encodeA(buffer)); + /* Check environment variable inheritance */ + *buffer = '\0'; + SetLastError(0); + GetEnvironmentVariableA("ShlexecVar", buffer, sizeof(buffer)); + childPrintf(hFile, "ShlexecVarLE=%d\r\n", GetLastError()); + childPrintf(hFile, "ShlexecVar=%s\r\n", encodeA(buffer)); - /* Recursively delete all the subkeys */ - while (TRUE) + map = OpenFileMappingA(FILE_MAP_READ, FALSE, "winetest_shlexec_dde_map"); + if (map != NULL) { - dwSize = dwMaxLen; - if (RegEnumKeyExA(hSubKey, 0, lpszName, &dwSize, NULL, - NULL, NULL, NULL)) break; + HANDLE dde_ready; + char *shared_block = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 4096); + CloseHandle(map); + if (shared_block[0] != '\0' || shared_block[1] != '\0') + { + HDDEDATA hdde; + HSZ hszApplication; + MSG msg; + UINT rc; - ret = myRegDeleteTreeA(hSubKey, lpszName); - if (ret) goto cleanup; - } + post_quit_on_execute = TRUE; + ddeInst = 0; + rc = DdeInitializeA(&ddeInst, ddeCb, CBF_SKIP_ALLNOTIFICATIONS | CBF_FAIL_ADVISES | + CBF_FAIL_POKES | CBF_FAIL_REQUESTS, 0); + ok(rc == DMLERR_NO_ERROR, "DdeInitializeA() returned %d\n", rc); + hszApplication = DdeCreateStringHandleA(ddeInst, shared_block, CP_WINANSI); + ok(hszApplication != NULL, "DdeCreateStringHandleA(%s) = NULL\n", shared_block); + shared_block += strlen(shared_block) + 1; + hszTopic = DdeCreateStringHandleA(ddeInst, shared_block, CP_WINANSI); + ok(hszTopic != NULL, "DdeCreateStringHandleA(%s) = NULL\n", shared_block); + hdde = DdeNameService(ddeInst, hszApplication, 0, DNS_REGISTER | DNS_FILTEROFF); + ok(hdde != NULL, "DdeNameService() failed le=%u\n", GetLastError()); - if (lpszSubKey) - ret = RegDeleteKeyA(hKey, lpszSubKey); - else - while (TRUE) - { - dwSize = dwMaxLen; - if (RegEnumValueA(hKey, 0, lpszName, &dwSize, - NULL, NULL, NULL, NULL)) break; + timer = SetTimer(NULL, 0, 2500, childTimeout); - ret = RegDeleteValueA(hKey, lpszName); - if (ret) goto cleanup; + dde_ready = OpenEventA(EVENT_MODIFY_STATE, FALSE, "winetest_shlexec_dde_ready"); + SetEvent(dde_ready); + CloseHandle(dde_ready); + + while (GetMessageA(&msg, NULL, 0, 0)) + { + if (winetest_debug > 2) + trace("msg %d lParam=%ld wParam=%lu\n", msg.message, msg.lParam, msg.wParam); + DispatchMessageA(&msg); + } + + Sleep(500); + KillTimer(NULL, timer); + hdde = DdeNameService(ddeInst, hszApplication, 0, DNS_UNREGISTER); + ok(hdde != NULL, "DdeNameService() failed le=%u\n", GetLastError()); + ok(DdeFreeStringHandle(ddeInst, hszTopic), "DdeFreeStringHandle(topic)\n"); + ok(DdeFreeStringHandle(ddeInst, hszApplication), "DdeFreeStringHandle(application)\n"); + ok(DdeUninitialize(ddeInst), "DdeUninitialize() failed\n"); + } + else + { + dde_ready = OpenEventA(EVENT_MODIFY_STATE, FALSE, "winetest_shlexec_dde_ready"); + SetEvent(dde_ready); + CloseHandle(dde_ready); } -cleanup: - /* Free buffer if allocated */ - if (lpszName != szNameBuf) - HeapFree( GetProcessHeap(), 0, lpszName); - if(lpszSubKey) - RegCloseKey(hSubKey); - return ret; -} + UnmapViewOfFile(shared_block); -static void delete_test_association(const char* extension) -{ - char class[MAX_PATH]; + childPrintf(hFile, "ddeExec=%s\r\n", encodeA(ddeExec)); + } - sprintf(class, "shlexec%s", extension); - myRegDeleteTreeA(HKEY_CLASSES_ROOT, class); - myRegDeleteTreeA(HKEY_CLASSES_ROOT, extension); + childPrintf(hFile, "Failures=%d\r\n", winetest_get_failures()); + CloseHandle(hFile); + + init_event(filename); + SetEvent(hEvent); + CloseHandle(hEvent); } -static void create_test_verb_dde(const char* extension, const char* verb, - int rawcmd, const char* cmdtail, const char *ddeexec, - const char *application, const char *topic, - const char *ifexec) +static void dump_child_(const char* file, int line) { - HKEY hkey_shell, hkey_verb, hkey_cmd; - char shell[MAX_PATH]; - char* cmd; - LONG rc; + if (winetest_debug > 1) + { + char key[18]; + char* str; + int i, c; - sprintf(shell, "shlexec%s\\shell", extension); - rc=RegOpenKeyExA(HKEY_CLASSES_ROOT, shell, 0, - KEY_CREATE_SUB_KEY, &hkey_shell); - ok(rc == ERROR_SUCCESS, "%s key creation failed with %d\n", shell, rc); + str=getChildString("Child", "cmdlineA"); + trace_(file, line)("cmdlineA='%s'\n", str); + c=GetPrivateProfileIntA("Child", "argcA", -1, child_file); + trace_(file, line)("argcA=%d\n",c); + for (i=0;i 1 the ShellExecute() command has already been + * traced. + */ + if (!condition && winetest_debug <= 1 && !shell_call_traced) { - rc=RegSetValueExA(hkey_cmd, NULL, 0, REG_SZ, (LPBYTE)cmdtail, strlen(cmdtail)+1); + printf("Called %s\n", shell_call); + if (*assoc_desc) + printf("%s\n", assoc_desc); + shell_call_traced=1; } - else + + va_start(valist, msg); + winetest_vok(condition, msg, valist); + va_end(valist); +} +#define okShell_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : _okShell +#define okShell okShell_(__FILE__, __LINE__) + +void reset_association_description(void) +{ + *assoc_desc = '\0'; +} + +static void okChildString_(const char* file, int line, const char* key, const char* expected, const char* bad) +{ + char* result; + result=getChildString("Child", key); + if (!result) { - cmd=HeapAlloc(GetProcessHeap(), 0, strlen(argv0)+10+strlen(child_file)+2+strlen(cmdtail)+1); - sprintf(cmd,"%s shlexec \"%s\" %s", argv0, child_file, cmdtail); - rc=RegSetValueExA(hkey_cmd, NULL, 0, REG_SZ, (LPBYTE)cmd, strlen(cmd)+1); - ok(rc == ERROR_SUCCESS, "setting command failed with %d\n", rc); - HeapFree(GetProcessHeap(), 0, cmd); + okShell_(file, line)(FALSE, "%s expected '%s', but key not found or empty\n", key, expected); + return; } + okShell_(file, line)(lstrcmpiA(result, expected) == 0 || + broken(lstrcmpiA(result, bad) == 0), + "%s expected '%s', got '%s'\n", key, expected, result); +} +#define okChildString(key, expected) okChildString_(__FILE__, __LINE__, (key), (expected), (expected)) +#define okChildStringBroken(key, expected, broken) okChildString_(__FILE__, __LINE__, (key), (expected), (broken)) - if (ddeexec) +static int StrCmpPath(const char* s1, const char* s2) +{ + if (!s1 && !s2) return 0; + if (!s2) return 1; + if (!s1) return -1; + while (*s1) { - HKEY hkey_ddeexec, hkey_application, hkey_topic, hkey_ifexec; - - rc=RegCreateKeyExA(hkey_verb, "ddeexec", 0, NULL, 0, KEY_SET_VALUE | - KEY_CREATE_SUB_KEY, NULL, &hkey_ddeexec, NULL); - ok(rc == ERROR_SUCCESS, "\'ddeexec\' key creation failed with %d\n", rc); - rc=RegSetValueExA(hkey_ddeexec, NULL, 0, REG_SZ, (LPBYTE)ddeexec, - strlen(ddeexec)+1); - ok(rc == ERROR_SUCCESS, "set value failed with %d\n", rc); - - if (application) + if (!*s2) { - rc=RegCreateKeyExA(hkey_ddeexec, "application", 0, NULL, 0, KEY_SET_VALUE, - NULL, &hkey_application, NULL); - ok(rc == ERROR_SUCCESS, "\'application\' key creation failed with %d\n", rc); - - rc=RegSetValueExA(hkey_application, NULL, 0, REG_SZ, (LPBYTE)application, - strlen(application)+1); - ok(rc == ERROR_SUCCESS, "set value failed with %d\n", rc); - CloseHandle(hkey_application); + if (*s1=='.') + s1++; + return (*s1-*s2); } - if (topic) + if ((*s1=='/' || *s1=='\\') && (*s2=='/' || *s2=='\\')) { - rc=RegCreateKeyExA(hkey_ddeexec, "topic", 0, NULL, 0, KEY_SET_VALUE, - NULL, &hkey_topic, NULL); - ok(rc == ERROR_SUCCESS, "\'topic\' key creation failed with %d\n", rc); - rc=RegSetValueExA(hkey_topic, NULL, 0, REG_SZ, (LPBYTE)topic, - strlen(topic)+1); - ok(rc == ERROR_SUCCESS, "set value failed with %d\n", rc); - CloseHandle(hkey_topic); + while (*s1=='/' || *s1=='\\') + s1++; + while (*s2=='/' || *s2=='\\') + s2++; } - if (ifexec) + else if (toupper(*s1)==toupper(*s2)) { - rc=RegCreateKeyExA(hkey_ddeexec, "ifexec", 0, NULL, 0, KEY_SET_VALUE, - NULL, &hkey_ifexec, NULL); - ok(rc == ERROR_SUCCESS, "\'ifexec\' key creation failed with %d\n", rc); - rc=RegSetValueExA(hkey_ifexec, NULL, 0, REG_SZ, (LPBYTE)ifexec, - strlen(ifexec)+1); - ok(rc == ERROR_SUCCESS, "set value failed with %d\n", rc); - CloseHandle(hkey_ifexec); + s1++; + s2++; + } + else + { + return (*s1-*s2); } - CloseHandle(hkey_ddeexec); } + if (*s2=='.') + s2++; + if (*s2) + return -1; + return 0; +} - CloseHandle(hkey_shell); - CloseHandle(hkey_verb); - CloseHandle(hkey_cmd); +static void okChildPath_(const char* file, int line, const char* key, const char* expected) +{ + char* result; + result=getChildString("Child", key); + if (!result) + { + okShell_(file,line)(FALSE, "%s expected '%s', but key not found or empty\n", key, expected); + return; + } + okShell_(file,line)(StrCmpPath(result, expected) == 0, + "%s expected '%s', got '%s'\n", key, expected, result); } +#define okChildPath(key, expected) okChildPath_(__FILE__, __LINE__, (key), (expected)) -static void create_test_verb(const char* extension, const char* verb, - int rawcmd, const char* cmdtail) +static void okChildInt_(const char* file, int line, const char* key, int expected) { - create_test_verb_dde(extension, verb, rawcmd, cmdtail, NULL, NULL, - NULL, NULL); + INT result; + result=GetPrivateProfileIntA("Child", key, expected, child_file); + okShell_(file,line)(result == expected, + "%s expected %d, but got %d\n", key, expected, result); } +#define okChildInt(key, expected) okChildInt_(__FILE__, __LINE__, (key), (expected)) + +static void okChildIntBroken_(const char* file, int line, const char* key, int expected) +{ + INT result; + result=GetPrivateProfileIntA("Child", key, expected, child_file); + okShell_(file,line)(result == expected || broken(result != expected), + "%s expected %d, but got %d\n", key, expected, result); +} +#define okChildIntBroken(key, expected) okChildIntBroken_(__FILE__, __LINE__, (key), (expected)) + /*** * - * Functions to check that the child process was started just right - * (borrowed from dlls/kernel32/tests/process.c) + * ShellExecute wrappers * ***/ -static const char* encodeA(const char* str) +static void strcat_param(char* str, const char* name, const char* param) { - static char encoded[2*1024+1]; - char* ptr; - size_t len,i; - - if (!str) return ""; - len = strlen(str) + 1; - if (len >= sizeof(encoded)/2) + if (param) { - fprintf(stderr, "string is too long!\n"); - assert(0); + if (str[strlen(str)-1] == '"') + strcat(str, ", "); + strcat(str, name); + strcat(str, "=\""); + strcat(str, param); + strcat(str, "\""); } - ptr = encoded; - for (i = 0; i < len; i++) - sprintf(&ptr[i * 2], "%02x", (unsigned char)str[i]); - ptr[2 * len] = '\0'; - return ptr; } -static unsigned decode_char(char c) -{ - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - assert(c >= 'A' && c <= 'F'); - return c - 'A' + 10; -} +static int _todo_wait = 0; +#define todo_wait for (_todo_wait = 1; _todo_wait; _todo_wait = 0) -static char* decodeA(const char* str) +static int bad_shellexecute = 0; + +static INT_PTR shell_execute_(const char* file, int line, LPCSTR verb, LPCSTR filename, LPCSTR parameters, LPCSTR directory) { - static char decoded[1024]; - char* ptr; - size_t len,i; + INT_PTR rc, rcEmpty = 0; - len = strlen(str) / 2; - if (!len--) return NULL; - if (len >= sizeof(decoded)) + if(!verb) + rcEmpty = shell_execute_(file, line, "", filename, parameters, directory); + + shell_call_traced=0; + strcpy(shell_call, "ShellExecute("); + strcat_param(shell_call, "verb", verb); + strcat_param(shell_call, "file", filename); + strcat_param(shell_call, "params", parameters); + strcat_param(shell_call, "dir", directory); + strcat(shell_call, ")"); + if (winetest_debug > 1) { - fprintf(stderr, "string is too long!\n"); - assert(0); + trace_(file, line)("Called %s\n", shell_call); + if (*assoc_desc) + trace_(file, line)("%s\n", assoc_desc); + shell_call_traced=1; } - ptr = decoded; - for (i = 0; i < len; i++) - ptr[i] = (decode_char(str[2 * i]) << 4) | decode_char(str[2 * i + 1]); - ptr[len] = '\0'; - return ptr; -} -static void childPrintf(HANDLE h, const char* fmt, ...) -{ - va_list valist; - char buffer[1024]; - DWORD w; + DeleteFileA(child_file); + SetLastError(0xcafebabe); - va_start(valist, fmt); - vsprintf(buffer, fmt, valist); - va_end(valist); - WriteFile(h, buffer, strlen(buffer), &w, NULL); -} + /* FIXME: We cannot use ShellExecuteEx() here because if there is no + * association it displays the 'Open With' dialog and I could not find + * a flag to prevent this. + */ + rc=(INT_PTR)ShellExecuteA(NULL, verb, filename, parameters, directory, SW_HIDE); -static DWORD ddeInst; -static HSZ hszTopic; -static char ddeExec[MAX_PATH], ddeApplication[MAX_PATH]; -static BOOL post_quit_on_execute; + if (rc > 32) + { + int wait_rc; + wait_rc=WaitForSingleObject(hEvent, 5000); + if (wait_rc == WAIT_TIMEOUT) + { + HWND wnd = FindWindowA("#32770", "Windows"); + if (!wnd) + wnd = FindWindowA("Shell_Flyout", ""); + if (wnd != NULL) + { + SendMessageA(wnd, WM_CLOSE, 0, 0); + win_skip("Skipping shellexecute of file with unassociated extension\n"); + skip_noassoc_tests = TRUE; + rc = SE_ERR_NOASSOC; + } + } + if (!_todo_wait) + okShell_(file, line)(wait_rc==WAIT_OBJECT_0 || rc <= 32, + "WaitForSingleObject returned %d\n", wait_rc); + else todo_wine + okShell_(file, line)(wait_rc==WAIT_OBJECT_0 || rc <= 32, + "WaitForSingleObject returned %d\n", wait_rc); + } + /* The child process may have changed the result file, so let profile + * functions know about it + */ + WritePrivateProfileStringA(NULL, NULL, NULL, child_file); + if (GetFileAttributesA(child_file) != INVALID_FILE_ATTRIBUTES) + { + int c; + dump_child_(file, line); + c = GetPrivateProfileIntA("Child", "Failures", -1, child_file); + if (c > 0) + winetest_add_failures(c); + okChildInt_(file, line, "ShlexecVarLE", 0); + okChildString_(file, line, "ShlexecVar", "Present", "Present"); + } -static HDDEDATA CALLBACK ddeCb(UINT uType, UINT uFmt, HCONV hConv, - HSZ hsz1, HSZ hsz2, HDDEDATA hData, - ULONG_PTR dwData1, ULONG_PTR dwData2) + if(!verb) + { + if (rc != rcEmpty && rcEmpty == SE_ERR_NOASSOC) /* NT4 */ + bad_shellexecute = 1; + okShell_(file, line)(rc == rcEmpty || + broken(rc != rcEmpty && rcEmpty == SE_ERR_NOASSOC) /* NT4 */, + "Got different return value with empty string: %lu %lu\n", rc, rcEmpty); + } + + return rc; +} +#define shell_execute(verb, filename, parameters, directory) \ + shell_execute_(__FILE__, __LINE__, verb, filename, parameters, directory) + +static INT_PTR shell_execute_ex_(const char* file, int line, + DWORD mask, LPCSTR verb, LPCSTR filename, + LPCSTR parameters, LPCSTR directory, + LPCSTR class) { - DWORD size = 0; + char smask[11]; + SHELLEXECUTEINFOA sei; + BOOL success; + INT_PTR rc; - if (winetest_debug > 2) - trace("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n", - uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2); + /* Add some flags so we can wait for the child process */ + mask |= SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE; - switch (uType) + shell_call_traced=0; + strcpy(shell_call, "ShellExecuteEx("); + sprintf(smask, "0x%x", mask); + strcat_param(shell_call, "mask", smask); + strcat_param(shell_call, "verb", verb); + strcat_param(shell_call, "file", filename); + strcat_param(shell_call, "params", parameters); + strcat_param(shell_call, "dir", directory); + strcat_param(shell_call, "class", class); + strcat(shell_call, ")"); + if (winetest_debug > 1) { - case XTYP_CONNECT: - if (!DdeCmpStringHandles(hsz1, hszTopic)) - { - size = DdeQueryStringA(ddeInst, hsz2, ddeApplication, MAX_PATH, CP_WINANSI); - ok(size < MAX_PATH, "got size %d\n", size); - assert(size < MAX_PATH); - return (HDDEDATA)TRUE; - } - return (HDDEDATA)FALSE; + trace_(file, line)("Called %s\n", shell_call); + if (*assoc_desc) + trace_(file, line)("%s\n", assoc_desc); + shell_call_traced=1; + } - case XTYP_EXECUTE: - size = DdeGetData(hData, (LPBYTE)ddeExec, MAX_PATH, 0); - ok(size < MAX_PATH, "got size %d\n", size); - assert(size < MAX_PATH); - DdeFreeDataHandle(hData); - if (post_quit_on_execute) - PostQuitMessage(0); - return (HDDEDATA)DDE_FACK; + sei.cbSize=sizeof(sei); + sei.fMask=mask; + sei.hwnd=NULL; + sei.lpVerb=verb; + sei.lpFile=filename; + sei.lpParameters=parameters; + sei.lpDirectory=directory; + sei.nShow=SW_SHOWNORMAL; + sei.hInstApp=NULL; /* Out */ + sei.lpIDList=NULL; + sei.lpClass=class; + sei.hkeyClass=NULL; + sei.dwHotKey=0; + U(sei).hIcon=NULL; + sei.hProcess=(HANDLE)0xdeadbeef; /* Out */ - default: - return NULL; + DeleteFileA(child_file); + SetLastError(0xcafebabe); + success=ShellExecuteExA(&sei); + rc=(INT_PTR)sei.hInstApp; + okShell_(file, line)((success && rc > 32) || (!success && rc <= 32), + "rc=%d and hInstApp=%ld is not allowed\n", + success, rc); + + if (rc > 32) + { + DWORD wait_rc, rc; + if (sei.hProcess!=NULL) + { + wait_rc=WaitForSingleObject(sei.hProcess, 5000); + okShell_(file, line)(wait_rc==WAIT_OBJECT_0, + "WaitForSingleObject(hProcess) returned %d\n", + wait_rc); + wait_rc = GetExitCodeProcess(sei.hProcess, &rc); + okShell_(file, line)(wait_rc, "GetExitCodeProcess() failed le=%u\n", GetLastError()); + if (!_todo_wait) + okShell_(file, line)(rc == 0, "child returned %u\n", rc); + else todo_wine + okShell_(file, line)(rc == 0, "child returned %u\n", rc); + CloseHandle(sei.hProcess); + } + wait_rc=WaitForSingleObject(hEvent, 5000); + if (!_todo_wait) + okShell_(file, line)(wait_rc==WAIT_OBJECT_0, + "WaitForSingleObject returned %d\n", wait_rc); + else todo_wine + okShell_(file, line)(wait_rc==WAIT_OBJECT_0, + "WaitForSingleObject returned %d\n", wait_rc); } -} + else + okShell_(file, line)(sei.hProcess==NULL, + "returned a process handle %p\n", sei.hProcess); -/* - * This is just to make sure the child won't run forever stuck in a GetMessage() - * loop when DDE fails for some reason. - */ -static void CALLBACK childTimeout(HWND wnd, UINT msg, UINT_PTR timer, DWORD time) -{ - trace("childTimeout called\n"); + /* The child process may have changed the result file, so let profile + * functions know about it + */ + WritePrivateProfileStringA(NULL, NULL, NULL, child_file); + if (GetFileAttributesA(child_file) != INVALID_FILE_ATTRIBUTES) + { + int c; + dump_child_(file, line); + c = GetPrivateProfileIntA("Child", "Failures", -1, child_file); + if (c > 0) + winetest_add_failures(c); + okChildInt_(file, line, "ShlexecVarLE", 0); + okChildString_(file, line, "ShlexecVar", "Present", "Present"); + } - PostQuitMessage(0); + return rc; } +#define shell_execute_ex(mask, verb, filename, parameters, directory, class) \ + shell_execute_ex_(__FILE__, __LINE__, mask, verb, filename, parameters, directory, class) -static void doChild(int argc, char** argv) + +/*** + * + * Functions to create / delete associations wrappers + * + ***/ + +static BOOL create_test_association(const char* extension) { - char *filename, longpath[MAX_PATH] = ""; - HANDLE hFile, map; - int i; - int rc; - HSZ hszApplication; - UINT_PTR timer; - HANDLE dde_ready; - MSG msg; - char *shared_block; + HKEY hkey, hkey_shell; + char class[MAX_PATH]; + LONG rc; + + sprintf(class, "shlexec%s", extension); + rc=RegCreateKeyExA(HKEY_CLASSES_ROOT, extension, 0, NULL, 0, KEY_SET_VALUE, + NULL, &hkey, NULL); + ok(rc == ERROR_SUCCESS || rc == ERROR_ACCESS_DENIED, + "could not create association %s (rc=%d)\n", class, rc); + if (rc != ERROR_SUCCESS) + return FALSE; + + rc=RegSetValueExA(hkey, NULL, 0, REG_SZ, (LPBYTE) class, strlen(class)+1); + ok(rc==ERROR_SUCCESS, "RegSetValueEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc); + CloseHandle(hkey); + + rc=RegCreateKeyExA(HKEY_CLASSES_ROOT, class, 0, NULL, 0, + KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS, NULL, &hkey, NULL); + ok(rc==ERROR_SUCCESS, "RegCreateKeyEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc); + + rc=RegCreateKeyExA(hkey, "shell", 0, NULL, 0, + KEY_CREATE_SUB_KEY, NULL, &hkey_shell, NULL); + ok(rc==ERROR_SUCCESS, "RegCreateKeyEx 'shell' failed, expected ERROR_SUCCESS, got %d\n", rc); + + CloseHandle(hkey); + CloseHandle(hkey_shell); + + return TRUE; +} - filename=argv[2]; - hFile=CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); - if (hFile == INVALID_HANDLE_VALUE) - return; +/* Based on RegDeleteTreeW from dlls/advapi32/registry.c */ +static LSTATUS myRegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey) +{ + LONG ret; + DWORD dwMaxSubkeyLen, dwMaxValueLen; + DWORD dwMaxLen, dwSize; + CHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf; + HKEY hSubKey = hKey; - /* Arguments */ - childPrintf(hFile, "[Arguments]\r\n"); - if (winetest_debug > 2) - { - trace("cmdlineA='%s'\n", GetCommandLineA()); - trace("argcA=%d\n", argc); - } - childPrintf(hFile, "cmdlineA=%s\r\n", encodeA(GetCommandLineA())); - childPrintf(hFile, "argcA=%d\r\n", argc); - for (i = 0; i < argc; i++) + if(lpszSubKey) { - if (winetest_debug > 2) - trace("argvA%d='%s'\n", i, argv[i]); - childPrintf(hFile, "argvA%d=%s\r\n", i, encodeA(argv[i])); + ret = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); + if (ret) return ret; } - GetModuleFileNameA(GetModuleHandleA(NULL), longpath, MAX_PATH); - childPrintf(hFile, "longPath=%s\r\n", encodeA(longpath)); - map = OpenFileMappingA(FILE_MAP_READ, FALSE, "winetest_shlexec_dde_map"); - if (map != NULL) + /* Get highest length for keys, values */ + ret = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, NULL, + &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL); + if (ret) goto cleanup; + + dwMaxSubkeyLen++; + dwMaxValueLen++; + dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen); + if (dwMaxLen > sizeof(szNameBuf)/sizeof(CHAR)) { - shared_block = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 4096); - CloseHandle(map); - if (shared_block[0] != '\0' || shared_block[1] != '\0') + /* Name too big: alloc a buffer for it */ + if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(CHAR)))) { - post_quit_on_execute = TRUE; - ddeInst = 0; - rc = DdeInitializeA(&ddeInst, ddeCb, CBF_SKIP_ALLNOTIFICATIONS | CBF_FAIL_ADVISES | - CBF_FAIL_POKES | CBF_FAIL_REQUESTS, 0); - ok(rc == DMLERR_NO_ERROR, "got %d\n", rc); - hszApplication = DdeCreateStringHandleA(ddeInst, shared_block, CP_WINANSI); - hszTopic = DdeCreateStringHandleA(ddeInst, shared_block + strlen(shared_block) + 1, CP_WINANSI); - assert(hszApplication && hszTopic); - assert(DdeNameService(ddeInst, hszApplication, 0, DNS_REGISTER | DNS_FILTEROFF)); + ret = ERROR_NOT_ENOUGH_MEMORY; + goto cleanup; + } + } - timer = SetTimer(NULL, 0, 2500, childTimeout); - dde_ready = OpenEventA(EVENT_MODIFY_STATE, FALSE, "winetest_shlexec_dde_ready"); - SetEvent(dde_ready); - CloseHandle(dde_ready); + /* Recursively delete all the subkeys */ + while (TRUE) + { + dwSize = dwMaxLen; + if (RegEnumKeyExA(hSubKey, 0, lpszName, &dwSize, NULL, + NULL, NULL, NULL)) break; - while (GetMessageA(&msg, NULL, 0, 0)) - DispatchMessageA(&msg); + ret = myRegDeleteTreeA(hSubKey, lpszName); + if (ret) goto cleanup; + } - Sleep(500); - KillTimer(NULL, timer); - assert(DdeNameService(ddeInst, hszApplication, 0, DNS_UNREGISTER)); - assert(DdeFreeStringHandle(ddeInst, hszTopic)); - assert(DdeFreeStringHandle(ddeInst, hszApplication)); - assert(DdeUninitialize(ddeInst)); - } - else + if (lpszSubKey) + ret = RegDeleteKeyA(hKey, lpszSubKey); + else + while (TRUE) { - dde_ready = OpenEventA(EVENT_MODIFY_STATE, FALSE, "winetest_shlexec_dde_ready"); - SetEvent(dde_ready); - CloseHandle(dde_ready); - } - - UnmapViewOfFile(shared_block); - - childPrintf(hFile, "ddeExec=%s\r\n", encodeA(ddeExec)); - } + dwSize = dwMaxLen; + if (RegEnumValueA(hKey, 0, lpszName, &dwSize, + NULL, NULL, NULL, NULL)) break; - CloseHandle(hFile); + ret = RegDeleteValueA(hKey, lpszName); + if (ret) goto cleanup; + } - init_event(filename); - SetEvent(hEvent); - CloseHandle(hEvent); +cleanup: + /* Free buffer if allocated */ + if (lpszName != szNameBuf) + HeapFree( GetProcessHeap(), 0, lpszName); + if(lpszSubKey) + RegCloseKey(hSubKey); + return ret; } -static char* getChildString(const char* sect, const char* key) +static void delete_test_association(const char* extension) { - char buf[1024]; - char* ret; + char class[MAX_PATH]; - GetPrivateProfileStringA(sect, key, "-", buf, sizeof(buf), child_file); - if (buf[0] == '\0' || (buf[0] == '-' && buf[1] == '\0')) return NULL; - assert(!(strlen(buf) & 1)); - ret = decodeA(buf); - return ret; + sprintf(class, "shlexec%s", extension); + myRegDeleteTreeA(HKEY_CLASSES_ROOT, class); + myRegDeleteTreeA(HKEY_CLASSES_ROOT, extension); } -static void dump_child(void) +static void create_test_verb_dde(const char* extension, const char* verb, + int rawcmd, const char* cmdtail, const char *ddeexec, + const char *application, const char *topic, + const char *ifexec) { - if (winetest_debug > 1) - { - char key[18]; - char* str; - int i, c; + HKEY hkey_shell, hkey_verb, hkey_cmd; + char shell[MAX_PATH]; + char* cmd; + LONG rc; - str=getChildString("Arguments", "cmdlineA"); - trace("cmdlineA='%s'\n", str); - c=GetPrivateProfileIntA("Arguments", "argcA", -1, child_file); - trace("argcA=%d\n",c); - for (i=0;i 32, "%s failed: rc=%lu\n", shell_call, rc); + okShell(rc > 32, "failed: rc=%lu\n", rc); /* if quoted, existing "drawback_file.noassoc" not prevents finding "drawback_file.noassoc foo.shlexec" on wine */ sprintf(fileA, "\"%s\\drawback_file.noassoc foo.shlexec\"", tmpdir); rc=shell_execute(NULL, fileA, NULL, NULL); - ok(rc > 32 || broken(rc == SE_ERR_FNF) /* Win95/NT4 */, - "%s failed: rc=%lu\n", shell_call, rc); + okShell(rc > 32 || broken(rc == SE_ERR_FNF) /* Win95/NT4 */, + "failed: rc=%lu\n", rc); /* error should be SE_ERR_FNF, not SE_ERR_NOASSOC */ sprintf(fileA, "\"%s\\drawback_file.noassoc\" foo.shlexec", tmpdir); rc=shell_execute(NULL, fileA, NULL, NULL); - ok(rc == SE_ERR_FNF, "%s succeeded: rc=%lu\n", shell_call, rc); + okShell(rc == SE_ERR_FNF, "returned %lu\n", rc); /* ""command"" not works on wine (and real win9x and w2k) */ sprintf(fileA, "\"\"%s\\simple.shlexec\"\"", tmpdir); rc=shell_execute(NULL, fileA, NULL, NULL); - todo_wine ok(rc > 32 || broken(rc == SE_ERR_FNF) /* Win9x/2000 */, - "%s failed: rc=%lu\n", shell_call, rc); + todo_wine okShell(rc > 32 || broken(rc == SE_ERR_FNF) /* Win9x/2000 */, + "failed: rc=%lu\n", rc); /* nonexisting "drawback_nonexist.noassoc" not prevents finding "drawback_nonexist.noassoc foo.shlexec" on wine */ sprintf(fileA, "%s\\drawback_nonexist.noassoc foo.shlexec", tmpdir); rc=shell_execute(NULL, fileA, NULL, NULL); - ok(rc > 32, "%s failed: rc=%lu\n", shell_call, rc); + okShell(rc > 32, "failed: rc=%lu\n", rc); /* is SEE_MASK_DOENVSUBST default flag? Should only be when XP emulates 9x (XP bug or real 95 or ME behavior ?) */ rc=shell_execute(NULL, "%TMPDIR%\\simple.shlexec", NULL, NULL); - todo_wine ok(rc == SE_ERR_FNF, "%s succeeded: rc=%lu\n", shell_call, rc); + todo_wine okShell(rc == SE_ERR_FNF, "returned %lu\n", rc); /* quoted */ rc=shell_execute(NULL, "\"%TMPDIR%\\simple.shlexec\"", NULL, NULL); - todo_wine ok(rc == SE_ERR_FNF, "%s succeeded: rc=%lu\n", shell_call, rc); + todo_wine okShell(rc == SE_ERR_FNF, "returned %lu\n", rc); /* test SEE_MASK_DOENVSUBST works */ rc=shell_execute_ex(SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI, NULL, "%TMPDIR%\\simple.shlexec", NULL, NULL, NULL); - ok(rc > 32, "%s failed: rc=%lu\n", shell_call, rc); + okShell(rc > 32, "failed: rc=%lu\n", rc); /* quoted lpFile does not work on real win95 and nt4 */ rc=shell_execute_ex(SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI, NULL, "\"%TMPDIR%\\simple.shlexec\"", NULL, NULL, NULL); - ok(rc > 32 || broken(rc == SE_ERR_FNF) /* Win95/NT4 */, - "%s failed: rc=%lu\n", shell_call, rc); + okShell(rc > 32 || broken(rc == SE_ERR_FNF) /* Win95/NT4 */, + "failed: rc=%lu\n", rc); } typedef struct @@ -1439,7 +1579,7 @@ /* trace("***** verb='%s' params='%s'\n", test->verb, test->params); */ rc = shell_execute_ex(SEE_MASK_DOENVSUBST, test->verb, fileA, test->params, NULL, NULL); - ok(rc > 32, "%s failed: rc=%lu\n", shell_call, rc); + okShell(rc > 32, "failed: rc=%lu\n", rc); count = 0; while (test->cmd.args[count]) @@ -1452,7 +1592,7 @@ else todo_wine okChildInt("argcA", 4 + count - 1); - cmd = getChildString("Arguments", "cmdlineA"); + cmd = getChildString("Child", "cmdlineA"); /* Our commands are such that the verb immediately precedes the * part we are interested in. */ @@ -1460,11 +1600,11 @@ if (cmd) cmd += strlen(test->verb); if (!cmd) cmd = "(null)"; if ((test->todo & 0x2) == 0) - ok(!strcmp(cmd, test->cmd.cmd) || broken(!strcmp(cmd, bad->cmd)), - "%s: the cmdline is '%s' instead of '%s'\n", shell_call, cmd, test->cmd.cmd); + okShell(!strcmp(cmd, test->cmd.cmd) || broken(!strcmp(cmd, bad->cmd)), + "the cmdline is '%s' instead of '%s'\n", cmd, test->cmd.cmd); else todo_wine - ok(!strcmp(cmd, test->cmd.cmd) || broken(!strcmp(cmd, bad->cmd)), - "%s: the cmdline is '%s' instead of '%s'\n", shell_call, cmd, test->cmd.cmd); + okShell(!strcmp(cmd, test->cmd.cmd) || broken(!strcmp(cmd, bad->cmd)), + "the cmdline is '%s' instead of '%s'\n", cmd, test->cmd.cmd); for (i = 0; i < count - 1; i++) { @@ -1489,9 +1629,9 @@ /* We need NOZONECHECKS on Win2003 to block a dialog */ rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, argv0, params, NULL, NULL); - ok(rc > 32, "%s failed: rc=%lu\n", shell_call, rc); + okShell(rc > 32, "failed: rc=%lu\n", rc); okChildInt("argcA", 4); - okChildString("argvA3", fileA); + okChildPath("argvA3", fileA); } static void test_filename(void) @@ -1544,10 +1684,9 @@ } if (rc > 32) rc=33; - ok(rc==test->rc || - broken(quotedfile && rc == SE_ERR_FNF), /* NT4 */ - "%s failed: rc=%ld err=%u\n", shell_call, - rc, GetLastError()); + okShell(rc==test->rc || + broken(quotedfile && rc == SE_ERR_FNF), /* NT4 */ + "failed: rc=%ld err=%u\n", rc, GetLastError()); if (rc == 33) { const char* verb; @@ -1589,13 +1728,11 @@ rc=33; if ((test->todo & 0x1)==0) { - ok(rc==test->rc, "%s failed: rc=%ld err=%u\n", shell_call, - rc, GetLastError()); + okShell(rc==test->rc, "failed: rc=%ld err=%u\n", rc, GetLastError()); } else todo_wine { - ok(rc==test->rc, "%s failed: rc=%ld err=%u\n", shell_call, - rc, GetLastError()); + okShell(rc==test->rc, "failed: rc=%ld err=%u\n", rc, GetLastError()); } if (rc==0) { @@ -1658,8 +1795,7 @@ */ sprintf(filename, "\"%s\\test file.shlexec\"", tmpdir); rc=shell_execute(NULL, filename, NULL, NULL); - ok(rc > 32, "%s failed: rc=%ld err=%u\n", shell_call, rc, - GetLastError()); + okShell(rc > 32, "failed: rc=%ld err=%u\n", rc, GetLastError()); okChildInt("argcA", 5); okChildString("argvA3", "Open"); sprintf(filename, "%s\\test file.shlexec", tmpdir); @@ -1770,20 +1906,20 @@ if (test->flags & URL_SUCCESS) { if ((test->todo & 0x1) == 0) - ok(rc > 32, "%s failed: bad rc=%lu\n", shell_call, rc); + okShell(rc > 32, "failed: bad rc=%lu\n", rc); else todo_wine - ok(rc > 32, "%s failed: bad rc=%lu\n", shell_call, rc); + okShell(rc > 32, "failed: bad rc=%lu\n", rc); } else { if ((test->todo & 0x1) == 0) - ok(rc == SE_ERR_FNF || rc == SE_ERR_PNF || + okShell(rc == SE_ERR_FNF || rc == SE_ERR_PNF || broken(rc == SE_ERR_ACCESSDENIED) /* win2000 */, - "%s failed: bad rc=%lu\n", shell_call, rc); + "failed: bad rc=%lu\n", rc); else todo_wine - ok(rc == SE_ERR_FNF || rc == SE_ERR_PNF || - broken(rc == SE_ERR_ACCESSDENIED) /* win2000 */, - "%s failed: bad rc=%lu\n", shell_call, rc); + okShell(rc == SE_ERR_FNF || rc == SE_ERR_PNF || + broken(rc == SE_ERR_ACCESSDENIED) /* win2000 */, + "failed: bad rc=%lu\n", rc); } if (rc == 33) { @@ -1982,7 +2118,7 @@ /* Should open through our association */ sprintf(filename, "%s\\test_shortcut_shlexec.lnk", tmpdir); rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename, NULL, NULL, NULL); - ok(rc > 32, "%s failed: rc=%lu err=%u\n", shell_call, rc, GetLastError()); + okShell(rc > 32, "failed: rc=%lu err=%u\n", rc, GetLastError()); okChildInt("argcA", 5); okChildString("argvA3", "Open"); sprintf(params, "%s\\test file.shlexec", tmpdir); @@ -1990,7 +2126,7 @@ okChildPath("argvA4", filename); todo_wait rc=shell_execute_ex(SEE_MASK_NOZONECHECKS|SEE_MASK_DOENVSUBST, NULL, "%TMPDIR%\\test_shortcut_shlexec.lnk", NULL, NULL, NULL); - ok(rc > 32, "%s failed: rc=%lu err=%u\n", shell_call, rc, GetLastError()); + okShell(rc > 32, "failed: rc=%lu err=%u\n", rc, GetLastError()); okChildInt("argcA", 5); todo_wine okChildString("argvA3", "Open"); sprintf(params, "%s\\test file.shlexec", tmpdir); @@ -2001,15 +2137,16 @@ /* Should just run our executable */ sprintf(filename, "%s\\test_shortcut_exe.lnk", tmpdir); rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename, NULL, NULL, NULL); - ok(rc > 32, "%s failed: rc=%lu err=%u\n", shell_call, rc, GetLastError()); + okShell(rc > 32, "failed: rc=%lu err=%u\n", rc, GetLastError()); okChildInt("argcA", 4); okChildString("argvA3", "Lnk"); - /* Lnk's ContextMenuHandler has priority over an explicit class */ - rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename, NULL, NULL, "shlexec.shlexec"); - ok(rc > 32, "%s failed: rc=%lu err=%u\n", shell_call, rc, GetLastError()); - okChildInt("argcA", 4); - okChildString("argvA3", "Lnk"); + /* An explicit class overrides lnk's ContextMenuHandler */ + rc=shell_execute_ex(SEE_MASK_CLASSNAME | SEE_MASK_NOZONECHECKS, NULL, filename, NULL, NULL, "shlexec.shlexec"); + okShell(rc > 32, "failed: rc=%lu err=%u\n", rc, GetLastError()); + okChildInt("argcA", 5); + okChildString("argvA3", "Open"); + okChildPath("argvA4", filename); if (dllver.dwMajorVersion>=6) { @@ -2026,8 +2163,7 @@ c++; } rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, filename, NULL, NULL, NULL); - ok(rc > 32, "%s failed: rc=%lu err=%u\n", shell_call, rc, - GetLastError()); + okShell(rc > 32, "failed: rc=%lu err=%u\n", rc, GetLastError()); okChildInt("argcA", 4); okChildString("argvA3", "Lnk"); } @@ -2045,13 +2181,11 @@ rc=33; if ((test->todo & 0x1)==0) { - ok(rc==test->rc, "%s failed: rc=%lu err=%u\n", shell_call, - rc, GetLastError()); + okShell(rc==test->rc, "failed: rc=%lu err=%u\n", rc, GetLastError()); } else todo_wine { - ok(rc==test->rc, "%s failed: rc=%lu err=%u\n", shell_call, - rc, GetLastError()); + okShell(rc==test->rc, "failed: rc=%lu err=%u\n", rc, GetLastError()); } if (rc==0) { @@ -2097,7 +2231,7 @@ /* We need NOZONECHECKS on Win2003 to block a dialog */ rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, argv0, params, NULL, NULL); - ok(rc > 32, "%s returned %lu\n", shell_call, rc); + okShell(rc > 32, "returned %lu\n", rc); okChildInt("argcA", 4); okChildString("argvA3", "Exec"); @@ -2108,7 +2242,7 @@ { rc=shell_execute(NULL, filename, params, NULL); todo_wine { - ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%lu\n", shell_call, rc); + okShell(rc==SE_ERR_NOASSOC, "returned %lu\n", rc); } } } @@ -2120,11 +2254,25 @@ /* test combining executable and parameters */ sprintf(filename, "%s shlexec \"%s\" Exec", argv0, child_file); rc = shell_execute(NULL, filename, NULL, NULL); - ok(rc == SE_ERR_FNF, "%s returned %lu\n", shell_call, rc); + okShell(rc == SE_ERR_FNF, "returned %lu\n", rc); sprintf(filename, "\"%s\" shlexec \"%s\" Exec", argv0, child_file); rc = shell_execute(NULL, filename, NULL, NULL); - ok(rc == SE_ERR_FNF, "%s returned %lu\n", shell_call, rc); + okShell(rc == SE_ERR_FNF, "returned %lu\n", rc); + + /* A verb, even if invalid, overrides the normal handling of executables */ + todo_wait rc = shell_execute_ex(SEE_MASK_FLAG_NO_UI, + "notaverb", argv0, NULL, NULL, NULL); + todo_wine okShell(rc == SE_ERR_NOASSOC, "returned %lu\n", rc); + + /* A class overrides the normal handling of executables too */ + /* FIXME SEE_MASK_FLAG_NO_UI is only needed due to Wine's bug */ + rc = shell_execute_ex(SEE_MASK_CLASSNAME | SEE_MASK_FLAG_NO_UI, + NULL, argv0, NULL, NULL, ".shlexec"); + todo_wine okShell(rc > 32, "returned %lu\n", rc); + okChildInt("argcA", 5); + todo_wine okChildString("argvA3", "Open"); + todo_wine okChildPath("argvA4", argv0); } typedef struct @@ -2143,32 +2291,34 @@ { /* Test passing and not passing command-line * argument, no DDE */ - {"", NULL, NULL, NULL, NULL, FALSE, ""}, - {"\"%1\"", NULL, NULL, NULL, NULL, TRUE, ""}, + {"", NULL, NULL, NULL, NULL, 0, ""}, + {"\"%1\"", NULL, NULL, NULL, NULL, 1, ""}, /* Test passing and not passing command-line * argument, with DDE */ - {"", "[open(\"%1\")]", "shlexec", "dde", NULL, FALSE, "[open(\"%s\")]"}, - {"\"%1\"", "[open(\"%1\")]", "shlexec", "dde", NULL, TRUE, "[open(\"%s\")]"}, + {"", "[open(\"%1\")]", "shlexec", "dde", NULL, 0, "[open(\"%s\")]"}, + {"\"%1\"", "[open(\"%1\")]", "shlexec", "dde", NULL, 1, "[open(\"%s\")]"}, /* Test unquoted %1 in command and ddeexec * (test filename has space) */ {"%1", "[open(%1)]", "shlexec", "dde", NULL, 2, "[open(%s)]", TRUE /* before vista */}, /* Test ifexec precedence over ddeexec */ - {"", "[open(\"%1\")]", "shlexec", "dde", "[ifexec(\"%1\")]", FALSE, "[ifexec(\"%s\")]"}, + {"", "[open(\"%1\")]", "shlexec", "dde", "[ifexec(\"%1\")]", 0, "[ifexec(\"%s\")]"}, /* Test default DDE topic */ - {"", "[open(\"%1\")]", "shlexec", NULL, NULL, FALSE, "[open(\"%s\")]"}, + {"", "[open(\"%1\")]", "shlexec", NULL, NULL, 0, "[open(\"%s\")]"}, /* Test default DDE application */ - {"", "[open(\"%1\")]", NULL, "dde", NULL, FALSE, "[open(\"%s\")]"}, + {"", "[open(\"%1\")]", NULL, "dde", NULL, 0, "[open(\"%s\")]"}, {NULL} }; static DWORD WINAPI hooked_WaitForInputIdle(HANDLE process, DWORD timeout) { + if (winetest_debug > 1) + trace("WaitForInputIdle() waiting for dde event\n"); return WaitForSingleObject(dde_ready_event, timeout); } @@ -2187,6 +2337,7 @@ PIMAGE_NT_HEADERS nt_headers; DWORD import_directory_rva; PIMAGE_IMPORT_DESCRIPTOR import_descriptor; + int hook_count = 0; base = (char *) GetModuleHandleA("shell32.dll"); nt_headers = (PIMAGE_NT_HEADERS)(base + ((PIMAGE_DOS_HEADER) base)->e_lfanew); @@ -2224,6 +2375,9 @@ VirtualProtect(&iat_entry->u1.Function, sizeof(ULONG_PTR), PAGE_READWRITE, &old_prot); iat_entry->u1.Function = (ULONG_PTR) new_func; VirtualProtect(&iat_entry->u1.Function, sizeof(ULONG_PTR), old_prot, &old_prot); + if (winetest_debug > 1) + trace("Hooked %s.WaitForInputIdle\n", import_module_name); + hook_count++; break; } } @@ -2235,6 +2389,7 @@ import_descriptor++; } + ok(hook_count, "Could not hook WaitForInputIdle()\n"); } static void test_dde(void) @@ -2284,7 +2439,7 @@ dde_ready_event = CreateEventA(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready"); rc = shell_execute_ex(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI, NULL, filename, NULL, NULL, NULL); CloseHandle(dde_ready_event); - ok(32 < rc, "%s failed: rc=%lu err=%u\n", shell_call, rc, GetLastError()); + okShell(32 < rc, "failed: rc=%lu err=%u\n", rc, GetLastError()); if (32 < rc) { @@ -2298,6 +2453,7 @@ sprintf(params, test->expectedDdeExec, filename); okChildPath("ddeExec", params); } + reset_association_description(); delete_test_association(".sde"); test++; @@ -2449,13 +2605,13 @@ if ((test->todo & 0x1)==0) { - ok(rc==test->rc[which], "%s failed: rc=%lu err=%u\n", shell_call, - rc, GetLastError()); + okShell(rc==test->rc[which], "failed: rc=%lu err=%u\n", + rc, GetLastError()); } else todo_wine { - ok(rc==test->rc[which], "%s failed: rc=%lu err=%u\n", shell_call, - rc, GetLastError()); + okShell(rc==test->rc[which], "failed: rc=%lu err=%u\n", + rc, GetLastError()); } if (rc == 33) { @@ -2472,6 +2628,7 @@ test->expectedDdeApplication[which], ddeApplication); } } + reset_association_description(); delete_test_association(".sde"); test++; @@ -2606,6 +2763,9 @@ create_test_verb(".shlexec", "QuotedLowerL", 0, "QuotedLowerL \"%l\""); create_test_verb(".shlexec", "UpperL", 0, "UpperL %L"); create_test_verb(".shlexec", "QuotedUpperL", 0, "QuotedUpperL \"%L\""); + + /* Set an environment variable to see if it is inherited */ + SetEnvironmentVariableA("ShlexecVar", "Present"); } static void cleanup_test(void) @@ -2650,7 +2810,7 @@ SetCurrentDirectoryA(tmpdir); rc=shell_execute_ex(SEE_MASK_NOZONECHECKS|SEE_MASK_FLAG_NO_UI, NULL, "test2.exe", params, NULL, NULL); - ok(rc > 32, "%s returned %lu\n", shell_call, rc); + okShell(rc > 32, "returned %lu\n", rc); okChildInt("argcA", 4); okChildString("argvA3", "Exec"); todo_wine okChildPath("longPath", path); @@ -2658,12 +2818,12 @@ rc=shell_execute_ex(SEE_MASK_NOZONECHECKS|SEE_MASK_FLAG_NO_UI, NULL, "test2.exe", params, NULL, NULL); - ok(rc == SE_ERR_FNF, "%s returned %lu\n", shell_call, rc); + okShell(rc == SE_ERR_FNF, "returned %lu\n", rc); /* Explicitly specify the directory to use */ rc=shell_execute_ex(SEE_MASK_NOZONECHECKS|SEE_MASK_FLAG_NO_UI, NULL, "test2.exe", params, tmpdir, NULL); - ok(rc > 32, "%s returned %lu\n", shell_call, rc); + okShell(rc > 32, "returned %lu\n", rc); okChildInt("argcA", 4); okChildString("argvA3", "Exec"); todo_wine okChildPath("longPath", path); @@ -2671,11 +2831,11 @@ /* Specify it through an environment variable */ rc=shell_execute_ex(SEE_MASK_NOZONECHECKS|SEE_MASK_FLAG_NO_UI, NULL, "test2.exe", params, "%TMPDIR%", NULL); - todo_wine ok(rc == SE_ERR_FNF, "%s returned %lu\n", shell_call, rc); + todo_wine okShell(rc == SE_ERR_FNF, "returned %lu\n", rc); rc=shell_execute_ex(SEE_MASK_DOENVSUBST|SEE_MASK_NOZONECHECKS|SEE_MASK_FLAG_NO_UI, NULL, "test2.exe", params, "%TMPDIR%", NULL); - ok(rc > 32, "%s returned %lu\n", shell_call, rc); + okShell(rc > 32, "returned %lu\n", rc); okChildInt("argcA", 4); okChildString("argvA3", "Exec"); todo_wine okChildPath("longPath", path); @@ -2684,7 +2844,7 @@ sprintf(dirpath, "%s:%s", curdir, tmpdir); rc=shell_execute_ex(SEE_MASK_NOZONECHECKS|SEE_MASK_FLAG_NO_UI, NULL, "test2.exe", params, dirpath, NULL); - ok(rc == SE_ERR_FNF, "%s returned %lu\n", shell_call, rc); + okShell(rc == SE_ERR_FNF, "returned %lu\n", rc); } START_TEST(shlexec) @@ -2694,7 +2854,8 @@ if (myARGC >= 3) { doChild(myARGC, myARGV); - exit(0); + /* Skip the tests/failures trace for child processes */ + ExitProcess(winetest_get_failures()); } init_test(); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/shell32/tests/shlfolder.c wine-staging-1.9.3~ubuntu12.04.1/dlls/shell32/tests/shlfolder.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/shell32/tests/shlfolder.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/shell32/tests/shlfolder.c 2016-02-08 19:32:34.000000000 +0000 @@ -388,6 +388,14 @@ SFGAO_CAPABILITYMASK | SFGAO_FILESYSTEM, SFGAO_CAPABILITYMASK | SFGAO_FILESYSTEM, }; + static const ULONG full_attrs[5] = + { + SFGAO_CAPABILITYMASK | SFGAO_STORAGE | SFGAO_STORAGEANCESTOR | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR, + SFGAO_CAPABILITYMASK | SFGAO_STORAGE | SFGAO_STORAGEANCESTOR | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR, + SFGAO_CAPABILITYMASK | SFGAO_STREAM | SFGAO_FILESYSTEM, + SFGAO_CAPABILITYMASK | SFGAO_STREAM | SFGAO_FILESYSTEM, + SFGAO_CAPABILITYMASK | SFGAO_STREAM | SFGAO_FILESYSTEM, + }; hr = IShellFolder_EnumObjects(iFolder, NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &iEnumList); ok(hr == S_OK, "EnumObjects failed %08x\n", hr); @@ -440,6 +448,11 @@ ok(flags == attrs[i] || flags == (attrs[i] & ~SFGAO_FILESYSANCESTOR), /* Win9x, NT4 */ "GetAttributesOf[%i] got %08x, expected %08x\n", i, flags, attrs[i]); + + flags = ~0u; + hr = IShellFolder_GetAttributesOf(iFolder, 1, (LPCITEMIDLIST*)(idlArr + i), &flags); + ok(hr == S_OK, "GetAttributesOf returns %08x\n", hr); + ok((flags & ~SFGAO_HASSUBFOLDER) == full_attrs[i], "%d: got %08x expected %08x\n", i, flags, full_attrs[i]); } for (i=0;i<5;i++) @@ -1889,14 +1902,14 @@ if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE; hr = pSHGetFolderPathA( 0, CSIDL_PROGRAM_FILES, 0, SHGFP_TYPE_CURRENT, path ); - ok( !hr, "SHGetFolderPathA failed %x\n", hr ); + ok( hr == S_OK, "SHGetFolderPathA failed %x\n", hr ); hr = pSHGetFolderPathA( 0, CSIDL_PROGRAM_FILESX86, 0, SHGFP_TYPE_CURRENT, path_x86 ); if (hr == E_FAIL) { win_skip( "Program Files (x86) not supported\n" ); return; } - ok( !hr, "SHGetFolderPathA failed %x\n", hr ); + ok( hr == S_OK, "SHGetFolderPathA failed %x\n", hr ); if (is_win64) { ok( lstrcmpiA( path, path_x86 ), "paths are identical '%s'\n", path ); @@ -1924,14 +1937,14 @@ } hr = pSHGetFolderPathA( 0, CSIDL_PROGRAM_FILES_COMMON, 0, SHGFP_TYPE_CURRENT, path ); - ok( !hr, "SHGetFolderPathA failed %x\n", hr ); + ok( hr == S_OK, "SHGetFolderPathA failed %x\n", hr ); hr = pSHGetFolderPathA( 0, CSIDL_PROGRAM_FILES_COMMONX86, 0, SHGFP_TYPE_CURRENT, path_x86 ); if (hr == E_FAIL) { win_skip( "Common Files (x86) not supported\n" ); return; } - ok( !hr, "SHGetFolderPathA failed %x\n", hr ); + ok( hr == S_OK, "SHGetFolderPathA failed %x\n", hr ); if (is_win64) { ok( lstrcmpiA( path, path_x86 ), "paths are identical '%s'\n", path ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/shlwapi/ordinal.c wine-staging-1.9.3~ubuntu12.04.1/dlls/shlwapi/ordinal.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/shlwapi/ordinal.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/shlwapi/ordinal.c 2016-02-08 19:32:34.000000000 +0000 @@ -4045,7 +4045,7 @@ case OS_SMALLBUSINESSSERVER: ISOS_RETURN(platform == VER_PLATFORM_WIN32_NT) case OS_TABLETPC: - FIXME("(OS_TABLEPC) What should we return here?\n"); + FIXME("(OS_TABLETPC) What should we return here?\n"); return FALSE; case OS_SERVERADMINUI: FIXME("(OS_SERVERADMINUI) What should we return here?\n"); @@ -4842,7 +4842,7 @@ * NOTES * Call should free returned descriptor with LocalFree */ -PSECURITY_DESCRIPTOR WINAPI GetShellSecurityDescriptor(PSHELL_USER_PERMISSION *apUserPerm, int cUserPerm) +PSECURITY_DESCRIPTOR WINAPI GetShellSecurityDescriptor(const PSHELL_USER_PERMISSION *apUserPerm, int cUserPerm) { PSID *sidlist; PSID cur_user = NULL; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/shlwapi/shlwapi_main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/shlwapi/shlwapi_main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/shlwapi/shlwapi_main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/shlwapi/shlwapi_main.c 2016-02-08 19:32:34.000000000 +0000 @@ -94,6 +94,9 @@ TRACE("(%p)\n",pdvi); + if (!pdvi) + return E_INVALIDARG; + switch (pdvi2->info1.cbSize) { case sizeof(DLLVERSIONINFO2): @@ -107,7 +110,7 @@ pdvi2->info1.dwPlatformID = DLLVER_PLATFORM_WINDOWS; return S_OK; } - if (pdvi) - WARN("pdvi->cbSize = %d, unhandled\n", pdvi2->info1.cbSize); + + WARN("pdvi->cbSize = %d, unhandled\n", pdvi2->info1.cbSize); return E_INVALIDARG; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/shlwapi/stopwatch.c wine-staging-1.9.3~ubuntu12.04.1/dlls/shlwapi/stopwatch.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/shlwapi/stopwatch.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/shlwapi/stopwatch.c 2016-02-08 19:32:34.000000000 +0000 @@ -190,16 +190,16 @@ */ DWORD WINAPI GetPerfTime(void) { - static LONG64 iCounterFreq = 0; + static LARGE_INTEGER iCounterFreq = { {0} }; LARGE_INTEGER iCounter; TRACE("()\n"); - if (!iCounterFreq) - QueryPerformanceFrequency((LARGE_INTEGER*)&iCounterFreq); + if (!iCounterFreq.QuadPart) + QueryPerformanceFrequency(&iCounterFreq); QueryPerformanceCounter(&iCounter); - iCounter.QuadPart = iCounter.QuadPart * 1000 / iCounterFreq; + iCounter.QuadPart = iCounter.QuadPart * 1000 / iCounterFreq.QuadPart; return iCounter.u.LowPart; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/shlwapi/tests/ordinal.c wine-staging-1.9.3~ubuntu12.04.1/dlls/shlwapi/tests/ordinal.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/shlwapi/tests/ordinal.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/shlwapi/tests/ordinal.c 2016-02-08 19:32:34.000000000 +0000 @@ -70,6 +70,24 @@ static HRESULT (WINAPI *pSKAllocValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD*, void**, DWORD*); static HWND (WINAPI *pSHSetParentHwnd)(HWND, HWND); static HRESULT (WINAPI *pIUnknown_GetClassID)(IUnknown*, CLSID*); +static HRESULT (WINAPI *pDllGetVersion)(DLLVERSIONINFO2*); + +typedef struct SHELL_USER_SID { + SID_IDENTIFIER_AUTHORITY sidAuthority; + DWORD dwUserGroupID; + DWORD dwUserID; +} SHELL_USER_SID, *PSHELL_USER_SID; +typedef struct SHELL_USER_PERMISSION { + + SHELL_USER_SID susID; + DWORD dwAccessType; + BOOL fInherit; + DWORD dwAccessMask; + DWORD dwInheritMask; + DWORD dwInheritAccessMask; +} SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION; + +static SECURITY_DESCRIPTOR* (WINAPI *pGetShellSecurityDescriptor)(const SHELL_USER_PERMISSION**,int); static HMODULE hmlang; static HRESULT (WINAPI *pLcidToRfc1766A)(LCID, LPSTR, INT); @@ -675,40 +693,23 @@ HeapFree(GetProcessHeap(), 0, mem); } - -typedef struct SHELL_USER_SID { - SID_IDENTIFIER_AUTHORITY sidAuthority; - DWORD dwUserGroupID; - DWORD dwUserID; -} SHELL_USER_SID, *PSHELL_USER_SID; -typedef struct SHELL_USER_PERMISSION { - SHELL_USER_SID susID; - DWORD dwAccessType; - BOOL fInherit; - DWORD dwAccessMask; - DWORD dwInheritMask; - DWORD dwInheritAccessMask; -} SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION; static void test_GetShellSecurityDescriptor(void) { - SHELL_USER_PERMISSION supCurrentUserFull = { + static const SHELL_USER_PERMISSION supCurrentUserFull = { { {SECURITY_NULL_SID_AUTHORITY}, 0, 0 }, ACCESS_ALLOWED_ACE_TYPE, FALSE, GENERIC_ALL, 0, 0 }; #define MY_INHERITANCE 0xBE /* invalid value to proof behavior */ - SHELL_USER_PERMISSION supEveryoneDenied = { + static const SHELL_USER_PERMISSION supEveryoneDenied = { { {SECURITY_WORLD_SID_AUTHORITY}, SECURITY_WORLD_RID, 0 }, ACCESS_DENIED_ACE_TYPE, TRUE, GENERIC_WRITE, MY_INHERITANCE | 0xDEADBA00, GENERIC_READ }; - PSHELL_USER_PERMISSION rgsup[2] = { + const SHELL_USER_PERMISSION* rgsup[2] = { &supCurrentUserFull, &supEveryoneDenied, }; SECURITY_DESCRIPTOR* psd; - SECURITY_DESCRIPTOR* (WINAPI*pGetShellSecurityDescriptor)(PSHELL_USER_PERMISSION*,int); void *pChrCmpIW = GetProcAddress(hShlwapi, "ChrCmpIW"); - pGetShellSecurityDescriptor=(void*)GetProcAddress(hShlwapi,(char*)475); - if(!pGetShellSecurityDescriptor) { win_skip("GetShellSecurityDescriptor not available\n"); @@ -3063,6 +3064,7 @@ MAKEFUNC(SHFormatDateTimeA, 353); MAKEFUNC(SHFormatDateTimeW, 354); MAKEFUNC(SHIShellFolder_EnumObjects, 404); + MAKEFUNC(GetShellSecurityDescriptor, 475); MAKEFUNC(SHGetObjectCompatFlags, 476); MAKEFUNC(IUnknown_QueryServiceExec, 484); MAKEFUNC(SHGetShellKey, 491); @@ -3073,6 +3075,8 @@ MAKEFUNC(SKDeleteValueW, 518); MAKEFUNC(SKAllocValueW, 519); #undef MAKEFUNC + + pDllGetVersion = (void*)GetProcAddress(hShlwapi, "DllGetVersion"); } static void test_SHSetParentHwnd(void) @@ -3246,6 +3250,14 @@ "got wrong clsid %s\n", wine_dbgstr_guid(&clsid)); } +static void test_DllGetVersion(void) +{ + HRESULT hr; + + hr = pDllGetVersion(NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); +} + START_TEST(ordinal) { char **argv; @@ -3301,6 +3313,7 @@ test_SHGetShellKey(); test_SHSetParentHwnd(); test_IUnknown_GetClassID(); + test_DllGetVersion(); FreeLibrary(hshell32); FreeLibrary(hmlang); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/shlwapi/tests/url.c wine-staging-1.9.3~ubuntu12.04.1/dlls/shlwapi/tests/url.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/shlwapi/tests/url.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/shlwapi/tests/url.c 2016-02-08 19:32:34.000000000 +0000 @@ -302,6 +302,45 @@ {"ftp\x1f\1end/", 0, 0, S_OK, "ftp%1F%01end/"} }; +typedef struct _TEST_URL_ESCAPEW { + const WCHAR url[INTERNET_MAX_URL_LENGTH]; + DWORD flags; + HRESULT expectret; + const WCHAR expecturl[INTERNET_MAX_URL_LENGTH]; + const WCHAR win7url[INTERNET_MAX_URL_LENGTH]; /* <= Win7 */ + const WCHAR vistaurl[INTERNET_MAX_URL_LENGTH]; /* <= Vista/2k8 */ +} TEST_URL_ESCAPEW; + +static const TEST_URL_ESCAPEW TEST_ESCAPEW[] = { + {{' ','<','>','"',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','2','0','%','3','C','%','3','E','%','2','2',0}}, + {{'{','}','|','\\',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','7','B','%','7','D','%','7','C','%','5','C',0}}, + {{'^',']','[','`',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','5','E','%','5','D','%','5','B','%','6','0',0}}, + {{'&','/','?','#',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','2','6','/','?','#',0}}, + {{'M','a','s','s',0}, URL_ESCAPE_AS_UTF8, S_OK, {'M','a','s','s',0}}, + + /* broken < Win8/10 */ + + {{'M','a',0xdf,0}, URL_ESCAPE_AS_UTF8, S_OK, {'M','a','%','C','3','%','9','F',0}, + {'M','a','%','D','F',0}}, + /* 0x2070E */ + {{0xd841,0xdf0e,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','F','0','%','A','0','%','9','C','%','8','E',0}, + {'%','E','F','%','B','F','%','B','D','%','E','F','%','B','F','%','B','D',0}, + {0xd841,0xdf0e,0}}, + /* 0x27A3E */ + {{0xd85e,0xde3e,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','F','0','%','A','7','%','A','8','%','B','E',0}, + {'%','E','F','%','B','F','%','B','D','%','E','F','%','B','F','%','B','D',0}, + {0xd85e,0xde3e,0}}, + + {{0xd85e,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','D',0}, + {0xd85e,0}}, + {{0xd85e,0x41}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','D','A',0}, + {0xd85e,'A',0}}, + {{0xdc00,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','D',0}, + {0xdc00,0}}, + {{0xffff,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','F',0}, + {0xffff,0}}, +}; + /* ################ */ typedef struct _TEST_URL_COMBINE { @@ -862,6 +901,15 @@ ok(size == 34, "got %d, expected %d\n", size, 34); ok(empty_string[0] == 127, "String has changed, empty_string[0] = %d\n", empty_string[0]); + size = 1; + empty_string[0] = 127; + ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, &size, URL_ESCAPE_AS_UTF8); + ok(ret == E_NOTIMPL || broken(ret == E_POINTER), /* < Win7/Win2k8 */ + "got %x, expected %x\n", ret, E_NOTIMPL); + ok(size == 1 || broken(size == 34), /* < Win7/Win2k8 */ + "got %d, expected %d\n", size, 1); + ok(empty_string[0] == 127, "String has changed, empty_string[0] = %d\n", empty_string[0]); + for(i=0; i= 0x80)) + return TRUE; + if (ch <= 31 || (ch >= 127 && ch <= 255) ) return TRUE; @@ -1069,8 +1074,8 @@ LPCWSTR src; DWORD needed = 0, ret; BOOL stop_escaping = FALSE; - WCHAR next[5], *dst, *dst_ptr; - INT len; + WCHAR next[12], *dst, *dst_ptr; + INT i, len; PARSEDURLW parsed_url; DWORD int_flags; DWORD slashes = 0; @@ -1085,7 +1090,8 @@ if(dwFlags & ~(URL_ESCAPE_SPACES_ONLY | URL_ESCAPE_SEGMENT_ONLY | URL_DONT_ESCAPE_EXTRA_INFO | - URL_ESCAPE_PERCENT)) + URL_ESCAPE_PERCENT | + URL_ESCAPE_AS_UTF8)) FIXME("Unimplemented flags: %08x\n", dwFlags); dst_ptr = dst = HeapAlloc(GetProcessHeap(), 0, *pcchEscaped*sizeof(WCHAR)); @@ -1188,10 +1194,40 @@ if(cur == '\\' && (int_flags & WINE_URL_BASH_AS_SLASH) && !stop_escaping) cur = '/'; if(URL_NeedEscapeW(cur, dwFlags, int_flags) && stop_escaping == FALSE) { - next[0] = '%'; - next[1] = hexDigits[(cur >> 4) & 0xf]; - next[2] = hexDigits[cur & 0xf]; - len = 3; + if(dwFlags & URL_ESCAPE_AS_UTF8) { + char utf[16]; + + if ((cur >= 0xd800 && cur <= 0xdfff) && + (src[1] >= 0xdc00 && src[1] <= 0xdfff)) + { + WCHAR sur[2]; + + sur[0] = cur; + sur[1] = *++src; + len = wine_utf8_wcstombs(WC_ERR_INVALID_CHARS, sur, 2, utf, sizeof(utf)); + } + else + len = wine_utf8_wcstombs(WC_ERR_INVALID_CHARS, &cur, 1, utf, sizeof(utf)); + + if(len < 0) { + utf[0] = 0xef; + utf[1] = 0xbf; + utf[2] = 0xbd; + len = 3; + } + + for(i = 0; i < len; i++) { + next[i*3+0] = '%'; + next[i*3+1] = hexDigits[(utf[i] >> 4) & 0xf]; + next[i*3+2] = hexDigits[utf[i] & 0xf]; + } + len *= 3; + } else { + next[0] = '%'; + next[1] = hexDigits[(cur >> 4) & 0xf]; + next[2] = hexDigits[cur & 0xf]; + len = 3; + } } else { next[0] = cur; len = 1; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/strmbase/transform.c wine-staging-1.9.3~ubuntu12.04.1/dlls/strmbase/transform.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/strmbase/transform.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/strmbase/transform.c 2016-02-08 19:32:34.000000000 +0000 @@ -365,6 +365,8 @@ This->filter.state = State_Stopped; if (This->pFuncsTable->pfnStopStreaming) hr = This->pFuncsTable->pfnStopStreaming(This); + if (SUCCEEDED(hr)) + hr = BaseOutputPinImpl_Inactive(impl_BaseOutputPin_from_IPin(This->ppPins[1])); } LeaveCriticalSection(&This->csReceive); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/ucrtbase/ucrtbase.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/ucrtbase/ucrtbase.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/ucrtbase/ucrtbase.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/ucrtbase/ucrtbase.spec 2016-02-08 19:32:34.000000000 +0000 @@ -43,7 +43,7 @@ @ cdecl _Strftime(str long str ptr ptr) @ cdecl _W_Getdays() @ cdecl _W_Getmonths() -@ stub _W_Gettnames +@ cdecl _W_Gettnames() @ stub _Wcsftime @ cdecl __AdjustPointer(ptr ptr) @ stub __BuildCatchObject @@ -242,7 +242,7 @@ @ cdecl _create_locale(long str) MSVCRT__create_locale @ stub _crt_at_quick_exit @ cdecl _crt_atexit(ptr) MSVCRT__crt_atexit -@ stub _crt_debugger_hook +@ cdecl _crt_debugger_hook(long) MSVCRT__crt_debugger_hook @ cdecl _ctime32(ptr) MSVCRT__ctime32 @ cdecl _ctime32_s(str long ptr) MSVCRT__ctime32_s @ cdecl _ctime64(ptr) MSVCRT__ctime64 @@ -255,7 +255,7 @@ @ cdecl _difftime64(long long) MSVCRT__difftime64 @ stub _dlog @ stub _dnorm -@ stub _dpcomp +@ cdecl _dpcomp(double double) MSVCR120__dpcomp @ stub _dpoly @ stub _dscale @ cdecl _dsign(double) MSVCR120__dsign @@ -296,7 +296,7 @@ @ stub _fdlog @ stub _fdnorm @ cdecl _fdopen(long str) MSVCRT__fdopen -@ stub _fdpcomp +@ cdecl _fdpcomp(float float) MSVCR120__fdpcomp @ stub _fdpoly @ stub _fdscale @ cdecl _fdsign(float) MSVCR120__fdsign @@ -534,7 +534,7 @@ @ cdecl _ldclass(double) MSVCR120__ldclass @ stub _ldexp @ stub _ldlog -@ stub _ldpcomp +@ cdecl _ldpcomp(double double) MSVCR120__dpcomp @ stub _ldpoly @ stub _ldscale @ cdecl _ldsign(double) MSVCR120__dsign @@ -623,7 +623,7 @@ @ stub _mbscspn_l @ cdecl _mbsdec(ptr ptr) @ stub _mbsdec_l -@ stub _mbsdup +@ stub _mbsdup(str) @ cdecl _mbsicmp(str str) @ stub _mbsicmp_l @ cdecl _mbsicoll(str str) @@ -1876,7 +1876,7 @@ @ cdecl _searchenv_s(str str ptr long) MSVCRT__searchenv_s @ cdecl -arch=i386,x86_64,arm _seh_filter_dll(long ptr) __CppXcptFilter @ cdecl _seh_filter_exe(long ptr) _XcptFilter -@ stub _set_FMA3_enable +@ cdecl -arch=win64 _set_FMA3_enable(long) MSVCRT__set_FMA3_enable @ stdcall -arch=i386 _seh_longjmp_unwind4(ptr) @ stdcall -arch=i386 _seh_longjmp_unwind(ptr) @ cdecl -arch=i386 _set_SSE2_enable(long) MSVCRT__set_SSE2_enable @@ -2057,9 +2057,9 @@ @ cdecl _wcsupr_s_l(wstr long ptr) MSVCRT__wcsupr_s_l @ cdecl _wcsxfrm_l(ptr wstr long ptr) MSVCRT__wcsxfrm_l @ cdecl _wctime32(ptr) MSVCRT__wctime32 -@ stub _wctime32_s +@ cdecl _wctime32_s(ptr long ptr) MSVCRT__wctime32_s @ cdecl _wctime64(ptr) MSVCRT__wctime64 -@ stub _wctime64_s +@ cdecl _wctime64_s(ptr long ptr) MSVCRT__wctime64_s @ cdecl _wctomb_l(ptr long ptr) MSVCRT__wctomb_l @ cdecl _wctomb_s_l(ptr ptr long long ptr) MSVCRT__wctomb_s_l @ stub _wctype @@ -2310,9 +2310,9 @@ @ cdecl fmax(double double) MSVCR120_fmax @ cdecl fmaxf(float float) MSVCR120_fmaxf @ cdecl fmaxl(double double) MSVCR120_fmax -@ stub fmin -@ stub fminf -@ stub fminl +@ cdecl fmin(double double) MSVCR120_fmin +@ cdecl fminf(float float) MSVCR120_fminf +@ cdecl fminl(double double) MSVCR120_fmin @ cdecl fmod(double double) MSVCRT_fmod @ cdecl -arch=arm,x86_64 fmodf(float float) MSVCRT_fmodf @ cdecl fopen(str str) MSVCRT_fopen @@ -2434,9 +2434,9 @@ @ stub nearbyint @ stub nearbyintf @ stub nearbyintl -@ stub nextafter -@ stub nextafterf -@ stub nextafterl +@ cdecl nextafter(double double) MSVCRT__nextafter +@ cdecl nextafterf(float float) MSVCRT__nextafterf +@ cdecl nextafterl(double double) MSVCRT__nextafter @ stub nexttoward @ stub nexttowardf @ stub nexttowardl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/button.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/button.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/button.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/button.c 2016-02-08 19:32:34.000000000 +0000 @@ -364,6 +364,7 @@ case WM_CAPTURECHANGED: TRACE("WM_CAPTURECHANGED %p\n", hWnd); + if (hWnd == (HWND)lParam) break; state = get_button_state( hWnd ); if (state & BUTTON_BTNPRESSED) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/caret.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/caret.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/caret.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/caret.c 2016-02-08 19:32:34.000000000 +0000 @@ -86,7 +86,7 @@ req->x = 0; req->y = 0; req->hide = 0; - req->state = -1; /* toggle current state */ + req->state = CARET_STATE_TOGGLE; if ((ret = !wine_server_call( req ))) { hwnd = wine_server_ptr_handle( reply->full_handle ); @@ -256,7 +256,7 @@ req->x = x; req->y = y; req->hide = 0; - req->state = 1; + req->state = CARET_STATE_ON_IF_MOVED; if ((ret = !wine_server_call_err( req ))) { hwnd = wine_server_ptr_handle( reply->full_handle ); @@ -300,7 +300,7 @@ req->x = 0; req->y = 0; req->hide = 1; - req->state = 0; + req->state = CARET_STATE_OFF; if ((ret = !wine_server_call_err( req ))) { hwnd = wine_server_ptr_handle( reply->full_handle ); @@ -339,7 +339,7 @@ req->x = 0; req->y = 0; req->hide = -1; - req->state = 1; + req->state = CARET_STATE_ON; if ((ret = !wine_server_call_err( req ))) { hwnd = wine_server_ptr_handle( reply->full_handle ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/dde_client.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/dde_client.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/dde_client.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/dde_client.c 2016-02-08 19:32:34.000000000 +0000 @@ -778,7 +778,7 @@ GlobalDeleteAtom(uiHi); if (ack) *ack = uiLo; - GlobalFree(pXAct->hMem); + pXAct->hMem = GlobalFree(pXAct->hMem); pXAct->hDdeData = (HDDEDATA)TRUE; return TRUE; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/dialog.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/dialog.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/dialog.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/dialog.c 2016-02-08 19:32:34.000000000 +0000 @@ -1174,7 +1174,7 @@ */ BOOL WINAPI IsDialogMessageW( HWND hwndDlg, LPMSG msg ) { - INT dlgCode = 0; + INT dlgCode; if (CallMsgFilterW( msg, MSGF_DIALOGBOX )) return TRUE; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/input.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/input.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/input.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/input.c 2016-02-08 19:32:34.000000000 +0000 @@ -108,7 +108,7 @@ { USER_Driver->pSetCapture( hwnd, gui_flags ); - if (previous && previous != hwnd) + if (previous) SendMessageW( previous, WM_CAPTURECHANGED, 0, (LPARAM)hwnd ); if (prev_ret) *prev_ret = previous; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/message.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/message.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/message.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/message.c 2016-02-08 19:32:34.000000000 +0000 @@ -422,9 +422,10 @@ }; /* check whether a given message type includes pointers */ -static inline BOOL is_pointer_message( UINT message ) +static inline BOOL is_pointer_message( UINT message, WPARAM wparam ) { if (message >= 8*sizeof(message_pointer_flags)) return FALSE; + if (message == WM_DEVICECHANGE && !(wparam & 0x8000)) return FALSE; return (message_pointer_flags[message / 32] & SET(message)) != 0; } @@ -2488,7 +2489,7 @@ INT hittest; EVENTMSG event; GUITHREADINFO info; - MOUSEHOOKSTRUCT hook; + MOUSEHOOKSTRUCTEX hook; BOOL eatMsg; /* find the window to dispatch this mouse message to */ @@ -2584,17 +2585,19 @@ /* message is accepted now (but may still get dropped) */ - hook.pt = msg->pt; - hook.hwnd = msg->hwnd; - hook.wHitTestCode = hittest; - hook.dwExtraInfo = extra_info; + hook.s.pt = msg->pt; + hook.s.hwnd = msg->hwnd; + hook.s.wHitTestCode = hittest; + hook.s.dwExtraInfo = extra_info; + hook.mouseData = msg->wParam; if (HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE, message, (LPARAM)&hook, TRUE )) { - hook.pt = msg->pt; - hook.hwnd = msg->hwnd; - hook.wHitTestCode = hittest; - hook.dwExtraInfo = extra_info; + hook.s.pt = msg->pt; + hook.s.hwnd = msg->hwnd; + hook.s.wHitTestCode = hittest; + hook.s.dwExtraInfo = extra_info; + hook.mouseData = msg->wParam; HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook, TRUE ); accept_hardware_message( hw_id, TRUE ); return FALSE; @@ -3490,7 +3493,7 @@ { struct send_message_info info; - if (is_pointer_message(msg)) + if (is_pointer_message( msg, wparam )) { SetLastError( ERROR_MESSAGE_SYNC_ONLY ); return FALSE; @@ -3515,7 +3518,7 @@ { struct send_message_info info; - if (is_pointer_message(msg)) + if (is_pointer_message( msg, wparam )) { SetLastError( ERROR_MESSAGE_SYNC_ONLY ); return FALSE; @@ -3540,7 +3543,7 @@ { struct send_message_info info; - if (is_pointer_message(msg)) + if (is_pointer_message( msg, wparam )) { SetLastError( ERROR_MESSAGE_SYNC_ONLY ); return FALSE; @@ -3568,7 +3571,7 @@ { struct send_message_info info; - if (is_pointer_message(msg)) + if (is_pointer_message( msg, wparam )) { SetLastError( ERROR_MESSAGE_SYNC_ONLY ); return FALSE; @@ -3638,7 +3641,7 @@ { struct send_message_info info; - if (is_pointer_message( msg )) + if (is_pointer_message( msg, wparam )) { SetLastError( ERROR_MESSAGE_SYNC_ONLY ); return FALSE; @@ -3687,7 +3690,7 @@ { struct send_message_info info; - if (is_pointer_message( msg )) + if (is_pointer_message( msg, wparam )) { SetLastError( ERROR_MESSAGE_SYNC_ONLY ); return FALSE; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/scroll.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/scroll.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/scroll.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/scroll.c 2016-02-08 19:32:34.000000000 +0000 @@ -1096,7 +1096,6 @@ void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt ) { MSG msg; - INT xoffset = 0, yoffset = 0; if (scrollbar != SB_CTL) { @@ -1117,8 +1116,8 @@ msg.message == WM_MOUSEMOVE || (msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER)) { - pt.x = (short)LOWORD(msg.lParam) + xoffset; - pt.y = (short)HIWORD(msg.lParam) + yoffset; + pt.x = (short)LOWORD(msg.lParam); + pt.y = (short)HIWORD(msg.lParam); SCROLL_HandleScrollEvent( hwnd, scrollbar, msg.message, pt ); } else diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/tests/combo.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/tests/combo.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/tests/combo.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/tests/combo.c 2016-02-08 19:32:34.000000000 +0000 @@ -17,6 +17,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include #include @@ -476,6 +477,8 @@ /* Now what is the selection - still empty */ SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end); + ok(start==0, "Unexpected start position for selection %d\n", start); + ok(end==0, "Unexpected end position for selection %d\n", end); len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0); ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len)); ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len)); @@ -483,6 +486,8 @@ /* Give it focus, and it gets selected */ SendMessageA(hCombo, WM_SETFOCUS, 0, (LPARAM)hEdit); SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end); + ok(start==0, "Unexpected start position for selection %d\n", start); + ok(end==6, "Unexpected end position for selection %d\n", end); len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0); ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len)); ok(HIWORD(len)==6, "Unexpected end position for selection %d\n", HIWORD(len)); @@ -523,6 +528,8 @@ /* Now what is the selection */ SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end); + ok(start==0, "Unexpected start position for selection %d\n", start); + ok(end==6, "Unexpected end position for selection %d\n", end); len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0); ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len)); ok(HIWORD(len)==6, "Unexpected end position for selection %d\n", HIWORD(len)); @@ -537,6 +544,107 @@ DestroyWindow(hCombo); } +static WNDPROC edit_window_proc; +static long setsel_start = 1, setsel_end = 1; +static HWND hCBN_SetFocus, hCBN_KillFocus; + +static LRESULT CALLBACK combobox_subclass_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == EM_SETSEL) + { + setsel_start = wParam; + setsel_end = lParam; + } + return CallWindowProcA(edit_window_proc, hwnd, msg, wParam, lParam); +} + +static LRESULT CALLBACK test_window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_COMMAND: + switch (HIWORD(wParam)) + { + case CBN_SETFOCUS: + hCBN_SetFocus = (HWND)lParam; + break; + case CBN_KILLFOCUS: + hCBN_KillFocus = (HWND)lParam; + break; + } + break; + case WM_NEXTDLGCTL: + SetFocus((HWND)wParam); + break; + } + return CallWindowProcA(old_parent_proc, hwnd, msg, wParam, lParam); +} + +static void test_editselection_focus(DWORD style) +{ + BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO); + HWND hCombo, hEdit, hButton; + COMBOBOXINFO cbInfo; + BOOL ret; + const char wine_test[] = "Wine Test"; + char buffer[16] = {0}; + DWORD len; + + pGetComboBoxInfo = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo"); + if (!pGetComboBoxInfo) + { + win_skip("GetComboBoxInfo is not available\n"); + return; + } + + hCombo = build_combo(style); + cbInfo.cbSize = sizeof(COMBOBOXINFO); + SetLastError(0xdeadbeef); + ret = pGetComboBoxInfo(hCombo, &cbInfo); + ok(ret, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError()); + hEdit = cbInfo.hwndItem; + + hButton = CreateWindowA("Button", "OK", WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, + 5, 50, 100, 20, hMainWnd, NULL, + (HINSTANCE)GetWindowLongPtrA(hMainWnd, GWLP_HINSTANCE), NULL); + + old_parent_proc = (WNDPROC)SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)test_window_proc); + edit_window_proc = (WNDPROC)SetWindowLongPtrA(hEdit, GWLP_WNDPROC, (ULONG_PTR)combobox_subclass_proc); + + SendMessageA(hCombo, WM_SETFOCUS, 0, (LPARAM)hEdit); + ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start); + todo_wine ok(setsel_end == INT_MAX, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end); + ok(hCBN_SetFocus == hCombo, "Wrong handle set by CBN_SETFOCUS; got %p\n", hCBN_SetFocus); + ok(GetFocus() == hEdit, "hEdit should have keyboard focus\n"); + + SendMessageA(hMainWnd, WM_NEXTDLGCTL, (WPARAM)hButton, TRUE); + ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start); + todo_wine ok(setsel_end == 0, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end); + ok(hCBN_KillFocus == hCombo, "Wrong handle set by CBN_KILLFOCUS; got %p\n", hCBN_KillFocus); + ok(GetFocus() == hButton, "hButton should have keyboard focus\n"); + + SendMessageA(hCombo, WM_SETTEXT, 0, (LPARAM)wine_test); + SendMessageA(hMainWnd, WM_NEXTDLGCTL, (WPARAM)hCombo, TRUE); + ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start); + todo_wine ok(setsel_end == INT_MAX, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end); + ok(hCBN_SetFocus == hCombo, "Wrong handle set by CBN_SETFOCUS; got %p\n", hCBN_SetFocus); + ok(GetFocus() == hEdit, "hEdit should have keyboard focus\n"); + SendMessageA(hCombo, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer); + ok(!strcmp(buffer, wine_test), "Unexpected text in edit control; got '%s'\n", buffer); + + SendMessageA(hMainWnd, WM_NEXTDLGCTL, (WPARAM)hButton, TRUE); + ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start); + todo_wine ok(setsel_end == 0, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end); + ok(hCBN_KillFocus == hCombo, "Wrong handle set by CBN_KILLFOCUS; got %p\n", hCBN_KillFocus); + ok(GetFocus() == hButton, "hButton should have keyboard focus\n"); + len = SendMessageA(hCombo, CB_GETEDITSEL, 0, 0); + ok(len == 0, "Unexpected text selection; start: %u, end: %u\n", LOWORD(len), HIWORD(len)); + + SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)old_parent_proc); + DestroyWindow(hButton); + DestroyWindow(hCombo); +} + static void test_listbox_styles(DWORD cb_style) { BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO); @@ -606,6 +714,8 @@ test_changesize(CBS_DROPDOWN); test_changesize(CBS_DROPDOWNLIST); test_editselection(); + test_editselection_focus(CBS_SIMPLE); + test_editselection_focus(CBS_DROPDOWN); test_listbox_styles(CBS_SIMPLE); test_listbox_styles(CBS_DROPDOWN); test_listbox_styles(CBS_DROPDOWNLIST); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/tests/dde.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/tests/dde.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/tests/dde.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/tests/dde.c 2016-02-08 19:32:34.000000000 +0000 @@ -2457,7 +2457,7 @@ ok(size == 12, "Expected 12, got %d, msg_index=%d\n", size, msg_index); size = DdeGetData(hdata, NULL, 0, 0); - ok((buffer = HeapAlloc(GetProcessHeap(), 0, size)) != NULL, "should not be null\n"); + ok((buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size)) != NULL, "should not be null\n"); rsize = DdeGetData(hdata, buffer, size, 0); ok(rsize == size, "Incorrect size returned, expected %d got %d, msg_index=%d\n", size, rsize, msg_index); @@ -2550,6 +2550,7 @@ ok( 0, "Invalid message %u\n", msg_index ); break; } + HeapFree(GetProcessHeap(), 0, buffer); return (HDDEDATA) DDE_FACK; } case XTYP_DISCONNECT: diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/tests/msg.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/tests/msg.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/tests/msg.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/tests/msg.c 2016-02-08 19:32:34.000000000 +0000 @@ -24,6 +24,7 @@ #define WINVER 0x0600 /* for WM_GETTITLEBARINFOEX */ #include +#include #include #include @@ -32,6 +33,7 @@ #include "wingdi.h" #include "winuser.h" #include "winnls.h" +#include "dbt.h" #include "wine/test.h" @@ -4520,6 +4522,47 @@ ok(ret == WAIT_IO_COMPLETION, "MsgWaitForMultipleObjectsEx returned %x\n", ret); } +static void test_WM_DEVICECHANGE(HWND hwnd) +{ + DWORD ret; + MSG msg; + int i; + static const WPARAM wparams[] = {0, + DBT_DEVNODES_CHANGED, + DBT_QUERYCHANGECONFIG, + DBT_CONFIGCHANGED, + DBT_CONFIGCHANGECANCELED, + DBT_NO_DISK_SPACE, + DBT_LOW_DISK_SPACE, + DBT_CONFIGMGPRIVATE, /* 0x7fff */ + DBT_DEVICEARRIVAL, /* 0x8000 */ + DBT_DEVICEQUERYREMOVE, + DBT_DEVICEQUERYREMOVEFAILED, + DBT_DEVICEREMOVEPENDING, + DBT_DEVICEREMOVECOMPLETE, + DBT_DEVICETYPESPECIFIC, + DBT_CUSTOMEVENT}; + + for (i = 0; i < sizeof(wparams)/sizeof(wparams[0]); i++) + { + SetLastError(0xdeadbeef); + ret = PostMessageA(hwnd, WM_DEVICECHANGE, wparams[i], 0); + if (wparams[i] & 0x8000) + { + ok(ret == FALSE, "PostMessage should returned %d\n", ret); + ok(GetLastError() == ERROR_MESSAGE_SYNC_ONLY, "PostMessage error %08x\n", GetLastError()); + } + else + { + ret = MsgWaitForMultipleObjects(0, NULL, FALSE, 0, QS_POSTMESSAGE); + ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjects returned %x\n", ret); + memset(&msg, 0, sizeof(msg)); + ok(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "PeekMessage should succeed\n"); + ok(msg.message == WM_DEVICECHANGE, "got %04x instead of WM_DEVICECHANGE\n", msg.message); + } + } +} + static DWORD CALLBACK show_window_thread(LPVOID arg) { HWND hwnd = arg; @@ -4911,6 +4954,7 @@ flush_sequence(); test_MsgWaitForMultipleObjects(hparent); + test_WM_DEVICECHANGE(hparent); /* the following test causes an exception in user.exe under win9x */ if (!PostMessageW( hparent, WM_USER, 0, 0 )) @@ -5893,7 +5937,96 @@ { 0 } }; -static WNDPROC old_combobox_proc; +static const struct message WMSetFocusComboBoxSeq[] = +{ + { WM_SETFOCUS, sent }, + { WM_KILLFOCUS, sent|parent }, + { WM_SETFOCUS, sent }, + { WM_COMMAND, sent|defwinproc|wparam, MAKEWPARAM(1001, EN_SETFOCUS) }, + { EM_SETSEL, sent|defwinproc|wparam|lparam, 0, INT_MAX }, + { WM_CTLCOLOREDIT, sent|defwinproc|optional },/* Not sent on W2000, XP or Server 2003 */ + { WM_CTLCOLOREDIT, sent|parent|optional },/* Not sent on W2000, XP or Server 2003 */ + { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_SETFOCUS) }, + { 0 } +}; + +static const struct message SetFocusButtonSeq[] = +{ + { WM_KILLFOCUS, sent }, + { CB_GETCOMBOBOXINFO, sent|optional },/* Windows 2000 */ + { 0x0167, sent|optional },/* Undocumented message. Sent on all versions except Windows 2000 */ + { WM_LBUTTONUP, sent|defwinproc }, + { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_SELENDCANCEL) }, + { EM_SETSEL, sent|defwinproc|wparam|lparam, 0, 0 }, + { WM_CTLCOLOREDIT, sent|defwinproc|optional },/* Not sent on W2000, XP or Server 2003 */ + { WM_CTLCOLOREDIT, sent|parent|optional },/* Not sent on W2000, XP or Server 2003 */ + { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_KILLFOCUS) }, + { WM_CTLCOLORBTN, sent|parent }, + { 0 } +}; + +static const struct message SetFocusComboBoxSeq[] = +{ + { WM_CTLCOLORBTN, sent|parent }, + { WM_SETFOCUS, sent }, + { WM_KILLFOCUS, sent|defwinproc }, + { WM_SETFOCUS, sent }, + { WM_COMMAND, sent|defwinproc|wparam, MAKEWPARAM(1001, EN_SETFOCUS) }, + { EM_SETSEL, sent|defwinproc|wparam|lparam, 0, INT_MAX }, + { WM_CTLCOLOREDIT, sent|defwinproc|optional },/* Not sent on W2000, XP or Server 2003 */ + { WM_CTLCOLOREDIT, sent|parent|optional },/* Not sent on W2000, XP or Server 2003 */ + { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_SETFOCUS) }, + { 0 } +}; + +static const struct message SetFocusButtonSeq2[] = +{ + { WM_KILLFOCUS, sent }, + { CB_GETCOMBOBOXINFO, sent|optional },/* Windows 2000 */ + { 0x0167, sent|optional },/* Undocumented message. Sent on all versions except Windows 2000 */ + { WM_LBUTTONUP, sent|defwinproc }, + { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_SELENDCANCEL) }, + { EM_SETSEL, sent|defwinproc|wparam|lparam, 0, 0 }, + { WM_CTLCOLOREDIT, sent|defwinproc }, + { WM_CTLCOLOREDIT, sent|parent }, + { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_KILLFOCUS) }, + { WM_CTLCOLORBTN, sent|parent }, + { 0 } +}; + +static WNDPROC old_combobox_proc, edit_window_proc; + +static LRESULT CALLBACK combobox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static LONG defwndproc_counter = 0; + LRESULT ret; + struct recvd_message msg; + + /* do not log painting messages */ + if (message != WM_PAINT && + message != WM_NCPAINT && + message != WM_SYNCPAINT && + message != WM_ERASEBKGND && + message != WM_NCHITTEST && + message != WM_GETTEXT && + !ignore_message( message )) + { + msg.hwnd = hwnd; + msg.message = message; + msg.flags = sent|wparam|lparam; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.lParam = lParam; + msg.descr = "combo"; + add_message(&msg); + } + + defwndproc_counter++; + ret = CallWindowProcA(edit_window_proc, hwnd, message, wParam, lParam); + defwndproc_counter--; + + return ret; +} static LRESULT CALLBACK combobox_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -5944,8 +6077,11 @@ static void test_combobox_messages(void) { - HWND parent, combo; + HWND parent, combo, button, edit; LRESULT ret; + BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO); + COMBOBOXINFO cbInfo; + BOOL res; subclass_combobox(); @@ -5986,6 +6122,65 @@ DestroyWindow(combo); DestroyWindow(parent); + + /* Start again. Test combobox text selection when getting and losing focus */ + pGetComboBoxInfo = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo"); + if (!pGetComboBoxInfo) + { + win_skip("GetComboBoxInfo is not available\n"); + return; + } + + parent = CreateWindowExA(0, "TestParentClass", "Parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 10, 10, 300, 300, NULL, NULL, NULL, NULL); + ok(parent != 0, "Failed to create parent window\n"); + + combo = CreateWindowExA(0, "my_combobox_class", "test", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN, + 5, 5, 100, 100, parent, (HMENU)ID_COMBOBOX, NULL, NULL); + ok(combo != 0, "Failed to create combobox window\n"); + + cbInfo.cbSize = sizeof(COMBOBOXINFO); + SetLastError(0xdeadbeef); + res = pGetComboBoxInfo(combo, &cbInfo); + ok(res, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError()); + edit = cbInfo.hwndItem; + + edit_window_proc = (WNDPROC)SetWindowLongPtrA(edit, GWLP_WNDPROC, (ULONG_PTR)combobox_subclass_proc); + + button = CreateWindowExA(0, "Button", "OK", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, + 5, 50, 100, 20, parent, NULL, + (HINSTANCE)GetWindowLongPtrA(parent, GWLP_HINSTANCE), NULL); + ok(button != 0, "Failed to create button window\n"); + + flush_sequence(); + log_all_parent_messages++; + SendMessageA(combo, WM_SETFOCUS, 0, (LPARAM)edit); + log_all_parent_messages--; + ok_sequence(WMSetFocusComboBoxSeq, "WM_SETFOCUS on a ComboBox", TRUE); + + flush_sequence(); + log_all_parent_messages++; + SetFocus(button); + log_all_parent_messages--; + ok_sequence(SetFocusButtonSeq, "SetFocus on a Button", TRUE); + + SendMessageA(combo, WM_SETTEXT, 0, (LPARAM)"Wine Test"); + + flush_sequence(); + log_all_parent_messages++; + SetFocus(combo); + log_all_parent_messages--; + ok_sequence(SetFocusComboBoxSeq, "SetFocus on a ComboBox", TRUE); + + flush_sequence(); + log_all_parent_messages++; + SetFocus(button); + log_all_parent_messages--; + ok_sequence(SetFocusButtonSeq2, "SetFocus on a Button (2)", TRUE); + + DestroyWindow(button); + DestroyWindow(combo); + DestroyWindow(parent); } /****************** WM_IME_KEYDOWN message test *******************/ @@ -8568,9 +8763,11 @@ static void test_timers_no_wnd(void) { + static UINT_PTR ids[0xffff]; UINT_PTR id, id2; DWORD start; MSG msg; + int i; count = 0; id = SetTimer(NULL, 0, 100, callback_count); @@ -8605,6 +8802,18 @@ count, TIMER_COUNT_EXPECTED); KillTimer(NULL, id); /* Note: SetSystemTimer doesn't support a NULL window, see test_timers */ + + /* Check what happens when we're running out of timers */ + for (i=0; i 0) KillTimer(NULL, ids[--i]); } static void test_timers_exception(DWORD code) @@ -14916,6 +15125,33 @@ flush_sequence(); } +static const struct message DoubleSetCaptureSeq[] = +{ + { WM_CAPTURECHANGED, sent }, + { 0 } +}; + +static void test_DoubleSetCapture(void) +{ + HWND hwnd; + + hwnd = CreateWindowExA(0, "TestWindowClass", "Test DoubleSetCapture", + WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 100, 100, 200, 200, 0, 0, 0, NULL); + ok (hwnd != 0, "Failed to create overlapped window\n"); + + ShowWindow( hwnd, SW_SHOW ); + UpdateWindow( hwnd ); + flush_events(); + flush_sequence(); + + SetCapture( hwnd ); + SetCapture( hwnd ); + ok_sequence(DoubleSetCaptureSeq, "SetCapture( hwnd ) twice", FALSE); + + DestroyWindow(hwnd); +} + static void init_funcs(void) { HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); @@ -15056,6 +15292,7 @@ test_layered_window(); test_TrackPopupMenu(); test_TrackPopupMenuEmpty(); + test_DoubleSetCapture(); /* keep it the last test, under Windows it tends to break the tests * which rely on active/foreground windows being correct. */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/tests/winstation.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/tests/winstation.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/tests/winstation.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/tests/winstation.c 2016-02-08 19:32:34.000000000 +0000 @@ -205,6 +205,35 @@ else if (le == ERROR_ACCESS_DENIED) win_skip( "Not enough privileges for CreateWindowStation\n" ); + SetLastError( 0xdeadbeef ); + w2 = OpenWindowStationA( "", TRUE, WINSTA_ALL_ACCESS ); + ok( !w2, "open station succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + w2 = CreateWindowStationA( "", 0, WINSTA_ALL_ACCESS, NULL ); + ok( w2 != 0, "create station failed err %u\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + w3 = OpenWindowStationA( "", TRUE, WINSTA_ALL_ACCESS ); + todo_wine + ok( w3 != 0, "open station failed err %u\n", GetLastError() ); + CloseWindowStation( w3 ); + CloseWindowStation( w2 ); + + SetLastError( 0xdeadbeef ); + w2 = CreateWindowStationA( "foo\\bar", 0, WINSTA_ALL_ACCESS, NULL ); + ok( !w2, "create station succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_PATH_NOT_FOUND || GetLastError() == ERROR_ACCESS_DENIED, + "wrong error %u\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + w2 = OpenWindowStationA( "foo\\bar", TRUE, WINSTA_ALL_ACCESS ); + ok( !w2, "create station succeeded\n" ); + ok( GetLastError() == ERROR_PATH_NOT_FOUND, "wrong error %u\n", GetLastError() ); + /* desktops */ d1 = GetThreadDesktop(GetCurrentThreadId()); initial_desktop = d1; @@ -239,6 +268,30 @@ d2 = OpenDesktopA( "dummy name", 0, TRUE, DESKTOP_ALL_ACCESS ); ok( !d2, "open dummy desktop succeeded\n" ); + SetLastError( 0xdeadbeef ); + d2 = CreateDesktopA( "", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); + todo_wine + ok( !d2, "create empty desktop succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + d2 = OpenDesktopA( "", 0, TRUE, DESKTOP_ALL_ACCESS ); + ok( !d2, "open mepty desktop succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + d2 = CreateDesktopA( "foo\\bar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); + ok( !d2, "create desktop succeeded\n" ); + ok( GetLastError() == ERROR_BAD_PATHNAME, "wrong error %u\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + d2 = OpenDesktopA( "foo\\bar", 0, TRUE, DESKTOP_ALL_ACCESS ); + ok( !d2, "open desktop succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_BAD_PATHNAME, "wrong error %u\n", GetLastError() ); + d2 = CreateDesktopA( "foobar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); ok( d2 != 0, "create foobar desktop failed\n" ); SetLastError( 0xdeadbeef ); @@ -452,8 +505,8 @@ name_info = (OBJECT_NAME_INFORMATION *)buffer; status = pNtQueryObject(desk, ObjectNameInformation, name_info, sizeof(buffer), NULL); ok(!status, "expected STATUS_SUCCESS, got %08x\n", status); - todo_wine ok(lstrcmpW(name_info->Name.Buffer, foobarTestW) == 0, - "expected '\\foobarTest', got %s\n", wine_dbgstr_w(name_info->Name.Buffer)); + ok(lstrcmpW(name_info->Name.Buffer, foobarTestW) == 0, + "expected '\\foobarTest', got %s\n", wine_dbgstr_w(name_info->Name.Buffer)); /** Tests for UOI_TYPE **/ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/winstation.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/winstation.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user32/winstation.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user32/winstation.c 2016-02-08 19:32:34.000000000 +0000 @@ -28,6 +28,8 @@ #include "winerror.h" #include "wingdi.h" #include "winuser.h" +#include "winternl.h" +#include "ddk/wdm.h" #include "wine/server.h" #include "wine/unicode.h" #include "wine/debug.h" @@ -53,6 +55,27 @@ return data->func( buffer, data->lparam ); } +/* return a handle to the directory where window station objects are created */ +static HANDLE get_winstations_dir_handle(void) +{ + static HANDLE handle = NULL; + static const WCHAR basenameW[] = {'\\','W','i','n','d','o','w','s','\\', + 'W','i','n','d','o','w','S','t','a','t','i','o','n','s',0}; + UNICODE_STRING str; + OBJECT_ATTRIBUTES attr; + + if (!handle) + { + HANDLE dir; + + RtlInitUnicodeString( &str, basenameW ); + InitializeObjectAttributes( &attr, &str, 0, 0, NULL ); + NtOpenDirectoryObject( &dir, DIRECTORY_CREATE_OBJECT | DIRECTORY_TRAVERSE, &attr ); + if (InterlockedCompareExchangePointer( &handle, dir, 0 ) != 0) /* someone beat us here */ + CloseHandle( dir ); + } + return handle; +} /*********************************************************************** * CreateWindowStationA (USER32.@) @@ -93,9 +116,9 @@ req->access = access; req->attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF | ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0); + req->rootdir = wine_server_obj_handle( get_winstations_dir_handle() ); wine_server_add_data( req, name, len * sizeof(WCHAR) ); - /* it doesn't seem to set last error */ - wine_server_call( req ); + wine_server_call_err( req ); ret = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; @@ -137,6 +160,7 @@ { req->access = access; req->attributes = OBJ_CASE_INSENSITIVE | (inherit ? OBJ_INHERIT : 0); + req->rootdir = wine_server_obj_handle( get_winstations_dir_handle() ); wine_server_add_data( req, name, len * sizeof(WCHAR) ); if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->handle ); } @@ -291,8 +315,7 @@ req->attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF | ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0); wine_server_add_data( req, name, len * sizeof(WCHAR) ); - /* it doesn't seem to set last error */ - wine_server_call( req ); + wine_server_call_err( req ); ret = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; @@ -334,7 +357,7 @@ req->access = access; req->attributes = OBJ_CASE_INSENSITIVE | (inherit ? OBJ_INHERIT : 0); wine_server_add_data( req, name, len * sizeof(WCHAR) ); - if (!wine_server_call( req )) ret = wine_server_ptr_handle( reply->handle ); + if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return ret; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/user.exe16/message.c wine-staging-1.9.3~ubuntu12.04.1/dlls/user.exe16/message.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/user.exe16/message.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/user.exe16/message.c 2016-02-08 19:32:34.000000000 +0000 @@ -1836,6 +1836,9 @@ msg.message = msg16->message; msg.wParam = msg16->wParam; msg.lParam = msg16->lParam; + msg.time = msg16->time; + msg.pt.x = msg16->pt.x; + msg.pt.y = msg16->pt.y; return IsDialogMessageA( hwndDlg32, &msg ); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/usp10/tests/usp10.c wine-staging-1.9.3~ubuntu12.04.1/dlls/usp10/tests/usp10.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/usp10/tests/usp10.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/usp10/tests/usp10.c 2016-02-08 19:32:34.000000000 +0000 @@ -456,6 +456,38 @@ static const itemTest t471[2] = {{{0,0,0,0,0},0,0,0,0,math_tag,TRUE,{-1,-1,-1,-1,0x0}},{{0,0,0,0,0},26,0,0,0,-1,FALSE}}; static const itemTest t472[2] = {{{0,0,0,0,0},0,0,0,2,math_tag,TRUE,{-1,1,1,1,0x0}},{{0,0,0,0,0},26,0,0,0,-1,FALSE}}; + /* Mathematical and Numeric combinations */ + /* These have a leading hebrew character to force complicated itemization */ + static const WCHAR test48[] = {0x05e9,' ','1','2','3','.'}; + static const itemTest t481[4] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE}, + {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},5,0,0,0,0,FALSE}, + {{0,0,0,0,0},6,0,0,0,-1,FALSE}}; + static const WCHAR test49[] = {0x05e9,' ','1','2','.','1','2'}; + static const itemTest t491[3] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE}, + {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},7,0,0,0,-1,FALSE}}; + static const WCHAR test50[] = {0x05e9,' ','.','1','2','3'}; + static const itemTest t501[4] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE}, + {{0,0,0,0,0},2,1,1,1,0,FALSE},{{0,0,0,0,0},3,0,1,2,0,FALSE}, + {{0,0,0,0,0},6,0,0,0,-1,FALSE}}; + static const WCHAR test51[] = {0x05e9,' ','a','b','.','1','2'}; + static const itemTest t511[5] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE}, + {{0,0,0,0,0},1,0,0,0,latn_tag,FALSE},{{0,0,0,0,0},4,0,0,0,0,FALSE}, + {{0,0,0,0,0},5,0,0,2,0,FALSE},{{0,0,0,0,0},7,0,0,0,-1,FALSE}}; + static const WCHAR test52[] = {0x05e9,' ','1','2','.','a','b'}; + static const itemTest t521[5] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE}, + {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},4,0,0,0,0,FALSE}, + {{0,0,0,0,0},5,0,0,0,latn_tag,FALSE},{{0,0,0,0,0},7,0,0,0,-1,FALSE}}; + static const WCHAR test53[] = {0x05e9,' ','1','2','.','.','1','2'}; + static const itemTest t531[5] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE}, + {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},4,1,1,1,0,FALSE}, + {{0,0,0,0,0},6,0,1,2,0,FALSE},{{0,0,0,0,0},8,0,0,0,-1,FALSE}}; + static const WCHAR test54[] = {0x05e9,' ','1','2','+','1','2'}; + static const itemTest t541[3] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE}, + {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},7,0,0,0,-1,FALSE}}; + static const WCHAR test55[] = {0x05e9,' ','1','2','+','+','1','2'}; + static const itemTest t551[3] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE}, + {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},8,0,0,0,-1,FALSE}}; + SCRIPT_ITEM items[15]; SCRIPT_CONTROL Control; SCRIPT_STATE State; @@ -590,6 +622,14 @@ test_items_ok(test45,24,&Control,&State,1,t451,FALSE,0); test_items_ok(test46,16,&Control,&State,1,t461,FALSE,0); test_items_ok(test47,26,&Control,&State,1,t471,FALSE,0); + test_items_ok(test48,6,&Control,&State,3,t481,FALSE,0); + test_items_ok(test49,7,&Control,&State,2,t491,FALSE,0); + test_items_ok(test50,6,&Control,&State,3,t501,FALSE,0); + test_items_ok(test51,7,&Control,&State,4,t511,FALSE,0); + test_items_ok(test52,7,&Control,&State,4,t521,FALSE,0); + test_items_ok(test53,8,&Control,&State,4,t531,FALSE,0); + test_items_ok(test54,7,&Control,&State,2,t541,FALSE,0); + test_items_ok(test55,8,&Control,&State,2,t551,FALSE,0); State.uBidiLevel = 1; test_items_ok(test1,4,&Control,&State,1,t12,FALSE,0); @@ -2438,6 +2478,70 @@ } } +#define test_caret_item_ScriptXtoCP(a,b,c,d,e,f) _test_caret_item_ScriptXtoCP(__LINE__,a,b,c,d,e,f) + +static void _test_caret_item_ScriptXtoCP(int line, SCRIPT_ANALYSIS *psa, int cChars, int cGlyphs, const int* offsets, const WORD *pwLogClust, const int* piAdvance ) +{ + int iX, iCP, i; + int icChars, icGlyphs; + int piCP; + int clusterSize; + HRESULT hr; + SCRIPT_VISATTR psva[10]; + int piTrailing; + int direction; + + memset(psva,0,sizeof(psva)); + direction = (psa->fRTL)?-1:+1; + + for(iX = -1, i = iCP = 0; i < cChars; i++) + { + if (offsets[i] != iX) + { + iX = offsets[i]; + iCP = i; + } + icChars = cChars; + icGlyphs = cGlyphs; + hr = ScriptXtoCP(iX, icChars, icGlyphs, pwLogClust, psva, piAdvance, psa, &piCP, &piTrailing); + ok_(__FILE__,line)(hr == S_OK, "ScriptXtoCP: should return S_OK not %08x\n", hr); + ok_(__FILE__,line)(piCP == iCP, "ScriptXtoCP: iX=%d should return piCP=%d not %d\n", iX, iCP, piCP); + ok_(__FILE__,line)(piTrailing == 0, "ScriptXtoCP: iX=%d should return piTrailing=0 not %d\n", iX, piTrailing); + } + + for(iX = -2, i = 0; i < cChars; i++) + { + if (offsets[i]+direction != iX) + { + iX = offsets[i] + direction; + iCP = i; + } + icChars = cChars; + icGlyphs = cGlyphs; + hr = ScriptXtoCP(iX, icChars, icGlyphs, pwLogClust, psva, piAdvance, psa, &piCP, &piTrailing); + ok_(__FILE__,line)(hr == S_OK, "ScriptXtoCP leading: should return S_OK not %08x\n", hr); + ok_(__FILE__,line)(piCP == iCP, "ScriptXtoCP leading: iX=%d should return piCP=%d not %d\n", iX, iCP, piCP); + ok_(__FILE__,line)(piTrailing == 0, "ScriptXtoCP leading: iX=%d should return piTrailing=0 not %d\n", iX, piTrailing); + } + + for(clusterSize = 0, iCP = 0, iX = -2, i = 0; i < cChars; i++) + { + clusterSize++; + if (offsets[i] != offsets[i+1]) + { + iX = offsets[i+1]-direction; + icChars = cChars; + icGlyphs = cGlyphs; + hr = ScriptXtoCP(iX, icChars, icGlyphs, pwLogClust, psva, piAdvance, psa, &piCP, &piTrailing); + ok_(__FILE__,line)(hr == S_OK, "ScriptXtoCP trailing: should return S_OK not %08x\n", hr); + ok_(__FILE__,line)(piCP == iCP, "ScriptXtoCP trailing: iX=%d should return piCP=%d not %d\n", iX, iCP, piCP); + ok_(__FILE__,line)(piTrailing == clusterSize, "ScriptXtoCP trailing: iX=%d should return piTrailing=%d not %d\n", iX, clusterSize, piTrailing); + iCP = i+1; + clusterSize = 0; + } + } +} + static void test_ScriptXtoX(void) /**************************************************************************************** * This routine tests the ScriptXtoCP and ScriptCPtoX functions using static variables * @@ -2446,17 +2550,28 @@ WORD pwLogClust[10] = {0, 0, 0, 1, 1, 2, 2, 3, 3, 3}; WORD pwLogClust_RTL[10] = {3, 3, 3, 2, 2, 1, 1, 0, 0, 0}; WORD pwLogClust_2[7] = {4, 3, 3, 2, 1, 0 ,0}; + WORD pwLogClust_3[17] = {0, 1, 1, 1, 1, 4, 5, 6, 6, 8, 8, 8, 8, 11, 11, 13, 13}; + WORD pwLogClust_3_RTL[17] = {13, 13, 11, 11, 8, 8, 8, 8, 6, 6, 5, 4, 1, 1, 1, 1, 0}; int piAdvance[10] = {201, 190, 210, 180, 170, 204, 189, 195, 212, 203}; int piAdvance_2[5] = {39, 26, 19, 17, 11}; + int piAdvance_3[15] = {6, 6, 0, 0, 10, 5, 10, 0, 12, 0, 0, 9, 0, 10, 0}; static const int offsets[13] = {0, 67, 134, 201, 296, 391, 496, 601, 1052, 1503, 1954, 1954, 1954}; static const int offsets_RTL[13] = {781, 721, 661, 601, 496, 391, 296, 201, 134, 67, 0, 0, 0}; static const int offsets_2[10] = {112, 101, 92, 84, 65, 39, 19, 0, 0, 0}; - SCRIPT_VISATTR psva[10]; + + static const int offsets_3[19] = {0, 6, 6, 6, 6, 12, 22, 27, 27, 37, 37, 37, 37, 49, 49, 58, 58, 68, 68}; + static const int offsets_3_RTL[19] = {68, 68, 58, 58, 49, 49, 49, 49, 37, 37, 27, 22, 12, 12, 12, 12, 6, 6}; + + SCRIPT_VISATTR psva[15]; SCRIPT_ANALYSIS sa; - int iX; + SCRIPT_ITEM items[2]; + int iX, i; int piCP; int piTrailing; HRESULT hr; + static const WCHAR hebrW[] = { 0x5be, 0}; + static const WCHAR thaiW[] = { 0xe2a, 0}; + const SCRIPT_PROPERTIES **ppScriptProperties; memset(&sa, 0 , sizeof(SCRIPT_ANALYSIS)); memset(psva, 0, sizeof(psva)); @@ -2518,6 +2633,34 @@ sa.fRTL = TRUE; test_item_ScriptXtoX(&sa, 10, 10, offsets_RTL, pwLogClust_RTL, piAdvance); test_item_ScriptXtoX(&sa, 7, 5, offsets_2, pwLogClust_2, piAdvance_2); + + /* Get thai eScript, This will do LTR and fNeedsCaretInfo */ + hr = ScriptItemize(thaiW, 1, 2, NULL, NULL, items, &i); + ok(hr == S_OK, "got %08x\n", hr); + ok(i == 1, "got %d\n", i); + sa = items[0].a; + + test_caret_item_ScriptXtoCP(&sa, 17, 15, offsets_3, pwLogClust_3, piAdvance_3); + + /* Get hebrew eScript, This will do RTL and fNeedsCaretInfo */ + hr = ScriptItemize(hebrW, 1, 2, NULL, NULL, items, &i); + ok(hr == S_OK, "got %08x\n", hr); + ok(i == 1, "got %d\n", i); + sa = items[0].a; + + /* Note: This behavior CHANGED in uniscribe versions... + * so we only want to test if fNeedsCaretInfo is set */ + hr = ScriptGetProperties(&ppScriptProperties, &i); + if (ppScriptProperties[sa.eScript]->fNeedsCaretInfo) + { + test_caret_item_ScriptXtoCP(&sa, 17, 15, offsets_3_RTL, pwLogClust_3_RTL, piAdvance_3); + hr = ScriptXtoCP(0, 17, 15, pwLogClust_3_RTL, psva, piAdvance_3, &sa, &piCP, &piTrailing); + ok(hr == S_OK, "ScriptXtoCP: should return S_OK not %08x\n", hr); + ok(piCP == 16, "ScriptXtoCP: iX=0 should return piCP=16 not %d\n", piCP); + ok(piTrailing == 1, "ScriptXtoCP: iX=0 should return piTrailing=1 not %d\n", piTrailing); + } + else + win_skip("Uniscribe version too old to test Hebrew clusters\n"); } static void test_ScriptString(HDC hdc) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/usp10/usp10.c wine-staging-1.9.3~ubuntu12.04.1/dlls/usp10/usp10.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/usp10/usp10.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/usp10/usp10.c 2016-02-08 19:32:34.000000000 +0000 @@ -26,6 +26,7 @@ #include #include +#include #include "windef.h" #include "winbase.h" @@ -1306,9 +1307,15 @@ else if (is_indic(scripts[i])) last_indic = base_indic(scripts[i]); - /* Some unicode points (Zero Width Space U+200B - - Right-to-Left Mark U+200F) will force us into bidi mode */ - if (!forceLevels && pwcInChars[i] >= 0x200B && pwcInChars[i] <= 0x200F) + /* Some unicode points : + (Zero Width Space U+200B - Right-to-Left Mark U+200F) + (Left Right Embed U+202A - Left Right Override U+202D) + (Left Right Isolate U+2066 - Pop Directional Isolate U+2069) + will force us into bidi mode */ + if (!forceLevels && ((pwcInChars[i] >= 0x200B && pwcInChars[i] <= 0x200F) || + (pwcInChars[i] >= 0x202A && pwcInChars[i] <= 0x202E) || + (pwcInChars[i] >= 0x2066 && pwcInChars[i] <= 0x2069))) + forceLevels = TRUE; /* Diacritical marks merge with other scripts */ @@ -1384,8 +1391,8 @@ } else { - BOOL inNumber = FALSE; static const WCHAR math_punc[] = {'#','$','%','+',',','-','.','/',':',0x2212, 0x2044, 0x00a0,0}; + static const WCHAR repeatable_math_punc[] = {'#','$','%','+','-','/',0x2212, 0x2044,0}; strength = heap_alloc_zero(cInChars * sizeof(WORD)); if (!strength) @@ -1400,21 +1407,48 @@ strength[i] = BIDI_STRONG; } + /* Math punctuation bordered on both sides by numbers can be + merged into the number */ for (i = 0; i < cInChars; i++) { - /* Script_Numeric and select puncuation at level 0 get bumped to level 2 */ - if ((levels[i] == 0 || (odd(psState->uBidiLevel) && levels[i] == psState->uBidiLevel+1)) && inNumber && strchrW(math_punc,pwcInChars[i])) + if (i > 0 && i < cInChars-1 && + scripts[i-1] == Script_Numeric && + strchrW(math_punc, pwcInChars[i])) { - scripts[i] = Script_Numeric; - levels[i] = 2; + if (scripts[i+1] == Script_Numeric) + { + scripts[i] = Script_Numeric; + levels[i] = levels[i-1]; + strength[i] = strength[i-1]; + i++; + } + else if (strchrW(repeatable_math_punc, pwcInChars[i])) + { + int j; + for (j = i+1; j < cInChars; j++) + { + if (scripts[j] == Script_Numeric) + { + for(;iuBidiLevel) && levels[i] == psState->uBidiLevel+1)) && scripts[i] == Script_Numeric) + } + + for (i = 0; i < cInChars; i++) + { + /* Script_Numeric at level 0 get bumped to level 2 */ + if ((levels[i] == 0 || (odd(psState->uBidiLevel) && levels[i] == psState->uBidiLevel+1)) && scripts[i] == Script_Numeric) { levels[i] = 2; - inNumber = TRUE; } - else - inNumber = FALSE; /* Joiners get merged preferencially right */ if (i > 0 && (pwcInChars[i] == ZWJ || pwcInChars[i] == ZWNJ)) @@ -2573,9 +2607,100 @@ return S_OK; } +/* Count the number of characters in a cluster and its starting index*/ +static inline BOOL get_cluster_data(const WORD *pwLogClust, int cChars, int cluster_index, int *cluster_size, int *start_index) +{ + int size = 0; + int i; + + for (i = 0; i < cChars; i++) + { + if (pwLogClust[i] == cluster_index) + { + if (!size && start_index) + { + *start_index = i; + if (!cluster_size) + return TRUE; + } + size++; + } + else if (size) break; + } + if (cluster_size) + *cluster_size = size; + + return (size > 0); +} + +/* + To handle multi-glyph clusters we need to find all the glyphs that are + represented in the cluster. This involves finding the glyph whose + index is the cluster index as well as whose glyph indices are greater than + our cluster index but not part of a new cluster. + + Then we sum all those glyphs' advances. +*/ +static inline int get_cluster_advance(const int* piAdvance, + const SCRIPT_VISATTR *psva, + const WORD *pwLogClust, int cGlyphs, + int cChars, int cluster, int direction) +{ + int glyph_start; + int glyph_end; + int i, advance; + + if (direction > 0) + i = 0; + else + i = (cChars - 1); + + for (glyph_start = -1, glyph_end = -1; i < cChars && i >= 0 && (glyph_start < 0 || glyph_end < 0); i+=direction) + { + if (glyph_start < 0 && pwLogClust[i] != cluster) continue; + if (pwLogClust[i] == cluster && glyph_start < 0) glyph_start = pwLogClust[i]; + if (glyph_start >= 0 && glyph_end < 0 && pwLogClust[i] != cluster) glyph_end = pwLogClust[i]; + } + if (glyph_end < 0) + { + if (direction > 0) + glyph_end = cGlyphs; + else + { + /* Don't fully understand multi-glyph reversed clusters yet, + * do they occur for real or just in our test? */ + FIXME("multi-glyph reversed clusters found\n"); + glyph_end = glyph_start + 1; + } + } + + /* Check for fClusterStart, finding this generally would mean a malformed set of data */ + for (i = glyph_start+1; i< glyph_end; i++) + { + if (psva[i].fClusterStart) + { + glyph_end = i; + break; + } + } + + for (advance = 0, i = glyph_start; i < glyph_end; i++) + advance += piAdvance[i]; + + return advance; +} + + /*********************************************************************** * ScriptXtoCP (USP10.@) * + * Basic algorithm : + * use piAdvance to find the cluster we are looking at + * Find the character that is the first character of the cluster + * That is our base piCP + * If the script snaps to cluster boundries (Hebrew, Indic, Thai) then we + * are good Otherwise if the cluster is larger than 1 glyph we need to + * determine how far through the cluster to advance the cursor. */ HRESULT WINAPI ScriptXtoCP(int iX, int cChars, @@ -2587,16 +2712,11 @@ int *piCP, int *piTrailing) { - int item; - float iPosX; - float iLastPosX; - int iSpecial = -1; - int iCluster = -1; - int clust_size = 1; - int cjump = 0; - int advance; - float special_size = 0.0; int direction = 1; + int iPosX; + int i; + int glyph_index, cluster_index; + int cluster_size; TRACE("(%d,%d,%d,%p,%p,%p,%p,%p,%p)\n", iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, @@ -2605,128 +2725,156 @@ if (psa->fRTL && ! psa->fLogicalOrder) direction = -1; - if (direction<0) + /* Handle an iX < 0 */ + if (iX < 0) { - int max_clust = pwLogClust[0]; - - if (iX < 0) + if (direction < 0) { *piCP = cChars; *piTrailing = 0; - return S_OK; } + else + { + *piCP = -1; + *piTrailing = 1; + } + return S_OK; + } - for (item=0; item < cChars; item++) - if (pwLogClust[item] > max_clust) + /* Looking for non-reversed clusters in a reversed string */ + if (direction < 0) + { + int max_clust = pwLogClust[0]; + for (i=0; i< cChars; i++) + if (pwLogClust[i] > max_clust) { - ERR("We do not handle non reversed clusters properly\n"); + FIXME("We do not handle non reversed clusters properly\n"); break; } } - if (iX < 0) + /* find the glyph_index based in iX */ + if (direction > 0) { - *piCP = -1; - *piTrailing = 1; - return S_OK; + for (glyph_index = -1, iPosX = iX; iPosX >=0 && glyph_index < cGlyphs; iPosX -= piAdvance[glyph_index+1], glyph_index++) + ; } - - iPosX = iLastPosX = 0; - if (direction > 0) - item = 0; else - item = cChars - 1; - for (; iPosX <= iX && item < cChars && item >= 0; item+=direction) { - iLastPosX = iPosX; - if (iSpecial == -1 && - (iCluster == -1 || - (iCluster != -1 && - ((direction > 0 && iCluster+clust_size <= item) || - (direction < 0 && iCluster-clust_size >= item)) - ) - ) - ) + for (glyph_index = -1, iPosX = iX; iPosX > 0 && glyph_index < cGlyphs; iPosX -= piAdvance[glyph_index+1], glyph_index++) + ; + } + + TRACE("iPosX %i -> glyph_index %i (%i)\n", iPosX, glyph_index, cGlyphs); + + *piTrailing = 0; + if (glyph_index >= 0 && glyph_index < cGlyphs) + { + /* find the cluster */ + if (direction > 0 ) + for (i = 0, cluster_index = pwLogClust[0]; i < cChars && pwLogClust[i] <= glyph_index; cluster_index=pwLogClust[i++]) + ; + else + for (i = 0, cluster_index = pwLogClust[0]; i < cChars && pwLogClust[i] >= glyph_index; cluster_index=pwLogClust[i++]) + ; + + TRACE("cluster_index %i\n", cluster_index); + + if (direction < 0 && iPosX >= 0 && glyph_index != cluster_index) { - int check; - int clust = pwLogClust[item]; + /* We are off the end of the string */ + *piCP = -1; + *piTrailing = 1; + return S_OK; + } - iCluster = -1; - cjump = 0; - clust_size = get_cluster_size(pwLogClust, cChars, item, direction, - &iCluster, &check); - advance = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, clust, direction); + get_cluster_data(pwLogClust, cChars, cluster_index, &cluster_size, &i); - if (check >= cChars && direction > 0) - { - int glyph; - for (glyph = clust; glyph < cGlyphs; glyph++) - special_size += get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, glyph, direction); - iSpecial = item; - special_size /= (cChars - item); - iPosX += special_size; - } - else + TRACE("first char index %i\n",i); + if (scriptInformation[psa->eScript].props.fNeedsCaretInfo) + { + /* Check trailing */ + if (glyph_index != cluster_index || + (direction > 0 && abs(iPosX) <= (piAdvance[glyph_index] / 2)) || + (direction < 0 && abs(iPosX) >= (piAdvance[glyph_index] / 2))) + *piTrailing = cluster_size; + } + else + { + if (cluster_size > 1) { - if (scriptInformation[psa->eScript].props.fNeedsCaretInfo) + /* Be part way through the glyph cluster based on size and position */ + int cluster_advance = get_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, cluster_index, direction); + double cluster_part_width = cluster_advance / (float)cluster_size; + double adv; + int part_index; + + /* back up to the beginning of the cluster */ + for (adv = iPosX, part_index = cluster_index; part_index <= glyph_index; part_index++) + adv += piAdvance[part_index]; + if (adv > iX) adv = iX; + + TRACE("Multi-char cluster, no snap\n"); + TRACE("cluster size %i, pre-cluster iPosX %f\n",cluster_size, adv); + TRACE("advance %i divides into %f per char\n", cluster_advance, cluster_part_width); + if (direction > 0) { - if (!cjump) - iPosX += advance; - cjump++; + for (part_index = 0; adv >= 0; adv-=cluster_part_width, part_index++) + ; + if (part_index) part_index--; } else - iPosX += advance / (float)clust_size; + { + for (part_index = 0; adv > 0; adv-=cluster_part_width, part_index++) + ; + if (part_index > cluster_size) + { + adv += cluster_part_width; + part_index=cluster_size; + } + } + + TRACE("base_char %i part_index %i, leftover advance %f\n",i, part_index, adv); + + if (direction > 0) + i += part_index; + else + i += (cluster_size - part_index); + + /* Check trailing */ + if ((direction > 0 && fabs(adv) <= (cluster_part_width / 2.0)) || + (direction < 0 && adv && fabs(adv) >= (cluster_part_width / 2.0))) + *piTrailing = 1; } - } - else if (iSpecial != -1) - iPosX += special_size; - else /* (iCluster != -1) */ - { - int adv = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, pwLogClust[iCluster], direction); - if (scriptInformation[psa->eScript].props.fNeedsCaretInfo) + else { - if (!cjump) - iPosX += adv; - cjump++; + /* Check trailing */ + if ((direction > 0 && abs(iPosX) <= (piAdvance[glyph_index] / 2)) || + (direction < 0 && abs(iPosX) >= (piAdvance[glyph_index] / 2))) + *piTrailing = 1; } - else - iPosX += adv / (float)clust_size; } } - - if (direction > 0) - { - if (iPosX > iX) - item--; - if (item < cChars && ((iPosX - iLastPosX) / 2.0) + iX >= iPosX) - { - if (scriptInformation[psa->eScript].props.fNeedsCaretInfo && clust_size > 1) - item+=(clust_size-1); - *piTrailing = 1; - } - else - *piTrailing = 0; - } else { - if (iX == iLastPosX) - item++; - if (iX >= iLastPosX && iX <= iPosX) - item++; - - if (iLastPosX == iX) - *piTrailing = 0; - else if (item < 0 || ((iLastPosX - iPosX) / 2.0) + iX <= iLastPosX) + TRACE("Point falls outside of string\n"); + if (glyph_index < 0) + i = cChars-1; + else /* (glyph_index >= cGlyphs) */ + i = cChars; + + /* If not snaping in the reverse direction (such as Hebrew) Then 0 + point flow to the next character */ + if (direction < 0) { - if (scriptInformation[psa->eScript].props.fNeedsCaretInfo && clust_size > 1) - item-=(clust_size-1); - *piTrailing = 1; + if (!scriptInformation[psa->eScript].props.fNeedsCaretInfo && abs(iPosX) == piAdvance[glyph_index]) + i++; + else + *piTrailing = 1; } - else - *piTrailing = 0; } - *piCP = item; + *piCP = i; TRACE("*piCP=%d\n", *piCP); TRACE("*piTrailing=%d\n", *piTrailing); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wbemprox/builtin.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wbemprox/builtin.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wbemprox/builtin.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wbemprox/builtin.c 2016-02-08 19:32:34.000000000 +0000 @@ -85,8 +85,6 @@ {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','d','i','a',0}; static const WCHAR class_physicalmemoryW[] = {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0}; -static const WCHAR class_qualifiersW[] = - {'_','_','Q','U','A','L','I','F','I','E','R','S',0}; static const WCHAR class_printerW[] = {'W','i','n','3','2','_','P','r','i','n','t','e','r',0}; static const WCHAR class_process_getowner_outW[] = @@ -96,6 +94,8 @@ {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0}; static const WCHAR class_processor2W[] = {'C','I','M','_','P','r','o','c','e','s','s','o','r',0}; +static const WCHAR class_qualifiersW[] = + {'_','_','Q','U','A','L','I','F','I','E','R','S',0}; static const WCHAR class_sidW[] = {'W','i','n','3','2','_','S','I','D',0}; static const WCHAR class_sounddeviceW[] = @@ -357,6 +357,8 @@ {'V','i','d','e','o','A','r','c','h','i','t','e','c','t','u','r','e',0}; static const WCHAR prop_videomemorytypeW[] = {'V','i','d','e','o','M','e','m','o','r','y','T','y','p','e',0}; +static const WCHAR prop_videomodedescriptionW[] = + {'V','i','d','e','o','M','o','d','e','D','e','s','c','r','i','p','t','i','o','n',0}; static const WCHAR prop_videoprocessorW[] = {'V','i','d','e','o','P','r','o','c','e','s','s','o','r',0}; static const WCHAR prop_volumenameW[] = @@ -657,6 +659,7 @@ { prop_pnpdeviceidW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_videoarchitectureW, CIM_UINT16, VT_I4 }, { prop_videomemorytypeW, CIM_UINT16, VT_I4 }, + { prop_videomodedescriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_videoprocessorW, CIM_STRING|COL_FLAG_DYNAMIC } }; @@ -1052,6 +1055,7 @@ const WCHAR *pnpdevice_id; UINT16 videoarchitecture; UINT16 videomemorytype; + const WCHAR *videomodedescription; const WCHAR *videoprocessor; }; #include "poppack.h" @@ -2938,16 +2942,16 @@ static enum fill_status fill_videocontroller( struct table *table, const struct expr *cond ) { - + static const WCHAR fmtW[] = {'%','u',' ','x',' ','%','u',' ','x',' ','%','I','6','4','u',' ','c','o','l','o','r','s',0}; struct record_videocontroller *rec; HRESULT hr; IDXGIFactory *factory = NULL; IDXGIAdapter *adapter = NULL; DXGI_ADAPTER_DESC desc; - UINT hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024; + UINT row = 0, hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024; const WCHAR *name = videocontroller_deviceidW; enum fill_status status = FILL_STATUS_UNFILTERED; - UINT row = 0; + WCHAR mode[44]; if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; @@ -2983,6 +2987,8 @@ rec->pnpdevice_id = get_pnpdeviceid( &desc ); rec->videoarchitecture = 2; /* Unknown */ rec->videomemorytype = 2; /* Unknown */ + wsprintfW( mode, fmtW, hres, vres, (UINT64)1 << rec->current_bitsperpixel ); + rec->videomodedescription = heap_strdupW( mode ); rec->videoprocessor = heap_strdupW( name ); if (!match_row( table, row, cond, &status )) free_row_values( table, row ); else row++; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wbemprox/query.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wbemprox/query.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wbemprox/query.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wbemprox/query.c 2016-02-08 19:32:34.000000000 +0000 @@ -266,7 +266,7 @@ if (is_int( ltype )) lstr = format_int( lbuf, ltype, lval ); else lstr = (const WCHAR *)(INT_PTR)lval; - if (is_int( rtype )) rstr = format_int( rbuf, ltype, rval ); + if (is_int( rtype )) rstr = format_int( rbuf, rtype, rval ); else rstr = (const WCHAR *)(INT_PTR)rval; return eval_strcmp( expr->op, lstr, rstr, val ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,5 +1,6 @@ MODULE = webservices.dll IMPORTLIB = webservices +IMPORTS = user32 C_SRCS = \ main.c \ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/reader.c wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/reader.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/reader.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/reader.c 2016-02-08 19:32:34.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright 2015 Hans Leidekker for CodeWeavers + * Copyright 2015, 2016 Hans Leidekker for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -164,6 +164,12 @@ return HeapAlloc( heap->handle, 0, size ); } +static void *ws_alloc_zero( WS_HEAP *handle, SIZE_T size ) +{ + struct heap *heap = (struct heap *)handle; + return HeapAlloc( heap->handle, HEAP_ZERO_MEMORY, size ); +} + void *ws_realloc( WS_HEAP *handle, void *ptr, SIZE_T size ) { struct heap *heap = (struct heap *)handle; @@ -301,7 +307,7 @@ { case WS_XML_NODE_TYPE_ELEMENT: { - WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node; + WS_XML_ELEMENT_NODE *elem = &node->hdr; ULONG i; for (i = 0; i < elem->attributeCount; i++) free_attribute( elem->attributes[i] ); @@ -323,6 +329,8 @@ heap_free( comment->value.bytes ); break; } + case WS_XML_NODE_TYPE_CDATA: + case WS_XML_NODE_TYPE_END_CDATA: case WS_XML_NODE_TYPE_END_ELEMENT: case WS_XML_NODE_TYPE_EOF: case WS_XML_NODE_TYPE_BOF: @@ -378,9 +386,13 @@ READER_STATE_INITIAL, READER_STATE_BOF, READER_STATE_STARTELEMENT, + READER_STATE_STARTATTRIBUTE, READER_STATE_STARTENDELEMENT, + READER_STATE_STARTCDATA, + READER_STATE_CDATA, READER_STATE_TEXT, READER_STATE_ENDELEMENT, + READER_STATE_ENDCDATA, READER_STATE_COMMENT, READER_STATE_EOF }; @@ -389,12 +401,13 @@ { ULONG read_size; ULONG read_pos; - const char *read_bufptr; + const unsigned char *read_bufptr; enum reader_state state; struct node *root; struct node *current; + ULONG current_attr; WS_XML_READER_INPUT_TYPE input_type; - const char *input_data; + const unsigned char *input_data; ULONG input_size; ULONG prop_count; WS_XML_READER_PROPERTY prop[sizeof(reader_props)/sizeof(reader_props[0])]; @@ -647,7 +660,7 @@ return E_NOTIMPL; } -WS_XML_STRING *alloc_xml_string( const char *data, ULONG len ) +WS_XML_STRING *alloc_xml_string( const unsigned char *data, ULONG len ) { WS_XML_STRING *ret; @@ -660,7 +673,7 @@ return ret; } -WS_XML_UTF8_TEXT *alloc_utf8_text( const char *data, ULONG len ) +WS_XML_UTF8_TEXT *alloc_utf8_text( const unsigned char *data, ULONG len ) { WS_XML_UTF8_TEXT *ret; @@ -679,7 +692,7 @@ return reader->read_pos >= reader->read_size; } -static inline const char *read_current_ptr( struct reader *reader ) +static inline const unsigned char *read_current_ptr( struct reader *reader ) { return &reader->read_bufptr[reader->read_pos]; } @@ -709,7 +722,7 @@ { unsigned int len, res; unsigned char ch = reader->read_bufptr[reader->read_pos]; - const char *end; + const unsigned char *end; if (reader->read_pos >= reader->read_size) return 0; @@ -773,7 +786,7 @@ static inline int read_cmp( struct reader *reader, const char *str, int len ) { - const char *ptr = read_current_ptr( reader ); + const unsigned char *ptr = read_current_ptr( reader ); if (len < 0) len = strlen( str ); if (reader->read_pos + len > reader->read_size) return -1; @@ -822,12 +835,38 @@ return S_OK; } +static HRESULT parse_name( const unsigned char *str, unsigned int len, + WS_XML_STRING **prefix, WS_XML_STRING **localname ) +{ + const unsigned char *name_ptr = str, *prefix_ptr = NULL; + unsigned int i, name_len = len, prefix_len = 0; + + for (i = 0; i < len; i++) + { + if (str[i] == ':') + { + prefix_ptr = str; + prefix_len = i; + name_ptr = &str[i + 1]; + name_len -= i + 1; + break; + } + } + if (!(*prefix = alloc_xml_string( prefix_ptr, prefix_len ))) return E_OUTOFMEMORY; + if (!(*localname = alloc_xml_string( name_ptr, name_len ))) + { + heap_free( *prefix ); + return E_OUTOFMEMORY; + } + return S_OK; +} + static HRESULT read_attribute( struct reader *reader, WS_XML_ATTRIBUTE **ret ) { WS_XML_ATTRIBUTE *attr; WS_XML_UTF8_TEXT *text; unsigned int len = 0, ch, skip, quote; - const char *start; + const unsigned char *start; HRESULT hr = WS_E_INVALID_FORMAT; if (!(attr = heap_alloc_zero( sizeof(*attr) ))) return E_OUTOFMEMORY; @@ -842,10 +881,9 @@ } if (!len) goto error; + if ((hr = parse_name( start, len, &attr->prefix, &attr->localName )) != S_OK) goto error; + if (!attr->prefix->length) attr->prefix->bytes = NULL; hr = E_OUTOFMEMORY; - if (!(attr->localName = alloc_xml_string( start, len ))) goto error; - if (!(attr->prefix = alloc_xml_string( NULL, 0 ))) goto error; - attr->prefix->bytes = NULL; if (!(attr->ns = alloc_xml_string( NULL, 0 ))) goto error; attr->ns->bytes = NULL; @@ -875,7 +913,7 @@ free_attribute( attr ); return E_OUTOFMEMORY; } - attr->value = (WS_XML_TEXT *)text; + attr->value = &text->text; attr->singleQuote = (quote == '\''); *ret = attr; @@ -889,7 +927,7 @@ static HRESULT read_element( struct reader *reader ) { unsigned int len = 0, ch, skip; - const char *start; + const unsigned char *start; struct node *node; WS_XML_ELEMENT_NODE *elem; WS_XML_ATTRIBUTE *attr; @@ -919,10 +957,9 @@ } if (!len) goto error; + if ((hr = parse_name( start, len, &elem->prefix, &elem->localName )) != S_OK) goto error; + if (!elem->prefix->length) elem->prefix->bytes = NULL; hr = E_OUTOFMEMORY; - if (!(elem->localName = alloc_xml_string( start, len ))) goto error; - if (!(elem->prefix = alloc_xml_string( NULL, 0 ))) goto error; - elem->prefix->bytes = NULL; if (!(elem->ns = alloc_xml_string( NULL, 0 ))) goto error; for (;;) @@ -966,7 +1003,7 @@ static HRESULT read_text( struct reader *reader ) { unsigned int len = 0, ch, skip; - const char *start; + const unsigned char *start; struct node *node; WS_XML_TEXT_NODE *text; WS_XML_UTF8_TEXT *utf8; @@ -988,7 +1025,7 @@ heap_free( node ); return E_OUTOFMEMORY; } - text->text = (WS_XML_TEXT *)utf8; + text->text = &utf8->text; read_insert_node( reader, reader->current, node ); reader->state = READER_STATE_TEXT; @@ -1031,7 +1068,7 @@ return hr; } -static BOOL cmp_localname( const char *name1, ULONG len1, const char *name2, ULONG len2 ) +static BOOL cmp_localname( const unsigned char *name1, ULONG len1, const unsigned char *name2, ULONG len2 ) { ULONG i; if (len1 != len2) return FALSE; @@ -1039,16 +1076,23 @@ return TRUE; } -static struct node *find_parent_element( struct node *node, const char *localname, ULONG len ) +struct node *find_parent_element( struct node *node, const WS_XML_STRING *prefix, + const WS_XML_STRING *localname ) { struct node *parent; - WS_XML_STRING *name; + const WS_XML_STRING *str; for (parent = node; parent; parent = parent->parent) { if (parent->hdr.node.nodeType != WS_XML_NODE_TYPE_ELEMENT) continue; - name = ((WS_XML_ELEMENT_NODE *)parent)->localName; - if (!cmp_localname( (const char *)name->bytes, name->length, localname, len )) continue; + if (!localname) return parent; + + str = parent->hdr.prefix; + if (!cmp_localname( str->bytes, str->length, prefix->bytes, prefix->length )) continue; + + str = parent->hdr.localName; + if (!cmp_localname( str->bytes, str->length, localname->bytes, localname->length )) continue; + return parent; } return NULL; @@ -1058,17 +1102,9 @@ { struct node *node, *parent; unsigned int len = 0, ch, skip; - const char *start; - - switch (reader->state) - { - case READER_STATE_TEXT: - case READER_STATE_STARTELEMENT: - case READER_STATE_STARTENDELEMENT: - break; - default: - return WS_E_INVALID_FORMAT; - } + const unsigned char *start; + WS_XML_STRING *prefix, *localname; + HRESULT hr; if (read_cmp( reader, "current, start, len ))) - return WS_E_INVALID_FORMAT; + + if ((hr = parse_name( start, len, &prefix, &localname )) != S_OK) return hr; + parent = find_parent_element( reader->current, prefix, localname ); + heap_free( prefix ); + heap_free( localname ); + if (!parent) return WS_E_INVALID_FORMAT; if (!(node = alloc_node( WS_XML_NODE_TYPE_END_ELEMENT ))) return E_OUTOFMEMORY; read_insert_node( reader, parent, node ); @@ -1098,7 +1138,7 @@ static HRESULT read_comment( struct reader *reader ) { unsigned int len = 0, ch, skip; - const char *start; + const unsigned char *start; struct node *node; WS_XML_COMMENT_NODE *comment; @@ -1133,6 +1173,63 @@ return S_OK; } +static HRESULT read_startcdata( struct reader *reader ) +{ + struct node *node; + + if (read_cmp( reader, "current, node ); + reader->state = READER_STATE_STARTCDATA; + return S_OK; +} + +static HRESULT read_cdata( struct reader *reader ) +{ + unsigned int len = 0, ch, skip; + const unsigned char *start; + struct node *node; + WS_XML_TEXT_NODE *text; + WS_XML_UTF8_TEXT *utf8; + + start = read_current_ptr( reader ); + for (;;) + { + if (!read_cmp( reader, "]]>", 3 )) break; + if (!(ch = read_utf8_char( reader, &skip ))) return WS_E_INVALID_FORMAT; + read_skip( reader, skip ); + len += skip; + } + + if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return E_OUTOFMEMORY; + text = (WS_XML_TEXT_NODE *)node; + if (!(utf8 = alloc_utf8_text( start, len ))) + { + heap_free( node ); + return E_OUTOFMEMORY; + } + text->text = &utf8->text; + + read_insert_node( reader, reader->current, node ); + reader->state = READER_STATE_CDATA; + return S_OK; +} + +static HRESULT read_endcdata( struct reader *reader ) +{ + struct node *node; + + if (read_cmp( reader, "]]>", 3 )) return WS_E_INVALID_FORMAT; + read_skip( reader, 3 ); + + if (!(node = alloc_node( WS_XML_NODE_TYPE_END_CDATA ))) return E_OUTOFMEMORY; + read_insert_node( reader, reader->current->parent, node ); + reader->state = READER_STATE_ENDCDATA; + return S_OK; +} + static HRESULT read_node( struct reader *reader ) { HRESULT hr; @@ -1146,13 +1243,16 @@ reader->state = READER_STATE_EOF; return S_OK; } - if (!read_cmp( reader, "state == READER_STATE_STARTCDATA) return read_cdata( reader ); + else if (reader->state == READER_STATE_CDATA) return read_endcdata( reader ); + else if (!read_cmp( reader, "current->hdr; + if (reader->state != READER_STATE_STARTELEMENT || index >= elem->attributeCount) + return WS_E_INVALID_FORMAT; + + reader->current_attr = index; + reader->state = READER_STATE_STARTATTRIBUTE; + return S_OK; +} + +/************************************************************************** + * WsReadEndAttribute [webservices.@] + */ +HRESULT WINAPI WsReadEndAttribute( WS_XML_READER *handle, WS_ERROR *error ) +{ + struct reader *reader = (struct reader *)handle; + + TRACE( "%p %p\n", handle, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!reader) return E_INVALIDARG; + + if (reader->state != READER_STATE_STARTATTRIBUTE) + return WS_E_INVALID_FORMAT; + + reader->state = READER_STATE_STARTELEMENT; + return S_OK; +} + static WCHAR *xmltext_to_widechar( WS_HEAP *heap, const WS_XML_TEXT *text ) { WCHAR *ret; @@ -1340,10 +1481,10 @@ #define MAX_UINT32 0xffffffff #define MAX_UINT64 (((UINT64)0xffffffff << 32) | 0xffffffff) -static HRESULT str_to_int64( const char *str, ULONG len, INT64 min, INT64 max, INT64 *ret ) +static HRESULT str_to_int64( const unsigned char *str, ULONG len, INT64 min, INT64 max, INT64 *ret ) { BOOL negative = FALSE; - const char *ptr = str; + const unsigned char *ptr = str; *ret = 0; while (len && read_isspace( *ptr )) { ptr++; len--; } @@ -1378,9 +1519,9 @@ return S_OK; } -static HRESULT str_to_uint64( const char *str, ULONG len, UINT64 max, UINT64 *ret ) +static HRESULT str_to_uint64( const unsigned char *str, ULONG len, UINT64 max, UINT64 *ret ) { - const char *ptr = str; + const unsigned char *ptr = str; *ret = 0; while (len && read_isspace( *ptr )) { ptr++; len--; } @@ -1402,179 +1543,681 @@ return S_OK; } -/************************************************************************** - * WsReadType [webservices.@] - */ -HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TYPE type, - const void *desc, WS_READ_OPTION option, WS_HEAP *heap, void *value, - ULONG value_size, WS_ERROR *error ) +static HRESULT read_get_node_text( struct reader *reader, WS_XML_UTF8_TEXT **ret ) { - struct reader *reader = (struct reader *)handle; WS_XML_TEXT_NODE *text; - TRACE( "%p %u %u %p %u %p %p %u %p\n", handle, mapping, type, desc, option, heap, value, - value_size, error ); - if (error) FIXME( "ignoring error parameter\n" ); - - if (!reader || !value) return E_INVALIDARG; - if (reader->current->hdr.node.nodeType != WS_XML_NODE_TYPE_TEXT) - { - FIXME( "only text nodes are supported\n" ); - return E_NOTIMPL; - } + return WS_E_INVALID_FORMAT; + text = (WS_XML_TEXT_NODE *)&reader->current->hdr.node; if (text->text->textType != WS_XML_TEXT_TYPE_UTF8) { FIXME( "text type %u not supported\n", text->text->textType ); return E_NOTIMPL; } + *ret = (WS_XML_UTF8_TEXT *)text->text; + return S_OK; +} + +static HRESULT read_get_attribute_text( struct reader *reader, WS_XML_UTF8_TEXT **ret ) +{ + WS_XML_ELEMENT_NODE *elem = &reader->current->hdr; + WS_XML_ATTRIBUTE *attr; + + if (reader->current->hdr.node.nodeType != WS_XML_NODE_TYPE_ELEMENT || + reader->current_attr >= elem->attributeCount) return WS_E_INVALID_FORMAT; + + attr = elem->attributes[reader->current_attr]; + if (attr->value->textType != WS_XML_TEXT_TYPE_UTF8) + { + FIXME( "text type %u not supported\n", attr->value->textType ); + return E_NOTIMPL; + } + *ret = (WS_XML_UTF8_TEXT *)attr->value; + reader->current_attr++; + return S_OK; +} + +static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_BOOL_DESCRIPTION *desc, BOOL *ret ) +{ + WS_XML_UTF8_TEXT *utf8; + HRESULT hr; + ULONG len; + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } switch (mapping) { + case WS_ATTRIBUTE_TYPE_MAPPING: + if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr; + len = utf8->value.length; + break; + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr; + len = utf8->value.length; break; + default: FIXME( "mapping %u not supported\n", mapping ); return E_NOTIMPL; } - switch (type) - { - case WS_BOOL_TYPE: + if (len == 4 && !memcmp( utf8->value.bytes, "true", 4 )) *ret = TRUE; + else if (len == 1 && !memcmp( utf8->value.bytes, "1", 1 )) *ret = TRUE; + else if (len == 5 && !memcmp( utf8->value.bytes, "false", 5 )) *ret = FALSE; + else if (len == 1 && !memcmp( utf8->value.bytes, "0", 1 )) *ret = FALSE; + else return WS_E_INVALID_FORMAT; + + return S_OK; +} + +static HRESULT read_type_int8( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_INT8_DESCRIPTION *desc, INT8 *ret ) +{ + WS_XML_UTF8_TEXT *utf8; + HRESULT hr; + INT64 val; + + if (desc) { - WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; - ULONG len = utf8->value.length; - BOOL *ret = value; - - if (value_size != sizeof(BOOL)) return E_INVALIDARG; - - if (len == 4 && !memcmp( utf8->value.bytes, "true", 4 )) *ret = TRUE; - else if (len == 1 && !memcmp( utf8->value.bytes, "1", 1 )) *ret = TRUE; - else if (len == 5 && !memcmp( utf8->value.bytes, "false", 5 )) *ret = FALSE; - else if (len == 1 && !memcmp( utf8->value.bytes, "0", 1 )) *ret = FALSE; - else return WS_E_INVALID_FORMAT; - break; + FIXME( "description not supported\n" ); + return E_NOTIMPL; } - case WS_INT8_TYPE: + switch (mapping) { - WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; - INT8 *ret = value; - HRESULT hr; - INT64 val; - - if (value_size != sizeof(INT8)) return E_INVALIDARG; - hr = str_to_int64( (const char *)utf8->value.bytes, utf8->value.length, MIN_INT8, MAX_INT8, &val ); - if (hr != S_OK) return hr; - *ret = val; + case WS_ATTRIBUTE_TYPE_MAPPING: + if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr; break; - } - case WS_INT16_TYPE: - { - WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; - INT16 *ret = value; - HRESULT hr; - INT64 val; - if (value_size != sizeof(INT16)) return E_INVALIDARG; - hr = str_to_int64( (const char *)utf8->value.bytes, utf8->value.length, MIN_INT16, MAX_INT16, &val ); - if (hr != S_OK) return hr; - *ret = val; + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr; break; - } - case WS_INT32_TYPE: - { - WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; - INT32 *ret = value; - HRESULT hr; - INT64 val; - if (value_size != sizeof(INT32)) return E_INVALIDARG; - hr = str_to_int64( (const char *)utf8->value.bytes, utf8->value.length, MIN_INT32, MAX_INT32, &val ); - if (hr != S_OK) return hr; - *ret = val; - break; + default: + FIXME( "mapping %u not supported\n", mapping ); + return E_NOTIMPL; } - case WS_INT64_TYPE: - { - WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; - INT64 val, *ret = value; - HRESULT hr; - if (value_size != sizeof(INT64)) return E_INVALIDARG; - hr = str_to_int64( (const char *)utf8->value.bytes, utf8->value.length, MIN_INT64, MAX_INT64, &val ); - if (hr != S_OK) return hr; - *ret = val; - break; + if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT8, MAX_INT8, &val )) != S_OK) + return hr; + + *ret = val; + return S_OK; +} + +static HRESULT read_type_int16( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_INT16_DESCRIPTION *desc, INT16 *ret ) +{ + WS_XML_UTF8_TEXT *utf8; + HRESULT hr; + INT64 val; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; } - case WS_UINT8_TYPE: + switch (mapping) { - WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; - UINT8 *ret = value; - HRESULT hr; - UINT64 val; + case WS_ATTRIBUTE_TYPE_MAPPING: + if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr; + break; - if (value_size != sizeof(UINT8)) return E_INVALIDARG; - hr = str_to_uint64( (const char *)utf8->value.bytes, utf8->value.length, MAX_UINT8, &val ); - if (hr != S_OK) return hr; - *ret = val; + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr; break; + + default: + FIXME( "mapping %u not supported\n", mapping ); + return E_NOTIMPL; } - case WS_UINT16_TYPE: - { - WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; - UINT16 *ret = value; - HRESULT hr; - UINT64 val; - if (value_size != sizeof(UINT16)) return E_INVALIDARG; - hr = str_to_uint64( (const char *)utf8->value.bytes, utf8->value.length, MAX_UINT16, &val ); - if (hr != S_OK) return hr; - *ret = val; - break; + if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT16, MAX_INT16, &val )) != S_OK) + return hr; + + *ret = val; + return S_OK; +} + +static HRESULT read_type_int32( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_INT32_DESCRIPTION *desc, INT32 *ret ) +{ + WS_XML_UTF8_TEXT *utf8; + HRESULT hr; + INT64 val; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; } - case WS_UINT32_TYPE: + switch (mapping) { - WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; - UINT32 *ret = value; - HRESULT hr; - UINT64 val; + case WS_ATTRIBUTE_TYPE_MAPPING: + if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr; + break; - if (value_size != sizeof(UINT32)) return E_INVALIDARG; - hr = str_to_uint64( (const char *)utf8->value.bytes, utf8->value.length, MAX_UINT32, &val ); - if (hr != S_OK) return hr; - *ret = val; + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr; break; + + default: + FIXME( "mapping %u not supported\n", mapping ); + return E_NOTIMPL; } - case WS_UINT64_TYPE: - { - WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; - UINT64 val, *ret = value; - HRESULT hr; - if (value_size != sizeof(UINT64)) return E_INVALIDARG; - hr = str_to_uint64( (const char *)utf8->value.bytes, utf8->value.length, MAX_UINT64, &val ); - if (hr != S_OK) return hr; - *ret = val; - break; + if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT32, MAX_INT32, &val )) != S_OK) + return hr; + + *ret = val; + return S_OK; +} + +static HRESULT read_type_int64( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_INT64_DESCRIPTION *desc, INT64 *ret ) +{ + WS_XML_UTF8_TEXT *utf8; + HRESULT hr; + INT64 val; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; } - case WS_WSZ_TYPE: + switch (mapping) { - WCHAR *str, **ret = value; + case WS_ATTRIBUTE_TYPE_MAPPING: + if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr; + break; - if (value_size != sizeof(WCHAR *)) return E_INVALIDARG; - if (!(str = xmltext_to_widechar( heap, text->text ))) return E_OUTOFMEMORY; - *ret = str; + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr; break; - } + default: - FIXME( "type %u not supported\n", type ); + FIXME( "mapping %u not supported\n", mapping ); return E_NOTIMPL; } + if ((hr = str_to_int64( utf8->value.bytes, utf8->value.length, MIN_INT64, MAX_INT64, &val )) != S_OK) + return hr; + + *ret = val; return S_OK; } +static HRESULT read_type_uint8( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_UINT8_DESCRIPTION *desc, UINT8 *ret ) +{ + WS_XML_UTF8_TEXT *utf8; + HRESULT hr; + UINT64 val; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + switch (mapping) + { + case WS_ATTRIBUTE_TYPE_MAPPING: + if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr; + break; + + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr; + break; + + default: + FIXME( "mapping %u not supported\n", mapping ); + return E_NOTIMPL; + } + + if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT8, &val )) != S_OK) + return hr; + + *ret = val; + return S_OK; +} + +static HRESULT read_type_uint16( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_UINT16_DESCRIPTION *desc, UINT16 *ret ) +{ + WS_XML_UTF8_TEXT *utf8; + HRESULT hr; + UINT64 val; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + switch (mapping) + { + case WS_ATTRIBUTE_TYPE_MAPPING: + if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr; + break; + + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr; + break; + + default: + FIXME( "mapping %u not supported\n", mapping ); + return E_NOTIMPL; + } + + if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT16, &val )) != S_OK) + return hr; + + *ret = val; + return S_OK; +} + +static HRESULT read_type_uint32( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_UINT32_DESCRIPTION *desc, UINT32 *ret ) +{ + WS_XML_UTF8_TEXT *utf8; + HRESULT hr; + UINT64 val; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + switch (mapping) + { + case WS_ATTRIBUTE_TYPE_MAPPING: + if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr; + break; + + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr; + break; + + default: + FIXME( "mapping %u not supported\n", mapping ); + return E_NOTIMPL; + } + + if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT32, &val )) != S_OK) + return hr; + + *ret = val; + return S_OK; +} + +static HRESULT read_type_uint64( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_UINT64_DESCRIPTION *desc, UINT64 *ret ) +{ + WS_XML_UTF8_TEXT *utf8; + HRESULT hr; + UINT64 val; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + switch (mapping) + { + case WS_ATTRIBUTE_TYPE_MAPPING: + if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr; + break; + + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr; + break; + + default: + FIXME( "mapping %u not supported\n", mapping ); + return E_NOTIMPL; + } + + if ((hr = str_to_uint64( utf8->value.bytes, utf8->value.length, MAX_UINT64, &val )) != S_OK) + return hr; + + *ret = val; + return S_OK; +} + +static HRESULT read_type_wsz( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_WSZ_DESCRIPTION *desc, WS_HEAP *heap, WCHAR **ret ) +{ + WS_XML_UTF8_TEXT *utf8; + HRESULT hr; + WCHAR *str; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + switch (mapping) + { + case WS_ATTRIBUTE_TYPE_MAPPING: + if ((hr = read_get_attribute_text( reader, &utf8 )) != S_OK) return hr; + break; + + case WS_ELEMENT_TYPE_MAPPING: + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_get_node_text( reader, &utf8 )) != S_OK) return hr; + break; + + default: + FIXME( "mapping %u not supported\n", mapping ); + return E_NOTIMPL; + } + + if (!(str = xmltext_to_widechar( heap, &utf8->text ))) return WS_E_QUOTA_EXCEEDED; + *ret = str; + return S_OK; +} + +static HRESULT read_type_struct( struct reader *, WS_TYPE_MAPPING, const WS_STRUCT_DESCRIPTION *, + WS_HEAP *, void ** ); + +static HRESULT read_type_struct_field( struct reader *reader, const WS_FIELD_DESCRIPTION *desc, + WS_HEAP *heap, char *buf ) +{ + char *ptr = buf + desc->offset; + WS_TYPE_MAPPING mapping; + HRESULT hr; + + if (desc->options && desc->options != WS_FIELD_POINTER && + desc->options != WS_FIELD_OPTIONAL && + desc->options != (WS_FIELD_POINTER | WS_FIELD_OPTIONAL)) + { + FIXME( "options 0x%x not supported\n", desc->options ); + return E_NOTIMPL; + } + + switch (desc->mapping) + { + case WS_ATTRIBUTE_FIELD_MAPPING: + mapping = WS_ATTRIBUTE_TYPE_MAPPING; + break; + + case WS_ELEMENT_FIELD_MAPPING: + mapping = WS_ELEMENT_TYPE_MAPPING; + break; + + default: + FIXME( "unhandled field mapping %u\n", desc->mapping ); + return E_NOTIMPL; + } + + switch (desc->type) + { + case WS_STRUCT_TYPE: + hr = read_type_struct( reader, mapping, desc->typeDescription, heap, (void **)ptr ); + break; + + case WS_BOOL_TYPE: + hr = read_type_bool( reader, mapping, desc->typeDescription, (BOOL *)ptr ); + break; + + case WS_INT8_TYPE: + hr = read_type_int8( reader, mapping, desc->typeDescription, (INT8 *)ptr ); + break; + + case WS_INT16_TYPE: + hr = read_type_int16( reader, mapping, desc->typeDescription, (INT16 *)ptr ); + break; + + case WS_INT32_TYPE: + hr = read_type_int32( reader, mapping, desc->typeDescription, (INT32 *)ptr ); + break; + + case WS_INT64_TYPE: + hr = read_type_int64( reader, mapping, desc->typeDescription, (INT64 *)ptr ); + break; + + case WS_UINT8_TYPE: + hr = read_type_uint8( reader, mapping, desc->typeDescription, (UINT8 *)ptr ); + break; + + case WS_UINT16_TYPE: + hr = read_type_uint16( reader, mapping, desc->typeDescription, (UINT16 *)ptr ); + break; + + case WS_UINT32_TYPE: + hr = read_type_uint32( reader, mapping, desc->typeDescription, (UINT32 *)ptr ); + break; + + case WS_UINT64_TYPE: + hr = read_type_uint64( reader, mapping, desc->typeDescription, (UINT64 *)ptr ); + break; + + case WS_WSZ_TYPE: + hr = read_type_wsz( reader, mapping, desc->typeDescription, heap, (WCHAR **)ptr ); + break; + + default: + FIXME( "type %u not implemented\n", desc->type ); + return E_NOTIMPL; + } + + return hr; +} + +static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, + const WS_STRUCT_DESCRIPTION *desc, WS_HEAP *heap, void **ret ) +{ + ULONG i; + HRESULT hr; + char *buf; + + if (!desc) return E_INVALIDARG; + + if (desc->structOptions) + { + FIXME( "struct options 0x%x not supported\n", desc->structOptions ); + return E_NOTIMPL; + } + + switch (mapping) + { + case WS_ELEMENT_TYPE_MAPPING: + if ((hr = read_to_startelement( reader, NULL )) != S_OK) return hr; + break; + + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_to_startelement( reader, NULL )) != S_OK) return hr; + if ((hr = read_startelement( reader )) != S_OK) return hr; + break; + + default: + FIXME( "unhandled mapping %u\n", mapping ); + return E_NOTIMPL; + } + + if (!(buf = ws_alloc_zero( heap, desc->size ))) return WS_E_QUOTA_EXCEEDED; + + for (i = 0; i < desc->fieldCount; i++) + { + if ((hr = read_type_struct_field( reader, desc->fields[i], heap, buf )) != S_OK) + { + ws_free( heap, buf ); + return hr; + } + } + + switch (mapping) + { + case WS_ELEMENT_TYPE_MAPPING: + if ((hr = read_endelement( reader )) != S_OK) return hr; + break; + + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = read_endelement( reader )) != S_OK) return hr; + if ((hr = read_node( reader )) != S_OK) return hr; + if (reader->state != READER_STATE_EOF) return WS_E_INVALID_FORMAT; + break; + + default: break; + } + + *ret = buf; + return S_OK; +} + +static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYPE type, + const void *desc, WS_READ_OPTION option, WS_HEAP *heap, + void *value, ULONG size ) +{ + switch (type) + { + case WS_STRUCT_TYPE: + { + void **ptr = value; + if (option != WS_READ_REQUIRED_POINTER || size != sizeof(*ptr)) + return E_INVALIDARG; + + return read_type_struct( reader, mapping, desc, heap, ptr ); + } + case WS_BOOL_TYPE: + { + BOOL *ptr = value; + if (option != WS_READ_REQUIRED_VALUE) + { + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + if (size != sizeof(*ptr)) return E_INVALIDARG; + return read_type_bool( reader, mapping, desc, ptr ); + } + case WS_INT8_TYPE: + { + INT8 *ptr = value; + if (option != WS_READ_REQUIRED_VALUE) + { + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + if (size != sizeof(*ptr)) return E_INVALIDARG; + return read_type_int8( reader, mapping, desc, ptr ); + } + case WS_INT16_TYPE: + { + INT16 *ptr = value; + if (option != WS_READ_REQUIRED_VALUE) + { + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + if (size != sizeof(*ptr)) return E_INVALIDARG; + return read_type_int16( reader, mapping, desc, ptr ); + } + case WS_INT32_TYPE: + { + INT32 *ptr = value; + if (option != WS_READ_REQUIRED_VALUE) + { + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + if (size != sizeof(*ptr)) return E_INVALIDARG; + return read_type_int32( reader, mapping, desc, ptr ); + } + case WS_INT64_TYPE: + { + INT64 *ptr = value; + if (option != WS_READ_REQUIRED_VALUE) + { + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + if (size != sizeof(*ptr)) return E_INVALIDARG; + return read_type_int64( reader, mapping, desc, ptr ); + } + case WS_UINT8_TYPE: + { + UINT8 *ptr = value; + if (option != WS_READ_REQUIRED_VALUE) + { + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + if (size != sizeof(*ptr)) return E_INVALIDARG; + return read_type_uint8( reader, mapping, desc, ptr ); + } + case WS_UINT16_TYPE: + { + UINT16 *ptr = value; + if (option != WS_READ_REQUIRED_VALUE) + { + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + if (size != sizeof(*ptr)) return E_INVALIDARG; + return read_type_uint16( reader, mapping, desc, ptr ); + } + case WS_UINT32_TYPE: + { + UINT32 *ptr = value; + if (option != WS_READ_REQUIRED_VALUE) + { + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + if (size != sizeof(*ptr)) return E_INVALIDARG; + return read_type_uint32( reader, mapping, desc, ptr ); + } + case WS_UINT64_TYPE: + { + UINT64 *ptr = value; + if (option != WS_READ_REQUIRED_VALUE) + { + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + if (size != sizeof(*ptr)) return E_INVALIDARG; + return read_type_uint64( reader, mapping, desc, ptr ); + } + case WS_WSZ_TYPE: + { + WCHAR **ptr = value; + if (option != WS_READ_REQUIRED_POINTER) + { + FIXME( "read option %u not supported\n", option ); + return E_NOTIMPL; + } + if (size != sizeof(*ptr)) return E_INVALIDARG; + return read_type_wsz( reader, mapping, desc, heap, ptr ); + } + default: + FIXME( "type %u not supported\n", type ); + return E_NOTIMPL; + } +} + +/************************************************************************** + * WsReadType [webservices.@] + */ +HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TYPE type, + const void *desc, WS_READ_OPTION option, WS_HEAP *heap, void *value, + ULONG size, WS_ERROR *error ) +{ + struct reader *reader = (struct reader *)handle; + + TRACE( "%p %u %u %p %u %p %p %u %p\n", handle, mapping, type, desc, option, heap, value, + size, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!reader || !value) return E_INVALIDARG; + + return read_type( reader, mapping, type, desc, option, heap, value, size ); +} + /************************************************************************** * WsSetErrorProperty [webservices.@] */ @@ -1625,7 +2268,7 @@ return ret; } -static void set_input_buffer( struct reader *reader, const char *data, ULONG size ) +static void set_input_buffer( struct reader *reader, const unsigned char *data, ULONG size ) { reader->input_type = WS_XML_READER_INPUT_TYPE_BUFFER; reader->input_data = data; @@ -1691,7 +2334,7 @@ case WS_XML_READER_INPUT_TYPE_BUFFER: { WS_XML_READER_BUFFER_INPUT *buf = (WS_XML_READER_BUFFER_INPUT *)input; - set_input_buffer( reader, (const char *)buf->encodedData + offset, buf->encodedDataSize - offset ); + set_input_buffer( reader, (const unsigned char *)buf->encodedData + offset, buf->encodedDataSize - offset ); break; } default: @@ -1735,7 +2378,7 @@ hr = set_reader_prop( reader, WS_XML_READER_PROPERTY_CHARSET, &charset, sizeof(charset) ); if (hr != S_OK) return hr; - set_input_buffer( reader, (const char *)xmlbuf->ptr + offset, xmlbuf->size - offset ); + set_input_buffer( reader, (const unsigned char *)xmlbuf->ptr + offset, xmlbuf->size - offset ); if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY; read_insert_bof( reader, node ); return S_OK; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/tests/reader.c wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/tests/reader.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/tests/reader.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/tests/reader.c 2016-02-08 19:32:34.000000000 +0000 @@ -869,6 +869,39 @@ ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType ); ok( !memcmp( elem->localName->bytes, "node2", 5), "wrong name\n" ); } + + hr = WsReadNode( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType ); + + hr = WsReadNode( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType ); + + hr = WsReadEndElement( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType ); + + /* WsReadEndElement advances reader to EOF */ + hr = WsReadEndElement( reader, NULL ); + todo_wine ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + todo_wine if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType ); + + hr = WsReadEndElement( reader, NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + WsFreeReader( reader ); } @@ -924,6 +957,40 @@ ok( hr == S_OK, "got %08x\n", hr ); if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType ); + hr = set_input( reader, data2, sizeof(data2) - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsFillReader( reader, sizeof(data2) - 1, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadStartElement( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + if (node) ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType ); + + hr = WsReadNode( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType ); + + /* WsReadEndElement advances reader to EOF */ + hr = WsReadEndElement( reader, NULL ); + todo_wine ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + todo_wine if (node) ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType ); + + hr = WsReadEndElement( reader, NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + hr = set_input( reader, data5, sizeof(data5) - 1 ); ok( hr == S_OK, "got %08x\n", hr ); @@ -1640,6 +1707,170 @@ WsFreeHeap( heap ); } +static void prepare_struct_type_test( WS_XML_READER *reader, const char *data ) +{ + HRESULT hr; + ULONG size = strlen( data ); + + hr = set_input( reader, data, size ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsFillReader( reader, size, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); +} + +static void test_simple_struct_type(void) +{ + static const WCHAR testW[] = {'t','e','s','t',0}; + HRESULT hr; + WS_XML_READER *reader; + WS_HEAP *heap; + WS_STRUCT_DESCRIPTION s; + WS_FIELD_DESCRIPTION f, *fields[1]; + WS_XML_STRING ns = {0, NULL}, localname = {3, (BYTE *)"str"}; + WS_XML_STRING localname2 = {4, (BYTE *)"test"}; + const WS_XML_NODE *node; + struct test { WCHAR *str; } *test; + + hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsCreateReader( NULL, 0, &reader, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + prepare_struct_type_test( reader, "test" ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( node->nodeType == WS_XML_NODE_TYPE_BOF, "got %u\n", node->nodeType ); + + /* element field mapping */ + memset( &f, 0, sizeof(f) ); + f.mapping = WS_ELEMENT_FIELD_MAPPING; + f.localName = &localname; + f.ns = &ns; + f.type = WS_WSZ_TYPE; + fields[0] = &f; + + memset( &s, 0, sizeof(s) ); + s.size = sizeof(struct test); + s.alignment = TYPE_ALIGNMENT(struct test); + s.fields = fields; + s.fieldCount = 1; + s.typeLocalName = &localname2; + s.typeNs = &ns; + + test = NULL; + prepare_struct_type_test( reader, "testtest2" ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + + test = NULL; + prepare_struct_type_test( reader, "test" ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( test != NULL, "test not set\n" ); + if (test) + { + ok( test->str != NULL, "str not set\n" ); + if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" ); + } + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType ); + + test = NULL; + prepare_struct_type_test( reader, "test" ); + hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( test != NULL, "test not set\n" ); + if (test) + { + ok( test->str != NULL, "str not set\n" ); + if (test->str) ok( !lstrcmpW( test->str, testW ), "wrong data\n" ); + } + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( node->nodeType == WS_XML_NODE_TYPE_EOF, "got %u\n", node->nodeType ); + + WsFreeReader( reader ); + WsFreeHeap( heap ); +} + +static void test_cdata(void) +{ + static const char test[] = "]]>"; + HRESULT hr; + WS_XML_READER *reader; + const WS_XML_NODE *node; + + hr = WsCreateReader( NULL, 0, &reader, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + hr = set_input( reader, test, sizeof(test) - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsFillReader( reader, sizeof(test) - 1, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadNode( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + if (node) ok( node->nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", node->nodeType ); + + hr = WsReadNode( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + if (node) ok( node->nodeType == WS_XML_NODE_TYPE_CDATA, "got %u\n", node->nodeType ); + + hr = WsReadNode( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + if (node) + { + WS_XML_TEXT_NODE *text = (WS_XML_TEXT_NODE *)node; + ok( node->nodeType == WS_XML_NODE_TYPE_TEXT, "got %u\n", node->nodeType ); + ok( text->text != NULL, "text not set\n" ); + if (text->text) + { + WS_XML_UTF8_TEXT *utf8 = (WS_XML_UTF8_TEXT *)text->text; + ok( utf8->text.textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", utf8->text.textType ); + ok( utf8->value.length == 6, "got %u\n", utf8->value.length ); + ok( !memcmp( utf8->value.bytes, "", 6 ), "wrong data\n" ); + } + } + + hr = WsReadNode( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_CDATA, "got %u\n", node->nodeType ); + + hr = WsReadNode( reader, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + if (node) ok( node->nodeType == WS_XML_NODE_TYPE_END_ELEMENT, "got %u\n", node->nodeType ); + + WsFreeReader( reader ); +} + START_TEST(reader) { test_WsCreateError(); @@ -1657,4 +1888,6 @@ test_WsXmlStringEquals(); test_WsAlloc(); test_WsMoveReader(); + test_simple_struct_type(); + test_cdata(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/tests/writer.c wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/tests/writer.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/tests/writer.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/tests/writer.c 2016-02-08 19:32:34.000000000 +0000 @@ -449,6 +449,576 @@ WsFreeWriter( writer ); } +static void test_WsWriteType(void) +{ + static const WCHAR testW[] = {'t','e','s','t',0}; + HRESULT hr; + WS_XML_WRITER *writer; + WS_XML_STRING prefix = {1, (BYTE*)"p"}, localname = {3, (BYTE *)"str"}, ns = {2, (BYTE *)"ns"}; + const WCHAR *val_str; + + hr = WsCreateWriter( NULL, 0, &writer, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + val_str = testW; + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_WRITE_REQUIRED_POINTER, &val_str, sizeof(val_str), NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, &prefix, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* required value */ + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_WRITE_REQUIRED_VALUE, NULL, sizeof(testW), NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_WRITE_REQUIRED_VALUE, testW, sizeof(testW), NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + /* required pointer */ + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_WRITE_REQUIRED_POINTER, NULL, sizeof(val_str), NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_WRITE_REQUIRED_POINTER, &val_str, sizeof(WCHAR **), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "test", __LINE__ ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "test", __LINE__ ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, &prefix, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartAttribute( writer, NULL, &localname, &ns, FALSE, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + val_str = testW; + hr = WsWriteType( writer, WS_ATTRIBUTE_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_WRITE_REQUIRED_POINTER, &val_str, sizeof(val_str), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "", __LINE__ ); + + hr = WsWriteEndAttribute( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "", __LINE__ ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "", __LINE__ ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, &prefix, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + val_str = testW; + hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_WSZ_TYPE, NULL, + WS_WRITE_REQUIRED_POINTER, &val_str, sizeof(val_str), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "test", __LINE__ ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "test", __LINE__ ); + + WsFreeWriter( writer ); +} + +static void test_basic_type(void) +{ + HRESULT hr; + WS_XML_WRITER *writer; + WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL}; + ULONG i; + static const struct + { + WS_TYPE type; + INT64 val; + ULONG size; + const char *result; + const char *result2; + } + tests[] = + { + { WS_BOOL_TYPE, TRUE, sizeof(BOOL), "true", "" }, + { WS_BOOL_TYPE, FALSE, sizeof(BOOL), "false", "" }, + { WS_INT8_TYPE, -128, sizeof(INT8), "-128", "" }, + { WS_INT16_TYPE, -32768, sizeof(INT16), "-32768", "" }, + { WS_INT32_TYPE, -2147483647 - 1, sizeof(INT32), "-2147483648", + "" }, + { WS_INT64_TYPE, -9223372036854775807 - 1, sizeof(INT64), "-9223372036854775808", + "" }, + { WS_UINT8_TYPE, 255, sizeof(UINT8), "255", "" }, + { WS_UINT16_TYPE, 65535, sizeof(UINT16), "65535", "" }, + { WS_UINT32_TYPE, ~0u, sizeof(UINT32), "4294967295", "" }, + { WS_UINT64_TYPE, ~0, sizeof(UINT64), "18446744073709551615", + "" }, + }; + + hr = WsCreateWriter( NULL, 0, &writer, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + /* element content type mapping */ + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, tests[i].type, NULL, + WS_WRITE_REQUIRED_VALUE, &tests[i].val, tests[i].size, NULL ); + ok( hr == S_OK, "%u: got %08x\n", i, hr ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, tests[i].result, __LINE__ ); + } + + /* element type mapping is the same as element content type mapping for basic types */ + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, tests[i].type, NULL, + WS_WRITE_REQUIRED_VALUE, &tests[i].val, tests[i].size, NULL ); + ok( hr == S_OK, "%u: got %08x\n", i, hr ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, tests[i].result, __LINE__ ); + } + + /* attribute type mapping */ + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartAttribute( writer, NULL, &localname, &ns, FALSE, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteType( writer, WS_ATTRIBUTE_TYPE_MAPPING, tests[i].type, NULL, + WS_WRITE_REQUIRED_VALUE, &tests[i].val, tests[i].size, NULL ); + ok( hr == S_OK, "%u: got %08x\n", i, hr ); + + hr = WsWriteEndAttribute( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, tests[i].result2, __LINE__ ); + } + + WsFreeWriter( writer ); +} + +static void test_simple_struct_type(void) +{ + static const WCHAR valueW[] = {'v','a','l','u','e',0}; + HRESULT hr; + WS_XML_WRITER *writer; + WS_STRUCT_DESCRIPTION s; + WS_FIELD_DESCRIPTION f, *fields[1]; + WS_XML_STRING localname = {6, (BYTE *)"struct"}, ns = {0, NULL}; + struct test + { + const WCHAR *field; + } *test; + + hr = WsCreateWriter( NULL, 0, &writer, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + memset( &f, 0, sizeof(f) ); + f.mapping = WS_TEXT_FIELD_MAPPING; + f.type = WS_WSZ_TYPE; + fields[0] = &f; + + memset( &s, 0, sizeof(s) ); + s.size = sizeof(struct test); + s.alignment = TYPE_ALIGNMENT(struct test); + s.fields = fields; + s.fieldCount = 1; + + test = HeapAlloc( GetProcessHeap(), 0, sizeof(*test) ); + test->field = valueW; + hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, NULL, + WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "value", __LINE__ ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteType( writer, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "value", __LINE__ ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartAttribute( writer, NULL, &localname, &ns, FALSE, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteType( writer, WS_ATTRIBUTE_TYPE_MAPPING, WS_STRUCT_TYPE, &s, + WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteEndAttribute( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "", __LINE__ ); + + HeapFree( GetProcessHeap(), 0, test ); + WsFreeWriter( writer ); +} + +static void test_WsWriteElement(void) +{ + static const WCHAR testW[] = {'t','e','s','t',0}; + HRESULT hr; + WS_XML_WRITER *writer; + WS_STRUCT_DESCRIPTION s; + WS_FIELD_DESCRIPTION f, *fields[1]; + WS_ELEMENT_DESCRIPTION desc; + WS_XML_STRING localname = {3, (BYTE *)"str"}, ns = {0, NULL}; + struct test { const WCHAR *str; } *test; + + hr = WsCreateWriter( NULL, 0, &writer, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* text field mapping */ + memset( &f, 0, sizeof(f) ); + f.mapping = WS_TEXT_FIELD_MAPPING; + f.type = WS_WSZ_TYPE; + fields[0] = &f; + + memset( &s, 0, sizeof(s) ); + s.size = sizeof(struct test); + s.alignment = TYPE_ALIGNMENT(struct test); + s.fields = fields; + s.fieldCount = 1; + + desc.elementLocalName = &localname; + desc.elementNs = &ns; + desc.type = WS_STRUCT_TYPE; + desc.typeDescription = &s; + + test = HeapAlloc( GetProcessHeap(), 0, sizeof(*test) ); + test->str = testW; + hr = WsWriteElement( NULL, &desc, WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsWriteElement( writer, NULL, WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsWriteElement( writer, &desc, WS_WRITE_REQUIRED_POINTER, NULL, 0, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsWriteElement( writer, &desc, WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "test", __LINE__ ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteElement( writer, &desc, WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "test", __LINE__ ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* attribute field mapping */ + f.mapping = WS_ATTRIBUTE_FIELD_MAPPING; + + /* requires localName and ns to be set */ + hr = WsWriteElement( writer, &desc, WS_WRITE_REQUIRED_POINTER, NULL, 0, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + f.localName = &localname; + f.ns = &ns; + hr = WsWriteElement( writer, &desc, WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "", __LINE__ ); + + HeapFree( GetProcessHeap(), 0, test ); + WsFreeWriter( writer ); +} + +static void test_WsWriteValue(void) +{ + HRESULT hr; + WS_XML_WRITER *writer; + WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL}; + ULONG i; + static const struct + { + WS_VALUE_TYPE type; + INT64 val; + ULONG size; + const char *result; + const char *result2; + } + tests[] = + { + { WS_BOOL_VALUE_TYPE, ~0, sizeof(BOOL), "true", "" }, + { WS_BOOL_VALUE_TYPE, FALSE, sizeof(BOOL), "false", "" }, + { WS_INT8_VALUE_TYPE, -128, sizeof(INT8), "-128", "" }, + { WS_INT16_VALUE_TYPE, -32768, sizeof(INT16), "-32768", "" }, + { WS_INT32_VALUE_TYPE, -2147483647 - 1, sizeof(INT32), "-2147483648", + "" }, + { WS_INT64_VALUE_TYPE, -9223372036854775807 - 1, sizeof(INT64), "-9223372036854775808", + "" }, + { WS_UINT8_VALUE_TYPE, 255, sizeof(UINT8), "255", "" }, + { WS_UINT16_VALUE_TYPE, 65535, sizeof(UINT16), "65535", "" }, + { WS_UINT32_VALUE_TYPE, ~0u, sizeof(UINT32), "4294967295", "" }, + { WS_UINT64_VALUE_TYPE, ~0, sizeof(UINT64), "18446744073709551615", + "" }, + }; + + hr = WsCreateWriter( NULL, 0, &writer, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteValue( NULL, tests[0].type, &tests[0].val, tests[0].size, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsWriteValue( writer, tests[0].type, &tests[0].val, tests[0].size, NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* zero size */ + hr = WsWriteValue( writer, tests[0].type, &tests[0].val, 0, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* NULL value */ + hr = WsWriteValue( writer, tests[0].type, NULL, 0, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + /* element type mapping */ + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteValue( writer, tests[i].type, &tests[i].val, tests[i].size, NULL ); + ok( hr == S_OK, "%u: got %08x\n", i, hr ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, tests[i].result, __LINE__ ); + } + + /* attribute type mapping */ + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartAttribute( writer, NULL, &localname, &ns, FALSE, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteValue( writer, tests[i].type, &tests[i].val, tests[i].size, NULL ); + ok( hr == S_OK, "%u: got %08x\n", i, hr ); + + hr = WsWriteEndAttribute( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, tests[i].result2, __LINE__ ); + } + + WsFreeWriter( writer ); +} + +static void test_WsWriteAttribute(void) +{ + static const WCHAR testW[] = {'t','e','s','t',0}; + HRESULT hr; + WS_XML_WRITER *writer; + WS_STRUCT_DESCRIPTION s; + WS_FIELD_DESCRIPTION f, *fields[1]; + WS_ATTRIBUTE_DESCRIPTION desc; + WS_XML_STRING localname = {3, (BYTE *)"str"}, ns = {0, NULL}; + struct test { const WCHAR *str; } *test; + + hr = WsCreateWriter( NULL, 0, &writer, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + /* text field mapping */ + memset( &f, 0, sizeof(f) ); + f.mapping = WS_TEXT_FIELD_MAPPING; + f.type = WS_WSZ_TYPE; + fields[0] = &f; + + memset( &s, 0, sizeof(s) ); + s.size = sizeof(struct test); + s.alignment = TYPE_ALIGNMENT(struct test); + s.fields = fields; + s.fieldCount = 1; + + desc.attributeLocalName = &localname; + desc.attributeNs = &ns; + desc.type = WS_STRUCT_TYPE; + desc.typeDescription = &s; + + test = HeapAlloc( GetProcessHeap(), 0, sizeof(*test) ); + test->str = testW; + hr = WsWriteAttribute( NULL, &desc, WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsWriteAttribute( writer, NULL, WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsWriteAttribute( writer, &desc, WS_WRITE_REQUIRED_POINTER, NULL, 0, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsWriteAttribute( writer, &desc, WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteAttribute( writer, &desc, WS_WRITE_REQUIRED_POINTER, &test, sizeof(test), NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "", __LINE__ ); + + HeapFree( GetProcessHeap(), 0, test ); + WsFreeWriter( writer ); +} + +static void test_WsWriteStartCData(void) +{ + HRESULT hr; + WS_XML_WRITER *writer; + WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL}; + WS_XML_UTF8_TEXT text; + + hr = WsCreateWriter( NULL, 0, &writer, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteEndCData( writer, NULL ); + ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "", __LINE__ ); + + hr = WsWriteStartCData( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, ""; + text.value.length = 6; + hr = WsWriteText( writer, &text.text, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "", __LINE__ ); + + hr = WsWriteEndCData( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "]]>", __LINE__ ); + + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output( writer, "]]>", __LINE__ ); + + WsFreeWriter( writer ); +} + START_TEST(writer) { test_WsCreateWriter(); @@ -457,4 +1027,11 @@ test_WsSetOutputToBuffer(); test_WsWriteStartElement(); test_WsWriteStartAttribute(); + test_WsWriteType(); + test_basic_type(); + test_simple_struct_type(); + test_WsWriteElement(); + test_WsWriteValue(); + test_WsWriteAttribute(); + test_WsWriteStartCData(); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/webservices_private.h wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/webservices_private.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/webservices_private.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/webservices_private.h 2016-02-08 19:32:34.000000000 +0000 @@ -28,10 +28,12 @@ void *ws_realloc( WS_HEAP *, void *, SIZE_T ) DECLSPEC_HIDDEN; void ws_free( WS_HEAP *, void * ) DECLSPEC_HIDDEN; const char *debugstr_xmlstr( const WS_XML_STRING * ) DECLSPEC_HIDDEN; -WS_XML_STRING *alloc_xml_string( const char *, ULONG ) DECLSPEC_HIDDEN; -WS_XML_UTF8_TEXT *alloc_utf8_text( const char *, ULONG ) DECLSPEC_HIDDEN; +WS_XML_STRING *alloc_xml_string( const unsigned char *, ULONG ) DECLSPEC_HIDDEN; +WS_XML_UTF8_TEXT *alloc_utf8_text( const unsigned char *, ULONG ) DECLSPEC_HIDDEN; HRESULT append_attribute( WS_XML_ELEMENT_NODE *, WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN; void free_attribute( WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN; +struct node *find_parent_element( struct node *, const WS_XML_STRING *, + const WS_XML_STRING * ) DECLSPEC_HIDDEN; struct node { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/webservices.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/webservices.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/webservices.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/webservices.spec 2016-02-08 19:32:34.000000000 +0000 @@ -108,7 +108,7 @@ @ stub WsReadChars @ stub WsReadCharsUtf8 @ stub WsReadElement -@ stub WsReadEndAttribute +@ stdcall WsReadEndAttribute(ptr ptr) @ stdcall WsReadEndElement(ptr ptr) @ stub WsReadEndpointAddressExtension @ stub WsReadEnvelopeEnd @@ -118,7 +118,7 @@ @ stub WsReadMetadata @ stdcall WsReadNode(ptr ptr) @ stub WsReadQualifiedName -@ stub WsReadStartAttribute +@ stdcall WsReadStartAttribute(ptr long ptr) @ stdcall WsReadStartElement(ptr ptr) @ stdcall WsReadToStartElement(ptr ptr ptr ptr ptr) @ stdcall WsReadType(ptr long long ptr long ptr ptr long ptr) @@ -165,14 +165,14 @@ @ stub WsTrimXmlWhitespace @ stub WsVerifyXmlNCName @ stub WsWriteArray -@ stub WsWriteAttribute +@ stdcall WsWriteAttribute(ptr ptr long ptr long ptr) @ stub WsWriteBody @ stub WsWriteBytes @ stub WsWriteChars @ stub WsWriteCharsUtf8 -@ stub WsWriteElement +@ stdcall WsWriteElement(ptr ptr long ptr long ptr) @ stdcall WsWriteEndAttribute(ptr ptr) -@ stub WsWriteEndCData +@ stdcall WsWriteEndCData(ptr ptr) @ stdcall WsWriteEndElement(ptr ptr) @ stdcall WsWriteEndStartElement(ptr ptr) @ stub WsWriteEnvelopeEnd @@ -182,12 +182,12 @@ @ stub WsWriteNode @ stub WsWriteQualifiedName @ stdcall WsWriteStartAttribute(ptr ptr ptr ptr long ptr) -@ stub WsWriteStartCData +@ stdcall WsWriteStartCData(ptr ptr) @ stdcall WsWriteStartElement(ptr ptr ptr ptr ptr) @ stdcall WsWriteText(ptr ptr ptr) -@ stub WsWriteType -@ stub WsWriteValue -@ stub WsWriteXmlBuffer -@ stub WsWriteXmlBufferToBytes +@ stdcall WsWriteType(ptr long long ptr long ptr long ptr) +@ stdcall WsWriteValue(ptr long ptr long ptr) +@ stdcall WsWriteXmlBuffer(ptr ptr ptr) +@ stdcall WsWriteXmlBufferToBytes(ptr ptr ptr ptr long ptr ptr ptr ptr) @ stub WsWriteXmlnsAttribute @ stdcall WsXmlStringEquals(ptr ptr ptr) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/writer.c wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/writer.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/webservices/writer.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/webservices/writer.c 2016-02-08 19:32:34.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright 2015 Hans Leidekker for CodeWeavers + * Copyright 2015, 2016 Hans Leidekker for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,10 +20,12 @@ #include "windef.h" #include "winbase.h" +#include "winuser.h" #include "webservices.h" #include "wine/debug.h" #include "wine/list.h" +#include "wine/unicode.h" #include "webservices_private.h" WINE_DEFAULT_DEBUG_CHANNEL(webservices); @@ -62,14 +64,17 @@ WRITER_STATE_STARTELEMENT, WRITER_STATE_STARTENDELEMENT, WRITER_STATE_STARTATTRIBUTE, + WRITER_STATE_STARTCDATA, WRITER_STATE_ENDSTARTELEMENT, - WRITER_STATE_ENDELEMENT + WRITER_STATE_TEXT, + WRITER_STATE_ENDELEMENT, + WRITER_STATE_ENDCDATA }; struct writer { ULONG write_pos; - char *write_bufptr; + unsigned char *write_bufptr; enum writer_state state; struct node *root; struct node *current; @@ -439,7 +444,7 @@ return S_OK; } -static inline void write_char( struct writer *writer, char ch ) +static inline void write_char( struct writer *writer, unsigned char ch ) { writer->write_bufptr[writer->write_pos++] = ch; } @@ -453,29 +458,32 @@ static HRESULT write_attribute( struct writer *writer, WS_XML_ATTRIBUTE *attr ) { WS_XML_UTF8_TEXT *text = (WS_XML_UTF8_TEXT *)attr->value; + unsigned char quote = attr->singleQuote ? '\'' : '"'; + const WS_XML_STRING *prefix; ULONG size; HRESULT hr; + if (attr->prefix) prefix = attr->prefix; + else prefix = writer->current->hdr.prefix; + /* ' prefix:attr="value"' */ size = attr->localName->length + 4 /* ' =""' */; - if (attr->prefix) size += attr->prefix->length + 1 /* ':' */; + if (prefix) size += prefix->length + 1 /* ':' */; if (text) size += text->value.length; if ((hr = write_grow_buffer( writer, size )) != S_OK) return hr; write_char( writer, ' ' ); - if (attr->prefix) + if (prefix) { - write_bytes( writer, attr->prefix->bytes, attr->prefix->length ); + write_bytes( writer, prefix->bytes, prefix->length ); write_char( writer, ':' ); } write_bytes( writer, attr->localName->bytes, attr->localName->length ); write_char( writer, '=' ); - if (attr->singleQuote) write_char( writer, '\'' ); - else write_char( writer, '"' ); + write_char( writer, quote ); if (text) write_bytes( writer, text->value.bytes, text->value.length ); - if (attr->singleQuote) write_char( writer, '\'' ); - else write_char( writer, '"' ); + write_char( writer, quote ); /* FIXME: ignoring namespace */ return S_OK; @@ -489,7 +497,7 @@ static HRESULT set_current_namespace( struct writer *writer, const WS_XML_STRING *ns ) { WS_XML_STRING *str; - if (!(str = alloc_xml_string( (const char *)ns->bytes, ns->length ))) return E_OUTOFMEMORY; + if (!(str = alloc_xml_string( ns->bytes, ns->length ))) return E_OUTOFMEMORY; heap_free( writer->current_ns ); writer->current_ns = str; return S_OK; @@ -497,7 +505,7 @@ static HRESULT write_startelement( struct writer *writer ) { - WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)writer->current; + WS_XML_ELEMENT_NODE *elem = &writer->current->hdr; ULONG size, i; HRESULT hr; @@ -543,10 +551,13 @@ static HRESULT write_endelement( struct writer *writer ) { - WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)writer->current; + struct node *node = find_parent_element( writer->current, NULL, NULL ); + WS_XML_ELEMENT_NODE *elem = &node->hdr; ULONG size; HRESULT hr; + if (!elem) return WS_E_INVALID_FORMAT; + /* '' */ size = elem->localName->length + 3 /* '' */; @@ -565,6 +576,15 @@ return S_OK; } +static HRESULT write_endstartelement( struct writer *writer ) +{ + HRESULT hr; + if ((hr = write_startelement( writer )) != S_OK) return hr; + if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr; + write_char( writer, '>' ); + return S_OK; +} + /************************************************************************** * WsWriteEndAttribute [webservices.@] */ @@ -582,19 +602,10 @@ return S_OK; } -/************************************************************************** - * WsWriteEndElement [webservices.@] - */ -HRESULT WINAPI WsWriteEndElement( WS_XML_WRITER *handle, WS_ERROR *error ) +static HRESULT write_close_element( struct writer *writer ) { - struct writer *writer = (struct writer *)handle; HRESULT hr; - TRACE( "%p %p\n", handle, error ); - if (error) FIXME( "ignoring error parameter\n" ); - - if (!writer) return E_INVALIDARG; - if (writer->state == WRITER_STATE_STARTELEMENT) { /* '/>' */ @@ -628,6 +639,21 @@ } /************************************************************************** + * WsWriteEndElement [webservices.@] + */ +HRESULT WINAPI WsWriteEndElement( WS_XML_WRITER *handle, WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + + TRACE( "%p %p\n", handle, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!writer) return E_INVALIDARG; + + return write_close_element( writer ); +} + +/************************************************************************** * WsWriteEndStartElement [webservices.@] */ HRESULT WINAPI WsWriteEndStartElement( WS_XML_WRITER *handle, WS_ERROR *error ) @@ -641,14 +667,48 @@ if (!writer) return E_INVALIDARG; if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION; - if ((hr = write_startelement( writer )) != S_OK) return hr; - if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr; - write_char( writer, '>' ); - + if ((hr = write_endstartelement( writer )) != S_OK) return hr; writer->state = WRITER_STATE_ENDSTARTELEMENT; return S_OK; } +static HRESULT write_add_attribute( struct writer *writer, const WS_XML_STRING *prefix, + const WS_XML_STRING *localname, const WS_XML_STRING *ns, + BOOL single ) +{ + WS_XML_ATTRIBUTE *attr; + WS_XML_ELEMENT_NODE *elem = &writer->current->hdr; + HRESULT hr; + + if (!(attr = heap_alloc_zero( sizeof(*attr) ))) return E_OUTOFMEMORY; + + if (!prefix) prefix = elem->prefix; + + attr->singleQuote = !!single; + if (prefix && !(attr->prefix = alloc_xml_string( prefix->bytes, prefix->length ))) + { + free_attribute( attr ); + return E_OUTOFMEMORY; + } + if (!(attr->localName = alloc_xml_string( localname->bytes, localname->length ))) + { + free_attribute( attr ); + return E_OUTOFMEMORY; + } + if (!(attr->ns = alloc_xml_string( ns->bytes, ns->length ))) + { + free_attribute( attr ); + return E_OUTOFMEMORY; + } + if ((hr = append_attribute( elem, attr )) != S_OK) + { + free_attribute( attr ); + return hr; + } + writer->state = WRITER_STATE_STARTATTRIBUTE; + return S_OK; +} + /************************************************************************** * WsWriteStartAttribute [webservices.@] */ @@ -657,9 +717,6 @@ BOOL single, WS_ERROR *error ) { struct writer *writer = (struct writer *)handle; - WS_XML_ELEMENT_NODE *elem; - WS_XML_ATTRIBUTE *attr; - HRESULT hr = E_OUTOFMEMORY; TRACE( "%p %s %s %s %d %p\n", handle, debugstr_xmlstr(prefix), debugstr_xmlstr(localname), debugstr_xmlstr(ns), single, error ); @@ -668,28 +725,88 @@ if (!writer || !localname || !ns) return E_INVALIDARG; if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION; - elem = (WS_XML_ELEMENT_NODE *)writer->current; - if (!(attr = heap_alloc_zero( sizeof(*attr) ))) return E_OUTOFMEMORY; - attr->singleQuote = !!single; + return write_add_attribute( writer, prefix, localname, ns, single ); +} - if (prefix && !(attr->prefix = alloc_xml_string( (const char *)prefix->bytes, prefix->length ))) - goto error; +/************************************************************************** + * WsWriteStartCData [webservices.@] + */ +HRESULT WINAPI WsWriteStartCData( WS_XML_WRITER *handle, WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + HRESULT hr; - if (!(attr->localName = alloc_xml_string( (const char *)localname->bytes, localname->length ))) - goto error; + TRACE( "%p %p\n", handle, error ); + if (error) FIXME( "ignoring error parameter\n" ); - if (!(attr->ns = alloc_xml_string( (const char *)ns->bytes, ns->length ))) - goto error; + if (!writer) return E_INVALIDARG; - if ((hr = append_attribute( elem, attr )) != S_OK) goto error; + /* flush current start element if necessary */ + if (writer->state == WRITER_STATE_STARTELEMENT && ((hr = write_endstartelement( writer )) != S_OK)) + return hr; - writer->state = WRITER_STATE_STARTATTRIBUTE; + if ((hr = write_grow_buffer( writer, 9 )) != S_OK) return hr; + write_bytes( writer, (const BYTE *)"state = WRITER_STATE_STARTCDATA; return S_OK; +} -error: - free_attribute( attr ); - return hr; +/************************************************************************** + * WsWriteEndCData [webservices.@] + */ +HRESULT WINAPI WsWriteEndCData( WS_XML_WRITER *handle, WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + HRESULT hr; + + TRACE( "%p %p\n", handle, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!writer) return E_INVALIDARG; + if (writer->state != WRITER_STATE_STARTCDATA) return WS_E_INVALID_OPERATION; + + if ((hr = write_grow_buffer( writer, 3 )) != S_OK) return hr; + write_bytes( writer, (const BYTE *)"]]>", 3 ); + writer->state = WRITER_STATE_ENDCDATA; + return S_OK; +} + +static HRESULT write_add_element_node( struct writer *writer, const WS_XML_STRING *prefix, + const WS_XML_STRING *localname, const WS_XML_STRING *ns ) +{ + struct node *node; + WS_XML_ELEMENT_NODE *elem, *current = &writer->current->hdr; + HRESULT hr; + + /* flush current start element if necessary */ + if (writer->state == WRITER_STATE_STARTELEMENT && ((hr = write_endstartelement( writer )) != S_OK)) + return hr; + + if (!prefix && current->node.nodeType == WS_XML_NODE_TYPE_ELEMENT) + prefix = current->prefix; + + if (!(node = alloc_node( WS_XML_NODE_TYPE_ELEMENT ))) return E_OUTOFMEMORY; + elem = &node->hdr; + + if (prefix && !(elem->prefix = alloc_xml_string( prefix->bytes, prefix->length ))) + { + free_node( node ); + return E_OUTOFMEMORY; + } + if (!(elem->localName = alloc_xml_string( localname->bytes, localname->length ))) + { + free_node( node ); + return E_OUTOFMEMORY; + } + if (!(elem->ns = alloc_xml_string( ns->bytes, ns->length ))) + { + free_node( node ); + return E_OUTOFMEMORY; + } + write_insert_node( writer, node ); + writer->state = WRITER_STATE_STARTELEMENT; + return S_OK; } /************************************************************************** @@ -700,9 +817,6 @@ WS_ERROR *error ) { struct writer *writer = (struct writer *)handle; - struct node *node; - WS_XML_ELEMENT_NODE *elem; - HRESULT hr = E_OUTOFMEMORY; TRACE( "%p %s %s %s %p\n", handle, debugstr_xmlstr(prefix), debugstr_xmlstr(localname), debugstr_xmlstr(ns), error ); @@ -710,63 +824,784 @@ if (!writer || !localname || !ns) return E_INVALIDARG; - /* flush current start element */ - if (writer->state == WRITER_STATE_STARTELEMENT) + return write_add_element_node( writer, prefix, localname, ns ); +} + +static inline void write_set_attribute_value( struct writer *writer, WS_XML_TEXT *text ) +{ + WS_XML_ELEMENT_NODE *elem = &writer->current->hdr; + elem->attributes[elem->attributeCount - 1]->value = text; +} + +/************************************************************************** + * WsWriteText [webservices.@] + */ +HRESULT WINAPI WsWriteText( WS_XML_WRITER *handle, const WS_XML_TEXT *text, WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + WS_XML_UTF8_TEXT *dst, *src = (WS_XML_UTF8_TEXT *)text; + HRESULT hr; + + TRACE( "%p %p %p\n", handle, text, error ); + + if (!writer || !text) return E_INVALIDARG; + + if (text->textType != WS_XML_TEXT_TYPE_UTF8) { - if ((hr = write_startelement( writer )) != S_OK) return hr; - if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr; - write_char( writer, '>' ); + FIXME( "text type %u not supported\n", text->textType ); + return E_NOTIMPL; } - if (!(node = alloc_node( WS_XML_NODE_TYPE_ELEMENT ))) return E_OUTOFMEMORY; - elem = (WS_XML_ELEMENT_NODE *)node; + if (writer->state == WRITER_STATE_STARTATTRIBUTE) + { + if (!(dst = alloc_utf8_text( src->value.bytes, src->value.length ))) + return E_OUTOFMEMORY; + + write_set_attribute_value( writer, &dst->text ); + } + else + { + if ((hr = write_grow_buffer( writer, src->value.length )) != S_OK) return hr; + write_bytes( writer, src->value.bytes, src->value.length ); + } + + return S_OK; +} + +static WS_XML_TEXT *widechar_to_xmltext( const WCHAR *src, WS_XML_TEXT_TYPE type ) +{ + switch (type) + { + case WS_XML_TEXT_TYPE_UTF8: + { + WS_XML_UTF8_TEXT *text; + int len = WideCharToMultiByte( CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL ) - 1; + if (!(text = alloc_utf8_text( NULL, len ))) return NULL; + WideCharToMultiByte( CP_UTF8, 0, src, -1, (char *)text->value.bytes, text->value.length, NULL, NULL ); + return &text->text; + } + default: + FIXME( "unhandled type %u\n", type ); + return NULL; + } +} + +static WS_XML_UTF8_TEXT *format_bool( const BOOL *ptr ) +{ + static const unsigned char bool_true[] = {'t','r','u','e'}, bool_false[] = {'f','a','l','s','e'}; + if (*ptr) return alloc_utf8_text( bool_true, sizeof(bool_true) ); + else return alloc_utf8_text( bool_false, sizeof(bool_false) ); +} - if (prefix && !(elem->prefix = alloc_xml_string( (const char *)prefix->bytes, prefix->length ))) - goto error; +static WS_XML_UTF8_TEXT *format_int8( const INT8 *ptr ) +{ + char buf[5]; /* "-128" */ + int len = wsprintfA( buf, "%d", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_int16( const INT16 *ptr ) +{ + char buf[7]; /* "-32768" */ + int len = wsprintfA( buf, "%d", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_int32( const INT32 *ptr ) +{ + char buf[12]; /* "-2147483648" */ + int len = wsprintfA( buf, "%d", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_int64( const INT64 *ptr ) +{ + char buf[21]; /* "-9223372036854775808" */ + int len = wsprintfA( buf, "%I64d", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_uint8( const UINT8 *ptr ) +{ + char buf[4]; /* "255" */ + int len = wsprintfA( buf, "%u", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_uint16( const UINT16 *ptr ) +{ + char buf[6]; /* "65535" */ + int len = wsprintfA( buf, "%u", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static WS_XML_UTF8_TEXT *format_uint32( const UINT32 *ptr ) +{ + char buf[11]; /* "4294967295" */ + int len = wsprintfA( buf, "%u", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} - if (!(elem->localName = alloc_xml_string( (const char *)localname->bytes, localname->length ))) - goto error; +static WS_XML_UTF8_TEXT *format_uint64( const UINT64 *ptr ) +{ + char buf[21]; /* "18446744073709551615" */ + int len = wsprintfA( buf, "%I64u", *ptr ); + return alloc_utf8_text( (const unsigned char *)buf, len ); +} + +static HRESULT write_add_text_node( struct writer *writer, WS_XML_TEXT *value ) +{ + struct node *node; + WS_XML_TEXT_NODE *text; - if (!(elem->ns = alloc_xml_string( (const char *)ns->bytes, ns->length ))) - goto error; + if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return E_OUTOFMEMORY; + text = (WS_XML_TEXT_NODE *)node; + text->text = value; write_insert_node( writer, node ); - writer->state = WRITER_STATE_STARTELEMENT; + writer->state = WRITER_STATE_TEXT; + return S_OK; +} + +static HRESULT write_text_node( struct writer *writer ) +{ + HRESULT hr; + WS_XML_TEXT_NODE *node = (WS_XML_TEXT_NODE *)writer->current; + WS_XML_UTF8_TEXT *text = (WS_XML_UTF8_TEXT *)node->text; + + if ((hr = write_grow_buffer( writer, text->value.length )) != S_OK) return hr; + write_bytes( writer, text->value.bytes, text->value.length ); return S_OK; +} + +static HRESULT write_type_text( struct writer *writer, WS_TYPE_MAPPING mapping, + WS_XML_TEXT *text ) +{ + HRESULT hr; + + switch (mapping) + { + case WS_ELEMENT_TYPE_MAPPING: + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if ((hr = write_endstartelement( writer )) != S_OK) return hr; + if ((hr = write_add_text_node( writer, text )) != S_OK) return hr; + return write_text_node( writer ); + + case WS_ATTRIBUTE_TYPE_MAPPING: + write_set_attribute_value( writer, text ); + return S_OK; + + case WS_ANY_ELEMENT_TYPE_MAPPING: + switch (writer->state) + { + case WRITER_STATE_STARTATTRIBUTE: + write_set_attribute_value( writer, text ); + writer->state = WRITER_STATE_STARTELEMENT; + return S_OK; + + case WRITER_STATE_STARTELEMENT: + if ((hr = write_endstartelement( writer )) != S_OK) return hr; + if ((hr = write_add_text_node( writer, text )) != S_OK) return hr; + return write_text_node( writer ); + + default: + FIXME( "writer state %u not handled\n", writer->state ); + return E_NOTIMPL; + } + + default: + FIXME( "mapping %u not implemented\n", mapping ); + return E_NOTIMPL; + } +} + +static HRESULT write_type_bool( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_BOOL_DESCRIPTION *desc, const BOOL *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_bool( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_int8( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_INT8_DESCRIPTION *desc, const INT8 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_int8( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_int16( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_INT16_DESCRIPTION *desc, const INT16 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_int16( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_int32( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_INT32_DESCRIPTION *desc, const INT32 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_int32( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_int64( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_INT64_DESCRIPTION *desc, const INT64 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_int64( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_uint8( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_UINT8_DESCRIPTION *desc, const UINT8 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_uint8( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_uint16( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_UINT16_DESCRIPTION *desc, const UINT16 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_uint16( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_uint32( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_UINT32_DESCRIPTION *desc, const UINT32 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_uint32( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_uint64( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_UINT64_DESCRIPTION *desc, const UINT64 *value ) +{ + WS_XML_UTF8_TEXT *text; + HRESULT hr; + + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = format_uint64( value ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, &text->text )) == S_OK) return S_OK; + heap_free( text ); + return hr; +} + +static HRESULT write_type_wsz( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_WSZ_DESCRIPTION *desc, const WCHAR *value ) +{ + WS_XML_TEXT *text; + HRESULT hr; -error: - free_node( node ); + if (desc) + { + FIXME( "description not supported\n" ); + return E_NOTIMPL; + } + if (!(text = widechar_to_xmltext( value, WS_XML_TEXT_TYPE_UTF8 ))) return E_OUTOFMEMORY; + if ((hr = write_type_text( writer, mapping, text )) == S_OK) return S_OK; + heap_free( text ); return hr; } +static HRESULT write_type_struct( struct writer *, WS_TYPE_MAPPING, const WS_STRUCT_DESCRIPTION *, + const void * ); + +static HRESULT write_type_struct_field( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_FIELD_DESCRIPTION *desc, const void *value ) +{ + HRESULT hr; + + if (desc->options && desc->options != WS_FIELD_POINTER && + desc->options != WS_FIELD_OPTIONAL && + desc->options != (WS_FIELD_POINTER | WS_FIELD_OPTIONAL)) + { + FIXME( "options 0x%x not supported\n", desc->options ); + return E_NOTIMPL; + } + + switch (desc->mapping) + { + case WS_ATTRIBUTE_FIELD_MAPPING: + if ((hr = write_add_attribute( writer, NULL, desc->localName, desc->ns, FALSE )) != S_OK) + return hr; + break; + + case WS_TEXT_FIELD_MAPPING: + break; + + default: + FIXME( "field mapping %u not supported\n", desc->mapping ); + return E_NOTIMPL; + } + + switch (desc->type) + { + case WS_STRUCT_TYPE: + { + const void * const *ptr = value; + if ((hr = write_type_struct( writer, mapping, desc->typeDescription, *ptr )) != S_OK) return hr; + break; + } + case WS_BOOL_TYPE: + { + const BOOL *ptr = value; + if ((hr = write_type_bool( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr; + break; + } + case WS_INT8_TYPE: + { + const INT8 *ptr = value; + if ((hr = write_type_int8( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr; + break; + } + case WS_INT16_TYPE: + { + const INT16 *ptr = value; + if ((hr = write_type_int16( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr; + break; + } + case WS_INT32_TYPE: + { + const INT32 *ptr = value; + if ((hr = write_type_int32( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr; + break; + } + case WS_INT64_TYPE: + { + const INT64 *ptr = value; + if ((hr = write_type_int64( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr; + break; + } + case WS_UINT8_TYPE: + { + const UINT8 *ptr = value; + if ((hr = write_type_uint8( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr; + break; + } + case WS_UINT16_TYPE: + { + const UINT16 *ptr = value; + if ((hr = write_type_uint16( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr; + break; + } + case WS_UINT32_TYPE: + { + const UINT32 *ptr = value; + if ((hr = write_type_uint32( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr; + break; + } + case WS_UINT64_TYPE: + { + const UINT64 *ptr = value; + if ((hr = write_type_uint64( writer, mapping, desc->typeDescription, ptr )) != S_OK) return hr; + break; + } + case WS_WSZ_TYPE: + { + const WCHAR * const *ptr = value; + if ((hr = write_type_wsz( writer, mapping, desc->typeDescription, *ptr )) != S_OK) return hr; + break; + } + default: + FIXME( "type %u not implemented\n", desc->type ); + return E_NOTIMPL; + } + + return S_OK; +} + +static HRESULT write_type_struct( struct writer *writer, WS_TYPE_MAPPING mapping, + const WS_STRUCT_DESCRIPTION *desc, const void *value ) +{ + ULONG i; + HRESULT hr; + const char *ptr; + + if (!desc) return E_INVALIDARG; + + if (desc->structOptions) + { + FIXME( "struct options 0x%x not supported\n", desc->structOptions ); + return E_NOTIMPL; + } + + for (i = 0; i < desc->fieldCount; i++) + { + ptr = (const char *)value + desc->fields[i]->offset; + if ((hr = write_type_struct_field( writer, mapping, desc->fields[i], ptr )) != S_OK) + return hr; + } + + return S_OK; +} + +static HRESULT write_type( struct writer *writer, WS_TYPE_MAPPING mapping, WS_TYPE type, + const void *desc, WS_WRITE_OPTION option, const void *value, + ULONG size ) +{ + switch (type) + { + case WS_STRUCT_TYPE: + { + const void * const *ptr = value; + + if (!desc || option != WS_WRITE_REQUIRED_POINTER || size != sizeof(*ptr)) + return E_INVALIDARG; + + return write_type_struct( writer, mapping, desc, *ptr ); + } + case WS_BOOL_TYPE: + { + const BOOL *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_bool( writer, mapping, desc, ptr ); + } + case WS_INT8_TYPE: + { + const INT8 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_int8( writer, mapping, desc, ptr ); + } + case WS_INT16_TYPE: + { + const INT16 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_int16( writer, mapping, desc, ptr ); + } + case WS_INT32_TYPE: + { + const INT32 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_int32( writer, mapping, desc, ptr ); + } + case WS_INT64_TYPE: + { + const INT64 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_int64( writer, mapping, desc, ptr ); + } + case WS_UINT8_TYPE: + { + const UINT8 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_uint8( writer, mapping, desc, ptr ); + } + case WS_UINT16_TYPE: + { + const UINT16 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_uint16( writer, mapping, desc, ptr ); + } + case WS_UINT32_TYPE: + { + const UINT32 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_uint32( writer, mapping, desc, ptr ); + } + case WS_UINT64_TYPE: + { + const UINT64 *ptr = value; + if (option != WS_WRITE_REQUIRED_VALUE || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_uint64( writer, mapping, desc, ptr ); + } + case WS_WSZ_TYPE: + { + const WCHAR * const *ptr = value; + if (option != WS_WRITE_REQUIRED_POINTER || size != sizeof(*ptr)) return E_INVALIDARG; + return write_type_wsz( writer, mapping, desc, *ptr ); + } + default: + FIXME( "type %u not supported\n", type ); + return E_NOTIMPL; + } +} + /************************************************************************** - * WsWriteText [webservices.@] + * WsWriteAttribute [webservices.@] */ -HRESULT WINAPI WsWriteText( WS_XML_WRITER *handle, const WS_XML_TEXT *text, WS_ERROR *error ) +HRESULT WINAPI WsWriteAttribute( WS_XML_WRITER *handle, const WS_ATTRIBUTE_DESCRIPTION *desc, + WS_WRITE_OPTION option, const void *value, ULONG size, + WS_ERROR *error ) { struct writer *writer = (struct writer *)handle; - WS_XML_ELEMENT_NODE *elem; - WS_XML_UTF8_TEXT *src, *dst; + HRESULT hr; - TRACE( "%p %p %p\n", handle, text, error ); + TRACE( "%p %p %u %p %u %p\n", handle, desc, option, value, size, error ); + if (error) FIXME( "ignoring error parameter\n" ); - if (!writer || !text) return E_INVALIDARG; + if (!writer || !desc || !desc->attributeLocalName || !desc->attributeNs || !value) + return E_INVALIDARG; + + if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION; + + if ((hr = write_add_attribute( writer, NULL, desc->attributeLocalName, desc->attributeNs, + FALSE )) != S_OK) return hr; + + if ((hr = write_type( writer, WS_ATTRIBUTE_TYPE_MAPPING, desc->type, desc->typeDescription, + option, value, size )) != S_OK) return hr; + + writer->state = WRITER_STATE_STARTELEMENT; + return S_OK; +} + +/************************************************************************** + * WsWriteElement [webservices.@] + */ +HRESULT WINAPI WsWriteElement( WS_XML_WRITER *handle, const WS_ELEMENT_DESCRIPTION *desc, + WS_WRITE_OPTION option, const void *value, ULONG size, + WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + HRESULT hr; + + TRACE( "%p %p %u %p %u %p\n", handle, desc, option, value, size, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!writer || !desc || !desc->elementLocalName || !desc->elementNs || !value) + return E_INVALIDARG; + + if ((hr = write_add_element_node( writer, NULL, desc->elementLocalName, desc->elementNs )) != S_OK) + return hr; + + if ((hr = write_type( writer, WS_ANY_ELEMENT_TYPE_MAPPING, desc->type, desc->typeDescription, + option, value, size )) != S_OK) return hr; + + return write_close_element( writer ); +} + +/************************************************************************** + * WsWriteType [webservices.@] + */ +HRESULT WINAPI WsWriteType( WS_XML_WRITER *handle, WS_TYPE_MAPPING mapping, WS_TYPE type, + const void *desc, WS_WRITE_OPTION option, const void *value, + ULONG size, WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + HRESULT hr; + + TRACE( "%p %u %u %p %u %p %u %p\n", handle, mapping, type, desc, option, value, + size, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!writer || !value) return E_INVALIDARG; - if (writer->state != WRITER_STATE_STARTATTRIBUTE) + switch (mapping) { - FIXME( "can't handle writer state %u\n", writer->state ); + case WS_ATTRIBUTE_TYPE_MAPPING: + if (writer->state != WRITER_STATE_STARTATTRIBUTE) return WS_E_INVALID_FORMAT; + hr = write_type( writer, mapping, type, desc, option, value, size ); + break; + + case WS_ELEMENT_TYPE_MAPPING: + case WS_ELEMENT_CONTENT_TYPE_MAPPING: + if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_FORMAT; + hr = write_type( writer, mapping, type, desc, option, value, size ); + break; + + case WS_ANY_ELEMENT_TYPE_MAPPING: + hr = write_type( writer, mapping, type, desc, option, value, size ); + break; + + default: + FIXME( "mapping %u not implemented\n", mapping ); return E_NOTIMPL; } - if (text->textType != WS_XML_TEXT_TYPE_UTF8) + + return hr; +} + +static WS_TYPE map_value_type( WS_VALUE_TYPE type ) +{ + switch (type) { - FIXME( "text type %u not supported\n", text->textType ); + case WS_BOOL_VALUE_TYPE: return WS_BOOL_TYPE; + case WS_INT8_VALUE_TYPE: return WS_INT8_TYPE; + case WS_INT16_VALUE_TYPE: return WS_INT16_TYPE; + case WS_INT32_VALUE_TYPE: return WS_INT32_TYPE; + case WS_INT64_VALUE_TYPE: return WS_INT64_TYPE; + case WS_UINT8_VALUE_TYPE: return WS_UINT8_TYPE; + case WS_UINT16_VALUE_TYPE: return WS_UINT16_TYPE; + case WS_UINT32_VALUE_TYPE: return WS_UINT32_TYPE; + case WS_UINT64_VALUE_TYPE: return WS_UINT64_TYPE; + case WS_FLOAT_VALUE_TYPE: return WS_FLOAT_TYPE; + case WS_DOUBLE_VALUE_TYPE: return WS_DOUBLE_TYPE; + case WS_DECIMAL_VALUE_TYPE: return WS_DECIMAL_TYPE; + case WS_DATETIME_VALUE_TYPE: return WS_DATETIME_TYPE; + case WS_TIMESPAN_VALUE_TYPE: return WS_TIMESPAN_TYPE; + case WS_GUID_VALUE_TYPE: return WS_GUID_TYPE; + default: + FIXME( "unhandled type %u\n", type ); + return ~0u; + } +} + +/************************************************************************** + * WsWriteValue [webservices.@] + */ +HRESULT WINAPI WsWriteValue( WS_XML_WRITER *handle, WS_VALUE_TYPE value_type, const void *value, + ULONG size, WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + WS_TYPE_MAPPING mapping; + WS_TYPE type; + + TRACE( "%p %u %p %u %p\n", handle, value_type, value, size, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!writer || !value || (type = map_value_type( value_type )) == ~0u) return E_INVALIDARG; + + switch (writer->state) + { + case WRITER_STATE_STARTATTRIBUTE: + mapping = WS_ATTRIBUTE_TYPE_MAPPING; + break; + + case WRITER_STATE_STARTELEMENT: + mapping = WS_ELEMENT_TYPE_MAPPING; + break; + + default: + return WS_E_INVALID_FORMAT; + } + + return write_type( writer, mapping, type, NULL, WS_WRITE_REQUIRED_VALUE, value, size ); +} + +/************************************************************************** + * WsWriteXmlBuffer [webservices.@] + */ +HRESULT WINAPI WsWriteXmlBuffer( WS_XML_WRITER *handle, WS_XML_BUFFER *buffer, WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer; + HRESULT hr; + + TRACE( "%p %p %p\n", handle, buffer, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!writer || !xmlbuf) return E_INVALIDARG; + + if ((hr = write_grow_buffer( writer, xmlbuf->size )) != S_OK) return hr; + write_bytes( writer, xmlbuf->ptr, xmlbuf->size ); + return S_OK; +} + +/************************************************************************** + * WsWriteXmlBufferToBytes [webservices.@] + */ +HRESULT WINAPI WsWriteXmlBufferToBytes( WS_XML_WRITER *handle, WS_XML_BUFFER *buffer, + const WS_XML_WRITER_ENCODING *encoding, + const WS_XML_WRITER_PROPERTY *properties, ULONG count, + WS_HEAP *heap, void **bytes, ULONG *size, WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer; + HRESULT hr; + char *buf; + ULONG i; + + TRACE( "%p %p %p %p %u %p %p %p %p\n", handle, buffer, encoding, properties, count, heap, + bytes, size, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!writer || !xmlbuf || !heap || !bytes) return E_INVALIDARG; + + if (encoding && encoding->encodingType != WS_XML_WRITER_ENCODING_TYPE_TEXT) + { + FIXME( "encoding type %u not supported\n", encoding->encodingType ); return E_NOTIMPL; } - src = (WS_XML_UTF8_TEXT *)text; - if (!(dst = alloc_utf8_text( (const char *)src->value.bytes, src->value.length ))) - return E_OUTOFMEMORY; - elem = (WS_XML_ELEMENT_NODE *)writer->current; - elem->attributes[elem->attributeCount - 1]->value = (WS_XML_TEXT *)dst; + for (i = 0; i < count; i++) + { + hr = set_writer_prop( writer, properties[i].id, properties[i].value, properties[i].valueSize ); + if (hr != S_OK) return hr; + } + + if (!(buf = ws_alloc( heap, xmlbuf->size ))) return WS_E_QUOTA_EXCEEDED; + memcpy( buf, xmlbuf->ptr, xmlbuf->size ); + *bytes = buf; return S_OK; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/arb_program_shader.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/arb_program_shader.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/arb_program_shader.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/arb_program_shader.c 2016-02-08 19:32:34.000000000 +0000 @@ -798,7 +798,7 @@ DWORD highest_constf = 0, clip_limit; max_constantsF -= reserved_vs_const(shader_data, reg_maps, gl_info); - max_constantsF -= count_bits(reg_maps->integer_constants); + max_constantsF -= wined3d_popcount(reg_maps->integer_constants); max_constantsF -= gl_info->reserved_arb_constants; for (i = 0; i < shader->limits->constant_float; ++i) @@ -819,7 +819,7 @@ else { unsigned int mask = ctx->cur_vs_args->clip.boolclip.clipplane_mask; - clip_limit = min(count_bits(mask), 4); + clip_limit = min(wined3d_popcount(mask), 4); } *num_clipplanes = min(clip_limit, max_constantsF - highest_constf - 1); max_constantsF -= *num_clipplanes; @@ -1798,7 +1798,7 @@ case WINED3DSIH_MOVA:instruction = "ARR"; break; case WINED3DSIH_DSX: instruction = "DDX"; break; default: instruction = ""; - FIXME("Unhandled opcode %#x\n", ins->handler_idx); + FIXME("Unhandled opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); break; } @@ -2487,7 +2487,7 @@ tmp_ins.handler_idx = WINED3DSIH_DP3; break; default: - FIXME("Unhandled opcode %#x\n", ins->handler_idx); + FIXME("Unhandled opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); break; } @@ -2559,7 +2559,7 @@ instruction = "LG2"; break; default: instruction = ""; - FIXME("Unhandled opcode %#x\n", ins->handler_idx); + FIXME("Unhandled opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); break; } @@ -3218,8 +3218,8 @@ } else if (args->clip.boolclip.clip_texcoord) { + static const char component[4] = {'x', 'y', 'z', 'w'}; unsigned int cur_clip = 0; - char component[4] = {'x', 'y', 'z', 'w'}; const char *zero = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ZERO); for (i = 0; i < gl_info->limits.clipplanes; ++i) @@ -5212,122 +5212,148 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = { - /* WINED3DSIH_ABS */ shader_hw_map2gl, - /* WINED3DSIH_ADD */ shader_hw_map2gl, - /* WINED3DSIH_AND */ NULL, - /* WINED3DSIH_BEM */ pshader_hw_bem, - /* WINED3DSIH_BREAK */ shader_hw_break, - /* WINED3DSIH_BREAKC */ shader_hw_breakc, - /* WINED3DSIH_BREAKP */ NULL, - /* WINED3DSIH_CALL */ shader_hw_call, - /* WINED3DSIH_CALLNZ */ NULL, - /* WINED3DSIH_CMP */ pshader_hw_cmp, - /* WINED3DSIH_CND */ pshader_hw_cnd, - /* WINED3DSIH_CRS */ shader_hw_map2gl, - /* WINED3DSIH_CUT */ NULL, - /* WINED3DSIH_DCL */ shader_hw_nop, - /* WINED3DSIH_DCL_CONSTANT_BUFFER */ shader_hw_nop, - /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_hw_nop, - /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ shader_hw_nop, - /* WINED3DSIH_DCL_VERTICES_OUT */ shader_hw_nop, - /* WINED3DSIH_DEF */ shader_hw_nop, - /* WINED3DSIH_DEFB */ shader_hw_nop, - /* WINED3DSIH_DEFI */ shader_hw_nop, - /* WINED3DSIH_DIV */ NULL, - /* WINED3DSIH_DP2 */ NULL, - /* WINED3DSIH_DP2ADD */ pshader_hw_dp2add, - /* WINED3DSIH_DP3 */ shader_hw_map2gl, - /* WINED3DSIH_DP4 */ shader_hw_map2gl, - /* WINED3DSIH_DST */ shader_hw_map2gl, - /* WINED3DSIH_DSX */ shader_hw_map2gl, - /* WINED3DSIH_DSY */ shader_hw_dsy, - /* WINED3DSIH_ELSE */ shader_hw_else, - /* WINED3DSIH_EMIT */ NULL, - /* WINED3DSIH_ENDIF */ shader_hw_endif, - /* WINED3DSIH_ENDLOOP */ shader_hw_endloop, - /* WINED3DSIH_ENDREP */ shader_hw_endrep, - /* WINED3DSIH_EQ */ NULL, - /* WINED3DSIH_EXP */ shader_hw_scalar_op, - /* WINED3DSIH_EXPP */ shader_hw_scalar_op, - /* WINED3DSIH_FRC */ shader_hw_map2gl, - /* WINED3DSIH_FTOI */ NULL, - /* WINED3DSIH_GE */ NULL, - /* WINED3DSIH_IADD */ NULL, - /* WINED3DSIH_IEQ */ NULL, - /* WINED3DSIH_IF */ NULL /* Hardcoded into the shader */, - /* WINED3DSIH_IFC */ shader_hw_ifc, - /* WINED3DSIH_IGE */ NULL, - /* WINED3DSIH_IMUL */ NULL, - /* WINED3DSIH_ISHL */ NULL, - /* WINED3DSIH_ITOF */ NULL, - /* WINED3DSIH_LABEL */ shader_hw_label, - /* WINED3DSIH_LD */ NULL, - /* WINED3DSIH_LIT */ shader_hw_map2gl, - /* WINED3DSIH_LOG */ shader_hw_scalar_op, - /* WINED3DSIH_LOGP */ shader_hw_scalar_op, - /* WINED3DSIH_LOOP */ shader_hw_loop, - /* WINED3DSIH_LRP */ shader_hw_lrp, - /* WINED3DSIH_LT */ NULL, - /* WINED3DSIH_M3x2 */ shader_hw_mnxn, - /* WINED3DSIH_M3x3 */ shader_hw_mnxn, - /* WINED3DSIH_M3x4 */ shader_hw_mnxn, - /* WINED3DSIH_M4x3 */ shader_hw_mnxn, - /* WINED3DSIH_M4x4 */ shader_hw_mnxn, - /* WINED3DSIH_MAD */ shader_hw_map2gl, - /* WINED3DSIH_MAX */ shader_hw_map2gl, - /* WINED3DSIH_MIN */ shader_hw_map2gl, - /* WINED3DSIH_MOV */ shader_hw_mov, - /* WINED3DSIH_MOVA */ shader_hw_mov, - /* WINED3DSIH_MOVC */ NULL, - /* WINED3DSIH_MUL */ shader_hw_map2gl, - /* WINED3DSIH_NE */ NULL, - /* WINED3DSIH_NOP */ shader_hw_nop, - /* WINED3DSIH_NRM */ shader_hw_nrm, - /* WINED3DSIH_OR */ NULL, - /* WINED3DSIH_PHASE */ shader_hw_nop, - /* WINED3DSIH_POW */ shader_hw_pow, - /* WINED3DSIH_RCP */ shader_hw_scalar_op, - /* WINED3DSIH_REP */ shader_hw_rep, - /* WINED3DSIH_RET */ shader_hw_ret, - /* WINED3DSIH_ROUND_NI */ NULL, - /* WINED3DSIH_RSQ */ shader_hw_scalar_op, - /* WINED3DSIH_SAMPLE */ NULL, - /* WINED3DSIH_SAMPLE_GRAD */ NULL, - /* WINED3DSIH_SAMPLE_LOD */ NULL, - /* WINED3DSIH_SETP */ NULL, - /* WINED3DSIH_SGE */ shader_hw_map2gl, - /* WINED3DSIH_SGN */ shader_hw_sgn, - /* WINED3DSIH_SINCOS */ shader_hw_sincos, - /* WINED3DSIH_SLT */ shader_hw_map2gl, - /* WINED3DSIH_SQRT */ NULL, - /* WINED3DSIH_SUB */ shader_hw_map2gl, - /* WINED3DSIH_TEX */ pshader_hw_tex, - /* WINED3DSIH_TEXBEM */ pshader_hw_texbem, - /* WINED3DSIH_TEXBEML */ pshader_hw_texbem, - /* WINED3DSIH_TEXCOORD */ pshader_hw_texcoord, - /* WINED3DSIH_TEXDEPTH */ pshader_hw_texdepth, - /* WINED3DSIH_TEXDP3 */ pshader_hw_texdp3, - /* WINED3DSIH_TEXDP3TEX */ pshader_hw_texdp3tex, - /* WINED3DSIH_TEXKILL */ pshader_hw_texkill, - /* WINED3DSIH_TEXLDD */ shader_hw_texldd, - /* WINED3DSIH_TEXLDL */ shader_hw_texldl, - /* WINED3DSIH_TEXM3x2DEPTH */ pshader_hw_texm3x2depth, - /* WINED3DSIH_TEXM3x2PAD */ pshader_hw_texm3x2pad, - /* WINED3DSIH_TEXM3x2TEX */ pshader_hw_texm3x2tex, - /* WINED3DSIH_TEXM3x3 */ pshader_hw_texm3x3, - /* WINED3DSIH_TEXM3x3DIFF */ NULL, - /* WINED3DSIH_TEXM3x3PAD */ pshader_hw_texm3x3pad, - /* WINED3DSIH_TEXM3x3SPEC */ pshader_hw_texm3x3spec, - /* WINED3DSIH_TEXM3x3TEX */ pshader_hw_texm3x3tex, - /* WINED3DSIH_TEXM3x3VSPEC */ pshader_hw_texm3x3vspec, - /* WINED3DSIH_TEXREG2AR */ pshader_hw_texreg2ar, - /* WINED3DSIH_TEXREG2GB */ pshader_hw_texreg2gb, - /* WINED3DSIH_TEXREG2RGB */ pshader_hw_texreg2rgb, - /* WINED3DSIH_UDIV */ NULL, - /* WINED3DSIH_UGE */ NULL, - /* WINED3DSIH_USHR */ NULL, - /* WINED3DSIH_UTOF */ NULL, - /* WINED3DSIH_XOR */ NULL, + /* WINED3DSIH_ABS */ shader_hw_map2gl, + /* WINED3DSIH_ADD */ shader_hw_map2gl, + /* WINED3DSIH_AND */ NULL, + /* WINED3DSIH_BEM */ pshader_hw_bem, + /* WINED3DSIH_BREAK */ shader_hw_break, + /* WINED3DSIH_BREAKC */ shader_hw_breakc, + /* WINED3DSIH_BREAKP */ NULL, + /* WINED3DSIH_CALL */ shader_hw_call, + /* WINED3DSIH_CALLNZ */ NULL, + /* WINED3DSIH_CMP */ pshader_hw_cmp, + /* WINED3DSIH_CND */ pshader_hw_cnd, + /* WINED3DSIH_CRS */ shader_hw_map2gl, + /* WINED3DSIH_CUT */ NULL, + /* WINED3DSIH_DCL */ shader_hw_nop, + /* WINED3DSIH_DCL_CONSTANT_BUFFER */ shader_hw_nop, + /* WINED3DSIH_DCL_GLOBAL_FLAGS */ NULL, + /* WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER */ NULL, + /* WINED3DSIH_DCL_INPUT */ NULL, + /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_hw_nop, + /* WINED3DSIH_DCL_INPUT_PS */ NULL, + /* WINED3DSIH_DCL_INPUT_PS_SGV */ NULL, + /* WINED3DSIH_DCL_INPUT_PS_SIV */ NULL, + /* WINED3DSIH_DCL_INPUT_SGV */ NULL, + /* WINED3DSIH_DCL_INPUT_SIV */ NULL, + /* WINED3DSIH_DCL_OUTPUT */ NULL, + /* WINED3DSIH_DCL_OUTPUT_SIV */ NULL, + /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ shader_hw_nop, + /* WINED3DSIH_DCL_SAMPLER */ NULL, + /* WINED3DSIH_DCL_TEMPS */ NULL, + /* WINED3DSIH_DCL_VERTICES_OUT */ shader_hw_nop, + /* WINED3DSIH_DEF */ shader_hw_nop, + /* WINED3DSIH_DEFB */ shader_hw_nop, + /* WINED3DSIH_DEFI */ shader_hw_nop, + /* WINED3DSIH_DIV */ NULL, + /* WINED3DSIH_DP2 */ NULL, + /* WINED3DSIH_DP2ADD */ pshader_hw_dp2add, + /* WINED3DSIH_DP3 */ shader_hw_map2gl, + /* WINED3DSIH_DP4 */ shader_hw_map2gl, + /* WINED3DSIH_DST */ shader_hw_map2gl, + /* WINED3DSIH_DSX */ shader_hw_map2gl, + /* WINED3DSIH_DSY */ shader_hw_dsy, + /* WINED3DSIH_ELSE */ shader_hw_else, + /* WINED3DSIH_EMIT */ NULL, + /* WINED3DSIH_ENDIF */ shader_hw_endif, + /* WINED3DSIH_ENDLOOP */ shader_hw_endloop, + /* WINED3DSIH_ENDREP */ shader_hw_endrep, + /* WINED3DSIH_EQ */ NULL, + /* WINED3DSIH_EXP */ shader_hw_scalar_op, + /* WINED3DSIH_EXPP */ shader_hw_scalar_op, + /* WINED3DSIH_FRC */ shader_hw_map2gl, + /* WINED3DSIH_FTOI */ NULL, + /* WINED3DSIH_FTOU */ NULL, + /* WINED3DSIH_GE */ NULL, + /* WINED3DSIH_IADD */ NULL, + /* WINED3DSIH_IEQ */ NULL, + /* WINED3DSIH_IF */ NULL /* Hardcoded into the shader */, + /* WINED3DSIH_IFC */ shader_hw_ifc, + /* WINED3DSIH_IGE */ NULL, + /* WINED3DSIH_ILT */ NULL, + /* WINED3DSIH_IMAD */ NULL, + /* WINED3DSIH_IMAX */ NULL, + /* WINED3DSIH_IMIN */ NULL, + /* WINED3DSIH_IMUL */ NULL, + /* WINED3DSIH_INE */ NULL, + /* WINED3DSIH_INEG */ NULL, + /* WINED3DSIH_ISHL */ NULL, + /* WINED3DSIH_ITOF */ NULL, + /* WINED3DSIH_LABEL */ shader_hw_label, + /* WINED3DSIH_LD */ NULL, + /* WINED3DSIH_LIT */ shader_hw_map2gl, + /* WINED3DSIH_LOG */ shader_hw_scalar_op, + /* WINED3DSIH_LOGP */ shader_hw_scalar_op, + /* WINED3DSIH_LOOP */ shader_hw_loop, + /* WINED3DSIH_LRP */ shader_hw_lrp, + /* WINED3DSIH_LT */ NULL, + /* WINED3DSIH_M3x2 */ shader_hw_mnxn, + /* WINED3DSIH_M3x3 */ shader_hw_mnxn, + /* WINED3DSIH_M3x4 */ shader_hw_mnxn, + /* WINED3DSIH_M4x3 */ shader_hw_mnxn, + /* WINED3DSIH_M4x4 */ shader_hw_mnxn, + /* WINED3DSIH_MAD */ shader_hw_map2gl, + /* WINED3DSIH_MAX */ shader_hw_map2gl, + /* WINED3DSIH_MIN */ shader_hw_map2gl, + /* WINED3DSIH_MOV */ shader_hw_mov, + /* WINED3DSIH_MOVA */ shader_hw_mov, + /* WINED3DSIH_MOVC */ NULL, + /* WINED3DSIH_MUL */ shader_hw_map2gl, + /* WINED3DSIH_NE */ NULL, + /* WINED3DSIH_NOP */ shader_hw_nop, + /* WINED3DSIH_NOT */ NULL, + /* WINED3DSIH_NRM */ shader_hw_nrm, + /* WINED3DSIH_OR */ NULL, + /* WINED3DSIH_PHASE */ shader_hw_nop, + /* WINED3DSIH_POW */ shader_hw_pow, + /* WINED3DSIH_RCP */ shader_hw_scalar_op, + /* WINED3DSIH_REP */ shader_hw_rep, + /* WINED3DSIH_RESINFO */ NULL, + /* WINED3DSIH_RET */ shader_hw_ret, + /* WINED3DSIH_ROUND_NI */ NULL, + /* WINED3DSIH_ROUND_PI */ NULL, + /* WINED3DSIH_ROUND_Z */ NULL, + /* WINED3DSIH_RSQ */ shader_hw_scalar_op, + /* WINED3DSIH_SAMPLE */ NULL, + /* WINED3DSIH_SAMPLE_B */ NULL, + /* WINED3DSIH_SAMPLE_C */ NULL, + /* WINED3DSIH_SAMPLE_C_LZ */ NULL, + /* WINED3DSIH_SAMPLE_GRAD */ NULL, + /* WINED3DSIH_SAMPLE_LOD */ NULL, + /* WINED3DSIH_SETP */ NULL, + /* WINED3DSIH_SGE */ shader_hw_map2gl, + /* WINED3DSIH_SGN */ shader_hw_sgn, + /* WINED3DSIH_SINCOS */ shader_hw_sincos, + /* WINED3DSIH_SLT */ shader_hw_map2gl, + /* WINED3DSIH_SQRT */ NULL, + /* WINED3DSIH_SUB */ shader_hw_map2gl, + /* WINED3DSIH_TEX */ pshader_hw_tex, + /* WINED3DSIH_TEXBEM */ pshader_hw_texbem, + /* WINED3DSIH_TEXBEML */ pshader_hw_texbem, + /* WINED3DSIH_TEXCOORD */ pshader_hw_texcoord, + /* WINED3DSIH_TEXDEPTH */ pshader_hw_texdepth, + /* WINED3DSIH_TEXDP3 */ pshader_hw_texdp3, + /* WINED3DSIH_TEXDP3TEX */ pshader_hw_texdp3tex, + /* WINED3DSIH_TEXKILL */ pshader_hw_texkill, + /* WINED3DSIH_TEXLDD */ shader_hw_texldd, + /* WINED3DSIH_TEXLDL */ shader_hw_texldl, + /* WINED3DSIH_TEXM3x2DEPTH */ pshader_hw_texm3x2depth, + /* WINED3DSIH_TEXM3x2PAD */ pshader_hw_texm3x2pad, + /* WINED3DSIH_TEXM3x2TEX */ pshader_hw_texm3x2tex, + /* WINED3DSIH_TEXM3x3 */ pshader_hw_texm3x3, + /* WINED3DSIH_TEXM3x3DIFF */ NULL, + /* WINED3DSIH_TEXM3x3PAD */ pshader_hw_texm3x3pad, + /* WINED3DSIH_TEXM3x3SPEC */ pshader_hw_texm3x3spec, + /* WINED3DSIH_TEXM3x3TEX */ pshader_hw_texm3x3tex, + /* WINED3DSIH_TEXM3x3VSPEC */ pshader_hw_texm3x3vspec, + /* WINED3DSIH_TEXREG2AR */ pshader_hw_texreg2ar, + /* WINED3DSIH_TEXREG2GB */ pshader_hw_texreg2gb, + /* WINED3DSIH_TEXREG2RGB */ pshader_hw_texreg2rgb, + /* WINED3DSIH_UDIV */ NULL, + /* WINED3DSIH_UGE */ NULL, + /* WINED3DSIH_USHR */ NULL, + /* WINED3DSIH_UTOF */ NULL, + /* WINED3DSIH_XOR */ NULL, }; static BOOL get_bool_const(const struct wined3d_shader_instruction *ins, @@ -5417,8 +5443,8 @@ static void record_instruction(struct list *list, const struct wined3d_shader_instruction *ins) { unsigned int i; - struct wined3d_shader_dst_param *dst_param = NULL; - struct wined3d_shader_src_param *src_param = NULL, *rel_addr = NULL; + struct wined3d_shader_dst_param *dst_param; + struct wined3d_shader_src_param *src_param = NULL, *rel_addr; struct recorded_instruction *rec = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rec)); if(!rec) { @@ -5727,7 +5753,7 @@ /* Unhandled opcode */ if (!hw_fct) { - FIXME("Backend can't handle opcode %#x\n", ins->handler_idx); + FIXME("Backend can't handle opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); return; } hw_fct(ins); @@ -6549,7 +6575,10 @@ gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); - } else { + } + else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP + && settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE) + { gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst, settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); @@ -7893,15 +7922,15 @@ surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); } -static HRESULT arbfp_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface, - const RECT *dst_rect, const struct wined3d_color *color) +static HRESULT arbfp_blit_color_fill(struct wined3d_device *device, struct wined3d_rendertarget_view *view, + const RECT *rect, const struct wined3d_color *color) { FIXME("Color filling not implemented by arbfp_blit\n"); return WINED3DERR_INVALIDCALL; } -static HRESULT arbfp_blit_depth_fill(struct wined3d_device *device, - struct wined3d_surface *surface, const RECT *rect, float depth) +static HRESULT arbfp_blit_depth_fill(struct wined3d_device *device, struct wined3d_rendertarget_view *view, + const RECT *rect, float depth) { FIXME("Depth filling not implemented by arbfp_blit.\n"); return WINED3DERR_INVALIDCALL; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/buffer.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/buffer.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/buffer.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/buffer.c 2016-02-08 19:32:34.000000000 +0000 @@ -650,7 +650,7 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info, DWORD flags) { BYTE *map; - UINT start = 0, len = 0; + UINT start, len; /* This potentially invalidates the element array buffer binding, but the * caller always takes care of this. */ @@ -722,7 +722,7 @@ { DWORD flags = buffer->flags & (WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); struct wined3d_device *device = buffer->resource.device; - UINT start = 0, end = 0, len = 0, vertices; + UINT start, end, len, vertices; const struct wined3d_gl_info *gl_info; BOOL decl_changed = FALSE; unsigned int i, j; @@ -1113,6 +1113,33 @@ } } +HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, + const struct wined3d_box *box, const void *data) +{ + UINT offset, size; + HRESULT hr; + BYTE *ptr; + + if (box) + { + offset = box->left; + size = box->right - box->left; + } + else + { + offset = 0; + size = buffer->resource.size; + } + + if (FAILED(hr = wined3d_buffer_map(buffer, offset, size, &ptr, 0))) + return hr; + + memcpy(ptr, data, size); + + wined3d_buffer_unmap(buffer); + return WINED3D_OK; +} + static ULONG buffer_resource_incref(struct wined3d_resource *resource) { return wined3d_buffer_incref(buffer_from_resource(resource)); @@ -1203,7 +1230,7 @@ TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage, debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory, buffer); - if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) + if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING || pool == WINED3D_POOL_MANAGED) { /* SWvp always returns the same pointer in buffer maps and retains data in DISCARD maps. * Keep a system memory copy of the buffer to provide the same behavior to the application. @@ -1240,20 +1267,13 @@ if (data) { - BYTE *ptr; - - hr = wined3d_buffer_map(buffer, 0, size, &ptr, 0); - if (FAILED(hr)) + if (FAILED(hr = wined3d_buffer_upload_data(buffer, NULL, data->data))) { - ERR("Failed to map buffer, hr %#x\n", hr); + ERR("Failed to upload data, hr %#x.\n", hr); buffer_unload(&buffer->resource); resource_cleanup(&buffer->resource); return hr; } - - memcpy(ptr, data->data, size); - - wined3d_buffer_unmap(buffer); } buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/context.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/context.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/context.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/context.c 2016-02-08 19:32:34.000000000 +0000 @@ -1456,7 +1456,7 @@ unsigned int s; int swap_interval; DWORD state; - HDC hdc; + HDC hdc = 0; BOOL hdc_is_private = FALSE; TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle); @@ -1837,6 +1837,7 @@ return ret; out: + if (hdc) wined3d_release_dc(swapchain->win_handle, hdc); device->shader_backend->shader_free_context_data(ret); device->adapter->fragment_pipe->free_context_data(ret); HeapFree(GetProcessHeap(), 0, ret->free_event_queries); @@ -3112,6 +3113,7 @@ static void context_bind_shader_resources(struct wined3d_context *context, const struct wined3d_state *state) { + const struct wined3d_device *device = context->swapchain->device; const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_shader_sampler_map_entry *entry; struct wined3d_shader_resource_view *view; @@ -3119,6 +3121,7 @@ struct wined3d_texture *texture; struct wined3d_shader *shader; unsigned int i, j, count; + GLuint sampler_name; static const struct { @@ -3161,7 +3164,15 @@ continue; } - if (!(sampler = state->sampler[shader_types[i].type][entry->sampler_idx])) + if (entry->sampler_idx == WINED3D_SAMPLER_DEFAULT) + { + sampler_name = device->default_sampler; + } + else if ((sampler = state->sampler[shader_types[i].type][entry->sampler_idx])) + { + sampler_name = sampler->name; + } + else { WARN("No sampler object bound at index %u, %u.\n", shader_types[i].type, entry->sampler_idx); continue; @@ -3171,7 +3182,7 @@ context_active_texture(context, gl_info, shader_types[i].base_idx + entry->bind_idx); wined3d_texture_bind(texture, context, FALSE); - GL_EXTCALL(glBindSampler(shader_types[i].base_idx + entry->bind_idx, sampler->name)); + GL_EXTCALL(glBindSampler(shader_types[i].base_idx + entry->bind_idx, sampler_name)); checkGLcall("glBindSampler"); } } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/device.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/device.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/device.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/device.c 2016-02-08 19:32:34.000000000 +0000 @@ -599,7 +599,6 @@ { struct wined3d_color_key color_key; struct wined3d_resource_desc desc; - struct wined3d_surface *surface; HBITMAP hbm; BITMAP bm; HRESULT hr; @@ -623,7 +622,7 @@ bm.bmHeight = 32; } - desc.resource_type = WINED3D_RTYPE_TEXTURE; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = WINED3DFMT_B5G6R5_UNORM; desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; @@ -633,20 +632,19 @@ desc.height = bm.bmHeight; desc.depth = 1; desc.size = 0; - if (FAILED(hr = wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE, + if (FAILED(hr = wined3d_texture_create(device, &desc, 1, WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, NULL, &wined3d_null_parent_ops, &device->logo_texture))) { ERR("Wine logo requested, but failed to create texture, hr %#x.\n", hr); goto out; } - surface = surface_from_resource(wined3d_texture_get_sub_resource(device->logo_texture, 0)); if (dcb) { - if (FAILED(hr = wined3d_surface_getdc(surface, &dcs))) + if (FAILED(hr = wined3d_texture_get_dc(device->logo_texture, 0, &dcs))) goto out; BitBlt(dcs, 0, 0, bm.bmWidth, bm.bmHeight, dcb, 0, 0, SRCCOPY); - wined3d_surface_releasedc(surface, dcs); + wined3d_texture_release_dc(device->logo_texture, 0, dcs); color_key.color_space_low_value = 0; color_key.color_space_high_value = 0; @@ -654,10 +652,12 @@ } else { - const RECT rect = {0, 0, surface->resource.width, surface->resource.height}; const struct wined3d_color c = {1.0f, 1.0f, 1.0f, 1.0f}; + const RECT rect = {0, 0, desc.width, desc.height}; + struct wined3d_surface *surface; /* Fill the surface with a white color to show that wined3d is there */ + surface = surface_from_resource(wined3d_texture_get_sub_resource(device->logo_texture, 0)); surface_color_fill(surface, &rect, &c); } @@ -679,7 +679,7 @@ count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers); for (i = 0; i < count; ++i) { - DWORD color = 0x000000ff; + static const DWORD color = 0x000000ff; /* Make appropriate texture active */ context_active_texture(context, gl_info, i); @@ -773,6 +773,51 @@ memset(device->dummy_texture_2d, 0, count * sizeof(*device->dummy_texture_2d)); } +/* Context activation is done by the caller. */ +static void create_default_sampler(struct wined3d_device *device) +{ + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + + /* + * In SM4+ shaders there is a separation between resources and samplers. Some of shader + * instructions allow to access resources without using samplers. + * In GLSL resources are always accessed through sampler or image variables. The default + * sampler object is used to emulate the direct resource access when there is no sampler state + * to use. + */ + + if (gl_info->supported[ARB_SAMPLER_OBJECTS]) + { + GL_EXTCALL(glGenSamplers(1, &device->default_sampler)); + checkGLcall("glGenSamplers"); + GL_EXTCALL(glSamplerParameteri(device->default_sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_EXTCALL(glSamplerParameteri(device->default_sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)); + if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) + { + GL_EXTCALL(glSamplerParameteri(device->default_sampler, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT)); + } + checkGLcall("glSamplerParamteri"); + } + else + { + device->default_sampler = 0; + } +} + +/* Context activation is done by the caller. */ +static void destroy_default_sampler(struct wined3d_device *device) +{ + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + + if (gl_info->supported[ARB_SAMPLER_OBJECTS]) + { + GL_EXTCALL(glDeleteSamplers(1, &device->default_sampler)); + checkGLcall("glDeleteSamplers"); + } + + device->default_sampler = 0; +} + static LONG fullscreen_style(LONG style) { /* Make sure the window is managed, otherwise we won't get keyboard input. */ @@ -950,12 +995,20 @@ goto err_out; } - if (swapchain_desc->backbuffer_count && FAILED(hr = wined3d_rendertarget_view_create_from_surface( - surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)), - NULL, &wined3d_null_parent_ops, &device->back_buffer_view))) + if (swapchain_desc->backbuffer_count) { - ERR("Failed to create rendertarget view, hr %#x.\n", hr); - goto err_out; + struct wined3d_rendertarget_view_desc view_desc; + + view_desc.format_id = swapchain_desc->backbuffer_format; + view_desc.u.texture.level_idx = 0; + view_desc.u.texture.layer_idx = 0; + view_desc.u.texture.layer_count = 1; + if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, &swapchain->back_buffers[0]->resource, + NULL, &wined3d_null_parent_ops, &device->back_buffer_view))) + { + ERR("Failed to create rendertarget view, hr %#x.\n", hr); + goto err_out; + } } device->swapchain_count = 1; @@ -972,6 +1025,7 @@ surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0))); create_dummy_textures(device, context); + create_default_sampler(device); device->contexts[0]->last_was_rhw = 0; @@ -1119,6 +1173,7 @@ device->blitter->free_private(device); device->shader_backend->shader_free_private(device); destroy_dummy_textures(device, gl_info); + destroy_default_sampler(device); /* Release the context again as soon as possible. In particular, * releasing the render target views below may release the last reference @@ -1968,24 +2023,34 @@ { struct wined3d_texture *texture = state->textures[0]; struct wined3d_surface *depth_stencil, *surface; + RECT src_rect, dst_rect; - if (!texture || texture->resource.type != WINED3D_RTYPE_TEXTURE + if (!texture || texture->resource.type != WINED3D_RTYPE_TEXTURE_2D || !(texture->resource.format_flags & WINED3DFMT_FLAG_DEPTH)) return; surface = surface_from_resource(texture->sub_resources[0]); if (!(depth_stencil = wined3d_rendertarget_view_get_surface(state->fb->depth_stencil))) return; - wined3d_surface_blt(surface, NULL, depth_stencil, NULL, 0, NULL, WINED3D_TEXF_POINT); + SetRect(&dst_rect, 0, 0, surface->resource.width, surface->resource.height); + SetRect(&src_rect, 0, 0, depth_stencil->resource.width, depth_stencil->resource.height); + wined3d_surface_blt(surface, &dst_rect, depth_stencil, &src_rect, 0, NULL, WINED3D_TEXF_POINT); } void CDECL wined3d_device_set_render_state(struct wined3d_device *device, enum wined3d_render_state state, DWORD value) { - DWORD old_value = device->state.render_states[state]; + DWORD old_value; TRACE("device %p, state %s (%#x), value %#x.\n", device, debug_d3drenderstate(state), state, value); + if (state > WINEHIGHEST_RENDER_STATE) + { + WARN("Unhandled render state %#x.\n", state); + return; + } + + old_value = device->state.render_states[state]; device->update_state->render_states[state] = value; /* Handle recording of state blocks. */ @@ -3539,8 +3604,9 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture) { + unsigned int src_size, dst_size, src_skip_levels = 0; + unsigned int layer_count, level_count, i, j; enum wined3d_resource_type type; - unsigned int level_count, i, j, src_size, dst_size, src_skip_levels = 0; HRESULT hr; struct wined3d_context *context; @@ -3572,6 +3638,13 @@ return WINED3DERR_INVALIDCALL; } + layer_count = src_texture->layer_count; + if (layer_count != dst_texture->layer_count) + { + WARN("Source and destination have different layer counts.\n"); + return WINED3DERR_INVALIDCALL; + } + level_count = min(wined3d_texture_get_level_count(src_texture), wined3d_texture_get_level_count(dst_texture)); @@ -3596,34 +3669,14 @@ /* Update every surface level of the texture. */ switch (type) { - case WINED3D_RTYPE_TEXTURE: - { - struct wined3d_surface *src_surface; - struct wined3d_surface *dst_surface; - - for (i = 0; i < level_count; ++i) - { - src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, - i + src_skip_levels)); - dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, i)); - hr = wined3d_device_update_surface(device, src_surface, NULL, dst_surface, NULL); - if (FAILED(hr)) - { - WARN("Failed to update surface, hr %#x.\n", hr); - return hr; - } - } - break; - } - - case WINED3D_RTYPE_CUBE_TEXTURE: + case WINED3D_RTYPE_TEXTURE_2D: { + unsigned int src_levels = src_texture->level_count; + unsigned int dst_levels = dst_texture->level_count; struct wined3d_surface *src_surface; struct wined3d_surface *dst_surface; - unsigned int src_levels = wined3d_texture_get_level_count(src_texture); - unsigned int dst_levels = wined3d_texture_get_level_count(dst_texture); - for (i = 0; i < 6; ++i) + for (i = 0; i < layer_count; ++i) { for (j = 0; j < level_count; ++j) { @@ -3631,8 +3684,7 @@ i * src_levels + j + src_skip_levels)); dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, i * dst_levels + j)); - hr = wined3d_device_update_surface(device, src_surface, NULL, dst_surface, NULL); - if (FAILED(hr)) + if (FAILED(hr = wined3d_device_update_surface(device, src_surface, NULL, dst_surface, NULL))) { WARN("Failed to update surface, hr %#x.\n", hr); return hr; @@ -3642,7 +3694,7 @@ break; } - case WINED3D_RTYPE_VOLUME_TEXTURE: + case WINED3D_RTYPE_TEXTURE_3D: { for (i = 0; i < level_count; ++i) { @@ -3831,6 +3883,7 @@ { struct wined3d_surface *dst_surface, *src_surface; struct wined3d_texture *dst_texture, *src_texture; + RECT dst_rect, src_rect; unsigned int i, count; HRESULT hr; @@ -3868,7 +3921,7 @@ return; } - if (dst_resource->type != WINED3D_RTYPE_TEXTURE) + if (dst_resource->type != WINED3D_RTYPE_TEXTURE_2D) { FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_resource->type)); return; @@ -3892,8 +3945,11 @@ dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, i)); src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, i)); - if (FAILED(hr = wined3d_surface_blt(dst_surface, NULL, src_surface, NULL, 0, NULL, WINED3D_TEXF_POINT))) - ERR("Failed to blit, subresource %u, hr %#x.\n", i, hr); + SetRect(&dst_rect, 0, 0, dst_surface->resource.width, dst_surface->resource.height); + SetRect(&src_rect, 0, 0, src_surface->resource.width, src_surface->resource.height); + if (FAILED(hr = wined3d_surface_blt(dst_surface, &dst_rect, + src_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT))) + ERR("Failed to blit, sub-resource %u, hr %#x.\n", i, hr); } } @@ -3909,9 +3965,9 @@ HRESULT hr; TRACE("device %p, dst_resource %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u, " - "src_resource %p, src_sub_resource_idx %u, src_box %p.\n", + "src_resource %p, src_sub_resource_idx %u, src_box %s.\n", device, dst_resource, dst_sub_resource_idx, dst_x, dst_y, dst_z, - src_resource, src_sub_resource_idx, src_box); + src_resource, src_sub_resource_idx, debug_box(src_box)); if (src_resource == dst_resource && src_sub_resource_idx == dst_sub_resource_idx) { @@ -3935,7 +3991,7 @@ return WINED3DERR_INVALIDCALL; } - if (dst_resource->type != WINED3D_RTYPE_TEXTURE) + if (dst_resource->type != WINED3D_RTYPE_TEXTURE_2D) { FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_resource->type)); return WINED3DERR_INVALIDCALL; @@ -3957,18 +4013,34 @@ } src_surface = surface_from_resource(tmp); + if (src_box) + { + if (src_box->front >= src_box->back) + { + WARN("Invalid box %s specified.\n", debug_box(src_box)); + return WINED3DERR_INVALIDCALL; + } + + src_rect.left = src_box->left; + src_rect.top = src_box->top; + src_rect.right = src_box->right; + src_rect.bottom = src_box->bottom; + } + else + { + src_rect.left = 0; + src_rect.top = 0; + src_rect.right = src_surface->resource.width; + src_rect.bottom = src_surface->resource.height; + } + dst_rect.left = dst_x; dst_rect.top = dst_y; - dst_rect.right = dst_x + (src_box->right - src_box->left); - dst_rect.bottom = dst_y + (src_box->bottom - src_box->top); - - src_rect.left = src_box->left; - src_rect.top = src_box->top; - src_rect.right = src_box->right; - src_rect.bottom = src_box->bottom; + dst_rect.right = dst_x + (src_rect.right - src_rect.left); + dst_rect.bottom = dst_y + (src_rect.bottom - src_rect.top); if (FAILED(hr = wined3d_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT))) - ERR("Failed to blit, hr %#x.\n", hr); + WARN("Failed to blit, hr %#x.\n", hr); return hr; } @@ -3986,10 +4058,27 @@ POINT dst_point; RECT src_rect; - TRACE("device %p, resource %p, sub_resource_idx %u, box %p, data %p, row_pitch %u, depth_pitch %u.\n", - device, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); + TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u.\n", + device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch); - if (resource->type != WINED3D_RTYPE_TEXTURE) + if (resource->type == WINED3D_RTYPE_BUFFER) + { + struct wined3d_buffer *buffer = buffer_from_resource(resource); + HRESULT hr; + + if (sub_resource_idx > 0) + { + WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); + return; + } + + if (FAILED(hr = wined3d_buffer_upload_data(buffer, box, data))) + WARN("Failed to update buffer data, hr %#x.\n", hr); + + return; + } + + if (resource->type != WINED3D_RTYPE_TEXTURE_2D) { FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); return; @@ -4008,10 +4097,10 @@ if (box) { if (box->left >= box->right || box->right > sub_resource->width - || box->top >= box->bottom || box->bottom > sub_resource->height) + || box->top >= box->bottom || box->bottom > sub_resource->height + || box->front >= box->back) { - WARN("Invalid box (%u, %u, %u)->(%u, %u, %u) specified.\n", - box->left, box->top, box->front, box->right, box->bottom, box->back); + WARN("Invalid box %s specified.\n", debug_box(box)); return; } @@ -4061,7 +4150,7 @@ device, view, wine_dbgstr_rect(rect), color->r, color->g, color->b, color->a); resource = view->resource; - if (resource->type != WINED3D_RTYPE_TEXTURE && resource->type != WINED3D_RTYPE_CUBE_TEXTURE) + if (resource->type != WINED3D_RTYPE_TEXTURE_2D) { FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); return WINED3DERR_INVALIDCALL; @@ -4203,7 +4292,7 @@ data.row_pitch = map_desc.row_pitch; data.slice_pitch = map_desc.slice_pitch; - desc.resource_type = WINED3D_RTYPE_TEXTURE; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = WINED3DFMT_B8G8R8A8_UNORM; desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; @@ -4214,7 +4303,7 @@ desc.depth = 1; desc.size = 0; - hr = wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE, + hr = wined3d_texture_create(device, &desc, 1, WINED3D_TEXTURE_CREATE_MAPPABLE, &data, NULL, &wined3d_null_parent_ops, &texture); wined3d_surface_unmap(cursor_image); if (FAILED(hr)) @@ -4446,6 +4535,7 @@ device->blitter->free_private(device); device->shader_backend->shader_free_private(device); destroy_dummy_textures(device, gl_info); + destroy_default_sampler(device); context_release(context); @@ -4503,6 +4593,7 @@ swapchain->context[0] = context; swapchain->num_contexts = 1; create_dummy_textures(device, context); + create_default_sampler(device); context_release(context); return WINED3D_OK; @@ -4512,6 +4603,7 @@ const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode, wined3d_device_reset_cb callback, BOOL reset_state) { + struct wined3d_rendertarget_view_desc view_desc; struct wined3d_resource *resource, *cursor; struct wined3d_swapchain *swapchain; struct wined3d_display_mode m; @@ -4704,11 +4796,10 @@ { struct wined3d_resource_desc texture_desc; struct wined3d_texture *texture; - struct wined3d_rendertarget_view_desc view_desc; TRACE("Creating the depth stencil buffer\n"); - texture_desc.resource_type = WINED3D_RTYPE_TEXTURE; + texture_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; texture_desc.format = swapchain->desc.auto_depth_stencil_format; texture_desc.multisample_type = swapchain->desc.multisample_type; texture_desc.multisample_quality = swapchain->desc.multisample_quality; @@ -4747,12 +4838,18 @@ wined3d_rendertarget_view_decref(device->back_buffer_view); device->back_buffer_view = NULL; } - if (swapchain->desc.backbuffer_count && FAILED(hr = wined3d_rendertarget_view_create_from_surface( - surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)), - NULL, &wined3d_null_parent_ops, &device->back_buffer_view))) + if (swapchain->desc.backbuffer_count) { - ERR("Failed to create rendertarget view, hr %#x.\n", hr); - return hr; + view_desc.format_id = swapchain_desc->backbuffer_format; + view_desc.u.texture.level_idx = 0; + view_desc.u.texture.layer_idx = 0; + view_desc.u.texture.layer_count = 1; + if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, &swapchain->back_buffers[0]->resource, + NULL, &wined3d_null_parent_ops, &device->back_buffer_view))) + { + ERR("Failed to create rendertarget view, hr %#x.\n", hr); + return hr; + } } wine_rb_clear(&device->samplers, device_free_sampler, NULL); @@ -4826,6 +4923,13 @@ *parameters = device->create_parms; } +struct wined3d * CDECL wined3d_device_get_wined3d(const struct wined3d_device *device) +{ + TRACE("device %p.\n", device); + + return device->wined3d; +} + void CDECL wined3d_device_set_gamma_ramp(const struct wined3d_device *device, UINT swapchain_idx, DWORD flags, const struct wined3d_gamma_ramp *ramp) { @@ -4898,9 +5002,8 @@ } break; - case WINED3D_RTYPE_TEXTURE: - case WINED3D_RTYPE_CUBE_TEXTURE: - case WINED3D_RTYPE_VOLUME_TEXTURE: + case WINED3D_RTYPE_TEXTURE_2D: + case WINED3D_RTYPE_TEXTURE_3D: for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) { struct wined3d_texture *texture = wined3d_texture_from_resource(resource); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/directx.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/directx.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/directx.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/directx.c 2016-02-08 19:32:34.000000000 +0000 @@ -101,7 +101,6 @@ static const struct wined3d_extension_map gl_extension_map[] = { /* APPLE */ - {"GL_APPLE_client_storage", APPLE_CLIENT_STORAGE }, {"GL_APPLE_fence", APPLE_FENCE }, {"GL_APPLE_float_pixels", APPLE_FLOAT_PIXELS }, {"GL_APPLE_flush_buffer_range", APPLE_FLUSH_BUFFER_RANGE }, @@ -124,8 +123,9 @@ {"GL_ARB_geometry_shader4", ARB_GEOMETRY_SHADER4 }, {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL }, {"GL_ARB_half_float_vertex", ARB_HALF_FLOAT_VERTEX }, - {"GL_ARB_instanced_arrays", ARB_INSTANCED_ARRAYS, }, - {"GL_ARB_internalformat_query2", ARB_INTERNALFORMAT_QUERY2, }, + {"GL_ARB_instanced_arrays", ARB_INSTANCED_ARRAYS }, + {"GL_ARB_internalformat_query", ARB_INTERNALFORMAT_QUERY }, + {"GL_ARB_internalformat_query2", ARB_INTERNALFORMAT_QUERY2 }, {"GL_ARB_map_buffer_alignment", ARB_MAP_BUFFER_ALIGNMENT }, {"GL_ARB_map_buffer_range", ARB_MAP_BUFFER_RANGE }, {"GL_ARB_multisample", ARB_MULTISAMPLE }, @@ -151,8 +151,10 @@ {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT }, {"GL_ARB_texture_mirror_clamp_to_edge", ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE}, {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO }, + {"GL_ARB_texture_query_levels", ARB_TEXTURE_QUERY_LEVELS }, {"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE }, {"GL_ARB_texture_rg", ARB_TEXTURE_RG }, + {"GL_ARB_texture_rgb10_a2ui", ARB_TEXTURE_RGB10_A2UI }, {"GL_ARB_timer_query", ARB_TIMER_QUERY }, {"GL_ARB_uniform_buffer_object", ARB_UNIFORM_BUFFER_OBJECT }, {"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA }, @@ -194,6 +196,7 @@ {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE }, {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3 }, {"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC}, + {"GL_EXT_texture_integer", EXT_TEXTURE_INTEGER }, {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS }, {"GL_EXT_texture_mirror_clamp", EXT_TEXTURE_MIRROR_CLAMP }, {"GL_EXT_texture_snorm", EXT_TEXTURE_SNORM }, @@ -1599,7 +1602,6 @@ * the chance that other implementations support them is rather small since Win32 QuickTime uses * DirectDraw, not OpenGL. */ if (gl_info->supported[APPLE_FENCE] - && gl_info->supported[APPLE_CLIENT_STORAGE] && gl_info->supported[APPLE_YCBCR_422]) return GL_VENDOR_APPLE; @@ -3409,6 +3411,7 @@ {ARB_TEXTURE_FLOAT, MAKEDWORD_VERSION(3, 0)}, {ARB_TEXTURE_RG, MAKEDWORD_VERSION(3, 0)}, {EXT_DRAW_BUFFERS2, MAKEDWORD_VERSION(3, 0)}, + {EXT_TEXTURE_INTEGER, MAKEDWORD_VERSION(3, 0)}, /* We don't want to enable EXT_GPU_SHADER4: even though similar * functionality is available in core GL 3.0 / GLSL 1.30, it's different * enough that reusing the same flag for the new features hurts more @@ -3434,14 +3437,17 @@ {ARB_INSTANCED_ARRAYS, MAKEDWORD_VERSION(3, 3)}, {ARB_SAMPLER_OBJECTS, MAKEDWORD_VERSION(3, 3)}, {ARB_SHADER_BIT_ENCODING, MAKEDWORD_VERSION(3, 3)}, + {ARB_TEXTURE_RGB10_A2UI, MAKEDWORD_VERSION(3, 3)}, {ARB_TIMER_QUERY, MAKEDWORD_VERSION(3, 3)}, {ARB_ES2_COMPATIBILITY, MAKEDWORD_VERSION(4, 1)}, + {ARB_INTERNALFORMAT_QUERY, MAKEDWORD_VERSION(4, 2)}, {ARB_MAP_BUFFER_ALIGNMENT, MAKEDWORD_VERSION(4, 2)}, {ARB_DEBUG_OUTPUT, MAKEDWORD_VERSION(4, 3)}, {ARB_INTERNALFORMAT_QUERY2, MAKEDWORD_VERSION(4, 3)}, + {ARB_TEXTURE_QUERY_LEVELS, MAKEDWORD_VERSION(4, 3)}, }; struct wined3d_driver_info *driver_info = &adapter->driver_info; const char *gl_vendor_str, *gl_renderer_str, *gl_version_str; @@ -4402,36 +4408,44 @@ enum wined3d_device_type device_type, enum wined3d_format_id surface_format_id, BOOL windowed, enum wined3d_multisample_type multisample_type, DWORD *quality_levels) { - const struct wined3d_gl_info *gl_info; + const struct wined3d_gl_info *gl_info = &wined3d->adapters[adapter_idx].gl_info; + const struct wined3d_format *format = wined3d_get_format(gl_info, surface_format_id); + HRESULT hr = WINED3D_OK; - TRACE("wined3d %p, adapter_idx %u, device_type %s, surface_format %s,\n" + TRACE("wined3d %p, adapter_idx %u, device_type %s, surface_format %s, " "windowed %#x, multisample_type %#x, quality_levels %p.\n", wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(surface_format_id), windowed, multisample_type, quality_levels); if (adapter_idx >= wined3d->adapter_count) return WINED3DERR_INVALIDCALL; - - gl_info = &wined3d->adapters[adapter_idx].gl_info; - - if (multisample_type > gl_info->limits.samples) + if (surface_format_id == WINED3DFMT_UNKNOWN) + return WINED3DERR_INVALIDCALL; + if (multisample_type < WINED3D_MULTISAMPLE_NONE) + return WINED3DERR_INVALIDCALL; + if (multisample_type > WINED3D_MULTISAMPLE_16_SAMPLES) { - TRACE("Returning not supported.\n"); - if (quality_levels) - *quality_levels = 0; - + FIXME("multisample_type %u not handled yet.\n", multisample_type); return WINED3DERR_NOTAVAILABLE; } - if (quality_levels) + if (multisample_type && !(format->multisample_types & 1u << (multisample_type - 1))) + hr = WINED3DERR_NOTAVAILABLE; + + if (SUCCEEDED(hr) || (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE && format->multisample_types)) { - if (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE) - *quality_levels = gl_info->limits.samples; - else - *quality_levels = 1; + if (quality_levels) + { + if (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE) + *quality_levels = wined3d_popcount(format->multisample_types); + else + *quality_levels = 1; + } + return WINED3D_OK; } - return WINED3D_OK; + TRACE("Returning not supported.\n"); + return hr; } /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */ @@ -4615,21 +4629,6 @@ switch (resource_type) { - case WINED3D_RTYPE_CUBE_TEXTURE: - format_flags |= WINED3DFMT_FLAG_TEXTURE; - allowed_usage = WINED3DUSAGE_AUTOGENMIPMAP - | WINED3DUSAGE_DYNAMIC - | WINED3DUSAGE_RENDERTARGET - | WINED3DUSAGE_SOFTWAREPROCESSING - | WINED3DUSAGE_QUERY_FILTER - | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING - | WINED3DUSAGE_QUERY_SRGBREAD - | WINED3DUSAGE_QUERY_SRGBWRITE - | WINED3DUSAGE_QUERY_VERTEXTEXTURE - | WINED3DUSAGE_QUERY_WRAPANDMIP; - gl_type = WINED3D_GL_RES_TYPE_TEX_CUBE; - break; - case WINED3D_RTYPE_SURFACE: if (!CheckSurfaceCapability(adapter, adapter_format, format, wined3d->flags & WINED3D_NO3D)) { @@ -4643,19 +4642,12 @@ gl_type = WINED3D_GL_RES_TYPE_RB; break; - case WINED3D_RTYPE_TEXTURE: - if ((usage & WINED3DUSAGE_DEPTHSTENCIL) - && (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_SHADOW) - && !gl_info->supported[ARB_SHADOW]) - { - TRACE("[FAILED] - No shadow sampler support.\n"); - return WINED3DERR_NOTAVAILABLE; - } - + case WINED3D_RTYPE_TEXTURE_2D: format_flags |= WINED3DFMT_FLAG_TEXTURE; allowed_usage = WINED3DUSAGE_AUTOGENMIPMAP | WINED3DUSAGE_DEPTHSTENCIL | WINED3DUSAGE_DYNAMIC + | WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_SOFTWAREPROCESSING | WINED3DUSAGE_QUERY_FILTER @@ -4666,9 +4658,21 @@ | WINED3DUSAGE_QUERY_VERTEXTEXTURE | WINED3DUSAGE_QUERY_WRAPANDMIP; gl_type = WINED3D_GL_RES_TYPE_TEX_2D; + if (usage & WINED3DUSAGE_LEGACY_CUBEMAP) + { + allowed_usage &= ~(WINED3DUSAGE_DEPTHSTENCIL | WINED3DUSAGE_QUERY_LEGACYBUMPMAP); + gl_type = WINED3D_GL_RES_TYPE_TEX_CUBE; + } + else if ((usage & WINED3DUSAGE_DEPTHSTENCIL) + && (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_SHADOW) + && !gl_info->supported[ARB_SHADOW]) + { + TRACE("[FAILED] - No shadow sampler support.\n"); + return WINED3DERR_NOTAVAILABLE; + } break; - case WINED3D_RTYPE_VOLUME_TEXTURE: + case WINED3D_RTYPE_TEXTURE_3D: case WINED3D_RTYPE_VOLUME: format_flags |= WINED3DFMT_FLAG_TEXTURE; allowed_usage = WINED3DUSAGE_DYNAMIC diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/drawprim.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/drawprim.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/drawprim.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/drawprim.c 2016-02-08 19:32:34.000000000 +0000 @@ -99,7 +99,7 @@ const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType, const void *idxData, UINT idxSize, UINT startIdx) { - unsigned int textureNo = 0; + unsigned int textureNo; const WORD *pIdxBufS = NULL; const DWORD *pIdxBufL = NULL; UINT vx_index; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/glsl_shader.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/glsl_shader.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/glsl_shader.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/glsl_shader.c 2016-02-08 19:32:34.000000000 +0000 @@ -44,10 +44,11 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(winediag); -#define WINED3D_GLSL_SAMPLE_PROJECTED 0x1 -#define WINED3D_GLSL_SAMPLE_NPOT 0x2 -#define WINED3D_GLSL_SAMPLE_LOD 0x4 -#define WINED3D_GLSL_SAMPLE_GRAD 0x8 +#define WINED3D_GLSL_SAMPLE_PROJECTED 0x01 +#define WINED3D_GLSL_SAMPLE_NPOT 0x02 +#define WINED3D_GLSL_SAMPLE_LOD 0x04 +#define WINED3D_GLSL_SAMPLE_GRAD 0x08 +#define WINED3D_GLSL_SAMPLE_LOAD 0x10 struct glsl_dst_param { @@ -1284,7 +1285,7 @@ const struct wined3d_gl_info *gl_info = context->gl_info; struct shader_glsl_priv *priv = shader_priv; float position_fixup[4]; - DWORD update_mask = 0; + DWORD update_mask; struct glsl_shader_prog_link *prog = ctx_data->glsl_program; UINT constant_version; @@ -1684,12 +1685,12 @@ max_constantsF = gl_info->limits.glsl_vs_float_constants - 3; if (vs_args->clip_enabled) max_constantsF -= gl_info->limits.clipplanes; - max_constantsF -= count_bits(reg_maps->integer_constants); + max_constantsF -= wined3d_popcount(reg_maps->integer_constants); /* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly, * so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but * for now take this into account when calculating the number of available constants */ - max_constantsF -= count_bits(reg_maps->boolean_constants); + max_constantsF -= wined3d_popcount(reg_maps->boolean_constants); /* Set by driver quirks in directx.c */ max_constantsF -= gl_info->reserved_glsl_constants; @@ -1733,8 +1734,8 @@ for (i = 0; i < reg_maps->sampler_map.count; ++i) { struct wined3d_shader_sampler_map_entry *entry; + const char *sampler_type_prefix, *sampler_type; BOOL shadow_sampler, tex_rect; - const char *sampler_type; entry = ®_maps->sampler_map.entries[i]; @@ -1744,6 +1745,28 @@ continue; } + switch (reg_maps->resource_info[entry->resource_idx].data_type) + { + case WINED3D_DATA_FLOAT: + case WINED3D_DATA_UNORM: + case WINED3D_DATA_SNORM: + sampler_type_prefix = ""; + break; + + case WINED3D_DATA_INT: + sampler_type_prefix = "i"; + break; + + case WINED3D_DATA_UINT: + sampler_type_prefix = "u"; + break; + + default: + sampler_type_prefix = ""; + ERR("Unhandled resource data type %#x.\n", reg_maps->resource_info[i].data_type); + break; + } + shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1u << entry->sampler_idx)); switch (reg_maps->resource_info[entry->resource_idx].type) { @@ -1791,7 +1814,8 @@ FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[i].type); break; } - shader_addline(buffer, "uniform %s %s_sampler%u;\n", sampler_type, prefix, entry->bind_idx); + shader_addline(buffer, "uniform %s%s %s_sampler%u;\n", + sampler_type_prefix, sampler_type, prefix, entry->bind_idx); } /* Declare uniforms for NP2 texcoord fixup: @@ -2065,8 +2089,6 @@ static void shader_glsl_gen_modifier(enum wined3d_shader_src_modifier src_modifier, const char *in_reg, const char *in_regswizzle, char *out_str) { - out_str[0] = 0; - switch (src_modifier) { case WINED3DSPSM_DZ: /* Need to handle this in the instructions itself (texld & texcrd). */ @@ -2384,6 +2406,13 @@ sprintf(register_name, "%s_cb%u[%u]", prefix, reg->idx[0].offset, reg->idx[1].offset); break; + case WINED3DSPR_IMMCONSTBUFFER: + if (reg->idx[0].rel_addr) + sprintf(register_name, "%s_icb[%s + %u]", prefix, rel_param0.param_str, reg->idx[0].offset); + else + sprintf(register_name, "%s_icb[%u]", prefix, reg->idx[0].offset); + break; + case WINED3DSPR_PRIMID: sprintf(register_name, "uint(gl_PrimitiveIDIn)"); break; @@ -2676,6 +2705,15 @@ } } + if (flags & WINED3D_GLSL_SAMPLE_LOAD) + { + if (flags != WINED3D_GLSL_SAMPLE_LOAD) + ERR("Unexpected flags for texelFetch %#x.\n", flags & ~WINED3D_GLSL_SAMPLE_LOAD); + + base = "texelFetch"; + type_part = ""; + } + sample_function->name = string_buffer_get(priv->string_buffers); string_buffer_sprintf(sample_function->name, "%s%s%s%s%s", base, type_part, projected ? "Proj" : "", lod ? "Lod" : grad ? "Grad" : "", suffix); @@ -2801,7 +2839,7 @@ } static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins, - DWORD sampler, const struct glsl_sample_function *sample_function, DWORD swizzle, + unsigned int sampler_bind_idx, const struct glsl_sample_function *sample_function, DWORD swizzle, const char *dx, const char *dy, const char *bias, const char *coord_reg_fmt, ...) { const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version; @@ -2819,9 +2857,9 @@ if (version->type == WINED3D_SHADER_TYPE_PIXEL && version->major < 4) { const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; - fixup = priv->cur_ps_args->color_fixup[sampler]; + fixup = priv->cur_ps_args->color_fixup[sampler_bind_idx]; - if (priv->cur_ps_args->np2_fixup & (1u << sampler)) + if (priv->cur_ps_args->np2_fixup & (1u << sampler_bind_idx)) np2_fixup = TRUE; } else @@ -2835,7 +2873,7 @@ shader_addline(ins->ctx->buffer, "vec4("); shader_addline(ins->ctx->buffer, "%s(%s_sampler%u, ", - sample_function->name->buffer, shader_glsl_get_prefix(version->type), sampler); + sample_function->name->buffer, shader_glsl_get_prefix(version->type), sampler_bind_idx); for (;;) { @@ -2851,7 +2889,7 @@ if (np2_fixup) { const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; - const unsigned char idx = priv->cur_np2fixup_info->idx[sampler]; + const unsigned char idx = priv->cur_np2fixup_info->idx[sampler_bind_idx]; switch (shader_glsl_get_write_mask_size(sample_function->coord_mask)) { @@ -2916,7 +2954,7 @@ case WINED3DSIH_XOR: op = "^"; break; default: op = ""; - FIXME("Opcode %#x not yet handled in GLSL\n", ins->handler_idx); + FIXME("Opcode %s not yet handled in GLSL.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); break; } @@ -2945,11 +2983,14 @@ switch (ins->handler_idx) { case WINED3DSIH_EQ: op = "equal"; break; + case WINED3DSIH_IEQ: op = "equal"; break; case WINED3DSIH_GE: op = "greaterThanEqual"; break; case WINED3DSIH_IGE: op = "greaterThanEqual"; break; case WINED3DSIH_UGE: op = "greaterThanEqual"; break; case WINED3DSIH_LT: op = "lessThan"; break; + case WINED3DSIH_ILT: op = "lessThan"; break; case WINED3DSIH_NE: op = "notEqual"; break; + case WINED3DSIH_INE: op = "notEqual"; break; default: op = ""; ERR("Unhandled opcode %#x.\n", ins->handler_idx); @@ -2964,11 +3005,14 @@ switch (ins->handler_idx) { case WINED3DSIH_EQ: op = "=="; break; + case WINED3DSIH_IEQ: op = "=="; break; case WINED3DSIH_GE: op = ">="; break; case WINED3DSIH_IGE: op = ">="; break; case WINED3DSIH_UGE: op = ">="; break; case WINED3DSIH_LT: op = "<"; break; + case WINED3DSIH_ILT: op = "<"; break; case WINED3DSIH_NE: op = "!="; break; + case WINED3DSIH_INE: op = "!="; break; default: op = ""; ERR("Unhandled opcode %#x.\n", ins->handler_idx); @@ -2980,6 +3024,28 @@ } } +static void shader_glsl_unary_op(const struct wined3d_shader_instruction *ins) +{ + struct glsl_src_param src_param; + DWORD write_mask; + const char *op; + + switch (ins->handler_idx) + { + case WINED3DSIH_INEG: op = "-"; break; + case WINED3DSIH_NOT: op = "~"; break; + default: + op = ""; + ERR("Unhandled opcode %s.\n", + debug_d3dshaderinstructionhandler(ins->handler_idx)); + break; + } + + write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins); + shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param); + shader_addline(ins->ctx->buffer, "%s%s);\n", op, src_param.param_str); +} + static void shader_glsl_imul(const struct wined3d_shader_instruction *ins) { struct wined3d_string_buffer *buffer = ins->ctx->buffer; @@ -3011,7 +3077,6 @@ if (ins->dst[0].reg.type != WINED3DSPR_NULL) { - if (ins->dst[1].reg.type != WINED3DSPR_NULL) { char dst_mask[6]; @@ -3019,15 +3084,15 @@ write_mask = shader_glsl_get_write_mask(&ins->dst[0], dst_mask); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); - shader_addline(buffer, "tmp0%s = %s / %s;\n", + shader_addline(buffer, "tmp0%s = uintBitsToFloat(%s / %s);\n", dst_mask, src0_param.param_str, src1_param.param_str); write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1], ins->dst[1].reg.data_type); shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param); shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param); - shader_addline(buffer, "%s %% %s));\n", src0_param.param_str, src1_param.param_str); + shader_addline(buffer, "%s %% %s);\n", src0_param.param_str, src1_param.param_str); - shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], ins->dst[0].reg.data_type); + shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], WINED3D_DATA_FLOAT); shader_addline(buffer, "tmp0%s);\n", dst_mask); } else @@ -3107,7 +3172,7 @@ struct glsl_src_param src0_param; struct glsl_src_param src1_param; DWORD dst_write_mask, src_write_mask; - unsigned int dst_size = 0; + unsigned int dst_size; dst_write_mask = shader_glsl_append_dst(buffer, ins); dst_size = shader_glsl_get_write_mask_size(dst_write_mask); @@ -3193,16 +3258,20 @@ /* TODO: Possibly make this a table for faster lookups */ switch (ins->handler_idx) { - case WINED3DSIH_MIN: instruction = "min"; break; - case WINED3DSIH_MAX: instruction = "max"; break; case WINED3DSIH_ABS: instruction = "abs"; break; - case WINED3DSIH_FRC: instruction = "fract"; break; case WINED3DSIH_DSX: instruction = "dFdx"; break; case WINED3DSIH_DSY: instruction = "ycorrection.y * dFdy"; break; + case WINED3DSIH_FRC: instruction = "fract"; break; + case WINED3DSIH_IMAX: instruction = "max"; break; + case WINED3DSIH_IMIN: instruction = "min"; break; + case WINED3DSIH_MAX: instruction = "max"; break; + case WINED3DSIH_MIN: instruction = "min"; break; case WINED3DSIH_ROUND_NI: instruction = "floor"; break; + case WINED3DSIH_ROUND_PI: instruction = "ceil"; break; + case WINED3DSIH_ROUND_Z: instruction = "trunc"; break; case WINED3DSIH_SQRT: instruction = "sqrt"; break; default: instruction = ""; - FIXME("Opcode %#x not yet handled in GLSL\n", ins->handler_idx); + FIXME("Opcode %s not yet handled in GLSL.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); break; } @@ -3256,6 +3325,8 @@ static void shader_glsl_scalar_op(const struct wined3d_shader_instruction *ins) { + DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major, + ins->ctx->reg_maps->shader_version.minor); struct wined3d_string_buffer *buffer = ins->ctx->buffer; struct glsl_src_param src0_param; const char *prefix, *suffix; @@ -3265,7 +3336,10 @@ dst_write_mask = shader_glsl_append_dst(buffer, ins); dst_size = shader_glsl_get_write_mask_size(dst_write_mask); - shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src0_param); + if (shader_version < WINED3D_SHADER_VERSION(4, 0)) + dst_write_mask = WINED3DSP_WRITEMASK_3; + + shader_glsl_add_src_param(ins, &ins->src[0], dst_write_mask, &src0_param); switch (ins->handler_idx) { @@ -3298,7 +3372,7 @@ break; } - if (dst_size > 1) + if (dst_size > 1 && shader_version < WINED3D_SHADER_VERSION(4, 0)) shader_addline(buffer, "vec%u(%s%s%s));\n", dst_size, prefix, src0_param.param_str, suffix); else shader_addline(buffer, "%s%s%s);\n", prefix, src0_param.param_str, suffix); @@ -3336,7 +3410,8 @@ shader_glsl_scalar_op(ins); } -static void shader_glsl_to_int(const struct wined3d_shader_instruction *ins) +static void shader_glsl_cast(const struct wined3d_shader_instruction *ins, + const char *vector_constructor, const char *scalar_constructor) { struct wined3d_string_buffer *buffer = ins->ctx->buffer; struct glsl_src_param src_param; @@ -3348,26 +3423,24 @@ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param); if (mask_size > 1) - shader_addline(buffer, "ivec%u(%s));\n", mask_size, src_param.param_str); + shader_addline(buffer, "%s%u(%s));\n", vector_constructor, mask_size, src_param.param_str); else - shader_addline(buffer, "int(%s));\n", src_param.param_str); + shader_addline(buffer, "%s(%s));\n", scalar_constructor, src_param.param_str); } -static void shader_glsl_to_float(const struct wined3d_shader_instruction *ins) +static void shader_glsl_to_int(const struct wined3d_shader_instruction *ins) { - struct wined3d_string_buffer *buffer = ins->ctx->buffer; - struct glsl_src_param src_param; - unsigned int mask_size; - DWORD write_mask; + shader_glsl_cast(ins, "ivec", "int"); +} - write_mask = shader_glsl_append_dst(buffer, ins); - mask_size = shader_glsl_get_write_mask_size(write_mask); - shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param); +static void shader_glsl_to_uint(const struct wined3d_shader_instruction *ins) +{ + shader_glsl_cast(ins, "uvec", "uint"); +} - if (mask_size > 1) - shader_addline(buffer, "vec%u(%s));\n", mask_size, src_param.param_str); - else - shader_addline(buffer, "float(%s));\n", src_param.param_str); +static void shader_glsl_to_float(const struct wined3d_shader_instruction *ins) +{ + shader_glsl_cast(ins, "vec", "float"); } /** Process signed comparison opcodes in GLSL. */ @@ -3391,7 +3464,7 @@ case WINED3DSIH_SLT: compare = "lessThan"; break; case WINED3DSIH_SGE: compare = "greaterThanEqual"; break; default: compare = ""; - FIXME("Can't handle opcode %#x\n", ins->handler_idx); + FIXME("Can't handle opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); } shader_addline(ins->ctx->buffer, "vec%d(%s(%s, %s)));\n", mask_size, compare, @@ -3415,7 +3488,7 @@ shader_addline(ins->ctx->buffer, "step(%s, %s));\n", src1_param.param_str, src0_param.param_str); break; default: - FIXME("Can't handle opcode %#x\n", ins->handler_idx); + FIXME("Can't handle opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); } } @@ -4231,18 +4304,140 @@ return ~0u; } +static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins) +{ + static const unsigned int texture_size_component_count[] = + { + 0, /* WINED3D_SHADER_RESOURCE_NONE */ + 1, /* WINED3D_SHADER_RESOURCE_BUFFER */ + 1, /* WINED3D_SHADER_RESOURCE_TEXTURE_1D */ + 2, /* WINED3D_SHADER_RESOURCE_TEXTURE_2D */ + 2, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMS */ + 3, /* WINED3D_SHADER_RESOURCE_TEXTURE_3D */ + 2, /* WINED3D_SHADER_RESOURCE_TEXTURE_CUBE */ + 2, /* WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY */ + 3, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY */ + 3, /* WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY */ + }; + + const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version; + const struct wined3d_gl_info *gl_info = ins->ctx->gl_info; + enum wined3d_shader_resource_type resource_type; + unsigned int resource_idx, sampler_bind_idx, i; + enum wined3d_data_type dst_data_type; + struct glsl_src_param lod_param; + char dst_swizzle[6]; + DWORD write_mask; + + dst_data_type = ins->dst[0].reg.data_type; + if (ins->flags == WINED3DSI_RESINFO_UINT) + dst_data_type = WINED3D_DATA_UINT; + else if (ins->flags) + FIXME("Unhandled flags %#x.\n", ins->flags); + + write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &ins->dst[0], dst_data_type); + shader_glsl_get_swizzle(&ins->src[1], FALSE, write_mask, dst_swizzle); + + resource_idx = ins->src[1].reg.idx[0].offset; + resource_type = ins->ctx->reg_maps->resource_info[resource_idx].type; + shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &lod_param); + sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, + resource_idx, WINED3D_SAMPLER_DEFAULT); + + if (resource_type >= ARRAY_SIZE(texture_size_component_count)) + { + ERR("Unexpected resource type %#x.\n", resource_type); + resource_type = WINED3D_SHADER_RESOURCE_TEXTURE_2D; + } + + if (dst_data_type == WINED3D_DATA_UINT) + shader_addline(ins->ctx->buffer, "uvec4("); + else + shader_addline(ins->ctx->buffer, "vec4("); + + shader_addline(ins->ctx->buffer, "textureSize(%s_sampler%u, %s), ", + shader_glsl_get_prefix(version->type), sampler_bind_idx, lod_param.param_str); + + for (i = 0; i < 3 - texture_size_component_count[resource_type]; ++i) + shader_addline(ins->ctx->buffer, "0, "); + + if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS]) + { + shader_addline(ins->ctx->buffer, "textureQueryLevels(%s_sampler%u)", + shader_glsl_get_prefix(version->type), sampler_bind_idx); + } + else + { + FIXME("textureQueryLevels is not supported, returning 1 mipmap level.\n"); + shader_addline(ins->ctx->buffer, "1"); + } + + shader_addline(ins->ctx->buffer, ")%s);\n", dst_swizzle); +} + +/* FIXME: The current implementation does not handle multisample textures correctly. */ +static void shader_glsl_ld(const struct wined3d_shader_instruction *ins) +{ + struct glsl_src_param coord_param, lod_param; + struct glsl_sample_function sample_function; + unsigned int sampler_bind_idx; + + shader_glsl_get_sample_function(ins->ctx, ins->src[1].reg.idx[0].offset, WINED3D_GLSL_SAMPLE_LOAD, + &sample_function); + shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param); + shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param); + sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, + ins->src[1].reg.idx[0].offset, WINED3D_SAMPLER_DEFAULT); + shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle, + NULL, NULL, lod_param.param_str, "%s", coord_param.param_str); + shader_glsl_release_sample_function(ins->ctx, &sample_function); +} + static void shader_glsl_sample(const struct wined3d_shader_instruction *ins) { + const char *lod_param_str = NULL, *dx_param_str = NULL, *dy_param_str = NULL; + struct glsl_src_param coord_param, lod_param, dx_param, dy_param; + unsigned int resource_idx, sampler_idx, sampler_bind_idx; struct glsl_sample_function sample_function; - struct glsl_src_param coord_param; - unsigned int sampler_idx; + DWORD flags = 0; + + if (ins->handler_idx == WINED3DSIH_SAMPLE_GRAD) + flags |= WINED3D_GLSL_SAMPLE_GRAD; + if (ins->handler_idx == WINED3DSIH_SAMPLE_LOD) + flags |= WINED3D_GLSL_SAMPLE_LOD; - shader_glsl_get_sample_function(ins->ctx, ins->src[1].reg.idx[0].offset, 0, &sample_function); + resource_idx = ins->src[1].reg.idx[0].offset; + sampler_idx = ins->src[2].reg.idx[0].offset; + + shader_glsl_get_sample_function(ins->ctx, resource_idx, flags, &sample_function); shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param); - sampler_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, - ins->src[1].reg.idx[0].offset, ins->src[2].reg.idx[0].offset); - shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, - NULL, NULL, NULL, "%s", coord_param.param_str); + + switch (ins->handler_idx) + { + case WINED3DSIH_SAMPLE: + break; + case WINED3DSIH_SAMPLE_B: + shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0, &lod_param); + lod_param_str = lod_param.param_str; + break; + case WINED3DSIH_SAMPLE_GRAD: + shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dx_param); + shader_glsl_add_src_param(ins, &ins->src[4], sample_function.coord_mask, &dy_param); + dx_param_str = dx_param.param_str; + dy_param_str = dy_param.param_str; + break; + case WINED3DSIH_SAMPLE_LOD: + shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0, &lod_param); + lod_param_str = lod_param.param_str; + break; + default: + ERR("Unhandled opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); + break; + } + + sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, resource_idx, sampler_idx); + shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle, + dx_param_str, dy_param_str, lod_param_str, "%s", coord_param.param_str); shader_glsl_release_sample_function(ins->ctx, &sample_function); } @@ -4960,7 +5155,7 @@ BOOL per_vertex_point_size, BOOL flatshading, const struct wined3d_gl_info *gl_info) { struct wined3d_string_buffer *buffer = &priv->shader_buffer; - GLuint ret = 0; + GLuint ret; DWORD ps_major = ps ? ps->reg_maps.shader_version.major : 0; unsigned int i; const char *semantic_name; @@ -5189,6 +5384,8 @@ shader_addline(buffer, "#extension GL_ARB_shader_bit_encoding : enable\n"); if (gl_info->supported[ARB_SHADER_TEXTURE_LOD]) shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n"); + if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS]) + shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n"); /* The spec says that it doesn't have to be explicitly enabled, but the * nvidia drivers write a warning if we don't do so. */ if (gl_info->supported[ARB_TEXTURE_RECTANGLE]) @@ -5283,6 +5480,8 @@ shader_addline(buffer, "#extension GL_ARB_draw_instanced : enable\n"); if (gl_info->supported[ARB_SHADER_BIT_ENCODING]) shader_addline(buffer, "#extension GL_ARB_shader_bit_encoding : enable\n"); + if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS]) + shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n"); if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n"); if (gl_info->supported[EXT_GPU_SHADER4]) @@ -5368,6 +5567,8 @@ shader_addline(buffer, "#extension GL_ARB_geometry_shader4 : enable\n"); if (gl_info->supported[ARB_SHADER_BIT_ENCODING]) shader_addline(buffer, "#extension GL_ARB_shader_bit_encoding : enable\n"); + if (gl_info->supported[ARB_TEXTURE_QUERY_LEVELS]) + shader_addline(buffer, "#extension GL_ARB_texture_query_levels : enable\n"); if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT]) shader_addline(buffer, "#extension GL_ARB_uniform_buffer_object : enable\n"); if (gl_info->supported[EXT_GPU_SHADER4]) @@ -6636,7 +6837,8 @@ settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].carg1, settings->op[stage].carg2); } - else + else if (settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP + && settings->op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE) { shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst, settings->op[stage].cop, settings->op[stage].carg0, @@ -6878,7 +7080,7 @@ struct wined3d_shader *vshader = NULL; struct wined3d_shader *gshader = NULL; struct wined3d_shader *pshader = NULL; - GLuint program_id = 0; + GLuint program_id; GLuint reorder_shader_id = 0; unsigned int i; GLuint vs_id = 0; @@ -7814,122 +8016,148 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TABLE_SIZE] = { - /* WINED3DSIH_ABS */ shader_glsl_map2gl, - /* WINED3DSIH_ADD */ shader_glsl_binop, - /* WINED3DSIH_AND */ shader_glsl_binop, - /* WINED3DSIH_BEM */ shader_glsl_bem, - /* WINED3DSIH_BREAK */ shader_glsl_break, - /* WINED3DSIH_BREAKC */ shader_glsl_breakc, - /* WINED3DSIH_BREAKP */ shader_glsl_breakp, - /* WINED3DSIH_CALL */ shader_glsl_call, - /* WINED3DSIH_CALLNZ */ shader_glsl_callnz, - /* WINED3DSIH_CMP */ shader_glsl_conditional_move, - /* WINED3DSIH_CND */ shader_glsl_cnd, - /* WINED3DSIH_CRS */ shader_glsl_cross, - /* WINED3DSIH_CUT */ shader_glsl_cut, - /* WINED3DSIH_DCL */ shader_glsl_nop, - /* WINED3DSIH_DCL_CONSTANT_BUFFER */ shader_glsl_nop, - /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_glsl_nop, - /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ shader_glsl_nop, - /* WINED3DSIH_DCL_VERTICES_OUT */ shader_glsl_nop, - /* WINED3DSIH_DEF */ shader_glsl_nop, - /* WINED3DSIH_DEFB */ shader_glsl_nop, - /* WINED3DSIH_DEFI */ shader_glsl_nop, - /* WINED3DSIH_DIV */ shader_glsl_binop, - /* WINED3DSIH_DP2 */ shader_glsl_dot, - /* WINED3DSIH_DP2ADD */ shader_glsl_dp2add, - /* WINED3DSIH_DP3 */ shader_glsl_dot, - /* WINED3DSIH_DP4 */ shader_glsl_dot, - /* WINED3DSIH_DST */ shader_glsl_dst, - /* WINED3DSIH_DSX */ shader_glsl_map2gl, - /* WINED3DSIH_DSY */ shader_glsl_map2gl, - /* WINED3DSIH_ELSE */ shader_glsl_else, - /* WINED3DSIH_EMIT */ shader_glsl_emit, - /* WINED3DSIH_ENDIF */ shader_glsl_end, - /* WINED3DSIH_ENDLOOP */ shader_glsl_end, - /* WINED3DSIH_ENDREP */ shader_glsl_end, - /* WINED3DSIH_EQ */ shader_glsl_relop, - /* WINED3DSIH_EXP */ shader_glsl_scalar_op, - /* WINED3DSIH_EXPP */ shader_glsl_expp, - /* WINED3DSIH_FRC */ shader_glsl_map2gl, - /* WINED3DSIH_FTOI */ shader_glsl_to_int, - /* WINED3DSIH_GE */ shader_glsl_relop, - /* WINED3DSIH_IADD */ shader_glsl_binop, - /* WINED3DSIH_IEQ */ NULL, - /* WINED3DSIH_IF */ shader_glsl_if, - /* WINED3DSIH_IFC */ shader_glsl_ifc, - /* WINED3DSIH_IGE */ shader_glsl_relop, - /* WINED3DSIH_IMUL */ shader_glsl_imul, - /* WINED3DSIH_ISHL */ shader_glsl_binop, - /* WINED3DSIH_ITOF */ shader_glsl_to_float, - /* WINED3DSIH_LABEL */ shader_glsl_label, - /* WINED3DSIH_LD */ NULL, - /* WINED3DSIH_LIT */ shader_glsl_lit, - /* WINED3DSIH_LOG */ shader_glsl_scalar_op, - /* WINED3DSIH_LOGP */ shader_glsl_scalar_op, - /* WINED3DSIH_LOOP */ shader_glsl_loop, - /* WINED3DSIH_LRP */ shader_glsl_lrp, - /* WINED3DSIH_LT */ shader_glsl_relop, - /* WINED3DSIH_M3x2 */ shader_glsl_mnxn, - /* WINED3DSIH_M3x3 */ shader_glsl_mnxn, - /* WINED3DSIH_M3x4 */ shader_glsl_mnxn, - /* WINED3DSIH_M4x3 */ shader_glsl_mnxn, - /* WINED3DSIH_M4x4 */ shader_glsl_mnxn, - /* WINED3DSIH_MAD */ shader_glsl_mad, - /* WINED3DSIH_MAX */ shader_glsl_map2gl, - /* WINED3DSIH_MIN */ shader_glsl_map2gl, - /* WINED3DSIH_MOV */ shader_glsl_mov, - /* WINED3DSIH_MOVA */ shader_glsl_mov, - /* WINED3DSIH_MOVC */ shader_glsl_conditional_move, - /* WINED3DSIH_MUL */ shader_glsl_binop, - /* WINED3DSIH_NE */ shader_glsl_relop, - /* WINED3DSIH_NOP */ shader_glsl_nop, - /* WINED3DSIH_NRM */ shader_glsl_nrm, - /* WINED3DSIH_OR */ shader_glsl_binop, - /* WINED3DSIH_PHASE */ shader_glsl_nop, - /* WINED3DSIH_POW */ shader_glsl_pow, - /* WINED3DSIH_RCP */ shader_glsl_scalar_op, - /* WINED3DSIH_REP */ shader_glsl_rep, - /* WINED3DSIH_RET */ shader_glsl_ret, - /* WINED3DSIH_ROUND_NI */ shader_glsl_map2gl, - /* WINED3DSIH_RSQ */ shader_glsl_scalar_op, - /* WINED3DSIH_SAMPLE */ shader_glsl_sample, - /* WINED3DSIH_SAMPLE_GRAD */ NULL, - /* WINED3DSIH_SAMPLE_LOD */ NULL, - /* WINED3DSIH_SETP */ NULL, - /* WINED3DSIH_SGE */ shader_glsl_compare, - /* WINED3DSIH_SGN */ shader_glsl_sgn, - /* WINED3DSIH_SINCOS */ shader_glsl_sincos, - /* WINED3DSIH_SLT */ shader_glsl_compare, - /* WINED3DSIH_SQRT */ shader_glsl_map2gl, - /* WINED3DSIH_SUB */ shader_glsl_binop, - /* WINED3DSIH_TEX */ shader_glsl_tex, - /* WINED3DSIH_TEXBEM */ shader_glsl_texbem, - /* WINED3DSIH_TEXBEML */ shader_glsl_texbem, - /* WINED3DSIH_TEXCOORD */ shader_glsl_texcoord, - /* WINED3DSIH_TEXDEPTH */ shader_glsl_texdepth, - /* WINED3DSIH_TEXDP3 */ shader_glsl_texdp3, - /* WINED3DSIH_TEXDP3TEX */ shader_glsl_texdp3tex, - /* WINED3DSIH_TEXKILL */ shader_glsl_texkill, - /* WINED3DSIH_TEXLDD */ shader_glsl_texldd, - /* WINED3DSIH_TEXLDL */ shader_glsl_texldl, - /* WINED3DSIH_TEXM3x2DEPTH */ shader_glsl_texm3x2depth, - /* WINED3DSIH_TEXM3x2PAD */ shader_glsl_texm3x2pad, - /* WINED3DSIH_TEXM3x2TEX */ shader_glsl_texm3x2tex, - /* WINED3DSIH_TEXM3x3 */ shader_glsl_texm3x3, - /* WINED3DSIH_TEXM3x3DIFF */ NULL, - /* WINED3DSIH_TEXM3x3PAD */ shader_glsl_texm3x3pad, - /* WINED3DSIH_TEXM3x3SPEC */ shader_glsl_texm3x3spec, - /* WINED3DSIH_TEXM3x3TEX */ shader_glsl_texm3x3tex, - /* WINED3DSIH_TEXM3x3VSPEC */ shader_glsl_texm3x3vspec, - /* WINED3DSIH_TEXREG2AR */ shader_glsl_texreg2ar, - /* WINED3DSIH_TEXREG2GB */ shader_glsl_texreg2gb, - /* WINED3DSIH_TEXREG2RGB */ shader_glsl_texreg2rgb, - /* WINED3DSIH_UDIV */ shader_glsl_udiv, - /* WINED3DSIH_UGE */ shader_glsl_relop, - /* WINED3DSIH_USHR */ shader_glsl_binop, - /* WINED3DSIH_UTOF */ shader_glsl_to_float, - /* WINED3DSIH_XOR */ shader_glsl_binop, + /* WINED3DSIH_ABS */ shader_glsl_map2gl, + /* WINED3DSIH_ADD */ shader_glsl_binop, + /* WINED3DSIH_AND */ shader_glsl_binop, + /* WINED3DSIH_BEM */ shader_glsl_bem, + /* WINED3DSIH_BREAK */ shader_glsl_break, + /* WINED3DSIH_BREAKC */ shader_glsl_breakc, + /* WINED3DSIH_BREAKP */ shader_glsl_breakp, + /* WINED3DSIH_CALL */ shader_glsl_call, + /* WINED3DSIH_CALLNZ */ shader_glsl_callnz, + /* WINED3DSIH_CMP */ shader_glsl_conditional_move, + /* WINED3DSIH_CND */ shader_glsl_cnd, + /* WINED3DSIH_CRS */ shader_glsl_cross, + /* WINED3DSIH_CUT */ shader_glsl_cut, + /* WINED3DSIH_DCL */ shader_glsl_nop, + /* WINED3DSIH_DCL_CONSTANT_BUFFER */ shader_glsl_nop, + /* WINED3DSIH_DCL_GLOBAL_FLAGS */ shader_glsl_nop, + /* WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER */ NULL, + /* WINED3DSIH_DCL_INPUT */ shader_glsl_nop, + /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_glsl_nop, + /* WINED3DSIH_DCL_INPUT_PS */ NULL, + /* WINED3DSIH_DCL_INPUT_PS_SGV */ NULL, + /* WINED3DSIH_DCL_INPUT_PS_SIV */ NULL, + /* WINED3DSIH_DCL_INPUT_SGV */ shader_glsl_nop, + /* WINED3DSIH_DCL_INPUT_SIV */ shader_glsl_nop, + /* WINED3DSIH_DCL_OUTPUT */ shader_glsl_nop, + /* WINED3DSIH_DCL_OUTPUT_SIV */ shader_glsl_nop, + /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ shader_glsl_nop, + /* WINED3DSIH_DCL_SAMPLER */ NULL, + /* WINED3DSIH_DCL_TEMPS */ shader_glsl_nop, + /* WINED3DSIH_DCL_VERTICES_OUT */ shader_glsl_nop, + /* WINED3DSIH_DEF */ shader_glsl_nop, + /* WINED3DSIH_DEFB */ shader_glsl_nop, + /* WINED3DSIH_DEFI */ shader_glsl_nop, + /* WINED3DSIH_DIV */ shader_glsl_binop, + /* WINED3DSIH_DP2 */ shader_glsl_dot, + /* WINED3DSIH_DP2ADD */ shader_glsl_dp2add, + /* WINED3DSIH_DP3 */ shader_glsl_dot, + /* WINED3DSIH_DP4 */ shader_glsl_dot, + /* WINED3DSIH_DST */ shader_glsl_dst, + /* WINED3DSIH_DSX */ shader_glsl_map2gl, + /* WINED3DSIH_DSY */ shader_glsl_map2gl, + /* WINED3DSIH_ELSE */ shader_glsl_else, + /* WINED3DSIH_EMIT */ shader_glsl_emit, + /* WINED3DSIH_ENDIF */ shader_glsl_end, + /* WINED3DSIH_ENDLOOP */ shader_glsl_end, + /* WINED3DSIH_ENDREP */ shader_glsl_end, + /* WINED3DSIH_EQ */ shader_glsl_relop, + /* WINED3DSIH_EXP */ shader_glsl_scalar_op, + /* WINED3DSIH_EXPP */ shader_glsl_expp, + /* WINED3DSIH_FRC */ shader_glsl_map2gl, + /* WINED3DSIH_FTOI */ shader_glsl_to_int, + /* WINED3DSIH_FTOU */ shader_glsl_to_uint, + /* WINED3DSIH_GE */ shader_glsl_relop, + /* WINED3DSIH_IADD */ shader_glsl_binop, + /* WINED3DSIH_IEQ */ shader_glsl_relop, + /* WINED3DSIH_IF */ shader_glsl_if, + /* WINED3DSIH_IFC */ shader_glsl_ifc, + /* WINED3DSIH_IGE */ shader_glsl_relop, + /* WINED3DSIH_ILT */ shader_glsl_relop, + /* WINED3DSIH_IMAD */ shader_glsl_mad, + /* WINED3DSIH_IMAX */ shader_glsl_map2gl, + /* WINED3DSIH_IMIN */ shader_glsl_map2gl, + /* WINED3DSIH_IMUL */ shader_glsl_imul, + /* WINED3DSIH_INE */ shader_glsl_relop, + /* WINED3DSIH_INEG */ shader_glsl_unary_op, + /* WINED3DSIH_ISHL */ shader_glsl_binop, + /* WINED3DSIH_ITOF */ shader_glsl_to_float, + /* WINED3DSIH_LABEL */ shader_glsl_label, + /* WINED3DSIH_LD */ shader_glsl_ld, + /* WINED3DSIH_LIT */ shader_glsl_lit, + /* WINED3DSIH_LOG */ shader_glsl_scalar_op, + /* WINED3DSIH_LOGP */ shader_glsl_scalar_op, + /* WINED3DSIH_LOOP */ shader_glsl_loop, + /* WINED3DSIH_LRP */ shader_glsl_lrp, + /* WINED3DSIH_LT */ shader_glsl_relop, + /* WINED3DSIH_M3x2 */ shader_glsl_mnxn, + /* WINED3DSIH_M3x3 */ shader_glsl_mnxn, + /* WINED3DSIH_M3x4 */ shader_glsl_mnxn, + /* WINED3DSIH_M4x3 */ shader_glsl_mnxn, + /* WINED3DSIH_M4x4 */ shader_glsl_mnxn, + /* WINED3DSIH_MAD */ shader_glsl_mad, + /* WINED3DSIH_MAX */ shader_glsl_map2gl, + /* WINED3DSIH_MIN */ shader_glsl_map2gl, + /* WINED3DSIH_MOV */ shader_glsl_mov, + /* WINED3DSIH_MOVA */ shader_glsl_mov, + /* WINED3DSIH_MOVC */ shader_glsl_conditional_move, + /* WINED3DSIH_MUL */ shader_glsl_binop, + /* WINED3DSIH_NE */ shader_glsl_relop, + /* WINED3DSIH_NOP */ shader_glsl_nop, + /* WINED3DSIH_NOT */ shader_glsl_unary_op, + /* WINED3DSIH_NRM */ shader_glsl_nrm, + /* WINED3DSIH_OR */ shader_glsl_binop, + /* WINED3DSIH_PHASE */ shader_glsl_nop, + /* WINED3DSIH_POW */ shader_glsl_pow, + /* WINED3DSIH_RCP */ shader_glsl_scalar_op, + /* WINED3DSIH_REP */ shader_glsl_rep, + /* WINED3DSIH_RESINFO */ shader_glsl_resinfo, + /* WINED3DSIH_RET */ shader_glsl_ret, + /* WINED3DSIH_ROUND_NI */ shader_glsl_map2gl, + /* WINED3DSIH_ROUND_PI */ shader_glsl_map2gl, + /* WINED3DSIH_ROUND_Z */ shader_glsl_map2gl, + /* WINED3DSIH_RSQ */ shader_glsl_scalar_op, + /* WINED3DSIH_SAMPLE */ shader_glsl_sample, + /* WINED3DSIH_SAMPLE_B */ shader_glsl_sample, + /* WINED3DSIH_SAMPLE_C */ NULL, + /* WINED3DSIH_SAMPLE_C_LZ */ NULL, + /* WINED3DSIH_SAMPLE_GRAD */ shader_glsl_sample, + /* WINED3DSIH_SAMPLE_LOD */ shader_glsl_sample, + /* WINED3DSIH_SETP */ NULL, + /* WINED3DSIH_SGE */ shader_glsl_compare, + /* WINED3DSIH_SGN */ shader_glsl_sgn, + /* WINED3DSIH_SINCOS */ shader_glsl_sincos, + /* WINED3DSIH_SLT */ shader_glsl_compare, + /* WINED3DSIH_SQRT */ shader_glsl_map2gl, + /* WINED3DSIH_SUB */ shader_glsl_binop, + /* WINED3DSIH_TEX */ shader_glsl_tex, + /* WINED3DSIH_TEXBEM */ shader_glsl_texbem, + /* WINED3DSIH_TEXBEML */ shader_glsl_texbem, + /* WINED3DSIH_TEXCOORD */ shader_glsl_texcoord, + /* WINED3DSIH_TEXDEPTH */ shader_glsl_texdepth, + /* WINED3DSIH_TEXDP3 */ shader_glsl_texdp3, + /* WINED3DSIH_TEXDP3TEX */ shader_glsl_texdp3tex, + /* WINED3DSIH_TEXKILL */ shader_glsl_texkill, + /* WINED3DSIH_TEXLDD */ shader_glsl_texldd, + /* WINED3DSIH_TEXLDL */ shader_glsl_texldl, + /* WINED3DSIH_TEXM3x2DEPTH */ shader_glsl_texm3x2depth, + /* WINED3DSIH_TEXM3x2PAD */ shader_glsl_texm3x2pad, + /* WINED3DSIH_TEXM3x2TEX */ shader_glsl_texm3x2tex, + /* WINED3DSIH_TEXM3x3 */ shader_glsl_texm3x3, + /* WINED3DSIH_TEXM3x3DIFF */ NULL, + /* WINED3DSIH_TEXM3x3PAD */ shader_glsl_texm3x3pad, + /* WINED3DSIH_TEXM3x3SPEC */ shader_glsl_texm3x3spec, + /* WINED3DSIH_TEXM3x3TEX */ shader_glsl_texm3x3tex, + /* WINED3DSIH_TEXM3x3VSPEC */ shader_glsl_texm3x3vspec, + /* WINED3DSIH_TEXREG2AR */ shader_glsl_texreg2ar, + /* WINED3DSIH_TEXREG2GB */ shader_glsl_texreg2gb, + /* WINED3DSIH_TEXREG2RGB */ shader_glsl_texreg2rgb, + /* WINED3DSIH_UDIV */ shader_glsl_udiv, + /* WINED3DSIH_UGE */ shader_glsl_relop, + /* WINED3DSIH_USHR */ shader_glsl_binop, + /* WINED3DSIH_UTOF */ shader_glsl_to_float, + /* WINED3DSIH_XOR */ shader_glsl_binop, }; static void shader_glsl_handle_instruction(const struct wined3d_shader_instruction *ins) { @@ -7941,7 +8169,7 @@ /* Unhandled opcode */ if (!hw_fct) { - FIXME("Backend can't handle opcode %#x\n", ins->handler_idx); + FIXME("Backend can't handle opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx)); return; } hw_fct(ins); @@ -8068,6 +8296,7 @@ const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; + BOOL normal = !!(context->stream_info.use_map & (1u << WINED3D_FFP_NORMAL)); BOOL transformed = context->stream_info.position_transformed; BOOL wasrhw = context->last_was_rhw; unsigned int i; @@ -8093,7 +8322,8 @@ /* Because of settings->texcoords, we have to regenerate the vertex * shader on a vdecl change if there aren't enough varyings to just * always output all the texture coordinates. */ - if (gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(gl_info)) + if (gl_info->limits.glsl_varyings < wined3d_max_compat_varyings(gl_info) + || normal != context->last_was_normal) context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX; if (use_ps(state) @@ -8112,6 +8342,7 @@ } context->last_was_vshader = use_vs(state); + context->last_was_normal = normal; } static void glsl_vertex_pipe_vs(struct wined3d_context *context, diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/resource.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/resource.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/resource.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/resource.c 2016-02-08 19:32:34.000000000 +0000 @@ -57,6 +57,7 @@ | WINED3DUSAGE_AUTOGENMIPMAP | WINED3DUSAGE_STATICDECL | WINED3DUSAGE_OVERLAY + | WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; /* WINED3DUSAGE_WRITEONLY is supposed to result in write-combined mappings @@ -78,84 +79,93 @@ void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops) { - const struct wined3d *d3d = device->wined3d; + enum wined3d_gl_resource_type base_type = WINED3D_GL_RES_TYPE_COUNT; + enum wined3d_gl_resource_type gl_type = WINED3D_GL_RES_TYPE_COUNT; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - static const enum wined3d_gl_resource_type gl_resource_types[][4] = + BOOL tex_2d_ok = FALSE; + unsigned int i; + + static const struct + { + enum wined3d_resource_type type; + DWORD cube_usage; + enum wined3d_gl_resource_type gl_type; + } + resource_types[] = { - /* 0 */ {WINED3D_GL_RES_TYPE_COUNT}, - /* WINED3D_RTYPE_SURFACE */ {WINED3D_GL_RES_TYPE_COUNT}, - /* WINED3D_RTYPE_VOLUME */ {WINED3D_GL_RES_TYPE_COUNT}, - /* WINED3D_RTYPE_TEXTURE */ {WINED3D_GL_RES_TYPE_TEX_2D, - WINED3D_GL_RES_TYPE_TEX_RECT, WINED3D_GL_RES_TYPE_RB, WINED3D_GL_RES_TYPE_COUNT}, - /* WINED3D_RTYPE_VOLUME_TEXTURE */ {WINED3D_GL_RES_TYPE_TEX_3D, WINED3D_GL_RES_TYPE_COUNT}, - /* WINED3D_RTYPE_CUBE_TEXTURE */ {WINED3D_GL_RES_TYPE_TEX_CUBE, WINED3D_GL_RES_TYPE_COUNT}, - /* WINED3D_RTYPE_BUFFER */ {WINED3D_GL_RES_TYPE_BUFFER, WINED3D_GL_RES_TYPE_COUNT}, + {WINED3D_RTYPE_BUFFER, 0, WINED3D_GL_RES_TYPE_BUFFER}, + {WINED3D_RTYPE_TEXTURE_2D, 0, WINED3D_GL_RES_TYPE_TEX_2D}, + {WINED3D_RTYPE_TEXTURE_2D, 0, WINED3D_GL_RES_TYPE_TEX_RECT}, + {WINED3D_RTYPE_TEXTURE_2D, 0, WINED3D_GL_RES_TYPE_RB}, + {WINED3D_RTYPE_TEXTURE_2D, WINED3DUSAGE_LEGACY_CUBEMAP, WINED3D_GL_RES_TYPE_TEX_CUBE}, + {WINED3D_RTYPE_TEXTURE_3D, 0, WINED3D_GL_RES_TYPE_TEX_3D}, }; - enum wined3d_gl_resource_type gl_type = WINED3D_GL_RES_TYPE_COUNT; - enum wined3d_gl_resource_type base_type = gl_resource_types[type][0]; resource_check_usage(usage); - if (base_type != WINED3D_GL_RES_TYPE_COUNT) + for (i = 0; i < ARRAY_SIZE(resource_types); ++i) { - unsigned int i; - BOOL tex_2d_ok = FALSE; + if (resource_types[i].type != type + || resource_types[i].cube_usage != (usage & WINED3DUSAGE_LEGACY_CUBEMAP)) + continue; + + gl_type = resource_types[i].gl_type; + if (base_type == WINED3D_GL_RES_TYPE_COUNT) + base_type = gl_type; + + if ((usage & WINED3DUSAGE_RENDERTARGET) && !(format->flags[gl_type] & WINED3DFMT_FLAG_RENDERTARGET)) + { + WARN("Format %s cannot be used for render targets.\n", debug_d3dformat(format->id)); + continue; + } + if ((usage & WINED3DUSAGE_DEPTHSTENCIL) + && !(format->flags[gl_type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) + { + WARN("Format %s cannot be used for depth/stencil buffers.\n", debug_d3dformat(format->id)); + continue; + } + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO + && usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL) + && !(format->flags[gl_type] & WINED3DFMT_FLAG_FBO_ATTACHABLE)) + { + WARN("Render target or depth stencil is not FBO attachable.\n"); + continue; + } + if ((usage & WINED3DUSAGE_TEXTURE) && !(format->flags[gl_type] & WINED3DFMT_FLAG_TEXTURE)) + { + WARN("Format %s cannot be used for texturing.\n", debug_d3dformat(format->id)); + continue; + } + if (((width & (width - 1)) || (height & (height - 1))) + && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] + && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] + && gl_type == WINED3D_GL_RES_TYPE_TEX_2D) + { + TRACE("Skipping 2D texture type to try texture rectangle.\n"); + tex_2d_ok = TRUE; + continue; + } + break; + } - for (i = 0; (gl_type = gl_resource_types[type][i]) != WINED3D_GL_RES_TYPE_COUNT; i++) + if (base_type != WINED3D_GL_RES_TYPE_COUNT && i == ARRAY_SIZE(resource_types)) + { + if (tex_2d_ok) + { + /* Non power of 2 texture and rectangle textures or renderbuffers do not work. + * Use 2D textures, the texture code will pad to a power of 2 size. */ + gl_type = WINED3D_GL_RES_TYPE_TEX_2D; + } + else if (pool == WINED3D_POOL_SCRATCH) { - if ((usage & WINED3DUSAGE_RENDERTARGET) && !(format->flags[gl_type] & WINED3DFMT_FLAG_RENDERTARGET)) - { - WARN("Format %s cannot be used for render targets.\n", debug_d3dformat(format->id)); - continue; - } - if ((usage & WINED3DUSAGE_DEPTHSTENCIL) && - !(format->flags[gl_type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) - { - WARN("Format %s cannot be used for depth/stencil buffers.\n", debug_d3dformat(format->id)); - continue; - } - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO - && usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL) - && !(format->flags[gl_type] & WINED3DFMT_FLAG_FBO_ATTACHABLE)) - { - WARN("Render target or depth stencil is not FBO attachable.\n"); - continue; - } - if ((usage & WINED3DUSAGE_TEXTURE) && !(format->flags[gl_type] & WINED3DFMT_FLAG_TEXTURE)) - { - WARN("Format %s cannot be used for texturing.\n", debug_d3dformat(format->id)); - continue; - } - if (((width & (width - 1)) || (height & (height - 1))) - && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] - && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] - && gl_type == WINED3D_GL_RES_TYPE_TEX_2D) - { - TRACE("Skipping 2D texture type to try texture rectangle.\n"); - tex_2d_ok = TRUE; - continue; - } - break; - } - - if (gl_type == WINED3D_GL_RES_TYPE_COUNT) - { - if (tex_2d_ok) - { - /* Non power of 2 texture and rectangle textures or renderbuffers do not work. - * Use 2D textures, the texture code will pad to a power of 2 size. */ - gl_type = WINED3D_GL_RES_TYPE_TEX_2D; - } - else if (pool == WINED3D_POOL_SCRATCH) - { - /* Needed for proper format information. */ - gl_type = base_type; - } - else - { - WARN("Did not find a suitable GL resource type, resource type, d3d type %u.\n", type); - return WINED3DERR_INVALIDCALL; - } + /* Needed for proper format information. */ + gl_type = base_type; + } + else + { + WARN("Did not find a suitable GL resource type for resource type %s.\n", + debug_d3dresourcetype(type)); + return WINED3DERR_INVALIDCALL; } } @@ -207,7 +217,7 @@ } /* Check that we have enough video ram left */ - if (pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING) + if (pool == WINED3D_POOL_DEFAULT && device->wined3d->flags & WINED3D_VIDMEM_ACCOUNTING) { if (size > wined3d_device_get_available_texture_mem(device)) { @@ -298,8 +308,8 @@ HRESULT CDECL wined3d_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) { - TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %p, flags %#x.\n", - resource, sub_resource_idx, map_desc, box, flags); + TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %s, flags %#x.\n", + resource, sub_resource_idx, map_desc, debug_box(box), flags); return resource->resource_ops->resource_sub_resource_map(resource, sub_resource_idx, map_desc, box, flags); } @@ -402,8 +412,8 @@ { struct wined3d_swapchain *swapchain; - /* Only texture resources can be onscreen. */ - if (resource->type != WINED3D_RTYPE_TEXTURE) + /* Only 2D texture resources can be onscreen. */ + if (resource->type != WINED3D_RTYPE_TEXTURE_2D) return TRUE; /* Not on a swapchain - must be offscreen */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/shader.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/shader.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/shader.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/shader.c 2016-02-08 19:32:34.000000000 +0000 @@ -40,122 +40,148 @@ static const char * const shader_opcode_names[] = { - /* WINED3DSIH_ABS */ "abs", - /* WINED3DSIH_ADD */ "add", - /* WINED3DSIH_AND */ "and", - /* WINED3DSIH_BEM */ "bem", - /* WINED3DSIH_BREAK */ "break", - /* WINED3DSIH_BREAKC */ "breakc", - /* WINED3DSIH_BREAKP */ "breakp", - /* WINED3DSIH_CALL */ "call", - /* WINED3DSIH_CALLNZ */ "callnz", - /* WINED3DSIH_CMP */ "cmp", - /* WINED3DSIH_CND */ "cnd", - /* WINED3DSIH_CRS */ "crs", - /* WINED3DSIH_CUT */ "cut", - /* WINED3DSIH_DCL */ "dcl", - /* WINED3DSIH_DCL_CONSTANT_BUFFER */ "dcl_constantBuffer", - /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ "dcl_inputPrimitive", - /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ "dcl_outputTopology", - /* WINED3DSIH_DCL_VERTICES_OUT */ "dcl_maxOutputVertexCount", - /* WINED3DSIH_DEF */ "def", - /* WINED3DSIH_DEFB */ "defb", - /* WINED3DSIH_DEFI */ "defi", - /* WINED3DSIH_DIV */ "div", - /* WINED3DSIH_DP2 */ "dp2", - /* WINED3DSIH_DP2ADD */ "dp2add", - /* WINED3DSIH_DP3 */ "dp3", - /* WINED3DSIH_DP4 */ "dp4", - /* WINED3DSIH_DST */ "dst", - /* WINED3DSIH_DSX */ "dsx", - /* WINED3DSIH_DSY */ "dsy", - /* WINED3DSIH_ELSE */ "else", - /* WINED3DSIH_EMIT */ "emit", - /* WINED3DSIH_ENDIF */ "endif", - /* WINED3DSIH_ENDLOOP */ "endloop", - /* WINED3DSIH_ENDREP */ "endrep", - /* WINED3DSIH_EQ */ "eq", - /* WINED3DSIH_EXP */ "exp", - /* WINED3DSIH_EXPP */ "expp", - /* WINED3DSIH_FRC */ "frc", - /* WINED3DSIH_FTOI */ "ftoi", - /* WINED3DSIH_GE */ "ge", - /* WINED3DSIH_IADD */ "iadd", - /* WINED3DSIH_IEQ */ "ieq", - /* WINED3DSIH_IF */ "if", - /* WINED3DSIH_IFC */ "ifc", - /* WINED3DSIH_IGE */ "ige", - /* WINED3DSIH_IMUL */ "imul", - /* WINED3DSIH_ISHL */ "ishl", - /* WINED3DSIH_ITOF */ "itof", - /* WINED3DSIH_LABEL */ "label", - /* WINED3DSIH_LD */ "ld", - /* WINED3DSIH_LIT */ "lit", - /* WINED3DSIH_LOG */ "log", - /* WINED3DSIH_LOGP */ "logp", - /* WINED3DSIH_LOOP */ "loop", - /* WINED3DSIH_LRP */ "lrp", - /* WINED3DSIH_LT */ "lt", - /* WINED3DSIH_M3x2 */ "m3x2", - /* WINED3DSIH_M3x3 */ "m3x3", - /* WINED3DSIH_M3x4 */ "m3x4", - /* WINED3DSIH_M4x3 */ "m4x3", - /* WINED3DSIH_M4x4 */ "m4x4", - /* WINED3DSIH_MAD */ "mad", - /* WINED3DSIH_MAX */ "max", - /* WINED3DSIH_MIN */ "min", - /* WINED3DSIH_MOV */ "mov", - /* WINED3DSIH_MOVA */ "mova", - /* WINED3DSIH_MOVC */ "movc", - /* WINED3DSIH_MUL */ "mul", - /* WINED3DSIH_NE */ "ne", - /* WINED3DSIH_NOP */ "nop", - /* WINED3DSIH_NRM */ "nrm", - /* WINED3DSIH_OR */ "or", - /* WINED3DSIH_PHASE */ "phase", - /* WINED3DSIH_POW */ "pow", - /* WINED3DSIH_RCP */ "rcp", - /* WINED3DSIH_REP */ "rep", - /* WINED3DSIH_RET */ "ret", - /* WINED3DSIH_ROUND_NI */ "round_ni", - /* WINED3DSIH_RSQ */ "rsq", - /* WINED3DSIH_SAMPLE */ "sample", - /* WINED3DSIH_SAMPLE_GRAD */ "sample_d", - /* WINED3DSIH_SAMPLE_LOD */ "sample_l", - /* WINED3DSIH_SETP */ "setp", - /* WINED3DSIH_SGE */ "sge", - /* WINED3DSIH_SGN */ "sgn", - /* WINED3DSIH_SINCOS */ "sincos", - /* WINED3DSIH_SLT */ "slt", - /* WINED3DSIH_SQRT */ "sqrt", - /* WINED3DSIH_SUB */ "sub", - /* WINED3DSIH_TEX */ "texld", - /* WINED3DSIH_TEXBEM */ "texbem", - /* WINED3DSIH_TEXBEML */ "texbeml", - /* WINED3DSIH_TEXCOORD */ "texcrd", - /* WINED3DSIH_TEXDEPTH */ "texdepth", - /* WINED3DSIH_TEXDP3 */ "texdp3", - /* WINED3DSIH_TEXDP3TEX */ "texdp3tex", - /* WINED3DSIH_TEXKILL */ "texkill", - /* WINED3DSIH_TEXLDD */ "texldd", - /* WINED3DSIH_TEXLDL */ "texldl", - /* WINED3DSIH_TEXM3x2DEPTH */ "texm3x2depth", - /* WINED3DSIH_TEXM3x2PAD */ "texm3x2pad", - /* WINED3DSIH_TEXM3x2TEX */ "texm3x2tex", - /* WINED3DSIH_TEXM3x3 */ "texm3x3", - /* WINED3DSIH_TEXM3x3DIFF */ "texm3x3diff", - /* WINED3DSIH_TEXM3x3PAD */ "texm3x3pad", - /* WINED3DSIH_TEXM3x3SPEC */ "texm3x3spec", - /* WINED3DSIH_TEXM3x3TEX */ "texm3x3tex", - /* WINED3DSIH_TEXM3x3VSPEC */ "texm3x3vspec", - /* WINED3DSIH_TEXREG2AR */ "texreg2ar", - /* WINED3DSIH_TEXREG2GB */ "texreg2gb", - /* WINED3DSIH_TEXREG2RGB */ "texreg2rgb", - /* WINED3DSIH_UDIV */ "udiv", - /* WINED3DSIH_UGE */ "uge", - /* WINED3DSIH_USHR */ "ushr", - /* WINED3DSIH_UTOF */ "utof", - /* WINED3DSIH_XOR */ "xor", + /* WINED3DSIH_ABS */ "abs", + /* WINED3DSIH_ADD */ "add", + /* WINED3DSIH_AND */ "and", + /* WINED3DSIH_BEM */ "bem", + /* WINED3DSIH_BREAK */ "break", + /* WINED3DSIH_BREAKC */ "breakc", + /* WINED3DSIH_BREAKP */ "breakp", + /* WINED3DSIH_CALL */ "call", + /* WINED3DSIH_CALLNZ */ "callnz", + /* WINED3DSIH_CMP */ "cmp", + /* WINED3DSIH_CND */ "cnd", + /* WINED3DSIH_CRS */ "crs", + /* WINED3DSIH_CUT */ "cut", + /* WINED3DSIH_DCL */ "dcl", + /* WINED3DSIH_DCL_CONSTANT_BUFFER */ "dcl_constantBuffer", + /* WINED3DSIH_DCL_GLOBAL_FLAGS */ "dcl_globalFlags", + /* WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER */ "dcl_immediateConstantBuffer", + /* WINED3DSIH_DCL_INPUT */ "dcl_input", + /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ "dcl_inputPrimitive", + /* WINED3DSIH_DCL_INPUT_PS */ "dcl_input_ps", + /* WINED3DSIH_DCL_INPUT_PS_SGV */ "dcl_input_ps_sgv", + /* WINED3DSIH_DCL_INPUT_PS_SIV */ "dcl_input_ps_siv", + /* WINED3DSIH_DCL_INPUT_SGV */ "dcl_input_sgv", + /* WINED3DSIH_DCL_INPUT_SIV */ "dcl_input_siv", + /* WINED3DSIH_DCL_OUTPUT */ "dcl_output", + /* WINED3DSIH_DCL_OUTPUT_SIV */ "dcl_output_siv", + /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ "dcl_outputTopology", + /* WINED3DSIH_DCL_SAMPLER */ "dcl_sampler", + /* WINED3DSIH_DCL_TEMPS */ "dcl_temps", + /* WINED3DSIH_DCL_VERTICES_OUT */ "dcl_maxOutputVertexCount", + /* WINED3DSIH_DEF */ "def", + /* WINED3DSIH_DEFB */ "defb", + /* WINED3DSIH_DEFI */ "defi", + /* WINED3DSIH_DIV */ "div", + /* WINED3DSIH_DP2 */ "dp2", + /* WINED3DSIH_DP2ADD */ "dp2add", + /* WINED3DSIH_DP3 */ "dp3", + /* WINED3DSIH_DP4 */ "dp4", + /* WINED3DSIH_DST */ "dst", + /* WINED3DSIH_DSX */ "dsx", + /* WINED3DSIH_DSY */ "dsy", + /* WINED3DSIH_ELSE */ "else", + /* WINED3DSIH_EMIT */ "emit", + /* WINED3DSIH_ENDIF */ "endif", + /* WINED3DSIH_ENDLOOP */ "endloop", + /* WINED3DSIH_ENDREP */ "endrep", + /* WINED3DSIH_EQ */ "eq", + /* WINED3DSIH_EXP */ "exp", + /* WINED3DSIH_EXPP */ "expp", + /* WINED3DSIH_FRC */ "frc", + /* WINED3DSIH_FTOI */ "ftoi", + /* WINED3DSIH_FTOU */ "ftou", + /* WINED3DSIH_GE */ "ge", + /* WINED3DSIH_IADD */ "iadd", + /* WINED3DSIH_IEQ */ "ieq", + /* WINED3DSIH_IF */ "if", + /* WINED3DSIH_IFC */ "ifc", + /* WINED3DSIH_IGE */ "ige", + /* WINED3DSIH_ILT */ "ilt", + /* WINED3DSIH_IMAD */ "imad", + /* WINED3DSIH_IMAX */ "imax", + /* WINED3DSIH_IMIN */ "imin", + /* WINED3DSIH_IMUL */ "imul", + /* WINED3DSIH_INE */ "ine", + /* WINED3DSIH_INEG */ "ineg", + /* WINED3DSIH_ISHL */ "ishl", + /* WINED3DSIH_ITOF */ "itof", + /* WINED3DSIH_LABEL */ "label", + /* WINED3DSIH_LD */ "ld", + /* WINED3DSIH_LIT */ "lit", + /* WINED3DSIH_LOG */ "log", + /* WINED3DSIH_LOGP */ "logp", + /* WINED3DSIH_LOOP */ "loop", + /* WINED3DSIH_LRP */ "lrp", + /* WINED3DSIH_LT */ "lt", + /* WINED3DSIH_M3x2 */ "m3x2", + /* WINED3DSIH_M3x3 */ "m3x3", + /* WINED3DSIH_M3x4 */ "m3x4", + /* WINED3DSIH_M4x3 */ "m4x3", + /* WINED3DSIH_M4x4 */ "m4x4", + /* WINED3DSIH_MAD */ "mad", + /* WINED3DSIH_MAX */ "max", + /* WINED3DSIH_MIN */ "min", + /* WINED3DSIH_MOV */ "mov", + /* WINED3DSIH_MOVA */ "mova", + /* WINED3DSIH_MOVC */ "movc", + /* WINED3DSIH_MUL */ "mul", + /* WINED3DSIH_NE */ "ne", + /* WINED3DSIH_NOP */ "nop", + /* WINED3DSIH_NOT */ "not", + /* WINED3DSIH_NRM */ "nrm", + /* WINED3DSIH_OR */ "or", + /* WINED3DSIH_PHASE */ "phase", + /* WINED3DSIH_POW */ "pow", + /* WINED3DSIH_RCP */ "rcp", + /* WINED3DSIH_REP */ "rep", + /* WINED3DSIH_RESINFO */ "resinfo", + /* WINED3DSIH_RET */ "ret", + /* WINED3DSIH_ROUND_NI */ "round_ni", + /* WINED3DSIH_ROUND_PI */ "round_pi", + /* WINED3DSIH_ROUND_Z */ "round_z", + /* WINED3DSIH_RSQ */ "rsq", + /* WINED3DSIH_SAMPLE */ "sample", + /* WINED3DSIH_SAMPLE_B */ "sample_b", + /* WINED3DSIH_SAMPLE_C */ "sample_c", + /* WINED3DSIH_SAMPLE_C_LZ */ "sample_c_lz", + /* WINED3DSIH_SAMPLE_GRAD */ "sample_d", + /* WINED3DSIH_SAMPLE_LOD */ "sample_l", + /* WINED3DSIH_SETP */ "setp", + /* WINED3DSIH_SGE */ "sge", + /* WINED3DSIH_SGN */ "sgn", + /* WINED3DSIH_SINCOS */ "sincos", + /* WINED3DSIH_SLT */ "slt", + /* WINED3DSIH_SQRT */ "sqrt", + /* WINED3DSIH_SUB */ "sub", + /* WINED3DSIH_TEX */ "texld", + /* WINED3DSIH_TEXBEM */ "texbem", + /* WINED3DSIH_TEXBEML */ "texbeml", + /* WINED3DSIH_TEXCOORD */ "texcrd", + /* WINED3DSIH_TEXDEPTH */ "texdepth", + /* WINED3DSIH_TEXDP3 */ "texdp3", + /* WINED3DSIH_TEXDP3TEX */ "texdp3tex", + /* WINED3DSIH_TEXKILL */ "texkill", + /* WINED3DSIH_TEXLDD */ "texldd", + /* WINED3DSIH_TEXLDL */ "texldl", + /* WINED3DSIH_TEXM3x2DEPTH */ "texm3x2depth", + /* WINED3DSIH_TEXM3x2PAD */ "texm3x2pad", + /* WINED3DSIH_TEXM3x2TEX */ "texm3x2tex", + /* WINED3DSIH_TEXM3x3 */ "texm3x3", + /* WINED3DSIH_TEXM3x3DIFF */ "texm3x3diff", + /* WINED3DSIH_TEXM3x3PAD */ "texm3x3pad", + /* WINED3DSIH_TEXM3x3SPEC */ "texm3x3spec", + /* WINED3DSIH_TEXM3x3TEX */ "texm3x3tex", + /* WINED3DSIH_TEXM3x3VSPEC */ "texm3x3vspec", + /* WINED3DSIH_TEXREG2AR */ "texreg2ar", + /* WINED3DSIH_TEXREG2GB */ "texreg2gb", + /* WINED3DSIH_TEXREG2RGB */ "texreg2rgb", + /* WINED3DSIH_UDIV */ "udiv", + /* WINED3DSIH_UGE */ "uge", + /* WINED3DSIH_USHR */ "ushr", + /* WINED3DSIH_UTOF */ "utof", + /* WINED3DSIH_XOR */ "xor", }; static const char * const semantic_names[] = @@ -176,6 +202,28 @@ /* WINED3D_DECL_USAGE_SAMPLE */ "SAMPLE", }; +static const struct +{ + enum wined3d_sysval_semantic sysval_semantic; + const char *sysval_name; +} +sysval_semantic_names[] = +{ + {WINED3D_SV_POSITION, "SV_Position"}, + {WINED3D_SV_INSTANCEID, "SV_InstanceID"}, + {WINED3D_SV_PRIMITIVEID, "SV_PrimitiveID"}, + {WINED3D_SV_ISFRONTFACE, "SV_IsFrontFace"}, + {WINED3D_SV_SAMPLEINDEX, "SV_SampleIndex"}, +}; + +const char *debug_d3dshaderinstructionhandler(enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx) +{ + if (handler_idx >= sizeof(shader_opcode_names) / sizeof(*shader_opcode_names)) + return wine_dbg_sprintf("UNRECOGNIZED(%#x)", handler_idx); + + return shader_opcode_names[handler_idx]; +} + static const char *shader_semantic_name_from_usage(enum wined3d_decl_usage usage) { if (usage >= sizeof(semantic_names) / sizeof(*semantic_names)) @@ -789,6 +837,12 @@ else reg_maps->cb_sizes[reg->idx[0].offset] = reg->idx[1].offset; } + else if (ins.handler_idx == WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER) + { + if (reg_maps->icb) + FIXME("Multiple immediate constant buffers.\n"); + reg_maps->icb = ins.declaration.icb; + } else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PRIMITIVE) { if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY) @@ -1052,12 +1106,20 @@ --cur_loop_depth; } else if (ins.handler_idx == WINED3DSIH_SAMPLE + || ins.handler_idx == WINED3DSIH_SAMPLE_B + || ins.handler_idx == WINED3DSIH_SAMPLE_C_LZ || ins.handler_idx == WINED3DSIH_SAMPLE_GRAD || ins.handler_idx == WINED3DSIH_SAMPLE_LOD) { shader_record_sample(reg_maps, ins.src[1].reg.idx[0].offset, ins.src[2].reg.idx[0].offset, reg_maps->sampler_map.count); } + else if (ins.handler_idx == WINED3DSIH_LD + || ins.handler_idx == WINED3DSIH_RESINFO) + { + shader_record_sample(reg_maps, ins.src[1].reg.idx[0].offset, + WINED3D_SAMPLER_DEFAULT, reg_maps->sampler_map.count); + } if (ins.predicate) if (!shader_record_register_usage(shader, reg_maps, &ins.predicate->reg, @@ -1114,7 +1176,7 @@ } else if (!input_signature->elements && reg_maps->input_registers) { - unsigned int count = count_bits(reg_maps->input_registers); + unsigned int count = wined3d_popcount(reg_maps->input_registers); struct wined3d_shader_signature_element *e; unsigned int i; @@ -1141,7 +1203,7 @@ } else if (reg_maps->output_registers) { - unsigned int count = count_bits(reg_maps->output_registers); + unsigned int count = wined3d_popcount(reg_maps->output_registers); struct wined3d_shader_signature_element *e; if (!(output_signature->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*output_signature->elements) * count))) @@ -1169,6 +1231,42 @@ return wined3d_log2i(map); } +static void shader_dump_global_flags(DWORD global_flags) +{ + if (global_flags & WINED3DSGF_REFACTORING_ALLOWED) + { + TRACE("refactoringAllowed"); + global_flags &= ~WINED3DSGF_REFACTORING_ALLOWED; + if (global_flags) + TRACE(" | "); + } + + if (global_flags & WINED3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS) + { + TRACE("enableRawAndStructuredBuffers"); + global_flags &= ~WINED3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS; + } + + if (global_flags) + TRACE("unknown_flags(%#x)", global_flags); +} + +static void shader_dump_sysval_semantic(enum wined3d_sysval_semantic semantic) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(sysval_semantic_names); ++i) + { + if (sysval_semantic_names[i].sysval_semantic == semantic) + { + TRACE("%s", sysval_semantic_names[i].sysval_name); + return; + } + } + + TRACE("unknown_sysval_semantic(%#x)", semantic); +} + static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semantic, const struct wined3d_shader_version *shader_version) { @@ -1429,6 +1527,10 @@ TRACE("cb"); break; + case WINED3DSPR_IMMCONSTBUFFER: + TRACE("icb"); + break; + case WINED3DSPR_PRIMID: TRACE("primID"); break; @@ -1731,6 +1833,37 @@ } } +static void shader_dump_interpolation_mode(enum wined3d_shader_interpolation_mode interpolation_mode) +{ + switch (interpolation_mode) + { + case WINED3DSIM_CONSTANT: + TRACE("constant"); + break; + case WINED3DSIM_LINEAR: + TRACE("linear"); + break; + case WINED3DSIM_LINEAR_CENTROID: + TRACE("linear centroid"); + break; + case WINED3DSIM_LINEAR_NOPERSPECTIVE: + TRACE("linear noperspective"); + break; + case WINED3DSIM_LINEAR_SAMPLE: + TRACE("linear sample"); + break; + case WINED3DSIM_LINEAR_NOPERSPECTIVE_CENTROID: + TRACE("linear noperspective centroid"); + break; + case WINED3DSIM_LINEAR_NOPERSPECTIVE_SAMPLE: + TRACE("linear noperspective sample"); + break; + default: + TRACE("", interpolation_mode); + break; + } +} + static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *byte_code) { struct wined3d_shader_version shader_version; @@ -1788,13 +1921,71 @@ shader_dump_src_param(&ins.declaration.src, &shader_version); TRACE(", %s", ins.flags & WINED3DSI_INDEXED_DYNAMIC ? "dynamicIndexed" : "immediateIndexed"); } + else if (ins.handler_idx == WINED3DSIH_DCL_GLOBAL_FLAGS) + { + TRACE("%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_global_flags(ins.flags); + } + else if (ins.handler_idx == WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER) + { + TRACE("%s {\n", shader_opcode_names[ins.handler_idx]); + for (i = 0; i < ins.declaration.icb->element_count / 4; ++i) + { + TRACE("{ 0x%08x, 0x%08x, 0x%08x, 0x%08x },\n", + ins.declaration.icb->data[4 * i + 0], + ins.declaration.icb->data[4 * i + 1], + ins.declaration.icb->data[4 * i + 2], + ins.declaration.icb->data[4 * i + 3]); + } + TRACE("}"); + } + else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PS) + { + TRACE("%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_interpolation_mode(ins.flags); + TRACE(" "); + shader_dump_dst_param(&ins.declaration.dst, &shader_version); + } + else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PS_SGV + || ins.handler_idx == WINED3DSIH_DCL_INPUT_SGV + || ins.handler_idx == WINED3DSIH_DCL_INPUT_SIV + || ins.handler_idx == WINED3DSIH_DCL_OUTPUT_SIV) + { + TRACE("%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_dst_param(&ins.declaration.register_semantic.reg, &shader_version); + TRACE(", "); + shader_dump_sysval_semantic(ins.declaration.register_semantic.sysval_semantic); + } + else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PS_SIV) + { + TRACE("%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_interpolation_mode(ins.flags); + TRACE(" "); + shader_dump_dst_param(&ins.declaration.register_semantic.reg, &shader_version); + TRACE(", "); + shader_dump_sysval_semantic(ins.declaration.register_semantic.sysval_semantic); + } + else if (ins.handler_idx == WINED3DSIH_DCL_INPUT + || ins.handler_idx == WINED3DSIH_DCL_OUTPUT) + { + TRACE("%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_dst_param(&ins.declaration.dst, &shader_version); + } else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PRIMITIVE || ins.handler_idx == WINED3DSIH_DCL_OUTPUT_TOPOLOGY) { TRACE("%s ", shader_opcode_names[ins.handler_idx]); shader_dump_primitive_type(ins.declaration.primitive_type); } - else if (ins.handler_idx == WINED3DSIH_DCL_VERTICES_OUT) + else if (ins.handler_idx == WINED3DSIH_DCL_SAMPLER) + { + TRACE("%s ", shader_opcode_names[ins.handler_idx]); + shader_dump_dst_param(&ins.declaration.dst, &shader_version); + if (ins.flags == WINED3DSI_SAMPLER_COMPARISON_MODE) + TRACE(", comparisonMode"); + } + else if (ins.handler_idx == WINED3DSIH_DCL_TEMPS + || ins.handler_idx == WINED3DSIH_DCL_VERTICES_OUT) { TRACE("%s %u", shader_opcode_names[ins.handler_idx], ins.declaration.count); } @@ -1853,6 +2044,16 @@ { TRACE("p"); } + else if (ins.handler_idx == WINED3DSIH_RESINFO + && ins.flags) + { + switch (ins.flags) + { + case WINED3DSI_RESINFO_RCP_FLOAT: TRACE("_rcpFloat"); break; + case WINED3DSI_RESINFO_UINT: TRACE("_uint"); break; + default: TRACE("_unrecognized(%#x)", ins.flags); + } + } for (i = 0; i < ins.dst_count; ++i) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/shader_sm1.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/shader_sm1.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/shader_sm1.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/shader_sm1.c 2016-02-08 19:32:34.000000000 +0000 @@ -30,73 +30,73 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); /* DCL usage masks */ -#define WINED3DSP_DCL_USAGE_SHIFT 0 -#define WINED3DSP_DCL_USAGE_MASK (0xfu << WINED3DSP_DCL_USAGE_SHIFT) -#define WINED3DSP_DCL_USAGEINDEX_SHIFT 16 -#define WINED3DSP_DCL_USAGEINDEX_MASK (0xfu << WINED3DSP_DCL_USAGEINDEX_SHIFT) +#define WINED3D_SM1_DCL_USAGE_SHIFT 0 +#define WINED3D_SM1_DCL_USAGE_MASK (0xfu << WINED3D_SM1_DCL_USAGE_SHIFT) +#define WINED3D_SM1_DCL_USAGE_INDEX_SHIFT 16 +#define WINED3D_SM1_DCL_USAGE_INDEX_MASK (0xfu << WINED3D_SM1_DCL_USAGE_INDEX_SHIFT) /* DCL sampler type */ #define WINED3D_SM1_RESOURCE_TYPE_SHIFT 27 #define WINED3D_SM1_RESOURCE_TYPE_MASK (0xfu << WINED3D_SM1_RESOURCE_TYPE_SHIFT) /* Opcode-related masks */ -#define WINED3DSI_OPCODE_MASK 0x0000ffff +#define WINED3D_SM1_OPCODE_MASK 0x0000ffff -#define WINED3D_OPCODESPECIFICCONTROL_SHIFT 16 -#define WINED3D_OPCODESPECIFICCONTROL_MASK (0xffu << WINED3D_OPCODESPECIFICCONTROL_SHIFT) +#define WINED3D_SM1_INSTRUCTION_FLAGS_SHIFT 16 +#define WINED3D_SM1_INSTRUCTION_FLAGS_MASK (0xffu << WINED3D_SM1_INSTRUCTION_FLAGS_SHIFT) -#define WINED3DSI_INSTLENGTH_SHIFT 24 -#define WINED3DSI_INSTLENGTH_MASK (0xfu << WINED3DSI_INSTLENGTH_SHIFT) +#define WINED3D_SM1_INSTRUCTION_LENGTH_SHIFT 24 +#define WINED3D_SM1_INSTRUCTION_LENGTH_MASK (0xfu << WINED3D_SM1_INSTRUCTION_LENGTH_SHIFT) -#define WINED3DSI_COISSUE (0x1u << 30) +#define WINED3D_SM1_COISSUE (0x1u << 30) -#define WINED3DSI_COMMENTSIZE_SHIFT 16 -#define WINED3DSI_COMMENTSIZE_MASK (0x7fffu << WINED3DSI_COMMENTSIZE_SHIFT) +#define WINED3D_SM1_COMMENT_SIZE_SHIFT 16 +#define WINED3D_SM1_COMMENT_SIZE_MASK (0x7fffu << WINED3D_SM1_COMMENT_SIZE_SHIFT) -#define WINED3DSHADER_INSTRUCTION_PREDICATED (0x1u << 28) +#define WINED3D_SM1_INSTRUCTION_PREDICATED (0x1u << 28) /* Register number mask */ -#define WINED3DSP_REGNUM_MASK 0x000007ff +#define WINED3D_SM1_REGISTER_NUMBER_MASK 0x000007ff /* Register type masks */ -#define WINED3DSP_REGTYPE_SHIFT 28 -#define WINED3DSP_REGTYPE_MASK (0x7u << WINED3DSP_REGTYPE_SHIFT) -#define WINED3DSP_REGTYPE_SHIFT2 8 -#define WINED3DSP_REGTYPE_MASK2 (0x18u << WINED3DSP_REGTYPE_SHIFT2) +#define WINED3D_SM1_REGISTER_TYPE_SHIFT 28 +#define WINED3D_SM1_REGISTER_TYPE_MASK (0x7u << WINED3D_SM1_REGISTER_TYPE_SHIFT) +#define WINED3D_SM1_REGISTER_TYPE_SHIFT2 8 +#define WINED3D_SM1_REGISTER_TYPE_MASK2 (0x18u << WINED3D_SM1_REGISTER_TYPE_SHIFT2) /* Relative addressing mask */ -#define WINED3DSHADER_ADDRESSMODE_SHIFT 13 -#define WINED3DSHADER_ADDRESSMODE_MASK (0x1u << WINED3DSHADER_ADDRESSMODE_SHIFT) +#define WINED3D_SM1_ADDRESS_MODE_SHIFT 13 +#define WINED3D_SM1_ADDRESS_MODE_MASK (0x1u << WINED3D_SM1_ADDRESS_MODE_SHIFT) /* Destination modifier mask */ -#define WINED3DSP_DSTMOD_SHIFT 20 -#define WINED3DSP_DSTMOD_MASK (0xfu << WINED3DSP_DSTMOD_SHIFT) +#define WINED3D_SM1_DST_MODIFIER_SHIFT 20 +#define WINED3D_SM1_DST_MODIFIER_MASK (0xfu << WINED3D_SM1_DST_MODIFIER_SHIFT) /* Destination shift mask */ -#define WINED3DSP_DSTSHIFT_SHIFT 24 -#define WINED3DSP_DSTSHIFT_MASK (0xfu << WINED3DSP_DSTSHIFT_SHIFT) +#define WINED3D_SM1_DSTSHIFT_SHIFT 24 +#define WINED3D_SM1_DSTSHIFT_MASK (0xfu << WINED3D_SM1_DSTSHIFT_SHIFT) /* Write mask */ #define WINED3D_SM1_WRITEMASK_SHIFT 16 #define WINED3D_SM1_WRITEMASK_MASK (0xfu << WINED3D_SM1_WRITEMASK_SHIFT) /* Swizzle mask */ -#define WINED3DSP_SWIZZLE_SHIFT 16 -#define WINED3DSP_SWIZZLE_MASK (0xffu << WINED3DSP_SWIZZLE_SHIFT) +#define WINED3D_SM1_SWIZZLE_SHIFT 16 +#define WINED3D_SM1_SWIZZLE_MASK (0xffu << WINED3D_SM1_SWIZZLE_SHIFT) /* Source modifier mask */ -#define WINED3DSP_SRCMOD_SHIFT 24 -#define WINED3DSP_SRCMOD_MASK (0xfu << WINED3DSP_SRCMOD_SHIFT) +#define WINED3D_SM1_SRC_MODIFIER_SHIFT 24 +#define WINED3D_SM1_SRC_MODIFIER_MASK (0xfu << WINED3D_SM1_SRC_MODIFIER_SHIFT) -#define WINED3DSP_END 0x0000ffff +#define WINED3D_SM1_END 0x0000ffff #define WINED3D_SM1_VERSION_MAJOR(version) (((version) >> 8) & 0xff) #define WINED3D_SM1_VERSION_MINOR(version) (((version) >> 0) & 0xff) -enum WINED3DSHADER_ADDRESSMODE_TYPE +enum wined3d_sm1_address_mode_type { - WINED3DSHADER_ADDRMODE_ABSOLUTE = 0u << WINED3DSHADER_ADDRESSMODE_SHIFT, - WINED3DSHADER_ADDRMODE_RELATIVE = 1u << WINED3DSHADER_ADDRESSMODE_SHIFT, + WINED3D_SM1_ADDRESS_MODE_ABSOLUTE = 0u << WINED3D_SM1_ADDRESS_MODE_SHIFT, + WINED3D_SM1_ADDRESS_MODE_RELATIVE = 1u << WINED3D_SM1_ADDRESS_MODE_SHIFT, }; enum wined3d_sm1_resource_type @@ -408,14 +408,14 @@ * VS >= 2.0 have relative addressing (with token) * VS >= 1.0 < 2.0 have relative addressing (without token) * The version check below should work in general */ - if (*ptr & WINED3DSHADER_ADDRMODE_RELATIVE) + if (*ptr & WINED3D_SM1_ADDRESS_MODE_RELATIVE) { if (priv->shader_version.major < 2) { *addr_token = (1u << 31) - | ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT2) & WINED3DSP_REGTYPE_MASK2) - | ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT) & WINED3DSP_REGTYPE_MASK) - | (WINED3DSP_NOSWIZZLE << WINED3DSP_SWIZZLE_SHIFT); + | ((WINED3DSPR_ADDR << WINED3D_SM1_REGISTER_TYPE_SHIFT2) & WINED3D_SM1_REGISTER_TYPE_MASK2) + | ((WINED3DSPR_ADDR << WINED3D_SM1_REGISTER_TYPE_SHIFT) & WINED3D_SM1_REGISTER_TYPE_MASK) + | (WINED3DSP_NOSWIZZLE << WINED3D_SM1_SWIZZLE_SHIFT); } else { @@ -435,7 +435,7 @@ while (opcode_table[i].handler_idx != WINED3DSIH_TABLE_SIZE) { - if ((code & WINED3DSI_OPCODE_MASK) == opcode_table[i].opcode + if ((code & WINED3D_SM1_OPCODE_MASK) == opcode_table[i].opcode && shader_version >= opcode_table[i].min_version && (!opcode_table[i].max_version || shader_version <= opcode_table[i].max_version)) { @@ -445,7 +445,7 @@ } FIXME("Unsupported opcode %#x(%d) masked %#x, shader version %#x\n", - code, code, code & WINED3DSI_OPCODE_MASK, shader_version); + code, code, code & WINED3D_SM1_OPCODE_MASK, shader_version); return NULL; } @@ -454,39 +454,39 @@ static int shader_skip_opcode(const struct wined3d_sm1_data *priv, const struct wined3d_sm1_opcode_info *opcode_info, DWORD opcode_token) { - /* Shaders >= 2.0 may contain address tokens, but fortunately they - * have a useful length mask - use it here. Shaders 1.0 contain no such tokens */ - return (priv->shader_version.major >= 2) - ? ((opcode_token & WINED3DSI_INSTLENGTH_MASK) >> WINED3DSI_INSTLENGTH_SHIFT) : opcode_info->param_count; + /* Shaders >= 2.0 may contain address tokens, but fortunately they + * have a useful length mask - use it here. Shaders 1.0 contain no such tokens */ + DWORD length = (opcode_token & WINED3D_SM1_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM1_INSTRUCTION_LENGTH_SHIFT; + return (priv->shader_version.major >= 2) ? length : opcode_info->param_count; } static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_param *rel_addr, struct wined3d_shader_src_param *src) { - src->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) - | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2); + src->reg.type = ((param & WINED3D_SM1_REGISTER_TYPE_MASK) >> WINED3D_SM1_REGISTER_TYPE_SHIFT) + | ((param & WINED3D_SM1_REGISTER_TYPE_MASK2) >> WINED3D_SM1_REGISTER_TYPE_SHIFT2); src->reg.data_type = WINED3D_DATA_FLOAT; - src->reg.idx[0].offset = param & WINED3DSP_REGNUM_MASK; + src->reg.idx[0].offset = param & WINED3D_SM1_REGISTER_NUMBER_MASK; src->reg.idx[0].rel_addr = rel_addr; src->reg.idx[1].offset = ~0U; src->reg.idx[1].rel_addr = NULL; - src->swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT; - src->modifiers = (param & WINED3DSP_SRCMOD_MASK) >> WINED3DSP_SRCMOD_SHIFT; + src->swizzle = (param & WINED3D_SM1_SWIZZLE_MASK) >> WINED3D_SM1_SWIZZLE_SHIFT; + src->modifiers = (param & WINED3D_SM1_SRC_MODIFIER_MASK) >> WINED3D_SM1_SRC_MODIFIER_SHIFT; } static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_param *rel_addr, struct wined3d_shader_dst_param *dst) { - dst->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) - | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2); + dst->reg.type = ((param & WINED3D_SM1_REGISTER_TYPE_MASK) >> WINED3D_SM1_REGISTER_TYPE_SHIFT) + | ((param & WINED3D_SM1_REGISTER_TYPE_MASK2) >> WINED3D_SM1_REGISTER_TYPE_SHIFT2); dst->reg.data_type = WINED3D_DATA_FLOAT; - dst->reg.idx[0].offset = param & WINED3DSP_REGNUM_MASK; + dst->reg.idx[0].offset = param & WINED3D_SM1_REGISTER_NUMBER_MASK; dst->reg.idx[0].rel_addr = rel_addr; dst->reg.idx[1].offset = ~0U; dst->reg.idx[1].rel_addr = NULL; dst->write_mask = (param & WINED3D_SM1_WRITEMASK_MASK) >> WINED3D_SM1_WRITEMASK_SHIFT; - dst->modifiers = (param & WINED3DSP_DSTMOD_MASK) >> WINED3DSP_DSTMOD_SHIFT; - dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; + dst->modifiers = (param & WINED3D_SM1_DST_MODIFIER_MASK) >> WINED3D_SM1_DST_MODIFIER_SHIFT; + dst->shift = (param & WINED3D_SM1_DSTSHIFT_MASK) >> WINED3D_SM1_DSTSHIFT_SHIFT; } /* Read the parameters of an unrecognized opcode from the input stream @@ -511,20 +511,20 @@ FIXME("Unrecognized opcode param: token=0x%08x addr_token=0x%08x name=", token, addr_token); - if (token & WINED3DSHADER_ADDRMODE_RELATIVE) shader_parse_src_param(addr_token, NULL, &rel_addr); + if (token & WINED3D_SM1_ADDRESS_MODE_RELATIVE) shader_parse_src_param(addr_token, NULL, &rel_addr); if (!i) { struct wined3d_shader_dst_param dst; - shader_parse_dst_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &dst); + shader_parse_dst_param(token, token & WINED3D_SM1_ADDRESS_MODE_RELATIVE ? &rel_addr : NULL, &dst); shader_dump_dst_param(&dst, &priv->shader_version); } else { struct wined3d_shader_src_param src; - shader_parse_src_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &src); + shader_parse_src_param(token, token & WINED3D_SM1_ADDRESS_MODE_RELATIVE ? &rel_addr : NULL, &src); shader_dump_src_param(&src, &priv->shader_version); } FIXME("\n"); @@ -600,7 +600,7 @@ DWORD token, addr_token; *ptr += shader_get_param(priv, *ptr, &token, &addr_token); - if (token & WINED3DSHADER_ADDRMODE_RELATIVE) + if (token & WINED3D_SM1_ADDRESS_MODE_RELATIVE) { shader_parse_src_param(addr_token, NULL, src_rel_addr); shader_parse_src_param(token, src_rel_addr, src_param); @@ -617,7 +617,7 @@ DWORD token, addr_token; *ptr += shader_get_param(priv, *ptr, &token, &addr_token); - if (token & WINED3DSHADER_ADDRMODE_RELATIVE) + if (token & WINED3D_SM1_ADDRESS_MODE_RELATIVE) { shader_parse_src_param(addr_token, NULL, dst_rel_addr); shader_parse_dst_param(token, dst_rel_addr, dst_param); @@ -634,8 +634,8 @@ DWORD usage_token = *(*ptr)++; DWORD dst_token = *(*ptr)++; - semantic->usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; - semantic->usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; + semantic->usage = (usage_token & WINED3D_SM1_DCL_USAGE_MASK) >> WINED3D_SM1_DCL_USAGE_SHIFT; + semantic->usage_idx = (usage_token & WINED3D_SM1_DCL_USAGE_INDEX_MASK) >> WINED3D_SM1_DCL_USAGE_INDEX_SHIFT; resource_type = (usage_token & WINED3D_SM1_RESOURCE_TYPE_MASK) >> WINED3D_SM1_RESOURCE_TYPE_SHIFT; if (resource_type >= ARRAY_SIZE(resource_type_table)) { @@ -674,9 +674,9 @@ const char *comment; UINT size; - while ((token & WINED3DSI_OPCODE_MASK) == WINED3D_SM1_OP_COMMENT) + while ((token & WINED3D_SM1_OPCODE_MASK) == WINED3D_SM1_OP_COMMENT) { - size = (token & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT; + size = (token & WINED3D_SM1_COMMENT_SIZE_MASK) >> WINED3D_SM1_COMMENT_SIZE_SHIFT; comment = (const char *)++(*ptr); *ptr += size; @@ -730,9 +730,9 @@ } ins->handler_idx = opcode_info->handler_idx; - ins->flags = (opcode_token & WINED3D_OPCODESPECIFICCONTROL_MASK) >> WINED3D_OPCODESPECIFICCONTROL_SHIFT; - ins->coissue = opcode_token & WINED3DSI_COISSUE; - ins->predicate = opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED ? &priv->pred_param : NULL; + ins->flags = (opcode_token & WINED3D_SM1_INSTRUCTION_FLAGS_MASK) >> WINED3D_SM1_INSTRUCTION_FLAGS_SHIFT; + ins->coissue = opcode_token & WINED3D_SM1_COISSUE; + ins->predicate = opcode_token & WINED3D_SM1_INSTRUCTION_PREDICATED ? &priv->pred_param : NULL; ins->dst_count = opcode_info->dst_count ? 1 : 0; ins->dst = &priv->dst_param; ins->src_count = opcode_info->param_count - opcode_info->dst_count; @@ -782,7 +782,7 @@ { shader_sm1_read_comment(ptr); - if (**ptr == WINED3DSP_END) + if (**ptr == WINED3D_SM1_END) { ++(*ptr); return TRUE; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/shader_sm4.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/shader_sm4.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/shader_sm4.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/shader_sm4.c 2016-02-08 19:32:34.000000000 +0000 @@ -29,6 +29,9 @@ #define WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT 24 #define WINED3D_SM4_INSTRUCTION_LENGTH_MASK (0x1fu << WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT) +#define WINED3D_SM4_INSTRUCTION_FLAGS_SHIFT 11 +#define WINED3D_SM4_INSTRUCTION_FLAGS_MASK (0x7u << WINED3D_SM4_INSTRUCTION_FLAGS_SHIFT) + #define WINED3D_SM4_RESOURCE_TYPE_SHIFT 11 #define WINED3D_SM4_RESOURCE_TYPE_MASK (0xfu << WINED3D_SM4_RESOURCE_TYPE_SHIFT) @@ -38,6 +41,18 @@ #define WINED3D_SM4_INDEX_TYPE_SHIFT 11 #define WINED3D_SM4_INDEX_TYPE_MASK (0x1u << WINED3D_SM4_INDEX_TYPE_SHIFT) +#define WINED3D_SM4_SAMPLER_MODE_SHIFT 11 +#define WINED3D_SM4_SAMPLER_MODE_MASK (0xfu << WINED3D_SM4_SAMPLER_MODE_SHIFT) + +#define WINED3D_SM4_SHADER_DATA_TYPE_SHIFT 11 +#define WINED3D_SM4_SHADER_DATA_TYPE_MASK (0xfu << WINED3D_SM4_SHADER_DATA_TYPE_SHIFT) + +#define WINED3D_SM4_INTERPOLATION_MODE_SHIFT 11 +#define WINED3D_SM4_INTERPOLATION_MODE_MASK (0xfu << WINED3D_SM4_INTERPOLATION_MODE_SHIFT) + +#define WINED3D_SM4_GLOBAL_FLAGS_SHIFT 11 +#define WINED3D_SM4_GLOBAL_FLAGS_MASK (0xffu << WINED3D_SM4_GLOBAL_FLAGS_SHIFT) + #define WINED3D_SM4_OPCODE_MASK 0xff #define WINED3D_SM4_REGISTER_MODIFIER (0x1u << 31) @@ -72,6 +87,8 @@ #define WINED3D_SM4_ADDRESSING_RELATIVE 0x2 #define WINED3D_SM4_ADDRESSING_OFFSET 0x1 +#define WINED3D_SM4_INSTRUCTION_FLAG_SATURATE 0x4 + enum wined3d_sm4_opcode { WINED3D_SM4_OP_ADD = 0x00, @@ -86,6 +103,7 @@ WINED3D_SM4_OP_DP2 = 0x0f, WINED3D_SM4_OP_DP3 = 0x10, WINED3D_SM4_OP_DP4 = 0x11, + WINED3D_SM4_OP_ELSE = 0x12, WINED3D_SM4_OP_EMIT = 0x13, WINED3D_SM4_OP_ENDIF = 0x15, WINED3D_SM4_OP_ENDLOOP = 0x16, @@ -93,12 +111,19 @@ WINED3D_SM4_OP_EXP = 0x19, WINED3D_SM4_OP_FRC = 0x1a, WINED3D_SM4_OP_FTOI = 0x1b, + WINED3D_SM4_OP_FTOU = 0x1c, WINED3D_SM4_OP_GE = 0x1d, WINED3D_SM4_OP_IADD = 0x1e, WINED3D_SM4_OP_IF = 0x1f, WINED3D_SM4_OP_IEQ = 0x20, WINED3D_SM4_OP_IGE = 0x21, + WINED3D_SM4_OP_ILT = 0x22, + WINED3D_SM4_OP_IMAD = 0x23, + WINED3D_SM4_OP_IMAX = 0x24, + WINED3D_SM4_OP_IMIN = 0x25, WINED3D_SM4_OP_IMUL = 0x26, + WINED3D_SM4_OP_INE = 0x27, + WINED3D_SM4_OP_INEG = 0x28, WINED3D_SM4_OP_ISHL = 0x29, WINED3D_SM4_OP_ITOF = 0x2b, WINED3D_SM4_OP_LD = 0x2d, @@ -108,17 +133,25 @@ WINED3D_SM4_OP_MAD = 0x32, WINED3D_SM4_OP_MIN = 0x33, WINED3D_SM4_OP_MAX = 0x34, + WINED3D_SM4_OP_SHADER_DATA = 0x35, WINED3D_SM4_OP_MOV = 0x36, WINED3D_SM4_OP_MOVC = 0x37, WINED3D_SM4_OP_MUL = 0x38, WINED3D_SM4_OP_NE = 0x39, + WINED3D_SM4_OP_NOT = 0x3b, WINED3D_SM4_OP_OR = 0x3c, + WINED3D_SM4_OP_RESINFO = 0x3d, WINED3D_SM4_OP_RET = 0x3e, WINED3D_SM4_OP_ROUND_NI = 0x41, + WINED3D_SM4_OP_ROUND_PI = 0x42, + WINED3D_SM4_OP_ROUND_Z = 0x43, WINED3D_SM4_OP_RSQ = 0x44, WINED3D_SM4_OP_SAMPLE = 0x45, + WINED3D_SM4_OP_SAMPLE_C = 0x46, + WINED3D_SM4_OP_SAMPLE_C_LZ = 0x47, WINED3D_SM4_OP_SAMPLE_LOD = 0x48, WINED3D_SM4_OP_SAMPLE_GRAD = 0x49, + WINED3D_SM4_OP_SAMPLE_B = 0x4a, WINED3D_SM4_OP_SQRT = 0x4b, WINED3D_SM4_OP_SINCOS = 0x4d, WINED3D_SM4_OP_UDIV = 0x4e, @@ -128,22 +161,35 @@ WINED3D_SM4_OP_XOR = 0x57, WINED3D_SM4_OP_DCL_RESOURCE = 0x58, WINED3D_SM4_OP_DCL_CONSTANT_BUFFER = 0x59, + WINED3D_SM4_OP_DCL_SAMPLER = 0x5a, WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY = 0x5c, WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE = 0x5d, WINED3D_SM4_OP_DCL_VERTICES_OUT = 0x5e, + WINED3D_SM4_OP_DCL_INPUT = 0x5f, + WINED3D_SM4_OP_DCL_INPUT_SGV = 0x60, + WINED3D_SM4_OP_DCL_INPUT_SIV = 0x61, + WINED3D_SM4_OP_DCL_INPUT_PS = 0x62, + WINED3D_SM4_OP_DCL_INPUT_PS_SGV = 0x63, + WINED3D_SM4_OP_DCL_INPUT_PS_SIV = 0x64, + WINED3D_SM4_OP_DCL_OUTPUT = 0x65, + WINED3D_SM4_OP_DCL_OUTPUT_SIV = 0x67, + WINED3D_SM4_OP_DCL_TEMPS = 0x68, + WINED3D_SM4_OP_DCL_GLOBAL_FLAGS = 0x6a, }; enum wined3d_sm4_register_type { - WINED3D_SM4_RT_TEMP = 0x0, - WINED3D_SM4_RT_INPUT = 0x1, - WINED3D_SM4_RT_OUTPUT = 0x2, - WINED3D_SM4_RT_IMMCONST = 0x4, - WINED3D_SM4_RT_SAMPLER = 0x6, - WINED3D_SM4_RT_RESOURCE = 0x7, - WINED3D_SM4_RT_CONSTBUFFER = 0x8, - WINED3D_SM4_RT_PRIMID = 0xb, - WINED3D_SM4_RT_NULL = 0xd, + WINED3D_SM4_RT_TEMP = 0x0, + WINED3D_SM4_RT_INPUT = 0x1, + WINED3D_SM4_RT_OUTPUT = 0x2, + WINED3D_SM4_RT_IMMCONST = 0x4, + WINED3D_SM4_RT_SAMPLER = 0x6, + WINED3D_SM4_RT_RESOURCE = 0x7, + WINED3D_SM4_RT_CONSTBUFFER = 0x8, + WINED3D_SM4_RT_IMMCONSTBUFFER = 0x9, + WINED3D_SM4_RT_PRIMID = 0xb, + WINED3D_SM4_RT_DEPTHOUT = 0xc, + WINED3D_SM4_RT_NULL = 0xd, }; enum wined3d_sm4_output_primitive_type @@ -164,6 +210,7 @@ enum wined3d_sm4_swizzle_type { + WINED3D_SM4_SWIZZLE_NONE = 0x0, WINED3D_SM4_SWIZZLE_VEC4 = 0x1, WINED3D_SM4_SWIZZLE_SCALAR = 0x2, }; @@ -196,6 +243,18 @@ WINED3D_SM4_DATA_FLOAT = 0x5, }; +enum wined3d_sm4_sampler_mode +{ + WINED3D_SM4_SAMPLER_DEFAULT = 0x0, + WINED3D_SM4_SAMPLER_COMPARISON = 0x1, +}; + +enum wined3d_sm4_shader_data_type +{ + WINED3D_SM4_SHADER_DATA_IMMEDIATE_CONSTANT_BUFFER = 0x3, + WINED3D_SM4_SHADER_DATA_MESSAGE = 0x4, +}; + struct wined3d_shader_src_param_entry { struct list entry; @@ -217,6 +276,7 @@ struct wined3d_shader_dst_param dst_param[2]; struct list src_free; struct list src; + struct wined3d_shader_immediate_constant_buffer icb; }; struct wined3d_sm4_opcode_info @@ -243,63 +303,90 @@ */ static const struct wined3d_sm4_opcode_info opcode_table[] = { - {WINED3D_SM4_OP_ADD, WINED3DSIH_ADD, "F", "FF"}, - {WINED3D_SM4_OP_AND, WINED3DSIH_AND, "U", "UU"}, - {WINED3D_SM4_OP_BREAK, WINED3DSIH_BREAK, "", ""}, - {WINED3D_SM4_OP_BREAKC, WINED3DSIH_BREAKP, "", "U"}, - {WINED3D_SM4_OP_CUT, WINED3DSIH_CUT, "", ""}, - {WINED3D_SM4_OP_DERIV_RTX, WINED3DSIH_DSX, "F", "F"}, - {WINED3D_SM4_OP_DERIV_RTY, WINED3DSIH_DSY, "F", "F"}, - {WINED3D_SM4_OP_DISCARD, WINED3DSIH_TEXKILL, "", "U"}, - {WINED3D_SM4_OP_DIV, WINED3DSIH_DIV, "F", "FF"}, - {WINED3D_SM4_OP_DP2, WINED3DSIH_DP2, "F", "FF"}, - {WINED3D_SM4_OP_DP3, WINED3DSIH_DP3, "F", "FF"}, - {WINED3D_SM4_OP_DP4, WINED3DSIH_DP4, "F", "FF"}, - {WINED3D_SM4_OP_EMIT, WINED3DSIH_EMIT, "", ""}, - {WINED3D_SM4_OP_ENDIF, WINED3DSIH_ENDIF, "", ""}, - {WINED3D_SM4_OP_ENDLOOP, WINED3DSIH_ENDLOOP, "", ""}, - {WINED3D_SM4_OP_EQ, WINED3DSIH_EQ, "U", "FF"}, - {WINED3D_SM4_OP_EXP, WINED3DSIH_EXP, "F", "F"}, - {WINED3D_SM4_OP_FRC, WINED3DSIH_FRC, "F", "F"}, - {WINED3D_SM4_OP_FTOI, WINED3DSIH_FTOI, "I", "F"}, - {WINED3D_SM4_OP_GE, WINED3DSIH_GE, "U", "FF"}, - {WINED3D_SM4_OP_IADD, WINED3DSIH_IADD, "I", "II"}, - {WINED3D_SM4_OP_IF, WINED3DSIH_IF, "", "U"}, - {WINED3D_SM4_OP_IEQ, WINED3DSIH_IEQ, "U", "II"}, - {WINED3D_SM4_OP_IGE, WINED3DSIH_IGE, "U", "II"}, - {WINED3D_SM4_OP_IMUL, WINED3DSIH_IMUL, "II", "II"}, - {WINED3D_SM4_OP_ISHL, WINED3DSIH_ISHL, "I", "II"}, - {WINED3D_SM4_OP_ITOF, WINED3DSIH_ITOF, "F", "I"}, - {WINED3D_SM4_OP_LD, WINED3DSIH_LD, "U", "FR"}, - {WINED3D_SM4_OP_LOG, WINED3DSIH_LOG, "F", "F"}, - {WINED3D_SM4_OP_LOOP, WINED3DSIH_LOOP, "", ""}, - {WINED3D_SM4_OP_LT, WINED3DSIH_LT, "U", "FF"}, - {WINED3D_SM4_OP_MAD, WINED3DSIH_MAD, "F", "FFF"}, - {WINED3D_SM4_OP_MIN, WINED3DSIH_MIN, "F", "FF"}, - {WINED3D_SM4_OP_MAX, WINED3DSIH_MAX, "F", "FF"}, - {WINED3D_SM4_OP_MOV, WINED3DSIH_MOV, "F", "F"}, - {WINED3D_SM4_OP_MOVC, WINED3DSIH_MOVC, "F", "UFF"}, - {WINED3D_SM4_OP_MUL, WINED3DSIH_MUL, "F", "FF"}, - {WINED3D_SM4_OP_NE, WINED3DSIH_NE, "U", "FF"}, - {WINED3D_SM4_OP_OR, WINED3DSIH_OR, "U", "UU"}, - {WINED3D_SM4_OP_RET, WINED3DSIH_RET, "", ""}, - {WINED3D_SM4_OP_ROUND_NI, WINED3DSIH_ROUND_NI, "F", "F"}, - {WINED3D_SM4_OP_RSQ, WINED3DSIH_RSQ, "F", "F"}, - {WINED3D_SM4_OP_SAMPLE, WINED3DSIH_SAMPLE, "U", "FRS"}, - {WINED3D_SM4_OP_SAMPLE_LOD, WINED3DSIH_SAMPLE_LOD, "U", "FRSF"}, - {WINED3D_SM4_OP_SAMPLE_GRAD, WINED3DSIH_SAMPLE_GRAD, "U", "FRSFF"}, - {WINED3D_SM4_OP_SQRT, WINED3DSIH_SQRT, "F", "F"}, - {WINED3D_SM4_OP_SINCOS, WINED3DSIH_SINCOS, "FF", "F"}, - {WINED3D_SM4_OP_UDIV, WINED3DSIH_UDIV, "UU", "UU"}, - {WINED3D_SM4_OP_UGE, WINED3DSIH_UGE, "U", "UU"}, - {WINED3D_SM4_OP_USHR, WINED3DSIH_USHR, "U", "UU"}, - {WINED3D_SM4_OP_UTOF, WINED3DSIH_UTOF, "F", "U"}, - {WINED3D_SM4_OP_XOR, WINED3DSIH_XOR, "U", "UU"}, - {WINED3D_SM4_OP_DCL_RESOURCE, WINED3DSIH_DCL, "R", ""}, - {WINED3D_SM4_OP_DCL_CONSTANT_BUFFER, WINED3DSIH_DCL_CONSTANT_BUFFER, "", ""}, - {WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, WINED3DSIH_DCL_OUTPUT_TOPOLOGY, "", ""}, - {WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE, WINED3DSIH_DCL_INPUT_PRIMITIVE, "", ""}, - {WINED3D_SM4_OP_DCL_VERTICES_OUT, WINED3DSIH_DCL_VERTICES_OUT, "", ""}, + {WINED3D_SM4_OP_ADD, WINED3DSIH_ADD, "F", "FF"}, + {WINED3D_SM4_OP_AND, WINED3DSIH_AND, "U", "UU"}, + {WINED3D_SM4_OP_BREAK, WINED3DSIH_BREAK, "", ""}, + {WINED3D_SM4_OP_BREAKC, WINED3DSIH_BREAKP, "", "U"}, + {WINED3D_SM4_OP_CUT, WINED3DSIH_CUT, "", ""}, + {WINED3D_SM4_OP_DERIV_RTX, WINED3DSIH_DSX, "F", "F"}, + {WINED3D_SM4_OP_DERIV_RTY, WINED3DSIH_DSY, "F", "F"}, + {WINED3D_SM4_OP_DISCARD, WINED3DSIH_TEXKILL, "", "U"}, + {WINED3D_SM4_OP_DIV, WINED3DSIH_DIV, "F", "FF"}, + {WINED3D_SM4_OP_DP2, WINED3DSIH_DP2, "F", "FF"}, + {WINED3D_SM4_OP_DP3, WINED3DSIH_DP3, "F", "FF"}, + {WINED3D_SM4_OP_DP4, WINED3DSIH_DP4, "F", "FF"}, + {WINED3D_SM4_OP_ELSE, WINED3DSIH_ELSE, "", ""}, + {WINED3D_SM4_OP_EMIT, WINED3DSIH_EMIT, "", ""}, + {WINED3D_SM4_OP_ENDIF, WINED3DSIH_ENDIF, "", ""}, + {WINED3D_SM4_OP_ENDLOOP, WINED3DSIH_ENDLOOP, "", ""}, + {WINED3D_SM4_OP_EQ, WINED3DSIH_EQ, "U", "FF"}, + {WINED3D_SM4_OP_EXP, WINED3DSIH_EXP, "F", "F"}, + {WINED3D_SM4_OP_FRC, WINED3DSIH_FRC, "F", "F"}, + {WINED3D_SM4_OP_FTOI, WINED3DSIH_FTOI, "I", "F"}, + {WINED3D_SM4_OP_FTOU, WINED3DSIH_FTOU, "U", "F"}, + {WINED3D_SM4_OP_GE, WINED3DSIH_GE, "U", "FF"}, + {WINED3D_SM4_OP_IADD, WINED3DSIH_IADD, "I", "II"}, + {WINED3D_SM4_OP_IF, WINED3DSIH_IF, "", "U"}, + {WINED3D_SM4_OP_IEQ, WINED3DSIH_IEQ, "U", "II"}, + {WINED3D_SM4_OP_IGE, WINED3DSIH_IGE, "U", "II"}, + {WINED3D_SM4_OP_ILT, WINED3DSIH_ILT, "U", "II"}, + {WINED3D_SM4_OP_IMAD, WINED3DSIH_IMAD, "I", "III"}, + {WINED3D_SM4_OP_IMAX, WINED3DSIH_IMAX, "I", "II"}, + {WINED3D_SM4_OP_IMIN, WINED3DSIH_IMIN, "I", "II"}, + {WINED3D_SM4_OP_IMUL, WINED3DSIH_IMUL, "II", "II"}, + {WINED3D_SM4_OP_INE, WINED3DSIH_INE, "U", "II"}, + {WINED3D_SM4_OP_INEG, WINED3DSIH_INEG, "I", "I"}, + {WINED3D_SM4_OP_ISHL, WINED3DSIH_ISHL, "I", "II"}, + {WINED3D_SM4_OP_ITOF, WINED3DSIH_ITOF, "F", "I"}, + {WINED3D_SM4_OP_LD, WINED3DSIH_LD, "U", "IR"}, + {WINED3D_SM4_OP_LOG, WINED3DSIH_LOG, "F", "F"}, + {WINED3D_SM4_OP_LOOP, WINED3DSIH_LOOP, "", ""}, + {WINED3D_SM4_OP_LT, WINED3DSIH_LT, "U", "FF"}, + {WINED3D_SM4_OP_MAD, WINED3DSIH_MAD, "F", "FFF"}, + {WINED3D_SM4_OP_MIN, WINED3DSIH_MIN, "F", "FF"}, + {WINED3D_SM4_OP_MAX, WINED3DSIH_MAX, "F", "FF"}, + {WINED3D_SM4_OP_SHADER_DATA, WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, "", ""}, + {WINED3D_SM4_OP_MOV, WINED3DSIH_MOV, "F", "F"}, + {WINED3D_SM4_OP_MOVC, WINED3DSIH_MOVC, "F", "UFF"}, + {WINED3D_SM4_OP_MUL, WINED3DSIH_MUL, "F", "FF"}, + {WINED3D_SM4_OP_NE, WINED3DSIH_NE, "U", "FF"}, + {WINED3D_SM4_OP_NOT, WINED3DSIH_NOT, "U", "U"}, + {WINED3D_SM4_OP_OR, WINED3DSIH_OR, "U", "UU"}, + {WINED3D_SM4_OP_RESINFO, WINED3DSIH_RESINFO, "F", "IR"}, + {WINED3D_SM4_OP_RET, WINED3DSIH_RET, "", ""}, + {WINED3D_SM4_OP_ROUND_NI, WINED3DSIH_ROUND_NI, "F", "F"}, + {WINED3D_SM4_OP_ROUND_PI, WINED3DSIH_ROUND_PI, "F", "F"}, + {WINED3D_SM4_OP_ROUND_Z, WINED3DSIH_ROUND_Z, "F", "F"}, + {WINED3D_SM4_OP_RSQ, WINED3DSIH_RSQ, "F", "F"}, + {WINED3D_SM4_OP_SAMPLE, WINED3DSIH_SAMPLE, "U", "FRS"}, + {WINED3D_SM4_OP_SAMPLE_C, WINED3DSIH_SAMPLE_C, "F", "FRSF"}, + {WINED3D_SM4_OP_SAMPLE_C_LZ, WINED3DSIH_SAMPLE_C_LZ, "F", "FRSF"}, + {WINED3D_SM4_OP_SAMPLE_LOD, WINED3DSIH_SAMPLE_LOD, "U", "FRSF"}, + {WINED3D_SM4_OP_SAMPLE_GRAD, WINED3DSIH_SAMPLE_GRAD, "U", "FRSFF"}, + {WINED3D_SM4_OP_SAMPLE_B, WINED3DSIH_SAMPLE_B, "U", "FRSF"}, + {WINED3D_SM4_OP_SQRT, WINED3DSIH_SQRT, "F", "F"}, + {WINED3D_SM4_OP_SINCOS, WINED3DSIH_SINCOS, "FF", "F"}, + {WINED3D_SM4_OP_UDIV, WINED3DSIH_UDIV, "UU", "UU"}, + {WINED3D_SM4_OP_UGE, WINED3DSIH_UGE, "U", "UU"}, + {WINED3D_SM4_OP_USHR, WINED3DSIH_USHR, "U", "UU"}, + {WINED3D_SM4_OP_UTOF, WINED3DSIH_UTOF, "F", "U"}, + {WINED3D_SM4_OP_XOR, WINED3DSIH_XOR, "U", "UU"}, + {WINED3D_SM4_OP_DCL_RESOURCE, WINED3DSIH_DCL, "R", ""}, + {WINED3D_SM4_OP_DCL_CONSTANT_BUFFER, WINED3DSIH_DCL_CONSTANT_BUFFER, "", ""}, + {WINED3D_SM4_OP_DCL_SAMPLER, WINED3DSIH_DCL_SAMPLER, "", ""}, + {WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, WINED3DSIH_DCL_OUTPUT_TOPOLOGY, "", ""}, + {WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE, WINED3DSIH_DCL_INPUT_PRIMITIVE, "", ""}, + {WINED3D_SM4_OP_DCL_VERTICES_OUT, WINED3DSIH_DCL_VERTICES_OUT, "", ""}, + {WINED3D_SM4_OP_DCL_INPUT, WINED3DSIH_DCL_INPUT, "", ""}, + {WINED3D_SM4_OP_DCL_INPUT_SGV, WINED3DSIH_DCL_INPUT_SGV, "", ""}, + {WINED3D_SM4_OP_DCL_INPUT_SIV, WINED3DSIH_DCL_INPUT_SIV, "", ""}, + {WINED3D_SM4_OP_DCL_INPUT_PS, WINED3DSIH_DCL_INPUT_PS, "", ""}, + {WINED3D_SM4_OP_DCL_INPUT_PS_SGV, WINED3DSIH_DCL_INPUT_PS_SGV, "", ""}, + {WINED3D_SM4_OP_DCL_INPUT_PS_SIV, WINED3DSIH_DCL_INPUT_PS_SIV, "", ""}, + {WINED3D_SM4_OP_DCL_OUTPUT, WINED3DSIH_DCL_OUTPUT, "", ""}, + {WINED3D_SM4_OP_DCL_OUTPUT_SIV, WINED3DSIH_DCL_OUTPUT_SIV, "", ""}, + {WINED3D_SM4_OP_DCL_TEMPS, WINED3DSIH_DCL_TEMPS, "", ""}, + {WINED3D_SM4_OP_DCL_GLOBAL_FLAGS, WINED3DSIH_DCL_GLOBAL_FLAGS, "", ""}, }; static const enum wined3d_shader_register_type register_type_table[] = @@ -313,10 +400,10 @@ /* WINED3D_SM4_RT_SAMPLER */ WINED3DSPR_SAMPLER, /* WINED3D_SM4_RT_RESOURCE */ WINED3DSPR_RESOURCE, /* WINED3D_SM4_RT_CONSTBUFFER */ WINED3DSPR_CONSTBUFFER, - /* UNKNOWN */ 0, + /* WINED3D_SM4_RT_IMMCONSTBUFFER */ WINED3DSPR_IMMCONSTBUFFER, /* UNKNOWN */ 0, /* WINED3D_SM4_RT_PRIMID */ WINED3DSPR_PRIMID, - /* UNKNOWN */ 0, + /* WINED3D_SM4_RT_DEPTHOUT */ WINED3DSPR_DEPTHOUT, /* WINED3D_SM4_RT_NULL */ WINED3DSPR_NULL, }; @@ -601,9 +688,6 @@ { DWORD m = *(*ptr)++; - /* FIXME: This will probably break down at some point. The SM4 - * modifiers look like flags, while wined3d currently has an enum - * with possible combinations, e.g. WINED3DSPSM_ABSNEG. */ switch (m) { case 0x41: @@ -614,6 +698,10 @@ *modifier = WINED3DSPSM_ABS; break; + case 0xc1: + *modifier = WINED3DSPSM_ABSNEG; + break; + default: FIXME("Skipping modifier 0x%08x.\n", m); *modifier = WINED3DSPSM_NONE; @@ -706,6 +794,10 @@ switch (swizzle_type) { + case WINED3D_SM4_SWIZZLE_NONE: + src_param->swizzle = WINED3DSP_NOSWIZZLE; + break; + case WINED3D_SM4_SWIZZLE_SCALAR: src_param->swizzle = (token & WINED3D_SM4_SWIZZLE_MASK) >> WINED3D_SM4_SWIZZLE_SHIFT; src_param->swizzle = (src_param->swizzle & 0x3) * 0x55; @@ -761,7 +853,11 @@ opcode_token = *(*ptr)++; opcode = opcode_token & WINED3D_SM4_OPCODE_MASK; - len = ((opcode_token & WINED3D_SM4_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT) - 1; + + len = ((opcode_token & WINED3D_SM4_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT); + if (!len) + len = **ptr; + --len; if (TRACE_ON(d3d_bytecode)) { @@ -799,7 +895,33 @@ FIXME("Skipping modifier 0x%08x.\n", modifier); } - if (opcode == WINED3D_SM4_OP_DCL_RESOURCE) + if (opcode == WINED3D_SM4_OP_SHADER_DATA) + { + unsigned int icb_size; + enum wined3d_sm4_shader_data_type type; + + type = (opcode_token & WINED3D_SM4_SHADER_DATA_TYPE_MASK) >> WINED3D_SM4_SHADER_DATA_TYPE_SHIFT; + if (type != WINED3D_SM4_SHADER_DATA_IMMEDIATE_CONSTANT_BUFFER) + { + FIXME("Unhandled shader data type %#x.\n", type); + ins->handler_idx = WINED3DSIH_TABLE_SIZE; + return; + } + + ++p; + icb_size = len - 1; + if (icb_size % 4 || icb_size > MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE) + { + FIXME("Unexpected immediate constant buffer size %u.\n", len); + ins->handler_idx = WINED3DSIH_TABLE_SIZE; + return; + } + + priv->icb.element_count = len; + memcpy(priv->icb.data, p, sizeof(*p) * icb_size); + ins->declaration.icb = &priv->icb; + } + else if (opcode == WINED3D_SM4_OP_DCL_RESOURCE) { enum wined3d_sm4_resource_type resource_type; enum wined3d_sm4_data_type data_type; @@ -838,6 +960,13 @@ if (opcode_token & WINED3D_SM4_INDEX_TYPE_MASK) ins->flags |= WINED3DSI_INDEXED_DYNAMIC; } + else if (opcode == WINED3D_SM4_OP_DCL_SAMPLER) + { + ins->flags = (opcode_token & WINED3D_SM4_SAMPLER_MODE_MASK) >> WINED3D_SM4_SAMPLER_MODE_SHIFT; + if (ins->flags & ~WINED3D_SM4_SAMPLER_COMPARISON) + FIXME("Unhandled sampler mode %#x.\n", ins->flags); + shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_SAMPLER, &ins->declaration.dst); + } else if (opcode == WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY) { enum wined3d_sm4_output_primitive_type primitive_type; @@ -868,12 +997,51 @@ ins->declaration.primitive_type = input_primitive_type_table[primitive_type]; } } - else if (opcode == WINED3D_SM4_OP_DCL_VERTICES_OUT) + else if (opcode == WINED3D_SM4_OP_DCL_INPUT_PS) + { + ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT; + shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.dst); + } + else if (opcode == WINED3D_SM4_OP_DCL_INPUT_PS_SGV + || opcode == WINED3D_SM4_OP_DCL_INPUT_SGV + || opcode == WINED3D_SM4_OP_DCL_INPUT_SIV + || opcode == WINED3D_SM4_OP_DCL_OUTPUT_SIV) + { + shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.register_semantic.reg); + ins->declaration.register_semantic.sysval_semantic = *p++; + } + else if (opcode == WINED3D_SM4_OP_DCL_INPUT_PS_SIV) + { + ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT; + shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.register_semantic.reg); + ins->declaration.register_semantic.sysval_semantic = *p++; + } + else if (opcode == WINED3D_SM4_OP_DCL_INPUT + || opcode == WINED3D_SM4_OP_DCL_OUTPUT) + { + shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.dst); + } + else if (opcode == WINED3D_SM4_OP_DCL_VERTICES_OUT + || opcode == WINED3D_SM4_OP_DCL_TEMPS) { ins->declaration.count = *p++; } + else if (opcode == WINED3D_SM4_OP_DCL_GLOBAL_FLAGS) + { + ins->flags = (opcode_token & WINED3D_SM4_GLOBAL_FLAGS_MASK) >> WINED3D_SM4_GLOBAL_FLAGS_SHIFT; + } else { + enum wined3d_shader_dst_modifier instruction_dst_modifier = WINED3DSPDM_NONE; + + ins->flags = (opcode_token & WINED3D_SM4_INSTRUCTION_FLAGS_MASK) >> WINED3D_SM4_INSTRUCTION_FLAGS_SHIFT; + + if (ins->flags & WINED3D_SM4_INSTRUCTION_FLAG_SATURATE) + { + ins->flags &= ~WINED3D_SM4_INSTRUCTION_FLAG_SATURATE; + instruction_dst_modifier = WINED3DSPDM_SATURATE; + } + for (i = 0; i < ins->dst_count; ++i) { if (!(shader_sm4_read_dst_param(priv, &p, map_data_type(opcode_info->dst_info[i]), &priv->dst_param[i]))) @@ -881,6 +1049,7 @@ ins->handler_idx = WINED3DSIH_TABLE_SIZE; return; } + priv->dst_param[i].modifiers |= instruction_dst_modifier; } for (i = 0; i < ins->src_count; ++i) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/state.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/state.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/state.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/state.c 2016-02-08 19:32:34.000000000 +0000 @@ -2767,7 +2767,7 @@ checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); } else Handled = FALSE; - break; + break; case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM: if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]) { @@ -2789,7 +2789,7 @@ checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); } else Handled = FALSE; - break; + break; case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR: if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]) { @@ -2817,7 +2817,7 @@ checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); } else Handled = FALSE; - break; + break; case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA: if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]) { @@ -2845,7 +2845,7 @@ checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); } else Handled = FALSE; - break; + break; case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR: if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]) { @@ -2873,7 +2873,7 @@ checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); } else Handled = FALSE; - break; + break; case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA: if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]) { @@ -2907,7 +2907,7 @@ checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); } else Handled = FALSE; - break; + break; case WINED3D_TOP_MULTIPLY_ADD: if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]) { @@ -2929,7 +2929,7 @@ checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); } else Handled = FALSE; - break; + break; case WINED3D_TOP_BUMPENVMAP_LUMINANCE: case WINED3D_TOP_BUMPENVMAP: if (gl_info->supported[NV_TEXTURE_SHADER2]) @@ -3198,7 +3198,7 @@ { const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int mapped_stage = 0; - unsigned int textureNo = 0; + unsigned int textureNo; for (textureNo = 0; textureNo < context->d3d_info->limits.ffp_blend_stages; ++textureNo) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/surface.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/surface.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/surface.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/surface.c 2016-02-08 19:32:34.000000000 +0000 @@ -356,7 +356,7 @@ masks[2] = ((1u << format->blue_size) - 1) << format->blue_offset; } -static HRESULT surface_create_dib_section(struct wined3d_surface *surface) +HRESULT surface_create_dib_section(struct wined3d_surface *surface) { const struct wined3d_format *format = surface->resource.format; unsigned int format_flags = surface->container->resource.format_flags; @@ -589,39 +589,15 @@ { /* In some conditions the surface memory must not be freed: * WINED3D_TEXTURE_CONVERTED: Converting the data back would take too long - * WINED3D_TEXTURE_DYNAMIC_MAP: Avoid freeing the data for performance - * SFLAG_CLIENT: OpenGL uses our memory as backup */ - if (surface->resource.map_count || surface->flags & SFLAG_CLIENT - || surface->container->flags & (WINED3D_TEXTURE_CONVERTED | WINED3D_TEXTURE_PIN_SYSMEM - | WINED3D_TEXTURE_DYNAMIC_MAP)) + * WINED3D_TEXTURE_DYNAMIC_MAP: Avoid freeing the data for performance */ + if (surface->resource.map_count || surface->container->flags & (WINED3D_TEXTURE_CONVERTED + | WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_DYNAMIC_MAP)) return; wined3d_resource_free_sysmem(&surface->resource); surface_invalidate_location(surface, WINED3D_LOCATION_SYSMEM); } -static void surface_release_client_storage(struct wined3d_surface *surface) -{ - struct wined3d_context *context = context_acquire(surface->resource.device, NULL); - const struct wined3d_gl_info *gl_info = context->gl_info; - - if (surface->container->texture_rgb.name) - { - wined3d_texture_bind_and_dirtify(surface->container, context, FALSE); - gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, - GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); - } - if (surface->container->texture_srgb.name) - { - wined3d_texture_bind_and_dirtify(surface->container, context, TRUE); - gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, - GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); - } - wined3d_texture_force_reload(surface->container); - - context_release(context); -} - static BOOL surface_use_pbo(const struct wined3d_surface *surface) { const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info; @@ -1072,19 +1048,35 @@ static HRESULT wined3d_surface_depth_fill(struct wined3d_surface *surface, const RECT *rect, float depth) { - const struct wined3d_resource *resource = &surface->container->resource; + struct wined3d_resource *resource = &surface->container->resource; struct wined3d_device *device = resource->device; + struct wined3d_rendertarget_view_desc view_desc; + struct wined3d_rendertarget_view *view; const struct blit_shader *blitter; + HRESULT hr; - blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, WINED3D_BLIT_OP_DEPTH_FILL, - NULL, 0, 0, NULL, rect, resource->usage, resource->pool, resource->format); - if (!blitter) + if (!(blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, + WINED3D_BLIT_OP_DEPTH_FILL, NULL, 0, 0, NULL, rect, resource->usage, resource->pool, resource->format))) { FIXME("No blitter is capable of performing the requested depth fill operation.\n"); return WINED3DERR_INVALIDCALL; } - return blitter->depth_fill(device, surface, rect, depth); + view_desc.format_id = resource->format->id; + view_desc.u.texture.level_idx = surface->texture_level; + view_desc.u.texture.layer_idx = surface->texture_layer; + view_desc.u.texture.layer_count = 1; + if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, + resource, NULL, &wined3d_null_parent_ops, &view))) + { + ERR("Failed to create rendertarget view, hr %#x.\n", hr); + return hr; + } + + hr = blitter->depth_fill(device, view, rect, depth); + wined3d_rendertarget_view_decref(view); + + return hr; } static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect, @@ -1117,12 +1109,20 @@ static ULONG surface_resource_incref(struct wined3d_resource *resource) { - return wined3d_surface_incref(surface_from_resource(resource)); + struct wined3d_surface *surface = surface_from_resource(resource); + + TRACE("surface %p, container %p.\n", surface, surface->container); + + return wined3d_texture_incref(surface->container); } static ULONG surface_resource_decref(struct wined3d_resource *resource) { - return wined3d_surface_decref(surface_from_resource(resource)); + struct wined3d_surface *surface = surface_from_resource(resource); + + TRACE("surface %p, container %p.\n", surface, surface->container); + + return wined3d_texture_decref(surface->container); } static void surface_unload(struct wined3d_resource *resource) @@ -1562,6 +1562,12 @@ && box->bottom == surface->resource.height) return TRUE; + if ((box->left >= box->right) + || (box->top >= box->bottom) + || (box->right > surface->resource.width) + || (box->bottom > surface->resource.height)) + return FALSE; + /* This assumes power of two block sizes, but NPOT block sizes would be * silly anyway. */ width_mask = surface->resource.format->block_width - 1; @@ -1877,33 +1883,6 @@ return ret; } -ULONG CDECL wined3d_surface_incref(struct wined3d_surface *surface) -{ - TRACE("surface %p, container %p.\n", surface, surface->container); - - return wined3d_texture_incref(surface->container); -} - -ULONG CDECL wined3d_surface_decref(struct wined3d_surface *surface) -{ - TRACE("surface %p, container %p.\n", surface, surface->container); - - return wined3d_texture_decref(surface->container); -} - -void CDECL wined3d_surface_preload(struct wined3d_surface *surface) -{ - TRACE("surface %p.\n", surface); - - if (!surface->resource.device->d3d_initialized) - { - ERR("D3D not initialized.\n"); - return; - } - - wined3d_texture_preload(surface->container); -} - void * CDECL wined3d_surface_get_parent(const struct wined3d_surface *surface) { TRACE("surface %p.\n", surface); @@ -1911,13 +1890,6 @@ return surface->resource.parent; } -struct wined3d_resource * CDECL wined3d_surface_get_resource(struct wined3d_surface *surface) -{ - TRACE("surface %p.\n", surface); - - return &surface->resource; -} - DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface) { unsigned int alignment; @@ -2358,12 +2330,13 @@ /* FIXME: Multisampled conversion? */ wined3d_resource_get_desc(&source->resource, &desc); - desc.resource_type = WINED3D_RTYPE_TEXTURE; + desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = to_fmt; desc.usage = 0; desc.pool = WINED3D_POOL_SCRATCH; if (FAILED(wined3d_texture_create(source->resource.device, &desc, 1, - WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_DISCARD, NULL, NULL, &wined3d_null_parent_ops, &ret))) + WINED3D_TEXTURE_CREATE_MAPPABLE | WINED3D_TEXTURE_CREATE_DISCARD, + NULL, NULL, &wined3d_null_parent_ops, &ret))) { ERR("Failed to create a destination surface for conversion.\n"); return NULL; @@ -2454,12 +2427,7 @@ return WINED3D_OK; } -struct wined3d_surface * CDECL wined3d_surface_from_resource(struct wined3d_resource *resource) -{ - return surface_from_resource(resource); -} - -HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface) +HRESULT wined3d_surface_unmap(struct wined3d_surface *surface) { TRACE("surface %p.\n", surface); @@ -2475,8 +2443,8 @@ return WINED3D_OK; } -HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) +HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, + const struct wined3d_box *box, DWORD flags) { const struct wined3d_format *format = surface->resource.format; unsigned int fmt_flags = surface->container->resource.format_flags; @@ -2485,8 +2453,8 @@ const struct wined3d_gl_info *gl_info; BYTE *base_memory; - TRACE("surface %p, map_desc %p, box %p, flags %#x.\n", - surface, map_desc, box, flags); + TRACE("surface %p, map_desc %p, box %s, flags %#x.\n", + surface, map_desc, debug_box(box), flags); if (surface->resource.map_count) { @@ -2497,8 +2465,8 @@ if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box && !surface_check_block_align(surface, box)) { - WARN("Map rect %p is misaligned for %ux%u blocks.\n", - box, format->block_width, format->block_height); + WARN("Map box %s is misaligned for %ux%u blocks.\n", + debug_box(box), format->block_width, format->block_height); if (surface->resource.pool == WINED3D_POOL_DEFAULT) return WINED3DERR_INVALIDCALL; @@ -2621,104 +2589,6 @@ return WINED3D_OK; } -HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) -{ - HRESULT hr; - struct wined3d_device *device = surface->resource.device; - struct wined3d_context *context = NULL; - - TRACE("surface %p, dc %p.\n", surface, dc); - - /* Give more detailed info for ddraw. */ - if (surface->flags & SFLAG_DCINUSE) - return WINEDDERR_DCALREADYCREATED; - - /* Can't GetDC if the surface is locked. */ - if (surface->resource.map_count) - return WINED3DERR_INVALIDCALL; - - if (device->d3d_initialized) - context = context_acquire(surface->resource.device, NULL); - - /* Create a DIB section if there isn't a dc yet. */ - if (!surface->hDC) - { - if (surface->flags & SFLAG_CLIENT) - { - surface_load_location(surface, context, WINED3D_LOCATION_SYSMEM); - surface_release_client_storage(surface); - } - hr = surface_create_dib_section(surface); - if (FAILED(hr)) - { - if (context) - context_release(context); - return WINED3DERR_INVALIDCALL; - } - if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY - || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM - || surface->pbo)) - surface->resource.map_binding = WINED3D_LOCATION_DIB; - } - - surface_load_location(surface, context, WINED3D_LOCATION_DIB); - surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB); - - if (context) - context_release(context); - - surface->flags |= SFLAG_DCINUSE; - surface->resource.map_count++; - - *dc = surface->hDC; - TRACE("Returning dc %p.\n", *dc); - - return WINED3D_OK; -} - -HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) -{ - TRACE("surface %p, dc %p.\n", surface, dc); - - if (!(surface->flags & SFLAG_DCINUSE)) - return WINEDDERR_NODC; - - if (surface->hDC != dc) - { - WARN("Application tries to release invalid DC %p, surface DC is %p.\n", - dc, surface->hDC); - return WINEDDERR_NODC; - } - - surface->resource.map_count--; - surface->flags &= ~SFLAG_DCINUSE; - - if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY - || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM - && surface->resource.map_binding != WINED3D_LOCATION_DIB)) - { - /* The game Salammbo modifies the surface contents without mapping the surface between - * a GetDC/ReleaseDC operation and flipping the surface. If the DIB remains the active - * copy and is copied to the screen, this update, which draws the mouse pointer, is lost. - * Do not only copy the DIB to the map location, but also make sure the map location is - * copied back to the DIB in the next getdc call. - * - * The same consideration applies to user memory surfaces. */ - struct wined3d_device *device = surface->resource.device; - struct wined3d_context *context = NULL; - - if (device->d3d_initialized) - context = context_acquire(device, NULL); - - surface_load_location(surface, context, surface->resource.map_binding); - surface_invalidate_location(surface, WINED3D_LOCATION_DIB); - if (context) - context_release(context); - } - - return WINED3D_OK; -} - static void read_from_framebuffer(struct wined3d_surface *surface, struct wined3d_context *old_ctx, DWORD dst_location) { @@ -2886,10 +2756,28 @@ * * AMD has a similar feature called Enhanced Quality Anti-Aliasing (EQAA), * but it does not have an equivalent OpenGL extension. */ + + /* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality levels + * as the count of advertised multisample types for the surface format. */ if (surface->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE) - samples = surface->resource.multisample_quality; + { + const struct wined3d_format *format = surface->resource.format; + unsigned int i, count = 0; + + for (i = 0; i < sizeof(format->multisample_types) * 8; ++i) + { + if (format->multisample_types & 1u << i) + { + if (surface->resource.multisample_quality == count++) + break; + } + } + samples = i + 1; + } else + { samples = surface->resource.multisample_type; + } gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_multisample); gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_multisample); @@ -3403,18 +3291,35 @@ HRESULT surface_color_fill(struct wined3d_surface *s, const RECT *rect, const struct wined3d_color *color) { - struct wined3d_device *device = s->resource.device; + struct wined3d_resource *resource = &s->container->resource; + struct wined3d_device *device = resource->device; + struct wined3d_rendertarget_view_desc view_desc; + struct wined3d_rendertarget_view *view; const struct blit_shader *blitter; + HRESULT hr; - blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, WINED3D_BLIT_OP_COLOR_FILL, - NULL, 0, 0, NULL, rect, s->resource.usage, s->resource.pool, s->resource.format); - if (!blitter) + if (!(blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, + WINED3D_BLIT_OP_COLOR_FILL, NULL, 0, 0, NULL, rect, resource->usage, resource->pool, resource->format))) { FIXME("No blitter is capable of performing the requested color fill operation.\n"); return WINED3DERR_INVALIDCALL; } - return blitter->color_fill(device, s, rect, color); + view_desc.format_id = resource->format->id; + view_desc.u.texture.level_idx = s->texture_level; + view_desc.u.texture.layer_idx = s->texture_layer; + view_desc.u.texture.layer_count = 1; + if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, + resource, NULL, &wined3d_null_parent_ops, &view))) + { + ERR("Failed to create rendertarget view, hr %#x.\n", hr); + return hr; + } + + hr = blitter->color_fill(device, view, rect, color); + wined3d_rendertarget_view_decref(view); + + return hr; } static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RECT *dst_rect, @@ -3661,10 +3566,10 @@ return; } + wined3d_surface_prepare(surface, context, location); if (surface->locations & WINED3D_LOCATION_DISCARDED) { TRACE("Surface was discarded, no need copy data.\n"); - wined3d_surface_prepare(surface, context, location); surface->locations &= ~WINED3D_LOCATION_DISCARDED; surface->locations |= location; surface->ds_current_size.cx = surface->resource.width; @@ -4279,43 +4184,24 @@ } } -static HRESULT ffp_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface, - const RECT *dst_rect, const struct wined3d_color *color) +static HRESULT ffp_blit_color_fill(struct wined3d_device *device, struct wined3d_rendertarget_view *view, + const RECT *rect, const struct wined3d_color *color) { - const RECT draw_rect = {0, 0, dst_surface->resource.width, dst_surface->resource.height}; - struct wined3d_rendertarget_view *view; + const RECT draw_rect = {0, 0, view->width, view->height}; struct wined3d_fb_state fb = {&view, NULL}; - HRESULT hr; - if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(dst_surface, - NULL, &wined3d_null_parent_ops, &view))) - { - ERR("Failed to create rendertarget view, hr %#x.\n", hr); - return hr; - } - - device_clear_render_targets(device, 1, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0); - wined3d_rendertarget_view_decref(view); + device_clear_render_targets(device, 1, &fb, 1, rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0); return WINED3D_OK; } -static HRESULT ffp_blit_depth_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface, - const RECT *dst_rect, float depth) +static HRESULT ffp_blit_depth_fill(struct wined3d_device *device, + struct wined3d_rendertarget_view *view, const RECT *rect, float depth) { - const RECT draw_rect = {0, 0, dst_surface->resource.width, dst_surface->resource.height}; - struct wined3d_fb_state fb = {NULL, NULL}; - HRESULT hr; - - if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(dst_surface, - NULL, &wined3d_null_parent_ops, &fb.depth_stencil))) - { - ERR("Failed to create rendertarget view, hr %#x.\n", hr); - return hr; - } + const RECT draw_rect = {0, 0, view->width, view->height}; + struct wined3d_fb_state fb = {NULL, view}; - device_clear_render_targets(device, 0, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_ZBUFFER, 0, depth, 0); - wined3d_rendertarget_view_decref(fb.depth_stencil); + device_clear_render_targets(device, 0, &fb, 1, rect, &draw_rect, WINED3DCLEAR_ZBUFFER, 0, depth, 0); return WINED3D_OK; } @@ -4989,21 +4875,22 @@ return hr; } -static HRESULT cpu_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface, - const RECT *dst_rect, const struct wined3d_color *color) +static HRESULT cpu_blit_color_fill(struct wined3d_device *device, struct wined3d_rendertarget_view *view, + const RECT *rect, const struct wined3d_color *color) { + struct wined3d_surface *surface = wined3d_rendertarget_view_get_surface(view); static const RECT src_rect; WINEDDBLTFX BltFx; memset(&BltFx, 0, sizeof(BltFx)); BltFx.dwSize = sizeof(BltFx); - BltFx.u5.dwFillColor = wined3d_format_convert_from_float(dst_surface, color); - return surface_cpu_blt(dst_surface, dst_rect, NULL, &src_rect, + BltFx.u5.dwFillColor = wined3d_format_convert_from_float(surface, color); + return surface_cpu_blt(surface, rect, NULL, &src_rect, WINEDDBLT_COLORFILL, &BltFx, WINED3D_TEXF_POINT); } static HRESULT cpu_blit_depth_fill(struct wined3d_device *device, - struct wined3d_surface *surface, const RECT *rect, float depth) + struct wined3d_rendertarget_view *view, const RECT *rect, float depth) { FIXME("Depth filling not implemented by cpu_blit.\n"); return WINED3DERR_INVALIDCALL; @@ -5029,14 +4916,13 @@ cpu_blit_blit_surface, }; -HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect_in, - struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, +HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, + struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) { struct wined3d_swapchain *src_swapchain, *dst_swapchain; struct wined3d_device *device = dst_surface->resource.device; DWORD src_ds_flags, dst_ds_flags; - RECT src_rect, dst_rect; BOOL scale, convert; static const DWORD simple_blit = WINEDDBLT_ASYNC @@ -5048,8 +4934,8 @@ | WINEDDBLT_DONOTWAIT | WINEDDBLT_ALPHATEST; - TRACE("dst_surface %p, dst_rect_in %s, src_surface %p, src_rect_in %s, flags %#x, fx %p, filter %s.\n", - dst_surface, wine_dbgstr_rect(dst_rect_in), src_surface, wine_dbgstr_rect(src_rect_in), + TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", + dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter)); TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage)); @@ -5090,13 +4976,11 @@ return WINEDDERR_SURFACEBUSY; } - surface_get_rect(dst_surface, dst_rect_in, &dst_rect); - - if (dst_rect.left >= dst_rect.right || dst_rect.top >= dst_rect.bottom - || dst_rect.left > dst_surface->resource.width || dst_rect.left < 0 - || dst_rect.top > dst_surface->resource.height || dst_rect.top < 0 - || dst_rect.right > dst_surface->resource.width || dst_rect.right < 0 - || dst_rect.bottom > dst_surface->resource.height || dst_rect.bottom < 0) + if (dst_rect->left >= dst_rect->right || dst_rect->top >= dst_rect->bottom + || dst_rect->left > dst_surface->resource.width || dst_rect->left < 0 + || dst_rect->top > dst_surface->resource.height || dst_rect->top < 0 + || dst_rect->right > dst_surface->resource.width || dst_rect->right < 0 + || dst_rect->bottom > dst_surface->resource.height || dst_rect->bottom < 0) { WARN("The application gave us a bad destination rectangle.\n"); return WINEDDERR_INVALIDRECT; @@ -5104,22 +4988,16 @@ if (src_surface) { - surface_get_rect(src_surface, src_rect_in, &src_rect); - - if (src_rect.left >= src_rect.right || src_rect.top >= src_rect.bottom - || src_rect.left > src_surface->resource.width || src_rect.left < 0 - || src_rect.top > src_surface->resource.height || src_rect.top < 0 - || src_rect.right > src_surface->resource.width || src_rect.right < 0 - || src_rect.bottom > src_surface->resource.height || src_rect.bottom < 0) + if (src_rect->left >= src_rect->right || src_rect->top >= src_rect->bottom + || src_rect->left > src_surface->resource.width || src_rect->left < 0 + || src_rect->top > src_surface->resource.height || src_rect->top < 0 + || src_rect->right > src_surface->resource.width || src_rect->right < 0 + || src_rect->bottom > src_surface->resource.height || src_rect->bottom < 0) { - WARN("Application gave us bad source rectangle for Blt.\n"); + WARN("The application gave us a bad source rectangle.\n"); return WINEDDERR_INVALIDRECT; } } - else - { - memset(&src_rect, 0, sizeof(src_rect)); - } if (!fx || !(fx->dwDDFX)) flags &= ~WINEDDBLT_DDFX; @@ -5188,8 +5066,8 @@ } scale = src_surface - && (src_rect.right - src_rect.left != dst_rect.right - dst_rect.left - || src_rect.bottom - src_rect.top != dst_rect.bottom - dst_rect.top); + && (src_rect->right - src_rect->left != dst_rect->right - dst_rect->left + || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top); convert = src_surface && src_surface->resource.format->id != dst_surface->resource.format->id; dst_ds_flags = dst_surface->container->resource.format_flags @@ -5211,7 +5089,7 @@ if (!surface_convert_depth_to_float(dst_surface, fx->u5.dwFillDepth, &depth)) return WINED3DERR_INVALIDCALL; - if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, &dst_rect, depth))) + if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, dst_rect, depth))) return WINED3D_OK; } else @@ -5223,7 +5101,7 @@ } if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->container->resource.draw_binding, - &src_rect, dst_surface, dst_surface->container->resource.draw_binding, &dst_rect))) + src_rect, dst_surface, dst_surface->container->resource.draw_binding, dst_rect))) return WINED3D_OK; } } @@ -5255,7 +5133,7 @@ palette, fx->u5.dwFillColor, &color)) goto fallback; - if (SUCCEEDED(surface_color_fill(dst_surface, &dst_rect, &color))) + if (SUCCEEDED(surface_color_fill(dst_surface, dst_rect, &color))) return WINED3D_OK; } else @@ -5288,9 +5166,9 @@ TRACE("Not doing upload because of format conversion.\n"); else { - POINT dst_point = {dst_rect.left, dst_rect.top}; + POINT dst_point = {dst_rect->left, dst_rect->top}; - if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, &src_rect))) + if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, src_rect))) { if (!wined3d_resource_is_offscreen(&dst_surface->container->resource)) { @@ -5326,16 +5204,16 @@ } if (fbo_blit_supported(&device->adapter->gl_info, blit_op, - &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, - &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format)) + src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, + dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format)) { struct wined3d_context *context; TRACE("Using FBO blit.\n"); context = context_acquire(device, NULL); surface_blt_fbo(device, context, filter, - src_surface, src_surface->container->resource.draw_binding, &src_rect, - dst_surface, dst_surface->container->resource.draw_binding, &dst_rect); + src_surface, src_surface->container->resource.draw_binding, src_rect, + dst_surface, dst_surface->container->resource.draw_binding, dst_rect); context_release(context); surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); @@ -5345,12 +5223,12 @@ } blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, blit_op, - &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, - &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format); + src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, + dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format); if (blitter) { blitter->blit_surface(device, blit_op, filter, src_surface, - &src_rect, dst_surface, &dst_rect, color_key); + src_rect, dst_surface, dst_rect, color_key); return WINED3D_OK; } } @@ -5358,15 +5236,11 @@ fallback: /* Special cases for render targets. */ - if (SUCCEEDED(surface_blt_special(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter))) + if (SUCCEEDED(surface_blt_special(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter))) return WINED3D_OK; cpu: - - /* For the rest call the X11 surface implementation. For render targets - * this should be implemented OpenGL accelerated in surface_blt_special(), - * other blits are rather rare. */ - return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter); + return surface_cpu_blt(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter); } static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_texture *container, @@ -5375,8 +5249,8 @@ struct wined3d_device *device = container->resource.device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format); + BOOL lockable = flags & WINED3D_TEXTURE_CREATE_MAPPABLE; UINT multisample_quality = desc->multisample_quality; - BOOL lockable = flags & WINED3D_SURFACE_MAPPABLE; unsigned int resource_size; HRESULT hr; @@ -5434,7 +5308,7 @@ list_init(&surface->overlays); /* Flags */ - if (flags & WINED3D_SURFACE_DISCARD) + if (flags & WINED3D_TEXTURE_CREATE_DISCARD) surface->flags |= SFLAG_DISCARD; if (lockable || desc->format == WINED3DFMT_D16_LOCKABLE) surface->resource.access_flags |= WINED3D_RESOURCE_ACCESS_CPU; @@ -5453,7 +5327,7 @@ /* Similar to lockable rendertargets above, creating the DIB section * during surface initialization prevents the sysmem pointer from changing - * after a wined3d_surface_getdc() call. */ + * after a wined3d_texture_get_dc() call. */ if ((desc->usage & WINED3DUSAGE_OWNDC) && !surface->hDC && SUCCEEDED(surface_create_dib_section(surface))) surface->resource.map_binding = WINED3D_LOCATION_DIB; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/swapchain.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/swapchain.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/swapchain.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/swapchain.c 2016-02-08 19:32:34.000000000 +0000 @@ -821,7 +821,7 @@ TRACE("Creating front buffer.\n"); - texture_desc.resource_type = WINED3D_RTYPE_TEXTURE; + texture_desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; texture_desc.format = swapchain->desc.backbuffer_format; texture_desc.multisample_type = swapchain->desc.multisample_type; texture_desc.multisample_quality = swapchain->desc.multisample_quality; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/texture.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/texture.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/texture.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/texture.c 2016-02-08 19:32:34.000000000 +0000 @@ -28,7 +28,7 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops, - UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, DWORD surface_flags, + UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, DWORD flags, struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops) { @@ -37,11 +37,11 @@ TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, " "multisample_type %#x, multisample_quality %#x, usage %s, pool %s, width %u, height %u, depth %u, " - "surface_flags %#x, device %p, parent %p, parent_ops %p, resource_ops %p.\n", + "flags %#x, device %p, parent %p, parent_ops %p, resource_ops %p.\n", texture, texture_ops, layer_count, level_count, debug_d3dresourcetype(desc->resource_type), debug_d3dformat(desc->format), desc->multisample_type, desc->multisample_quality, debug_d3dusage(desc->usage), debug_d3dpool(desc->pool), desc->width, desc->height, desc->depth, - surface_flags, device, parent, parent_ops, resource_ops); + flags, device, parent, parent_ops, resource_ops); if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format, desc->multisample_type, desc->multisample_quality, desc->usage, desc->pool, @@ -53,7 +53,7 @@ if ((desc->format == WINED3DFMT_DXT1 || desc->format == WINED3DFMT_DXT2 || desc->format == WINED3DFMT_DXT3 || desc->format == WINED3DFMT_DXT4 || desc->format == WINED3DFMT_DXT5) && !(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE) - && desc->resource_type != WINED3D_RTYPE_VOLUME_TEXTURE && !once++) + && desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !once++) ERR_(winediag)("The application tried to create a DXTn texture, but the driver does not support them.\n"); WARN("Failed to initialize resource, returning %#x\n", hr); @@ -76,7 +76,7 @@ texture->filter_type = (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3D_TEXF_LINEAR : WINED3D_TEXF_NONE; texture->lod = 0; texture->flags = WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS; - if (surface_flags & WINED3D_SURFACE_PIN_SYSMEM) + if (flags & WINED3D_TEXTURE_CREATE_PIN_SYSMEM) texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM; return WINED3D_OK; @@ -610,9 +610,9 @@ return WINED3DERR_INVALIDCALL; } - if (texture->resource.type == WINED3D_RTYPE_VOLUME_TEXTURE) + if (texture->resource.type == WINED3D_RTYPE_TEXTURE_3D) { - WARN("Not supported on volume textures.\n"); + WARN("Not supported on 3D textures.\n"); return WINED3DERR_INVALIDCALL; } @@ -691,7 +691,7 @@ FIXME("texture %p stub!\n", texture); } -struct wined3d_resource * CDECL wined3d_texture_get_sub_resource(struct wined3d_texture *texture, +struct wined3d_resource * CDECL wined3d_texture_get_sub_resource(const struct wined3d_texture *texture, UINT sub_resource_idx) { UINT sub_count = texture->level_count * texture->layer_count; @@ -712,7 +712,7 @@ { struct wined3d_resource *sub_resource; - TRACE("texture %p, layer %u, dirty_region %p.\n", texture, layer, dirty_region); + TRACE("texture %p, layer %u, dirty_region %s.\n", texture, layer, debug_box(dirty_region)); if (!(sub_resource = wined3d_texture_get_sub_resource(texture, layer * texture->level_count))) { @@ -863,7 +863,6 @@ struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[i]); GLsizei height = surface->pow2Height; GLsizei width = surface->pow2Width; - const BYTE *mem = NULL; if (texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE) { @@ -874,48 +873,9 @@ TRACE("surface %p, target %#x, level %d, width %d, height %d.\n", surface, surface->texture_target, surface->texture_level, width, height); - if (gl_info->supported[APPLE_CLIENT_STORAGE]) - { - if (surface->flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION) - || texture->flags & WINED3D_TEXTURE_CONVERTED - || !surface->resource.heap_memory) - { - /* In some cases we want to disable client storage. - * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches - * SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues... - * WINED3D_TEXTURE_CONVERTED: The conversion destination memory is freed after loading the surface - * heap_memory == NULL: Not defined in the extension. Seems to disable client storage effectively - */ - surface->flags &= ~SFLAG_CLIENT; - } - else - { - surface->flags |= SFLAG_CLIENT; - mem = surface->resource.heap_memory; - - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); - checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)"); - } - } - - if (texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED && mem) - { - GL_EXTCALL(glCompressedTexImage2D(surface->texture_target, surface->texture_level, - internal, width, height, 0, surface->resource.size, mem)); - checkGLcall("glCompressedTexImage2D"); - } - else - { - gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, - internal, width, height, 0, format->glFormat, format->glType, mem); - checkGLcall("glTexImage2D"); - } - - if (mem) - { - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); - checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)"); - } + gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, + internal, width, height, 0, format->glFormat, format->glType, NULL); + checkGLcall("glTexImage2D"); } } @@ -989,119 +949,15 @@ texture2d_resource_sub_resource_unmap, }; -static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, - UINT levels, DWORD surface_flags, struct wined3d_device *device, void *parent, - const struct wined3d_parent_ops *parent_ops) -{ - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_resource_desc surface_desc; - unsigned int i, j; - HRESULT hr; - - /* TODO: It should only be possible to create textures for formats - * that are reported as supported. */ - if (WINED3DFMT_UNKNOWN >= desc->format) - { - WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); - return WINED3DERR_INVALIDCALL; - } - - /* Calculate levels for mip mapping */ - if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) - { - if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (levels != 1) - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - } - - if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) - { - UINT pow2_edge_length = 1; - while (pow2_edge_length < desc->width) - pow2_edge_length <<= 1; - - if (desc->width != pow2_edge_length) - { - if (desc->pool == WINED3D_POOL_SCRATCH) - { - /* SCRATCH textures cannot be used for texturing */ - WARN("Creating a scratch NPOT cube texture despite lack of HW support.\n"); - } - else - { - WARN("Attempted to create a NPOT cube texture (edge length %u) without GL support.\n", desc->width); - return WINED3DERR_INVALIDCALL; - } - } - } - - if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels, desc, - surface_flags, device, parent, parent_ops, &texture2d_resource_ops))) - { - WARN("Failed to initialize texture, returning %#x\n", hr); - return hr; - } - - texture->pow2_matrix[0] = 1.0f; - texture->pow2_matrix[5] = 1.0f; - texture->pow2_matrix[10] = 1.0f; - texture->pow2_matrix[15] = 1.0f; - texture->target = GL_TEXTURE_CUBE_MAP_ARB; - - /* Generate all the surfaces. */ - surface_desc = *desc; - surface_desc.resource_type = WINED3D_RTYPE_SURFACE; - for (i = 0; i < texture->level_count; ++i) - { - /* Create the 6 faces. */ - for (j = 0; j < 6; ++j) - { - static const GLenum cube_targets[6] = - { - GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, - GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, - }; - UINT idx = j * texture->level_count + i; - struct wined3d_surface *surface; - - if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, - cube_targets[j], i, j, surface_flags, &surface))) - { - WARN("Failed to create surface, hr %#x.\n", hr); - wined3d_texture_cleanup(texture); - return hr; - } - - texture->sub_resources[idx] = &surface->resource; - TRACE("Created surface level %u @ %p.\n", i, surface); - } - surface_desc.width = max(1, surface_desc.width >> 1); - surface_desc.height = surface_desc.width; - } - - return WINED3D_OK; -} - static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, - UINT levels, DWORD surface_flags, struct wined3d_device *device, void *parent, + UINT level_count, DWORD flags, struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops) { + unsigned int layer_count = desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP ? 6 : 1; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_resource_desc surface_desc; UINT pow2_width, pow2_height; - unsigned int i; + unsigned int i, j; HRESULT hr; /* TODO: It should only be possible to create textures for formats @@ -1129,16 +985,16 @@ if (pow2_width != desc->width || pow2_height != desc->height) { - /* levels == 0 returns an error as well */ - if (levels != 1) + /* level_count == 0 returns an error as well */ + if (level_count != 1 || desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) { if (desc->pool == WINED3D_POOL_SCRATCH) { - WARN("Creating a scratch mipmapped NPOT texture despite lack of HW support.\n"); + WARN("Creating a scratch mipmapped/cube NPOT texture despite lack of HW support.\n"); } else { - WARN("Attempted to create a mipmapped NPOT texture without unconditional NPOT support.\n"); + WARN("Attempted to create a mipmapped/cube NPOT texture without unconditional NPOT support.\n"); return WINED3DERR_INVALIDCALL; } } @@ -1154,15 +1010,15 @@ return WINED3DERR_INVALIDCALL; } - if (levels != 1) + if (level_count != 1) { WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); return WINED3DERR_INVALIDCALL; } } - if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels, desc, - surface_flags, device, parent, parent_ops, &texture2d_resource_ops))) + if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc, + flags, device, parent, parent_ops, &texture2d_resource_ops))) { WARN("Failed to initialize texture, returning %#x.\n", hr); return hr; @@ -1181,7 +1037,10 @@ } else { - texture->target = GL_TEXTURE_2D; + if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) + texture->target = GL_TEXTURE_CUBE_MAP_ARB; + else + texture->target = GL_TEXTURE_2D; if (desc->width == pow2_width && desc->height == pow2_height) { texture->pow2_matrix[0] = 1.0f; @@ -1209,18 +1068,32 @@ surface_desc.resource_type = WINED3D_RTYPE_SURFACE; for (i = 0; i < texture->level_count; ++i) { - struct wined3d_surface *surface; - - if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, - texture->target, i, 0, surface_flags, &surface))) + for (j = 0; j < texture->layer_count; ++j) { - WARN("Failed to create surface, hr %#x.\n", hr); - wined3d_texture_cleanup(texture); - return hr; - } + static const GLenum cube_targets[6] = + { + GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, + }; + GLenum target = desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP ? cube_targets[j] : texture->target; + unsigned int idx = j * texture->level_count + i; + struct wined3d_surface *surface; - texture->sub_resources[i] = &surface->resource; - TRACE("Created surface level %u @ %p.\n", i, surface); + if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, + target, i, j, flags, &surface))) + { + WARN("Failed to create surface, hr %#x.\n", hr); + wined3d_texture_cleanup(texture); + return hr; + } + + texture->sub_resources[idx] = &surface->resource; + TRACE("Created surface level %u @ %p.\n", i, surface); + } /* Calculate the next mipmap level. */ surface_desc.width = max(1, surface_desc.width >> 1); surface_desc.height = max(1, surface_desc.height >> 1); @@ -1291,29 +1164,12 @@ for (i = 0; i < sub_count; ++i) { struct wined3d_volume *volume = volume_from_resource(texture->sub_resources[i]); - void *mem = NULL; - - if (gl_info->supported[APPLE_CLIENT_STORAGE] && !format->convert - && volume_prepare_system_memory(volume)) - { - TRACE("Enabling GL_UNPACK_CLIENT_STORAGE_APPLE for volume %p\n", volume); - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); - checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)"); - mem = volume->resource.heap_memory; - volume->flags |= WINED3D_VFLAG_CLIENT_STORAGE; - } GL_EXTCALL(glTexImage3D(GL_TEXTURE_3D, volume->texture_level, srgb ? format->glGammaInternal : format->glInternal, volume->resource.width, volume->resource.height, volume->resource.depth, - 0, format->glFormat, format->glType, mem)); + 0, format->glFormat, format->glType, NULL)); checkGLcall("glTexImage3D"); - - if (mem) - { - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); - checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)"); - } } } @@ -1462,14 +1318,16 @@ return WINED3D_OK; } -HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect_in, - struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, const RECT *src_rect_in, DWORD flags, - const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) +HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, + const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, + const RECT *src_rect, DWORD flags, const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) { struct wined3d_resource *dst_resource, *src_resource = NULL; - TRACE("dst_texture %p, dst_sub_resource_idx %u, src_texture %p, src_sub_resource_idx %u.\n", - dst_texture, dst_sub_resource_idx, src_texture, src_sub_resource_idx); + TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_rect %s, src_texture %p, " + "src_sub_resource_idx %u, src_rect %s, flags %#x, fx %p, filter %s.\n", + dst_texture, dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), src_texture, + src_sub_resource_idx, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter)); if (!(dst_resource = wined3d_texture_get_sub_resource(dst_texture, dst_sub_resource_idx)) || dst_resource->type != WINED3D_RTYPE_SURFACE) @@ -1482,19 +1340,19 @@ return WINED3DERR_INVALIDCALL; } - return wined3d_surface_blt(surface_from_resource(dst_resource), dst_rect_in, - src_resource ? surface_from_resource(src_resource) : NULL, src_rect_in, flags, fx, filter); + return wined3d_surface_blt(surface_from_resource(dst_resource), dst_rect, + src_resource ? surface_from_resource(src_resource) : NULL, src_rect, flags, fx, filter); } HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc, - UINT level_count, DWORD surface_flags, const struct wined3d_sub_resource_data *data, void *parent, + UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) { struct wined3d_texture *object; HRESULT hr; - TRACE("device %p, desc %p, level_count %u, surface_flags %#x, data %p, parent %p, parent_ops %p, texture %p.\n", - device, desc, level_count, surface_flags, data, parent, parent_ops, texture); + TRACE("device %p, desc %p, level_count %u, flags %#x, data %p, parent %p, parent_ops %p, texture %p.\n", + device, desc, level_count, flags, data, parent, parent_ops, texture); if (!level_count) { @@ -1502,23 +1360,40 @@ return WINED3DERR_INVALIDCALL; } + if (desc->multisample_type != WINED3D_MULTISAMPLE_NONE) + { + const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, desc->format); + + if (desc->multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE + && desc->multisample_quality >= wined3d_popcount(format->multisample_types)) + { + WARN("Unsupported quality level %u requested for WINED3D_MULTISAMPLE_NON_MASKABLE.\n", + desc->multisample_quality); + return WINED3DERR_NOTAVAILABLE; + } + if (desc->multisample_type != WINED3D_MULTISAMPLE_NON_MASKABLE + && (!(format->multisample_types & 1u << (desc->multisample_type - 1)) + || desc->multisample_quality)) + { + WARN("Unsupported multisample type %u quality %u requested.\n", desc->multisample_type, + desc->multisample_quality); + return WINED3DERR_NOTAVAILABLE; + } + } + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY; switch (desc->resource_type) { - case WINED3D_RTYPE_TEXTURE: - hr = texture_init(object, desc, level_count, surface_flags, device, parent, parent_ops); + case WINED3D_RTYPE_TEXTURE_2D: + hr = texture_init(object, desc, level_count, flags, device, parent, parent_ops); break; - case WINED3D_RTYPE_VOLUME_TEXTURE: + case WINED3D_RTYPE_TEXTURE_3D: hr = volumetexture_init(object, desc, level_count, device, parent, parent_ops); break; - case WINED3D_RTYPE_CUBE_TEXTURE: - hr = cubetexture_init(object, desc, level_count, surface_flags, device, parent, parent_ops); - break; - default: ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type)); hr = WINED3DERR_INVALIDCALL; @@ -1549,7 +1424,11 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc) { + struct wined3d_device *device = texture->resource.device; + struct wined3d_context *context = NULL; struct wined3d_resource *sub_resource; + struct wined3d_surface *surface; + HRESULT hr; TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc); @@ -1562,12 +1441,55 @@ return WINED3DERR_INVALIDCALL; } - return wined3d_surface_getdc(surface_from_resource(sub_resource), dc); + surface = surface_from_resource(sub_resource); + + /* Give more detailed info for ddraw. */ + if (surface->flags & SFLAG_DCINUSE) + return WINEDDERR_DCALREADYCREATED; + + /* Can't GetDC if the surface is locked. */ + if (surface->resource.map_count) + return WINED3DERR_INVALIDCALL; + + if (device->d3d_initialized) + context = context_acquire(device, NULL); + + /* Create a DIB section if there isn't a dc yet. */ + if (!surface->hDC) + { + if (FAILED(hr = surface_create_dib_section(surface))) + { + if (context) + context_release(context); + return WINED3DERR_INVALIDCALL; + } + if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY + || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM + || surface->pbo)) + surface->resource.map_binding = WINED3D_LOCATION_DIB; + } + + surface_load_location(surface, context, WINED3D_LOCATION_DIB); + surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB); + + if (context) + context_release(context); + + surface->flags |= SFLAG_DCINUSE; + surface->resource.map_count++; + + *dc = surface->hDC; + TRACE("Returning dc %p.\n", *dc); + + return WINED3D_OK; } HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc) { + struct wined3d_device *device = texture->resource.device; + struct wined3d_context *context = NULL; struct wined3d_resource *sub_resource; + struct wined3d_surface *surface; TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc); @@ -1580,5 +1502,41 @@ return WINED3DERR_INVALIDCALL; } - return wined3d_surface_releasedc(surface_from_resource(sub_resource), dc); + surface = surface_from_resource(sub_resource); + + if (!(surface->flags & SFLAG_DCINUSE)) + return WINEDDERR_NODC; + + if (surface->hDC != dc) + { + WARN("Application tries to release invalid DC %p, surface DC is %p.\n", + dc, surface->hDC); + return WINEDDERR_NODC; + } + + surface->resource.map_count--; + surface->flags &= ~SFLAG_DCINUSE; + + if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY + || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM + && surface->resource.map_binding != WINED3D_LOCATION_DIB)) + { + /* The game Salammbo modifies the surface contents without mapping the surface between + * a GetDC/ReleaseDC operation and flipping the surface. If the DIB remains the active + * copy and is copied to the screen, this update, which draws the mouse pointer, is lost. + * Do not only copy the DIB to the map location, but also make sure the map location is + * copied back to the DIB in the next getdc call. + * + * The same consideration applies to user memory surfaces. */ + + if (device->d3d_initialized) + context = context_acquire(device, NULL); + + surface_load_location(surface, context, surface->resource.map_binding); + surface_invalidate_location(surface, WINED3D_LOCATION_DIB); + if (context) + context_release(context); + } + + return WINED3D_OK; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/utils.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/utils.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/utils.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/utils.c 2016-02-08 19:32:34.000000000 +0000 @@ -57,6 +57,9 @@ {WINED3DFMT_DXT3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_DXT4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_DXT5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, + {WINED3DFMT_BC1_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, + {WINED3DFMT_BC2_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, + {WINED3DFMT_BC3_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_MULTI2_ARGB8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, @@ -95,10 +98,13 @@ {WINED3DFMT_R8G8B8A8_UNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0}, {WINED3DFMT_R8G8B8A8_UNORM_SRGB, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0}, {WINED3DFMT_R8G8B8A8_UINT, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0}, + {WINED3DFMT_R8G8B8A8_SINT, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0}, {WINED3DFMT_R8G8B8X8_UNORM, 8, 8, 8, 0, 0, 8, 16, 0, 4, 0, 0}, {WINED3DFMT_R16G16_UNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0}, {WINED3DFMT_B10G10R10A2_UNORM, 10, 10, 10, 2, 20, 10, 0, 30, 4, 0, 0}, {WINED3DFMT_R16G16B16A16_UNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0}, + {WINED3DFMT_R8G8_UNORM, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0}, + {WINED3DFMT_R16_UNORM, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0}, /* Luminance */ {WINED3DFMT_L8_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_L8A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0}, @@ -188,6 +194,8 @@ {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT}, {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT}, {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT}, + {WINED3DFMT_R8G8B8A8_UINT, WINED3DFMT_FLAG_INTEGER}, + {WINED3DFMT_R8G8B8A8_SINT, WINED3DFMT_FLAG_INTEGER}, }; struct wined3d_format_block_info @@ -201,15 +209,18 @@ static const struct wined3d_format_block_info format_block_info[] = { - {WINED3DFMT_DXT1, 4, 4, 8, TRUE}, - {WINED3DFMT_DXT2, 4, 4, 16, TRUE}, - {WINED3DFMT_DXT3, 4, 4, 16, TRUE}, - {WINED3DFMT_DXT4, 4, 4, 16, TRUE}, - {WINED3DFMT_DXT5, 4, 4, 16, TRUE}, - {WINED3DFMT_ATI1N, 4, 4, 8, FALSE}, - {WINED3DFMT_ATI2N, 4, 4, 16, FALSE}, - {WINED3DFMT_YUY2, 2, 1, 4, FALSE}, - {WINED3DFMT_UYVY, 2, 1, 4, FALSE}, + {WINED3DFMT_DXT1, 4, 4, 8, TRUE}, + {WINED3DFMT_DXT2, 4, 4, 16, TRUE}, + {WINED3DFMT_DXT3, 4, 4, 16, TRUE}, + {WINED3DFMT_DXT4, 4, 4, 16, TRUE}, + {WINED3DFMT_DXT5, 4, 4, 16, TRUE}, + {WINED3DFMT_BC1_UNORM, 4, 4, 8, TRUE}, + {WINED3DFMT_BC2_UNORM, 4, 4, 16, TRUE}, + {WINED3DFMT_BC3_UNORM, 4, 4, 16, TRUE}, + {WINED3DFMT_ATI1N, 4, 4, 8, FALSE}, + {WINED3DFMT_ATI2N, 4, 4, 16, FALSE}, + {WINED3DFMT_YUY2, 2, 1, 4, FALSE}, + {WINED3DFMT_UYVY, 2, 1, 4, FALSE}, }; struct wined3d_format_vertex_info @@ -950,6 +961,21 @@ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, EXT_TEXTURE_COMPRESSION_S3TC, NULL}, + {WINED3DFMT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_COMPRESSED, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, + {WINED3DFMT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_COMPRESSED, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, + {WINED3DFMT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_COMPRESSED, + EXT_TEXTURE_COMPRESSION_S3TC, NULL}, /* IEEE formats */ {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0, GL_RED, GL_FLOAT, 0, @@ -967,6 +993,10 @@ GL_RG, GL_FLOAT, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R32G32B32_FLOAT, GL_RGB32F, GL_RGB32F, 0, + GL_RGB, GL_FLOAT, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET, + ARB_TEXTURE_FLOAT, NULL}, {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0, GL_RGBA, GL_FLOAT, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF, @@ -1065,6 +1095,14 @@ | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE | WINED3DFMT_FLAG_VTF, WINED3D_GL_EXT_NONE, NULL}, + {WINED3DFMT_R8G8B8A8_UINT, GL_RGBA8UI, GL_RGBA8UI, 0, + GL_RGBA_INTEGER, GL_UNSIGNED_INT_8_8_8_8_REV, 0, + WINED3DFMT_FLAG_TEXTURE, + ARB_TEXTURE_RGB10_A2UI, NULL}, + {WINED3DFMT_R8G8B8A8_SINT, GL_RGBA8I, GL_RGBA8I, 0, + GL_RGBA_INTEGER, GL_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE, + EXT_TEXTURE_INTEGER, NULL}, {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, @@ -1088,6 +1126,15 @@ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET, WINED3D_GL_EXT_NONE, NULL}, + {WINED3DFMT_R8G8_UNORM, GL_RG8, GL_RG8, 0, + GL_RG, GL_UNSIGNED_BYTE, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING, + ARB_TEXTURE_RG, NULL}, + {WINED3DFMT_R16_UNORM, GL_R16, GL_R16, 0, + WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING + | WINED3DFMT_FLAG_RENDERTARGET, + GL_RED, GL_UNSIGNED_SHORT, 0, + ARB_TEXTURE_RG, NULL}, /* Luminance */ {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, @@ -1783,6 +1830,7 @@ if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags[type] & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING)) + && !(format->flags[type] & WINED3DFMT_FLAG_INTEGER) && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA && (format->red_size || format->alpha_size)) @@ -2124,10 +2172,11 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info) { + GLint count, multisample_types[MAX_MULTISAMPLE_TYPES]; struct fragment_caps fragment_caps; struct shader_caps shader_caps; BOOL srgb_write; - unsigned int i; + unsigned int i, j, max_log2; adapter->fragment_pipe->get_caps(gl_info, &fragment_caps); adapter->shader_backend->shader_get_caps(gl_info, &shader_caps); @@ -2246,6 +2295,34 @@ } } + if (format->glInternal && format->flags[WINED3D_GL_RES_TYPE_RB] + & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) + { + if (gl_info->supported[ARB_INTERNALFORMAT_QUERY]) + { + GL_EXTCALL(glGetInternalformativ(GL_RENDERBUFFER, format->glInternal, + GL_NUM_SAMPLE_COUNTS, 1, &count)); + checkGLcall("glGetInternalformativ(GL_NUM_SAMPLE_COUNTS)"); + count = min(count, MAX_MULTISAMPLE_TYPES); + GL_EXTCALL(glGetInternalformativ(GL_RENDERBUFFER, format->glInternal, + GL_SAMPLES, count, multisample_types)); + checkGLcall("glGetInternalformativ(GL_SAMPLES)"); + for (j = 0; j < count; ++j) + { + if (multisample_types[j] > sizeof(format->multisample_types) * 8) + continue; + format->multisample_types |= 1u << (multisample_types[j] - 1); + } + } + else + { + max_log2 = wined3d_log2i(min(gl_info->limits.samples, + sizeof(format->multisample_types) * 8)); + for (j = 1; j <= max_log2; ++j) + format->multisample_types |= 1u << ((1u << j) - 1); + } + } + /* Texture conversion stuff */ format->convert = format_texture_info[i].convert; format->conv_byte_count = format_texture_info[i].conv_byte_count; @@ -2648,6 +2725,12 @@ gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; idx = getFmtIdx(WINED3DFMT_DXT5); gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + idx = getFmtIdx(WINED3DFMT_BC1_UNORM); + gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + idx = getFmtIdx(WINED3DFMT_BC2_UNORM); + gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; + idx = getFmtIdx(WINED3DFMT_BC3_UNORM); + gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; /* Similarly with ATI1N / ATI2N and GL_ARB_texture_compression_rgtc. */ idx = getFmtIdx(WINED3DFMT_ATI1N); gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE; @@ -2875,6 +2958,15 @@ /***************************************************************************** * Trace formatting of useful values */ +const char *debug_box(const struct wined3d_box *box) +{ + if (!box) + return "(null)"; + return wine_dbg_sprintf("(%u, %u, %u)-(%u, %u, %u)", + box->left, box->top, box->front, + box->right, box->bottom, box->back); +} + const char *debug_d3dformat(enum wined3d_format_id format_id) { switch (format_id) @@ -3158,14 +3250,13 @@ { switch (resource_type) { -#define RES_TO_STR(res) case res: return #res - RES_TO_STR(WINED3D_RTYPE_SURFACE); - RES_TO_STR(WINED3D_RTYPE_VOLUME); - RES_TO_STR(WINED3D_RTYPE_TEXTURE); - RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE); - RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE); - RES_TO_STR(WINED3D_RTYPE_BUFFER); -#undef RES_TO_STR +#define WINED3D_TO_STR(x) case x: return #x + WINED3D_TO_STR(WINED3D_RTYPE_SURFACE); + WINED3D_TO_STR(WINED3D_RTYPE_VOLUME); + WINED3D_TO_STR(WINED3D_RTYPE_BUFFER); + WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_2D); + WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_3D); +#undef WINED3D_TO_STR default: FIXME("Unrecognized resource type %#x.\n", resource_type); return "unrecognized"; @@ -4005,17 +4096,6 @@ } } -/* This small helper function is used to convert a bitmask into the number of masked bits */ -unsigned int count_bits(unsigned int mask) -{ - unsigned int count; - for (count = 0; mask; ++count) - { - mask &= mask - 1; - } - return count; -} - /* Note: It's the caller's responsibility to ensure values can be expressed * in the requested format. UNORM formats for example can only express values * in the range 0.0f -> 1.0f. */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/view.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/view.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/view.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/view.c 2016-02-08 19:32:34.000000000 +0000 @@ -145,41 +145,21 @@ return WINED3D_OK; } -HRESULT CDECL wined3d_rendertarget_view_create_from_surface(struct wined3d_surface *surface, - void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_rendertarget_view **view) -{ - struct wined3d_rendertarget_view_desc desc; - - TRACE("surface %p, parent %p, parent_ops %p, view %p.\n", surface, parent, parent_ops, view); - - desc.format_id = surface->resource.format->id; - desc.u.texture.level_idx = surface->texture_level; - desc.u.texture.layer_idx = surface->texture_layer; - desc.u.texture.layer_count = 1; - - return wined3d_rendertarget_view_create(&desc, &surface->container->resource, parent, parent_ops, view); -} - HRESULT CDECL wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture *texture, unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_rendertarget_view **view) { - struct wined3d_resource *sub_resource; + struct wined3d_rendertarget_view_desc desc; TRACE("texture %p, sub_resource_idx %u, parent %p, parent_ops %p, view %p.\n", texture, sub_resource_idx, parent, parent_ops, view); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx))) - return WINED3DERR_INVALIDCALL; - - if (sub_resource->type != WINED3D_RTYPE_SURFACE) - { - FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(texture->resource.type)); - return WINED3DERR_INVALIDCALL; - } + desc.format_id = texture->resource.format->id; + desc.u.texture.level_idx = sub_resource_idx % texture->level_count; + desc.u.texture.layer_idx = sub_resource_idx / texture->level_count; + desc.u.texture.layer_count = 1; - return wined3d_rendertarget_view_create_from_surface(surface_from_resource(sub_resource), - parent, parent_ops, view); + return wined3d_rendertarget_view_create(&desc, &texture->resource, parent, parent_ops, view); } ULONG CDECL wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view *view) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/volume.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/volume.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/volume.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/volume.c 2016-02-08 19:32:34.000000000 +0000 @@ -230,8 +230,6 @@ return FALSE; if (volume->resource.format->convert) return FALSE; - if (volume->flags & WINED3D_VFLAG_CLIENT_STORAGE) - return FALSE; return TRUE; } @@ -455,7 +453,6 @@ } /* The texture name is managed by the container. */ - volume->flags &= ~WINED3D_VFLAG_CLIENT_STORAGE; resource_unload(resource); } @@ -520,8 +517,8 @@ const struct wined3d_format *format = volume->resource.format; const unsigned int fmt_flags = volume->container->resource.format_flags; - TRACE("volume %p, map_desc %p, box %p, flags %#x.\n", - volume, map_desc, box, flags); + TRACE("volume %p, map_desc %p, box %s, flags %#x.\n", + volume, map_desc, debug_box(box), flags); map_desc->data = NULL; if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) @@ -541,8 +538,8 @@ } if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !volume_check_block_align(volume, box)) { - WARN("Map box is misaligned for %ux%u blocks.\n", - format->block_width, format->block_height); + WARN("Map box %s is misaligned for %ux%u blocks.\n", + debug_box(box), format->block_width, format->block_height); return WINED3DERR_INVALIDCALL; } @@ -615,14 +612,10 @@ if (!box) { - TRACE("No box supplied - all is ok\n"); map_desc->data = base_memory; } else { - TRACE("Lock Box (%p) = l %u, t %u, r %u, b %u, fr %u, ba %u\n", - box, box->left, box->top, box->right, box->bottom, box->front, box->back); - if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) { /* Compressed textures are block based, so calculate the offset of diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/wined3d_gl.h wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/wined3d_gl.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/wined3d_gl.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/wined3d_gl.h 2016-02-08 19:32:34.000000000 +0000 @@ -38,7 +38,6 @@ WINED3D_GL_EXT_NONE, /* APPLE */ - APPLE_CLIENT_STORAGE, APPLE_FENCE, APPLE_FLOAT_PIXELS, APPLE_FLUSH_BUFFER_RANGE, @@ -61,6 +60,7 @@ ARB_HALF_FLOAT_PIXEL, ARB_HALF_FLOAT_VERTEX, ARB_INSTANCED_ARRAYS, + ARB_INTERNALFORMAT_QUERY, ARB_INTERNALFORMAT_QUERY2, ARB_MAP_BUFFER_ALIGNMENT, ARB_MAP_BUFFER_RANGE, @@ -87,8 +87,10 @@ ARB_TEXTURE_MIRRORED_REPEAT, ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE, ARB_TEXTURE_NON_POWER_OF_TWO, + ARB_TEXTURE_QUERY_LEVELS, ARB_TEXTURE_RECTANGLE, ARB_TEXTURE_RG, + ARB_TEXTURE_RGB10_A2UI, ARB_TIMER_QUERY, ARB_UNIFORM_BUFFER_OBJECT, ARB_VERTEX_ARRAY_BGRA, @@ -128,6 +130,7 @@ EXT_TEXTURE_ENV_COMBINE, EXT_TEXTURE_ENV_DOT3, EXT_TEXTURE_FILTER_ANISOTROPIC, + EXT_TEXTURE_INTEGER, EXT_TEXTURE_LOD_BIAS, EXT_TEXTURE_MIRROR_CLAMP, EXT_TEXTURE_SNORM, diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/wined3d_private.h wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/wined3d_private.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/wined3d_private.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/wined3d_private.h 2016-02-08 19:32:34.000000000 +0000 @@ -185,6 +185,7 @@ #define MAX_SAMPLER_OBJECTS 16 #define MAX_SHADER_RESOURCE_VIEWS 128 #define MAX_VERTEX_BLENDS 4 +#define MAX_MULTISAMPLE_TYPES 8 struct min_lookup { @@ -257,6 +258,17 @@ } } +static inline unsigned int wined3d_popcount(unsigned int x) +{ +#ifdef HAVE___BUILTIN_POPCOUNT + return __builtin_popcount(x); +#else + x -= x >> 1 & 0x55555555; + x = (x & 0x33333333) + (x >> 2 & 0x33333333); + return ((x + (x >> 4)) & 0x0f0f0f0f) * 0x01010101 >> 24; +#endif +} + #define ORM_BACKBUFFER 0 #define ORM_FBO 1 @@ -347,6 +359,7 @@ WINED3DSPR_PREDICATE = 19, WINED3DSPR_IMMCONST, WINED3DSPR_CONSTBUFFER, + WINED3DSPR_IMMCONSTBUFFER, WINED3DSPR_PRIMID, WINED3DSPR_NULL, WINED3DSPR_RESOURCE, @@ -403,10 +416,30 @@ WINED3DSPDM_MSAMPCENTROID = 4, }; +enum wined3d_shader_interpolation_mode +{ + WINED3DSIM_CONSTANT = 1, + WINED3DSIM_LINEAR = 2, + WINED3DSIM_LINEAR_CENTROID = 3, + WINED3DSIM_LINEAR_NOPERSPECTIVE = 4, + WINED3DSIM_LINEAR_NOPERSPECTIVE_CENTROID = 5, + WINED3DSIM_LINEAR_SAMPLE = 6, + WINED3DSIM_LINEAR_NOPERSPECTIVE_SAMPLE = 7, +}; + +enum wined3d_shader_global_flags +{ + WINED3DSGF_REFACTORING_ALLOWED = 0x1, + WINED3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS = 0x8, +}; + /* Undocumented opcode control to identify projective texture lookups in ps 2.0 and later */ #define WINED3DSI_TEXLD_PROJECT 0x1 #define WINED3DSI_TEXLD_BIAS 0x2 #define WINED3DSI_INDEXED_DYNAMIC 0x4 +#define WINED3DSI_RESINFO_RCP_FLOAT 0x1 +#define WINED3DSI_RESINFO_UINT 0x2 +#define WINED3DSI_SAMPLER_COMPARISON_MODE 0x1 enum wined3d_shader_rel_op { @@ -445,6 +478,8 @@ * Shader model 3 according to msdn (and for software shaders) */ #define MAX_LABELS 16 +#define MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE 4096 + struct wined3d_string_buffer { struct list entry; @@ -470,8 +505,20 @@ WINED3DSIH_CUT, WINED3DSIH_DCL, WINED3DSIH_DCL_CONSTANT_BUFFER, + WINED3DSIH_DCL_GLOBAL_FLAGS, + WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, + WINED3DSIH_DCL_INPUT, WINED3DSIH_DCL_INPUT_PRIMITIVE, + WINED3DSIH_DCL_INPUT_PS, + WINED3DSIH_DCL_INPUT_PS_SGV, + WINED3DSIH_DCL_INPUT_PS_SIV, + WINED3DSIH_DCL_INPUT_SGV, + WINED3DSIH_DCL_INPUT_SIV, + WINED3DSIH_DCL_OUTPUT, + WINED3DSIH_DCL_OUTPUT_SIV, WINED3DSIH_DCL_OUTPUT_TOPOLOGY, + WINED3DSIH_DCL_SAMPLER, + WINED3DSIH_DCL_TEMPS, WINED3DSIH_DCL_VERTICES_OUT, WINED3DSIH_DEF, WINED3DSIH_DEFB, @@ -494,13 +541,20 @@ WINED3DSIH_EXPP, WINED3DSIH_FRC, WINED3DSIH_FTOI, + WINED3DSIH_FTOU, WINED3DSIH_GE, WINED3DSIH_IADD, WINED3DSIH_IEQ, WINED3DSIH_IF, WINED3DSIH_IFC, WINED3DSIH_IGE, + WINED3DSIH_ILT, + WINED3DSIH_IMAD, + WINED3DSIH_IMAX, + WINED3DSIH_IMIN, WINED3DSIH_IMUL, + WINED3DSIH_INE, + WINED3DSIH_INEG, WINED3DSIH_ISHL, WINED3DSIH_ITOF, WINED3DSIH_LABEL, @@ -525,16 +579,23 @@ WINED3DSIH_MUL, WINED3DSIH_NE, WINED3DSIH_NOP, + WINED3DSIH_NOT, WINED3DSIH_NRM, WINED3DSIH_OR, WINED3DSIH_PHASE, WINED3DSIH_POW, WINED3DSIH_RCP, WINED3DSIH_REP, + WINED3DSIH_RESINFO, WINED3DSIH_RET, WINED3DSIH_ROUND_NI, + WINED3DSIH_ROUND_PI, + WINED3DSIH_ROUND_Z, WINED3DSIH_RSQ, WINED3DSIH_SAMPLE, + WINED3DSIH_SAMPLE_B, + WINED3DSIH_SAMPLE_C, + WINED3DSIH_SAMPLE_C_LZ, WINED3DSIH_SAMPLE_GRAD, WINED3DSIH_SAMPLE_LOD, WINED3DSIH_SETP, @@ -595,6 +656,8 @@ enum wined3d_data_type data_type; }; +#define WINED3D_SAMPLER_DEFAULT ~0x0u + struct wined3d_shader_sampler_map_entry { unsigned int resource_idx; @@ -609,6 +672,12 @@ size_t count; }; +struct wined3d_shader_immediate_constant_buffer +{ + UINT element_count; + DWORD data[MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE]; +}; + #define WINED3D_SHADER_VERSION(major, minor) (((major) << 8) | (minor)) struct wined3d_shader_reg_maps @@ -619,6 +688,7 @@ WORD labels; /* MAX_LABELS, 16 */ DWORD temporary; /* MAX_REG_TEMP, 32 */ DWORD *constf; /* pixel, vertex */ + const struct wined3d_shader_immediate_constant_buffer *icb; union { DWORD texcoord_mask[MAX_REG_TEXCRD]; /* vertex < 3.0 */ @@ -724,6 +794,12 @@ struct wined3d_shader_dst_param reg; }; +struct wined3d_shader_register_semantic +{ + struct wined3d_shader_dst_param reg; + enum wined3d_sysval_semantic sysval_semantic; +}; + struct wined3d_shader_instruction { const struct wined3d_shader_context *ctx; @@ -738,9 +814,12 @@ union { struct wined3d_shader_semantic semantic; + struct wined3d_shader_register_semantic register_semantic; enum wined3d_primitive_type primitive_type; + struct wined3d_shader_dst_param dst; struct wined3d_shader_src_param src; UINT count; + const struct wined3d_shader_immediate_constant_buffer *icb; } declaration; }; @@ -1175,6 +1254,7 @@ DWORD last_was_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */ DWORD last_was_pshader : 1; DWORD last_was_vshader : 1; + DWORD last_was_normal : 1; DWORD namedArraysLoaded : 1; DWORD numberedArraysLoaded : 1; DWORD last_was_blit : 1; @@ -1185,17 +1265,17 @@ DWORD current : 1; DWORD destroyed : 1; DWORD valid : 1; - DWORD use_immediate_mode_draw : 1; DWORD texShaderBumpMap : 8; /* MAX_TEXTURES, 8 */ DWORD lastWasPow2Texture : 8; /* MAX_TEXTURES, 8 */ DWORD fixed_function_usage_map : 8; /* MAX_TEXTURES, 8 */ DWORD lowest_disabled_stage : 4; /* Max MAX_TEXTURES, 8 */ + DWORD use_immediate_mode_draw : 1; DWORD rebind_fbo : 1; DWORD needs_set : 1; DWORD hdc_is_private : 1; DWORD hdc_has_format : 1; /* only meaningful if hdc_is_private */ DWORD update_shader_resource_bindings : 1; - DWORD padding : 15; + DWORD padding : 14; DWORD shader_update_mask; DWORD constant_update_mask; DWORD numbered_array_mask; @@ -1382,10 +1462,10 @@ const struct wined3d_d3d_info *d3d_info, enum wined3d_blit_op blit_op, const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format, const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format); - HRESULT (*color_fill)(struct wined3d_device *device, struct wined3d_surface *dst_surface, - const RECT *dst_rect, const struct wined3d_color *color); + HRESULT (*color_fill)(struct wined3d_device *device, struct wined3d_rendertarget_view *view, + const RECT *rect, const struct wined3d_color *color); HRESULT (*depth_fill)(struct wined3d_device *device, - struct wined3d_surface *surface, const RECT *rect, float depth); + struct wined3d_rendertarget_view *view, const RECT *rect, float depth); void (*blit_surface)(struct wined3d_device *device, enum wined3d_blit_op op, DWORD filter, struct wined3d_surface *src_surface, const RECT *src_rect, struct wined3d_surface *dst_surface, const RECT *dst_rect, @@ -2125,6 +2205,9 @@ UINT dummy_texture_3d[MAX_COMBINED_SAMPLERS]; UINT dummy_texture_cube[MAX_COMBINED_SAMPLERS]; + /* Default sampler used to emulate the direct resource access without using wined3d_sampler */ + GLuint default_sampler; + /* Command stream */ struct wined3d_cs *cs; @@ -2334,14 +2417,12 @@ const char *wined3d_debug_location(DWORD location) DECLSPEC_HIDDEN; -#define WINED3D_VFLAG_CLIENT_STORAGE 0x00000001 - struct wined3d_volume { struct wined3d_resource resource; struct wined3d_texture *container; - DWORD flags, locations; + DWORD locations; GLint texture_level; DWORD download_count; GLuint pbo; @@ -2452,9 +2533,13 @@ ? surface->container->texture_srgb.name : surface->container->texture_rgb.name; } +HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, + struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, + const WINEDDBLTFX *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; void surface_set_dirty(struct wined3d_surface *surface) DECLSPEC_HIDDEN; HRESULT surface_color_fill(struct wined3d_surface *s, const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; +HRESULT surface_create_dib_section(struct wined3d_surface *surface) DECLSPEC_HIDDEN; GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) DECLSPEC_HIDDEN; void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context, unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN; @@ -2466,6 +2551,8 @@ struct wined3d_context *context) DECLSPEC_HIDDEN; HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; +HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, + const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; @@ -2473,6 +2560,7 @@ const struct wined3d_surface *rt) DECLSPEC_HIDDEN; void surface_set_texture_target(struct wined3d_surface *surface, GLenum target, GLint level) DECLSPEC_HIDDEN; void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN; +HRESULT wined3d_surface_unmap(struct wined3d_surface *surface) DECLSPEC_HIDDEN; HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, void *mem, unsigned int pitch) DECLSPEC_HIDDEN; HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, @@ -2494,7 +2582,6 @@ #define SFLAG_DIBSECTION 0x00000001 /* Has a DIB section attached for GetDC. */ #define SFLAG_DISCARD 0x00000002 /* ??? */ #define SFLAG_NONPOW2 0x00000004 /* Surface sizes are not a power of 2 */ -#define SFLAG_CLIENT 0x00000010 /* GL_APPLE_client_storage is used with this surface. */ #define SFLAG_DCINUSE 0x00000020 /* Set between GetDC and ReleaseDC calls. */ struct wined3d_sampler @@ -2755,6 +2842,8 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state) DECLSPEC_HIDDEN; void buffer_mark_used(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; +HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, + const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN; struct wined3d_rendertarget_view { @@ -2780,10 +2869,7 @@ struct wined3d_resource *resource; struct wined3d_texture *texture; - if (!view) - return NULL; - - if (view->resource->type != WINED3D_RTYPE_TEXTURE && view->resource->type != WINED3D_RTYPE_CUBE_TEXTURE) + if (!view || view->resource->type != WINED3D_RTYPE_TEXTURE_2D) return NULL; texture = wined3d_texture_from_resource(view->resource); @@ -2850,6 +2936,8 @@ */ /* Trace routines */ +const char *debug_box(const struct wined3d_box *box) DECLSPEC_HIDDEN; +const char *debug_d3dshaderinstructionhandler(enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx) DECLSPEC_HIDDEN; const char *debug_d3dformat(enum wined3d_format_id format_id) DECLSPEC_HIDDEN; const char *debug_d3ddevicetype(enum wined3d_device_type device_type) DECLSPEC_HIDDEN; const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type) DECLSPEC_HIDDEN; @@ -2915,7 +3003,6 @@ /* Math utils */ void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1, const struct wined3d_matrix *src2) DECLSPEC_HIDDEN; -unsigned int count_bits(unsigned int mask) DECLSPEC_HIDDEN; void wined3d_release_dc(HWND window, HDC dc) DECLSPEC_HIDDEN; @@ -3194,6 +3281,7 @@ #define WINED3DFMT_FLAG_HEIGHT_SCALE 0x00040000 #define WINED3DFMT_FLAG_TEXTURE 0x00080000 #define WINED3DFMT_FLAG_BLOCKS_NO_VERIFY 0x00100000 +#define WINED3DFMT_FLAG_INTEGER 0x00200000 struct wined3d_rational { @@ -3241,6 +3329,7 @@ GLint glFormat; GLint glType; UINT conv_byte_count; + DWORD multisample_types; unsigned int flags[WINED3D_GL_RES_TYPE_COUNT]; struct wined3d_rational height_scale; struct color_fixup_desc color_fixup; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/wined3d.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/wined3d.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wined3d/wined3d.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wined3d/wined3d.spec 2016-02-08 19:32:34.000000000 +0000 @@ -99,6 +99,7 @@ @ cdecl wined3d_device_get_vs_consts_i(ptr long ptr long) @ cdecl wined3d_device_get_vs_resource_view(ptr long) @ cdecl wined3d_device_get_vs_sampler(ptr long) +@ cdecl wined3d_device_get_wined3d(ptr) @ cdecl wined3d_device_incref(ptr) @ cdecl wined3d_device_init_3d(ptr ptr) @ cdecl wined3d_device_init_gdi(ptr ptr) @@ -188,7 +189,6 @@ @ cdecl wined3d_resource_unmap(ptr long) @ cdecl wined3d_rendertarget_view_create(ptr ptr ptr ptr ptr) -@ cdecl wined3d_rendertarget_view_create_from_surface(ptr ptr ptr ptr) @ cdecl wined3d_rendertarget_view_create_from_sub_resource(ptr long ptr ptr ptr) @ cdecl wined3d_rendertarget_view_decref(ptr) @ cdecl wined3d_rendertarget_view_get_parent(ptr) @@ -222,20 +222,10 @@ @ cdecl wined3d_stateblock_decref(ptr) @ cdecl wined3d_stateblock_incref(ptr) -@ cdecl wined3d_surface_blt(ptr ptr ptr ptr long ptr long) -@ cdecl wined3d_surface_decref(ptr) -@ cdecl wined3d_surface_from_resource(ptr) @ cdecl wined3d_surface_get_overlay_position(ptr ptr ptr) @ cdecl wined3d_surface_get_parent(ptr) @ cdecl wined3d_surface_get_pitch(ptr) -@ cdecl wined3d_surface_get_resource(ptr) -@ cdecl wined3d_surface_getdc(ptr ptr) -@ cdecl wined3d_surface_incref(ptr) -@ cdecl wined3d_surface_map(ptr ptr ptr long) -@ cdecl wined3d_surface_preload(ptr) -@ cdecl wined3d_surface_releasedc(ptr ptr) @ cdecl wined3d_surface_set_overlay_position(ptr long long) -@ cdecl wined3d_surface_unmap(ptr) @ cdecl wined3d_surface_update_overlay(ptr ptr ptr ptr long ptr) @ cdecl wined3d_surface_update_overlay_z_order(ptr long ptr) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/glibthread.c wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/glibthread.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/glibthread.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/glibthread.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,390 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * Wine GStreamer integration - * Copyright 2010 Aric Stewart, CodeWeavers - * - * gthread.c: solaris thread system implementation - * Copyright 1998-2001 Sebastian Wilhelmi; University of Karlsruhe - * Copyright 2001 Hans Breuer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#include "config.h" - -#ifdef HAVE_PTHREAD_H -#include -#endif - -#include - -#include -#include -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winnls.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(gstreamer); - -static gchar * -g_win32_error_message (gint error) -{ - gchar *retval; - WCHAR *msg = NULL; - int nchars; - - FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER - |FORMAT_MESSAGE_IGNORE_INSERTS - |FORMAT_MESSAGE_FROM_SYSTEM, - NULL, error, 0, - (LPWSTR) &msg, 0, NULL); - if (msg != NULL) - { - nchars = WideCharToMultiByte(CP_UTF8, 0, msg, -1, NULL, 0, NULL, NULL); - - if (nchars > 2 && msg[nchars-1] == '\n' && msg[nchars-2] == '\r') - msg[nchars-2] = '\0'; - - retval = g_utf16_to_utf8 (msg, -1, NULL, NULL, NULL); - - LocalFree (msg); - } - else - retval = g_strdup (""); - - return retval; -} - -static gint g_thread_priority_map [G_THREAD_PRIORITY_URGENT + 1] = { - THREAD_PRIORITY_BELOW_NORMAL, - THREAD_PRIORITY_NORMAL, - THREAD_PRIORITY_ABOVE_NORMAL, - THREAD_PRIORITY_HIGHEST -}; - -static DWORD g_thread_self_tls; - -/* A "forward" declaration of this structure */ -static GThreadFunctions g_thread_functions_for_glib_use_default; - -typedef struct _GThreadData GThreadData; -struct _GThreadData -{ - GThreadFunc func; - gpointer data; - HANDLE thread; - gboolean joinable; -}; - -static GMutex * -g_mutex_new_posix_impl (void) -{ - GMutex *result = (GMutex *) g_new (pthread_mutex_t, 1); - pthread_mutex_init ((pthread_mutex_t *) result, NULL); - return result; -} - -static void -g_mutex_free_posix_impl (GMutex * mutex) -{ - pthread_mutex_destroy ((pthread_mutex_t *) mutex); - g_free (mutex); -} - -/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use - functions from gmem.c and gmessages.c; */ - -/* pthread_mutex_lock, pthread_mutex_unlock can be taken directly, as - signature and semantic are right, but without error check then!!!!, - we might want to change this therefore. */ - -static gboolean -g_mutex_trylock_posix_impl (GMutex * mutex) -{ - int result; - - result = pthread_mutex_trylock ((pthread_mutex_t *) mutex); - - if (result == EBUSY) - return FALSE; - - if (result) ERR("pthread_mutex_trylock %x\n",result); - return TRUE; -} - -static GCond * -g_cond_new_posix_impl (void) -{ - GCond *result = (GCond *) g_new (pthread_cond_t, 1); - pthread_cond_init ((pthread_cond_t *) result, NULL); - return result; -} - -/* pthread_cond_signal, pthread_cond_broadcast and pthread_cond_wait - can be taken directly, as signature and semantic are right, but - without error check then!!!!, we might want to change this - therefore. */ - -#define G_NSEC_PER_SEC 1000000000 - -static gboolean -g_cond_timed_wait_posix_impl (GCond * cond, - GMutex * entered_mutex, - GTimeVal * abs_time) -{ - int result; - struct timespec end_time; - gboolean timed_out; - - g_return_val_if_fail (cond != NULL, FALSE); - g_return_val_if_fail (entered_mutex != NULL, FALSE); - - if (!abs_time) - { - result = pthread_cond_wait ((pthread_cond_t *)cond, - (pthread_mutex_t *) entered_mutex); - timed_out = FALSE; - } - else - { - end_time.tv_sec = abs_time->tv_sec; - end_time.tv_nsec = abs_time->tv_usec * (G_NSEC_PER_SEC / G_USEC_PER_SEC); - - g_return_val_if_fail (end_time.tv_nsec < G_NSEC_PER_SEC, TRUE); - - result = pthread_cond_timedwait ((pthread_cond_t *) cond, - (pthread_mutex_t *) entered_mutex, - &end_time); - timed_out = (result == ETIMEDOUT); - } - - if (!timed_out) - if (result) ERR("pthread_cond_timedwait %x\n",result); - - return !timed_out; -} - -static void -g_cond_free_posix_impl (GCond * cond) -{ - pthread_cond_destroy ((pthread_cond_t *) cond); - g_free (cond); -} - -static GPrivate * -g_private_new_posix_impl (GDestroyNotify destructor) -{ - GPrivate *result = (GPrivate *) g_new (pthread_key_t, 1); - pthread_key_create ((pthread_key_t *) result, destructor); - return result; -} - -/* NOTE: the functions g_private_get and g_private_set may not use - functions from gmem.c and gmessages.c */ - -static void -g_private_set_posix_impl (GPrivate * private_key, gpointer value) -{ - if (!private_key) - return; - pthread_setspecific (*(pthread_key_t *) private_key, value); -} - -static gpointer -g_private_get_posix_impl (GPrivate * private_key) -{ - if (!private_key) - return NULL; - return pthread_getspecific (*(pthread_key_t *) private_key); -} - -static void -g_thread_set_priority_win32_impl (gpointer thread, GThreadPriority priority) -{ - GThreadData *target = *(GThreadData **)thread; - - g_return_if_fail ((int)priority >= G_THREAD_PRIORITY_LOW); - g_return_if_fail ((int)priority <= G_THREAD_PRIORITY_URGENT); - - SetThreadPriority (target->thread, g_thread_priority_map [priority]); -} - -static void -g_thread_self_win32_impl (gpointer thread) -{ - GThreadData *self = TlsGetValue (g_thread_self_tls); - - if (!self) - { - /* This should only happen for the main thread! */ - HANDLE handle = GetCurrentThread (); - HANDLE process = GetCurrentProcess (); - self = g_new (GThreadData, 1); - DuplicateHandle (process, handle, process, &self->thread, 0, FALSE, - DUPLICATE_SAME_ACCESS); - TlsSetValue (g_thread_self_tls, self); - self->func = NULL; - self->data = NULL; - self->joinable = FALSE; - } - - *(GThreadData **)thread = self; -} - -static void -g_thread_exit_win32_impl (void) -{ - GThreadData *self = TlsGetValue (g_thread_self_tls); - - if (self) - { - if (!self->joinable) - { - CloseHandle (self->thread); - g_free (self); - } - TlsSetValue (g_thread_self_tls, NULL); - } - - ExitThread (0); -} - -static guint __stdcall -g_thread_proxy (gpointer data) -{ - GThreadData *self = (GThreadData*) data; - - TlsSetValue (g_thread_self_tls, self); - - self->func (self->data); - - g_thread_exit_win32_impl (); - - g_assert_not_reached (); - - return 0; -} - -static void -g_thread_create_win32_impl (GThreadFunc func, - gpointer data, - gulong stack_size, - gboolean joinable, - gboolean bound, - GThreadPriority priority, - gpointer thread, - GError **error) -{ - guint ignore; - GThreadData *retval; - - g_return_if_fail (func); - g_return_if_fail ((int)priority >= G_THREAD_PRIORITY_LOW); - g_return_if_fail ((int)priority <= G_THREAD_PRIORITY_URGENT); - - retval = g_new(GThreadData, 1); - retval->func = func; - retval->data = data; - - retval->joinable = joinable; - - retval->thread = (HANDLE) CreateThread (NULL, stack_size, g_thread_proxy, - retval, 0, &ignore); - - if (retval->thread == NULL) - { - gchar *win_error = g_win32_error_message (GetLastError ()); - g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, - "Error creating thread: %s", win_error); - g_free (retval); - g_free (win_error); - return; - } - - *(GThreadData **)thread = retval; - - g_thread_set_priority_win32_impl (thread, priority); -} - -static void -g_thread_yield_win32_impl (void) -{ - Sleep(0); -} - -static void -g_thread_join_win32_impl (gpointer thread) -{ - GThreadData *target = *(GThreadData **)thread; - - g_return_if_fail (target->joinable); - - WaitForSingleObject (target->thread, INFINITE); - - CloseHandle (target->thread); - g_free (target); -} - -static GThreadFunctions g_thread_functions_for_glib_use_default = -{ - /* Posix functions here for speed */ - g_mutex_new_posix_impl, - (void (*)(GMutex *)) pthread_mutex_lock, - g_mutex_trylock_posix_impl, - (void (*)(GMutex *)) pthread_mutex_unlock, - g_mutex_free_posix_impl, - g_cond_new_posix_impl, - (void (*)(GCond *)) pthread_cond_signal, - (void (*)(GCond *)) pthread_cond_broadcast, - (void (*)(GCond *, GMutex *)) pthread_cond_wait, - g_cond_timed_wait_posix_impl, - g_cond_free_posix_impl, - g_private_new_posix_impl, - g_private_get_posix_impl, - g_private_set_posix_impl, - /* win32 function required here */ - g_thread_create_win32_impl, /* thread */ - g_thread_yield_win32_impl, - g_thread_join_win32_impl, - g_thread_exit_win32_impl, - g_thread_set_priority_win32_impl, - g_thread_self_win32_impl, - NULL /* no equal function necessary */ -}; - -void g_thread_impl_init (void) -{ - static gboolean beenhere = FALSE; - - if (beenhere) - return; - - beenhere = TRUE; - - g_thread_self_tls = TlsAlloc (); - g_thread_init(&g_thread_functions_for_glib_use_default); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/gst_cbs.c wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/gst_cbs.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/gst_cbs.c 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/gst_cbs.c 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,296 @@ +/* + * Copyright 2015 Andrew Eikum for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include + +#include "wine/list.h" + +#include "gst_cbs.h" + +/* gstreamer calls our callbacks from threads that Wine did not create. Some + * callbacks execute code which requires Wine to have created the thread + * (critical sections, debug logging, dshow client code). Since gstreamer can't + * provide an API to override its thread creation, we have to intercept all + * callbacks in code which avoids the Wine thread requirement, and then + * dispatch those callbacks on a thread that is known to be created by Wine. + * + * This file must not contain any code that depends on the Wine TEB! + */ + +static void call_cb(struct cb_data *cbdata) +{ + pthread_mutex_init(&cbdata->lock, NULL); + pthread_cond_init(&cbdata->cond, NULL); + cbdata->finished = 0; + + if(is_wine_thread()){ + /* The thread which triggered gstreamer to call this callback may + * already hold a critical section. If so, executing the callback on a + * worker thread can cause a deadlock. If we are already on a Wine + * thread, then there is no need to run this callback on a worker + * thread anyway, which avoids the deadlock issue. */ + perform_cb(NULL, cbdata); + + pthread_cond_destroy(&cbdata->cond); + pthread_mutex_destroy(&cbdata->lock); + + return; + } + + pthread_mutex_lock(&cb_list_lock); + + list_add_tail(&cb_list, &cbdata->entry); + pthread_cond_broadcast(&cb_list_cond); + + pthread_mutex_lock(&cbdata->lock); + + pthread_mutex_unlock(&cb_list_lock); + + while(!cbdata->finished) + pthread_cond_wait(&cbdata->cond, &cbdata->lock); + + pthread_mutex_unlock(&cbdata->lock); + + pthread_cond_destroy(&cbdata->cond); + pthread_mutex_destroy(&cbdata->lock); +} + +GstBusSyncReply watch_bus_wrapper(GstBus *bus, GstMessage *msg, gpointer user) +{ + struct cb_data cbdata = { WATCH_BUS }; + + cbdata.u.watch_bus_data.bus = bus; + cbdata.u.watch_bus_data.msg = msg; + cbdata.u.watch_bus_data.user = user; + + call_cb(&cbdata); + + return cbdata.u.watch_bus_data.ret; +} + +void existing_new_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) +{ + struct cb_data cbdata = { EXISTING_NEW_PAD }; + + cbdata.u.existing_new_pad_data.bin = bin; + cbdata.u.existing_new_pad_data.pad = pad; + cbdata.u.existing_new_pad_data.user = user; + + call_cb(&cbdata); +} + +gboolean query_function_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) +{ + struct cb_data cbdata = { QUERY_FUNCTION }; + + cbdata.u.query_function_data.pad = pad; + cbdata.u.query_function_data.parent = parent; + cbdata.u.query_function_data.query = query; + + call_cb(&cbdata); + + return cbdata.u.query_function_data.ret; +} + +gboolean activate_mode_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) +{ + struct cb_data cbdata = { ACTIVATE_MODE }; + + cbdata.u.activate_mode_data.pad = pad; + cbdata.u.activate_mode_data.parent = parent; + cbdata.u.activate_mode_data.mode = mode; + cbdata.u.activate_mode_data.activate = activate; + + call_cb(&cbdata); + + return cbdata.u.activate_mode_data.ret; +} + +void no_more_pads_wrapper(GstElement *decodebin, gpointer user) +{ + struct cb_data cbdata = { NO_MORE_PADS }; + + cbdata.u.no_more_pads_data.decodebin = decodebin; + cbdata.u.no_more_pads_data.user = user; + + call_cb(&cbdata); +} + +GstFlowReturn request_buffer_src_wrapper(GstPad *pad, GstObject *parent, guint64 ofs, guint len, + GstBuffer **buf) +{ + struct cb_data cbdata = { REQUEST_BUFFER_SRC }; + + cbdata.u.request_buffer_src_data.pad = pad; + cbdata.u.request_buffer_src_data.parent = parent; + cbdata.u.request_buffer_src_data.ofs = ofs; + cbdata.u.request_buffer_src_data.len = len; + cbdata.u.request_buffer_src_data.buf = buf; + + call_cb(&cbdata); + + return cbdata.u.request_buffer_src_data.ret; +} + +gboolean event_src_wrapper(GstPad *pad, GstObject *parent, GstEvent *event) +{ + struct cb_data cbdata = { EVENT_SRC }; + + cbdata.u.event_src_data.pad = pad; + cbdata.u.event_src_data.parent = parent; + cbdata.u.event_src_data.event = event; + + call_cb(&cbdata); + + return cbdata.u.event_src_data.ret; +} + +gboolean event_sink_wrapper(GstPad *pad, GstObject *parent, GstEvent *event) +{ + struct cb_data cbdata = { EVENT_SINK }; + + cbdata.u.event_sink_data.pad = pad; + cbdata.u.event_sink_data.parent = parent; + cbdata.u.event_sink_data.event = event; + + call_cb(&cbdata); + + return cbdata.u.event_sink_data.ret; +} + +gboolean accept_caps_sink_wrapper(GstPad *pad, GstCaps *caps) +{ + struct cb_data cbdata = { ACCEPT_CAPS_SINK }; + + cbdata.u.accept_caps_sink_data.pad = pad; + cbdata.u.accept_caps_sink_data.caps = caps; + + call_cb(&cbdata); + + return cbdata.u.accept_caps_sink_data.ret; +} + +gboolean setcaps_sink_wrapper(GstPad *pad, GstCaps *caps) +{ + struct cb_data cbdata = { SETCAPS_SINK }; + + cbdata.u.setcaps_sink_data.pad = pad; + cbdata.u.setcaps_sink_data.caps = caps; + + call_cb(&cbdata); + + return cbdata.u.setcaps_sink_data.ret; +} + +GstFlowReturn got_data_sink_wrapper(GstPad *pad, GstObject *parent, GstBuffer *buf) +{ + struct cb_data cbdata = { GOT_DATA_SINK }; + + cbdata.u.got_data_sink_data.pad = pad; + cbdata.u.got_data_sink_data.parent = parent; + cbdata.u.got_data_sink_data.buf = buf; + + call_cb(&cbdata); + + return cbdata.u.got_data_sink_data.ret; +} + +GstFlowReturn got_data_wrapper(GstPad *pad, GstObject *parent, GstBuffer *buf) +{ + struct cb_data cbdata = { GOT_DATA }; + + cbdata.u.got_data_data.pad = pad; + cbdata.u.got_data_data.parent = parent; + cbdata.u.got_data_data.buf = buf; + + call_cb(&cbdata); + + return cbdata.u.got_data_data.ret; +} + +void removed_decoded_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) +{ + struct cb_data cbdata = { REMOVED_DECODED_PAD }; + + cbdata.u.removed_decoded_pad_data.bin = bin; + cbdata.u.removed_decoded_pad_data.pad = pad; + cbdata.u.removed_decoded_pad_data.user = user; + + call_cb(&cbdata); +} + +GstAutoplugSelectResult autoplug_blacklist_wrapper(GstElement *bin, GstPad *pad, + GstCaps *caps, GstElementFactory *fact, gpointer user) +{ + struct cb_data cbdata = { AUTOPLUG_BLACKLIST }; + + cbdata.u.autoplug_blacklist_data.bin = bin; + cbdata.u.autoplug_blacklist_data.pad = pad; + cbdata.u.autoplug_blacklist_data.caps = caps; + cbdata.u.autoplug_blacklist_data.fact = fact; + cbdata.u.autoplug_blacklist_data.user = user; + + call_cb(&cbdata); + + return cbdata.u.autoplug_blacklist_data.ret; +} + +void unknown_type_wrapper(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer user) +{ + struct cb_data cbdata = { UNKNOWN_TYPE }; + + cbdata.u.unknown_type_data.bin = bin; + cbdata.u.unknown_type_data.pad = pad; + cbdata.u.unknown_type_data.caps = caps; + cbdata.u.unknown_type_data.user = user; + + call_cb(&cbdata); +} + +void release_sample_wrapper(gpointer data) +{ + struct cb_data cbdata = { RELEASE_SAMPLE }; + + cbdata.u.release_sample_data.data = data; + + call_cb(&cbdata); +} + +void Gstreamer_transform_pad_added_wrapper(GstElement *filter, GstPad *pad, gpointer user) +{ + struct cb_data cbdata = { TRANSFORM_PAD_ADDED }; + + cbdata.u.transform_pad_added_data.filter = filter; + cbdata.u.transform_pad_added_data.pad = pad; + cbdata.u.transform_pad_added_data.user = user; + + call_cb(&cbdata); +} + +gboolean query_sink_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) +{ + struct cb_data cbdata = { QUERY_SINK, + { .query_sink_data = {pad, parent, query} } + }; + + call_cb(&cbdata); + + return cbdata.u.query_sink_data.ret; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/gst_cbs.h wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/gst_cbs.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/gst_cbs.h 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/gst_cbs.h 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,193 @@ +/* + * Copyright 2015 Andrew Eikum for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GST_CBS_H +#define GST_CBS_H + +#include "wine/list.h" +#include "windef.h" +#include + +typedef enum { + GST_AUTOPLUG_SELECT_TRY, + GST_AUTOPLUG_SELECT_EXPOSE, + GST_AUTOPLUG_SELECT_SKIP +} GstAutoplugSelectResult; + +enum CB_TYPE { + WATCH_BUS, + EXISTING_NEW_PAD, + QUERY_FUNCTION, + ACTIVATE_MODE, + NO_MORE_PADS, + REQUEST_BUFFER_SRC, + EVENT_SRC, + EVENT_SINK, + ACCEPT_CAPS_SINK, + SETCAPS_SINK, + GOT_DATA_SINK, + GOT_DATA, + REMOVED_DECODED_PAD, + AUTOPLUG_BLACKLIST, + UNKNOWN_TYPE, + RELEASE_SAMPLE, + TRANSFORM_PAD_ADDED, + QUERY_SINK +}; + +struct cb_data { + enum CB_TYPE type; + union { + struct watch_bus_data { + GstBus *bus; + GstMessage *msg; + gpointer user; + GstBusSyncReply ret; + } watch_bus_data; + struct existing_new_pad_data { + GstElement *bin; + GstPad *pad; + gpointer user; + } existing_new_pad_data; + struct query_function_data { + GstPad *pad; + GstObject *parent; + GstQuery *query; + gboolean ret; + } query_function_data; + struct activate_mode_data { + GstPad *pad; + GstObject *parent; + GstPadMode mode; + gboolean activate; + gboolean ret; + } activate_mode_data; + struct no_more_pads_data { + GstElement *decodebin; + gpointer user; + } no_more_pads_data; + struct request_buffer_src_data { + GstPad *pad; + GstObject *parent; + guint64 ofs; + guint len; + GstBuffer **buf; + GstFlowReturn ret; + } request_buffer_src_data; + struct event_src_data { + GstPad *pad; + GstObject *parent; + GstEvent *event; + gboolean ret; + } event_src_data; + struct event_sink_data { + GstPad *pad; + GstObject *parent; + GstEvent *event; + gboolean ret; + } event_sink_data; + struct accept_caps_sink_data { + GstPad *pad; + GstCaps *caps; + gboolean ret; + } accept_caps_sink_data; + struct setcaps_sink_data { + GstPad *pad; + GstCaps *caps; + gboolean ret; + } setcaps_sink_data; + struct got_data_sink_data { + GstPad *pad; + GstObject *parent; + GstBuffer *buf; + GstFlowReturn ret; + } got_data_sink_data; + struct got_data_data { + GstPad *pad; + GstObject *parent; + GstBuffer *buf; + GstFlowReturn ret; + } got_data_data; + struct removed_decoded_pad_data { + GstElement *bin; + GstPad *pad; + gpointer user; + } removed_decoded_pad_data; + struct autoplug_blacklist_data { + GstElement *bin; + GstPad *pad; + GstCaps *caps; + GstElementFactory *fact; + gpointer user; + GstAutoplugSelectResult ret; + } autoplug_blacklist_data; + struct unknown_type_data { + GstElement *bin; + GstPad *pad; + GstCaps *caps; + gpointer user; + } unknown_type_data; + struct release_sample_data { + gpointer data; + } release_sample_data; + struct transform_pad_added_data { + GstElement *filter; + GstPad *pad; + gpointer user; + } transform_pad_added_data; + struct query_sink_data { + GstPad *pad; + GstObject *parent; + GstQuery *query; + gboolean ret; + } query_sink_data; + } u; + + int finished; + pthread_mutex_t lock; + pthread_cond_t cond; + struct list entry; +}; + +extern pthread_mutex_t cb_list_lock DECLSPEC_HIDDEN; +extern pthread_cond_t cb_list_cond DECLSPEC_HIDDEN; +extern struct list cb_list DECLSPEC_HIDDEN; +void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) DECLSPEC_HIDDEN; +BOOL is_wine_thread(void) DECLSPEC_HIDDEN; +void mark_wine_thread(void) DECLSPEC_HIDDEN; + +GstBusSyncReply watch_bus_wrapper(GstBus *bus, GstMessage *msg, gpointer user) DECLSPEC_HIDDEN; +void existing_new_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; +gboolean query_function_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; +gboolean activate_mode_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) DECLSPEC_HIDDEN; +void no_more_pads_wrapper(GstElement *decodebin, gpointer user) DECLSPEC_HIDDEN; +GstFlowReturn request_buffer_src_wrapper(GstPad *pad, GstObject *parent, guint64 ofs, guint len, GstBuffer **buf) DECLSPEC_HIDDEN; +gboolean event_src_wrapper(GstPad *pad, GstObject *parent, GstEvent *event) DECLSPEC_HIDDEN; +gboolean event_sink_wrapper(GstPad *pad, GstObject *parent, GstEvent *event) DECLSPEC_HIDDEN; +gboolean accept_caps_sink_wrapper(GstPad *pad, GstCaps *caps) DECLSPEC_HIDDEN; +gboolean setcaps_sink_wrapper(GstPad *pad, GstCaps *caps) DECLSPEC_HIDDEN; +GstFlowReturn got_data_sink_wrapper(GstPad *pad, GstObject *parent, GstBuffer *buf) DECLSPEC_HIDDEN; +GstFlowReturn got_data_wrapper(GstPad *pad, GstObject *parent, GstBuffer *buf) DECLSPEC_HIDDEN; +void removed_decoded_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; +GstAutoplugSelectResult autoplug_blacklist_wrapper(GstElement *bin, GstPad *pad, GstCaps *caps, GstElementFactory *fact, gpointer user) DECLSPEC_HIDDEN; +void unknown_type_wrapper(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer user) DECLSPEC_HIDDEN; +void release_sample_wrapper(gpointer data) DECLSPEC_HIDDEN; +void Gstreamer_transform_pad_added_wrapper(GstElement *filter, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; +gboolean query_sink_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; + +#endif diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/gstdemux.c wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/gstdemux.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/gstdemux.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/gstdemux.c 2016-02-08 19:32:34.000000000 +0000 @@ -20,13 +20,14 @@ */ #include "config.h" -#include -#include -#include -#include + +#include +#include +#include #include "gst_private.h" #include "gst_guids.h" +#include "gst_cbs.h" #include "vfwmsgs.h" #include "amvideo.h" @@ -44,6 +45,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(gstreamer); +static pthread_key_t wine_gst_key; + typedef struct GSTOutPin GSTOutPin; typedef struct GSTInPin { BasePin pin; @@ -60,7 +63,7 @@ LONGLONG filesize; - BOOL discont, initial; + BOOL discont, initial, ignore_flush; GstElement *gstfilter; GstPad *my_src, *their_sink; GstBus *bus; @@ -77,6 +80,7 @@ GstPad *their_src; GstPad *my_sink; + GstBufferPool *gstpool; int isaud, isvid; AM_MEDIA_TYPE * pmt; HANDLE caps_event; @@ -84,6 +88,8 @@ SourceSeeking seek; }; +const char* media_quark_string = "media-sample"; + static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; static const IMediaSeekingVtbl GST_Seeking_Vtbl; static const IPinVtbl GST_OutputPin_Vtbl; @@ -97,15 +103,25 @@ static HRESULT WINAPI GST_ChangeStop(IMediaSeeking *iface); static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface); -static gboolean amt_from_gst_caps_audio(GstCaps *caps, AM_MEDIA_TYPE *amt) { +void mark_wine_thread(void) +{ + /* set it to non-NULL to indicate that this is a Wine thread */ + pthread_setspecific(wine_gst_key, &wine_gst_key); +} + +BOOL is_wine_thread(void) +{ + return pthread_getspecific(wine_gst_key) != NULL; +} + +static gboolean amt_from_gst_caps_audio(GstCaps *caps, AM_MEDIA_TYPE *amt) +{ WAVEFORMATEXTENSIBLE *wfe; WAVEFORMATEX *wfx; - GstStructure *arg; gint32 depth = 0, bpp = 0; - const char *typename; - arg = gst_caps_get_structure(caps, 0); - typename = gst_structure_get_name(arg); - if (!typename) + GstAudioInfo ainfo; + + if (!gst_audio_info_from_caps (&ainfo, caps)) return FALSE; wfe = CoTaskMemAlloc(sizeof(*wfe)); @@ -121,12 +137,12 @@ amt->pUnk = NULL; wfx->wFormatTag = WAVE_FORMAT_EXTENSIBLE; - if (!gst_structure_get_int(arg, "channels", (INT*)&wfx->nChannels)) - return FALSE; - if (!gst_structure_get_int(arg, "rate", (INT*)&wfx->nSamplesPerSec)) - return FALSE; - gst_structure_get_int(arg, "width", &depth); - gst_structure_get_int(arg, "depth", &bpp); + + wfx->nChannels = ainfo.channels; + wfx->nSamplesPerSec = ainfo.rate; + depth = GST_AUDIO_INFO_WIDTH(&ainfo); + bpp = GST_AUDIO_INFO_DEPTH(&ainfo); + if (!depth || depth > 32 || depth % 8) depth = bpp; else if (!bpp) @@ -144,7 +160,7 @@ default: wfe->dwChannelMask = 0; } - if (!strcmp(typename, "audio/x-raw-float")) { + if (GST_AUDIO_INFO_IS_FLOAT(&ainfo)) { wfe->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; wfx->wBitsPerSample = wfe->Samples.wValidBitsPerSample = 32; } else { @@ -159,20 +175,20 @@ return TRUE; } -static gboolean amt_from_gst_caps_video(GstCaps *caps, AM_MEDIA_TYPE *amt) { +static gboolean amt_from_gst_caps_video(GstCaps *caps, AM_MEDIA_TYPE *amt) +{ VIDEOINFOHEADER *vih = CoTaskMemAlloc(sizeof(*vih)); BITMAPINFOHEADER *bih = &vih->bmiHeader; - GstStructure *arg; gint32 width = 0, height = 0, nom = 0, denom = 0; - const char *typename; - arg = gst_caps_get_structure(caps, 0); - typename = gst_structure_get_name(arg); - if (!typename) - return FALSE; - if (!gst_structure_get_int(arg, "width", &width) || - !gst_structure_get_int(arg, "height", &height) || - !gst_structure_get_fraction(arg, "framerate", &nom, &denom)) + GstVideoInfo vinfo; + + if (!gst_video_info_from_caps (&vinfo, caps)) return FALSE; + width = vinfo.width; + height = vinfo.height; + nom = vinfo.fps_n; + denom = vinfo.fps_d; + amt->formattype = FORMAT_VideoInfo; amt->pbFormat = (BYTE*)vih; amt->cbFormat = sizeof(*vih); @@ -181,9 +197,8 @@ amt->pUnk = NULL; ZeroMemory(vih, sizeof(*vih)); amt->majortype = MEDIATYPE_Video; - if (!strcmp(typename, "video/x-raw-rgb")) { - if (!gst_structure_get_int(arg, "bpp", (INT*)&bih->biBitCount)) - return FALSE; + if (GST_VIDEO_INFO_IS_RGB(&vinfo)) { + bih->biBitCount = GST_VIDEO_FORMAT_INFO_BITS(vinfo.finfo); switch (bih->biBitCount) { case 16: amt->subtype = MEDIASUBTYPE_RGB555; break; case 24: amt->subtype = MEDIASUBTYPE_RGB24; break; @@ -195,7 +210,7 @@ bih->biCompression = BI_RGB; } else { amt->subtype = MEDIATYPE_Video; - if (!gst_structure_get_fourcc(arg, "format", &amt->subtype.Data1)) + if (!(amt->subtype.Data1 = gst_video_format_to_fourcc(vinfo.finfo->format))) return FALSE; switch (amt->subtype.Data1) { case mmioFOURCC('I','4','2','0'): @@ -225,16 +240,19 @@ return TRUE; } -static gboolean accept_caps_sink(GstPad *pad, GstCaps *caps) { +static gboolean accept_caps_sink(GstPad *pad, GstCaps *caps) +{ GSTOutPin *pin = gst_pad_get_element_private(pad); AM_MEDIA_TYPE amt; GstStructure *arg; const char *typename; gboolean ret; + + TRACE("%p %p\n", pad, caps); + arg = gst_caps_get_structure(caps, 0); typename = gst_structure_get_name(arg); - if (!strcmp(typename, "audio/x-raw-int") || - !strcmp(typename, "audio/x-raw-float")) { + if (!strcmp(typename, "audio/x-raw")) { if (!pin->isaud) { ERR("Setting audio caps on non-audio pad?\n"); return FALSE; @@ -243,8 +261,7 @@ FreeMediaType(&amt); TRACE("+%i\n", ret); return ret; - } else if (!strcmp(typename, "video/x-raw-rgb") - || !strcmp(typename, "video/x-raw-yuv")) { + } else if (!strcmp(typename, "video/x-raw")) { if (!pin->isvid) { ERR("Setting video caps on non-video pad?\n"); return FALSE; @@ -259,24 +276,26 @@ } } -static gboolean setcaps_sink(GstPad *pad, GstCaps *caps) { +static gboolean setcaps_sink(GstPad *pad, GstCaps *caps) +{ GSTOutPin *pin = gst_pad_get_element_private(pad); GSTImpl *This = (GSTImpl *)pin->pin.pin.pinInfo.pFilter; AM_MEDIA_TYPE amt; GstStructure *arg; const char *typename; gboolean ret; + + TRACE("%p %p\n", pad, caps); + arg = gst_caps_get_structure(caps, 0); typename = gst_structure_get_name(arg); - if (!strcmp(typename, "audio/x-raw-int") || - !strcmp(typename, "audio/x-raw-float")) { + if (!strcmp(typename, "audio/x-raw")) { if (!pin->isaud) { ERR("Setting audio caps on non-audio pad?\n"); return FALSE; } ret = amt_from_gst_caps_audio(caps, &amt); - } else if (!strcmp(typename, "video/x-raw-rgb") - || !strcmp(typename, "video/x-raw-yuv")) { + } else if (!strcmp(typename, "video/x-raw")) { if (!pin->isvid) { ERR("Setting video caps on non-video pad?\n"); return FALSE; @@ -296,6 +315,23 @@ return TRUE; } +static gboolean query_sink(GstPad *pad, GstObject *parent, GstQuery *query) +{ + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_ACCEPT_CAPS: + { + GstCaps *caps; + gboolean res; + gst_query_parse_accept_caps(query, &caps); + res = accept_caps_sink(pad, caps); + gst_query_set_accept_caps_result(query, res); + return TRUE; /* FIXME */ + } + default: + return gst_pad_query_default (pad, parent, query); + } +} + static gboolean gst_base_src_perform_seek(GSTImpl *This, GstEvent *event) { gboolean res = TRUE; @@ -309,6 +345,8 @@ GstEvent *tevent; BOOL thread = !!This->push_thread; + TRACE("%p %p\n", This, event); + gst_event_parse_seek(event, &rate, &seek_format, &flags, &cur_type, &cur, &stop_type, &stop); @@ -328,27 +366,31 @@ if (This->pInputPin.pReader) IAsyncReader_BeginFlush(This->pInputPin.pReader); if (thread) - gst_pad_activate_push(This->my_src, 0); + gst_pad_set_active(This->my_src, 1); } This->nextofs = This->start = cur; /* and prepare to continue streaming */ if (flush) { - tevent = gst_event_new_flush_stop(); + tevent = gst_event_new_flush_stop(TRUE); gst_event_set_seqnum(tevent, seqnum); gst_pad_push_event(This->my_src, tevent); if (This->pInputPin.pReader) IAsyncReader_EndFlush(This->pInputPin.pReader); if (thread) - gst_pad_activate_push(This->my_src, 1); + gst_pad_set_active(This->my_src, 1); } return res; } -static gboolean event_src(GstPad *pad, GstEvent *event) { +static gboolean event_src(GstPad *pad, GstObject *parent, GstEvent *event) +{ GSTImpl *This = gst_pad_get_element_private(pad); + + TRACE("%p %p\n", pad, event); + switch (event->type) { case GST_EVENT_SEEK: return gst_base_src_perform_seek(This, event); @@ -368,30 +410,45 @@ FIXME("%p (%u) stub\n", event, event->type); case GST_EVENT_TAG: case GST_EVENT_QOS: - return gst_pad_event_default(pad, event); + return gst_pad_event_default(pad, parent, event); } return TRUE; } -static gboolean event_sink(GstPad *pad, GstEvent *event) { +static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event) +{ GSTOutPin *pin = gst_pad_get_element_private(pad); + + TRACE("%p %p\n", pad, event); + switch (event->type) { - case GST_EVENT_NEWSEGMENT: { - gboolean update; + case GST_EVENT_SEGMENT: { gdouble rate, applied_rate; - GstFormat format; - gint64 start, stop, pos; - gst_event_parse_new_segment_full(event, &update, &rate, &applied_rate, &format, &start, &stop, &pos); - if (format != GST_FORMAT_TIME) { - FIXME("Ignoring new segment because of format %i\n", format); + gint64 stop, pos; + const GstSegment *segment; + + gst_event_parse_segment(event, &segment); + + pos = segment->position; + stop = segment->stop; + rate = segment->rate; + applied_rate = segment->applied_rate; + + if (segment->format != GST_FORMAT_TIME) { + FIXME("Ignoring new segment because of format %i\n", segment->format); return TRUE; } - gst_segment_set_newsegment_full(pin->segment, update, rate, applied_rate, format, start, stop, pos); + + gst_segment_copy_into(segment, pin->segment); + pos /= 100; + if (stop > 0) stop /= 100; + if (pin->pin.pin.pConnectedTo) IPin_NewSegment(pin->pin.pin.pConnectedTo, pos, stop, rate*applied_rate); + return TRUE; } case GST_EVENT_EOS: @@ -399,6 +456,17 @@ IPin_EndOfStream(pin->pin.pin.pConnectedTo); return TRUE; case GST_EVENT_FLUSH_START: + if (((GSTImpl *)pin->pin.pin.pinInfo.pFilter)->ignore_flush) { + /* gst-plugins-base prior to 1.7 contains a bug which causes + * our sink pins to receive a flush-start event when the + * decodebin changes from PAUSED to READY (including + * PLAYING->PAUSED->READY), but no matching flush-stop event is + * sent. See pin.pin.pConnectedTo) IPin_BeginFlush(pin->pin.pin.pConnectedTo); return TRUE; @@ -407,19 +475,26 @@ if (pin->pin.pin.pConnectedTo) IPin_EndFlush(pin->pin.pin.pConnectedTo); return TRUE; + case GST_EVENT_CAPS: { + GstCaps *caps; + gst_event_parse_caps(event, &caps); + return setcaps_sink(pad, caps); + } default: - FIXME("%p stub %s\n", event, gst_event_type_get_name(event->type)); - return gst_pad_event_default(pad, event); + TRACE("%p stub %s\n", event, gst_event_type_get_name(event->type)); + return gst_pad_event_default(pad, parent, event); } } -static void release_sample(void *data) { +static void release_sample(void *data) +{ ULONG ret; ret = IMediaSample_Release((IMediaSample *)data); TRACE("Releasing %p returns %u\n", data, ret); } -static DWORD CALLBACK push_data(LPVOID iface) { +static DWORD CALLBACK push_data(LPVOID iface) +{ LONGLONG maxlen, curlen; GSTImpl *This = iface; IMediaSample *buf; @@ -430,14 +505,21 @@ IAsyncReader_Length(This->pInputPin.pReader, &maxlen, &curlen); else maxlen = This->stop; + + TRACE("Waiting..\n"); + + WaitForSingleObject(This->event, INFINITE); + TRACE("Starting..\n"); for (;;) { REFERENCE_TIME tStart, tStop; ULONG len; GstBuffer *gstbuf; + gsize bufsize; BYTE *data; int ret; + TRACE("pAlloc: %p\n", This->pInputPin.pAlloc); hr = IMemAllocator_GetBuffer(This->pInputPin.pAlloc, &buf, NULL, NULL, 0); if (FAILED(hr)) break; @@ -466,12 +548,15 @@ } IMediaSample_GetPointer(buf, &data); - gstbuf = gst_app_buffer_new(data, IMediaSample_GetActualDataLength(buf), release_sample, buf); + bufsize = IMediaSample_GetActualDataLength(buf); + gstbuf = gst_buffer_new_wrapped_full(0, data, bufsize, 0, bufsize, buf, release_sample_wrapper); + IMediaSample_AddRef(buf); + gst_mini_object_set_qdata(GST_MINI_OBJECT(gstbuf), g_quark_from_static_string(media_quark_string), buf, release_sample_wrapper); if (!gstbuf) { IMediaSample_Release(buf); break; } - gstbuf->duration = gstbuf->timestamp = -1; + gstbuf->duration = gstbuf->pts = -1; ret = gst_pad_push(This->my_src, gstbuf); if (ret >= 0) hr = S_OK; @@ -479,10 +564,8 @@ ERR("Sending returned: %i\n", ret); if (ret == GST_FLOW_ERROR) hr = E_FAIL; - else if (ret == GST_FLOW_WRONG_STATE) + else if (ret == GST_FLOW_FLUSHING) hr = VFW_E_WRONG_STATE; - else if (ret == GST_FLOW_RESEND) - hr = S_FALSE; if (hr != S_OK) break; } @@ -500,61 +583,68 @@ return 0; } -static HRESULT WINAPI GST_OutPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt) { +static HRESULT WINAPI GST_OutPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt) +{ GSTOutPin *pin = (GSTOutPin*)iface; FIXME("stub %p\n", pin); return S_OK; } -static GstFlowReturn got_data_sink(GstPad *pad, GstBuffer *buf) { +static GstFlowReturn got_data_sink(GstPad *pad, GstObject *parent, GstBuffer *buf) +{ GSTOutPin *pin = gst_pad_get_element_private(pad); GSTImpl *This = (GSTImpl *)pin->pin.pin.pinInfo.pFilter; - IMediaSample *sample; HRESULT hr; - BOOL freeSamp = FALSE; + BYTE *ptr = NULL; + IMediaSample *sample; + GstMapInfo info; + + TRACE("%p %p\n", pad, buf); if (This->initial) { gst_buffer_unref(buf); TRACE("Triggering %p %p\n", pad, pin->caps_event); SetEvent(pin->caps_event); + return GST_FLOW_OK; + } + + hr = BaseOutputPinImpl_GetDeliveryBuffer(&pin->pin, &sample, NULL, NULL, 0); + + if (hr == VFW_E_NOT_CONNECTED) { + gst_buffer_unref(buf); return GST_FLOW_NOT_LINKED; } - if (GST_IS_APP_BUFFER(buf)) { - sample = GST_APP_BUFFER(buf)->priv; - TRACE("Pushing buffer\n"); - } else if (buf->parent && GST_IS_APP_BUFFER(buf->parent)) { - sample = GST_APP_BUFFER(buf->parent)->priv; - TRACE("Pushing sub-buffer\n"); - } else { - BYTE *ptr = NULL; - hr = BaseOutputPinImpl_GetDeliveryBuffer(&pin->pin, &sample, NULL, NULL, 0); - freeSamp = TRUE; - if (hr == VFW_E_NOT_CONNECTED) { - gst_buffer_unref(buf); - return GST_FLOW_NOT_LINKED; - } - if (FAILED(hr)) { - gst_buffer_unref(buf); - ERR("Didn't get a GST_APP_BUFFER, and could not get a delivery buffer (%x), returning GST_FLOW_WRONG_STATE\n", hr); - return GST_FLOW_WRONG_STATE; - } - TRACE("Did not get a GST_APP_BUFFER, creating a sample\n"); - IMediaSample_GetPointer(sample, &ptr); - memcpy(ptr, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf)); + if (FAILED(hr)) { + gst_buffer_unref(buf); + ERR("Could not get a delivery buffer (%x), returning GST_FLOW_FLUSHING\n", hr); + return GST_FLOW_FLUSHING; } - IMediaSample_SetActualDataLength(sample, GST_BUFFER_SIZE(buf)); - if (GST_BUFFER_TIMESTAMP_IS_VALID(buf)) { - REFERENCE_TIME rtStart = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, buf->timestamp); + gst_buffer_map(buf, &info, GST_MAP_READ); + + hr = IMediaSample_SetActualDataLength(sample, info.size); + if(FAILED(hr)){ + WARN("SetActualDataLength failed: %08x\n", hr); + return GST_FLOW_FLUSHING; + } + + IMediaSample_GetPointer(sample, &ptr); + + memcpy(ptr, info.data, info.size); + + gst_buffer_unmap(buf, &info); + + if (GST_BUFFER_PTS_IS_VALID(buf)) { + REFERENCE_TIME rtStart = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, buf->pts); if (rtStart >= 0) rtStart /= 100; if (GST_BUFFER_DURATION_IS_VALID(buf)) { - REFERENCE_TIME tStart = buf->timestamp / 100; - REFERENCE_TIME tStop = (buf->timestamp + buf->duration) / 100; + REFERENCE_TIME tStart = buf->pts / 100; + REFERENCE_TIME tStop = (buf->pts + buf->duration) / 100; REFERENCE_TIME rtStop; - rtStop = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, buf->timestamp + buf->duration); + rtStop = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, buf->pts + buf->duration); if (rtStop >= 0) rtStop /= 100; TRACE("Current time on %p: %i to %i ms\n", pin, (int)(rtStart / 10000), (int)(rtStop / 10000)); @@ -570,103 +660,67 @@ } IMediaSample_SetDiscontinuity(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DISCONT)); - IMediaSample_SetPreroll(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_PREROLL)); + IMediaSample_SetPreroll(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_LIVE)); IMediaSample_SetSyncPoint(sample, !GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT)); if (!pin->pin.pin.pConnectedTo) hr = VFW_E_NOT_CONNECTED; else hr = IMemInputPin_Receive(pin->pin.pMemInputPin, sample); - TRACE("sending sample: %08x\n", hr); - gst_buffer_unref(buf); - if (freeSamp) - IMediaSample_Release(sample); - if (hr == VFW_E_NOT_CONNECTED) - return GST_FLOW_NOT_LINKED; - else if (FAILED(hr)) - return GST_FLOW_WRONG_STATE; - if (hr != S_OK) - return GST_FLOW_RESEND; - return GST_FLOW_OK; -} -static GstFlowReturn request_buffer_sink(GstPad *pad, guint64 ofs, guint size, GstCaps *caps, GstBuffer **buf) { - GSTOutPin *pin = gst_pad_get_element_private(pad); - GSTImpl *This = (GSTImpl *)pin->pin.pin.pinInfo.pFilter; - IMediaSample *sample; - BYTE *ptr; - HRESULT hr; + TRACE("sending sample returned: %08x\n", hr); - TRACE("Requesting buffer\n"); - if (This->initial) { - int ret; - ret = setcaps_sink(pad, caps); - if (!ret) - return GST_FLOW_NOT_NEGOTIATED; - *buf = gst_buffer_new_and_alloc(size); - return GST_FLOW_OK; - } - - if (caps && caps != GST_PAD_CAPS(pad)) - if (!setcaps_sink(pad, caps)) - return GST_FLOW_NOT_NEGOTIATED; + gst_buffer_unref(buf); + IMediaSample_Release(sample); - hr = BaseOutputPinImpl_GetDeliveryBuffer(&pin->pin, &sample, NULL, NULL, 0); if (hr == VFW_E_NOT_CONNECTED) return GST_FLOW_NOT_LINKED; - if (FAILED(hr)) { - ERR("Could not get output buffer: %08x\n", hr); - *buf = NULL; - return GST_FLOW_WRONG_STATE; - } - IMediaSample_SetActualDataLength(sample, size); - IMediaSample_GetPointer(sample, &ptr); - *buf = gst_app_buffer_new(ptr, size, release_sample, sample); - if (!*buf) { - IMediaSample_Release(sample); - ERR("Out of memory\n"); - return GST_FLOW_ERROR; - } - gst_buffer_set_caps(*buf, caps); + + if (FAILED(hr)) + return GST_FLOW_FLUSHING; + return GST_FLOW_OK; } -static GstFlowReturn request_buffer_src(GstPad *pad, guint64 ofs, guint len, GstBuffer **buf) { +static GstFlowReturn request_buffer_src(GstPad *pad, GstObject *parent, guint64 ofs, guint len, GstBuffer **buf) +{ GSTImpl *This = gst_pad_get_element_private(pad); - int ret; + HRESULT hr; + GstMapInfo info; + + TRACE("%p %s %i %p\n", pad, wine_dbgstr_longlong(ofs), len, buf); *buf = NULL; - TRACE("Requesting %s %u\n", wine_dbgstr_longlong(ofs), len); if (ofs == (guint64)-1) ofs = This->nextpullofs; if (ofs >= This->filesize) { WARN("Reading past eof: %s, %u\n", wine_dbgstr_longlong(ofs), len); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } if (len + ofs > This->filesize) len = This->filesize - ofs; This->nextpullofs = ofs + len; - ret = gst_pad_alloc_buffer(This->my_src, ofs, len, NULL, buf); - if (ret >= 0) { - HRESULT hr; - hr = IAsyncReader_SyncRead(This->pInputPin.pReader, ofs, len, GST_BUFFER_DATA(*buf)); - if (FAILED(hr)) { - ERR("Returned %08x\n", hr); - return GST_FLOW_ERROR; - } + *buf = gst_buffer_new_and_alloc(len); + gst_buffer_map(*buf, &info, GST_MAP_WRITE); + hr = IAsyncReader_SyncRead(This->pInputPin.pReader, ofs, len, info.data); + gst_buffer_unmap(*buf, &info); + if (FAILED(hr)) { + ERR("Returned %08x\n", hr); + return GST_FLOW_ERROR; } - return ret; + return GST_FLOW_OK; } -static DWORD CALLBACK push_data_init(LPVOID iface) { +static DWORD CALLBACK push_data_init(LPVOID iface) +{ GSTImpl *This = iface; DWORD64 ofs = 0; TRACE("Starting..\n"); for (;;) { GstBuffer *buf; - GstFlowReturn ret = request_buffer_src(This->my_src, ofs, 4096, &buf); + GstFlowReturn ret = request_buffer_src(This->my_src, NULL, ofs, 4096, &buf); if (ret < 0) { ERR("Obtaining buffer returned: %i\n", ret); break; @@ -682,10 +736,14 @@ return 0; } -static void removed_decoded_pad(GstElement *bin, GstPad *pad, GSTImpl *This) { +static void removed_decoded_pad(GstElement *bin, GstPad *pad, gpointer user) +{ + GSTImpl *This = (GSTImpl*)user; int x; GSTOutPin *pin; + TRACE("%p %p %p\n", This, bin, pad); + EnterCriticalSection(&This->filter.csFilter); for (x = 0; x < This->cStreams; ++x) { if (This->ppPins[x]->their_src == pad) @@ -702,7 +760,8 @@ LeaveCriticalSection(&This->filter.csFilter); } -static void init_new_decoded_pad(GstElement *bin, GstPad *pad, gboolean last, GSTImpl *This) { +static void init_new_decoded_pad(GstElement *bin, GstPad *pad, GSTImpl *This) +{ HRESULT hr; PIN_INFO piOutput; const char *typename; @@ -714,42 +773,45 @@ GSTOutPin *pin; int ret; int isvid = 0, isaud = 0; + gchar my_name[1024]; + + TRACE("%p %p %p\n", This, bin, pad); piOutput.dir = PINDIR_OUTPUT; piOutput.pFilter = (IBaseFilter *)This; name = gst_pad_get_name(pad); MultiByteToWideChar(CP_UNIXCP, 0, name, -1, piOutput.achName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0]) - 1); TRACE("Name: %s\n", name); + strcpy(my_name, "qz_sink_"); + strcat(my_name, name); g_free(name); piOutput.achName[sizeof(piOutput.achName) / sizeof(piOutput.achName[0]) - 1] = 0; - caps = gst_pad_get_caps_reffed(pad); + caps = gst_pad_query_caps(pad, NULL); + caps = gst_caps_make_writable(caps); arg = gst_caps_get_structure(caps, 0); typename = gst_structure_get_name(arg); - mypad = gst_pad_new(NULL, GST_PAD_SINK); - gst_pad_set_chain_function(mypad, got_data_sink); - gst_pad_set_event_function(mypad, event_sink); - gst_pad_set_bufferalloc_function(mypad, request_buffer_sink); - gst_pad_set_acceptcaps_function(mypad, accept_caps_sink); - gst_pad_set_setcaps_function(mypad, setcaps_sink); + mypad = gst_pad_new(my_name, GST_PAD_SINK); + gst_pad_set_chain_function(mypad, got_data_sink_wrapper); + gst_pad_set_event_function(mypad, event_sink_wrapper); + gst_pad_set_query_function(mypad, query_sink_wrapper); - if (!strcmp(typename, "audio/x-raw-int") || - !strcmp(typename, "audio/x-raw-float")) { + if (!strcmp(typename, "audio/x-raw")) { isaud = 1; - } else if (!strcmp(typename, "video/x-raw-rgb") - || !strcmp(typename, "video/x-raw-yuv")) { + } else if (!strcmp(typename, "video/x-raw")) { isvid = 1; } else { FIXME("Unknown type \'%s\'\n", typename); return; } - GST_PAD_CAPS(mypad) = GST_CAPS_ANY; + hr = GST_AddPin(This, &piOutput, &amt); if (FAILED(hr)) { ERR("%08x\n", hr); return; } + pin = This->ppPins[This->cStreams - 1]; gst_pad_set_element_private(mypad, pin); pin->my_sink = mypad; @@ -758,23 +820,30 @@ gst_segment_init(pin->segment, GST_FORMAT_TIME); ret = gst_pad_link(pad, mypad); - gst_pad_activate_push(mypad, 1); + + gst_pad_set_active(mypad, 1); + TRACE("Linking: %i\n", ret); + if (ret >= 0) { pin->their_src = pad; gst_object_ref(pin->their_src); } } -static void existing_new_pad(GstElement *bin, GstPad *pad, gboolean last, GSTImpl *This) { +static void existing_new_pad(GstElement *bin, GstPad *pad, gpointer user) +{ + GSTImpl *This = (GSTImpl*)user; int x; + TRACE("%p %p %p\n", This, bin, pad); + if (gst_pad_is_linked(pad)) return; /* Still holding our own lock */ if (This->initial) { - init_new_decoded_pad(bin, pad, last, This); + init_new_decoded_pad(bin, pad, This); return; } @@ -792,20 +861,19 @@ } } } - init_new_decoded_pad(bin, pad, last, This); + init_new_decoded_pad(bin, pad, This); LeaveCriticalSection(&This->filter.csFilter); } -static gboolean check_get_range(GstPad *pad) { - return TRUE; -} - -static gboolean query_function(GstPad *pad, GstQuery *query) { +static gboolean query_function(GstPad *pad, GstObject *parent, GstQuery *query) +{ GSTImpl *This = gst_pad_get_element_private(pad); GstFormat format; int ret; LONGLONG duration; + TRACE("%p %p %p\n", This, pad, query); + switch (GST_QUERY_TYPE(query)) { case GST_QUERY_DURATION: gst_query_parse_duration (query, &format, NULL); @@ -813,7 +881,7 @@ gst_query_set_duration (query, GST_FORMAT_PERCENT, GST_FORMAT_PERCENT_MAX); return TRUE; } - ret = gst_pad_query_convert (pad, GST_FORMAT_BYTES, This->filesize, &format, &duration); + ret = gst_pad_query_convert (pad, GST_FORMAT_BYTES, This->filesize, format, &duration); gst_query_set_duration(query, format, duration); return ret; case GST_QUERY_SEEKING: @@ -823,16 +891,23 @@ return FALSE; gst_query_set_seeking(query, GST_FORMAT_BYTES, 1, 0, This->filesize); return TRUE; + case GST_QUERY_SCHEDULING: + gst_query_set_scheduling(query, GST_SCHEDULING_FLAG_SEEKABLE, 1, -1, 0); + gst_query_add_scheduling_mode(query, GST_PAD_MODE_PUSH); + gst_query_add_scheduling_mode(query, GST_PAD_MODE_PULL); + return TRUE; default: - FIXME("Unhandled query type %i\n", GST_QUERY_TYPE(query)); - case GST_QUERY_URI: - case GST_QUERY_CONVERT: + TRACE("Unhandled query type: %s\n", GST_QUERY_TYPE_NAME(query)); return FALSE; } } -static gboolean activate_push(GstPad *pad, gboolean activate) { +static gboolean activate_push(GstPad *pad, gboolean activate) +{ GSTImpl *This = gst_pad_get_element_private(pad); + + TRACE("%p %p %u\n", This, pad, activate); + EnterCriticalSection(&This->filter.csFilter); if (!activate) { TRACE("Deactivating\n"); @@ -858,18 +933,29 @@ return TRUE; } -static void no_more_pads(GstElement *decodebin, GSTImpl *This) { - TRACE("Done\n"); - SetEvent(This->event); +static gboolean activate_mode(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) +{ + TRACE("%p %p 0x%x %u\n", pad, parent, mode, activate); + switch (mode) { + case GST_PAD_MODE_PULL: + return TRUE; + case GST_PAD_MODE_PUSH: + return activate_push(pad, activate); + default: + return FALSE; + } + return FALSE; } -typedef enum { - GST_AUTOPLUG_SELECT_TRY, - GST_AUTOPLUG_SELECT_EXPOSE, - GST_AUTOPLUG_SELECT_SKIP -} GstAutoplugSelectResult; +static void no_more_pads(GstElement *decodebin, gpointer user) +{ + GSTImpl *This = (GSTImpl*)user; + TRACE("%p %p\n", This, decodebin); + SetEvent(This->event); +} -static GstAutoplugSelectResult autoplug_blacklist(GstElement *bin, GstPad *pad, GstCaps *caps, GstElementFactory *fact, GSTImpl *This) { +static GstAutoplugSelectResult autoplug_blacklist(GstElement *bin, GstPad *pad, GstCaps *caps, GstElementFactory *fact, gpointer user) +{ const char *name = gst_element_factory_get_longname(fact); if (strstr(name, "Player protection")) { @@ -884,10 +970,14 @@ return GST_AUTOPLUG_SELECT_TRY; } -static GstBusSyncReply watch_bus(GstBus *bus, GstMessage *msg, gpointer data) { +static GstBusSyncReply watch_bus(GstBus *bus, GstMessage *msg, gpointer data) +{ GSTImpl *This = data; GError *err = NULL; gchar *dbg_info = NULL; + + TRACE("%p %p %p\n", This, bus, msg); + if (GST_MESSAGE_TYPE(msg) & GST_MESSAGE_ERROR) { gst_message_parse_error(msg, &err, &dbg_info); FIXME("%s: %s\n", GST_OBJECT_NAME(msg->src), err->message); @@ -904,18 +994,19 @@ return GST_BUS_DROP; } -static void unknown_type(GstElement *bin, GstPad *pad, GstCaps *caps, GSTImpl *This) { +static void unknown_type(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer user) +{ gchar *strcaps = gst_caps_to_string(caps); FIXME("Could not find a filter for caps: %s\n", strcaps); g_free(strcaps); } -static HRESULT GST_Connect(GSTInPin *pPin, IPin *pConnectPin, ALLOCATOR_PROPERTIES *props) { +static HRESULT GST_Connect(GSTInPin *pPin, IPin *pConnectPin, ALLOCATOR_PROPERTIES *props) +{ GSTImpl *This = (GSTImpl*)pPin->pin.pinInfo.pFilter; HRESULT hr; int ret, i; LONGLONG avail, duration; - GstFormat format = GST_FORMAT_TIME; GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE( "quartz_src", GST_PAD_SRC, @@ -923,38 +1014,37 @@ GST_STATIC_CAPS_ANY); TRACE("%p %p %p\n", pPin, pConnectPin, props); + This->props = *props; IAsyncReader_Length(pPin->pReader, &This->filesize, &avail); if (!This->bus) { This->bus = gst_bus_new(); - gst_bus_set_sync_handler(This->bus, watch_bus, This); + gst_bus_set_sync_handler(This->bus, watch_bus_wrapper, This, NULL); } - This->gstfilter = gst_element_factory_make("decodebin2", NULL); + This->gstfilter = gst_element_factory_make("decodebin", NULL); if (!This->gstfilter) { FIXME("Could not make source filter, are gstreamer-plugins-* installed for %u bits?\n", 8 * (int)sizeof(void*)); return E_FAIL; } gst_element_set_bus(This->gstfilter, This->bus); - g_signal_connect(This->gstfilter, "new-decoded-pad", G_CALLBACK(existing_new_pad), This); - g_signal_connect(This->gstfilter, "pad-removed", G_CALLBACK(removed_decoded_pad), This); - g_signal_connect(This->gstfilter, "autoplug-select", G_CALLBACK(autoplug_blacklist), This); - g_signal_connect(This->gstfilter, "unknown-type", G_CALLBACK(unknown_type), This); + g_signal_connect(This->gstfilter, "pad-added", G_CALLBACK(existing_new_pad_wrapper), This); + g_signal_connect(This->gstfilter, "pad-removed", G_CALLBACK(removed_decoded_pad_wrapper), This); + g_signal_connect(This->gstfilter, "autoplug-select", G_CALLBACK(autoplug_blacklist_wrapper), This); + g_signal_connect(This->gstfilter, "unknown-type", G_CALLBACK(unknown_type_wrapper), This); This->my_src = gst_pad_new_from_static_template(&src_template, "quartz-src"); - gst_pad_set_getrange_function(This->my_src, request_buffer_src); - gst_pad_set_checkgetrange_function(This->my_src, check_get_range); - gst_pad_set_query_function(This->my_src, query_function); - gst_pad_set_activatepush_function(This->my_src, activate_push); - gst_pad_set_event_function(This->my_src, event_src); + gst_pad_set_getrange_function(This->my_src, request_buffer_src_wrapper); + gst_pad_set_query_function(This->my_src, query_function_wrapper); + gst_pad_set_activatemode_function(This->my_src, activate_mode_wrapper); + gst_pad_set_event_function(This->my_src, event_src_wrapper); gst_pad_set_element_private (This->my_src, This); This->their_sink = gst_element_get_static_pad(This->gstfilter, "sink"); - g_signal_connect(This->gstfilter, "no-more-pads", G_CALLBACK(no_more_pads), This); + g_signal_connect(This->gstfilter, "no-more-pads", G_CALLBACK(no_more_pads_wrapper), This); ret = gst_pad_link(This->my_src, This->their_sink); - gst_object_unref(This->their_sink); if (ret < 0) { ERR("Returns: %i\n", ret); return E_FAIL; @@ -965,7 +1055,6 @@ This->initial = This->discont = TRUE; ResetEvent(This->event); gst_element_set_state(This->gstfilter, GST_STATE_PLAYING); - gst_pad_set_active(This->my_src, 1); WaitForSingleObject(This->event, -1); gst_element_get_state(This->gstfilter, NULL, NULL, -1); @@ -976,7 +1065,7 @@ FIXME("GStreamer could not find any streams\n"); hr = E_FAIL; } else { - gst_pad_query_duration(This->ppPins[0]->their_src, &format, &duration); + gst_pad_query_duration(This->ppPins[0]->their_src, GST_FORMAT_TIME, &duration); for (i = 0; i < This->cStreams; ++i) { This->ppPins[i]->seek.llDuration = This->ppPins[i]->seek.llStop = duration / 100; This->ppPins[i]->seek.llCurrent = 0; @@ -987,24 +1076,31 @@ hr = S_OK; } *props = This->props; + + This->ignore_flush = TRUE; gst_element_set_state(This->gstfilter, GST_STATE_READY); gst_element_get_state(This->gstfilter, NULL, NULL, -1); - if (This->push_thread) - gst_pad_activate_push(This->my_src, 0); + This->ignore_flush = FALSE; This->initial = FALSE; + + /* don't set active during test-play, as we don't want to push/pull data + * from the source yet */ + gst_pad_set_active(This->my_src, 1); + This->nextofs = This->nextpullofs = 0; return hr; } -static inline GSTOutPin *impl_from_IMediaSeeking( IMediaSeeking *iface ) { +static inline GSTOutPin *impl_from_IMediaSeeking( IMediaSeeking *iface ) +{ return CONTAINING_RECORD(iface, GSTOutPin, seek.IMediaSeeking_iface); } static IPin* WINAPI GST_GetPin(BaseFilter *iface, int pos) { GSTImpl *This = (GSTImpl *)iface; - TRACE("Asking for pos %x\n", pos); + TRACE("%p: Asking for pos %x\n", This, pos); if (pos > This->cStreams || pos < 0) return NULL; @@ -1023,6 +1119,7 @@ static LONG WINAPI GST_GetPinCount(BaseFilter *iface) { GSTImpl *This = (GSTImpl *)iface; + TRACE("%p -> %u\n", This, This->cStreams + 1); return (This->cStreams + 1); } @@ -1031,17 +1128,22 @@ GST_GetPinCount }; -IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *punkout, HRESULT *phr) { +IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr) +{ IUnknown *obj = NULL; PIN_INFO *piInput; GSTImpl *This; + TRACE("%p %p\n", pUnkOuter, phr); + if (!Gstreamer_init()) { *phr = E_FAIL; return NULL; } + mark_wine_thread(); + This = CoTaskMemAlloc(sizeof(*This)); obj = (IUnknown*)This; if (!This) @@ -1068,15 +1170,19 @@ This->pInputPin.pin.pCritSec = &This->filter.csFilter; ZeroMemory(&This->pInputPin.pin.mtCurrent, sizeof(AM_MEDIA_TYPE)); *phr = S_OK; + + TRACE("returning %p\n", obj); + return obj; } -static void GST_Destroy(GSTImpl *This) { +static void GST_Destroy(GSTImpl *This) +{ IPin *connected = NULL; ULONG pinref; HRESULT hr; - TRACE("Destroying\n"); + TRACE("Destroying %p\n", This); CloseHandle(This->event); @@ -1099,16 +1205,18 @@ pinref = IPin_Release((IPin *)&This->pInputPin); } if (This->bus) { - gst_bus_set_sync_handler(This->bus, NULL, NULL); + gst_bus_set_sync_handler(This->bus, NULL, NULL, NULL); gst_object_unref(This->bus); } BaseFilter_Destroy(&This->filter); CoTaskMemFree(This); } -static HRESULT WINAPI GST_QueryInterface(IBaseFilter *iface, REFIID riid, LPVOID *ppv) { +static HRESULT WINAPI GST_QueryInterface(IBaseFilter *iface, REFIID riid, LPVOID *ppv) +{ GSTImpl *This = (GSTImpl *)iface; - TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); + + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); *ppv = NULL; @@ -1133,7 +1241,8 @@ return E_NOINTERFACE; } -static ULONG WINAPI GST_Release(IBaseFilter *iface) { +static ULONG WINAPI GST_Release(IBaseFilter *iface) +{ GSTImpl *This = (GSTImpl *)iface; ULONG refCount = InterlockedDecrement(&This->filter.refCount); @@ -1145,26 +1254,37 @@ return refCount; } -static HRESULT WINAPI GST_Stop(IBaseFilter *iface) { +static HRESULT WINAPI GST_Stop(IBaseFilter *iface) +{ GSTImpl *This = (GSTImpl *)iface; - TRACE("()\n"); + TRACE("(%p)\n", This); + + mark_wine_thread(); - if (This->gstfilter) + if (This->gstfilter) { + This->ignore_flush = TRUE; gst_element_set_state(This->gstfilter, GST_STATE_READY); + gst_element_get_state(This->gstfilter, NULL, NULL, -1); + This->ignore_flush = FALSE; + } return S_OK; } -static HRESULT WINAPI GST_Pause(IBaseFilter *iface) { +static HRESULT WINAPI GST_Pause(IBaseFilter *iface) +{ HRESULT hr = S_OK; GSTImpl *This = (GSTImpl *)iface; GstState now; GstStateChangeReturn ret; - TRACE("()\n"); + + TRACE("(%p)\n", This); if (!This->gstfilter) return VFW_E_NOT_CONNECTED; + mark_wine_thread(); + gst_element_get_state(This->gstfilter, &now, NULL, -1); if (now == GST_STATE_PAUSED) return S_OK; @@ -1178,14 +1298,17 @@ return hr; } -static HRESULT WINAPI GST_Run(IBaseFilter *iface, REFERENCE_TIME tStart) { +static HRESULT WINAPI GST_Run(IBaseFilter *iface, REFERENCE_TIME tStart) +{ HRESULT hr = S_OK; GSTImpl *This = (GSTImpl *)iface; ULONG i; GstState now; HRESULT hr_any = VFW_E_NOT_CONNECTED; - TRACE("(%s)\n", wine_dbgstr_longlong(tStart)); + TRACE("(%p)->(%s)\n", This, wine_dbgstr_longlong(tStart)); + + mark_wine_thread(); if (!This->gstfilter) return VFW_E_NOT_CONNECTED; @@ -1206,35 +1329,31 @@ } EnterCriticalSection(&This->filter.csFilter); - gst_pad_set_blocked(This->my_src, 0); - gst_pad_set_blocked(This->their_sink, 0); gst_element_set_state(This->gstfilter, GST_STATE_PLAYING); This->filter.rtStreamStart = tStart; for (i = 0; i < This->cStreams; i++) { hr = BaseOutputPinImpl_Active((BaseOutputPin *)This->ppPins[i]); if (SUCCEEDED(hr)) { - gst_pad_set_blocked(This->ppPins[i]->my_sink, 0); - if (This->ppPins[i]->their_src) - gst_pad_set_blocked(This->ppPins[i]->their_src, 0); hr_any = hr; } } hr = hr_any; - if (SUCCEEDED(hr)) - gst_pad_set_active(This->my_src, 1); LeaveCriticalSection(&This->filter.csFilter); return hr; } -static HRESULT WINAPI GST_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) { +static HRESULT WINAPI GST_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) +{ GSTImpl *This = (GSTImpl *)iface; HRESULT hr = S_OK; GstState now, pending; GstStateChangeReturn ret; - TRACE("(%d, %p)\n", dwMilliSecsTimeout, pState); + TRACE("(%p)->(%d, %p)\n", This, dwMilliSecsTimeout, pState); + + mark_wine_thread(); if (!This->gstfilter) { *pState = State_Stopped; @@ -1255,7 +1374,8 @@ } } -static HRESULT WINAPI GST_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin) { +static HRESULT WINAPI GST_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin) +{ FIXME("(%p)->(%s,%p) stub\n", iface, debugstr_w(Id), ppPin); return E_NOTIMPL; } @@ -1278,44 +1398,59 @@ BaseFilterImpl_QueryVendorInfo }; -static HRESULT WINAPI GST_ChangeCurrent(IMediaSeeking *iface) { +static HRESULT WINAPI GST_ChangeCurrent(IMediaSeeking *iface) +{ + GSTOutPin *This = impl_from_IMediaSeeking(iface); + TRACE("(%p)\n", This); return S_OK; } -static HRESULT WINAPI GST_ChangeStop(IMediaSeeking *iface) { +static HRESULT WINAPI GST_ChangeStop(IMediaSeeking *iface) +{ + GSTOutPin *This = impl_from_IMediaSeeking(iface); + TRACE("(%p)\n", This); return S_OK; } -static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface) { +static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface) +{ GSTOutPin *This = impl_from_IMediaSeeking(iface); GstEvent *ev = gst_event_new_seek(This->seek.dRate, GST_FORMAT_TIME, 0, GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1); - TRACE("(%p) New rate %g\n", iface, This->seek.dRate); + TRACE("(%p) New rate %g\n", This, This->seek.dRate); + mark_wine_thread(); gst_pad_push_event(This->my_sink, ev); return S_OK; } -static HRESULT WINAPI GST_Seeking_QueryInterface(IMediaSeeking *iface, REFIID riid, void **ppv) { +static HRESULT WINAPI GST_Seeking_QueryInterface(IMediaSeeking *iface, REFIID riid, void **ppv) +{ GSTOutPin *This = impl_from_IMediaSeeking(iface); return IUnknown_QueryInterface((IUnknown *)This, riid, ppv); } -static ULONG WINAPI GST_Seeking_AddRef(IMediaSeeking *iface) { +static ULONG WINAPI GST_Seeking_AddRef(IMediaSeeking *iface) +{ GSTOutPin *This = impl_from_IMediaSeeking(iface); return IUnknown_AddRef((IUnknown *)This); } -static ULONG WINAPI GST_Seeking_Release(IMediaSeeking *iface) { +static ULONG WINAPI GST_Seeking_Release(IMediaSeeking *iface) +{ GSTOutPin *This = impl_from_IMediaSeeking(iface); return IUnknown_Release((IUnknown *)This); } -static HRESULT WINAPI GST_Seeking_GetCurrentPosition(IMediaSeeking *iface, REFERENCE_TIME *pos) { +static HRESULT WINAPI GST_Seeking_GetCurrentPosition(IMediaSeeking *iface, REFERENCE_TIME *pos) +{ GSTOutPin *This = impl_from_IMediaSeeking(iface); - GstFormat format = GST_FORMAT_TIME; + + TRACE("(%p)->(%p)\n", This, pos); if (!pos) return E_POINTER; + mark_wine_thread(); + if (!This->their_src) { *pos = This->seek.llCurrent; TRACE("Cached value\n"); @@ -1325,7 +1460,7 @@ return E_NOTIMPL; } - if (!gst_pad_query_position(This->their_src, &format, pos)) { + if (!gst_pad_query_position(This->their_src, GST_FORMAT_TIME, pos)) { WARN("Could not query position\n"); return E_NOTIMPL; } @@ -1334,23 +1469,34 @@ return S_OK; } -static GstSeekType type_from_flags(DWORD flags) { +static GstSeekType type_from_flags(DWORD flags) +{ switch (flags & AM_SEEKING_PositioningBitsMask) { - case AM_SEEKING_NoPositioning: return GST_SEEK_TYPE_NONE; - case AM_SEEKING_AbsolutePositioning: return GST_SEEK_TYPE_SET; - case AM_SEEKING_RelativePositioning: return GST_SEEK_TYPE_CUR; - case AM_SEEKING_IncrementalPositioning: return GST_SEEK_TYPE_END; + case AM_SEEKING_NoPositioning: + return GST_SEEK_TYPE_NONE; + case AM_SEEKING_AbsolutePositioning: + case AM_SEEKING_RelativePositioning: + return GST_SEEK_TYPE_SET; + case AM_SEEKING_IncrementalPositioning: + return GST_SEEK_TYPE_END; } return GST_SEEK_TYPE_NONE; } - -static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface, REFERENCE_TIME *pCur, DWORD curflags, REFERENCE_TIME *pStop, DWORD stopflags) { +static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface, + REFERENCE_TIME *pCur, DWORD curflags, REFERENCE_TIME *pStop, + DWORD stopflags) +{ HRESULT hr; GSTOutPin *This = impl_from_IMediaSeeking(iface); GstSeekFlags f = 0; GstSeekType curtype, stoptype; GstEvent *e; + gint64 stop_pos = 0, curr_pos = 0; + + TRACE("(%p)->(%p, 0x%x, %p, 0x%x)\n", This, pCur, curflags, pStop, stopflags); + + mark_wine_thread(); if (!This->seek.llDuration) return E_NOTIMPL; @@ -1368,7 +1514,17 @@ if (!(curflags & AM_SEEKING_NoFlush)) f |= GST_SEEK_FLAG_FLUSH; - e = gst_event_new_seek(This->seek.dRate, GST_FORMAT_TIME, f, curtype, pCur ? *pCur * 100 : -1, stoptype, pStop ? *pStop * 100 : -1); + if (((curflags & AM_SEEKING_PositioningBitsMask) == AM_SEEKING_RelativePositioning) || + ((stopflags & AM_SEEKING_PositioningBitsMask) == AM_SEEKING_RelativePositioning)) { + gint64 tmp_pos; + gst_pad_query_position (This->my_sink, GST_FORMAT_TIME, &tmp_pos); + if ((curflags & AM_SEEKING_PositioningBitsMask) == AM_SEEKING_RelativePositioning) + curr_pos = tmp_pos; + if ((stopflags & AM_SEEKING_PositioningBitsMask) == AM_SEEKING_RelativePositioning) + stop_pos = tmp_pos; + } + + e = gst_event_new_seek(This->seek.dRate, GST_FORMAT_TIME, f, curtype, pCur ? curr_pos + *pCur * 100 : -1, stoptype, pStop ? stop_pos + *pStop * 100 : -1); if (gst_pad_push_event(This->my_sink, e)) return S_OK; else @@ -1422,17 +1578,22 @@ return IPin_Release((IPin*)pin); } -static HRESULT WINAPI GST_QualityControl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality qm) { +static HRESULT WINAPI GST_QualityControl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality qm) +{ GSTOutPin *pin = impl_from_IQualityControl(iface); REFERENCE_TIME late = qm.Late; + TRACE("(%p)->(%p, qm)\n", pin, sender); + mark_wine_thread(); if (qm.Late < 0 && -qm.Late > qm.TimeStamp) late = -qm.TimeStamp; - gst_pad_push_event(pin->my_sink, gst_event_new_qos(1000./qm.Proportion, late*100, qm.TimeStamp*100)); + gst_pad_push_event(pin->my_sink, gst_event_new_qos(late <= 0 ? GST_QOS_TYPE_OVERFLOW : GST_QOS_TYPE_UNDERFLOW, 1000./qm.Proportion, late*100, qm.TimeStamp*100)); return S_OK; } static HRESULT WINAPI GST_QualityControl_SetSink(IQualityControl *iface, IQualityControl *tonotify) { + GSTOutPin *pin = impl_from_IQualityControl(iface); + TRACE("(%p)->(%p)\n", pin, pin); /* Do nothing */ return S_OK; } @@ -1445,10 +1606,11 @@ GST_QualityControl_SetSink }; -static HRESULT WINAPI GSTOutPin_QueryInterface(IPin *iface, REFIID riid, void **ppv) { +static HRESULT WINAPI GSTOutPin_QueryInterface(IPin *iface, REFIID riid, void **ppv) +{ GSTOutPin *This = (GSTOutPin *)iface; - TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); *ppv = NULL; @@ -1469,19 +1631,27 @@ return E_NOINTERFACE; } -static ULONG WINAPI GSTOutPin_Release(IPin *iface) { +static ULONG WINAPI GSTOutPin_Release(IPin *iface) +{ GSTOutPin *This = (GSTOutPin *)iface; ULONG refCount = InterlockedDecrement(&This->pin.pin.refCount); - TRACE("(%p)->() Release from %d\n", iface, refCount + 1); + + TRACE("(%p)->() Release from %d\n", This, refCount + 1); + + mark_wine_thread(); if (!refCount) { - if (This->their_src) + if (This->their_src) { gst_pad_unlink(This->their_src, This->my_sink); + gst_object_unref(This->their_src); + } gst_object_unref(This->my_sink); CloseHandle(This->caps_event); DeleteMediaType(This->pmt); FreeMediaType(&This->pin.pin.mtCurrent); gst_segment_free(This->segment); + if(This->gstpool) + gst_object_unref(This->gstpool); if (This->pin.pAllocator) IMemAllocator_Release(This->pin.pAllocator); CoTaskMemFree(This); @@ -1494,16 +1664,23 @@ { GSTOutPin *This = (GSTOutPin *)iface; + TRACE("(%p)->(%i, %p)\n", This, iPosition, pmt); + if (iPosition < 0) return E_INVALIDARG; + if (iPosition > 0) return VFW_S_NO_MORE_ITEMS; + CopyMediaType(pmt, This->pmt); + return S_OK; } static HRESULT WINAPI GSTOutPin_DecideBufferSize(BaseOutputPin *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest) { + GSTOutPin *This = (GSTOutPin *)iface; + TRACE("(%p)->(%p, %p)\n", This, pAlloc, ppropInputRequest); /* Unused */ return S_OK; } @@ -1514,6 +1691,8 @@ GSTOutPin *This = (GSTOutPin *)iface; GSTImpl *GSTfilter = (GSTImpl*)This->pin.pin.pinInfo.pFilter; + TRACE("(%p)->(%p, %p)\n", This, pPin, pAlloc); + *pAlloc = NULL; if (GSTfilter->pInputPin.pAlloc) { @@ -1582,13 +1761,15 @@ GSTOutPin_BreakConnect }; -static HRESULT GST_AddPin(GSTImpl *This, const PIN_INFO *piOutput, const AM_MEDIA_TYPE *amt) { +static HRESULT GST_AddPin(GSTImpl *This, const PIN_INFO *piOutput, const AM_MEDIA_TYPE *amt) +{ HRESULT hr; This->ppPins = CoTaskMemRealloc(This->ppPins, (This->cStreams + 1) * sizeof(IPin *)); hr = BaseOutputPin_Construct(&GST_OutputPin_Vtbl, sizeof(GSTOutPin), piOutput, &output_BaseOutputFuncTable, &This->filter.csFilter, (IPin**)(This->ppPins + This->cStreams)); if (SUCCEEDED(hr)) { GSTOutPin *pin = This->ppPins[This->cStreams]; + memset((char*)pin + sizeof(pin->pin), 0, sizeof(GSTOutPin) - sizeof(pin->pin)); pin->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); CopyMediaType(pin->pmt, amt); pin->pin.pin.pinInfo.pFilter = (LPVOID)This; @@ -1603,20 +1784,22 @@ return hr; } -static HRESULT GST_RemoveOutputPins(GSTImpl *This) { +static HRESULT GST_RemoveOutputPins(GSTImpl *This) +{ HRESULT hr; ULONG i; GSTOutPin **ppOldPins = This->ppPins; + TRACE("(%p)\n", This); + mark_wine_thread(); if (!This->gstfilter) return S_OK; gst_element_set_bus(This->gstfilter, NULL); gst_element_set_state(This->gstfilter, GST_STATE_NULL); gst_pad_unlink(This->my_src, This->their_sink); - if (This->push_thread) - gst_pad_activate_push(This->my_src, 0); gst_object_unref(This->my_src); + gst_object_unref(This->their_sink); This->my_src = This->their_sink = NULL; for (i = 0; i < This->cStreams; i++) { @@ -1633,7 +1816,8 @@ return S_OK; } -static ULONG WINAPI GSTInPin_Release(IPin *iface) { +static ULONG WINAPI GSTInPin_Release(IPin *iface) +{ GSTInPin *This = (GSTInPin*)iface; ULONG refCount = InterlockedDecrement(&This->pin.refCount); @@ -1649,7 +1833,8 @@ return refCount; } -static HRESULT WINAPI GSTInPin_ReceiveConnection(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) { +static HRESULT WINAPI GSTInPin_ReceiveConnection(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) +{ PIN_DIRECTION pindirReceive; HRESULT hr = S_OK; GSTInPin *This = (GSTInPin*)iface; @@ -1657,6 +1842,8 @@ TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt); dump_AM_MEDIA_TYPE(pmt); + mark_wine_thread(); + EnterCriticalSection(This->pin.pCritSec); if (!This->pin.pConnectedTo) { ALLOCATOR_PROPERTIES props; @@ -1689,6 +1876,7 @@ This->pin.pConnectedTo = pReceivePin; IPin_AddRef(pReceivePin); hr = IMemAllocator_Commit(This->pAlloc); + SetEvent(((GSTImpl*)This->pin.pinInfo.pFilter)->event); } else { GST_RemoveOutputPins((GSTImpl *)This->pin.pinInfo.pFilter); if (This->pReader) @@ -1705,11 +1893,15 @@ return hr; } -static HRESULT WINAPI GSTInPin_Disconnect(IPin *iface) { +static HRESULT WINAPI GSTInPin_Disconnect(IPin *iface) +{ HRESULT hr; GSTInPin *This = (GSTInPin*)iface; FILTER_STATE state; - TRACE("()\n"); + + TRACE("(%p)\n", This); + + mark_wine_thread(); hr = IBaseFilter_GetState(This->pin.pinInfo.pFilter, INFINITE, &state); EnterCriticalSection(This->pin.pCritSec); @@ -1729,7 +1921,8 @@ return hr; } -static HRESULT WINAPI GSTInPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt) { +static HRESULT WINAPI GSTInPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt) +{ GSTInPin *This = (GSTInPin*)iface; TRACE("(%p)->(%p)\n", This, pmt); @@ -1740,7 +1933,8 @@ return S_FALSE; } -static HRESULT WINAPI GSTInPin_EndOfStream(IPin *iface) { +static HRESULT WINAPI GSTInPin_EndOfStream(IPin *iface) +{ GSTInPin *pin = (GSTInPin*)iface; GSTImpl *This = (GSTImpl*)pin->pin.pinInfo.pFilter; @@ -1748,7 +1942,8 @@ return S_OK; } -static HRESULT WINAPI GSTInPin_BeginFlush(IPin *iface) { +static HRESULT WINAPI GSTInPin_BeginFlush(IPin *iface) +{ GSTInPin *pin = (GSTInPin*)iface; GSTImpl *This = (GSTImpl*)pin->pin.pinInfo.pFilter; @@ -1756,7 +1951,8 @@ return S_OK; } -static HRESULT WINAPI GSTInPin_EndFlush(IPin *iface) { +static HRESULT WINAPI GSTInPin_EndFlush(IPin *iface) +{ GSTInPin *pin = (GSTInPin*)iface; GSTImpl *This = (GSTImpl*)pin->pin.pinInfo.pFilter; @@ -1764,7 +1960,8 @@ return S_OK; } -static HRESULT WINAPI GSTInPin_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) { +static HRESULT WINAPI GSTInPin_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) +{ GSTInPin *pin = (GSTInPin*)iface; GSTImpl *This = (GSTImpl*)pin->pin.pinInfo.pFilter; @@ -1830,3 +2027,162 @@ GSTInPin_EndFlush, GSTInPin_NewSegment }; + +pthread_mutex_t cb_list_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cb_list_cond = PTHREAD_COND_INITIALIZER; +struct list cb_list = LIST_INIT(cb_list); + +void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) +{ + struct cb_data *cbdata = user; + + TRACE("got cb type: 0x%x\n", cbdata->type); + + switch(cbdata->type) + { + case WATCH_BUS: + { + struct watch_bus_data *data = &cbdata->u.watch_bus_data; + cbdata->u.watch_bus_data.ret = watch_bus(data->bus, data->msg, data->user); + break; + } + case EXISTING_NEW_PAD: + { + struct existing_new_pad_data *data = &cbdata->u.existing_new_pad_data; + existing_new_pad(data->bin, data->pad, data->user); + break; + } + case QUERY_FUNCTION: + { + struct query_function_data *data = &cbdata->u.query_function_data; + cbdata->u.query_function_data.ret = query_function(data->pad, data->parent, data->query); + break; + } + case ACTIVATE_MODE: + { + struct activate_mode_data *data = &cbdata->u.activate_mode_data; + cbdata->u.activate_mode_data.ret = activate_mode(data->pad, data->parent, data->mode, data->activate); + break; + } + case NO_MORE_PADS: + { + struct no_more_pads_data *data = &cbdata->u.no_more_pads_data; + no_more_pads(data->decodebin, data->user); + break; + } + case REQUEST_BUFFER_SRC: + { + struct request_buffer_src_data *data = &cbdata->u.request_buffer_src_data; + cbdata->u.request_buffer_src_data.ret = request_buffer_src(data->pad, data->parent, + data->ofs, data->len, data->buf); + break; + } + case EVENT_SRC: + { + struct event_src_data *data = &cbdata->u.event_src_data; + cbdata->u.event_src_data.ret = event_src(data->pad, data->parent, data->event); + break; + } + case EVENT_SINK: + { + struct event_sink_data *data = &cbdata->u.event_sink_data; + cbdata->u.event_sink_data.ret = event_sink(data->pad, data->parent, data->event); + break; + } + case ACCEPT_CAPS_SINK: + { + struct accept_caps_sink_data *data = &cbdata->u.accept_caps_sink_data; + cbdata->u.accept_caps_sink_data.ret = accept_caps_sink(data->pad, data->caps); + break; + } + case SETCAPS_SINK: + { + struct setcaps_sink_data *data = &cbdata->u.setcaps_sink_data; + cbdata->u.setcaps_sink_data.ret = setcaps_sink(data->pad, data->caps); + break; + } + case GOT_DATA_SINK: + { + struct got_data_sink_data *data = &cbdata->u.got_data_sink_data; + cbdata->u.got_data_sink_data.ret = got_data_sink(data->pad, data->parent, data->buf); + break; + } + case GOT_DATA: + { + struct got_data_data *data = &cbdata->u.got_data_data; + cbdata->u.got_data_data.ret = got_data(data->pad, data->parent, data->buf); + break; + } + case REMOVED_DECODED_PAD: + { + struct removed_decoded_pad_data *data = &cbdata->u.removed_decoded_pad_data; + removed_decoded_pad(data->bin, data->pad, data->user); + break; + } + case AUTOPLUG_BLACKLIST: + { + struct autoplug_blacklist_data *data = &cbdata->u.autoplug_blacklist_data; + cbdata->u.autoplug_blacklist_data.ret = autoplug_blacklist(data->bin, + data->pad, data->caps, data->fact, data->user); + break; + } + case UNKNOWN_TYPE: + { + struct unknown_type_data *data = &cbdata->u.unknown_type_data; + unknown_type(data->bin, data->pad, data->caps, data->user); + break; + } + case RELEASE_SAMPLE: + { + struct release_sample_data *data = &cbdata->u.release_sample_data; + release_sample(data->data); + break; + } + case TRANSFORM_PAD_ADDED: + { + struct transform_pad_added_data *data = &cbdata->u.transform_pad_added_data; + Gstreamer_transform_pad_added(data->filter, data->pad, data->user); + break; + } + case QUERY_SINK: + { + struct query_sink_data *data = &cbdata->u.query_sink_data; + cbdata->u.query_sink_data.ret = query_sink(data->pad, data->parent, + data->query); + break; + } + } + + pthread_mutex_lock(&cbdata->lock); + cbdata->finished = 1; + pthread_cond_broadcast(&cbdata->cond); + pthread_mutex_unlock(&cbdata->lock); +} + +static DWORD WINAPI dispatch_thread(void *user) +{ + struct cb_data *cbdata; + + pthread_mutex_lock(&cb_list_lock); + + while(1){ + pthread_cond_wait(&cb_list_cond, &cb_list_lock); + + while(!list_empty(&cb_list)){ + cbdata = LIST_ENTRY(list_head(&cb_list), struct cb_data, entry); + list_remove(&cbdata->entry); + + TrySubmitThreadpoolCallback(&perform_cb, cbdata, NULL); + } + } + + pthread_mutex_unlock(&cb_list_lock); + + return 0; +} + +void start_dispatch_thread(void) +{ + pthread_key_create(&wine_gst_key, NULL); + CloseHandle(CreateThread(NULL, 0, &dispatch_thread, NULL, 0, NULL)); +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/gst_private.h wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/gst_private.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/gst_private.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/gst_private.h 2016-02-08 19:32:34.000000000 +0000 @@ -42,6 +42,14 @@ IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *pUnkOuter, HRESULT *phr); IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr); -void g_thread_impl_init(void); DWORD Gstreamer_init(void); + +GstFlowReturn got_data(GstPad *pad, GstObject *parent, GstBuffer *buf) DECLSPEC_HIDDEN; +GstFlowReturn request_buffer(GstPad *pad, guint64 ofs, guint size, GstCaps *caps, GstBuffer **buf) DECLSPEC_HIDDEN; +void Gstreamer_transform_pad_added(GstElement *filter, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; + +void start_dispatch_thread(void) DECLSPEC_HIDDEN; + +extern const char *media_quark_string DECLSPEC_HIDDEN; + #endif /* __GST_PRIVATE_INCLUDED__ */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/gsttffilter.c wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/gsttffilter.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/gsttffilter.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/gsttffilter.c 2016-02-08 19:32:34.000000000 +0000 @@ -22,12 +22,13 @@ #include "config.h" -#include -#include -#include +#include +#include +#include #include "gst_private.h" #include "gst_guids.h" +#include "gst_cbs.h" #include "uuids.h" #include "mmreg.h" @@ -58,7 +59,8 @@ static const IBaseFilterVtbl GSTTf_Vtbl; -static gboolean match_element(GstPluginFeature *feature, gpointer gdata) { +static gboolean match_element(GstPluginFeature *feature, gpointer gdata) +{ struct typeinfo *data = (struct typeinfo*)gdata; GstElementFactory *factory; const GList *list; @@ -91,9 +93,11 @@ GstElementFactory *bestfactory = NULL; GstCaps *caps = gst_caps_from_string(strcaps); + TRACE("%s\n", strcaps); + data.caps = caps; data.type = "Decoder"; - copy = gst_default_registry_feature_filter(match_element, 0, &data); + copy = gst_registry_feature_filter(gst_registry_get(), match_element, 0, &data); for (list = copy; list; list = list->next) { GstElementFactory *factory = (GstElementFactory*)list->data; guint rank; @@ -121,10 +125,13 @@ LONG cbBuffer; } GstTfImpl; -static HRESULT WINAPI Gstreamer_transform_ProcessBegin(TransformFilter *iface) { +static HRESULT WINAPI Gstreamer_transform_ProcessBegin(TransformFilter *iface) +{ GstTfImpl *This = (GstTfImpl*)iface; int ret; + mark_wine_thread(); + ret = gst_element_set_state(This->filter, GST_STATE_PLAYING); TRACE("Returned: %i\n", ret); return S_OK; @@ -135,6 +142,8 @@ GstTfImpl *This = (GstTfImpl*)tf; ALLOCATOR_PROPERTIES actual; + TRACE("%p, %p, %p\n", This, pAlloc, ppropInputRequest); + if (!ppropInputRequest->cbAlign) ppropInputRequest->cbAlign = 1; @@ -146,20 +155,39 @@ return IMemAllocator_SetProperties(pAlloc, ppropInputRequest, &actual); } -static void release_sample(void *data) { - TRACE("Releasing %p\n", data); - IMediaSample_Release((IMediaSample *)data); -} - -static GstFlowReturn got_data(GstPad *pad, GstBuffer *buf) { +GstFlowReturn got_data(GstPad *pad, GstObject *parent, GstBuffer *buf) +{ GstTfImpl *This = gst_pad_get_element_private(pad); - IMediaSample *sample = GST_APP_BUFFER(buf)->priv; + IMediaSample *sample = (IMediaSample *) gst_mini_object_get_qdata(GST_MINI_OBJECT(buf), g_quark_from_static_string(media_quark_string)); REFERENCE_TIME tStart, tStop; HRESULT hr; - if (GST_BUFFER_TIMESTAMP_IS_VALID(buf) && + TRACE("%p, %p\n", pad, buf); + + if(!sample){ + GstMapInfo info; + BYTE *ptr; + + gst_buffer_map(buf, &info, GST_MAP_READ); + + hr = BaseOutputPinImpl_GetDeliveryBuffer((BaseOutputPin*)This->tf.ppPins[1], &sample, NULL, NULL, 0); + if (FAILED(hr)) { + ERR("Could not get output buffer: %08x\n", hr); + return GST_FLOW_FLUSHING; + } + + IMediaSample_SetActualDataLength(sample, info.size); + + IMediaSample_GetPointer(sample, &ptr); + + memcpy(ptr, info.data, info.size); + + gst_buffer_unmap(buf, &info); + } + + if (GST_BUFFER_PTS_IS_VALID(buf) && GST_BUFFER_DURATION_IS_VALID(buf)) { - tStart = buf->timestamp / 100; + tStart = buf->pts / 100; tStop = tStart + buf->duration / 100; IMediaSample_SetTime(sample, &tStart, &tStop); } @@ -175,68 +203,51 @@ IMediaSample_SetMediaTime(sample, NULL, NULL); IMediaSample_SetDiscontinuity(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DISCONT)); - IMediaSample_SetPreroll(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_PREROLL)); + IMediaSample_SetPreroll(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_LIVE)); IMediaSample_SetSyncPoint(sample, !GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT)); - IMediaSample_SetActualDataLength(sample, GST_BUFFER_SIZE(buf)); + IMediaSample_SetActualDataLength(sample, gst_buffer_get_size(buf)); hr = BaseOutputPinImpl_Deliver((BaseOutputPin*)This->tf.ppPins[1], sample); + IMediaSample_Release(sample); gst_buffer_unref(buf); if (FAILED(hr)) - return GST_FLOW_WRONG_STATE; - if (hr != S_OK) - return GST_FLOW_RESEND; - return GST_FLOW_OK; -} - -static GstFlowReturn request_buffer(GstPad *pad, guint64 ofs, guint size, GstCaps *caps, GstBuffer **buf) { - GstTfImpl *This = gst_pad_get_element_private(pad); - IMediaSample *sample; - BYTE *ptr; - HRESULT hr; - TRACE("Requesting buffer\n"); - - hr = BaseOutputPinImpl_GetDeliveryBuffer((BaseOutputPin*)This->tf.ppPins[1], &sample, NULL, NULL, 0); - if (FAILED(hr)) { - ERR("Could not get output buffer: %08x\n", hr); - return GST_FLOW_WRONG_STATE; - } - IMediaSample_SetActualDataLength(sample, size); - IMediaSample_GetPointer(sample, &ptr); - *buf = gst_app_buffer_new(ptr, size, release_sample, sample); - - if (!*buf) { - IMediaSample_Release(sample); - ERR("Out of memory\n"); - return GST_FLOW_ERROR; - } - if (!caps) - caps = gst_pad_get_caps_reffed(This->my_sink); - gst_buffer_set_caps(*buf, caps); + return GST_FLOW_FLUSHING; return GST_FLOW_OK; } -static HRESULT WINAPI Gstreamer_transform_ProcessData(TransformFilter *iface, IMediaSample *sample) { +static HRESULT WINAPI Gstreamer_transform_ProcessData(TransformFilter *iface, IMediaSample *sample) +{ GstTfImpl *This = (GstTfImpl*)iface; REFERENCE_TIME tStart, tStop; BYTE *data; GstBuffer *buf; HRESULT hr; + DWORD bufsize; int ret; - TRACE("Reading %p\n", sample); + + TRACE("%p, %p\n", This, sample); + + mark_wine_thread(); EnterCriticalSection(&This->tf.csReceive); IMediaSample_GetPointer(sample, &data); - buf = gst_app_buffer_new(data, IMediaSample_GetActualDataLength(sample), release_sample, sample); + + IMediaSample_AddRef(sample); + bufsize = IMediaSample_GetActualDataLength(sample); + buf = gst_buffer_new_wrapped_full(0, data, bufsize, 0, bufsize, sample, release_sample_wrapper); if (!buf) { + IMediaSample_Release(sample); LeaveCriticalSection(&This->tf.csReceive); return S_OK; } - gst_buffer_set_caps(buf, gst_pad_get_caps_reffed(This->my_src)); + IMediaSample_AddRef(sample); - buf->duration = buf->timestamp = -1; + gst_mini_object_set_qdata(GST_MINI_OBJECT(buf), g_quark_from_static_string(media_quark_string), sample, release_sample_wrapper); + + buf->duration = buf->pts = -1; hr = IMediaSample_GetTime(sample, &tStart, &tStop); if (SUCCEEDED(hr)) { - buf->timestamp = tStart * 100; + buf->pts = tStart * 100; if (hr == S_OK) buf->duration = (tStop - tStart)*100; } @@ -247,26 +258,25 @@ if (IMediaSample_IsDiscontinuity(sample) == S_OK) GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_DISCONT); if (IMediaSample_IsPreroll(sample) == S_OK) - GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_PREROLL); + GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_LIVE); if (IMediaSample_IsSyncPoint(sample) != S_OK) GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT); LeaveCriticalSection(&This->tf.csReceive); ret = gst_pad_push(This->my_src, buf); if (ret) WARN("Sending returned: %i\n", ret); - if (ret == GST_FLOW_ERROR) - return E_FAIL; - if (ret == GST_FLOW_WRONG_STATE) + if (ret == GST_FLOW_FLUSHING) return VFW_E_WRONG_STATE; - if (ret == GST_FLOW_RESEND) - return S_FALSE; return S_OK; } -static HRESULT WINAPI Gstreamer_transform_ProcessEnd(TransformFilter *iface) { +static HRESULT WINAPI Gstreamer_transform_ProcessEnd(TransformFilter *iface) +{ GstTfImpl *This = (GstTfImpl*)iface; int ret; + mark_wine_thread(); + LeaveCriticalSection(&This->tf.csReceive); ret = gst_element_set_state(This->filter, GST_STATE_READY); EnterCriticalSection(&This->tf.csReceive); @@ -274,9 +284,13 @@ return S_OK; } -static void Gstreamer_transform_pad_added(GstElement *filter, GstPad *pad, GstTfImpl *This) +void Gstreamer_transform_pad_added(GstElement *filter, GstPad *pad, gpointer user) { + GstTfImpl *This = (GstTfImpl*)user; int ret; + + TRACE("%p %p %p\n", This, filter, pad); + if (!GST_PAD_IS_SRC(pad)) return; @@ -284,51 +298,44 @@ if (ret < 0) WARN("Failed to link with %i\n", ret); This->their_src = pad; - - gst_pad_set_active(pad, TRUE); - gst_pad_set_active(This->my_sink, TRUE); } -static HRESULT Gstreamer_transform_ConnectInput(GstTfImpl *This, const AM_MEDIA_TYPE *amt, GstCaps *capsin, GstCaps *capsout) { +static HRESULT Gstreamer_transform_ConnectInput(GstTfImpl *This, const AM_MEDIA_TYPE *amt, GstCaps *capsin, GstCaps *capsout) +{ GstIterator *it; BOOL done = FALSE, found = FALSE; int ret; + TRACE("%p %p %p %p\n", This, amt, capsin, capsout); + + mark_wine_thread(); + This->filter = gst_element_factory_make(This->gstreamer_name, NULL); if (!This->filter) { FIXME("Could not make %s filter\n", This->gstreamer_name); return E_FAIL; } - This->my_src = gst_pad_new(NULL, GST_PAD_SRC); + This->my_src = gst_pad_new("yuvsrc", GST_PAD_SRC); gst_pad_set_element_private (This->my_src, This); + gst_pad_set_active(This->my_src, 1); - This->my_sink = gst_pad_new(NULL, GST_PAD_SINK); - gst_pad_set_chain_function(This->my_sink, got_data); - gst_pad_set_bufferalloc_function(This->my_sink, request_buffer); + This->my_sink = gst_pad_new("yuvsink", GST_PAD_SINK); + gst_pad_set_chain_function(This->my_sink, got_data_wrapper); gst_pad_set_element_private (This->my_sink, This); - - ret = gst_pad_set_caps(This->my_src, capsin); - if (ret < 0) { - WARN("Failed to set caps on own source with %i\n", ret); - return E_FAIL; - } - - ret = gst_pad_set_caps(This->my_sink, capsout); - if (ret < 0) { - WARN("Failed to set caps on own sink with %i\n", ret); - return E_FAIL; - } + gst_pad_set_active(This->my_sink, 1); it = gst_element_iterate_sink_pads(This->filter); while (!done) { - gpointer item; + GValue item = {0}; switch (gst_iterator_next(it, &item)) { case GST_ITERATOR_RESYNC: gst_iterator_resync (it); break; case GST_ITERATOR_OK: - This->their_sink = item; + This->their_sink = g_value_get_object(&item); + gst_object_ref(This->their_sink); + g_value_reset(&item); case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: done = TRUE; @@ -345,14 +352,16 @@ gst_iterator_resync(it); done = FALSE; while (!done) { - gpointer item; + GValue item = {0}; switch (gst_iterator_next(it, &item)) { case GST_ITERATOR_RESYNC: gst_iterator_resync (it); break; case GST_ITERATOR_OK: - This->their_src = item; + This->their_src = g_value_get_object(&item); + gst_object_ref(This->their_src); + g_value_reset(&item); case GST_ITERATOR_ERROR: case GST_ITERATOR_DONE: done = TRUE; @@ -362,26 +371,43 @@ gst_iterator_free(it); found = !!This->their_src; if (!found) - g_signal_connect(This->filter, "pad-added", G_CALLBACK(Gstreamer_transform_pad_added), This); + g_signal_connect(This->filter, "pad-added", G_CALLBACK(Gstreamer_transform_pad_added_wrapper), This); ret = gst_pad_link(This->my_src, This->their_sink); if (ret < 0) { WARN("Failed to link with %i\n", ret); return E_FAIL; } + ret = gst_pad_set_caps(This->my_src, capsin); + if (ret < 0) { + WARN("Failed to set caps on own source with %i\n", ret); + return E_FAIL; + } + if (found) Gstreamer_transform_pad_added(This->filter, This->their_src, This); if (!gst_pad_is_linked(This->my_sink)) return E_FAIL; + ret = gst_pad_set_caps(This->my_sink, capsout); + if (ret < 0) { + WARN("Failed to set caps on own sink with %i\n", ret); + return E_FAIL; + } + TRACE("Connected\n"); return S_OK; } -static HRESULT WINAPI Gstreamer_transform_Cleanup(TransformFilter *tf, PIN_DIRECTION dir) { +static HRESULT WINAPI Gstreamer_transform_Cleanup(TransformFilter *tf, PIN_DIRECTION dir) +{ GstTfImpl *This = (GstTfImpl*)tf; + TRACE("%p 0x%x\n", This, dir); + + mark_wine_thread(); + if (dir == PINDIR_INPUT) { if (This->filter) { @@ -392,72 +418,95 @@ if (This->my_src) { gst_pad_unlink(This->my_src, This->their_sink); gst_object_unref(This->my_src); + gst_object_unref(This->their_sink); } if (This->my_sink) { gst_pad_unlink(This->their_src, This->my_sink); gst_object_unref(This->my_sink); + gst_object_unref(This->their_src); } This->my_sink = This->my_src = This->their_sink = This->their_src = NULL; } return S_OK; } -static HRESULT WINAPI Gstreamer_transform_EndOfStream(TransformFilter *iface) { +static HRESULT WINAPI Gstreamer_transform_EndOfStream(TransformFilter *iface) +{ GstTfImpl *This = (GstTfImpl*)iface; TRACE("%p\n", This); + mark_wine_thread(); gst_pad_push_event(This->my_src, gst_event_new_eos()); return S_OK; } -static HRESULT WINAPI Gstreamer_transform_BeginFlush(TransformFilter *iface) { +static HRESULT WINAPI Gstreamer_transform_BeginFlush(TransformFilter *iface) +{ GstTfImpl *This = (GstTfImpl*)iface; TRACE("%p\n", This); + mark_wine_thread(); gst_pad_push_event(This->my_src, gst_event_new_flush_start()); return S_OK; } -static HRESULT WINAPI Gstreamer_transform_EndFlush(TransformFilter *iface) { +static HRESULT WINAPI Gstreamer_transform_EndFlush(TransformFilter *iface) +{ GstTfImpl *This = (GstTfImpl*)iface; TRACE("%p\n", This); + mark_wine_thread(); - gst_pad_push_event(This->my_src, gst_event_new_flush_stop()); + gst_pad_push_event(This->my_src, gst_event_new_flush_stop(TRUE)); return S_OK; } -static HRESULT WINAPI Gstreamer_transform_NewSegment(TransformFilter *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) { +static HRESULT WINAPI Gstreamer_transform_NewSegment(TransformFilter *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) +{ GstTfImpl *This = (GstTfImpl*)iface; + const GstSegment segment = { GST_SEGMENT_FLAG_NONE, 1.0, dRate, GST_FORMAT_TIME, 0, 0, 0, tStop <= tStart ? -1 : tStop * 100, 0, tStart*100, -1 }; + TRACE("%p\n", This); + mark_wine_thread(); + + gst_pad_push_event(This->my_src, gst_event_new_segment(&segment)); - gst_pad_push_event(This->my_src, gst_event_new_new_segment_full(1, - 1.0, dRate, GST_FORMAT_TIME, 0, tStop <= tStart ? -1 : tStop * 100, tStart*100)); return S_OK; } -static HRESULT WINAPI Gstreamer_transform_QOS(TransformFilter *iface, IBaseFilter *sender, Quality qm) { +static HRESULT WINAPI Gstreamer_transform_QOS(TransformFilter *iface, IBaseFilter *sender, Quality qm) +{ GstTfImpl *This = (GstTfImpl*)iface; REFERENCE_TIME late = qm.Late; + + TRACE("%p %p qm\n", This, sender); + + mark_wine_thread(); + if (qm.Late < 0 && -qm.Late > qm.TimeStamp) late = -qm.TimeStamp; - gst_pad_push_event(This->my_sink, gst_event_new_qos(1000. / qm.Proportion, late * 100, qm.TimeStamp * 100)); + gst_pad_push_event(This->my_sink, gst_event_new_qos(late <= 0 ? GST_QOS_TYPE_OVERFLOW : GST_QOS_TYPE_UNDERFLOW, 1000. / qm.Proportion, late * 100, qm.TimeStamp * 100)); return TransformFilterImpl_Notify(iface, sender, qm); } -static HRESULT Gstreamer_transform_create(IUnknown *punkout, const CLSID *clsid, const char *name, const TransformFilterFuncTable *vtbl, void **obj) +static HRESULT Gstreamer_transform_create(IUnknown *punkouter, const CLSID *clsid, const char *name, const TransformFilterFuncTable *vtbl, void **obj) { GstTfImpl *This; + TRACE("%p, %p, %p, %p, %p\n", punkouter, clsid, name, vtbl, obj); + if (FAILED(TransformFilter_Construct(&GSTTf_Vtbl, sizeof(GstTfImpl), clsid, vtbl, (IBaseFilter**)&This))) return E_OUTOFMEMORY; This->gstreamer_name = name; *obj = This; + TRACE("returning %p\n", This); + return S_OK; } -static HRESULT WINAPI Gstreamer_Mp3_QueryConnect(TransformFilter *iface, const AM_MEDIA_TYPE *amt) { +static HRESULT WINAPI Gstreamer_Mp3_QueryConnect(TransformFilter *iface, const AM_MEDIA_TYPE *amt) +{ GstTfImpl *This = (GstTfImpl*)iface; TRACE("%p %p\n", This, amt); dump_AM_MEDIA_TYPE(amt); @@ -466,13 +515,15 @@ !IsEqualGUID(&amt->majortype, &MEDIATYPE_Stream)) || (!IsEqualGUID(&amt->subtype, &MEDIASUBTYPE_MPEG1AudioPayload) && !IsEqualGUID(&amt->subtype, &WMMEDIASUBTYPE_MP3)) - || !IsEqualGUID(&amt->formattype, &FORMAT_WaveFormatEx)) + || !IsEqualGUID(&amt->formattype, &FORMAT_WaveFormatEx)){ return S_FALSE; + } return S_OK; } -static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt) { +static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt) +{ GstTfImpl *This = (GstTfImpl*)tf; GstCaps *capsin, *capsout; AM_MEDIA_TYPE *outpmt = &This->tf.pmt; @@ -480,6 +531,10 @@ HRESULT hr; int layer; + TRACE("%p 0x%x %p\n", This, dir, amt); + + mark_wine_thread(); + if (dir != PINDIR_INPUT) return S_OK; @@ -524,11 +579,8 @@ "rate", G_TYPE_INT, wfx->nSamplesPerSec, "channels", G_TYPE_INT, wfx->nChannels, NULL); - capsout = gst_caps_new_simple("audio/x-raw-int", - "endianness", G_TYPE_INT, 1234, - "signed", G_TYPE_BOOLEAN, 1, - "width", G_TYPE_INT, 16, - "depth", G_TYPE_INT, 16, + capsout = gst_caps_new_simple("audio/x-raw", + "format", G_TYPE_STRING, "S16LE" "rate", G_TYPE_INT, wfx->nSamplesPerSec, "channels", G_TYPE_INT, wfx->nChannels, NULL); @@ -544,6 +596,7 @@ static HRESULT WINAPI Gstreamer_Mp3_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin) { + TRACE("%p 0x%x %p\n", tf, dir, pin); return S_OK; } @@ -563,26 +616,37 @@ Gstreamer_transform_QOS }; -IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *punkout, HRESULT *phr) +IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *punkouter, HRESULT *phr) { const char *plugin; IUnknown *obj = NULL; + + TRACE("%p %p\n", punkouter, phr); + if (!Gstreamer_init()) { *phr = E_FAIL; return NULL; } + + mark_wine_thread(); + plugin = Gstreamer_FindMatch("audio/mpeg, mpegversion=(int) 1"); if (!plugin) { *phr = E_FAIL; return NULL; } - *phr = Gstreamer_transform_create(punkout, &CLSID_Gstreamer_Mp3, plugin, &Gstreamer_Mp3_vtbl, (LPVOID*)&obj); + + *phr = Gstreamer_transform_create(punkouter, &CLSID_Gstreamer_Mp3, plugin, &Gstreamer_Mp3_vtbl, (LPVOID*)&obj); + + TRACE("returning %p\n", obj); + return obj; } -static HRESULT WINAPI Gstreamer_YUV_QueryConnect(TransformFilter *iface, const AM_MEDIA_TYPE *amt) { +static HRESULT WINAPI Gstreamer_YUV_QueryConnect(TransformFilter *iface, const AM_MEDIA_TYPE *amt) +{ GstTfImpl *This = (GstTfImpl*)iface; TRACE("%p %p\n", This, amt); dump_AM_MEDIA_TYPE(amt); @@ -609,10 +673,12 @@ static HRESULT WINAPI Gstreamer_YUV_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin) { + TRACE("%p 0x%x %p\n", tf, dir, pin); return S_OK; } -static HRESULT WINAPI Gstreamer_YUV_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt) { +static HRESULT WINAPI Gstreamer_YUV_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt) +{ GstTfImpl *This = (GstTfImpl*)tf; GstCaps *capsin, *capsout; AM_MEDIA_TYPE *outpmt = &This->tf.pmt; @@ -620,6 +686,10 @@ int avgtime; LONG width, height; + TRACE("%p 0x%x %p\n", This, dir, amt); + + mark_wine_thread(); + if (dir != PINDIR_INPUT) return S_OK; @@ -655,22 +725,19 @@ outpmt->subtype = MEDIASUBTYPE_RGB24; - capsin = gst_caps_new_simple("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, amt->subtype.Data1, + capsin = gst_caps_new_simple("video/x-raw", + "format", G_TYPE_STRING, + gst_video_format_to_string( + gst_video_format_from_fourcc(amt->subtype.Data1)), "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, "framerate", GST_TYPE_FRACTION, 10000000, avgtime, NULL); - capsout = gst_caps_new_simple("video/x-raw-rgb", - "endianness", G_TYPE_INT, 4321, + capsout = gst_caps_new_simple("video/x-raw", + "format", G_TYPE_STRING, "BGR", "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, "framerate", GST_TYPE_FRACTION, 10000000, avgtime, - "bpp", G_TYPE_INT, 24, - "depth", G_TYPE_INT, 24, - "red_mask", G_TYPE_INT, 0xff, - "green_mask", G_TYPE_INT, 0xff00, - "blue_mask", G_TYPE_INT, 0xff0000, NULL); hr = Gstreamer_transform_ConnectInput(This, amt, capsin, capsout); @@ -697,19 +764,27 @@ Gstreamer_transform_QOS }; -IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *punkout, HRESULT *phr) +IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *punkouter, HRESULT *phr) { IUnknown *obj = NULL; + + TRACE("%p %p\n", punkouter, phr); + if (!Gstreamer_init()) { *phr = E_FAIL; return NULL; } - *phr = Gstreamer_transform_create(punkout, &CLSID_Gstreamer_YUV, "ffmpegcolorspace", &Gstreamer_YUV_vtbl, (LPVOID*)&obj); + + *phr = Gstreamer_transform_create(punkouter, &CLSID_Gstreamer_YUV, "videoconvert", &Gstreamer_YUV_vtbl, (LPVOID*)&obj); + + TRACE("returning %p\n", obj); + return obj; } -static HRESULT WINAPI Gstreamer_AudioConvert_QueryConnect(TransformFilter *iface, const AM_MEDIA_TYPE *amt) { +static HRESULT WINAPI Gstreamer_AudioConvert_QueryConnect(TransformFilter *iface, const AM_MEDIA_TYPE *amt) +{ GstTfImpl *This = (GstTfImpl*)iface; TRACE("%p %p\n", This, amt); dump_AM_MEDIA_TYPE(amt); @@ -723,20 +798,27 @@ static HRESULT WINAPI Gstreamer_AudioConvert_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin) { + TRACE("%p 0x%x %p\n", tf, dir, pin); return S_OK; } -static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt) { +static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt) +{ GstTfImpl *This = (GstTfImpl*)tf; GstCaps *capsin, *capsout; AM_MEDIA_TYPE *outpmt = &This->tf.pmt; WAVEFORMATEX *inwfe; WAVEFORMATEX *outwfe; WAVEFORMATEXTENSIBLE *outwfx; + GstAudioFormat format; HRESULT hr; BOOL inisfloat = FALSE; int indepth; + TRACE("%p 0x%x %p\n", This, dir, amt); + + mark_wine_thread(); + if (dir != PINDIR_INPUT) return S_OK; @@ -758,10 +840,12 @@ indepth = inwfx->Samples.wValidBitsPerSample; } - capsin = gst_caps_new_simple(inisfloat ? "audio/x-raw-float" : "audio/x-raw-int", - "endianness", G_TYPE_INT, 1234, - "width", G_TYPE_INT, inwfe->wBitsPerSample, - "depth", G_TYPE_INT, indepth, + format = inisfloat ? (inwfe->wBitsPerSample == 64 ? GST_AUDIO_FORMAT_F64LE : GST_AUDIO_FORMAT_F32LE) + : gst_audio_format_build_integer(inwfe->wBitsPerSample == 8 ? FALSE : TRUE, + inwfe->wBitsPerSample, + indepth, G_LITTLE_ENDIAN); + capsin = gst_caps_new_simple("audio/x-raw", + "format", G_TYPE_STRING, gst_audio_format_to_string(format), "channels", G_TYPE_INT, inwfe->nChannels, "rate", G_TYPE_INT, inwfe->nSamplesPerSec, NULL); @@ -779,14 +863,13 @@ outwfx->dwChannelMask = SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT; outwfx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; - capsout = gst_caps_new_simple("audio/x-raw-int", - "endianness", G_TYPE_INT, 1234, - "width", G_TYPE_INT, outwfe->wBitsPerSample, - "depth", G_TYPE_INT, outwfx->Samples.wValidBitsPerSample, + capsout = gst_caps_new_simple("audio/x-raw", + "format", G_TYPE_STRING, "S16LE", "channels", G_TYPE_INT, outwfe->nChannels, "rate", G_TYPE_INT, outwfe->nSamplesPerSec, NULL); + hr = Gstreamer_transform_ConnectInput(This, amt, capsin, capsout); gst_caps_unref(capsin); gst_caps_unref(capsout); @@ -811,15 +894,22 @@ Gstreamer_transform_QOS }; -IUnknown * CALLBACK Gstreamer_AudioConvert_create(IUnknown *punkout, HRESULT *phr) +IUnknown * CALLBACK Gstreamer_AudioConvert_create(IUnknown *punkouter, HRESULT *phr) { IUnknown *obj = NULL; + + TRACE("%p %p\n", punkouter, phr); + if (!Gstreamer_init()) { *phr = E_FAIL; return NULL; } - *phr = Gstreamer_transform_create(punkout, &CLSID_Gstreamer_AudioConvert, "audioconvert", &Gstreamer_AudioConvert_vtbl, (LPVOID*)&obj); + + *phr = Gstreamer_transform_create(punkouter, &CLSID_Gstreamer_AudioConvert, "audioconvert", &Gstreamer_AudioConvert_vtbl, (LPVOID*)&obj); + + TRACE("returning %p\n", obj); + return obj; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/main.c 2016-02-08 19:32:34.000000000 +0000 @@ -22,9 +22,7 @@ #include #include -#include -#include -#include +#include #include "windef.h" #include "winbase.h" @@ -242,7 +240,8 @@ TRACE("\t%s\n\t%s\n\t...\n\t%s\n", debugstr_guid(&pmt->majortype), debugstr_guid(&pmt->subtype), debugstr_guid(&pmt->formattype)); } -DWORD Gstreamer_init(void) { +DWORD Gstreamer_init(void) +{ static int inited; if (!inited) { @@ -251,10 +250,12 @@ char **argv = HeapAlloc(GetProcessHeap(), 0, sizeof(char *)*3); int argc = 2; GError *err = NULL; + + TRACE("initializing\n"); + argv[0] = argv0; argv[1] = argv1; argv[2] = NULL; - g_thread_impl_init(); inited = gst_init_check(&argc, &argv, &err); HeapFree(GetProcessHeap(), 0, argv); if (err) { @@ -269,6 +270,8 @@ (LPCWSTR)hInst, &newhandle); if (!newhandle) ERR("Could not pin module %p\n", hInst); + + start_dispatch_thread(); } } return inited; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winegstreamer/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winegstreamer/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -4,7 +4,7 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS) C_SRCS = \ - glibthread.c \ + gst_cbs.c \ gstdemux.c \ gsttffilter.c \ main.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/cocoa_event.h wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/cocoa_event.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/cocoa_event.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/cocoa_event.h 2016-02-08 19:32:34.000000000 +0000 @@ -22,6 +22,12 @@ #include "macdrv_cocoa.h" +enum { + WineQueryProcessEvents = 1 << 0, + WineQueryNoPreemptWait = 1 << 1, +}; + + @class WineWindow; @@ -42,7 +48,7 @@ - (void) postEvent:(macdrv_event*)inEvent; - (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*)window; - - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout processEvents:(BOOL)processEvents; + - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout flags:(NSUInteger)flags; - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout; - (void) resetMouseEventPositions:(CGPoint)pos; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/cocoa_event.m wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/cocoa_event.m --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/cocoa_event.m 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/cocoa_event.m 2016-02-08 19:32:34.000000000 +0000 @@ -294,13 +294,15 @@ }]; } - - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout processEvents:(BOOL)processEvents + - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout flags:(NSUInteger)flags { + int type; macdrv_event* event; NSDate* timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeout]; BOOL timedout; - event = macdrv_create_event(QUERY_EVENT, (WineWindow*)query->window); + type = (flags & WineQueryNoPreemptWait) ? QUERY_EVENT_NO_PREEMPT_WAIT : QUERY_EVENT; + event = macdrv_create_event(type, (WineWindow*)query->window); event->query_event.query = macdrv_retain_query(query); query->done = FALSE; @@ -308,13 +310,13 @@ macdrv_release_event(event); timedout = ![[WineApplicationController sharedController] waitUntilQueryDone:&query->done timeout:timeoutDate - processEvents:processEvents]; + processEvents:(flags & WineQueryProcessEvents) != 0]; return !timedout && query->status; } - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout { - return [self query:query timeout:timeout processEvents:FALSE]; + return [self query:query timeout:timeout flags:0]; } - (void) resetMouseEventPositions:(CGPoint)pos @@ -654,6 +656,7 @@ CFRelease(event->keyboard_changed.input_source); break; case QUERY_EVENT: + case QUERY_EVENT_NO_PREEMPT_WAIT: macdrv_release_query(event->query_event.query); break; case WINDOW_GOT_FOCUS: diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/cocoa_window.m wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/cocoa_window.m --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/cocoa_window.m 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/cocoa_window.m 2016-02-08 19:32:34.000000000 +0000 @@ -649,7 +649,7 @@ query->ime_char_rect.data = [window imeData]; query->ime_char_rect.range = CFRangeMake(aRange.location, aRange.length); - if ([window.queue query:query timeout:1]) + if ([window.queue query:query timeout:0.3 flags:WineQueryNoPreemptWait]) { aRange = NSMakeRange(query->ime_char_rect.range.location, query->ime_char_rect.range.length); ret = NSRectFromCGRect(query->ime_char_rect.rect); @@ -2657,7 +2657,7 @@ query->drag_drop.op = [sender draggingSourceOperationMask]; query->drag_drop.pasteboard = (CFTypeRef)[pb retain]; - [self.queue query:query timeout:3 * 60 processEvents:YES]; + [self.queue query:query timeout:3 * 60 flags:WineQueryProcessEvents]; ret = query->status; macdrv_release_query(query); @@ -3230,11 +3230,11 @@ /*********************************************************************** * macdrv_send_text_input_event */ -int macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, int keyc, void* data) +void macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, int keyc, void* data, int* done) { - __block BOOL ret; - - OnMainThread(^{ + OnMainThreadAsync(^{ + BOOL ret; + macdrv_event* event; WineWindow* window = (WineWindow*)[NSApp keyWindow]; if (![window isKindOfClass:[WineWindow class]]) { @@ -3266,7 +3266,11 @@ } else ret = FALSE; - }); - return ret; + event = macdrv_create_event(SENT_TEXT_INPUT, window); + event->sent_text_input.handled = ret; + event->sent_text_input.done = done; + [[window queue] postEvent:event]; + macdrv_release_event(event); + }); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/event.c wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/event.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/event.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/event.c 2016-02-08 19:32:34.000000000 +0000 @@ -45,8 +45,10 @@ "MOUSE_MOVED_ABSOLUTE", "MOUSE_SCROLL", "QUERY_EVENT", + "QUERY_EVENT_NO_PREEMPT_WAIT", "REASSERT_WINDOW_POSITION", "RELEASE_CAPTURE", + "SENT_TEXT_INPUT", "STATUS_ITEM_MOUSE_BUTTON", "STATUS_ITEM_MOUSE_MOVE", "WINDOW_BROUGHT_FORWARD", @@ -116,8 +118,10 @@ if (mask & QS_SENDMESSAGE) { event_mask |= event_mask_for_type(QUERY_EVENT); + event_mask |= event_mask_for_type(QUERY_EVENT_NO_PREEMPT_WAIT); event_mask |= event_mask_for_type(REASSERT_WINDOW_POSITION); event_mask |= event_mask_for_type(RELEASE_CAPTURE); + event_mask |= event_mask_for_type(SENT_TEXT_INPUT); event_mask |= event_mask_for_type(WINDOW_BROUGHT_FORWARD); event_mask |= event_mask_for_type(WINDOW_CLOSE_REQUESTED); event_mask |= event_mask_for_type(WINDOW_DRAG_BEGIN); @@ -135,7 +139,7 @@ /*********************************************************************** * macdrv_query_event * - * Handler for QUERY_EVENT queries. + * Handler for QUERY_EVENT and QUERY_EVENT_NO_PREEMPT_WAIT queries. */ static void macdrv_query_event(HWND hwnd, const macdrv_event *event) { @@ -237,6 +241,7 @@ macdrv_mouse_scroll(hwnd, event); break; case QUERY_EVENT: + case QUERY_EVENT_NO_PREEMPT_WAIT: macdrv_query_event(hwnd, event); break; case REASSERT_WINDOW_POSITION: @@ -245,6 +250,9 @@ case RELEASE_CAPTURE: macdrv_release_capture(hwnd, event); break; + case SENT_TEXT_INPUT: + macdrv_sent_text_input(event); + break; case STATUS_ITEM_MOUSE_BUTTON: macdrv_status_item_mouse_button(event); break; @@ -336,6 +344,7 @@ } if (data->current_event && data->current_event->type != QUERY_EVENT && + data->current_event->type != QUERY_EVENT_NO_PREEMPT_WAIT && data->current_event->type != APP_QUIT_REQUESTED && data->current_event->type != WINDOW_DRAG_BEGIN) event_mask = 0; /* don't process nested events */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/ime.c wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/ime.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/ime.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/ime.c 2016-02-08 19:32:34.000000000 +0000 @@ -690,7 +690,7 @@ LPIMEPRIVATE myPrivate; HWND hwndDefault; UINT repeat; - INT rc; + int done = 0; TRACE("uVKey 0x%04x uScanCode 0x%04x fuState %u hIMC %p\n", uVKey, uScanCode, fuState, hIMC); @@ -717,9 +717,12 @@ UnlockRealIMC(hIMC); TRACE("Processing Mac 0x%04x\n", vkey); - rc = macdrv_process_text_input(uVKey, uScanCode, repeat, lpbKeyState, hIMC); + macdrv_process_text_input(uVKey, uScanCode, repeat, lpbKeyState, hIMC, &done); - if (!rc) + while (!done) + MsgWaitForMultipleObjectsEx(0, NULL, INFINITE, QS_POSTMESSAGE | QS_SENDMESSAGE, 0); + + if (done < 0) { UINT msgs = 0; UINT msg = (uScanCode & 0x8000) ? WM_KEYUP : WM_KEYDOWN; @@ -1482,6 +1485,15 @@ IME_NotifyComplete(himc); } +/*********************************************************************** + * macdrv_sent_text_input + */ +void macdrv_sent_text_input(const macdrv_event *event) +{ + TRACE("handled: %s\n", event->sent_text_input.handled ? "TRUE" : "FALSE"); + *event->sent_text_input.done = event->sent_text_input.handled ? 1 : -1; +} + /************************************************************************** * query_ime_char_rect diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/keyboard.c wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/keyboard.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/keyboard.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/keyboard.c 2016-02-08 19:32:34.000000000 +0000 @@ -1117,12 +1117,11 @@ /*********************************************************************** * macdrv_process_text_input */ -BOOL macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const BYTE *key_state, void *himc) +void macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const BYTE *key_state, void *himc, int* done) { struct macdrv_thread_data *thread_data = macdrv_thread_data(); unsigned int flags; int keyc; - BOOL ret = FALSE; TRACE("vkey 0x%04x scan 0x%04x repeat %u himc %p\n", vkey, scan, repeat, himc); @@ -1149,15 +1148,11 @@ if (thread_data->keyc2vkey[keyc] == vkey) break; if (keyc >= sizeof(thread_data->keyc2vkey)/sizeof(thread_data->keyc2vkey[0])) - goto done; + return; TRACE("flags 0x%08x keyc 0x%04x\n", flags, keyc); - ret = macdrv_send_text_input_event(((scan & 0x8000) == 0), flags, repeat, keyc, himc); - -done: - TRACE(" -> %s\n", ret ? "TRUE" : "FALSE"); - return ret; + macdrv_send_text_input_event(((scan & 0x8000) == 0), flags, repeat, keyc, himc, done); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/macdrv_cocoa.h wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/macdrv_cocoa.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/macdrv_cocoa.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/macdrv_cocoa.h 2016-02-08 19:32:34.000000000 +0000 @@ -199,8 +199,10 @@ MOUSE_MOVED_ABSOLUTE, MOUSE_SCROLL, QUERY_EVENT, + QUERY_EVENT_NO_PREEMPT_WAIT, REASSERT_WINDOW_POSITION, RELEASE_CAPTURE, + SENT_TEXT_INPUT, STATUS_ITEM_MOUSE_BUTTON, STATUS_ITEM_MOUSE_MOVE, WINDOW_BROUGHT_FORWARD, @@ -286,6 +288,10 @@ struct macdrv_query *query; } query_event; struct { + int handled; + int *done; + } sent_text_input; + struct { macdrv_status_item item; int button; int down; @@ -438,8 +444,8 @@ extern void macdrv_add_view_opengl_context(macdrv_view v, macdrv_opengl_context c) DECLSPEC_HIDDEN; extern void macdrv_remove_view_opengl_context(macdrv_view v, macdrv_opengl_context c) DECLSPEC_HIDDEN; extern uint32_t macdrv_window_background_color(void) DECLSPEC_HIDDEN; -extern int macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, int keyc, - void* data) DECLSPEC_HIDDEN; +extern void macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, int keyc, + void* data, int* done) DECLSPEC_HIDDEN; /* keyboard */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/macdrv.h wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/macdrv.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winemac.drv/macdrv.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winemac.drv/macdrv.h 2016-02-08 19:32:34.000000000 +0000 @@ -224,10 +224,11 @@ * Mac IME driver */ -extern BOOL macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const BYTE *key_state, - void *himc) DECLSPEC_HIDDEN; +extern void macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const BYTE *key_state, + void *himc, int* done) DECLSPEC_HIDDEN; extern void macdrv_im_set_text(const macdrv_event *event) DECLSPEC_HIDDEN; +extern void macdrv_sent_text_input(const macdrv_event *event) DECLSPEC_HIDDEN; extern BOOL query_ime_char_rect(macdrv_query* query) DECLSPEC_HIDDEN; #endif /* __WINE_MACDRV_H */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winex11.drv/window.c wine-staging-1.9.3~ubuntu12.04.1/dlls/winex11.drv/window.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winex11.drv/window.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winex11.drv/window.c 2016-02-08 19:32:34.000000000 +0000 @@ -128,7 +128,7 @@ pos = snprintf(message, sizeof(message), "remove: ID="); message[pos++] = '"'; - for (i = 0; id[i] && pos < sizeof(message) - 2; i++) + for (i = 0; id[i] && pos < sizeof(message) - 3; i++) { if (id[i] == '"' || id[i] == '\\') message[pos++] = '\\'; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wininet/tests/http.c wine-staging-1.9.3~ubuntu12.04.1/dlls/wininet/tests/http.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wininet/tests/http.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wininet/tests/http.c 2016-02-08 19:32:34.000000000 +0000 @@ -5809,15 +5809,33 @@ static void WINAPI header_cb( HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID info, DWORD len ) { - if (status == INTERNET_STATUS_REQUEST_COMPLETE) SetEvent( (HANDLE)ctx ); + BOOL ret; + DWORD index, size; + char buf[256]; + + if (status == INTERNET_STATUS_SENDING_REQUEST) + { + ret = HttpAddRequestHeadersA( handle, "winetest: winetest", ~0u, HTTP_ADDREQ_FLAG_ADD ); + ok( ret, "HttpAddRequestHeadersA failed %u\n", GetLastError() ); + SetEvent( (HANDLE)ctx ); + } + else if (status == INTERNET_STATUS_REQUEST_SENT) + { + index = 0; + size = sizeof(buf); + ret = HttpQueryInfoA( handle, HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS, + buf, &size, &index ); + ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() ); + ok( strstr( buf, "winetest: winetest" ) != NULL, "header missing\n" ); + SetEvent( (HANDLE)ctx ); + } } static void test_concurrent_header_access(void) { HINTERNET ses, con, req; - DWORD index, len, err; + DWORD err; BOOL ret; - char buf[128]; HANDLE wait = CreateEventW( NULL, FALSE, FALSE, NULL ); ses = InternetOpenA( "winetest", 0, NULL, NULL, INTERNET_FLAG_ASYNC ); @@ -5838,16 +5856,7 @@ ok( !ret, "HttpSendRequestA succeeded\n" ); ok( err == ERROR_IO_PENDING, "got %u\n", ERROR_IO_PENDING ); - ret = HttpAddRequestHeadersA( req, "winetest: winetest", ~0u, HTTP_ADDREQ_FLAG_ADD ); - ok( ret, "HttpAddRequestHeadersA failed %u\n", GetLastError() ); - - index = 0; - len = sizeof(buf); - ret = HttpQueryInfoA( req, HTTP_QUERY_RAW_HEADERS_CRLF|HTTP_QUERY_FLAG_REQUEST_HEADERS, - buf, &len, &index ); - ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() ); - ok( strstr( buf, "winetest: winetest" ) != NULL, "header missing\n" ); - + WaitForSingleObject( wait, 5000 ); WaitForSingleObject( wait, 5000 ); InternetCloseHandle( req ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winspool.drv/info.c wine-staging-1.9.3~ubuntu12.04.1/dlls/winspool.drv/info.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winspool.drv/info.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winspool.drv/info.c 2016-02-08 19:32:34.000000000 +0000 @@ -781,13 +781,15 @@ DO_FUNC(cupsPrintFile) #define CUPS_OPT_FUNCS \ DO_FUNC(cupsGetNamedDest); \ - DO_FUNC(cupsGetPPD3) + DO_FUNC(cupsGetPPD3); \ + DO_FUNC(cupsLastErrorString) #define DO_FUNC(f) static typeof(f) *p##f CUPS_FUNCS; #undef DO_FUNC static cups_dest_t * (*pcupsGetNamedDest)(http_t *, const char *, const char *); static http_status_t (*pcupsGetPPD3)(http_t *, const char *, time_t *, char *, size_t); +static const char * (*pcupsLastErrorString)(void); static http_status_t cupsGetPPD3_wrapper( http_t *http, const char *name, time_t *modtime, char *buffer, @@ -7527,6 +7529,26 @@ } /***************************************************************************** + * EnumPrinterKeyA [WINSPOOL.@] + * + */ +DWORD WINAPI EnumPrinterKeyA(HANDLE printer, const CHAR *key, CHAR *subkey, DWORD size, DWORD *needed) +{ + FIXME("%p %s %p %x %p\n", printer, debugstr_a(key), subkey, size, needed); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +/***************************************************************************** + * EnumPrinterKeyW [WINSPOOL.@] + * + */ +DWORD WINAPI EnumPrinterKeyW(HANDLE printer, const WCHAR *key, WCHAR *subkey, DWORD size, DWORD *needed) +{ + FIXME("%p %s %p %x %p\n", printer, debugstr_w(key), subkey, size, needed); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +/***************************************************************************** * EnumPrintProcessorDatatypesA [WINSPOOL.@] * */ @@ -8217,6 +8239,8 @@ TRACE( "\t%d: %s = %s\n", i, options[i].name, options[i].value ); ret = pcupsPrintFile( queue, unixname, unix_doc_title, num_options, options ); + if (ret == 0 && pcupsLastErrorString) + WARN("cupsPrintFile failed with error %s\n", debugstr_a(pcupsLastErrorString())); pcupsFreeOptions( num_options, options ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/winspool.drv/winspool.drv.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/winspool.drv/winspool.drv.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/winspool.drv/winspool.drv.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/winspool.drv/winspool.drv.spec 2016-02-08 19:32:34.000000000 +0000 @@ -124,6 +124,8 @@ @ stdcall EnumPrinterDriversW(wstr wstr long ptr long ptr ptr) @ stdcall EnumPrintersA(long ptr long ptr long ptr ptr) @ stdcall EnumPrintersW(long ptr long ptr long ptr ptr) +@ stdcall EnumPrinterKeyA(long str ptr long ptr) +@ stdcall EnumPrinterKeyW(long wstr ptr long ptr) @ stdcall ExtDeviceMode(long long ptr str str ptr str long) @ stdcall FindClosePrinterChangeNotification(long) @ stdcall FindFirstPrinterChangeNotification(long long long ptr) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/wpcap/wpcap.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/wpcap/wpcap.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/wpcap/wpcap.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/wpcap/wpcap.spec 2016-02-08 19:32:34.000000000 +0000 @@ -74,5 +74,5 @@ @ cdecl pcap_snapshot(ptr) wine_pcap_snapshot @ cdecl pcap_stats(ptr ptr) wine_pcap_stats @ stub pcap_stats_ex -@ stub pcap_strerror +@ cdecl pcap_strerror(long) msvcrt.strerror @ cdecl wsockinit() wine_wsockinit diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_0/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_0/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_0/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_0/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ -#include "config.h" -#include - -#include "windef.h" -#include "winbase.h" - -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_0/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_0/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_0/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_0/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,6 @@ +EXTRADEFS = -DX3DAUDIO1_VER=0 -DXAUDIO2_VER=0 MODULE = x3daudio1_0.dll +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + x3daudio.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_0/x3daudio1_0.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_0/x3daudio1_0.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_0/x3daudio1_0.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_0/x3daudio1_0.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,2 +1,2 @@ -@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) xaudio2_8.X3DAudioCalculate -@ cdecl X3DAudioInitialize(long float ptr) x3daudio1_7.X3DAudioInitialize +@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) +@ cdecl X3DAudioInitialize(long float ptr) LEGACY_X3DAudioInitialize diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_1/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_1/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_1/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_1/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright 2015 Austin English - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ -#include "config.h" -#include - -#include "windef.h" -#include "winbase.h" - -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_1/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_1/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_1/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_1/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,6 @@ +EXTRADEFS = -DX3DAUDIO1_VER=1 -DXAUDIO2_VER=1 MODULE = x3daudio1_1.dll +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + x3daudio.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_1/x3daudio1_1.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_1/x3daudio1_1.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_1/x3daudio1_1.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_1/x3daudio1_1.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,2 +1,2 @@ -@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) xaudio2_8.X3DAudioCalculate -@ cdecl X3DAudioInitialize(long float ptr) x3daudio1_7.X3DAudioInitialize +@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) +@ cdecl X3DAudioInitialize(long float ptr) LEGACY_X3DAudioInitialize diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_2/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_2/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_2/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_2/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright 2015 Alex Henrie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include - -#include "windef.h" -#include "winbase.h" - -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_2/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_2/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_2/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_2/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,6 @@ +EXTRADEFS = -DX3DAUDIO1_VER=2 -DXAUDIO2_VER=2 MODULE = x3daudio1_2.dll +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + x3daudio.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_2/x3daudio1_2.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_2/x3daudio1_2.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_2/x3daudio1_2.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_2/x3daudio1_2.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,2 +1,2 @@ -@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) xaudio2_8.X3DAudioCalculate -@ cdecl X3DAudioInitialize(long float ptr) x3daudio1_7.X3DAudioInitialize +@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) +@ cdecl X3DAudioInitialize(long float ptr) LEGACY_X3DAudioInitialize diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_3/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_3/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_3/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_3/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright 2015 Andrey Gusev - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include - -#include "windef.h" -#include "winbase.h" - -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_3/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_3/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_3/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_3/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,6 @@ +EXTRADEFS = -DX3DAUDIO1_VER=3 -DXAUDIO2_VER=3 MODULE = x3daudio1_3.dll +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + x3daudio.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_3/x3daudio1_3.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_3/x3daudio1_3.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_3/x3daudio1_3.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_3/x3daudio1_3.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,2 +1,2 @@ -@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) xaudio2_8.X3DAudioCalculate -@ cdecl X3DAudioInitialize(long float ptr) x3daudio1_7.X3DAudioInitialize +@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) +@ cdecl X3DAudioInitialize(long float ptr) LEGACY_X3DAudioInitialize diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_4/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_4/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_4/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_4/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright 2015 Andrey Gusev - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include - -#include "windef.h" -#include "winbase.h" - -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_4/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_4/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_4/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_4/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,6 @@ +EXTRADEFS = -DX3DAUDIO1_VER=4 -DXAUDIO2_VER=4 MODULE = x3daudio1_4.dll +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + x3daudio.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_4/x3daudio1_4.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_4/x3daudio1_4.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_4/x3daudio1_4.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_4/x3daudio1_4.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,2 +1,2 @@ -@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) xaudio2_8.X3DAudioCalculate -@ cdecl X3DAudioInitialize(long float ptr) x3daudio1_7.X3DAudioInitialize +@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) +@ cdecl X3DAudioInitialize(long float ptr) LEGACY_X3DAudioInitialize diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_5/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_5/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_5/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_5/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright 2015 Andrey Gusev - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include - -#include "windef.h" -#include "winbase.h" - -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_5/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_5/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_5/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_5/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,6 @@ +EXTRADEFS = -DX3DAUDIO1_VER=5 -DXAUDIO2_VER=5 MODULE = x3daudio1_5.dll +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + x3daudio.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_5/x3daudio1_5.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_5/x3daudio1_5.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_5/x3daudio1_5.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_5/x3daudio1_5.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,2 +1,2 @@ -@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) xaudio2_8.X3DAudioCalculate -@ cdecl X3DAudioInitialize(long float ptr) x3daudio1_7.X3DAudioInitialize +@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) +@ cdecl X3DAudioInitialize(long float ptr) LEGACY_X3DAudioInitialize diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_6/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_6/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_6/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_6/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright 2015 Austin English - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include - -#include "windef.h" -#include "winbase.h" - -#include "x3daudio.h" - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - switch (fdwReason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); - break; - case DLL_PROCESS_DETACH: - break; - } - - return TRUE; -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_6/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_6/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_6/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_6/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,6 @@ +EXTRADEFS = -DX3DAUDIO1_VER=6 -DXAUDIO2_VER=6 MODULE = x3daudio1_6.dll +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + x3daudio.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_6/x3daudio1_6.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_6/x3daudio1_6.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_6/x3daudio1_6.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_6/x3daudio1_6.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,2 +1,2 @@ -@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) xaudio2_8.X3DAudioCalculate -@ cdecl X3DAudioInitialize(long float ptr) x3daudio1_7.X3DAudioInitialize +@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) +@ cdecl X3DAudioInitialize(long float ptr) LEGACY_X3DAudioInitialize diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_7/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_7/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_7/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_7/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright 2014 Alex Henrie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include - -#include "windef.h" -#include "winbase.h" -#include "x3daudio.h" - -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} - -void CDECL X3DA17_X3DAudioInitialize(UINT32 chanmask, float speedofsound, - X3DAUDIO_HANDLE handle) -{ - /* forward to xaudio2_8 */ - X3DAudioInitialize(chanmask, speedofsound, handle); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_7/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_7/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_7/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_7/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,5 +1,6 @@ +EXTRADEFS = -DX3DAUDIO1_VER=7 -DXAUDIO2_VER=7 MODULE = x3daudio1_7.dll -IMPORTS = xaudio2_8 +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + x3daudio.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_7/x3daudio1_7.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_7/x3daudio1_7.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/x3daudio1_7/x3daudio1_7.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/x3daudio1_7/x3daudio1_7.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,2 +1,2 @@ -@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) xaudio2_8.X3DAudioCalculate -@ cdecl X3DAudioInitialize(long float ptr) X3DA17_X3DAudioInitialize +@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) +@ cdecl X3DAudioInitialize(long float ptr) LEGACY_X3DAudioInitialize diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_1/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_1/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_1/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_1/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright 2010 Louis Lenders - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include - -#include "initguid.h" -#include "windef.h" -#include "winbase.h" -#include "compobj.h" -#include "xapofx.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(xapofx); - -/***************************************************** - * DllMain - */ -BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) -{ - TRACE("(%p, %d, %p)\n", hinst, reason, reserved); - - switch(reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinst); - break; - } - return TRUE; -} - -HRESULT CDECL CreateFX(REFCLSID clsid, IUnknown **out) -{ - const GUID *class = clsid; - - TRACE("%s %p\n", debugstr_guid(clsid), out); - - if(IsEqualGUID(clsid, &CLSID_FXReverb27) || - IsEqualGUID(clsid, &CLSID_FXReverb)) - class = &CLSID_WINE_FXReverb11; - else if(IsEqualGUID(clsid, &CLSID_FXEQ27) || - IsEqualGUID(clsid, &CLSID_FXEQ)) - class = &CLSID_WINE_FXEQ11; - - return CoCreateInstance(class, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)out); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_1/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_1/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_1/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_1/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,7 +1,9 @@ +EXTRADEFS = -DXAPOFX1_VER=1 -DXAUDIO2_VER=2 MODULE = xapofx1_1.dll IMPORTS = ole32 +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + xapofx.c RC_SRCS = version.rc diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_2/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_2/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_2/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_2/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include - -#include "initguid.h" -#include "windef.h" -#include "winbase.h" -#include "compobj.h" -#include "xapofx.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(xapofx); - -/***************************************************** - * DllMain - */ -BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) -{ - TRACE("(%p, %d, %p)\n", hinst, reason, reserved); - - switch(reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinst); - break; - } - return TRUE; -} - -HRESULT CDECL CreateFX(REFCLSID clsid, IUnknown **out) -{ - const GUID *class = clsid; - - TRACE("%s %p\n", debugstr_guid(clsid), out); - - if(IsEqualGUID(clsid, &CLSID_FXReverb27) || - IsEqualGUID(clsid, &CLSID_FXReverb)) - class = &CLSID_WINE_FXReverb12; - else if(IsEqualGUID(clsid, &CLSID_FXEQ27) || - IsEqualGUID(clsid, &CLSID_FXEQ)) - class = &CLSID_WINE_FXEQ12; - - return CoCreateInstance(class, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)out); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_2/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_2/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_2/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_2/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,5 +1,7 @@ +EXTRADEFS = -DXAPOFX1_VER=2 -DXAUDIO2_VER=3 MODULE = xapofx1_2.dll IMPORTS = ole32 +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + xapofx.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_3/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_3/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_3/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_3/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright 2015 Andrey Gusev - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include - -#include "initguid.h" -#include "windef.h" -#include "winbase.h" -#include "compobj.h" -#include "xapofx.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(xaudio2); - -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} - -HRESULT CDECL CreateFX(REFCLSID clsid, IUnknown **out) -{ - const GUID *class = clsid; - - TRACE("%s %p\n", debugstr_guid(clsid), out); - - if(IsEqualGUID(clsid, &CLSID_FXReverb27) || - IsEqualGUID(clsid, &CLSID_FXReverb)) - class = &CLSID_WINE_FXReverb13; - else if(IsEqualGUID(clsid, &CLSID_FXEQ27) || - IsEqualGUID(clsid, &CLSID_FXEQ)) - class = &CLSID_WINE_FXEQ13; - - return CoCreateInstance(class, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)out); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_3/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_3/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_3/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_3/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,7 +1,9 @@ +EXTRADEFS = -DXAPOFX1_VER=3 -DXAUDIO2_VER=4 MODULE = xapofx1_3.dll IMPORTS = ole32 +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + xapofx.c RC_SRCS = version.rc diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_4/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_4/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_4/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_4/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2015 Austin English - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include - -#include "initguid.h" -#include "windef.h" -#include "winbase.h" -#include "compobj.h" -#include "xapofx.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(xaudio2); - -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} - -HRESULT CDECL CreateFX(REFCLSID clsid, IUnknown **out) -{ - const GUID *class = clsid; - - TRACE("%s %p\n", debugstr_guid(clsid), out); - - if(IsEqualGUID(clsid, &CLSID_FXReverb27) || - IsEqualGUID(clsid, &CLSID_FXReverb)) - class = &CLSID_WINE_FXReverb14; - else if(IsEqualGUID(clsid, &CLSID_FXEQ27) || - IsEqualGUID(clsid, &CLSID_FXEQ)) - class = &CLSID_WINE_FXEQ14; - - return CoCreateInstance(class, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)out); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_4/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_4/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_4/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_4/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,5 +1,7 @@ +EXTRADEFS = -DXAPOFX1_VER=4 -DXAUDIO2_VER=6 MODULE = xapofx1_4.dll IMPORTS = ole32 +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + xapofx.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_5/main.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_5/main.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_5/main.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_5/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2015 Austin English - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include - -#include "initguid.h" -#include "windef.h" -#include "winbase.h" -#include "compobj.h" -#include "xapofx.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(xaudio2); - -BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(instance); - break; - } - - return TRUE; -} - -HRESULT CDECL CreateFX(REFCLSID clsid, IUnknown **out) -{ - const GUID *class = clsid; - - TRACE("%s %p\n", debugstr_guid(clsid), out); - - if(IsEqualGUID(clsid, &CLSID_FXReverb27) || - IsEqualGUID(clsid, &CLSID_FXReverb)) - class = &CLSID_WINE_FXReverb15; - else if(IsEqualGUID(clsid, &CLSID_FXEQ27) || - IsEqualGUID(clsid, &CLSID_FXEQ)) - class = &CLSID_WINE_FXEQ15; - - return CoCreateInstance(class, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)out); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_5/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_5/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xapofx1_5/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xapofx1_5/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,5 +1,7 @@ +EXTRADEFS = -DXAPOFX1_VER=5 -DXAUDIO2_VER=7 MODULE = xapofx1_5.dll IMPORTS = ole32 +PARENTSRC = ../xaudio2_7 C_SRCS = \ - main.c + xapofx.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_0/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_0/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_0/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_0/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,7 +1,12 @@ +EXTRADEFS = -DXAUDIO2_VER=0 MODULE = xaudio2_0.dll -IMPORTS = ole32 +IMPORTS = advapi32 ole32 user32 uuid +EXTRALIBS = $(OPENAL_LIBS) +PARENTSRC = ../xaudio2_7 C_SRCS = \ + compat.c \ + xapofx.c \ xaudio_dll.c IDL_SRCS = xaudio_classes.idl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_0/xaudio2_0.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_0/xaudio2_0.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_0/xaudio2_0.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_0/xaudio2_0.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,4 @@ @ stdcall -private DllCanUnloadNow() -@ stdcall -private DllGetClassObject(ptr ptr ptr) xaudio2_7.DllGetClassObject +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_0/xaudio_classes.idl wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_0/xaudio_classes.idl --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_0/xaudio_classes.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_0/xaudio_classes.idl 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * COM Classes for xaudio - * - * Copyright 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#pragma makedep register - -[ - helpstring("XAudio2.0 Class"), - threading(both), - uuid(fac23f48-31f5-45a8-b49b-5225d61401aa) -] -coclass XAudio20 { interface IXAudio20; } - -[ - helpstring("XAudio2.0 AudioReverb Class"), - threading(both), - uuid(6f6ea3a9-2cf5-41cf-91c1-2170b1540063) -] -coclass AudioReverb20 { interface IXAPO; } - -[ - helpstring("XAudio2.0 AudioVolumeMeter Class"), - threading(both), - uuid(c0c56f46-29b1-44e9-9939-a32ce86867e2) -] -coclass AudioVolumeMeter20 { interface IXAPO; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_0/xaudio_dll.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_0/xaudio_dll.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_0/xaudio_dll.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_0/xaudio_dll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include "windef.h" -#include "winbase.h" -#include "objbase.h" -#include "rpcproxy.h" - -static HINSTANCE instance; - -BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - instance = hinstance; - DisableThreadLibraryCalls(hinstance); - break; - } - return TRUE; -} - -HRESULT WINAPI DllCanUnloadNow(void) -{ - return S_FALSE; -} - -HRESULT WINAPI DllRegisterServer(void) -{ - return __wine_register_resources(instance); -} - -HRESULT WINAPI DllUnregisterServer(void) -{ - return __wine_unregister_resources(instance); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_1/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_1/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_1/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_1/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,7 +1,12 @@ +EXTRADEFS = -DXAUDIO2_VER=1 MODULE = xaudio2_1.dll -IMPORTS = ole32 +IMPORTS = advapi32 ole32 user32 uuid +EXTRALIBS = $(OPENAL_LIBS) +PARENTSRC = ../xaudio2_7 C_SRCS = \ + compat.c \ + xapofx.c \ xaudio_dll.c IDL_SRCS = xaudio_classes.idl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_1/xaudio2_1.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_1/xaudio2_1.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_1/xaudio2_1.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_1/xaudio2_1.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,4 @@ @ stdcall -private DllCanUnloadNow() -@ stdcall -private DllGetClassObject(ptr ptr ptr) xaudio2_7.DllGetClassObject +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_1/xaudio_classes.idl wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_1/xaudio_classes.idl --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_1/xaudio_classes.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_1/xaudio_classes.idl 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * COM Classes for xaudio - * - * Copyright 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#pragma makedep register - -[ - helpstring("XAudio2.1 Class"), - threading(both), - uuid(e21a7345-eb21-468e-be50-804db97cf708) -] -coclass XAudio21 { interface IXAudio22; } - -[ - helpstring("XAudio2.1 AudioReverb Class"), - threading(both), - uuid(f4769300-b949-4df9-b333-00d33932e9a6) -] -coclass AudioReverb21 { interface IXAPO; } - -[ - helpstring("XAudio2.1 AudioVolumeMeter Class"), - threading(both), - uuid(c1e3f122-a2ea-442c-854f-20d98f8357a1) -] -coclass AudioVolumeMeter21 { interface IXAPO; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_1/xaudio_dll.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_1/xaudio_dll.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_1/xaudio_dll.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_1/xaudio_dll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include "windef.h" -#include "winbase.h" -#include "objbase.h" -#include "rpcproxy.h" - -static HINSTANCE instance; - -BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - instance = hinstance; - DisableThreadLibraryCalls(hinstance); - break; - } - return TRUE; -} - -HRESULT WINAPI DllCanUnloadNow(void) -{ - return S_FALSE; -} - -HRESULT WINAPI DllRegisterServer(void) -{ - return __wine_register_resources(instance); -} - -HRESULT WINAPI DllUnregisterServer(void) -{ - return __wine_unregister_resources(instance); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_2/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_2/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_2/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_2/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,7 +1,12 @@ +EXTRADEFS = -DXAUDIO2_VER=2 MODULE = xaudio2_2.dll -IMPORTS = ole32 +IMPORTS = advapi32 ole32 user32 uuid +EXTRALIBS = $(OPENAL_LIBS) +PARENTSRC = ../xaudio2_7 C_SRCS = \ + compat.c \ + xapofx.c \ xaudio_dll.c IDL_SRCS = xaudio_classes.idl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_2/xaudio2_2.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_2/xaudio2_2.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_2/xaudio2_2.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_2/xaudio2_2.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,4 @@ @ stdcall -private DllCanUnloadNow() -@ stdcall -private DllGetClassObject(ptr ptr ptr) xaudio2_7.DllGetClassObject +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_2/xaudio_classes.idl wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_2/xaudio_classes.idl --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_2/xaudio_classes.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_2/xaudio_classes.idl 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * COM Classes for xaudio - * - * Copyright 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#pragma makedep register - -[ - helpstring("XAudio2.2 Class"), - threading(both), - uuid(b802058a-464a-42db-bc10-b650d6f2586a) -] -coclass XAudio22 { interface IXAudio22; } - -[ - helpstring("XAudio2.2 AudioReverb Class"), - threading(both), - uuid(629cf0de-3ecc-41e7-9926-f7e43eebec51) -] -coclass AudioReverb22 { interface IXAPO; } - -[ - helpstring("XAudio2.2 AudioVolumeMeter Class"), - threading(both), - uuid(f5ca7b34-8055-42c0-b836-216129eb7e30) -] -coclass AudioVolumeMeter22 { interface IXAPO; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_2/xaudio_dll.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_2/xaudio_dll.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_2/xaudio_dll.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_2/xaudio_dll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include "windef.h" -#include "winbase.h" -#include "objbase.h" -#include "rpcproxy.h" - -static HINSTANCE instance; - -BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - instance = hinstance; - DisableThreadLibraryCalls(hinstance); - break; - } - return TRUE; -} - -HRESULT WINAPI DllCanUnloadNow(void) -{ - return S_FALSE; -} - -HRESULT WINAPI DllRegisterServer(void) -{ - return __wine_register_resources(instance); -} - -HRESULT WINAPI DllUnregisterServer(void) -{ - return __wine_unregister_resources(instance); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_3/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_3/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_3/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_3/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,7 +1,12 @@ +EXTRADEFS = -DXAUDIO2_VER=3 MODULE = xaudio2_3.dll -IMPORTS = ole32 +IMPORTS = advapi32 ole32 user32 uuid +EXTRALIBS = $(OPENAL_LIBS) +PARENTSRC = ../xaudio2_7 C_SRCS = \ + compat.c \ + xapofx.c \ xaudio_dll.c IDL_SRCS = xaudio_classes.idl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_3/xaudio2_3.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_3/xaudio2_3.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_3/xaudio2_3.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_3/xaudio2_3.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,4 @@ @ stdcall -private DllCanUnloadNow() -@ stdcall -private DllGetClassObject(ptr ptr ptr) xaudio2_7.DllGetClassObject +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_3/xaudio_classes.idl wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_3/xaudio_classes.idl --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_3/xaudio_classes.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_3/xaudio_classes.idl 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * COM Classes for xaudio - * - * Copyright 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#pragma makedep register - -[ - helpstring("XAudio2.3 Class"), - threading(both), - uuid(4c5e637a-16c7-4de3-9c46-5ed22181962d) -] -coclass XAudio23 { interface IXAudio27; } - -[ - helpstring("XAudio2.3 AudioReverb Class"), - threading(both), - uuid(9cab402c-1d37-44b4-886d-fa4f36170a4c) -] -coclass AudioReverb23 { interface IXAPO; } - -[ - helpstring("XAudio2.3 AudioVolumeMeter Class"), - threading(both), - uuid(e180344b-ac83-4483-959e-18a5c56a5e19) -] -coclass AudioVolumeMeter23 { interface IXAPO; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_3/xaudio_dll.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_3/xaudio_dll.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_3/xaudio_dll.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_3/xaudio_dll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include "windef.h" -#include "winbase.h" -#include "objbase.h" -#include "rpcproxy.h" - -static HINSTANCE instance; - -BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - instance = hinstance; - DisableThreadLibraryCalls(hinstance); - break; - } - return TRUE; -} - -HRESULT WINAPI DllCanUnloadNow(void) -{ - return S_FALSE; -} - -HRESULT WINAPI DllRegisterServer(void) -{ - return __wine_register_resources(instance); -} - -HRESULT WINAPI DllUnregisterServer(void) -{ - return __wine_unregister_resources(instance); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_4/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_4/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_4/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_4/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,7 +1,12 @@ +EXTRADEFS = -DXAUDIO2_VER=4 MODULE = xaudio2_4.dll -IMPORTS = ole32 +IMPORTS = advapi32 ole32 user32 uuid +EXTRALIBS = $(OPENAL_LIBS) +PARENTSRC = ../xaudio2_7 C_SRCS = \ + compat.c \ + xapofx.c \ xaudio_dll.c IDL_SRCS = xaudio_classes.idl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_4/xaudio2_4.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_4/xaudio2_4.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_4/xaudio2_4.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_4/xaudio2_4.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,4 @@ @ stdcall -private DllCanUnloadNow() -@ stdcall -private DllGetClassObject(ptr ptr ptr) xaudio2_7.DllGetClassObject +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_4/xaudio_classes.idl wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_4/xaudio_classes.idl --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_4/xaudio_classes.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_4/xaudio_classes.idl 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * COM Classes for xaudio - * - * Copyright 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#pragma makedep register - -[ - helpstring("XAudio2.4 Class"), - threading(both), - uuid(03219e78-5bc3-44d1-b92e-f63d89cc6526) -] -coclass XAudio24 { interface IXAudio27; } - -[ - helpstring("XAudio2.4 AudioReverb Class"), - threading(both), - uuid(8bb7778b-645b-4475-9a73-1de3170bd3af) -] -coclass AudioReverb24 { interface IXAPO; } - -[ - helpstring("XAudio2.4 AudioVolumeMeter Class"), - threading(both), - uuid(c7338b95-52b8-4542-aa79-42eb016c8c1c) -] -coclass AudioVolumeMeter24 { interface IXAPO; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_4/xaudio_dll.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_4/xaudio_dll.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_4/xaudio_dll.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_4/xaudio_dll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include "windef.h" -#include "winbase.h" -#include "objbase.h" -#include "rpcproxy.h" - -static HINSTANCE instance; - -BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - instance = hinstance; - DisableThreadLibraryCalls(hinstance); - break; - } - return TRUE; -} - -HRESULT WINAPI DllCanUnloadNow(void) -{ - return S_FALSE; -} - -HRESULT WINAPI DllRegisterServer(void) -{ - return __wine_register_resources(instance); -} - -HRESULT WINAPI DllUnregisterServer(void) -{ - return __wine_unregister_resources(instance); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_5/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_5/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_5/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_5/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,7 +1,12 @@ +EXTRADEFS = -DXAUDIO2_VER=5 MODULE = xaudio2_5.dll -IMPORTS = ole32 +IMPORTS = advapi32 ole32 user32 uuid +EXTRALIBS = $(OPENAL_LIBS) +PARENTSRC = ../xaudio2_7 C_SRCS = \ + compat.c \ + xapofx.c \ xaudio_dll.c IDL_SRCS = xaudio_classes.idl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_5/xaudio2_5.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_5/xaudio2_5.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_5/xaudio2_5.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_5/xaudio2_5.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,4 @@ @ stdcall -private DllCanUnloadNow() -@ stdcall -private DllGetClassObject(ptr ptr ptr) xaudio2_7.DllGetClassObject +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_5/xaudio_classes.idl wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_5/xaudio_classes.idl --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_5/xaudio_classes.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_5/xaudio_classes.idl 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * COM Classes for xaudio - * - * Copyright 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#pragma makedep register - -[ - helpstring("XAudio2.5 Class"), - threading(both), - uuid(4c9b6dde-6809-46e6-a278-9b6a97588670) -] -coclass XAudio25 { interface IXAudio27; } - -[ - helpstring("XAudio2.5 AudioReverb Class"), - threading(both), - uuid(d06df0d0-8518-441e-822f-5451d5c595b8) -] -coclass AudioReverb25 { interface IXAPO; } - -[ - helpstring("XAudio2.5 AudioVolumeMeter Class"), - threading(both), - uuid(2139e6da-c341-4774-9ac3-b4e026347f64) -] -coclass AudioVolumeMeter25 { interface IXAPO; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_5/xaudio_dll.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_5/xaudio_dll.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_5/xaudio_dll.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_5/xaudio_dll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include "windef.h" -#include "winbase.h" -#include "objbase.h" -#include "rpcproxy.h" - -static HINSTANCE instance; - -BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - instance = hinstance; - DisableThreadLibraryCalls(hinstance); - break; - } - return TRUE; -} - -HRESULT WINAPI DllCanUnloadNow(void) -{ - return S_FALSE; -} - -HRESULT WINAPI DllRegisterServer(void) -{ - return __wine_register_resources(instance); -} - -HRESULT WINAPI DllUnregisterServer(void) -{ - return __wine_unregister_resources(instance); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_6/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_6/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_6/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_6/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,7 +1,12 @@ +EXTRADEFS = -DXAUDIO2_VER=6 MODULE = xaudio2_6.dll -IMPORTS = ole32 +IMPORTS = advapi32 ole32 user32 uuid +EXTRALIBS = $(OPENAL_LIBS) +PARENTSRC = ../xaudio2_7 C_SRCS = \ + compat.c \ + xapofx.c \ xaudio_dll.c IDL_SRCS = xaudio_classes.idl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_6/xaudio2_6.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_6/xaudio2_6.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_6/xaudio2_6.spec 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_6/xaudio2_6.spec 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,4 @@ @ stdcall -private DllCanUnloadNow() -@ stdcall -private DllGetClassObject(ptr ptr ptr) xaudio2_7.DllGetClassObject +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_6/xaudio_classes.idl wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_6/xaudio_classes.idl --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_6/xaudio_classes.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_6/xaudio_classes.idl 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - * COM Classes for xaudio - * - * Copyright 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#pragma makedep register - -[ - helpstring("XAudio2.6 Class"), - threading(both), - uuid(3eda9b49-2085-498b-9bb2-39a6778493de) -] -coclass XAudio26 { interface IXAudio27; } - -[ - helpstring("XAudio2.6 AudioReverb Class"), - threading(both), - uuid(cecec95a-d894-491a-bee3-5e106fb59f2d) -] -coclass AudioReverb26 { interface IXAPO; } - -[ - helpstring("XAudio2.6 AudioVolumeMeter Class"), - threading(both), - uuid(e48c5a3f-93ef-43bb-a092-2c7ceb946f27) -] -coclass AudioVolumeMeter26 { interface IXAPO; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_6/xaudio_dll.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_6/xaudio_dll.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_6/xaudio_dll.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_6/xaudio_dll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include "windef.h" -#include "winbase.h" -#include "objbase.h" -#include "rpcproxy.h" - -static HINSTANCE instance; - -BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) -{ - switch (reason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - instance = hinstance; - DisableThreadLibraryCalls(hinstance); - break; - } - return TRUE; -} - -HRESULT WINAPI DllCanUnloadNow(void) -{ - return S_FALSE; -} - -HRESULT WINAPI DllRegisterServer(void) -{ - return __wine_register_resources(instance); -} - -HRESULT WINAPI DllUnregisterServer(void) -{ - return __wine_unregister_resources(instance); -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/compat.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/compat.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/compat.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/compat.c 2016-02-08 19:32:34.000000000 +0000 @@ -78,6 +78,14 @@ * Change parameter of IXAudio2::CreateMasteringVoice * Add Flags parameter to IXAudio2SourceVoice::GetState * Add IXAudio2MasteringVoice::GetChannelMask + * Add DisableLateField member to XAUDIO2FX_REVERB_PARAMETERS + * + * 2.9 + * Change IID_IXAudio2 + * New flags: XAUDIO2_STOP_ENGINE_WHEN_IDLE, XAUDIO2_1024_QUANTUM, + * XAUDIO2_NO_VIRTUAL_AUDIO_CLIENT + * ABI break: + * Add SideDelay member to XAUDIO2FX_REVERB_PARAMETERS */ #include "config.h" @@ -94,496 +102,263 @@ WINE_DEFAULT_DEBUG_CHANNEL(xaudio2); -static XA2SourceImpl *impl_from_IXAudio27SourceVoice(IXAudio27SourceVoice *iface) +/* BEGIN IXAudio2SourceVoice */ +#if XAUDIO2_VER == 0 +static XA2SourceImpl *impl_from_IXAudio20SourceVoice(IXAudio20SourceVoice *iface) { - return CONTAINING_RECORD(iface, XA2SourceImpl, IXAudio27SourceVoice_iface); + return CONTAINING_RECORD(iface, XA2SourceImpl, IXAudio20SourceVoice_iface); } -static void WINAPI XA27SRC_GetVoiceDetails(IXAudio27SourceVoice *iface, +static void WINAPI XA20SRC_GetVoiceDetails(IXAudio20SourceVoice *iface, XAUDIO2_VOICE_DETAILS *pVoiceDetails) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_GetVoiceDetails(&This->IXAudio2SourceVoice_iface, pVoiceDetails); } -static HRESULT WINAPI XA27SRC_SetOutputVoices(IXAudio27SourceVoice *iface, - const XAUDIO2_VOICE_SENDS *pSendList) +static HRESULT WINAPI XA20SRC_SetOutputVoices(IXAudio20SourceVoice *iface, + const XAUDIO23_VOICE_SENDS *pSendList) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - return IXAudio2SourceVoice_SetOutputVoices(&This->IXAudio2SourceVoice_iface, pSendList); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + XAUDIO2_VOICE_SENDS sends; + HRESULT hr; + DWORD i; + + TRACE("%p, %p\n", This, pSendList); + + sends.SendCount = pSendList->OutputCount; + sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends)); + for(i = 0; i < sends.SendCount; ++i){ + sends.pSends[i].Flags = 0; + sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i]; + } + + hr = IXAudio2SourceVoice_SetOutputVoices(&This->IXAudio2SourceVoice_iface, &sends); + + HeapFree(GetProcessHeap(), 0, sends.pSends); + + return hr; } -static HRESULT WINAPI XA27SRC_SetEffectChain(IXAudio27SourceVoice *iface, +static HRESULT WINAPI XA20SRC_SetEffectChain(IXAudio20SourceVoice *iface, const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_SetEffectChain(&This->IXAudio2SourceVoice_iface, pEffectChain); } -static HRESULT WINAPI XA27SRC_EnableEffect(IXAudio27SourceVoice *iface, +static HRESULT WINAPI XA20SRC_EnableEffect(IXAudio20SourceVoice *iface, UINT32 EffectIndex, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - return IXAudio2SourceVoice_EnableEffect(&This->IXAudio2SourceVoice_iface, EffectIndex, OperationSet); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + return IXAudio2SourceVoice_EnableEffect(&This->IXAudio2SourceVoice_iface, + EffectIndex, OperationSet); } -static HRESULT WINAPI XA27SRC_DisableEffect(IXAudio27SourceVoice *iface, +static HRESULT WINAPI XA20SRC_DisableEffect(IXAudio20SourceVoice *iface, UINT32 EffectIndex, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - return IXAudio2SourceVoice_DisableEffect(&This->IXAudio2SourceVoice_iface, EffectIndex, OperationSet); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + return IXAudio2SourceVoice_DisableEffect(&This->IXAudio2SourceVoice_iface, + EffectIndex, OperationSet); } -static void WINAPI XA27SRC_GetEffectState(IXAudio27SourceVoice *iface, +static void WINAPI XA20SRC_GetEffectState(IXAudio20SourceVoice *iface, UINT32 EffectIndex, BOOL *pEnabled) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - IXAudio2SourceVoice_GetEffectState(&This->IXAudio2SourceVoice_iface, EffectIndex, pEnabled); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + return IXAudio2SourceVoice_GetEffectState(&This->IXAudio2SourceVoice_iface, + EffectIndex, pEnabled); } -static HRESULT WINAPI XA27SRC_SetEffectParameters(IXAudio27SourceVoice *iface, +static HRESULT WINAPI XA20SRC_SetEffectParameters(IXAudio20SourceVoice *iface, UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_SetEffectParameters(&This->IXAudio2SourceVoice_iface, EffectIndex, pParameters, ParametersByteSize, OperationSet); } -static HRESULT WINAPI XA27SRC_GetEffectParameters(IXAudio27SourceVoice *iface, +static HRESULT WINAPI XA20SRC_GetEffectParameters(IXAudio20SourceVoice *iface, UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_GetEffectParameters(&This->IXAudio2SourceVoice_iface, EffectIndex, pParameters, ParametersByteSize); } -static HRESULT WINAPI XA27SRC_SetFilterParameters(IXAudio27SourceVoice *iface, +static HRESULT WINAPI XA20SRC_SetFilterParameters(IXAudio20SourceVoice *iface, const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_SetFilterParameters(&This->IXAudio2SourceVoice_iface, pParameters, OperationSet); } -static void WINAPI XA27SRC_GetFilterParameters(IXAudio27SourceVoice *iface, - XAUDIO2_FILTER_PARAMETERS *pParameters) -{ - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - IXAudio2SourceVoice_GetFilterParameters(&This->IXAudio2SourceVoice_iface, pParameters); -} - -static HRESULT WINAPI XA27SRC_SetOutputFilterParameters(IXAudio27SourceVoice *iface, - IXAudio2Voice *pDestinationVoice, - const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet) -{ - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - return IXAudio2SourceVoice_SetOutputFilterParameters(&This->IXAudio2SourceVoice_iface, - pDestinationVoice, pParameters, OperationSet); -} - -static void WINAPI XA27SRC_GetOutputFilterParameters(IXAudio27SourceVoice *iface, - IXAudio2Voice *pDestinationVoice, +static void WINAPI XA20SRC_GetFilterParameters(IXAudio20SourceVoice *iface, XAUDIO2_FILTER_PARAMETERS *pParameters) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - IXAudio2SourceVoice_GetOutputFilterParameters(&This->IXAudio2SourceVoice_iface, - pDestinationVoice, pParameters); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + return IXAudio2SourceVoice_GetFilterParameters(&This->IXAudio2SourceVoice_iface, pParameters); } -static HRESULT WINAPI XA27SRC_SetVolume(IXAudio27SourceVoice *iface, float Volume, - UINT32 OperationSet) +static HRESULT WINAPI XA20SRC_SetVolume(IXAudio20SourceVoice *iface, + float Volume, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - return IXAudio2SourceVoice_SetVolume(&This->IXAudio2SourceVoice_iface, Volume, - OperationSet); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + return IXAudio2SourceVoice_SetVolume(&This->IXAudio2SourceVoice_iface, + Volume, OperationSet); } -static void WINAPI XA27SRC_GetVolume(IXAudio27SourceVoice *iface, float *pVolume) +static void WINAPI XA20SRC_GetVolume(IXAudio20SourceVoice *iface, + float *pVolume) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - IXAudio2SourceVoice_GetVolume(&This->IXAudio2SourceVoice_iface, pVolume); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + return IXAudio2SourceVoice_GetVolume(&This->IXAudio2SourceVoice_iface, pVolume); } -static HRESULT WINAPI XA27SRC_SetChannelVolumes(IXAudio27SourceVoice *iface, +static HRESULT WINAPI XA20SRC_SetChannelVolumes(IXAudio20SourceVoice *iface, UINT32 Channels, const float *pVolumes, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - return IXAudio2SourceVoice_SetChannelVolumes(&This->IXAudio2SourceVoice_iface, Channels, - pVolumes, OperationSet); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + return IXAudio2SourceVoice_SetChannelVolumes(&This->IXAudio2SourceVoice_iface, + Channels, pVolumes, OperationSet); } -static void WINAPI XA27SRC_GetChannelVolumes(IXAudio27SourceVoice *iface, +static void WINAPI XA20SRC_GetChannelVolumes(IXAudio20SourceVoice *iface, UINT32 Channels, float *pVolumes) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - IXAudio2SourceVoice_GetChannelVolumes(&This->IXAudio2SourceVoice_iface, Channels, - pVolumes); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + return IXAudio2SourceVoice_GetChannelVolumes(&This->IXAudio2SourceVoice_iface, + Channels, pVolumes); } -static HRESULT WINAPI XA27SRC_SetOutputMatrix(IXAudio27SourceVoice *iface, +static HRESULT WINAPI XA20SRC_SetOutputMatrix(IXAudio20SourceVoice *iface, IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels, UINT32 DestinationChannels, const float *pLevelMatrix, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_SetOutputMatrix(&This->IXAudio2SourceVoice_iface, pDestinationVoice, SourceChannels, DestinationChannels, pLevelMatrix, OperationSet); } -static void WINAPI XA27SRC_GetOutputMatrix(IXAudio27SourceVoice *iface, +static HRESULT WINAPI XA20SRC_GetOutputMatrix(IXAudio20SourceVoice *iface, IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels, UINT32 DestinationChannels, float *pLevelMatrix) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - IXAudio2SourceVoice_GetOutputMatrix(&This->IXAudio2SourceVoice_iface, pDestinationVoice, - SourceChannels, DestinationChannels, pLevelMatrix); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + IXAudio2SourceVoice_GetOutputMatrix(&This->IXAudio2SourceVoice_iface, + pDestinationVoice, SourceChannels, DestinationChannels, + pLevelMatrix); + return S_OK; } -static void WINAPI XA27SRC_DestroyVoice(IXAudio27SourceVoice *iface) +static void WINAPI XA20SRC_DestroyVoice(IXAudio20SourceVoice *iface) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - IXAudio2SourceVoice_DestroyVoice(&This->IXAudio2SourceVoice_iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + return IXAudio2SourceVoice_DestroyVoice(&This->IXAudio2SourceVoice_iface); } -static HRESULT WINAPI XA27SRC_Start(IXAudio27SourceVoice *iface, UINT32 Flags, +static HRESULT WINAPI XA20SRC_Start(IXAudio20SourceVoice *iface, UINT32 Flags, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_Start(&This->IXAudio2SourceVoice_iface, Flags, OperationSet); } -static HRESULT WINAPI XA27SRC_Stop(IXAudio27SourceVoice *iface, UINT32 Flags, +static HRESULT WINAPI XA20SRC_Stop(IXAudio20SourceVoice *iface, UINT32 Flags, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_Stop(&This->IXAudio2SourceVoice_iface, Flags, OperationSet); } -static HRESULT WINAPI XA27SRC_SubmitSourceBuffer(IXAudio27SourceVoice *iface, +static HRESULT WINAPI XA20SRC_SubmitSourceBuffer(IXAudio20SourceVoice *iface, const XAUDIO2_BUFFER *pBuffer, const XAUDIO2_BUFFER_WMA *pBufferWMA) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - return IXAudio2SourceVoice_SubmitSourceBuffer(&This->IXAudio2SourceVoice_iface, pBuffer, - pBufferWMA); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + return IXAudio2SourceVoice_SubmitSourceBuffer(&This->IXAudio2SourceVoice_iface, + pBuffer, pBufferWMA); } -static HRESULT WINAPI XA27SRC_FlushSourceBuffers(IXAudio27SourceVoice *iface) +static HRESULT WINAPI XA20SRC_FlushSourceBuffers(IXAudio20SourceVoice *iface) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_FlushSourceBuffers(&This->IXAudio2SourceVoice_iface); } -static HRESULT WINAPI XA27SRC_Discontinuity(IXAudio27SourceVoice *iface) +static HRESULT WINAPI XA20SRC_Discontinuity(IXAudio20SourceVoice *iface) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_Discontinuity(&This->IXAudio2SourceVoice_iface); } -static HRESULT WINAPI XA27SRC_ExitLoop(IXAudio27SourceVoice *iface, UINT32 OperationSet) +static HRESULT WINAPI XA20SRC_ExitLoop(IXAudio20SourceVoice *iface, + UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_ExitLoop(&This->IXAudio2SourceVoice_iface, OperationSet); } -static void WINAPI XA27SRC_GetState(IXAudio27SourceVoice *iface, +static void WINAPI XA20SRC_GetState(IXAudio20SourceVoice *iface, XAUDIO2_VOICE_STATE *pVoiceState) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_GetState(&This->IXAudio2SourceVoice_iface, pVoiceState, 0); } -static HRESULT WINAPI XA27SRC_SetFrequencyRatio(IXAudio27SourceVoice *iface, +static HRESULT WINAPI XA20SRC_SetFrequencyRatio(IXAudio20SourceVoice *iface, float Ratio, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - return IXAudio2SourceVoice_SetFrequencyRatio(&This->IXAudio2SourceVoice_iface, Ratio, OperationSet); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + return IXAudio2SourceVoice_SetFrequencyRatio(&This->IXAudio2SourceVoice_iface, + Ratio, OperationSet); } -static void WINAPI XA27SRC_GetFrequencyRatio(IXAudio27SourceVoice *iface, float *pRatio) +static void WINAPI XA20SRC_GetFrequencyRatio(IXAudio20SourceVoice *iface, + float *pRatio) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); return IXAudio2SourceVoice_GetFrequencyRatio(&This->IXAudio2SourceVoice_iface, pRatio); } -static HRESULT WINAPI XA27SRC_SetSourceSampleRate( - IXAudio27SourceVoice *iface, - UINT32 NewSourceSampleRate) +const IXAudio20SourceVoiceVtbl XAudio20SourceVoice_Vtbl = { + XA20SRC_GetVoiceDetails, + XA20SRC_SetOutputVoices, + XA20SRC_SetEffectChain, + XA20SRC_EnableEffect, + XA20SRC_DisableEffect, + XA20SRC_GetEffectState, + XA20SRC_SetEffectParameters, + XA20SRC_GetEffectParameters, + XA20SRC_SetFilterParameters, + XA20SRC_GetFilterParameters, + XA20SRC_SetVolume, + XA20SRC_GetVolume, + XA20SRC_SetChannelVolumes, + XA20SRC_GetChannelVolumes, + XA20SRC_SetOutputMatrix, + XA20SRC_GetOutputMatrix, + XA20SRC_DestroyVoice, + XA20SRC_Start, + XA20SRC_Stop, + XA20SRC_SubmitSourceBuffer, + XA20SRC_FlushSourceBuffers, + XA20SRC_Discontinuity, + XA20SRC_ExitLoop, + XA20SRC_GetState, + XA20SRC_SetFrequencyRatio, + XA20SRC_GetFrequencyRatio, +}; + +#elif XAUDIO2_VER <= 3 + +static XA2SourceImpl *impl_from_IXAudio23SourceVoice(IXAudio23SourceVoice *iface) { - XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); - return IXAudio2SourceVoice_SetSourceSampleRate(&This->IXAudio2SourceVoice_iface, NewSourceSampleRate); -} - -const IXAudio27SourceVoiceVtbl XAudio27SourceVoice_Vtbl = { - XA27SRC_GetVoiceDetails, - XA27SRC_SetOutputVoices, - XA27SRC_SetEffectChain, - XA27SRC_EnableEffect, - XA27SRC_DisableEffect, - XA27SRC_GetEffectState, - XA27SRC_SetEffectParameters, - XA27SRC_GetEffectParameters, - XA27SRC_SetFilterParameters, - XA27SRC_GetFilterParameters, - XA27SRC_SetOutputFilterParameters, - XA27SRC_GetOutputFilterParameters, - XA27SRC_SetVolume, - XA27SRC_GetVolume, - XA27SRC_SetChannelVolumes, - XA27SRC_GetChannelVolumes, - XA27SRC_SetOutputMatrix, - XA27SRC_GetOutputMatrix, - XA27SRC_DestroyVoice, - XA27SRC_Start, - XA27SRC_Stop, - XA27SRC_SubmitSourceBuffer, - XA27SRC_FlushSourceBuffers, - XA27SRC_Discontinuity, - XA27SRC_ExitLoop, - XA27SRC_GetState, - XA27SRC_SetFrequencyRatio, - XA27SRC_GetFrequencyRatio, - XA27SRC_SetSourceSampleRate -}; - -static inline IXAudio2Impl *impl_from_IXAudio27(IXAudio27 *iface) -{ - return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio27_iface); -} - -static HRESULT WINAPI XA27_QueryInterface(IXAudio27 *iface, REFIID riid, - void **ppvObject) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - return IXAudio2_QueryInterface(&This->IXAudio2_iface, riid, ppvObject); -} - -static ULONG WINAPI XA27_AddRef(IXAudio27 *iface) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - return IXAudio2_AddRef(&This->IXAudio2_iface); -} - -static ULONG WINAPI XA27_Release(IXAudio27 *iface) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - return IXAudio2_Release(&This->IXAudio2_iface); -} - -static HRESULT WINAPI XA27_GetDeviceCount(IXAudio27 *iface, UINT32 *pCount) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - - TRACE("%p, %p\n", This, pCount); - - *pCount = This->ndevs; - - return S_OK; -} - -static HRESULT WINAPI XA27_GetDeviceDetails(IXAudio27 *iface, UINT32 index, - XAUDIO2_DEVICE_DETAILS *pDeviceDetails) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - HRESULT hr; - IMMDevice *dev; - IAudioClient *client; - IPropertyStore *ps; - WAVEFORMATEX *wfx; - PROPVARIANT var; - - TRACE("%p, %u, %p\n", This, index, pDeviceDetails); - - if(index >= This->ndevs) - return E_INVALIDARG; - - hr = IMMDeviceEnumerator_GetDevice(This->devenum, This->devids[index], &dev); - if(FAILED(hr)){ - WARN("GetDevice failed: %08x\n", hr); - return hr; - } - - hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, - NULL, (void**)&client); - if(FAILED(hr)){ - WARN("Activate failed: %08x\n", hr); - IMMDevice_Release(dev); - return hr; - } - - hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, &ps); - if(FAILED(hr)){ - WARN("OpenPropertyStore failed: %08x\n", hr); - IAudioClient_Release(client); - IMMDevice_Release(dev); - return hr; - } - - PropVariantInit(&var); - - hr = IPropertyStore_GetValue(ps, (PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &var); - if(FAILED(hr)){ - WARN("GetValue failed: %08x\n", hr); - goto done; - } - - lstrcpynW(pDeviceDetails->DisplayName, var.u.pwszVal, sizeof(pDeviceDetails->DisplayName)/sizeof(WCHAR)); - - PropVariantClear(&var); - - hr = IAudioClient_GetMixFormat(client, &wfx); - if(FAILED(hr)){ - WARN("GetMixFormat failed: %08x\n", hr); - goto done; - } - - lstrcpyW(pDeviceDetails->DeviceID, This->devids[index]); - - if(index == 0) - pDeviceDetails->Role = GlobalDefaultDevice; - else - pDeviceDetails->Role = NotDefaultDevice; - - if(sizeof(WAVEFORMATEX) + wfx->cbSize > sizeof(pDeviceDetails->OutputFormat)){ - FIXME("AudioClient format is too large to fit into WAVEFORMATEXTENSIBLE!\n"); - CoTaskMemFree(wfx); - hr = E_FAIL; - goto done; - } - memcpy(&pDeviceDetails->OutputFormat, wfx, sizeof(WAVEFORMATEX) + wfx->cbSize); - - CoTaskMemFree(wfx); - -done: - IPropertyStore_Release(ps); - IAudioClient_Release(client); - IMMDevice_Release(dev); - - return hr; -} - -static HRESULT WINAPI XA27_Initialize(IXAudio27 *iface, UINT32 flags, - XAUDIO2_PROCESSOR processor) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor); - return S_OK; -} - -static HRESULT WINAPI XA27_RegisterForCallbacks(IXAudio27 *iface, - IXAudio2EngineCallback *pCallback) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - return IXAudio2_RegisterForCallbacks(&This->IXAudio2_iface, pCallback); -} - -static void WINAPI XA27_UnregisterForCallbacks(IXAudio27 *iface, - IXAudio2EngineCallback *pCallback) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback); -} - -static HRESULT WINAPI XA27_CreateSourceVoice(IXAudio27 *iface, - IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat, - UINT32 flags, float maxFrequencyRatio, - IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList, - const XAUDIO2_EFFECT_CHAIN *pEffectChain) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - return IXAudio2_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice, - pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList, - pEffectChain); -} - -static HRESULT WINAPI XA27_CreateSubmixVoice(IXAudio27 *iface, - IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels, - UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage, - const XAUDIO2_VOICE_SENDS *pSendList, - const XAUDIO2_EFFECT_CHAIN *pEffectChain) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - return IXAudio2_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice, - inputChannels, inputSampleRate, flags, processingStage, pSendList, - pEffectChain); -} - -static HRESULT WINAPI XA27_CreateMasteringVoice(IXAudio27 *iface, - IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels, - UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex, - const XAUDIO2_EFFECT_CHAIN *pEffectChain) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - - TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p)\n", This, ppMasteringVoice, - inputChannels, inputSampleRate, flags, deviceIndex, - pEffectChain); - - if(deviceIndex >= This->ndevs) - return E_INVALIDARG; - - return IXAudio2_CreateMasteringVoice(&This->IXAudio2_iface, ppMasteringVoice, - inputChannels, inputSampleRate, flags, This->devids[deviceIndex], - pEffectChain, AudioCategory_GameEffects); -} - -static HRESULT WINAPI XA27_StartEngine(IXAudio27 *iface) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - return IXAudio2_StartEngine(&This->IXAudio2_iface); -} - -static void WINAPI XA27_StopEngine(IXAudio27 *iface) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - return IXAudio2_StopEngine(&This->IXAudio2_iface); -} - -static HRESULT WINAPI XA27_CommitChanges(IXAudio27 *iface, UINT32 operationSet) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - return IXAudio2_CommitChanges(&This->IXAudio2_iface, operationSet); -} - -static void WINAPI XA27_GetPerformanceData(IXAudio27 *iface, - XAUDIO2_PERFORMANCE_DATA *pPerfData) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - return IXAudio2_GetPerformanceData(&This->IXAudio2_iface, pPerfData); -} - -static void WINAPI XA27_SetDebugConfiguration(IXAudio27 *iface, - const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration, - void *pReserved) -{ - IXAudio2Impl *This = impl_from_IXAudio27(iface); - return IXAudio2_SetDebugConfiguration(&This->IXAudio2_iface, - pDebugConfiguration, pReserved); -} - -const IXAudio27Vtbl XAudio27_Vtbl = { - XA27_QueryInterface, - XA27_AddRef, - XA27_Release, - XA27_GetDeviceCount, - XA27_GetDeviceDetails, - XA27_Initialize, - XA27_RegisterForCallbacks, - XA27_UnregisterForCallbacks, - XA27_CreateSourceVoice, - XA27_CreateSubmixVoice, - XA27_CreateMasteringVoice, - XA27_StartEngine, - XA27_StopEngine, - XA27_CommitChanges, - XA27_GetPerformanceData, - XA27_SetDebugConfiguration -}; - -static XA2SourceImpl *impl_from_IXAudio23SourceVoice(IXAudio23SourceVoice *iface) -{ - return CONTAINING_RECORD(iface, XA2SourceImpl, IXAudio23SourceVoice_iface); + return CONTAINING_RECORD(iface, XA2SourceImpl, IXAudio23SourceVoice_iface); } static void WINAPI XA23SRC_GetVoiceDetails(IXAudio23SourceVoice *iface, @@ -830,628 +605,644 @@ XA23SRC_GetFrequencyRatio, }; -static XA2SubmixImpl *impl_from_IXAudio23SubmixVoice(IXAudio23SubmixVoice *iface) +#elif XAUDIO2_VER <= 7 + +static XA2SourceImpl *impl_from_IXAudio27SourceVoice(IXAudio27SourceVoice *iface) { - return CONTAINING_RECORD(iface, XA2SubmixImpl, IXAudio23SubmixVoice_iface); + return CONTAINING_RECORD(iface, XA2SourceImpl, IXAudio27SourceVoice_iface); } -static void WINAPI XA23SUB_GetVoiceDetails(IXAudio23SubmixVoice *iface, +static void WINAPI XA27SRC_GetVoiceDetails(IXAudio27SourceVoice *iface, XAUDIO2_VOICE_DETAILS *pVoiceDetails) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_GetVoiceDetails(&This->IXAudio2SubmixVoice_iface, pVoiceDetails); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_GetVoiceDetails(&This->IXAudio2SourceVoice_iface, pVoiceDetails); } -static HRESULT WINAPI XA23SUB_SetOutputVoices(IXAudio23SubmixVoice *iface, - const XAUDIO23_VOICE_SENDS *pSendList) +static HRESULT WINAPI XA27SRC_SetOutputVoices(IXAudio27SourceVoice *iface, + const XAUDIO2_VOICE_SENDS *pSendList) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - XAUDIO2_VOICE_SENDS sends; - HRESULT hr; - DWORD i; - - TRACE("%p, %p\n", This, pSendList); - - sends.SendCount = pSendList->OutputCount; - sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends)); - for(i = 0; i < sends.SendCount; ++i){ - sends.pSends[i].Flags = 0; - sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i]; - } - - hr = IXAudio2SubmixVoice_SetOutputVoices(&This->IXAudio2SubmixVoice_iface, &sends); - - HeapFree(GetProcessHeap(), 0, sends.pSends); - - return hr; + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_SetOutputVoices(&This->IXAudio2SourceVoice_iface, pSendList); } -static HRESULT WINAPI XA23SUB_SetEffectChain(IXAudio23SubmixVoice *iface, +static HRESULT WINAPI XA27SRC_SetEffectChain(IXAudio27SourceVoice *iface, const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_SetEffectChain(&This->IXAudio2SubmixVoice_iface, pEffectChain); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_SetEffectChain(&This->IXAudio2SourceVoice_iface, pEffectChain); } -static HRESULT WINAPI XA23SUB_EnableEffect(IXAudio23SubmixVoice *iface, +static HRESULT WINAPI XA27SRC_EnableEffect(IXAudio27SourceVoice *iface, UINT32 EffectIndex, UINT32 OperationSet) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_EnableEffect(&This->IXAudio2SubmixVoice_iface, - EffectIndex, OperationSet); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_EnableEffect(&This->IXAudio2SourceVoice_iface, EffectIndex, OperationSet); } -static HRESULT WINAPI XA23SUB_DisableEffect(IXAudio23SubmixVoice *iface, +static HRESULT WINAPI XA27SRC_DisableEffect(IXAudio27SourceVoice *iface, UINT32 EffectIndex, UINT32 OperationSet) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_DisableEffect(&This->IXAudio2SubmixVoice_iface, - EffectIndex, OperationSet); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_DisableEffect(&This->IXAudio2SourceVoice_iface, EffectIndex, OperationSet); } -static void WINAPI XA23SUB_GetEffectState(IXAudio23SubmixVoice *iface, +static void WINAPI XA27SRC_GetEffectState(IXAudio27SourceVoice *iface, UINT32 EffectIndex, BOOL *pEnabled) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_GetEffectState(&This->IXAudio2SubmixVoice_iface, - EffectIndex, pEnabled); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + IXAudio2SourceVoice_GetEffectState(&This->IXAudio2SourceVoice_iface, EffectIndex, pEnabled); } -static HRESULT WINAPI XA23SUB_SetEffectParameters(IXAudio23SubmixVoice *iface, +static HRESULT WINAPI XA27SRC_SetEffectParameters(IXAudio27SourceVoice *iface, UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize, UINT32 OperationSet) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_SetEffectParameters(&This->IXAudio2SubmixVoice_iface, + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_SetEffectParameters(&This->IXAudio2SourceVoice_iface, EffectIndex, pParameters, ParametersByteSize, OperationSet); } -static HRESULT WINAPI XA23SUB_GetEffectParameters(IXAudio23SubmixVoice *iface, +static HRESULT WINAPI XA27SRC_GetEffectParameters(IXAudio27SourceVoice *iface, UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_GetEffectParameters(&This->IXAudio2SubmixVoice_iface, + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_GetEffectParameters(&This->IXAudio2SourceVoice_iface, EffectIndex, pParameters, ParametersByteSize); } -static HRESULT WINAPI XA23SUB_SetFilterParameters(IXAudio23SubmixVoice *iface, +static HRESULT WINAPI XA27SRC_SetFilterParameters(IXAudio27SourceVoice *iface, const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_SetFilterParameters(&This->IXAudio2SubmixVoice_iface, + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_SetFilterParameters(&This->IXAudio2SourceVoice_iface, pParameters, OperationSet); } -static void WINAPI XA23SUB_GetFilterParameters(IXAudio23SubmixVoice *iface, +static void WINAPI XA27SRC_GetFilterParameters(IXAudio27SourceVoice *iface, XAUDIO2_FILTER_PARAMETERS *pParameters) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_GetFilterParameters(&This->IXAudio2SubmixVoice_iface, pParameters); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + IXAudio2SourceVoice_GetFilterParameters(&This->IXAudio2SourceVoice_iface, pParameters); } -static HRESULT WINAPI XA23SUB_SetVolume(IXAudio23SubmixVoice *iface, - float Volume, UINT32 OperationSet) +static HRESULT WINAPI XA27SRC_SetOutputFilterParameters(IXAudio27SourceVoice *iface, + IXAudio2Voice *pDestinationVoice, + const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_SetVolume(&This->IXAudio2SubmixVoice_iface, - Volume, OperationSet); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_SetOutputFilterParameters(&This->IXAudio2SourceVoice_iface, + pDestinationVoice, pParameters, OperationSet); } -static void WINAPI XA23SUB_GetVolume(IXAudio23SubmixVoice *iface, - float *pVolume) +static void WINAPI XA27SRC_GetOutputFilterParameters(IXAudio27SourceVoice *iface, + IXAudio2Voice *pDestinationVoice, + XAUDIO2_FILTER_PARAMETERS *pParameters) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_GetVolume(&This->IXAudio2SubmixVoice_iface, pVolume); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + IXAudio2SourceVoice_GetOutputFilterParameters(&This->IXAudio2SourceVoice_iface, + pDestinationVoice, pParameters); } -static HRESULT WINAPI XA23SUB_SetChannelVolumes(IXAudio23SubmixVoice *iface, +static HRESULT WINAPI XA27SRC_SetVolume(IXAudio27SourceVoice *iface, float Volume, + UINT32 OperationSet) +{ + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_SetVolume(&This->IXAudio2SourceVoice_iface, Volume, + OperationSet); +} + +static void WINAPI XA27SRC_GetVolume(IXAudio27SourceVoice *iface, float *pVolume) +{ + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + IXAudio2SourceVoice_GetVolume(&This->IXAudio2SourceVoice_iface, pVolume); +} + +static HRESULT WINAPI XA27SRC_SetChannelVolumes(IXAudio27SourceVoice *iface, UINT32 Channels, const float *pVolumes, UINT32 OperationSet) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_SetChannelVolumes(&This->IXAudio2SubmixVoice_iface, - Channels, pVolumes, OperationSet); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_SetChannelVolumes(&This->IXAudio2SourceVoice_iface, Channels, + pVolumes, OperationSet); } -static void WINAPI XA23SUB_GetChannelVolumes(IXAudio23SubmixVoice *iface, +static void WINAPI XA27SRC_GetChannelVolumes(IXAudio27SourceVoice *iface, UINT32 Channels, float *pVolumes) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_GetChannelVolumes(&This->IXAudio2SubmixVoice_iface, - Channels, pVolumes); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + IXAudio2SourceVoice_GetChannelVolumes(&This->IXAudio2SourceVoice_iface, Channels, + pVolumes); } -static HRESULT WINAPI XA23SUB_SetOutputMatrix(IXAudio23SubmixVoice *iface, - IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels, +static HRESULT WINAPI XA27SRC_SetOutputMatrix(IXAudio27SourceVoice *iface, + IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels, UINT32 DestinationChannels, const float *pLevelMatrix, UINT32 OperationSet) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_SetOutputMatrix(&This->IXAudio2SubmixVoice_iface, - pDestinationVoice, SubmixChannels, DestinationChannels, + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_SetOutputMatrix(&This->IXAudio2SourceVoice_iface, + pDestinationVoice, SourceChannels, DestinationChannels, pLevelMatrix, OperationSet); } -static void WINAPI XA23SUB_GetOutputMatrix(IXAudio23SubmixVoice *iface, - IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels, +static void WINAPI XA27SRC_GetOutputMatrix(IXAudio27SourceVoice *iface, + IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels, UINT32 DestinationChannels, float *pLevelMatrix) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_GetOutputMatrix(&This->IXAudio2SubmixVoice_iface, - pDestinationVoice, SubmixChannels, DestinationChannels, - pLevelMatrix); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + IXAudio2SourceVoice_GetOutputMatrix(&This->IXAudio2SourceVoice_iface, pDestinationVoice, + SourceChannels, DestinationChannels, pLevelMatrix); } -static void WINAPI XA23SUB_DestroyVoice(IXAudio23SubmixVoice *iface) +static void WINAPI XA27SRC_DestroyVoice(IXAudio27SourceVoice *iface) { - XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); - return IXAudio2SubmixVoice_DestroyVoice(&This->IXAudio2SubmixVoice_iface); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + IXAudio2SourceVoice_DestroyVoice(&This->IXAudio2SourceVoice_iface); } -const IXAudio23SubmixVoiceVtbl XAudio23SubmixVoice_Vtbl = { - XA23SUB_GetVoiceDetails, - XA23SUB_SetOutputVoices, - XA23SUB_SetEffectChain, - XA23SUB_EnableEffect, - XA23SUB_DisableEffect, - XA23SUB_GetEffectState, - XA23SUB_SetEffectParameters, - XA23SUB_GetEffectParameters, - XA23SUB_SetFilterParameters, - XA23SUB_GetFilterParameters, - XA23SUB_SetVolume, - XA23SUB_GetVolume, - XA23SUB_SetChannelVolumes, - XA23SUB_GetChannelVolumes, - XA23SUB_SetOutputMatrix, - XA23SUB_GetOutputMatrix, - XA23SUB_DestroyVoice -}; - -static IXAudio2Impl *impl_from_IXAudio23MasteringVoice(IXAudio23MasteringVoice *iface) +static HRESULT WINAPI XA27SRC_Start(IXAudio27SourceVoice *iface, UINT32 Flags, + UINT32 OperationSet) { - return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio23MasteringVoice_iface); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_Start(&This->IXAudio2SourceVoice_iface, Flags, OperationSet); } -static void WINAPI XA23M_GetVoiceDetails(IXAudio23MasteringVoice *iface, - XAUDIO2_VOICE_DETAILS *pVoiceDetails) +static HRESULT WINAPI XA27SRC_Stop(IXAudio27SourceVoice *iface, UINT32 Flags, + UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_GetVoiceDetails(&This->IXAudio2MasteringVoice_iface, pVoiceDetails); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_Stop(&This->IXAudio2SourceVoice_iface, Flags, OperationSet); } -static HRESULT WINAPI XA23M_SetOutputVoices(IXAudio23MasteringVoice *iface, - const XAUDIO23_VOICE_SENDS *pSendList) +static HRESULT WINAPI XA27SRC_SubmitSourceBuffer(IXAudio27SourceVoice *iface, + const XAUDIO2_BUFFER *pBuffer, const XAUDIO2_BUFFER_WMA *pBufferWMA) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - XAUDIO2_VOICE_SENDS sends; - HRESULT hr; - DWORD i; - - TRACE("%p, %p\n", This, pSendList); - - sends.SendCount = pSendList->OutputCount; - sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends)); - for(i = 0; i < sends.SendCount; ++i){ - sends.pSends[i].Flags = 0; - sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i]; - } - - hr = IXAudio2MasteringVoice_SetOutputVoices(&This->IXAudio2MasteringVoice_iface, &sends); - - HeapFree(GetProcessHeap(), 0, sends.pSends); - - return hr; + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_SubmitSourceBuffer(&This->IXAudio2SourceVoice_iface, pBuffer, + pBufferWMA); } -static HRESULT WINAPI XA23M_SetEffectChain(IXAudio23MasteringVoice *iface, - const XAUDIO2_EFFECT_CHAIN *pEffectChain) +static HRESULT WINAPI XA27SRC_FlushSourceBuffers(IXAudio27SourceVoice *iface) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_SetEffectChain(&This->IXAudio2MasteringVoice_iface, pEffectChain); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_FlushSourceBuffers(&This->IXAudio2SourceVoice_iface); } -static HRESULT WINAPI XA23M_EnableEffect(IXAudio23MasteringVoice *iface, - UINT32 EffectIndex, UINT32 OperationSet) +static HRESULT WINAPI XA27SRC_Discontinuity(IXAudio27SourceVoice *iface) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_EnableEffect(&This->IXAudio2MasteringVoice_iface, - EffectIndex, OperationSet); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_Discontinuity(&This->IXAudio2SourceVoice_iface); } -static HRESULT WINAPI XA23M_DisableEffect(IXAudio23MasteringVoice *iface, - UINT32 EffectIndex, UINT32 OperationSet) +static HRESULT WINAPI XA27SRC_ExitLoop(IXAudio27SourceVoice *iface, UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_DisableEffect(&This->IXAudio2MasteringVoice_iface, - EffectIndex, OperationSet); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_ExitLoop(&This->IXAudio2SourceVoice_iface, OperationSet); } -static void WINAPI XA23M_GetEffectState(IXAudio23MasteringVoice *iface, - UINT32 EffectIndex, BOOL *pEnabled) +static void WINAPI XA27SRC_GetState(IXAudio27SourceVoice *iface, + XAUDIO2_VOICE_STATE *pVoiceState) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_GetEffectState(&This->IXAudio2MasteringVoice_iface, - EffectIndex, pEnabled); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_GetState(&This->IXAudio2SourceVoice_iface, pVoiceState, 0); } -static HRESULT WINAPI XA23M_SetEffectParameters(IXAudio23MasteringVoice *iface, - UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize, - UINT32 OperationSet) +static HRESULT WINAPI XA27SRC_SetFrequencyRatio(IXAudio27SourceVoice *iface, + float Ratio, UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_SetEffectParameters(&This->IXAudio2MasteringVoice_iface, - EffectIndex, pParameters, ParametersByteSize, OperationSet); + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_SetFrequencyRatio(&This->IXAudio2SourceVoice_iface, Ratio, OperationSet); } -static HRESULT WINAPI XA23M_GetEffectParameters(IXAudio23MasteringVoice *iface, +static void WINAPI XA27SRC_GetFrequencyRatio(IXAudio27SourceVoice *iface, float *pRatio) +{ + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_GetFrequencyRatio(&This->IXAudio2SourceVoice_iface, pRatio); +} + +static HRESULT WINAPI XA27SRC_SetSourceSampleRate( + IXAudio27SourceVoice *iface, + UINT32 NewSourceSampleRate) +{ + XA2SourceImpl *This = impl_from_IXAudio27SourceVoice(iface); + return IXAudio2SourceVoice_SetSourceSampleRate(&This->IXAudio2SourceVoice_iface, NewSourceSampleRate); +} + +const IXAudio27SourceVoiceVtbl XAudio27SourceVoice_Vtbl = { + XA27SRC_GetVoiceDetails, + XA27SRC_SetOutputVoices, + XA27SRC_SetEffectChain, + XA27SRC_EnableEffect, + XA27SRC_DisableEffect, + XA27SRC_GetEffectState, + XA27SRC_SetEffectParameters, + XA27SRC_GetEffectParameters, + XA27SRC_SetFilterParameters, + XA27SRC_GetFilterParameters, + XA27SRC_SetOutputFilterParameters, + XA27SRC_GetOutputFilterParameters, + XA27SRC_SetVolume, + XA27SRC_GetVolume, + XA27SRC_SetChannelVolumes, + XA27SRC_GetChannelVolumes, + XA27SRC_SetOutputMatrix, + XA27SRC_GetOutputMatrix, + XA27SRC_DestroyVoice, + XA27SRC_Start, + XA27SRC_Stop, + XA27SRC_SubmitSourceBuffer, + XA27SRC_FlushSourceBuffers, + XA27SRC_Discontinuity, + XA27SRC_ExitLoop, + XA27SRC_GetState, + XA27SRC_SetFrequencyRatio, + XA27SRC_GetFrequencyRatio, + XA27SRC_SetSourceSampleRate +}; +#endif +/* END IXAudio2SourceVoice */ + + +/* BEGIN IXAudio2SubmixVoice */ +#if XAUDIO2_VER == 0 +static XA2SubmixImpl *impl_from_IXAudio20SubmixVoice(IXAudio20SubmixVoice *iface) +{ + return CONTAINING_RECORD(iface, XA2SubmixImpl, IXAudio20SubmixVoice_iface); +} + +static void WINAPI XA20SUB_GetVoiceDetails(IXAudio20SubmixVoice *iface, + XAUDIO2_VOICE_DETAILS *pVoiceDetails) +{ + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_GetVoiceDetails(&This->IXAudio2SubmixVoice_iface, pVoiceDetails); +} + +static HRESULT WINAPI XA20SUB_SetOutputVoices(IXAudio20SubmixVoice *iface, + const XAUDIO23_VOICE_SENDS *pSendList) +{ + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + XAUDIO2_VOICE_SENDS sends; + HRESULT hr; + DWORD i; + + TRACE("%p, %p\n", This, pSendList); + + sends.SendCount = pSendList->OutputCount; + sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends)); + for(i = 0; i < sends.SendCount; ++i){ + sends.pSends[i].Flags = 0; + sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i]; + } + + hr = IXAudio2SubmixVoice_SetOutputVoices(&This->IXAudio2SubmixVoice_iface, &sends); + + HeapFree(GetProcessHeap(), 0, sends.pSends); + + return hr; +} + +static HRESULT WINAPI XA20SUB_SetEffectChain(IXAudio20SubmixVoice *iface, + const XAUDIO2_EFFECT_CHAIN *pEffectChain) +{ + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_SetEffectChain(&This->IXAudio2SubmixVoice_iface, pEffectChain); +} + +static HRESULT WINAPI XA20SUB_EnableEffect(IXAudio20SubmixVoice *iface, + UINT32 EffectIndex, UINT32 OperationSet) +{ + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_EnableEffect(&This->IXAudio2SubmixVoice_iface, + EffectIndex, OperationSet); +} + +static HRESULT WINAPI XA20SUB_DisableEffect(IXAudio20SubmixVoice *iface, + UINT32 EffectIndex, UINT32 OperationSet) +{ + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_DisableEffect(&This->IXAudio2SubmixVoice_iface, + EffectIndex, OperationSet); +} + +static void WINAPI XA20SUB_GetEffectState(IXAudio20SubmixVoice *iface, + UINT32 EffectIndex, BOOL *pEnabled) +{ + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_GetEffectState(&This->IXAudio2SubmixVoice_iface, + EffectIndex, pEnabled); +} + +static HRESULT WINAPI XA20SUB_SetEffectParameters(IXAudio20SubmixVoice *iface, + UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize, + UINT32 OperationSet) +{ + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_SetEffectParameters(&This->IXAudio2SubmixVoice_iface, + EffectIndex, pParameters, ParametersByteSize, OperationSet); +} + +static HRESULT WINAPI XA20SUB_GetEffectParameters(IXAudio20SubmixVoice *iface, UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_GetEffectParameters(&This->IXAudio2MasteringVoice_iface, + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_GetEffectParameters(&This->IXAudio2SubmixVoice_iface, EffectIndex, pParameters, ParametersByteSize); } -static HRESULT WINAPI XA23M_SetFilterParameters(IXAudio23MasteringVoice *iface, +static HRESULT WINAPI XA20SUB_SetFilterParameters(IXAudio20SubmixVoice *iface, const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_SetFilterParameters(&This->IXAudio2MasteringVoice_iface, + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_SetFilterParameters(&This->IXAudio2SubmixVoice_iface, pParameters, OperationSet); } -static void WINAPI XA23M_GetFilterParameters(IXAudio23MasteringVoice *iface, +static void WINAPI XA20SUB_GetFilterParameters(IXAudio20SubmixVoice *iface, XAUDIO2_FILTER_PARAMETERS *pParameters) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_GetFilterParameters(&This->IXAudio2MasteringVoice_iface, pParameters); + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_GetFilterParameters(&This->IXAudio2SubmixVoice_iface, pParameters); } -static HRESULT WINAPI XA23M_SetVolume(IXAudio23MasteringVoice *iface, +static HRESULT WINAPI XA20SUB_SetVolume(IXAudio20SubmixVoice *iface, float Volume, UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_SetVolume(&This->IXAudio2MasteringVoice_iface, + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_SetVolume(&This->IXAudio2SubmixVoice_iface, Volume, OperationSet); } -static void WINAPI XA23M_GetVolume(IXAudio23MasteringVoice *iface, +static void WINAPI XA20SUB_GetVolume(IXAudio20SubmixVoice *iface, float *pVolume) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_GetVolume(&This->IXAudio2MasteringVoice_iface, pVolume); + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_GetVolume(&This->IXAudio2SubmixVoice_iface, pVolume); } -static HRESULT WINAPI XA23M_SetChannelVolumes(IXAudio23MasteringVoice *iface, +static HRESULT WINAPI XA20SUB_SetChannelVolumes(IXAudio20SubmixVoice *iface, UINT32 Channels, const float *pVolumes, UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_SetChannelVolumes(&This->IXAudio2MasteringVoice_iface, + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_SetChannelVolumes(&This->IXAudio2SubmixVoice_iface, Channels, pVolumes, OperationSet); } -static void WINAPI XA23M_GetChannelVolumes(IXAudio23MasteringVoice *iface, +static void WINAPI XA20SUB_GetChannelVolumes(IXAudio20SubmixVoice *iface, UINT32 Channels, float *pVolumes) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_GetChannelVolumes(&This->IXAudio2MasteringVoice_iface, + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_GetChannelVolumes(&This->IXAudio2SubmixVoice_iface, Channels, pVolumes); } -static HRESULT WINAPI XA23M_SetOutputMatrix(IXAudio23MasteringVoice *iface, - IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels, +static HRESULT WINAPI XA20SUB_SetOutputMatrix(IXAudio20SubmixVoice *iface, + IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels, UINT32 DestinationChannels, const float *pLevelMatrix, UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_SetOutputMatrix(&This->IXAudio2MasteringVoice_iface, - pDestinationVoice, MasteringChannels, DestinationChannels, + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_SetOutputMatrix(&This->IXAudio2SubmixVoice_iface, + pDestinationVoice, SubmixChannels, DestinationChannels, pLevelMatrix, OperationSet); } -static void WINAPI XA23M_GetOutputMatrix(IXAudio23MasteringVoice *iface, - IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels, +static HRESULT WINAPI XA20SUB_GetOutputMatrix(IXAudio20SubmixVoice *iface, + IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels, UINT32 DestinationChannels, float *pLevelMatrix) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_GetOutputMatrix(&This->IXAudio2MasteringVoice_iface, - pDestinationVoice, MasteringChannels, DestinationChannels, + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + IXAudio2SubmixVoice_GetOutputMatrix(&This->IXAudio2SubmixVoice_iface, + pDestinationVoice, SubmixChannels, DestinationChannels, pLevelMatrix); + return S_OK; } -static void WINAPI XA23M_DestroyVoice(IXAudio23MasteringVoice *iface) +static void WINAPI XA20SUB_DestroyVoice(IXAudio20SubmixVoice *iface) { - IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); - return IXAudio2MasteringVoice_DestroyVoice(&This->IXAudio2MasteringVoice_iface); + XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); + return IXAudio2SubmixVoice_DestroyVoice(&This->IXAudio2SubmixVoice_iface); } -const IXAudio23MasteringVoiceVtbl XAudio23MasteringVoice_Vtbl = { - XA23M_GetVoiceDetails, - XA23M_SetOutputVoices, - XA23M_SetEffectChain, - XA23M_EnableEffect, - XA23M_DisableEffect, - XA23M_GetEffectState, - XA23M_SetEffectParameters, - XA23M_GetEffectParameters, - XA23M_SetFilterParameters, - XA23M_GetFilterParameters, - XA23M_SetVolume, - XA23M_GetVolume, - XA23M_SetChannelVolumes, - XA23M_GetChannelVolumes, - XA23M_SetOutputMatrix, - XA23M_GetOutputMatrix, - XA23M_DestroyVoice +const IXAudio20SubmixVoiceVtbl XAudio20SubmixVoice_Vtbl = { + XA20SUB_GetVoiceDetails, + XA20SUB_SetOutputVoices, + XA20SUB_SetEffectChain, + XA20SUB_EnableEffect, + XA20SUB_DisableEffect, + XA20SUB_GetEffectState, + XA20SUB_SetEffectParameters, + XA20SUB_GetEffectParameters, + XA20SUB_SetFilterParameters, + XA20SUB_GetFilterParameters, + XA20SUB_SetVolume, + XA20SUB_GetVolume, + XA20SUB_SetChannelVolumes, + XA20SUB_GetChannelVolumes, + XA20SUB_SetOutputMatrix, + XA20SUB_GetOutputMatrix, + XA20SUB_DestroyVoice }; -static inline IXAudio2Impl *impl_from_IXAudio22(IXAudio22 *iface) -{ - return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio22_iface); -} +#elif XAUDIO2_VER <= 3 -static HRESULT WINAPI XA22_QueryInterface(IXAudio22 *iface, REFIID riid, - void **ppvObject) +static XA2SubmixImpl *impl_from_IXAudio23SubmixVoice(IXAudio23SubmixVoice *iface) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - return IXAudio2_QueryInterface(&This->IXAudio2_iface, riid, ppvObject); + return CONTAINING_RECORD(iface, XA2SubmixImpl, IXAudio23SubmixVoice_iface); } -static ULONG WINAPI XA22_AddRef(IXAudio22 *iface) +static void WINAPI XA23SUB_GetVoiceDetails(IXAudio23SubmixVoice *iface, + XAUDIO2_VOICE_DETAILS *pVoiceDetails) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - return IXAudio2_AddRef(&This->IXAudio2_iface); + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_GetVoiceDetails(&This->IXAudio2SubmixVoice_iface, pVoiceDetails); } -static ULONG WINAPI XA22_Release(IXAudio22 *iface) +static HRESULT WINAPI XA23SUB_SetOutputVoices(IXAudio23SubmixVoice *iface, + const XAUDIO23_VOICE_SENDS *pSendList) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - return IXAudio2_Release(&This->IXAudio2_iface); -} + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + XAUDIO2_VOICE_SENDS sends; + HRESULT hr; + DWORD i; -static HRESULT WINAPI XA22_GetDeviceCount(IXAudio22 *iface, UINT32 *pCount) -{ - IXAudio2Impl *This = impl_from_IXAudio22(iface); - - TRACE("%p, %p\n", This, pCount); - - *pCount = This->ndevs; - - return S_OK; -} - -static HRESULT WINAPI XA22_GetDeviceDetails(IXAudio22 *iface, UINT32 index, - XAUDIO2_DEVICE_DETAILS *pDeviceDetails) -{ - IXAudio2Impl *This = impl_from_IXAudio22(iface); - HRESULT hr; - IMMDevice *dev; - IAudioClient *client; - IPropertyStore *ps; - WAVEFORMATEX *wfx; - PROPVARIANT var; - - TRACE("%p, %u, %p\n", This, index, pDeviceDetails); - - if(index >= This->ndevs) - return E_INVALIDARG; - - hr = IMMDeviceEnumerator_GetDevice(This->devenum, This->devids[index], &dev); - if(FAILED(hr)){ - WARN("GetDevice failed: %08x\n", hr); - return hr; - } - - hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, - NULL, (void**)&client); - if(FAILED(hr)){ - WARN("Activate failed: %08x\n", hr); - IMMDevice_Release(dev); - return hr; - } - - hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, &ps); - if(FAILED(hr)){ - WARN("OpenPropertyStore failed: %08x\n", hr); - IAudioClient_Release(client); - IMMDevice_Release(dev); - return hr; - } - - PropVariantInit(&var); - - hr = IPropertyStore_GetValue(ps, (PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &var); - if(FAILED(hr)){ - WARN("GetValue failed: %08x\n", hr); - goto done; - } - - lstrcpynW(pDeviceDetails->DisplayName, var.u.pwszVal, sizeof(pDeviceDetails->DisplayName)/sizeof(WCHAR)); - - PropVariantClear(&var); - - hr = IAudioClient_GetMixFormat(client, &wfx); - if(FAILED(hr)){ - WARN("GetMixFormat failed: %08x\n", hr); - goto done; - } - - lstrcpyW(pDeviceDetails->DeviceID, This->devids[index]); - - if(index == 0) - pDeviceDetails->Role = GlobalDefaultDevice; - else - pDeviceDetails->Role = NotDefaultDevice; + TRACE("%p, %p\n", This, pSendList); - if(sizeof(WAVEFORMATEX) + wfx->cbSize > sizeof(pDeviceDetails->OutputFormat)){ - FIXME("AudioClient format is too large to fit into WAVEFORMATEXTENSIBLE!\n"); - CoTaskMemFree(wfx); - hr = E_FAIL; - goto done; + sends.SendCount = pSendList->OutputCount; + sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends)); + for(i = 0; i < sends.SendCount; ++i){ + sends.pSends[i].Flags = 0; + sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i]; } - memcpy(&pDeviceDetails->OutputFormat, wfx, sizeof(WAVEFORMATEX) + wfx->cbSize); - CoTaskMemFree(wfx); + hr = IXAudio2SubmixVoice_SetOutputVoices(&This->IXAudio2SubmixVoice_iface, &sends); -done: - IPropertyStore_Release(ps); - IAudioClient_Release(client); - IMMDevice_Release(dev); + HeapFree(GetProcessHeap(), 0, sends.pSends); return hr; } -static HRESULT WINAPI XA22_Initialize(IXAudio22 *iface, UINT32 flags, - XAUDIO2_PROCESSOR processor) +static HRESULT WINAPI XA23SUB_SetEffectChain(IXAudio23SubmixVoice *iface, + const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor); - return S_OK; + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_SetEffectChain(&This->IXAudio2SubmixVoice_iface, pEffectChain); } -static HRESULT WINAPI XA22_RegisterForCallbacks(IXAudio22 *iface, - IXAudio2EngineCallback *pCallback) +static HRESULT WINAPI XA23SUB_EnableEffect(IXAudio23SubmixVoice *iface, + UINT32 EffectIndex, UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - return IXAudio2_RegisterForCallbacks(&This->IXAudio2_iface, pCallback); + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_EnableEffect(&This->IXAudio2SubmixVoice_iface, + EffectIndex, OperationSet); } -static void WINAPI XA22_UnregisterForCallbacks(IXAudio22 *iface, - IXAudio2EngineCallback *pCallback) +static HRESULT WINAPI XA23SUB_DisableEffect(IXAudio23SubmixVoice *iface, + UINT32 EffectIndex, UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback); + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_DisableEffect(&This->IXAudio2SubmixVoice_iface, + EffectIndex, OperationSet); } -static HRESULT WINAPI XA22_CreateSourceVoice(IXAudio22 *iface, - IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat, - UINT32 flags, float maxFrequencyRatio, - IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList, - const XAUDIO2_EFFECT_CHAIN *pEffectChain) +static void WINAPI XA23SUB_GetEffectState(IXAudio23SubmixVoice *iface, + UINT32 EffectIndex, BOOL *pEnabled) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - return IXAudio2_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice, - pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList, - pEffectChain); + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_GetEffectState(&This->IXAudio2SubmixVoice_iface, + EffectIndex, pEnabled); } -static HRESULT WINAPI XA22_CreateSubmixVoice(IXAudio22 *iface, - IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels, - UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage, - const XAUDIO2_VOICE_SENDS *pSendList, - const XAUDIO2_EFFECT_CHAIN *pEffectChain) +static HRESULT WINAPI XA23SUB_SetEffectParameters(IXAudio23SubmixVoice *iface, + UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize, + UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - return IXAudio2_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice, - inputChannels, inputSampleRate, flags, processingStage, pSendList, - pEffectChain); + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_SetEffectParameters(&This->IXAudio2SubmixVoice_iface, + EffectIndex, pParameters, ParametersByteSize, OperationSet); } -static HRESULT WINAPI XA22_CreateMasteringVoice(IXAudio22 *iface, - IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels, - UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex, - const XAUDIO2_EFFECT_CHAIN *pEffectChain) +static HRESULT WINAPI XA23SUB_GetEffectParameters(IXAudio23SubmixVoice *iface, + UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - - TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p)\n", This, ppMasteringVoice, - inputChannels, inputSampleRate, flags, deviceIndex, - pEffectChain); - - if(deviceIndex >= This->ndevs) - return E_INVALIDARG; - - return IXAudio2_CreateMasteringVoice(&This->IXAudio2_iface, ppMasteringVoice, - inputChannels, inputSampleRate, flags, This->devids[deviceIndex], - pEffectChain, AudioCategory_GameEffects); + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_GetEffectParameters(&This->IXAudio2SubmixVoice_iface, + EffectIndex, pParameters, ParametersByteSize); } -static HRESULT WINAPI XA22_StartEngine(IXAudio22 *iface) +static HRESULT WINAPI XA23SUB_SetFilterParameters(IXAudio23SubmixVoice *iface, + const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - return IXAudio2_StartEngine(&This->IXAudio2_iface); + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_SetFilterParameters(&This->IXAudio2SubmixVoice_iface, + pParameters, OperationSet); } -static void WINAPI XA22_StopEngine(IXAudio22 *iface) +static void WINAPI XA23SUB_GetFilterParameters(IXAudio23SubmixVoice *iface, + XAUDIO2_FILTER_PARAMETERS *pParameters) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - return IXAudio2_StopEngine(&This->IXAudio2_iface); + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_GetFilterParameters(&This->IXAudio2SubmixVoice_iface, pParameters); } -static HRESULT WINAPI XA22_CommitChanges(IXAudio22 *iface, UINT32 operationSet) +static HRESULT WINAPI XA23SUB_SetVolume(IXAudio23SubmixVoice *iface, + float Volume, UINT32 OperationSet) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - return IXAudio2_CommitChanges(&This->IXAudio2_iface, operationSet); + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_SetVolume(&This->IXAudio2SubmixVoice_iface, + Volume, OperationSet); } -static void WINAPI XA22_GetPerformanceData(IXAudio22 *iface, - XAUDIO22_PERFORMANCE_DATA *pPerfData) +static void WINAPI XA23SUB_GetVolume(IXAudio23SubmixVoice *iface, + float *pVolume) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - XAUDIO2_PERFORMANCE_DATA data; + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_GetVolume(&This->IXAudio2SubmixVoice_iface, pVolume); +} - IXAudio2_GetPerformanceData(&This->IXAudio2_iface, &data); +static HRESULT WINAPI XA23SUB_SetChannelVolumes(IXAudio23SubmixVoice *iface, + UINT32 Channels, const float *pVolumes, UINT32 OperationSet) +{ + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_SetChannelVolumes(&This->IXAudio2SubmixVoice_iface, + Channels, pVolumes, OperationSet); +} - pPerfData->AudioCyclesSinceLastQuery = data.AudioCyclesSinceLastQuery; - pPerfData->TotalCyclesSinceLastQuery = data.TotalCyclesSinceLastQuery; - pPerfData->MinimumCyclesPerQuantum = data.MinimumCyclesPerQuantum; - pPerfData->MaximumCyclesPerQuantum = data.MaximumCyclesPerQuantum; - pPerfData->MemoryUsageInBytes = data.MemoryUsageInBytes; - pPerfData->CurrentLatencyInSamples = data.CurrentLatencyInSamples; - pPerfData->GlitchesSinceEngineStarted = data.GlitchesSinceEngineStarted; - pPerfData->ActiveSourceVoiceCount = data.ActiveSourceVoiceCount; - pPerfData->TotalSourceVoiceCount = data.TotalSourceVoiceCount; +static void WINAPI XA23SUB_GetChannelVolumes(IXAudio23SubmixVoice *iface, + UINT32 Channels, float *pVolumes) +{ + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_GetChannelVolumes(&This->IXAudio2SubmixVoice_iface, + Channels, pVolumes); +} - pPerfData->ActiveSubmixVoiceCount = data.ActiveSubmixVoiceCount; - pPerfData->TotalSubmixVoiceCount = data.ActiveSubmixVoiceCount; +static HRESULT WINAPI XA23SUB_SetOutputMatrix(IXAudio23SubmixVoice *iface, + IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels, + UINT32 DestinationChannels, const float *pLevelMatrix, + UINT32 OperationSet) +{ + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_SetOutputMatrix(&This->IXAudio2SubmixVoice_iface, + pDestinationVoice, SubmixChannels, DestinationChannels, + pLevelMatrix, OperationSet); +} - pPerfData->ActiveXmaSourceVoices = data.ActiveXmaSourceVoices; - pPerfData->ActiveXmaStreams = data.ActiveXmaStreams; +static void WINAPI XA23SUB_GetOutputMatrix(IXAudio23SubmixVoice *iface, + IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels, + UINT32 DestinationChannels, float *pLevelMatrix) +{ + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_GetOutputMatrix(&This->IXAudio2SubmixVoice_iface, + pDestinationVoice, SubmixChannels, DestinationChannels, + pLevelMatrix); } -static void WINAPI XA22_SetDebugConfiguration(IXAudio22 *iface, - const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration, - void *pReserved) +static void WINAPI XA23SUB_DestroyVoice(IXAudio23SubmixVoice *iface) { - IXAudio2Impl *This = impl_from_IXAudio22(iface); - return IXAudio2_SetDebugConfiguration(&This->IXAudio2_iface, - pDebugConfiguration, pReserved); + XA2SubmixImpl *This = impl_from_IXAudio23SubmixVoice(iface); + return IXAudio2SubmixVoice_DestroyVoice(&This->IXAudio2SubmixVoice_iface); } -const IXAudio22Vtbl XAudio22_Vtbl = { - XA22_QueryInterface, - XA22_AddRef, - XA22_Release, - XA22_GetDeviceCount, - XA22_GetDeviceDetails, - XA22_Initialize, - XA22_RegisterForCallbacks, - XA22_UnregisterForCallbacks, - XA22_CreateSourceVoice, - XA22_CreateSubmixVoice, - XA22_CreateMasteringVoice, - XA22_StartEngine, - XA22_StopEngine, - XA22_CommitChanges, - XA22_GetPerformanceData, - XA22_SetDebugConfiguration +const IXAudio23SubmixVoiceVtbl XAudio23SubmixVoice_Vtbl = { + XA23SUB_GetVoiceDetails, + XA23SUB_SetOutputVoices, + XA23SUB_SetEffectChain, + XA23SUB_EnableEffect, + XA23SUB_DisableEffect, + XA23SUB_GetEffectState, + XA23SUB_SetEffectParameters, + XA23SUB_GetEffectParameters, + XA23SUB_SetFilterParameters, + XA23SUB_GetFilterParameters, + XA23SUB_SetVolume, + XA23SUB_GetVolume, + XA23SUB_SetChannelVolumes, + XA23SUB_GetChannelVolumes, + XA23SUB_SetOutputMatrix, + XA23SUB_GetOutputMatrix, + XA23SUB_DestroyVoice }; +#endif +/* END IXAudio2SubmixVoice */ -static XA2SourceImpl *impl_from_IXAudio20SourceVoice(IXAudio20SourceVoice *iface) + +/* BEGIN IXAudio2MasteringVoice */ +#if XAUDIO2_VER == 0 +static IXAudio2Impl *impl_from_IXAudio20MasteringVoice(IXAudio20MasteringVoice *iface) { - return CONTAINING_RECORD(iface, XA2SourceImpl, IXAudio20SourceVoice_iface); + return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio20MasteringVoice_iface); } -static void WINAPI XA20SRC_GetVoiceDetails(IXAudio20SourceVoice *iface, +static void WINAPI XA20M_GetVoiceDetails(IXAudio20MasteringVoice *iface, XAUDIO2_VOICE_DETAILS *pVoiceDetails) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_GetVoiceDetails(&This->IXAudio2SourceVoice_iface, pVoiceDetails); + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_GetVoiceDetails(&This->IXAudio2MasteringVoice_iface, pVoiceDetails); } -static HRESULT WINAPI XA20SRC_SetOutputVoices(IXAudio20SourceVoice *iface, +static HRESULT WINAPI XA20M_SetOutputVoices(IXAudio20MasteringVoice *iface, const XAUDIO23_VOICE_SENDS *pSendList) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); XAUDIO2_VOICE_SENDS sends; HRESULT hr; DWORD i; @@ -1465,610 +1256,875 @@ sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i]; } - hr = IXAudio2SourceVoice_SetOutputVoices(&This->IXAudio2SourceVoice_iface, &sends); + hr = IXAudio2MasteringVoice_SetOutputVoices(&This->IXAudio2MasteringVoice_iface, &sends); HeapFree(GetProcessHeap(), 0, sends.pSends); return hr; } -static HRESULT WINAPI XA20SRC_SetEffectChain(IXAudio20SourceVoice *iface, +static HRESULT WINAPI XA20M_SetEffectChain(IXAudio20MasteringVoice *iface, const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_SetEffectChain(&This->IXAudio2SourceVoice_iface, pEffectChain); + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_SetEffectChain(&This->IXAudio2MasteringVoice_iface, pEffectChain); } -static HRESULT WINAPI XA20SRC_EnableEffect(IXAudio20SourceVoice *iface, +static HRESULT WINAPI XA20M_EnableEffect(IXAudio20MasteringVoice *iface, UINT32 EffectIndex, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_EnableEffect(&This->IXAudio2SourceVoice_iface, + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_EnableEffect(&This->IXAudio2MasteringVoice_iface, EffectIndex, OperationSet); } -static HRESULT WINAPI XA20SRC_DisableEffect(IXAudio20SourceVoice *iface, +static HRESULT WINAPI XA20M_DisableEffect(IXAudio20MasteringVoice *iface, UINT32 EffectIndex, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_DisableEffect(&This->IXAudio2SourceVoice_iface, + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_DisableEffect(&This->IXAudio2MasteringVoice_iface, EffectIndex, OperationSet); } -static void WINAPI XA20SRC_GetEffectState(IXAudio20SourceVoice *iface, +static void WINAPI XA20M_GetEffectState(IXAudio20MasteringVoice *iface, UINT32 EffectIndex, BOOL *pEnabled) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_GetEffectState(&This->IXAudio2SourceVoice_iface, + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_GetEffectState(&This->IXAudio2MasteringVoice_iface, EffectIndex, pEnabled); } -static HRESULT WINAPI XA20SRC_SetEffectParameters(IXAudio20SourceVoice *iface, +static HRESULT WINAPI XA20M_SetEffectParameters(IXAudio20MasteringVoice *iface, UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_SetEffectParameters(&This->IXAudio2SourceVoice_iface, + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_SetEffectParameters(&This->IXAudio2MasteringVoice_iface, EffectIndex, pParameters, ParametersByteSize, OperationSet); } -static HRESULT WINAPI XA20SRC_GetEffectParameters(IXAudio20SourceVoice *iface, +static HRESULT WINAPI XA20M_GetEffectParameters(IXAudio20MasteringVoice *iface, UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_GetEffectParameters(&This->IXAudio2SourceVoice_iface, + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_GetEffectParameters(&This->IXAudio2MasteringVoice_iface, EffectIndex, pParameters, ParametersByteSize); } -static HRESULT WINAPI XA20SRC_SetFilterParameters(IXAudio20SourceVoice *iface, +static HRESULT WINAPI XA20M_SetFilterParameters(IXAudio20MasteringVoice *iface, const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_SetFilterParameters(&This->IXAudio2SourceVoice_iface, + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_SetFilterParameters(&This->IXAudio2MasteringVoice_iface, pParameters, OperationSet); } -static void WINAPI XA20SRC_GetFilterParameters(IXAudio20SourceVoice *iface, +static void WINAPI XA20M_GetFilterParameters(IXAudio20MasteringVoice *iface, XAUDIO2_FILTER_PARAMETERS *pParameters) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_GetFilterParameters(&This->IXAudio2SourceVoice_iface, pParameters); + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_GetFilterParameters(&This->IXAudio2MasteringVoice_iface, pParameters); } -static HRESULT WINAPI XA20SRC_SetVolume(IXAudio20SourceVoice *iface, +static HRESULT WINAPI XA20M_SetVolume(IXAudio20MasteringVoice *iface, float Volume, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_SetVolume(&This->IXAudio2SourceVoice_iface, + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_SetVolume(&This->IXAudio2MasteringVoice_iface, Volume, OperationSet); } -static void WINAPI XA20SRC_GetVolume(IXAudio20SourceVoice *iface, +static void WINAPI XA20M_GetVolume(IXAudio20MasteringVoice *iface, float *pVolume) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_GetVolume(&This->IXAudio2SourceVoice_iface, pVolume); + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_GetVolume(&This->IXAudio2MasteringVoice_iface, pVolume); } -static HRESULT WINAPI XA20SRC_SetChannelVolumes(IXAudio20SourceVoice *iface, +static HRESULT WINAPI XA20M_SetChannelVolumes(IXAudio20MasteringVoice *iface, UINT32 Channels, const float *pVolumes, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_SetChannelVolumes(&This->IXAudio2SourceVoice_iface, + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_SetChannelVolumes(&This->IXAudio2MasteringVoice_iface, Channels, pVolumes, OperationSet); } -static void WINAPI XA20SRC_GetChannelVolumes(IXAudio20SourceVoice *iface, +static void WINAPI XA20M_GetChannelVolumes(IXAudio20MasteringVoice *iface, UINT32 Channels, float *pVolumes) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_GetChannelVolumes(&This->IXAudio2SourceVoice_iface, + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_GetChannelVolumes(&This->IXAudio2MasteringVoice_iface, Channels, pVolumes); } -static HRESULT WINAPI XA20SRC_SetOutputMatrix(IXAudio20SourceVoice *iface, - IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels, +static HRESULT WINAPI XA20M_SetOutputMatrix(IXAudio20MasteringVoice *iface, + IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels, UINT32 DestinationChannels, const float *pLevelMatrix, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_SetOutputMatrix(&This->IXAudio2SourceVoice_iface, - pDestinationVoice, SourceChannels, DestinationChannels, + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_SetOutputMatrix(&This->IXAudio2MasteringVoice_iface, + pDestinationVoice, MasteringChannels, DestinationChannels, pLevelMatrix, OperationSet); } -static HRESULT WINAPI XA20SRC_GetOutputMatrix(IXAudio20SourceVoice *iface, - IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels, +static HRESULT WINAPI XA20M_GetOutputMatrix(IXAudio20MasteringVoice *iface, + IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels, UINT32 DestinationChannels, float *pLevelMatrix) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - IXAudio2SourceVoice_GetOutputMatrix(&This->IXAudio2SourceVoice_iface, - pDestinationVoice, SourceChannels, DestinationChannels, + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + IXAudio2MasteringVoice_GetOutputMatrix(&This->IXAudio2MasteringVoice_iface, + pDestinationVoice, MasteringChannels, DestinationChannels, pLevelMatrix); return S_OK; } -static void WINAPI XA20SRC_DestroyVoice(IXAudio20SourceVoice *iface) +static void WINAPI XA20M_DestroyVoice(IXAudio20MasteringVoice *iface) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_DestroyVoice(&This->IXAudio2SourceVoice_iface); + IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); + return IXAudio2MasteringVoice_DestroyVoice(&This->IXAudio2MasteringVoice_iface); } -static HRESULT WINAPI XA20SRC_Start(IXAudio20SourceVoice *iface, UINT32 Flags, - UINT32 OperationSet) +const IXAudio20MasteringVoiceVtbl XAudio20MasteringVoice_Vtbl = { + XA20M_GetVoiceDetails, + XA20M_SetOutputVoices, + XA20M_SetEffectChain, + XA20M_EnableEffect, + XA20M_DisableEffect, + XA20M_GetEffectState, + XA20M_SetEffectParameters, + XA20M_GetEffectParameters, + XA20M_SetFilterParameters, + XA20M_GetFilterParameters, + XA20M_SetVolume, + XA20M_GetVolume, + XA20M_SetChannelVolumes, + XA20M_GetChannelVolumes, + XA20M_SetOutputMatrix, + XA20M_GetOutputMatrix, + XA20M_DestroyVoice +}; + +#elif XAUDIO2_VER <= 3 + +static IXAudio2Impl *impl_from_IXAudio23MasteringVoice(IXAudio23MasteringVoice *iface) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_Start(&This->IXAudio2SourceVoice_iface, Flags, OperationSet); + return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio23MasteringVoice_iface); } -static HRESULT WINAPI XA20SRC_Stop(IXAudio20SourceVoice *iface, UINT32 Flags, - UINT32 OperationSet) +static void WINAPI XA23M_GetVoiceDetails(IXAudio23MasteringVoice *iface, + XAUDIO2_VOICE_DETAILS *pVoiceDetails) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_Stop(&This->IXAudio2SourceVoice_iface, Flags, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_GetVoiceDetails(&This->IXAudio2MasteringVoice_iface, pVoiceDetails); } -static HRESULT WINAPI XA20SRC_SubmitSourceBuffer(IXAudio20SourceVoice *iface, - const XAUDIO2_BUFFER *pBuffer, const XAUDIO2_BUFFER_WMA *pBufferWMA) +static HRESULT WINAPI XA23M_SetOutputVoices(IXAudio23MasteringVoice *iface, + const XAUDIO23_VOICE_SENDS *pSendList) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_SubmitSourceBuffer(&This->IXAudio2SourceVoice_iface, - pBuffer, pBufferWMA); + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + XAUDIO2_VOICE_SENDS sends; + HRESULT hr; + DWORD i; + + TRACE("%p, %p\n", This, pSendList); + + sends.SendCount = pSendList->OutputCount; + sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends)); + for(i = 0; i < sends.SendCount; ++i){ + sends.pSends[i].Flags = 0; + sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i]; + } + + hr = IXAudio2MasteringVoice_SetOutputVoices(&This->IXAudio2MasteringVoice_iface, &sends); + + HeapFree(GetProcessHeap(), 0, sends.pSends); + + return hr; } -static HRESULT WINAPI XA20SRC_FlushSourceBuffers(IXAudio20SourceVoice *iface) +static HRESULT WINAPI XA23M_SetEffectChain(IXAudio23MasteringVoice *iface, + const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_FlushSourceBuffers(&This->IXAudio2SourceVoice_iface); + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_SetEffectChain(&This->IXAudio2MasteringVoice_iface, pEffectChain); } -static HRESULT WINAPI XA20SRC_Discontinuity(IXAudio20SourceVoice *iface) +static HRESULT WINAPI XA23M_EnableEffect(IXAudio23MasteringVoice *iface, + UINT32 EffectIndex, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_Discontinuity(&This->IXAudio2SourceVoice_iface); + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_EnableEffect(&This->IXAudio2MasteringVoice_iface, + EffectIndex, OperationSet); } -static HRESULT WINAPI XA20SRC_ExitLoop(IXAudio20SourceVoice *iface, - UINT32 OperationSet) +static HRESULT WINAPI XA23M_DisableEffect(IXAudio23MasteringVoice *iface, + UINT32 EffectIndex, UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_ExitLoop(&This->IXAudio2SourceVoice_iface, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_DisableEffect(&This->IXAudio2MasteringVoice_iface, + EffectIndex, OperationSet); } -static void WINAPI XA20SRC_GetState(IXAudio20SourceVoice *iface, - XAUDIO2_VOICE_STATE *pVoiceState) +static void WINAPI XA23M_GetEffectState(IXAudio23MasteringVoice *iface, + UINT32 EffectIndex, BOOL *pEnabled) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_GetState(&This->IXAudio2SourceVoice_iface, pVoiceState, 0); + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_GetEffectState(&This->IXAudio2MasteringVoice_iface, + EffectIndex, pEnabled); } -static HRESULT WINAPI XA20SRC_SetFrequencyRatio(IXAudio20SourceVoice *iface, - float Ratio, UINT32 OperationSet) +static HRESULT WINAPI XA23M_SetEffectParameters(IXAudio23MasteringVoice *iface, + UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize, + UINT32 OperationSet) { - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_SetFrequencyRatio(&This->IXAudio2SourceVoice_iface, - Ratio, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_SetEffectParameters(&This->IXAudio2MasteringVoice_iface, + EffectIndex, pParameters, ParametersByteSize, OperationSet); } -static void WINAPI XA20SRC_GetFrequencyRatio(IXAudio20SourceVoice *iface, - float *pRatio) -{ - XA2SourceImpl *This = impl_from_IXAudio20SourceVoice(iface); - return IXAudio2SourceVoice_GetFrequencyRatio(&This->IXAudio2SourceVoice_iface, pRatio); +static HRESULT WINAPI XA23M_GetEffectParameters(IXAudio23MasteringVoice *iface, + UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize) +{ + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_GetEffectParameters(&This->IXAudio2MasteringVoice_iface, + EffectIndex, pParameters, ParametersByteSize); } -const IXAudio20SourceVoiceVtbl XAudio20SourceVoice_Vtbl = { - XA20SRC_GetVoiceDetails, - XA20SRC_SetOutputVoices, - XA20SRC_SetEffectChain, - XA20SRC_EnableEffect, - XA20SRC_DisableEffect, - XA20SRC_GetEffectState, - XA20SRC_SetEffectParameters, - XA20SRC_GetEffectParameters, - XA20SRC_SetFilterParameters, - XA20SRC_GetFilterParameters, - XA20SRC_SetVolume, - XA20SRC_GetVolume, - XA20SRC_SetChannelVolumes, - XA20SRC_GetChannelVolumes, - XA20SRC_SetOutputMatrix, - XA20SRC_GetOutputMatrix, - XA20SRC_DestroyVoice, - XA20SRC_Start, - XA20SRC_Stop, - XA20SRC_SubmitSourceBuffer, - XA20SRC_FlushSourceBuffers, - XA20SRC_Discontinuity, - XA20SRC_ExitLoop, - XA20SRC_GetState, - XA20SRC_SetFrequencyRatio, - XA20SRC_GetFrequencyRatio, +static HRESULT WINAPI XA23M_SetFilterParameters(IXAudio23MasteringVoice *iface, + const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet) +{ + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_SetFilterParameters(&This->IXAudio2MasteringVoice_iface, + pParameters, OperationSet); +} + +static void WINAPI XA23M_GetFilterParameters(IXAudio23MasteringVoice *iface, + XAUDIO2_FILTER_PARAMETERS *pParameters) +{ + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_GetFilterParameters(&This->IXAudio2MasteringVoice_iface, pParameters); +} + +static HRESULT WINAPI XA23M_SetVolume(IXAudio23MasteringVoice *iface, + float Volume, UINT32 OperationSet) +{ + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_SetVolume(&This->IXAudio2MasteringVoice_iface, + Volume, OperationSet); +} + +static void WINAPI XA23M_GetVolume(IXAudio23MasteringVoice *iface, + float *pVolume) +{ + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_GetVolume(&This->IXAudio2MasteringVoice_iface, pVolume); +} + +static HRESULT WINAPI XA23M_SetChannelVolumes(IXAudio23MasteringVoice *iface, + UINT32 Channels, const float *pVolumes, UINT32 OperationSet) +{ + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_SetChannelVolumes(&This->IXAudio2MasteringVoice_iface, + Channels, pVolumes, OperationSet); +} + +static void WINAPI XA23M_GetChannelVolumes(IXAudio23MasteringVoice *iface, + UINT32 Channels, float *pVolumes) +{ + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_GetChannelVolumes(&This->IXAudio2MasteringVoice_iface, + Channels, pVolumes); +} + +static HRESULT WINAPI XA23M_SetOutputMatrix(IXAudio23MasteringVoice *iface, + IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels, + UINT32 DestinationChannels, const float *pLevelMatrix, + UINT32 OperationSet) +{ + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_SetOutputMatrix(&This->IXAudio2MasteringVoice_iface, + pDestinationVoice, MasteringChannels, DestinationChannels, + pLevelMatrix, OperationSet); +} + +static void WINAPI XA23M_GetOutputMatrix(IXAudio23MasteringVoice *iface, + IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels, + UINT32 DestinationChannels, float *pLevelMatrix) +{ + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_GetOutputMatrix(&This->IXAudio2MasteringVoice_iface, + pDestinationVoice, MasteringChannels, DestinationChannels, + pLevelMatrix); +} + +static void WINAPI XA23M_DestroyVoice(IXAudio23MasteringVoice *iface) +{ + IXAudio2Impl *This = impl_from_IXAudio23MasteringVoice(iface); + return IXAudio2MasteringVoice_DestroyVoice(&This->IXAudio2MasteringVoice_iface); +} + +const IXAudio23MasteringVoiceVtbl XAudio23MasteringVoice_Vtbl = { + XA23M_GetVoiceDetails, + XA23M_SetOutputVoices, + XA23M_SetEffectChain, + XA23M_EnableEffect, + XA23M_DisableEffect, + XA23M_GetEffectState, + XA23M_SetEffectParameters, + XA23M_GetEffectParameters, + XA23M_SetFilterParameters, + XA23M_GetFilterParameters, + XA23M_SetVolume, + XA23M_GetVolume, + XA23M_SetChannelVolumes, + XA23M_GetChannelVolumes, + XA23M_SetOutputMatrix, + XA23M_GetOutputMatrix, + XA23M_DestroyVoice }; +#endif +/* END IXAudio2MasteringVoice */ -static XA2SubmixImpl *impl_from_IXAudio20SubmixVoice(IXAudio20SubmixVoice *iface) + +/* BEGIN IXAudio2 */ +#if XAUDIO2_VER == 0 +static inline IXAudio2Impl *impl_from_IXAudio20(IXAudio20 *iface) { - return CONTAINING_RECORD(iface, XA2SubmixImpl, IXAudio20SubmixVoice_iface); + return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio20_iface); } -static void WINAPI XA20SUB_GetVoiceDetails(IXAudio20SubmixVoice *iface, - XAUDIO2_VOICE_DETAILS *pVoiceDetails) +static HRESULT WINAPI XA20_QueryInterface(IXAudio20 *iface, REFIID riid, + void **ppvObject) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_GetVoiceDetails(&This->IXAudio2SubmixVoice_iface, pVoiceDetails); + IXAudio2Impl *This = impl_from_IXAudio20(iface); + return IXAudio2_QueryInterface(&This->IXAudio2_iface, riid, ppvObject); } -static HRESULT WINAPI XA20SUB_SetOutputVoices(IXAudio20SubmixVoice *iface, - const XAUDIO23_VOICE_SENDS *pSendList) +static ULONG WINAPI XA20_AddRef(IXAudio20 *iface) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - XAUDIO2_VOICE_SENDS sends; + IXAudio2Impl *This = impl_from_IXAudio20(iface); + return IXAudio2_AddRef(&This->IXAudio2_iface); +} + +static ULONG WINAPI XA20_Release(IXAudio20 *iface) +{ + IXAudio2Impl *This = impl_from_IXAudio20(iface); + return IXAudio2_Release(&This->IXAudio2_iface); +} + +static HRESULT WINAPI XA20_GetDeviceCount(IXAudio20 *iface, UINT32 *pCount) +{ + IXAudio2Impl *This = impl_from_IXAudio20(iface); + + TRACE("%p, %p\n", This, pCount); + + *pCount = This->ndevs; + + return S_OK; +} + +static HRESULT WINAPI XA20_GetDeviceDetails(IXAudio20 *iface, UINT32 index, + XAUDIO2_DEVICE_DETAILS *pDeviceDetails) +{ + IXAudio2Impl *This = impl_from_IXAudio20(iface); HRESULT hr; - DWORD i; + IMMDevice *dev; + IAudioClient *client; + IPropertyStore *ps; + WAVEFORMATEX *wfx; + PROPVARIANT var; - TRACE("%p, %p\n", This, pSendList); + TRACE("%p, %u, %p\n", This, index, pDeviceDetails); - sends.SendCount = pSendList->OutputCount; - sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends)); - for(i = 0; i < sends.SendCount; ++i){ - sends.pSends[i].Flags = 0; - sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i]; + if(index >= This->ndevs) + return E_INVALIDARG; + + hr = IMMDeviceEnumerator_GetDevice(This->devenum, This->devids[index], &dev); + if(FAILED(hr)){ + WARN("GetDevice failed: %08x\n", hr); + return hr; } - hr = IXAudio2SubmixVoice_SetOutputVoices(&This->IXAudio2SubmixVoice_iface, &sends); + hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, + NULL, (void**)&client); + if(FAILED(hr)){ + WARN("Activate failed: %08x\n", hr); + IMMDevice_Release(dev); + return hr; + } - HeapFree(GetProcessHeap(), 0, sends.pSends); + hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, &ps); + if(FAILED(hr)){ + WARN("OpenPropertyStore failed: %08x\n", hr); + IAudioClient_Release(client); + IMMDevice_Release(dev); + return hr; + } + + PropVariantInit(&var); + + hr = IPropertyStore_GetValue(ps, (PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &var); + if(FAILED(hr)){ + WARN("GetValue failed: %08x\n", hr); + goto done; + } + + lstrcpynW(pDeviceDetails->DisplayName, var.u.pwszVal, sizeof(pDeviceDetails->DisplayName)/sizeof(WCHAR)); + + PropVariantClear(&var); + + hr = IAudioClient_GetMixFormat(client, &wfx); + if(FAILED(hr)){ + WARN("GetMixFormat failed: %08x\n", hr); + goto done; + } + + lstrcpyW(pDeviceDetails->DeviceID, This->devids[index]); + + if(index == 0) + pDeviceDetails->Role = GlobalDefaultDevice; + else + pDeviceDetails->Role = NotDefaultDevice; + + if(sizeof(WAVEFORMATEX) + wfx->cbSize > sizeof(pDeviceDetails->OutputFormat)){ + FIXME("AudioClient format is too large to fit into WAVEFORMATEXTENSIBLE!\n"); + CoTaskMemFree(wfx); + hr = E_FAIL; + goto done; + } + memcpy(&pDeviceDetails->OutputFormat, wfx, sizeof(WAVEFORMATEX) + wfx->cbSize); + + CoTaskMemFree(wfx); + +done: + IPropertyStore_Release(ps); + IAudioClient_Release(client); + IMMDevice_Release(dev); return hr; } -static HRESULT WINAPI XA20SUB_SetEffectChain(IXAudio20SubmixVoice *iface, +static HRESULT WINAPI XA20_Initialize(IXAudio20 *iface, UINT32 flags, + XAUDIO2_PROCESSOR processor) +{ + IXAudio2Impl *This = impl_from_IXAudio20(iface); + TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor); + return xaudio2_initialize(This, flags, processor); +} + +static HRESULT WINAPI XA20_RegisterForCallbacks(IXAudio20 *iface, + IXAudio2EngineCallback *pCallback) +{ + IXAudio2Impl *This = impl_from_IXAudio20(iface); + return IXAudio2_RegisterForCallbacks(&This->IXAudio2_iface, pCallback); +} + +static void WINAPI XA20_UnregisterForCallbacks(IXAudio20 *iface, + IXAudio2EngineCallback *pCallback) +{ + IXAudio2Impl *This = impl_from_IXAudio20(iface); + return IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback); +} + +static HRESULT WINAPI XA20_CreateSourceVoice(IXAudio20 *iface, + IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat, + UINT32 flags, float maxFrequencyRatio, + IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList, const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_SetEffectChain(&This->IXAudio2SubmixVoice_iface, pEffectChain); + IXAudio2Impl *This = impl_from_IXAudio20(iface); + return IXAudio2_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice, + pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList, + pEffectChain); } -static HRESULT WINAPI XA20SUB_EnableEffect(IXAudio20SubmixVoice *iface, - UINT32 EffectIndex, UINT32 OperationSet) +static HRESULT WINAPI XA20_CreateSubmixVoice(IXAudio20 *iface, + IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels, + UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage, + const XAUDIO2_VOICE_SENDS *pSendList, + const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_EnableEffect(&This->IXAudio2SubmixVoice_iface, - EffectIndex, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio20(iface); + return IXAudio2_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice, + inputChannels, inputSampleRate, flags, processingStage, pSendList, + pEffectChain); } -static HRESULT WINAPI XA20SUB_DisableEffect(IXAudio20SubmixVoice *iface, - UINT32 EffectIndex, UINT32 OperationSet) +static HRESULT WINAPI XA20_CreateMasteringVoice(IXAudio20 *iface, + IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels, + UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex, + const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_DisableEffect(&This->IXAudio2SubmixVoice_iface, - EffectIndex, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio20(iface); + + TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p)\n", This, ppMasteringVoice, + inputChannels, inputSampleRate, flags, deviceIndex, + pEffectChain); + + if(deviceIndex >= This->ndevs) + return E_INVALIDARG; + + return IXAudio2_CreateMasteringVoice(&This->IXAudio2_iface, ppMasteringVoice, + inputChannels, inputSampleRate, flags, This->devids[deviceIndex], + pEffectChain, AudioCategory_GameEffects); } -static void WINAPI XA20SUB_GetEffectState(IXAudio20SubmixVoice *iface, - UINT32 EffectIndex, BOOL *pEnabled) +static HRESULT WINAPI XA20_StartEngine(IXAudio20 *iface) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_GetEffectState(&This->IXAudio2SubmixVoice_iface, - EffectIndex, pEnabled); + IXAudio2Impl *This = impl_from_IXAudio20(iface); + return IXAudio2_StartEngine(&This->IXAudio2_iface); } -static HRESULT WINAPI XA20SUB_SetEffectParameters(IXAudio20SubmixVoice *iface, - UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize, - UINT32 OperationSet) +static void WINAPI XA20_StopEngine(IXAudio20 *iface) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_SetEffectParameters(&This->IXAudio2SubmixVoice_iface, - EffectIndex, pParameters, ParametersByteSize, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio20(iface); + return IXAudio2_StopEngine(&This->IXAudio2_iface); } -static HRESULT WINAPI XA20SUB_GetEffectParameters(IXAudio20SubmixVoice *iface, - UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize) +static HRESULT WINAPI XA20_CommitChanges(IXAudio20 *iface, UINT32 operationSet) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_GetEffectParameters(&This->IXAudio2SubmixVoice_iface, - EffectIndex, pParameters, ParametersByteSize); + IXAudio2Impl *This = impl_from_IXAudio20(iface); + return IXAudio2_CommitChanges(&This->IXAudio2_iface, operationSet); } -static HRESULT WINAPI XA20SUB_SetFilterParameters(IXAudio20SubmixVoice *iface, - const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet) -{ - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_SetFilterParameters(&This->IXAudio2SubmixVoice_iface, - pParameters, OperationSet); -} +static void WINAPI XA20_GetPerformanceData(IXAudio20 *iface, + XAUDIO20_PERFORMANCE_DATA *pPerfData) +{ + IXAudio2Impl *This = impl_from_IXAudio20(iface); + XAUDIO2_PERFORMANCE_DATA data; + + IXAudio2_GetPerformanceData(&This->IXAudio2_iface, &data); + + pPerfData->AudioCyclesSinceLastQuery = data.AudioCyclesSinceLastQuery; + pPerfData->TotalCyclesSinceLastQuery = data.TotalCyclesSinceLastQuery; + pPerfData->MinimumCyclesPerQuantum = data.MinimumCyclesPerQuantum; + pPerfData->MaximumCyclesPerQuantum = data.MaximumCyclesPerQuantum; + pPerfData->MemoryUsageInBytes = data.MemoryUsageInBytes; + pPerfData->CurrentLatencyInSamples = data.CurrentLatencyInSamples; + pPerfData->GlitchesSinceLastQuery = data.GlitchesSinceEngineStarted - This->last_query_glitches; + This->last_query_glitches = data.GlitchesSinceEngineStarted; + pPerfData->ActiveSourceVoiceCount = data.ActiveSourceVoiceCount; + pPerfData->TotalSourceVoiceCount = data.TotalSourceVoiceCount; + + pPerfData->ActiveSubmixVoiceCount = data.ActiveSubmixVoiceCount; + pPerfData->TotalSubmixVoiceCount = data.ActiveSubmixVoiceCount; + + pPerfData->ActiveXmaSourceVoices = data.ActiveXmaSourceVoices; + pPerfData->ActiveXmaStreams = data.ActiveXmaStreams; +} + +static void WINAPI XA20_SetDebugConfiguration(IXAudio20 *iface, + const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration, + void *pReserved) +{ + IXAudio2Impl *This = impl_from_IXAudio20(iface); + return IXAudio2_SetDebugConfiguration(&This->IXAudio2_iface, + pDebugConfiguration, pReserved); +} + +const IXAudio20Vtbl XAudio20_Vtbl = { + XA20_QueryInterface, + XA20_AddRef, + XA20_Release, + XA20_GetDeviceCount, + XA20_GetDeviceDetails, + XA20_Initialize, + XA20_RegisterForCallbacks, + XA20_UnregisterForCallbacks, + XA20_CreateSourceVoice, + XA20_CreateSubmixVoice, + XA20_CreateMasteringVoice, + XA20_StartEngine, + XA20_StopEngine, + XA20_CommitChanges, + XA20_GetPerformanceData, + XA20_SetDebugConfiguration +}; + +#elif XAUDIO2_VER <= 2 -static void WINAPI XA20SUB_GetFilterParameters(IXAudio20SubmixVoice *iface, - XAUDIO2_FILTER_PARAMETERS *pParameters) +static inline IXAudio2Impl *impl_from_IXAudio22(IXAudio22 *iface) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_GetFilterParameters(&This->IXAudio2SubmixVoice_iface, pParameters); + return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio22_iface); } -static HRESULT WINAPI XA20SUB_SetVolume(IXAudio20SubmixVoice *iface, - float Volume, UINT32 OperationSet) +static HRESULT WINAPI XA22_QueryInterface(IXAudio22 *iface, REFIID riid, + void **ppvObject) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_SetVolume(&This->IXAudio2SubmixVoice_iface, - Volume, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + return IXAudio2_QueryInterface(&This->IXAudio2_iface, riid, ppvObject); } -static void WINAPI XA20SUB_GetVolume(IXAudio20SubmixVoice *iface, - float *pVolume) +static ULONG WINAPI XA22_AddRef(IXAudio22 *iface) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_GetVolume(&This->IXAudio2SubmixVoice_iface, pVolume); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + return IXAudio2_AddRef(&This->IXAudio2_iface); } -static HRESULT WINAPI XA20SUB_SetChannelVolumes(IXAudio20SubmixVoice *iface, - UINT32 Channels, const float *pVolumes, UINT32 OperationSet) +static ULONG WINAPI XA22_Release(IXAudio22 *iface) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_SetChannelVolumes(&This->IXAudio2SubmixVoice_iface, - Channels, pVolumes, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + return IXAudio2_Release(&This->IXAudio2_iface); } -static void WINAPI XA20SUB_GetChannelVolumes(IXAudio20SubmixVoice *iface, - UINT32 Channels, float *pVolumes) +static HRESULT WINAPI XA22_GetDeviceCount(IXAudio22 *iface, UINT32 *pCount) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_GetChannelVolumes(&This->IXAudio2SubmixVoice_iface, - Channels, pVolumes); -} + IXAudio2Impl *This = impl_from_IXAudio22(iface); -static HRESULT WINAPI XA20SUB_SetOutputMatrix(IXAudio20SubmixVoice *iface, - IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels, - UINT32 DestinationChannels, const float *pLevelMatrix, - UINT32 OperationSet) -{ - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_SetOutputMatrix(&This->IXAudio2SubmixVoice_iface, - pDestinationVoice, SubmixChannels, DestinationChannels, - pLevelMatrix, OperationSet); -} + TRACE("%p, %p\n", This, pCount); + + *pCount = This->ndevs; -static HRESULT WINAPI XA20SUB_GetOutputMatrix(IXAudio20SubmixVoice *iface, - IXAudio2Voice *pDestinationVoice, UINT32 SubmixChannels, - UINT32 DestinationChannels, float *pLevelMatrix) -{ - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - IXAudio2SubmixVoice_GetOutputMatrix(&This->IXAudio2SubmixVoice_iface, - pDestinationVoice, SubmixChannels, DestinationChannels, - pLevelMatrix); return S_OK; } -static void WINAPI XA20SUB_DestroyVoice(IXAudio20SubmixVoice *iface) +static HRESULT WINAPI XA22_GetDeviceDetails(IXAudio22 *iface, UINT32 index, + XAUDIO2_DEVICE_DETAILS *pDeviceDetails) { - XA2SubmixImpl *This = impl_from_IXAudio20SubmixVoice(iface); - return IXAudio2SubmixVoice_DestroyVoice(&This->IXAudio2SubmixVoice_iface); -} + IXAudio2Impl *This = impl_from_IXAudio22(iface); + HRESULT hr; + IMMDevice *dev; + IAudioClient *client; + IPropertyStore *ps; + WAVEFORMATEX *wfx; + PROPVARIANT var; -const IXAudio20SubmixVoiceVtbl XAudio20SubmixVoice_Vtbl = { - XA20SUB_GetVoiceDetails, - XA20SUB_SetOutputVoices, - XA20SUB_SetEffectChain, - XA20SUB_EnableEffect, - XA20SUB_DisableEffect, - XA20SUB_GetEffectState, - XA20SUB_SetEffectParameters, - XA20SUB_GetEffectParameters, - XA20SUB_SetFilterParameters, - XA20SUB_GetFilterParameters, - XA20SUB_SetVolume, - XA20SUB_GetVolume, - XA20SUB_SetChannelVolumes, - XA20SUB_GetChannelVolumes, - XA20SUB_SetOutputMatrix, - XA20SUB_GetOutputMatrix, - XA20SUB_DestroyVoice -}; + TRACE("%p, %u, %p\n", This, index, pDeviceDetails); -static IXAudio2Impl *impl_from_IXAudio20MasteringVoice(IXAudio20MasteringVoice *iface) -{ - return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio20MasteringVoice_iface); -} + if(index >= This->ndevs) + return E_INVALIDARG; -static void WINAPI XA20M_GetVoiceDetails(IXAudio20MasteringVoice *iface, - XAUDIO2_VOICE_DETAILS *pVoiceDetails) -{ - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_GetVoiceDetails(&This->IXAudio2MasteringVoice_iface, pVoiceDetails); -} + hr = IMMDeviceEnumerator_GetDevice(This->devenum, This->devids[index], &dev); + if(FAILED(hr)){ + WARN("GetDevice failed: %08x\n", hr); + return hr; + } -static HRESULT WINAPI XA20M_SetOutputVoices(IXAudio20MasteringVoice *iface, - const XAUDIO23_VOICE_SENDS *pSendList) -{ - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - XAUDIO2_VOICE_SENDS sends; - HRESULT hr; - DWORD i; + hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, + NULL, (void**)&client); + if(FAILED(hr)){ + WARN("Activate failed: %08x\n", hr); + IMMDevice_Release(dev); + return hr; + } - TRACE("%p, %p\n", This, pSendList); + hr = IMMDevice_OpenPropertyStore(dev, STGM_READ, &ps); + if(FAILED(hr)){ + WARN("OpenPropertyStore failed: %08x\n", hr); + IAudioClient_Release(client); + IMMDevice_Release(dev); + return hr; + } - sends.SendCount = pSendList->OutputCount; - sends.pSends = HeapAlloc(GetProcessHeap(), 0, sends.SendCount * sizeof(*sends.pSends)); - for(i = 0; i < sends.SendCount; ++i){ - sends.pSends[i].Flags = 0; - sends.pSends[i].pOutputVoice = pSendList->pOutputVoices[i]; + PropVariantInit(&var); + + hr = IPropertyStore_GetValue(ps, (PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &var); + if(FAILED(hr)){ + WARN("GetValue failed: %08x\n", hr); + goto done; } - hr = IXAudio2MasteringVoice_SetOutputVoices(&This->IXAudio2MasteringVoice_iface, &sends); + lstrcpynW(pDeviceDetails->DisplayName, var.u.pwszVal, sizeof(pDeviceDetails->DisplayName)/sizeof(WCHAR)); - HeapFree(GetProcessHeap(), 0, sends.pSends); + PropVariantClear(&var); - return hr; -} + hr = IAudioClient_GetMixFormat(client, &wfx); + if(FAILED(hr)){ + WARN("GetMixFormat failed: %08x\n", hr); + goto done; + } -static HRESULT WINAPI XA20M_SetEffectChain(IXAudio20MasteringVoice *iface, - const XAUDIO2_EFFECT_CHAIN *pEffectChain) -{ - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_SetEffectChain(&This->IXAudio2MasteringVoice_iface, pEffectChain); -} + lstrcpyW(pDeviceDetails->DeviceID, This->devids[index]); -static HRESULT WINAPI XA20M_EnableEffect(IXAudio20MasteringVoice *iface, - UINT32 EffectIndex, UINT32 OperationSet) -{ - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_EnableEffect(&This->IXAudio2MasteringVoice_iface, - EffectIndex, OperationSet); -} + if(index == 0) + pDeviceDetails->Role = GlobalDefaultDevice; + else + pDeviceDetails->Role = NotDefaultDevice; -static HRESULT WINAPI XA20M_DisableEffect(IXAudio20MasteringVoice *iface, - UINT32 EffectIndex, UINT32 OperationSet) -{ - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_DisableEffect(&This->IXAudio2MasteringVoice_iface, - EffectIndex, OperationSet); + if(sizeof(WAVEFORMATEX) + wfx->cbSize > sizeof(pDeviceDetails->OutputFormat)){ + FIXME("AudioClient format is too large to fit into WAVEFORMATEXTENSIBLE!\n"); + CoTaskMemFree(wfx); + hr = E_FAIL; + goto done; + } + memcpy(&pDeviceDetails->OutputFormat, wfx, sizeof(WAVEFORMATEX) + wfx->cbSize); + + CoTaskMemFree(wfx); + +done: + IPropertyStore_Release(ps); + IAudioClient_Release(client); + IMMDevice_Release(dev); + + return hr; } -static void WINAPI XA20M_GetEffectState(IXAudio20MasteringVoice *iface, - UINT32 EffectIndex, BOOL *pEnabled) +static HRESULT WINAPI XA22_Initialize(IXAudio22 *iface, UINT32 flags, + XAUDIO2_PROCESSOR processor) { - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_GetEffectState(&This->IXAudio2MasteringVoice_iface, - EffectIndex, pEnabled); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor); + return xaudio2_initialize(This, flags, processor); } -static HRESULT WINAPI XA20M_SetEffectParameters(IXAudio20MasteringVoice *iface, - UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize, - UINT32 OperationSet) +static HRESULT WINAPI XA22_RegisterForCallbacks(IXAudio22 *iface, + IXAudio2EngineCallback *pCallback) { - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_SetEffectParameters(&This->IXAudio2MasteringVoice_iface, - EffectIndex, pParameters, ParametersByteSize, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + return IXAudio2_RegisterForCallbacks(&This->IXAudio2_iface, pCallback); } -static HRESULT WINAPI XA20M_GetEffectParameters(IXAudio20MasteringVoice *iface, - UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize) +static void WINAPI XA22_UnregisterForCallbacks(IXAudio22 *iface, + IXAudio2EngineCallback *pCallback) { - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_GetEffectParameters(&This->IXAudio2MasteringVoice_iface, - EffectIndex, pParameters, ParametersByteSize); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback); } -static HRESULT WINAPI XA20M_SetFilterParameters(IXAudio20MasteringVoice *iface, - const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet) +static HRESULT WINAPI XA22_CreateSourceVoice(IXAudio22 *iface, + IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat, + UINT32 flags, float maxFrequencyRatio, + IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList, + const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_SetFilterParameters(&This->IXAudio2MasteringVoice_iface, - pParameters, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + return IXAudio2_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice, + pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList, + pEffectChain); } -static void WINAPI XA20M_GetFilterParameters(IXAudio20MasteringVoice *iface, - XAUDIO2_FILTER_PARAMETERS *pParameters) +static HRESULT WINAPI XA22_CreateSubmixVoice(IXAudio22 *iface, + IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels, + UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage, + const XAUDIO2_VOICE_SENDS *pSendList, + const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_GetFilterParameters(&This->IXAudio2MasteringVoice_iface, pParameters); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + return IXAudio2_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice, + inputChannels, inputSampleRate, flags, processingStage, pSendList, + pEffectChain); } -static HRESULT WINAPI XA20M_SetVolume(IXAudio20MasteringVoice *iface, - float Volume, UINT32 OperationSet) +static HRESULT WINAPI XA22_CreateMasteringVoice(IXAudio22 *iface, + IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels, + UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex, + const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_SetVolume(&This->IXAudio2MasteringVoice_iface, - Volume, OperationSet); -} + IXAudio2Impl *This = impl_from_IXAudio22(iface); -static void WINAPI XA20M_GetVolume(IXAudio20MasteringVoice *iface, - float *pVolume) -{ - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_GetVolume(&This->IXAudio2MasteringVoice_iface, pVolume); + TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p)\n", This, ppMasteringVoice, + inputChannels, inputSampleRate, flags, deviceIndex, + pEffectChain); + + if(deviceIndex >= This->ndevs) + return E_INVALIDARG; + + return IXAudio2_CreateMasteringVoice(&This->IXAudio2_iface, ppMasteringVoice, + inputChannels, inputSampleRate, flags, This->devids[deviceIndex], + pEffectChain, AudioCategory_GameEffects); } -static HRESULT WINAPI XA20M_SetChannelVolumes(IXAudio20MasteringVoice *iface, - UINT32 Channels, const float *pVolumes, UINT32 OperationSet) +static HRESULT WINAPI XA22_StartEngine(IXAudio22 *iface) { - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_SetChannelVolumes(&This->IXAudio2MasteringVoice_iface, - Channels, pVolumes, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + return IXAudio2_StartEngine(&This->IXAudio2_iface); } -static void WINAPI XA20M_GetChannelVolumes(IXAudio20MasteringVoice *iface, - UINT32 Channels, float *pVolumes) +static void WINAPI XA22_StopEngine(IXAudio22 *iface) { - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_GetChannelVolumes(&This->IXAudio2MasteringVoice_iface, - Channels, pVolumes); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + return IXAudio2_StopEngine(&This->IXAudio2_iface); } -static HRESULT WINAPI XA20M_SetOutputMatrix(IXAudio20MasteringVoice *iface, - IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels, - UINT32 DestinationChannels, const float *pLevelMatrix, - UINT32 OperationSet) +static HRESULT WINAPI XA22_CommitChanges(IXAudio22 *iface, UINT32 operationSet) { - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_SetOutputMatrix(&This->IXAudio2MasteringVoice_iface, - pDestinationVoice, MasteringChannels, DestinationChannels, - pLevelMatrix, OperationSet); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + return IXAudio2_CommitChanges(&This->IXAudio2_iface, operationSet); } -static HRESULT WINAPI XA20M_GetOutputMatrix(IXAudio20MasteringVoice *iface, - IXAudio2Voice *pDestinationVoice, UINT32 MasteringChannels, - UINT32 DestinationChannels, float *pLevelMatrix) +static void WINAPI XA22_GetPerformanceData(IXAudio22 *iface, + XAUDIO22_PERFORMANCE_DATA *pPerfData) { - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - IXAudio2MasteringVoice_GetOutputMatrix(&This->IXAudio2MasteringVoice_iface, - pDestinationVoice, MasteringChannels, DestinationChannels, - pLevelMatrix); - return S_OK; + IXAudio2Impl *This = impl_from_IXAudio22(iface); + XAUDIO2_PERFORMANCE_DATA data; + + IXAudio2_GetPerformanceData(&This->IXAudio2_iface, &data); + + pPerfData->AudioCyclesSinceLastQuery = data.AudioCyclesSinceLastQuery; + pPerfData->TotalCyclesSinceLastQuery = data.TotalCyclesSinceLastQuery; + pPerfData->MinimumCyclesPerQuantum = data.MinimumCyclesPerQuantum; + pPerfData->MaximumCyclesPerQuantum = data.MaximumCyclesPerQuantum; + pPerfData->MemoryUsageInBytes = data.MemoryUsageInBytes; + pPerfData->CurrentLatencyInSamples = data.CurrentLatencyInSamples; + pPerfData->GlitchesSinceEngineStarted = data.GlitchesSinceEngineStarted; + pPerfData->ActiveSourceVoiceCount = data.ActiveSourceVoiceCount; + pPerfData->TotalSourceVoiceCount = data.TotalSourceVoiceCount; + + pPerfData->ActiveSubmixVoiceCount = data.ActiveSubmixVoiceCount; + pPerfData->TotalSubmixVoiceCount = data.ActiveSubmixVoiceCount; + + pPerfData->ActiveXmaSourceVoices = data.ActiveXmaSourceVoices; + pPerfData->ActiveXmaStreams = data.ActiveXmaStreams; } -static void WINAPI XA20M_DestroyVoice(IXAudio20MasteringVoice *iface) +static void WINAPI XA22_SetDebugConfiguration(IXAudio22 *iface, + const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration, + void *pReserved) { - IXAudio2Impl *This = impl_from_IXAudio20MasteringVoice(iface); - return IXAudio2MasteringVoice_DestroyVoice(&This->IXAudio2MasteringVoice_iface); + IXAudio2Impl *This = impl_from_IXAudio22(iface); + return IXAudio2_SetDebugConfiguration(&This->IXAudio2_iface, + pDebugConfiguration, pReserved); } -const IXAudio20MasteringVoiceVtbl XAudio20MasteringVoice_Vtbl = { - XA20M_GetVoiceDetails, - XA20M_SetOutputVoices, - XA20M_SetEffectChain, - XA20M_EnableEffect, - XA20M_DisableEffect, - XA20M_GetEffectState, - XA20M_SetEffectParameters, - XA20M_GetEffectParameters, - XA20M_SetFilterParameters, - XA20M_GetFilterParameters, - XA20M_SetVolume, - XA20M_GetVolume, - XA20M_SetChannelVolumes, - XA20M_GetChannelVolumes, - XA20M_SetOutputMatrix, - XA20M_GetOutputMatrix, - XA20M_DestroyVoice +const IXAudio22Vtbl XAudio22_Vtbl = { + XA22_QueryInterface, + XA22_AddRef, + XA22_Release, + XA22_GetDeviceCount, + XA22_GetDeviceDetails, + XA22_Initialize, + XA22_RegisterForCallbacks, + XA22_UnregisterForCallbacks, + XA22_CreateSourceVoice, + XA22_CreateSubmixVoice, + XA22_CreateMasteringVoice, + XA22_StartEngine, + XA22_StopEngine, + XA22_CommitChanges, + XA22_GetPerformanceData, + XA22_SetDebugConfiguration }; -static inline IXAudio2Impl *impl_from_IXAudio20(IXAudio20 *iface) +#elif XAUDIO2_VER <= 7 + +static inline IXAudio2Impl *impl_from_IXAudio27(IXAudio27 *iface) { - return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio20_iface); + return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio27_iface); } -static HRESULT WINAPI XA20_QueryInterface(IXAudio20 *iface, REFIID riid, +static HRESULT WINAPI XA27_QueryInterface(IXAudio27 *iface, REFIID riid, void **ppvObject) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); return IXAudio2_QueryInterface(&This->IXAudio2_iface, riid, ppvObject); } -static ULONG WINAPI XA20_AddRef(IXAudio20 *iface) +static ULONG WINAPI XA27_AddRef(IXAudio27 *iface) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); return IXAudio2_AddRef(&This->IXAudio2_iface); } -static ULONG WINAPI XA20_Release(IXAudio20 *iface) +static ULONG WINAPI XA27_Release(IXAudio27 *iface) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); return IXAudio2_Release(&This->IXAudio2_iface); } -static HRESULT WINAPI XA20_GetDeviceCount(IXAudio20 *iface, UINT32 *pCount) +static HRESULT WINAPI XA27_GetDeviceCount(IXAudio27 *iface, UINT32 *pCount) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); TRACE("%p, %p\n", This, pCount); @@ -2077,10 +2133,10 @@ return S_OK; } -static HRESULT WINAPI XA20_GetDeviceDetails(IXAudio20 *iface, UINT32 index, +static HRESULT WINAPI XA27_GetDeviceDetails(IXAudio27 *iface, UINT32 index, XAUDIO2_DEVICE_DETAILS *pDeviceDetails) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); HRESULT hr; IMMDevice *dev; IAudioClient *client; @@ -2158,58 +2214,58 @@ return hr; } -static HRESULT WINAPI XA20_Initialize(IXAudio20 *iface, UINT32 flags, +static HRESULT WINAPI XA27_Initialize(IXAudio27 *iface, UINT32 flags, XAUDIO2_PROCESSOR processor) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor); - return S_OK; + return xaudio2_initialize(This, flags, processor); } -static HRESULT WINAPI XA20_RegisterForCallbacks(IXAudio20 *iface, +static HRESULT WINAPI XA27_RegisterForCallbacks(IXAudio27 *iface, IXAudio2EngineCallback *pCallback) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); return IXAudio2_RegisterForCallbacks(&This->IXAudio2_iface, pCallback); } -static void WINAPI XA20_UnregisterForCallbacks(IXAudio20 *iface, +static void WINAPI XA27_UnregisterForCallbacks(IXAudio27 *iface, IXAudio2EngineCallback *pCallback) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); - return IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback); + IXAudio2Impl *This = impl_from_IXAudio27(iface); + IXAudio2_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback); } -static HRESULT WINAPI XA20_CreateSourceVoice(IXAudio20 *iface, +static HRESULT WINAPI XA27_CreateSourceVoice(IXAudio27 *iface, IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat, UINT32 flags, float maxFrequencyRatio, IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList, const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); return IXAudio2_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice, pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList, pEffectChain); } -static HRESULT WINAPI XA20_CreateSubmixVoice(IXAudio20 *iface, +static HRESULT WINAPI XA27_CreateSubmixVoice(IXAudio27 *iface, IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels, UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage, const XAUDIO2_VOICE_SENDS *pSendList, const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); return IXAudio2_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice, inputChannels, inputSampleRate, flags, processingStage, pSendList, pEffectChain); } -static HRESULT WINAPI XA20_CreateMasteringVoice(IXAudio20 *iface, +static HRESULT WINAPI XA27_CreateMasteringVoice(IXAudio27 *iface, IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels, UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex, const XAUDIO2_EFFECT_CHAIN *pEffectChain) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p)\n", This, ppMasteringVoice, inputChannels, inputSampleRate, flags, deviceIndex, @@ -2223,74 +2279,57 @@ pEffectChain, AudioCategory_GameEffects); } -static HRESULT WINAPI XA20_StartEngine(IXAudio20 *iface) +static HRESULT WINAPI XA27_StartEngine(IXAudio27 *iface) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); return IXAudio2_StartEngine(&This->IXAudio2_iface); } -static void WINAPI XA20_StopEngine(IXAudio20 *iface) +static void WINAPI XA27_StopEngine(IXAudio27 *iface) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); return IXAudio2_StopEngine(&This->IXAudio2_iface); } -static HRESULT WINAPI XA20_CommitChanges(IXAudio20 *iface, UINT32 operationSet) +static HRESULT WINAPI XA27_CommitChanges(IXAudio27 *iface, UINT32 operationSet) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); return IXAudio2_CommitChanges(&This->IXAudio2_iface, operationSet); } -static void WINAPI XA20_GetPerformanceData(IXAudio20 *iface, - XAUDIO20_PERFORMANCE_DATA *pPerfData) +static void WINAPI XA27_GetPerformanceData(IXAudio27 *iface, + XAUDIO2_PERFORMANCE_DATA *pPerfData) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); - XAUDIO2_PERFORMANCE_DATA data; - - IXAudio2_GetPerformanceData(&This->IXAudio2_iface, &data); - - pPerfData->AudioCyclesSinceLastQuery = data.AudioCyclesSinceLastQuery; - pPerfData->TotalCyclesSinceLastQuery = data.TotalCyclesSinceLastQuery; - pPerfData->MinimumCyclesPerQuantum = data.MinimumCyclesPerQuantum; - pPerfData->MaximumCyclesPerQuantum = data.MaximumCyclesPerQuantum; - pPerfData->MemoryUsageInBytes = data.MemoryUsageInBytes; - pPerfData->CurrentLatencyInSamples = data.CurrentLatencyInSamples; - pPerfData->GlitchesSinceLastQuery = data.GlitchesSinceEngineStarted - This->last_query_glitches; - This->last_query_glitches = data.GlitchesSinceEngineStarted; - pPerfData->ActiveSourceVoiceCount = data.ActiveSourceVoiceCount; - pPerfData->TotalSourceVoiceCount = data.TotalSourceVoiceCount; - - pPerfData->ActiveSubmixVoiceCount = data.ActiveSubmixVoiceCount; - pPerfData->TotalSubmixVoiceCount = data.ActiveSubmixVoiceCount; - - pPerfData->ActiveXmaSourceVoices = data.ActiveXmaSourceVoices; - pPerfData->ActiveXmaStreams = data.ActiveXmaStreams; + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2_GetPerformanceData(&This->IXAudio2_iface, pPerfData); } -static void WINAPI XA20_SetDebugConfiguration(IXAudio20 *iface, +static void WINAPI XA27_SetDebugConfiguration(IXAudio27 *iface, const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration, void *pReserved) { - IXAudio2Impl *This = impl_from_IXAudio20(iface); + IXAudio2Impl *This = impl_from_IXAudio27(iface); return IXAudio2_SetDebugConfiguration(&This->IXAudio2_iface, pDebugConfiguration, pReserved); } -const IXAudio20Vtbl XAudio20_Vtbl = { - XA20_QueryInterface, - XA20_AddRef, - XA20_Release, - XA20_GetDeviceCount, - XA20_GetDeviceDetails, - XA20_Initialize, - XA20_RegisterForCallbacks, - XA20_UnregisterForCallbacks, - XA20_CreateSourceVoice, - XA20_CreateSubmixVoice, - XA20_CreateMasteringVoice, - XA20_StartEngine, - XA20_StopEngine, - XA20_CommitChanges, - XA20_GetPerformanceData, - XA20_SetDebugConfiguration +const IXAudio27Vtbl XAudio27_Vtbl = { + XA27_QueryInterface, + XA27_AddRef, + XA27_Release, + XA27_GetDeviceCount, + XA27_GetDeviceDetails, + XA27_Initialize, + XA27_RegisterForCallbacks, + XA27_UnregisterForCallbacks, + XA27_CreateSourceVoice, + XA27_CreateSubmixVoice, + XA27_CreateMasteringVoice, + XA27_StartEngine, + XA27_StopEngine, + XA27_CommitChanges, + XA27_GetPerformanceData, + XA27_SetDebugConfiguration }; +#endif +/* END IXAudio2 */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,9 +1,11 @@ +EXTRADEFS = -DXAUDIO2_VER=7 MODULE = xaudio2_7.dll -IMPORTS = advapi32 kernel32 ole32 user32 uuid +IMPORTS = advapi32 ole32 user32 uuid EXTRALIBS = $(OPENAL_LIBS) C_SRCS = \ compat.c \ + x3daudio.c \ xapofx.c \ xaudio_dll.c diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/tests/xaudio2.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/tests/xaudio2.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/tests/xaudio2.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/tests/xaudio2.c 2016-02-08 19:32:34.000000000 +0000 @@ -249,7 +249,7 @@ if(xaudio27){ IXAPO *xapo; - hr = CoCreateInstance(&CLSID_AudioVolumeMeter, NULL, + hr = CoCreateInstance(&CLSID_AudioVolumeMeter27, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&vumeter); ok(hr == S_OK, "CoCreateInstance(AudioVolumeMeter) failed: %08x\n", hr); @@ -834,7 +834,7 @@ &CLSID_AudioVolumeMeter24, &CLSID_AudioVolumeMeter25, &CLSID_AudioVolumeMeter26, - &CLSID_AudioVolumeMeter + &CLSID_AudioVolumeMeter27 }; static const GUID *ar_clsids[] = { @@ -845,7 +845,7 @@ &CLSID_AudioReverb24, &CLSID_AudioReverb25, &CLSID_AudioReverb26, - &CLSID_AudioReverb + &CLSID_AudioReverb27 }; xapofxdll = LoadLibraryA(module); @@ -973,7 +973,7 @@ } /* test legacy CLSID */ - hr = pCreateFX(&CLSID_AudioVolumeMeter, &fx_unk, NULL, 0); + hr = pCreateFX(&CLSID_AudioVolumeMeter27, &fx_unk, NULL, 0); ok(hr == S_OK, "%s: CreateFX(CLSID_AudioVolumeMeter) failed: %08x\n", module, hr); if(SUCCEEDED(hr)){ IXAPO *xapo; @@ -1060,7 +1060,7 @@ test_xapo_creation(); /* XAudio 2.7 (Jun 2010 DirectX) */ - hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, + hr = CoCreateInstance(&CLSID_XAudio27, NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio27, (void**)&xa27); if(hr == S_OK){ xaudio27 = TRUE; @@ -1087,6 +1087,9 @@ hr = pXAudio2Create(&xa, 0, XAUDIO2_DEFAULT_PROCESSOR); ok(hr == S_OK, "XAudio2Create failed: %08x\n", hr); + hr = IXAudio2_QueryInterface(xa, &IID_IXAudio27, (void**)&xa27); + ok(hr == E_NOINTERFACE, "XA28 object should support IXAudio27, gave: %08x\n", hr); + has_devices = check_has_devices(xa); if(has_devices){ test_simple_streaming(xa); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/x3daudio.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/x3daudio.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/x3daudio.c 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/x3daudio.c 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016 Andrew Eikum for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "xaudio_private.h" +#include "x3daudio.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(xaudio2); + +#ifdef X3DAUDIO1_VER +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, void *pReserved) +{ + TRACE("(%p, %d, %p)\n", hinstDLL, reason, pReserved); + + switch (reason) + { + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls( hinstDLL ); + break; + } + return TRUE; +} +#endif /* X3DAUDIO1_VER */ + +#if XAUDIO2_VER >= 8 +HRESULT CDECL X3DAudioInitialize(UINT32 chanmask, float speedofsound, + X3DAUDIO_HANDLE handle) +{ + FIXME("0x%x, %f, %p: Stub!\n", chanmask, speedofsound, handle); + return S_OK; +} +#endif /* XAUDIO2_VER >= 8 */ + +#ifdef X3DAUDIO1_VER +void CDECL LEGACY_X3DAudioInitialize(UINT32 chanmask, float speedofsound, + X3DAUDIO_HANDLE handle) +{ + FIXME("0x%x, %f, %p: Stub!\n", chanmask, speedofsound, handle); +} +#endif /* X3DAUDIO1_VER */ + +#if XAUDIO2_VER >= 8 || defined X3DAUDIO1_VER +void CDECL X3DAudioCalculate(const X3DAUDIO_HANDLE handle, + const X3DAUDIO_LISTENER *listener, const X3DAUDIO_EMITTER *emitter, + UINT32 flags, X3DAUDIO_DSP_SETTINGS *out) +{ + static int once = 0; + if(!once){ + FIXME("%p %p %p 0x%x %p: Stub!\n", handle, listener, emitter, flags, out); + ++once; + } + + out->LPFDirectCoefficient = 0; + out->LPFReverbCoefficient = 0; + out->ReverbLevel = 0; + out->DopplerFactor = 1; + out->EmitterToListenerAngle = 0; + out->EmitterToListenerDistance = 0; + out->EmitterVelocityComponent = 0; + out->ListenerVelocityComponent = 0; +} +#endif /* XAUDIO2_VER >= 8 || defined X3DAUDIO1_VER */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/xapofx.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/xapofx.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/xapofx.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/xapofx.c 2016-02-08 19:32:34.000000000 +0000 @@ -23,6 +23,7 @@ #define NONAMELESSUNION #define COBJMACROS +#include "initguid.h" #include "xaudio_private.h" #include "xapofx.h" @@ -30,13 +31,28 @@ WINE_DEFAULT_DEBUG_CHANNEL(xaudio2); +#ifdef XAPOFX1_VER +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, void *pReserved) +{ + TRACE("(%p, %d, %p)\n", hinstDLL, reason, pReserved); + + switch (reason) + { + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls( hinstDLL ); + break; + } + return TRUE; +} +#endif /* XAPOFX1_VER */ + typedef struct _VUMeterImpl { IXAPO IXAPO_iface; IXAPOParameters IXAPOParameters_iface; LONG ref; - - DWORD version; } VUMeterImpl; static VUMeterImpl *VUMeterImpl_from_IXAPO(IXAPO *iface) @@ -240,8 +256,6 @@ IXAPOParameters IXAPOParameters_iface; LONG ref; - - DWORD version; } ReverbImpl; static ReverbImpl *ReverbImpl_from_IXAPO(IXAPO *iface) @@ -443,8 +457,6 @@ IXAPOParameters IXAPOParameters_iface; LONG ref; - - DWORD version; } EQImpl; static EQImpl *EQImpl_from_IXAPO(IXAPO *iface) @@ -644,7 +656,6 @@ struct xapo_cf { IClassFactory IClassFactory_iface; LONG ref; - DWORD version; const CLSID *class; }; @@ -699,7 +710,7 @@ if(pOuter) return CLASS_E_NOAGGREGATION; - if(IsEqualGUID(This->class, &CLSID_AudioVolumeMeter)){ + if(IsEqualGUID(This->class, &CLSID_AudioVolumeMeter27)){ VUMeterImpl *object; object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); @@ -708,14 +719,13 @@ object->IXAPO_iface.lpVtbl = &VUMXAPO_Vtbl; object->IXAPOParameters_iface.lpVtbl = &VUMXAPOParameters_Vtbl; - object->version = This->version; hr = IXAPO_QueryInterface(&object->IXAPO_iface, riid, ppobj); if(FAILED(hr)){ HeapFree(GetProcessHeap(), 0, object); return hr; } - }else if(IsEqualGUID(This->class, &CLSID_AudioReverb)){ + }else if(IsEqualGUID(This->class, &CLSID_FXReverb)){ ReverbImpl *object; object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); @@ -724,7 +734,6 @@ object->IXAPO_iface.lpVtbl = &RVBXAPO_Vtbl; object->IXAPOParameters_iface.lpVtbl = &RVBXAPOParameters_Vtbl; - object->version = This->version; hr = IXAPO_QueryInterface(&object->IXAPO_iface, riid, ppobj); if(FAILED(hr)){ @@ -740,7 +749,6 @@ object->IXAPO_iface.lpVtbl = &EQXAPO_Vtbl; object->IXAPOParameters_iface.lpVtbl = &EQXAPOParameters_Vtbl; - object->version = This->version; hr = IXAPO_QueryInterface(&object->IXAPO_iface, riid, ppobj); if(FAILED(hr)){ @@ -748,6 +756,7 @@ return hr; } }else + /* TODO FXECHO, FXMasteringLimiter, */ return E_INVALIDARG; return S_OK; @@ -768,12 +777,135 @@ xapocf_LockServer }; -IClassFactory *make_xapo_factory(REFCLSID clsid, DWORD version) +IClassFactory *make_xapo_factory(REFCLSID clsid) { struct xapo_cf *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct xapo_cf)); ret->IClassFactory_iface.lpVtbl = &xapo_Vtbl; - ret->version = version; ret->class = clsid; ret->ref = 0; return &ret->IClassFactory_iface; } + +#if XAUDIO2_VER >= 8 +HRESULT WINAPI CreateAudioVolumeMeter(IUnknown **out) +{ + IClassFactory *cf; + HRESULT hr; + + cf = make_xapo_factory(&CLSID_AudioVolumeMeter27); + + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)out); + + IClassFactory_Release(cf); + + return hr; +} + +HRESULT WINAPI CreateAudioReverb(IUnknown **out) +{ + IClassFactory *cf; + HRESULT hr; + + cf = make_xapo_factory(&CLSID_FXReverb); + + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)out); + + IClassFactory_Release(cf); + + return hr; +} + +HRESULT CDECL CreateFX(REFCLSID clsid, IUnknown **out, void *initdata, UINT32 initdata_bytes) +{ + HRESULT hr; + IUnknown *obj; + const GUID *class = NULL; + IClassFactory *cf; + + *out = NULL; + + if(IsEqualGUID(clsid, &CLSID_FXReverb27) || + IsEqualGUID(clsid, &CLSID_FXReverb)) + class = &CLSID_FXReverb; + else if(IsEqualGUID(clsid, &CLSID_FXEQ27) || + IsEqualGUID(clsid, &CLSID_FXEQ)) + class = &CLSID_FXEQ; + + if(class){ + cf = make_xapo_factory(class); + + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj); + IClassFactory_Release(cf); + if(FAILED(hr)) + return hr; + }else{ + hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&obj); + if(FAILED(hr)){ + WARN("CoCreateInstance failed: %08x\n", hr); + return hr; + } + } + + if(initdata && initdata_bytes > 0){ + IXAPO *xapo; + + hr = IUnknown_QueryInterface(obj, &IID_IXAPO, (void**)&xapo); + if(SUCCEEDED(hr)){ + hr = IXAPO_Initialize(xapo, initdata, initdata_bytes); + + IXAPO_Release(xapo); + + if(FAILED(hr)){ + WARN("Initialize failed: %08x\n", hr); + IUnknown_Release(obj); + return hr; + } + } + } + + *out = obj; + + return S_OK; +} +#endif /* XAUDIO2_VER >= 8 */ + +#ifdef XAPOFX1_VER +HRESULT CDECL CreateFX(REFCLSID clsid, IUnknown **out) +{ + HRESULT hr; + IUnknown *obj; + const GUID *class = NULL; + IClassFactory *cf; + + TRACE("%s %p\n", debugstr_guid(clsid), out); + + *out = NULL; + + if(IsEqualGUID(clsid, &CLSID_FXReverb27) || + IsEqualGUID(clsid, &CLSID_FXReverb)) + class = &CLSID_FXReverb; + else if(IsEqualGUID(clsid, &CLSID_FXEQ27) || + IsEqualGUID(clsid, &CLSID_FXEQ)) + class = &CLSID_FXEQ; + /* TODO FXECHO, FXMasteringLimiter, */ + + if(class){ + cf = make_xapo_factory(class); + + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj); + IClassFactory_Release(cf); + if(FAILED(hr)) + return hr; + }else{ + hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&obj); + if(FAILED(hr)){ + WARN("CoCreateInstance failed: %08x\n", hr); + return hr; + } + } + + *out = obj; + + return S_OK; +} +#endif /* XAPOFX1_VER */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/xaudio_classes.idl wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/xaudio_classes.idl --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/xaudio_classes.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/xaudio_classes.idl 2016-02-08 19:32:34.000000000 +0000 @@ -20,12 +20,13 @@ #pragma makedep register +#if XAUDIO2_VER == 7 [ helpstring("XAudio2 Class"), threading(both), uuid(5a508685-a254-4fba-9b82-9a24b00306af) ] -coclass XAudio2 { interface IXAudio2; } +coclass XAudio27 { interface IXAudio27; } [ helpstring("XAudio2 Volume Meter Class"), @@ -47,87 +48,165 @@ uuid(962f5027-99be-4692-a468-85802cf8de61) ] coclass XACT31 { interface IUnknown; } +#endif /* XAUDIO2_VER == 7 */ +#if XAUDIO2_VER == 6 [ - helpstring("XAPOFX1.1 FXReverb Class (Wine)"), + helpstring("XAudio2.6 Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF02000101) + uuid(3eda9b49-2085-498b-9bb2-39a6778493de) ] -coclass FXReverb11 { interface IXAPO; } +coclass XAudio26 { interface IXAudio27; } [ - helpstring("XAPOFX1.2 FXReverb Class (Wine)"), + helpstring("XAudio2.6 AudioReverb Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF02000102) + uuid(cecec95a-d894-491a-bee3-5e106fb59f2d) ] -coclass FXReverb12 { interface IXAPO; } +coclass AudioReverb26 { interface IXAPO; } [ - helpstring("XAPOFX1.3 FXReverb Class (Wine)"), + helpstring("XAudio2.6 AudioVolumeMeter Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF02000103) + uuid(e48c5a3f-93ef-43bb-a092-2c7ceb946f27) ] -coclass FXReverb13 { interface IXAPO; } +coclass AudioVolumeMeter26 { interface IXAPO; } +#endif /* XAUDIO2_VER == 6 */ +#if XAUDIO2_VER == 5 [ - helpstring("XAPOFX1.4 FXReverb Class (Wine)"), + helpstring("XAudio2.5 Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF02000104) + uuid(4c9b6dde-6809-46e6-a278-9b6a97588670) ] -coclass FXReverb14 { interface IXAPO; } +coclass XAudio25 { interface IXAudio27; } [ - helpstring("XAPOFX1.5 FXReverb Class (Wine)"), + helpstring("XAudio2.5 AudioReverb Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF02000105) + uuid(d06df0d0-8518-441e-822f-5451d5c595b8) ] -coclass FXReverb15 { interface IXAPO; } +coclass AudioReverb25 { interface IXAPO; } [ - helpstring("XAudio2.8 FXReverb Class (Wine)"), + helpstring("XAudio2.5 AudioVolumeMeter Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF02000208) + uuid(2139e6da-c341-4774-9ac3-b4e026347f64) ] -coclass FXReverb28 { interface IXAPO; } +coclass AudioVolumeMeter25 { interface IXAPO; } +#endif /* XAUDIO2_VER == 5 */ +#if XAUDIO2_VER == 4 [ - helpstring("XAPOFX1.1 FXEQ Class (Wine)"), + helpstring("XAudio2.4 Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF00000101) + uuid(03219e78-5bc3-44d1-b92e-f63d89cc6526) ] -coclass FXEQ11 { interface IXAPO; } +coclass XAudio24 { interface IXAudio27; } [ - helpstring("XAPOFX1.2 FXEQ Class (Wine)"), + helpstring("XAudio2.4 AudioReverb Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF00000102) + uuid(8bb7778b-645b-4475-9a73-1de3170bd3af) ] -coclass FXEQ12 { interface IXAPO; } +coclass AudioReverb24 { interface IXAPO; } [ - helpstring("XAPOFX1.3 FXEQ Class (Wine)"), + helpstring("XAudio2.4 AudioVolumeMeter Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF00000103) + uuid(c7338b95-52b8-4542-aa79-42eb016c8c1c) ] -coclass FXEQ13 { interface IXAPO; } +coclass AudioVolumeMeter24 { interface IXAPO; } +#endif /* XAUDIO2_VER == 4 */ +#if XAUDIO2_VER == 3 [ - helpstring("XAPOFX1.4 FXEQ Class (Wine)"), + helpstring("XAudio2.3 Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF00000104) + uuid(4c5e637a-16c7-4de3-9c46-5ed22181962d) ] -coclass FXEQ14 { interface IXAPO; } +coclass XAudio23 { interface IXAudio27; } [ - helpstring("XAPOFX1.5 FXEQ Class (Wine)"), + helpstring("XAudio2.3 AudioReverb Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF00000105) + uuid(9cab402c-1d37-44b4-886d-fa4f36170a4c) ] -coclass FXEQ15 { interface IXAPO; } +coclass AudioReverb23 { interface IXAPO; } [ - helpstring("XAudio2.8 FXEQ Class (Wine)"), + helpstring("XAudio2.3 AudioVolumeMeter Class"), threading(both), - uuid(a90bc001-e897-e897-7439-43FF00000208) + uuid(e180344b-ac83-4483-959e-18a5c56a5e19) ] -coclass FXEQ28 { interface IXAPO; } +coclass AudioVolumeMeter23 { interface IXAPO; } +#endif /* XAUDIO2_VER == 3 */ + +#if XAUDIO2_VER == 2 +[ + helpstring("XAudio2.2 Class"), + threading(both), + uuid(b802058a-464a-42db-bc10-b650d6f2586a) +] +coclass XAudio22 { interface IXAudio22; } + +[ + helpstring("XAudio2.2 AudioReverb Class"), + threading(both), + uuid(629cf0de-3ecc-41e7-9926-f7e43eebec51) +] +coclass AudioReverb22 { interface IXAPO; } + +[ + helpstring("XAudio2.2 AudioVolumeMeter Class"), + threading(both), + uuid(f5ca7b34-8055-42c0-b836-216129eb7e30) +] +coclass AudioVolumeMeter22 { interface IXAPO; } +#endif /* XAUDIO2_VER == 2 */ + +#if XAUDIO2_VER == 1 +[ + helpstring("XAudio2.1 Class"), + threading(both), + uuid(e21a7345-eb21-468e-be50-804db97cf708) +] +coclass XAudio21 { interface IXAudio22; } + +[ + helpstring("XAudio2.1 AudioReverb Class"), + threading(both), + uuid(f4769300-b949-4df9-b333-00d33932e9a6) +] +coclass AudioReverb21 { interface IXAPO; } + +[ + helpstring("XAudio2.1 AudioVolumeMeter Class"), + threading(both), + uuid(c1e3f122-a2ea-442c-854f-20d98f8357a1) +] +coclass AudioVolumeMeter21 { interface IXAPO; } +#endif /* XAUDIO2_VER == 1 */ + +#if XAUDIO2_VER == 0 +[ + helpstring("XAudio2.0 Class"), + threading(both), + uuid(fac23f48-31f5-45a8-b49b-5225d61401aa) +] +coclass XAudio20 { interface IXAudio20; } + +[ + helpstring("XAudio2.0 AudioReverb Class"), + threading(both), + uuid(6f6ea3a9-2cf5-41cf-91c1-2170b1540063) +] +coclass AudioReverb20 { interface IXAPO; } + +[ + helpstring("XAudio2.0 AudioVolumeMeter Class"), + threading(both), + uuid(c0c56f46-29b1-44e9-9939-a32ce86867e2) +] +coclass AudioVolumeMeter20 { interface IXAPO; } +#endif /* XAUDIO2_VER == 0 */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/xaudio_dll.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/xaudio_dll.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/xaudio_dll.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/xaudio_dll.c 2016-02-08 19:32:34.000000000 +0000 @@ -22,8 +22,6 @@ #define NONAMELESSUNION #define COBJMACROS -#include "initguid.h" - #include "xaudio_private.h" #include "ole2.h" @@ -40,8 +38,15 @@ static HINSTANCE instance; -#define COMPAT_E_INVALID_CALL(v) (v == 20) ? E_INVALIDARG : XAUDIO2_E_INVALID_CALL -#define COMPAT_E_DEVICE_INVALIDATED(v) (v == 20) ? XAUDIO20_E_DEVICE_INVALIDATED : XAUDIO2_E_DEVICE_INVALIDATED +#define IN_AL_PERIODS 4 + +#if XAUDIO2_VER == 0 +#define COMPAT_E_INVALID_CALL E_INVALIDARG +#define COMPAT_E_DEVICE_INVALIDATED XAUDIO20_E_DEVICE_INVALIDATED +#else +#define COMPAT_E_INVALID_CALL XAUDIO2_E_INVALID_CALL +#define COMPAT_E_DEVICE_INVALIDATED XAUDIO2_E_DEVICE_INVALIDATED +#endif static void dump_fmt(const WAVEFORMATEX *fmt) { @@ -449,6 +454,7 @@ case 8: return AL_FORMAT_71CHN8; } + break; case 16: switch(fmt->nChannels){ case 1: @@ -464,6 +470,7 @@ case 8: return AL_FORMAT_71CHN16; } + break; } }else if(fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT || (fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE && @@ -506,7 +513,7 @@ if(This->nbufs >= XAUDIO2_MAX_QUEUED_BUFFERS){ TRACE("Too many buffers queued!\n"); LeaveCriticalSection(&This->lock); - return COMPAT_E_INVALID_CALL(This->xa2->version); + return COMPAT_E_INVALID_CALL; } buf_idx = (This->first_buf + This->nbufs) % XAUDIO2_MAX_QUEUED_BUFFERS; @@ -517,10 +524,10 @@ * but pBuffer itself may be reused immediately */ memcpy(&buf->xa2buffer, pBuffer, sizeof(*pBuffer)); - if(This->xa2->version == 20){ - if(buf->xa2buffer.LoopCount == XAUDIO20_LOOP_INFINITE) - buf->xa2buffer.LoopCount = XAUDIO2_LOOP_INFINITE; - } +#if XAUDIO2_VER == 0 + if(buf->xa2buffer.LoopCount == XAUDIO20_LOOP_INFINITE) + buf->xa2buffer.LoopCount = XAUDIO2_LOOP_INFINITE; +#endif /* convert samples offsets to bytes */ if(This->fmt->wFormatTag == WAVE_FORMAT_ADPCM){ @@ -551,29 +558,29 @@ if(buf->xa2buffer.LoopBegin >= buf->play_end_bytes){ /* this actually crashes on native xaudio 2.7 */ LeaveCriticalSection(&This->lock); - return COMPAT_E_INVALID_CALL(This->xa2->version); + return COMPAT_E_INVALID_CALL; } buf->loop_end_bytes = buf->xa2buffer.LoopBegin + buf->xa2buffer.LoopLength; /* xaudio 2.7 allows some invalid looping setups, but later versions * return an error */ - if(This->xa2->version > 27){ - if(buf->loop_end_bytes > buf->play_end_bytes){ - LeaveCriticalSection(&This->lock); - return COMPAT_E_INVALID_CALL(This->xa2->version); - } +#if XAUDIO2_VER > 7 + if(buf->loop_end_bytes > buf->play_end_bytes){ + LeaveCriticalSection(&This->lock); + return COMPAT_E_INVALID_CALL; + } - if(buf->loop_end_bytes <= buf->xa2buffer.PlayBegin){ - LeaveCriticalSection(&This->lock); - return COMPAT_E_INVALID_CALL(This->xa2->version); - } - }else{ - if(buf->loop_end_bytes <= buf->xa2buffer.PlayBegin){ - buf->xa2buffer.LoopCount = 0; - buf->loop_end_bytes = buf->play_end_bytes; - } + if(buf->loop_end_bytes <= buf->xa2buffer.PlayBegin){ + LeaveCriticalSection(&This->lock); + return COMPAT_E_INVALID_CALL; + } +#else + if(buf->loop_end_bytes <= buf->xa2buffer.PlayBegin){ + buf->xa2buffer.LoopCount = 0; + buf->loop_end_bytes = buf->play_end_bytes; } +#endif }else{ buf->xa2buffer.LoopLength = buf->xa2buffer.PlayLength; buf->xa2buffer.LoopBegin = buf->xa2buffer.PlayBegin; @@ -743,7 +750,7 @@ if(This->nbufs){ LeaveCriticalSection(&This->lock); - return COMPAT_E_INVALID_CALL(This->xa2->version); + return COMPAT_E_INVALID_CALL; } This->fmt->nSamplesPerSec = NewSourceSampleRate; @@ -1187,16 +1194,20 @@ TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject); if(IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IXAudio28) || IsEqualGUID(riid, &IID_IXAudio2)) *ppvObject = &This->IXAudio2_iface; else if(IsEqualGUID(riid, &IID_IXAudio27)){ /* all xaudio versions before 28 share an IID */ - if(This->version == 20) - *ppvObject = &This->IXAudio20_iface; - else if(This->version == 21 || This->version == 22) - *ppvObject = &This->IXAudio22_iface; - else - *ppvObject = &This->IXAudio27_iface; +#if XAUDIO2_VER == 0 + *ppvObject = &This->IXAudio20_iface; +#elif XAUDIO2_VER <= 2 + *ppvObject = &This->IXAudio22_iface; +#elif XAUDIO2_VER <= 7 + *ppvObject = &This->IXAudio27_iface; +#else + *ppvObject = NULL; +#endif }else *ppvObject = NULL; @@ -1368,10 +1379,15 @@ list_add_head(&This->source_voices, &src->entry); + src->IXAudio2SourceVoice_iface.lpVtbl = &XAudio2SourceVoice_Vtbl; + +#if XAUDIO2_VER == 0 src->IXAudio20SourceVoice_iface.lpVtbl = &XAudio20SourceVoice_Vtbl; +#elif XAUDIO2_VER <= 3 src->IXAudio23SourceVoice_iface.lpVtbl = &XAudio23SourceVoice_Vtbl; +#elif XAUDIO2_VER <= 7 src->IXAudio27SourceVoice_iface.lpVtbl = &XAudio27SourceVoice_Vtbl; - src->IXAudio2SourceVoice_iface.lpVtbl = &XAudio2SourceVoice_Vtbl; +#endif InitializeCriticalSection(&src->lock); src->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": XA2SourceImpl.lock"); @@ -1408,14 +1424,15 @@ alSourcePlay(src->al_src); - if(This->version == 20) - *ppSourceVoice = (IXAudio2SourceVoice*)&src->IXAudio20SourceVoice_iface; - else if(This->version <= 23) - *ppSourceVoice = (IXAudio2SourceVoice*)&src->IXAudio23SourceVoice_iface; - else if(This->version <= 27) - *ppSourceVoice = (IXAudio2SourceVoice*)&src->IXAudio27SourceVoice_iface; - else - *ppSourceVoice = &src->IXAudio2SourceVoice_iface; +#if XAUDIO2_VER == 0 + *ppSourceVoice = (IXAudio2SourceVoice*)&src->IXAudio20SourceVoice_iface; +#elif XAUDIO2_VER <= 3 + *ppSourceVoice = (IXAudio2SourceVoice*)&src->IXAudio23SourceVoice_iface; +#elif XAUDIO2_VER <= 7 + *ppSourceVoice = (IXAudio2SourceVoice*)&src->IXAudio27SourceVoice_iface; +#else + *ppSourceVoice = &src->IXAudio2SourceVoice_iface; +#endif TRACE("Created source voice: %p\n", src); @@ -1451,9 +1468,13 @@ list_add_head(&This->submix_voices, &sub->entry); + sub->IXAudio2SubmixVoice_iface.lpVtbl = &XAudio2SubmixVoice_Vtbl; + +#if XAUDIO2_VER == 0 sub->IXAudio20SubmixVoice_iface.lpVtbl = &XAudio20SubmixVoice_Vtbl; +#elif XAUDIO2_VER <= 3 sub->IXAudio23SubmixVoice_iface.lpVtbl = &XAudio23SubmixVoice_Vtbl; - sub->IXAudio2SubmixVoice_iface.lpVtbl = &XAudio2SubmixVoice_Vtbl; +#endif InitializeCriticalSection(&sub->lock); sub->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": XA2SubmixImpl.lock"); @@ -1463,12 +1484,13 @@ LeaveCriticalSection(&This->lock); - if(This->version == 20) - *ppSubmixVoice = (IXAudio2SubmixVoice*)&sub->IXAudio20SubmixVoice_iface; - else if(This->version <= 23) - *ppSubmixVoice = (IXAudio2SubmixVoice*)&sub->IXAudio23SubmixVoice_iface; - else - *ppSubmixVoice = &sub->IXAudio2SubmixVoice_iface; +#if XAUDIO2_VER == 0 + *ppSubmixVoice = (IXAudio2SubmixVoice*)&sub->IXAudio20SubmixVoice_iface; +#elif XAUDIO2_VER <= 3 + *ppSubmixVoice = (IXAudio2SubmixVoice*)&sub->IXAudio23SubmixVoice_iface; +#else + *ppSubmixVoice = &sub->IXAudio2SubmixVoice_iface; +#endif TRACE("Created submix voice: %p\n", sub); @@ -1525,13 +1547,13 @@ /* there can only be one Mastering Voice, so just build it into XA2 */ if(This->aclient){ LeaveCriticalSection(&This->lock); - return COMPAT_E_INVALID_CALL(This->version); + return COMPAT_E_INVALID_CALL; } if(!deviceId){ if(This->ndevs == 0){ LeaveCriticalSection(&This->lock); - return ERROR_NOT_FOUND; + return E_NOTFOUND; } deviceId = This->devids[0]; } @@ -1539,7 +1561,7 @@ hr = IMMDeviceEnumerator_GetDevice(This->devenum, deviceId, &dev); if(FAILED(hr)){ WARN("GetDevice failed: %08x\n", hr); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } @@ -1548,7 +1570,7 @@ if(FAILED(hr)){ WARN("Activate(IAudioClient) failed: %08x\n", hr); IMMDevice_Release(dev); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } @@ -1557,13 +1579,13 @@ hr = IAudioClient_GetMixFormat(This->aclient, &fmt); if(FAILED(hr)){ WARN("GetMixFormat failed: %08x\n", hr); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } if(sizeof(WAVEFORMATEX) + fmt->cbSize > sizeof(WAVEFORMATEXTENSIBLE)){ FIXME("Mix format doesn't fit into WAVEFORMATEXTENSIBLE!\n"); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } @@ -1587,7 +1609,7 @@ if(hr == S_FALSE){ if(sizeof(WAVEFORMATEX) + fmt->cbSize > sizeof(WAVEFORMATEXTENSIBLE)){ FIXME("Mix format doesn't fit into WAVEFORMATEXTENSIBLE!\n"); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } memcpy(&This->fmt, fmt, sizeof(WAVEFORMATEX) + fmt->cbSize); @@ -1598,7 +1620,7 @@ hr = IAudioClient_GetDevicePeriod(This->aclient, &period, NULL); if(FAILED(hr)){ WARN("GetDevicePeriod failed: %08x\n", hr); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } @@ -1610,7 +1632,7 @@ 0, &This->fmt.Format, NULL); if(FAILED(hr)){ WARN("Initialize failed: %08x\n", hr); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } @@ -1619,7 +1641,7 @@ hr = IAudioClient_SetEventHandle(This->aclient, This->mmevt); if(FAILED(hr)){ WARN("Initialize failed: %08x\n", hr); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } @@ -1627,7 +1649,7 @@ (void**)&This->render); if(FAILED(hr)){ WARN("GetService(IAudioRenderClient) failed: %08x\n", hr); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } @@ -1665,27 +1687,27 @@ if(!attrs[5]){ WARN("OpenAL can't output samples in this format\n"); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } This->al_device = palcLoopbackOpenDeviceSOFT(NULL); if(!This->al_device){ WARN("alcLoopbackOpenDeviceSOFT failed\n"); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } This->al_ctx = alcCreateContext(This->al_device, attrs); if(!This->al_ctx){ WARN("alcCreateContext failed\n"); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } if(alcMakeContextCurrent(This->al_ctx) == ALC_FALSE){ WARN("alcMakeContextCurrent failed\n"); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } @@ -1693,16 +1715,17 @@ if (FAILED(hr)) { WARN("Start(IAudioClient) failed: %08x\n", hr); - hr = COMPAT_E_DEVICE_INVALIDATED(This->version); + hr = COMPAT_E_DEVICE_INVALIDATED; goto exit; } - if(This->version <= 20) - *ppMasteringVoice = (IXAudio2MasteringVoice*)&This->IXAudio20MasteringVoice_iface; - else if(This->version <= 23) - *ppMasteringVoice = (IXAudio2MasteringVoice*)&This->IXAudio23MasteringVoice_iface; - else - *ppMasteringVoice = &This->IXAudio2MasteringVoice_iface; +#if XAUDIO2_VER == 0 + *ppMasteringVoice = (IXAudio2MasteringVoice*)&This->IXAudio20MasteringVoice_iface; +#elif XAUDIO2_VER <= 3 + *ppMasteringVoice = (IXAudio2MasteringVoice*)&This->IXAudio23MasteringVoice_iface; +#else + *ppMasteringVoice = &This->IXAudio2MasteringVoice_iface; +#endif exit: if(FAILED(hr)){ @@ -1804,7 +1827,6 @@ struct xaudio2_cf { IClassFactory IClassFactory_iface; LONG ref; - DWORD version; }; static struct xaudio2_cf *impl_from_IClassFactory(IClassFactory *iface) @@ -1936,18 +1958,22 @@ if(!object) return E_OUTOFMEMORY; + object->IXAudio2_iface.lpVtbl = &XAudio2_Vtbl; + object->IXAudio2MasteringVoice_iface.lpVtbl = &XAudio2MasteringVoice_Vtbl; + +#if XAUDIO2_VER == 0 object->IXAudio20_iface.lpVtbl = &XAudio20_Vtbl; +#elif XAUDIO2_VER <= 2 object->IXAudio22_iface.lpVtbl = &XAudio22_Vtbl; +#elif XAUDIO2_VER <= 7 object->IXAudio27_iface.lpVtbl = &XAudio27_Vtbl; - object->IXAudio2_iface.lpVtbl = &XAudio2_Vtbl; +#endif + +#if XAUDIO2_VER == 0 object->IXAudio20MasteringVoice_iface.lpVtbl = &XAudio20MasteringVoice_Vtbl; +#elif XAUDIO2_VER <= 3 object->IXAudio23MasteringVoice_iface.lpVtbl = &XAudio23MasteringVoice_Vtbl; - object->IXAudio2MasteringVoice_iface.lpVtbl = &XAudio2MasteringVoice_Vtbl; - - if(IsEqualGUID(riid, &IID_IXAudio27)) - object->version = This->version; - else /* only xaudio 2.8 has a different IID */ - object->version = 28; +#endif list_init(&object->source_voices); list_init(&object->submix_voices); @@ -1973,7 +1999,7 @@ IXAudio2_StartEngine(&object->IXAudio2_iface); - TRACE("Created XAudio version %u: %p\n", object->version, object); + TRACE("Created XAudio version %u: %p\n", 20 + XAUDIO2_VER, object); return hr; } @@ -1993,11 +2019,10 @@ XAudio2CF_LockServer }; -static IClassFactory *make_xaudio2_factory(DWORD version) +static IClassFactory *make_xaudio2_factory(void) { struct xaudio2_cf *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct xaudio2_cf)); ret->IClassFactory_iface.lpVtbl = &XAudio2CF_Vtbl; - ret->version = version; ret->ref = 0; return &ret->IClassFactory_iface; } @@ -2008,88 +2033,35 @@ TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); - if(IsEqualGUID(rclsid, &CLSID_XAudio20)){ - factory = make_xaudio2_factory(20); - }else if(IsEqualGUID(rclsid, &CLSID_XAudio21)){ - factory = make_xaudio2_factory(21); - }else if(IsEqualGUID(rclsid, &CLSID_XAudio22)){ - factory = make_xaudio2_factory(22); - }else if(IsEqualGUID(rclsid, &CLSID_XAudio23)){ - factory = make_xaudio2_factory(23); - }else if(IsEqualGUID(rclsid, &CLSID_XAudio24)){ - factory = make_xaudio2_factory(24); - }else if(IsEqualGUID(rclsid, &CLSID_XAudio25)){ - factory = make_xaudio2_factory(25); - }else if(IsEqualGUID(rclsid, &CLSID_XAudio26)){ - factory = make_xaudio2_factory(26); - }else if(IsEqualGUID(rclsid, &CLSID_XAudio2)){ - factory = make_xaudio2_factory(27); - - }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter20)){ - factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 20); - }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter21)){ - factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 21); - }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter22)){ - factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 22); - }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter23)){ - factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 23); - }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter24)){ - factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 24); - }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter25)){ - factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 25); - }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter26)){ - factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 26); - }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter)){ - factory = make_xapo_factory(&CLSID_AudioVolumeMeter, 27); - - }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb20)){ - factory = make_xapo_factory(&CLSID_AudioReverb, 20); - - }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb21) || - IsEqualGUID(rclsid, &CLSID_WINE_FXReverb10)){ - factory = make_xapo_factory(&CLSID_AudioReverb, 21); - - }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb22) || - IsEqualGUID(rclsid, &CLSID_WINE_FXReverb11)){ - factory = make_xapo_factory(&CLSID_AudioReverb, 22); - - }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb23) || - IsEqualGUID(rclsid, &CLSID_WINE_FXReverb12)){ - factory = make_xapo_factory(&CLSID_AudioReverb, 23); - - }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb24) || - IsEqualGUID(rclsid, &CLSID_WINE_FXReverb13)){ - factory = make_xapo_factory(&CLSID_AudioReverb, 24); - - }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb25)){ - factory = make_xapo_factory(&CLSID_AudioReverb, 25); - - }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb26) || - IsEqualGUID(rclsid, &CLSID_WINE_FXReverb14)){ - factory = make_xapo_factory(&CLSID_AudioReverb, 26); - - }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb) || - IsEqualGUID(rclsid, &CLSID_WINE_FXReverb15)){ - factory = make_xapo_factory(&CLSID_AudioReverb, 27); - - }else if(IsEqualGUID(rclsid, &CLSID_WINE_FXReverb28)){ - factory = make_xapo_factory(&CLSID_AudioReverb, 28); - - - }else if(IsEqualGUID(rclsid, &CLSID_WINE_FXEQ10)){ - factory = make_xapo_factory(&CLSID_FXEQ, 21); - }else if(IsEqualGUID(rclsid, &CLSID_WINE_FXEQ11)){ - factory = make_xapo_factory(&CLSID_FXEQ, 22); - }else if(IsEqualGUID(rclsid, &CLSID_WINE_FXEQ12)){ - factory = make_xapo_factory(&CLSID_FXEQ, 23); - }else if(IsEqualGUID(rclsid, &CLSID_WINE_FXEQ13)){ - factory = make_xapo_factory(&CLSID_FXEQ, 24); - }else if(IsEqualGUID(rclsid, &CLSID_WINE_FXEQ14)){ - factory = make_xapo_factory(&CLSID_FXEQ, 26); - }else if(IsEqualGUID(rclsid, &CLSID_WINE_FXEQ15)){ - factory = make_xapo_factory(&CLSID_FXEQ, 27); - }else if(IsEqualGUID(rclsid, &CLSID_WINE_FXEQ28)){ - factory = make_xapo_factory(&CLSID_FXEQ, 28); + if(IsEqualGUID(rclsid, &CLSID_XAudio20) || + IsEqualGUID(rclsid, &CLSID_XAudio21) || + IsEqualGUID(rclsid, &CLSID_XAudio22) || + IsEqualGUID(rclsid, &CLSID_XAudio23) || + IsEqualGUID(rclsid, &CLSID_XAudio24) || + IsEqualGUID(rclsid, &CLSID_XAudio25) || + IsEqualGUID(rclsid, &CLSID_XAudio26) || + IsEqualGUID(rclsid, &CLSID_XAudio27)){ + factory = make_xaudio2_factory(); + + }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter20) || + IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter21) || + IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter22) || + IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter23) || + IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter24) || + IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter25) || + IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter26) || + IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter27)){ + factory = make_xapo_factory(&CLSID_AudioVolumeMeter27); + + }else if(IsEqualGUID(rclsid, &CLSID_AudioReverb20) || + IsEqualGUID(rclsid, &CLSID_AudioReverb21) || + IsEqualGUID(rclsid, &CLSID_AudioReverb22) || + IsEqualGUID(rclsid, &CLSID_AudioReverb23) || + IsEqualGUID(rclsid, &CLSID_AudioReverb24) || + IsEqualGUID(rclsid, &CLSID_AudioReverb25) || + IsEqualGUID(rclsid, &CLSID_AudioReverb26) || + IsEqualGUID(rclsid, &CLSID_AudioReverb27)){ + factory = make_xapo_factory(&CLSID_FXReverb); } if(!factory) return CLASS_E_CLASSNOTAVAILABLE; @@ -2097,6 +2069,41 @@ return IClassFactory_QueryInterface(factory, riid, ppv); } +HRESULT xaudio2_initialize(IXAudio2Impl *This, UINT32 flags, XAUDIO2_PROCESSOR proc) +{ + if(flags) + FIXME("Unimplemented flags: 0x%x\n", flags); + return S_OK; +} + +#if XAUDIO2_VER >= 8 +HRESULT WINAPI XAudio2Create(IXAudio2 **ppxa2, UINT32 flags, XAUDIO2_PROCESSOR proc) +{ + HRESULT hr; + IXAudio2 *xa2; + IClassFactory *cf; + + TRACE("%p 0x%x 0x%x\n", ppxa2, flags, proc); + + cf = make_xaudio2_factory(); + + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IXAudio2, (void**)&xa2); + IClassFactory_Release(cf); + if(FAILED(hr)) + return hr; + + hr = xaudio2_initialize(impl_from_IXAudio2(xa2), flags, proc); + if(FAILED(hr)){ + IXAudio2_Release(xa2); + return hr; + } + + *ppxa2 = xa2; + + return S_OK; +} +#endif /* XAUDIO2_VER >= 8 */ + /* returns TRUE if there is more data available in the buffer, FALSE if the * buffer's data has all been queued */ static BOOL xa2buffer_queue_period(XA2SourceImpl *src, XA2Buffer *buf, ALuint al_buf) @@ -2128,6 +2135,30 @@ return buf->offs_bytes < buf->cur_end_bytes; } +#if XAUDIO2_VER > 0 +static UINT32 get_underrun_warning(XA2SourceImpl *src) +{ + UINT32 period_bytes = src->xa2->period_frames * src->submit_blocksize; + UINT32 total = 0, i; + + for(i = 0; i < src->nbufs && total < IN_AL_PERIODS * period_bytes; ++i){ + XA2Buffer *buf = &src->buffers[(src->first_buf + i) % XAUDIO2_MAX_QUEUED_BUFFERS]; + total += buf->cur_end_bytes - buf->offs_bytes; + if(buf->xa2buffer.LoopCount == XAUDIO2_LOOP_INFINITE) + return 0; + if(buf->xa2buffer.LoopCount > 0){ + total += (buf->loop_end_bytes - buf->xa2buffer.LoopBegin) * (buf->xa2buffer.LoopCount - buf->looped); + total += buf->play_end_bytes - buf->loop_end_bytes; + } + } + + if(total >= IN_AL_PERIODS * period_bytes) + return 0; + + return ((IN_AL_PERIODS * period_bytes - total) / period_bytes + 1) * period_bytes; +} +#endif + /* Looping: * * The looped section of a buffer is a subset of the play area which is looped @@ -2143,7 +2174,7 @@ * * In the simple case, playback will start at PlayBegin. At LoopEnd, playback * will move to LoopBegin and repeat that loop LoopCount times. Then, playback - * will cease at LoopEnd. + * will cease at PlayEnd. * * If PlayLength is zero, then PlayEnd is the end of the buffer. * @@ -2203,9 +2234,9 @@ alGetSourcei(src->al_src, AL_BYTE_OFFSET, &bufpos); - /* maintain 4 periods in AL */ + /* maintain IN_AL_PERIODS periods in AL */ while(src->cur_buf != (src->first_buf + src->nbufs) % XAUDIO2_MAX_QUEUED_BUFFERS && - src->in_al_bytes - bufpos < 4 * src->xa2->period_frames * src->submit_blocksize){ + src->in_al_bytes - bufpos < IN_AL_PERIODS * src->xa2->period_frames * src->submit_blocksize){ TRACE("%p: going to queue a period from buffer %u\n", src, src->cur_buf); /* starting from an empty buffer */ @@ -2280,11 +2311,15 @@ } if(src->cb){ - if(This->version == 20) - IXAudio20VoiceCallback_OnVoiceProcessingPassStart((IXAudio20VoiceCallback*)src->cb); - else - /* TODO: detect incoming underrun and inform callback */ - IXAudio2VoiceCallback_OnVoiceProcessingPassStart(src->cb, 0); +#if XAUDIO2_VER == 0 + IXAudio20VoiceCallback_OnVoiceProcessingPassStart((IXAudio20VoiceCallback*)src->cb); +#else + UINT32 underrun; + underrun = get_underrun_warning(src); + if(underrun > 0) + TRACE("Calling OnVoiceProcessingPassStart with BytesRequired: %u\n", underrun); + IXAudio2VoiceCallback_OnVoiceProcessingPassStart(src->cb, underrun); +#endif } update_source_state(src); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/xaudio_private.h wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/xaudio_private.h --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_7/xaudio_private.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_7/xaudio_private.h 2016-02-08 19:32:34.000000000 +0000 @@ -42,10 +42,15 @@ typedef struct _IXAudio2Impl IXAudio2Impl; typedef struct _XA2SourceImpl { + IXAudio2SourceVoice IXAudio2SourceVoice_iface; + +#if XAUDIO2_VER == 0 IXAudio20SourceVoice IXAudio20SourceVoice_iface; +#elif XAUDIO2_VER <= 3 IXAudio23SourceVoice IXAudio23SourceVoice_iface; +#elif XAUDIO2_VER <= 7 IXAudio27SourceVoice IXAudio27SourceVoice_iface; - IXAudio2SourceVoice IXAudio2SourceVoice_iface; +#endif IXAudio2Impl *xa2; @@ -82,9 +87,13 @@ } XA2SourceImpl; typedef struct _XA2SubmixImpl { + IXAudio2SubmixVoice IXAudio2SubmixVoice_iface; + +#if XAUDIO2_VER == 0 IXAudio20SubmixVoice IXAudio20SubmixVoice_iface; +#elif XAUDIO2_VER <= 3 IXAudio23SubmixVoice IXAudio23SubmixVoice_iface; - IXAudio2SubmixVoice IXAudio2SubmixVoice_iface; +#endif BOOL in_use; @@ -94,13 +103,22 @@ } XA2SubmixImpl; struct _IXAudio2Impl { + IXAudio2 IXAudio2_iface; + IXAudio2MasteringVoice IXAudio2MasteringVoice_iface; + +#if XAUDIO2_VER == 0 IXAudio20 IXAudio20_iface; +#elif XAUDIO2_VER <= 2 IXAudio22 IXAudio22_iface; +#elif XAUDIO2_VER <= 7 IXAudio27 IXAudio27_iface; - IXAudio2 IXAudio2_iface; +#endif + +#if XAUDIO2_VER == 0 IXAudio20MasteringVoice IXAudio20MasteringVoice_iface; +#elif XAUDIO2_VER <= 3 IXAudio23MasteringVoice IXAudio23MasteringVoice_iface; - IXAudio2MasteringVoice IXAudio2MasteringVoice_iface; +#endif LONG ref; @@ -109,8 +127,6 @@ HANDLE engine, mmevt; BOOL stop_engine; - DWORD version; - struct list source_voices; struct list submix_voices; @@ -137,18 +153,25 @@ BOOL running; }; -extern const IXAudio27SourceVoiceVtbl XAudio27SourceVoice_Vtbl DECLSPEC_HIDDEN; -extern const IXAudio27Vtbl XAudio27_Vtbl DECLSPEC_HIDDEN; - +#if XAUDIO2_VER == 0 +extern const IXAudio20SourceVoiceVtbl XAudio20SourceVoice_Vtbl DECLSPEC_HIDDEN; +extern const IXAudio20SubmixVoiceVtbl XAudio20SubmixVoice_Vtbl DECLSPEC_HIDDEN; +extern const IXAudio20MasteringVoiceVtbl XAudio20MasteringVoice_Vtbl DECLSPEC_HIDDEN; +#elif XAUDIO2_VER <= 3 extern const IXAudio23SourceVoiceVtbl XAudio23SourceVoice_Vtbl DECLSPEC_HIDDEN; extern const IXAudio23SubmixVoiceVtbl XAudio23SubmixVoice_Vtbl DECLSPEC_HIDDEN; extern const IXAudio23MasteringVoiceVtbl XAudio23MasteringVoice_Vtbl DECLSPEC_HIDDEN; +#elif XAUDIO2_VER <= 7 +extern const IXAudio27SourceVoiceVtbl XAudio27SourceVoice_Vtbl DECLSPEC_HIDDEN; +#endif -extern const IXAudio22Vtbl XAudio22_Vtbl DECLSPEC_HIDDEN; - +#if XAUDIO2_VER == 0 extern const IXAudio20Vtbl XAudio20_Vtbl DECLSPEC_HIDDEN; -extern const IXAudio20SourceVoiceVtbl XAudio20SourceVoice_Vtbl DECLSPEC_HIDDEN; -extern const IXAudio20SubmixVoiceVtbl XAudio20SubmixVoice_Vtbl DECLSPEC_HIDDEN; -extern const IXAudio20MasteringVoiceVtbl XAudio20MasteringVoice_Vtbl DECLSPEC_HIDDEN; +#elif XAUDIO2_VER <= 2 +extern const IXAudio22Vtbl XAudio22_Vtbl DECLSPEC_HIDDEN; +#elif XAUDIO2_VER <= 7 +extern const IXAudio27Vtbl XAudio27_Vtbl DECLSPEC_HIDDEN; +#endif -extern IClassFactory *make_xapo_factory(REFCLSID clsid, DWORD version); +extern IClassFactory *make_xapo_factory(REFCLSID clsid) DECLSPEC_HIDDEN; +extern HRESULT xaudio2_initialize(IXAudio2Impl *This, UINT32 flags, XAUDIO2_PROCESSOR proc) DECLSPEC_HIDDEN; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_8/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_8/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_8/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_8/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -1,6 +1,13 @@ +EXTRADEFS = -DXAUDIO2_VER=8 MODULE = xaudio2_8.dll -IMPORTLIB = xaudio2_8 -IMPORTS = ole32 +IMPORTS = advapi32 ole32 user32 uuid +EXTRALIBS = $(OPENAL_LIBS) +PARENTSRC = ../xaudio2_7 C_SRCS = \ + compat.c \ + x3daudio.c \ + xapofx.c \ xaudio_dll.c + +IDL_SRCS = xaudio_classes.idl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_8/xaudio_dll.c wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_8/xaudio_dll.c --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_8/xaudio_dll.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_8/xaudio_dll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Eikum for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "wine/debug.h" - -#include "initguid.h" -#include "xaudio2.h" -#include "xaudio2fx.h" -#include "xapo.h" -#include "xapofx.h" -#include "x3daudio.h" - -WINE_DEFAULT_DEBUG_CHANNEL(xaudio2); - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - switch (fdwReason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls( hinstDLL ); - break; - } - return TRUE; -} - -HRESULT WINAPI XAudio2Create(IXAudio2 **ppxa2, UINT32 flags, XAUDIO2_PROCESSOR proc) -{ - HRESULT hr; - IXAudio2 *xa2; - IXAudio27 *xa27; - - /* create XAudio2 2.8 instance */ - hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, - &IID_IXAudio2, (void**)&xa2); - if(FAILED(hr)) - return hr; - - hr = IXAudio2_QueryInterface(xa2, &IID_IXAudio27, (void**)&xa27); - if(FAILED(hr)){ - IXAudio2_Release(xa2); - return hr; - } - - hr = IXAudio27_Initialize(xa27, flags, proc); - if(FAILED(hr)){ - IXAudio27_Release(xa27); - IXAudio2_Release(xa2); - return hr; - } - - IXAudio27_Release(xa27); - - *ppxa2 = xa2; - - return S_OK; -} - -HRESULT WINAPI CreateAudioVolumeMeter(IUnknown **out) -{ - return CoCreateInstance(&CLSID_AudioVolumeMeter, NULL, CLSCTX_INPROC_SERVER, - &IID_IUnknown, (void**)out); -} - -HRESULT WINAPI CreateAudioReverb(IUnknown **out) -{ - return CoCreateInstance(&CLSID_AudioReverb, NULL, CLSCTX_INPROC_SERVER, - &IID_IUnknown, (void**)out); -} - -HRESULT CDECL CreateFX(REFCLSID clsid, IUnknown **out, void *initdata, UINT32 initdata_bytes) -{ - HRESULT hr; - IUnknown *obj; - const GUID *class; - - *out = NULL; - class = clsid; - - if(IsEqualGUID(clsid, &CLSID_FXReverb27) || - IsEqualGUID(clsid, &CLSID_FXReverb)) - class = &CLSID_WINE_FXReverb28; - else if(IsEqualGUID(clsid, &CLSID_FXEQ27) || - IsEqualGUID(clsid, &CLSID_FXEQ)) - class = &CLSID_WINE_FXEQ28; - - hr = CoCreateInstance(class, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&obj); - if(FAILED(hr)){ - WARN("CoCreateInstance failed: %08x\n", hr); - return hr; - } - - if(initdata && initdata_bytes > 0){ - IXAPO *xapo; - - hr = IUnknown_QueryInterface(obj, &IID_IXAPO, (void**)&xapo); - if(SUCCEEDED(hr)){ - hr = IXAPO_Initialize(xapo, initdata, initdata_bytes); - - IXAPO_Release(xapo); - - if(FAILED(hr)){ - WARN("Initialize failed: %08x\n", hr); - IUnknown_Release(obj); - return hr; - } - } - } - - *out = obj; - - return S_OK; -} - -HRESULT CDECL X3DAudioInitialize(UINT32 chanmask, float speedofsound, - X3DAUDIO_HANDLE handle) -{ - FIXME("0x%x, %f, %p: Stub!\n", chanmask, speedofsound, handle); - return S_OK; -} - -void CDECL X3DAudioCalculate(const X3DAUDIO_HANDLE handle, - const X3DAUDIO_LISTENER *listener, const X3DAUDIO_EMITTER *emitter, - UINT32 flags, X3DAUDIO_DSP_SETTINGS *out) -{ - static int once = 0; - if(!once){ - FIXME("%p %p %p 0x%x %p: Stub!\n", handle, listener, emitter, flags, out); - ++once; - } - - out->LPFDirectCoefficient = 0; - out->LPFReverbCoefficient = 0; - out->ReverbLevel = 0; - out->DopplerFactor = 1; - out->EmitterToListenerAngle = 0; - out->EmitterToListenerDistance = 0; - out->EmitterVelocityComponent = 0; - out->ListenerVelocityComponent = 0; -} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_9/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_9/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_9/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_9/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,13 @@ +EXTRADEFS = -DXAUDIO2_VER=9 +MODULE = xaudio2_9.dll +IMPORTS = advapi32 ole32 user32 uuid +EXTRALIBS = $(OPENAL_LIBS) +PARENTSRC = ../xaudio2_7 + +C_SRCS = \ + compat.c \ + x3daudio.c \ + xapofx.c \ + xaudio_dll.c + +IDL_SRCS = xaudio_classes.idl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_9/xaudio2_9.spec wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_9/xaudio2_9.spec --- wine-staging-1.9.0~ubuntu12.04.1/dlls/xaudio2_9/xaudio2_9.spec 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/dlls/xaudio2_9/xaudio2_9.spec 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,6 @@ +@ stdcall XAudio2Create(ptr long long) +@ stdcall CreateAudioVolumeMeter(ptr) +@ stdcall CreateAudioReverb(ptr) +@ cdecl CreateFX(ptr ptr ptr long) +@ cdecl X3DAudioCalculate(ptr ptr ptr long ptr) +@ cdecl X3DAudioInitialize(long float ptr) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/bcrypt.h wine-staging-1.9.3~ubuntu12.04.1/include/bcrypt.h --- wine-staging-1.9.0~ubuntu12.04.1/include/bcrypt.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/bcrypt.h 2016-02-08 19:32:34.000000000 +0000 @@ -40,6 +40,34 @@ typedef LONG NTSTATUS; #endif +#define BCRYPT_ALGORITHM_NAME (const WCHAR []){'A','l','g','o','r','i','t','h','m','N','a','m','e',0} +#define BCRYPT_AUTH_TAG_LENGTH (const WCHAR []){'A','u','t','h','T','a','g','L','e','n','g','t','h',0} +#define BCRYPT_BLOCK_LENGTH (const WCHAR []){'B','l','o','c','k','L','e','n','g','t','h',0} +#define BCRYPT_BLOCK_SIZE_LIST (const WCHAR []){'B','l','o','c','k','S','i','z','e','L','i','s','t',0} +#define BCRYPT_CHAINING_MODE (const WCHAR []){'C','h','a','i','n','i','n','g','M','o','d','e',0} +#define BCRYPT_EFFECTIVE_KEY_LENGTH (const WCHAR []){'E','f','f','e','c','t','i','v','e','K','e','y','L','e','n','g','t','h',0} +#define BCRYPT_HASH_BLOCK_LENGTH (const WCHAR []){'H','a','s','h','B','l','o','c','k','L','e','n','g','t','h',0} +#define BCRYPT_HASH_LENGTH (const WCHAR []){'H','a','s','h','D','i','g','e','s','t','L','e','n','g','t','h',0} +#define BCRYPT_HASH_OID_LIST (const WCHAR []){'H','a','s','h','O','I','D','L','i','s','t',0} +#define BCRYPT_KEY_LENGTH (const WCHAR []){'K','e','y','L','e','n','g','t','h',0} +#define BCRYPT_KEY_LENGTHS (const WCHAR []){'K','e','y','L','e','n','g','t','h','s',0} +#define BCRYPT_KEY_OBJECT_LENGTH (const WCHAR []){'K','e','y','O','b','j','e','c','t','L','e','n','g','t','h',0} +#define BCRYPT_KEY_STRENGTH (const WCHAR []){'K','e','y','S','t','r','e','n','g','t','h',0} +#define BCRYPT_OBJECT_LENGTH (const WCHAR []){'O','b','j','e','c','t','L','e','n','g','t','h',0} +#define BCRYPT_PADDING_SCHEMES (const WCHAR []){'P','a','d','d','i','n','g','S','c','h','e','m','e','s',0} +#define BCRYPT_PROVIDER_HANDLE (const WCHAR []){'P','r','o','v','i','d','e','r','H','a','n','d','l','e',0} +#define BCRYPT_SIGNATURE_LENGTH (const WCHAR []){'S','i','g','n','a','t','u','r','e','L','e','n','g','t','h',0} + +#define MS_PRIMITIVE_PROVIDER (const WCHAR [])\ + {'M','i','c','r','o','s','o','f','t',' ','P','r','i','m','i','t','i','v','e',' ','P','r','o','v','i','d','e','r',0} +#define MS_PLATFORM_CRYPTO_PROVIDER (const WCHAR [])\ + {'M','i','c','r','o','s','o','f','t',' ','P','l','a','t','f','o','r','m',' ','C','r','y','p','t','o',' ','P','r','o','v','i','d','e','r',0} + +#define BCRYPT_SHA1_ALGORITHM (const WCHAR []){'S','H','A','1',0} +#define BCRYPT_SHA256_ALGORITHM (const WCHAR []){'S','H','A','2','5','6',0} +#define BCRYPT_SHA384_ALGORITHM (const WCHAR []){'S','H','A','3','8','4',0} +#define BCRYPT_SHA512_ALGORITHM (const WCHAR []){'S','H','A','5','1','2',0} + typedef struct _BCRYPT_ALGORITHM_IDENTIFIER { LPWSTR pszName; @@ -54,4 +82,15 @@ #define BCRYPT_RNG_USE_ENTROPY_IN_BUFFER 0x00000001 #define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002 +NTSTATUS WINAPI BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE, ULONG); +NTSTATUS WINAPI BCryptCreateHash(BCRYPT_ALG_HANDLE, BCRYPT_HASH_HANDLE *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG); +NTSTATUS WINAPI BCryptDestroyHash(BCRYPT_HASH_HANDLE); +NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG, ULONG *, BCRYPT_ALGORITHM_IDENTIFIER **, ULONG); +NTSTATUS WINAPI BCryptFinishHash(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG); +NTSTATUS WINAPI BCryptGenRandom(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, ULONG); +NTSTATUS WINAPI BCryptGetFipsAlgorithmMode(BOOLEAN *); +NTSTATUS WINAPI BCryptGetProperty(BCRYPT_HANDLE, LPCWSTR, PUCHAR, ULONG, ULONG *, ULONG); +NTSTATUS WINAPI BCryptHashData(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG); +NTSTATUS WINAPI BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *, LPCWSTR, LPCWSTR, ULONG); + #endif /* __WINE_BCRYPT_H */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/config.h.in wine-staging-1.9.3~ubuntu12.04.1/include/config.h.in --- wine-staging-1.9.0~ubuntu12.04.1/include/config.h.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/config.h.in 2016-02-08 19:32:34.000000000 +0000 @@ -71,6 +71,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_CL_CL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_COMMONCRYPTO_COMMONDIGEST_H + /* Define to 1 if you have the header file. */ #undef HAVE_COREAUDIO_COREAUDIO_H @@ -225,6 +228,9 @@ /* Define to 1 if you have the `getuid' function. */ #undef HAVE_GETUID +/* Define to 1 if you have the `gnutls_hash' function. */ +#undef HAVE_GNUTLS_HASH + /* Define if we have the libgphoto2 development environment */ #undef HAVE_GPHOTO2 @@ -1305,6 +1311,9 @@ /* Define to 1 if you have the `__builtin_clz' built-in function. */ #undef HAVE___BUILTIN_CLZ +/* Define to 1 if you have the `__builtin_popcount' built-in function. */ +#undef HAVE___BUILTIN_POPCOUNT + /* Define to 1 if you have the `__res_getservers' function. */ #undef HAVE___RES_GETSERVERS diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/d3d11.idl wine-staging-1.9.3~ubuntu12.04.1/include/d3d11.idl --- wine-staging-1.9.0~ubuntu12.04.1/include/d3d11.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/d3d11.idl 2016-02-08 19:32:34.000000000 +0000 @@ -27,6 +27,11 @@ typedef D3D_SRV_DIMENSION D3D11_SRV_DIMENSION; typedef RECT D3D11_RECT; +interface ID3D11Device; +interface ID3D11ClassLinkage; +interface ID3D11Resource; +interface ID3D11VideoProcessorInputView; + const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT = 14; const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_COMPONENTS = 4; const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_COMPONENT_BIT_COUNT = 32; @@ -106,6 +111,8 @@ const UINT D3D11_SHADER_MINOR_VERSION = 0; const UINT D3D11_VS_OUTPUT_REGISTER_COUNT = 32; +const UINT D3D11_OMAC_SIZE = 16; + const UINT D3D11_PS_CS_UAV_REGISTER_COMPONENTS = 1; const UINT D3D11_PS_CS_UAV_REGISTER_COUNT = 8; const UINT D3D11_PS_CS_UAV_REGISTER_READS_PER_INST = 1; @@ -228,6 +235,61 @@ D3D11_BLEND_OP_MAX } D3D11_BLEND_OP; +typedef enum D3D11_VIDEO_DECODER_BUFFER_TYPE +{ + D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS = 0, + D3D11_VIDEO_DECODER_BUFFER_MACROBLOCK_CONTROL = 1, + D3D11_VIDEO_DECODER_BUFFER_RESIDUAL_DIFFERENCE = 2, + D3D11_VIDEO_DECODER_BUFFER_DEBLOCKING_CONTROL = 3, + D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX = 4, + D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL = 5, + D3D11_VIDEO_DECODER_BUFFER_BITSTREAM = 6, + D3D11_VIDEO_DECODER_BUFFER_MOTION_VECTOR = 7, + D3D11_VIDEO_DECODER_BUFFER_FILM_GRAIN = 8, +} D3D11_VIDEO_DECODER_BUFFER_TYPE; + +typedef enum D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE +{ + D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_OPAQUE = 0, + D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_BACKGROUND = 1, + D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_DESTINATION = 2, + D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE_SOURCE_STREAM = 3, +} D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE; + +typedef enum D3D11_VIDEO_PROCESSOR_OUTPUT_RATE +{ + D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_NORMAL = 0, + D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_HALF = 1, + D3D11_VIDEO_PROCESSOR_OUTPUT_RATE_CUSTOM = 2, +} D3D11_VIDEO_PROCESSOR_OUTPUT_RATE; + +typedef enum D3D11_VIDEO_PROCESSOR_STEREO_FORMAT +{ + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_MONO = 0, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_HORIZONTAL = 1, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_VERTICAL = 2, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_SEPARATE = 3, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_MONO_OFFSET = 4, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_ROW_INTERLEAVED = 5, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_COLUMN_INTERLEAVED = 6, + D3D11_VIDEO_PROCESSOR_STEREO_FORMAT_CHECKERBOARD = 7, +} D3D11_VIDEO_PROCESSOR_STEREO_FORMAT; + +typedef enum D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE +{ + D3D11_VIDEO_PROCESSOR_STEREO_FLIP_NONE = 0, + D3D11_VIDEO_PROCESSOR_STEREO_FLIP_FRAME0 = 1, + D3D11_VIDEO_PROCESSOR_STEREO_FLIP_FRAME1 = 2, +} D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE; + +typedef enum D3D11_VIDEO_PROCESSOR_ROTATION +{ + D3D11_VIDEO_PROCESSOR_ROTATION_IDENTITY = 0, + D3D11_VIDEO_PROCESSOR_ROTATION_90 = 1, + D3D11_VIDEO_PROCESSOR_ROTATION_180 = 2, + D3D11_VIDEO_PROCESSOR_ROTATION_270 = 3, +} D3D11_VIDEO_PROCESSOR_ROTATION; + typedef struct D3D11_BOX { UINT left; @@ -954,7 +1016,11 @@ D3D11_FORMAT_SUPPORT_SHADER_GATHER = 0x00800000, D3D11_FORMAT_SUPPORT_BACK_BUFFER_CAST = 0x01000000, D3D11_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW = 0x02000000, - D3D11_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON = 0x04000000 + D3D11_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON = 0x04000000, + D3D11_FORMAT_SUPPORT_DECODER_OUTPUT = 0x08000000, + D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT = 0x10000000, + D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_INPUT = 0x20000000, + D3D11_FORMAT_SUPPORT_VIDEO_ENCODER = 0x40000000, } D3D11_FORMAT_SUPPORT; typedef enum D3D11_CLEAR_FLAG @@ -1086,6 +1152,72 @@ }; } D3D11_RENDER_TARGET_VIEW_DESC; +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D11_RENDER_TARGET_VIEW_DESC : public D3D11_RENDER_TARGET_VIEW_DESC {") +cpp_quote(" CD3D11_RENDER_TARGET_VIEW_DESC() {}") +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(D3D11_RTV_DIMENSION dim, DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN,") +cpp_quote(" UINT mip_slice = 0, UINT first_slice = 0, UINT array_size = -1) {") +cpp_quote(" Format = format;") +cpp_quote(" ViewDimension = dim;") +cpp_quote(" switch(dim) {") +cpp_quote(" case D3D11_RTV_DIMENSION_BUFFER:") +cpp_quote(" Buffer.FirstElement = mip_slice;") +cpp_quote(" Buffer.NumElements = first_slice;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE1D:") +cpp_quote(" Texture1D.MipSlice = mip_slice;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:") +cpp_quote(" Texture1DArray.MipSlice = mip_slice;") +cpp_quote(" Texture1DArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture1DArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE2D:") +cpp_quote(" Texture2D.MipSlice = mip_slice;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:") +cpp_quote(" Texture2DArray.MipSlice = mip_slice;") +cpp_quote(" Texture2DArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture2DArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:") +cpp_quote(" Texture2DMSArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture2DMSArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_RTV_DIMENSION_TEXTURE3D:") +cpp_quote(" Texture3D.MipSlice = mip_slice;") +cpp_quote(" Texture3D.FirstWSlice = first_slice;") +cpp_quote(" Texture3D.WSize = array_size;") +cpp_quote(" break;") +cpp_quote(" default:") +cpp_quote(" break;") +cpp_quote(" }") +cpp_quote(" }") +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(ID3D11Buffer*, DXGI_FORMAT format, UINT first_elem,") +cpp_quote(" UINT elem_cnt) {") +cpp_quote(" Format = format;") +cpp_quote(" ViewDimension = D3D11_RTV_DIMENSION_BUFFER;") +cpp_quote(" Buffer.FirstElement = first_elem;") +cpp_quote(" Buffer.NumElements = elem_cnt;") +cpp_quote(" }") +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(ID3D11Texture1D *texture, D3D11_RTV_DIMENSION dim,") +cpp_quote(" DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, UINT mip_slice = 0, UINT first_slice = 0,") +cpp_quote(" UINT array_size = -1);") /* FIXME: implement */ +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(ID3D11Texture2D *texture, D3D11_RTV_DIMENSION dim,") +cpp_quote(" DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, UINT mip_slice = 0, UINT first_slice = 0,") +cpp_quote(" UINT array_size = -1);") /* FIXME: implement */ +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(ID3D11Texture3D *texture, DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN,") +cpp_quote(" UINT mip_slice = 0, UINT first_w_slice = 0, UINT w_slice = -1 );") /* FIXME: implement */ +cpp_quote(" ~CD3D11_RENDER_TARGET_VIEW_DESC() {}") +cpp_quote(" explicit CD3D11_RENDER_TARGET_VIEW_DESC(const D3D11_RENDER_TARGET_VIEW_DESC &other)") +cpp_quote(" : D3D11_RENDER_TARGET_VIEW_DESC(other) {}") +cpp_quote(" operator const D3D11_RENDER_TARGET_VIEW_DESC&() const {") +cpp_quote(" return *this;") +cpp_quote(" }") +cpp_quote("};") +cpp_quote("#endif") + + typedef struct D3D11_SAMPLER_DESC { D3D11_FILTER Filter; @@ -1164,6 +1296,85 @@ }; } D3D11_SHADER_RESOURCE_VIEW_DESC; +cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined( __cplusplus )") +cpp_quote("struct CD3D11_SHADER_RESOURCE_VIEW_DESC : public D3D11_SHADER_RESOURCE_VIEW_DESC {") +cpp_quote(" CD3D11_SHADER_RESOURCE_VIEW_DESC() {}") +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(D3D11_SRV_DIMENSION dim,") +cpp_quote(" DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, UINT most_detailed_mip = 0,") +cpp_quote(" UINT mip_levels = -1, UINT first_slice = 0, UINT array_size = -1, UINT flags = 0) {") +cpp_quote(" Format = format;") +cpp_quote(" ViewDimension = dim;") +cpp_quote(" switch(ViewDimension) {") +cpp_quote(" case D3D11_SRV_DIMENSION_BUFFER:") +cpp_quote(" Buffer.FirstElement = most_detailed_mip;") +cpp_quote(" Buffer.NumElements = mip_levels;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE1D:") +cpp_quote(" Texture1D.MostDetailedMip = most_detailed_mip;") +cpp_quote(" Texture1D.MipLevels = mip_levels;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:") +cpp_quote(" Texture1DArray.MostDetailedMip = most_detailed_mip;") +cpp_quote(" Texture1DArray.MipLevels = mip_levels;") +cpp_quote(" Texture1DArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture1DArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE2D:") +cpp_quote(" Texture2D.MostDetailedMip = most_detailed_mip;") +cpp_quote(" Texture2D.MipLevels = mip_levels;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:") +cpp_quote(" Texture2DArray.MostDetailedMip = most_detailed_mip;") +cpp_quote(" Texture2DArray.MipLevels = mip_levels;") +cpp_quote(" Texture2DArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture2DArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:") +cpp_quote(" Texture2DMSArray.FirstArraySlice = first_slice;") +cpp_quote(" Texture2DMSArray.ArraySize = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURE3D:") +cpp_quote(" Texture3D.MostDetailedMip = most_detailed_mip;") +cpp_quote(" Texture3D.MipLevels = mip_levels;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURECUBE:") +cpp_quote(" TextureCube.MostDetailedMip = most_detailed_mip;") +cpp_quote(" TextureCube.MipLevels = mip_levels;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY:") +cpp_quote(" TextureCubeArray.MostDetailedMip = most_detailed_mip;") +cpp_quote(" TextureCubeArray.MipLevels = mip_levels;") +cpp_quote(" TextureCubeArray.First2DArrayFace = first_slice;") +cpp_quote(" TextureCubeArray.NumCubes = array_size;") +cpp_quote(" break;") +cpp_quote(" case D3D11_SRV_DIMENSION_BUFFEREX:") +cpp_quote(" BufferEx.FirstElement = most_detailed_mip;") +cpp_quote(" BufferEx.NumElements = mip_levels;") +cpp_quote(" BufferEx.Flags = flags;") +cpp_quote(" break;") +cpp_quote(" default:") +cpp_quote(" break;") +cpp_quote(" }") +cpp_quote(" }") +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(ID3D11Buffer*, DXGI_FORMAT format, UINT first_elem,") +cpp_quote(" UINT elem_cnt, UINT flags = 0);") /* FIXME: implement */ +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(ID3D11Texture1D *texture, D3D11_SRV_DIMENSION dim,") +cpp_quote(" DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, UINT most_detailed_mip = 0, UINT mip_levels = -1,") +cpp_quote(" UINT first_slice = 0, UINT array_size = -1 );") /* FIXME: implement */ +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(ID3D11Texture2D *texture, D3D11_SRV_DIMENSION dim,") +cpp_quote(" DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, UINT most_detailed_mip = 0, UINT mip_levels = -1,") +cpp_quote(" UINT first_slice = 0, UINT array_size = -1 );") /* FIXME: implement */ +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(ID3D11Texture3D *texture, DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN,") +cpp_quote(" UINT most_detailed_mip = 0, UINT mip_levels = -1 );") +cpp_quote(" ~CD3D11_SHADER_RESOURCE_VIEW_DESC() {}") +cpp_quote(" explicit CD3D11_SHADER_RESOURCE_VIEW_DESC(const D3D11_SHADER_RESOURCE_VIEW_DESC &other)") +cpp_quote(" : D3D11_SHADER_RESOURCE_VIEW_DESC(other) {}") +cpp_quote(" operator const D3D11_SHADER_RESOURCE_VIEW_DESC&() const {") +cpp_quote(" return *this;") +cpp_quote(" }") +cpp_quote("};") +cpp_quote("#endif") + typedef struct D3D11_TEXTURE1D_DESC { UINT Width; @@ -1417,9 +1628,105 @@ ULONGLONG ProtectedMemorySize; } D3D11_VIDEO_CONTENT_PROTECTION_CAPS; -/* A couple forward declarations are needed */ -interface ID3D11Device; -interface ID3D11ClassLinkage; +typedef struct D3D11_ENCRYPTED_BLOCK_INFO +{ + UINT NumEncryptedBytesAtBeginning; + UINT NumBytesInSkipPattern; + UINT NumBytesInEncryptPattern; +} D3D11_ENCRYPTED_BLOCK_INFO; + +typedef struct D3D11_VIDEO_DECODER_BUFFER_DESC +{ + D3D11_VIDEO_DECODER_BUFFER_TYPE BufferType; + UINT BufferIndex; + UINT DataOffset; + UINT DataSize; + UINT FirstMBaddress; + UINT NumMBsInBuffer; + UINT Width; + UINT Height; + UINT Stride; + UINT ReservedBits; + void *pIV; + UINT IVSize; + BOOL PartialEncryption; + D3D11_ENCRYPTED_BLOCK_INFO EncryptedBlockInfo; +} D3D11_VIDEO_DECODER_BUFFER_DESC; + +typedef struct D3D11_VIDEO_DECODER_EXTENSION +{ + UINT Function; + void *pPrivateInputData; + UINT PrivateInputDataSize; + void *pPrivateOutputData; + UINT PrivateOutputDataSize; + UINT ResourceCount; + ID3D11Resource **ppResourceList; +} D3D11_VIDEO_DECODER_EXTENSION; + +typedef struct D3D11_VIDEO_COLOR_YCbCrA +{ + float Y; + float Cb; + float Cr; + float A; +} D3D11_VIDEO_COLOR_YCbCrA; + +typedef struct D3D11_VIDEO_COLOR_RGBA +{ + float R; + float G; + float B; + float A; +} D3D11_VIDEO_COLOR_RGBA; + +typedef struct D3D11_VIDEO_COLOR +{ + union + { + D3D11_VIDEO_COLOR_YCbCrA YCbCr; + D3D11_VIDEO_COLOR_RGBA RGBA; + }; +} D3D11_VIDEO_COLOR; + +typedef struct D3D11_VIDEO_PROCESSOR_COLOR_SPACE +{ + UINT Usage : 1; + UINT RGB_Range : 1; + UINT YCbCr_Matrix : 1; + UINT YCbCr_xvYCC : 1; + UINT Nominal_Range : 2; + UINT Reserved : 26; +} D3D11_VIDEO_PROCESSOR_COLOR_SPACE; + +typedef struct D3D11_VIDEO_PROCESSOR_STREAM +{ + BOOL Enable; + UINT OutputIndex; + UINT InputFrameOrField; + UINT PastFrames; + UINT FutureFrames; + ID3D11VideoProcessorInputView **ppPastSurfaces; + ID3D11VideoProcessorInputView *pInputSurface; + ID3D11VideoProcessorInputView **ppFutureSurfaces; + ID3D11VideoProcessorInputView **ppPastSurfacesRight; + ID3D11VideoProcessorInputView *pInputSurfaceRight; + ID3D11VideoProcessorInputView **ppFutureSurfacesRight; +} D3D11_VIDEO_PROCESSOR_STREAM; + +typedef struct D3D11_OMAC +{ + BYTE Omac[D3D11_OMAC_SIZE]; +} D3D11_OMAC; + +typedef struct D3D11_AUTHENTICATED_CONFIGURE_OUTPUT +{ + D3D11_OMAC omac; + GUID ConfigureType; + HANDLE hChannel; + UINT SequenceNumber; + HRESULT ReturnCode; +} D3D11_AUTHENTICATED_CONFIGURE_OUTPUT; [ object, @@ -2371,6 +2678,352 @@ } [ + object, + uuid(61f21c45-3c0e-4a74-9cea-67100d9ad5e4), + local, + pointer_default(unique) +] +interface ID3D11VideoContext : ID3D11DeviceChild +{ + HRESULT GetDecoderBuffer( + [in] ID3D11VideoDecoder *decoder, + [in] D3D11_VIDEO_DECODER_BUFFER_TYPE type, + [out] UINT *buffer_size, + [out] void **buffer + ); + HRESULT ReleaseDecoderBuffer( + [in] ID3D11VideoDecoder *decoder, + [in] D3D11_VIDEO_DECODER_BUFFER_TYPE type + ); + HRESULT DecoderBeginFrame( + [in] ID3D11VideoDecoder *decoder, + [in] ID3D11VideoDecoderOutputView *view, + [in] UINT key_size, + [in] const void *key + ); + HRESULT DecoderEndFrame( + [in] ID3D11VideoDecoder *decoder + ); + HRESULT SubmitDecoderBuffers( + [in] ID3D11VideoDecoder *decoder, + [in] UINT buffers_count, + [in] const D3D11_VIDEO_DECODER_BUFFER_DESC *buffer_desc + ); + HRESULT DecoderExtension( + [in] ID3D11VideoDecoder *decoder, + [in] const D3D11_VIDEO_DECODER_EXTENSION *extension + ); + void VideoProcessorSetOutputTargetRect( + [in] ID3D11VideoProcessor *processor, + [in] BOOL enable, + [in] const RECT *rect + ); + void VideoProcessorSetOutputBackgroundColor( + [in] ID3D11VideoProcessor *processor, + [in] BOOL y_cb_cr, + [in] const D3D11_VIDEO_COLOR *color + ); + void VideoProcessorSetOutputColorSpace( + [in] ID3D11VideoProcessor *processor, + [in] const D3D11_VIDEO_PROCESSOR_COLOR_SPACE *color_space + ); + void VideoProcessorSetOutputAlphaFillMode( + [in] ID3D11VideoProcessor *processor, + [in] D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE alpha_fill_mode, + [in] UINT stream_idx + ); + void VideoProcessorSetOutputConstriction( + [in] ID3D11VideoProcessor *processor, + [in] BOOL enable, + [in] SIZE size + ); + void VideoProcessorSetOutputStereoMode( + [in] ID3D11VideoProcessor *processor, + [in] BOOL enable + ); + HRESULT VideoProcessorSetOutputExtension( + [in] ID3D11VideoProcessor *processor, + [in] const GUID *guid, + [in] UINT data_size, + [in] void *data + ); + void VideoProcessorGetOutputTargetRect( + [in] ID3D11VideoProcessor *processor, + [out] BOOL *enabled, + [out] RECT *rect + ); + void VideoProcessorGetOutputBackgroundColor( + [in] ID3D11VideoProcessor *processor, + [out] BOOL *y_cb_cr, + [out] D3D11_VIDEO_COLOR *color + ); + void VideoProcessorGetOutputColorSpace( + [in] ID3D11VideoProcessor *processor, + [out] D3D11_VIDEO_PROCESSOR_COLOR_SPACE *color_space + ); + void VideoProcessorGetOutputAlphaFillMode( + [in] ID3D11VideoProcessor *processor, + [out] D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE *alpha_fill_mode, + [out] UINT *stream_idx + ); + void VideoProcessorGetOutputConstriction( + [in] ID3D11VideoProcessor *processor, + [out] BOOL *enabled, + [out] SIZE *size + ); + void VideoProcessorGetOutputStereoMode( + [in] ID3D11VideoProcessor *processor, + [out] BOOL *enabled + ); + HRESULT VideoProcessorGetOutputExtension( + [in] ID3D11VideoProcessor *processor, + [in] const GUID *guid, + [in] UINT data_size, + [out] void *data + ); + void VideoProcessorSetStreamFrameFormat( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] D3D11_VIDEO_FRAME_FORMAT format + ); + void VideoProcessorSetStreamColorSpace( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] const D3D11_VIDEO_PROCESSOR_COLOR_SPACE *color_space + ); + void VideoProcessorSetStreamOutputRate( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] D3D11_VIDEO_PROCESSOR_OUTPUT_RATE rate, + [in] BOOL repeat, + [in] const DXGI_RATIONAL *custom_rate + ); + void VideoProcessorSetStreamSourceRect( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] const RECT *rect + ); + void VideoProcessorSetStreamDestRect( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] const RECT *rect + ); + void VideoProcessorSetStreamAlpha( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] float alpha + ); + void VideoProcessorSetStreamPalette( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] UINT entry_count, + [in] const UINT *entries + ); + void VideoProcessorSetStreamPixelAspectRatio( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] const DXGI_RATIONAL *src_aspect_ratio, + [in] const DXGI_RATIONAL *dst_aspect_ratio + ); + void VideoProcessorSetStreamLumaKey( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] float lower, + [in] float upper + ); + void VideoProcessorSetStreamStereoFormat( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] D3D11_VIDEO_PROCESSOR_STEREO_FORMAT format, + [in] BOOL left_view_frame0, + [in] BOOL base_view_frame0, + [in] D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE flip_mode, + [in] int mono_offset + ); + void VideoProcessorSetStreamAutoProcessingMode( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable + ); + void VideoProcessorSetStreamFilter( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] D3D11_VIDEO_PROCESSOR_FILTER filter, + [in] BOOL enable, + [in] int level + ); + HRESULT VideoProcessorSetStreamExtension( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] const GUID *guid, + [in] UINT data_size, + [in] void *data + ); + void VideoProcessorGetStreamFrameFormat( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] D3D11_VIDEO_FRAME_FORMAT *format + ); + void VideoProcessorGetStreamColorSpace( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] D3D11_VIDEO_PROCESSOR_COLOR_SPACE *color_space + ); + void VideoProcessorGetStreamOutputRate( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] D3D11_VIDEO_PROCESSOR_OUTPUT_RATE *rate, + [out] BOOL *repeat, + [out] DXGI_RATIONAL *custom_rate + ); + void VideoProcessorGetStreamSourceRect( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] RECT *rect + ); + void VideoProcessorGetStreamDestRect( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] RECT *rect + ); + void VideoProcessorGetStreamAlpha( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] float *alpha + ); + void VideoProcessorGetStreamPalette( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] UINT entry_count, + [out] UINT *entries + ); + void VideoProcessorGetStreamPixelAspectRatio( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] DXGI_RATIONAL *src_aspect_ratio, + [out] DXGI_RATIONAL *dst_aspect_ratio + ); + void VideoProcessorGetStreamLumaKey( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] float *lower, + [out] float *upper + ); + void VideoProcessorGetStreamStereoFormat( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled, + [out] D3D11_VIDEO_PROCESSOR_STEREO_FORMAT *format, + [out] BOOL *left_view_frame0, + [out] BOOL *base_view_frame0, + [out] D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE *flip_mode, + [out] int *mono_offset + ); + void VideoProcessorGetStreamAutoProcessingMode( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enabled + ); + void VideoProcessorGetStreamFilter( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] D3D11_VIDEO_PROCESSOR_FILTER filter, + [out] BOOL *enabled, + [out] int *level + ); + HRESULT VideoProcessorGetStreamExtension( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] const GUID *guid, + [in] UINT data_size, + [out] void *data + ); + HRESULT VideoProcessorBlt( + [in] ID3D11VideoProcessor *processor, + [in] ID3D11VideoProcessorOutputView *view, + [in] UINT frame_idx, + [in] UINT stream_count, + [in] const D3D11_VIDEO_PROCESSOR_STREAM *streams + ); + HRESULT NegotiateCryptoSessionKeyExchange( + [in] ID3D11CryptoSession *session, + [in] UINT data_size, + [in, out] void *data + ); + void EncryptionBlt( + [in] ID3D11CryptoSession *session, + [in] ID3D11Texture2D *src_surface, + [in] ID3D11Texture2D *dst_surface, + [in] UINT iv_size, + [in, out] void *iv + ); + void DecryptionBlt( + [in] ID3D11CryptoSession *session, + [in] ID3D11Texture2D *src_surface, + [in] ID3D11Texture2D *dst_surface, + [in] D3D11_ENCRYPTED_BLOCK_INFO *block_info, + [in] UINT key_size, + [in] const void *key, + [in] UINT iv_size, + [in, out] void *iv + ); + void StartSessionKeyRefresh( + [in] ID3D11CryptoSession *session, + [in] UINT random_number_size, + [out] void *random_number + ); + void FinishSessionKeyRefresh( + [in] ID3D11CryptoSession *session + ); + HRESULT GetEncryptionBltKey( + [in] ID3D11CryptoSession *session, + [in] UINT key_size, + [out] void *key + ); + HRESULT NegotiateAuthenticatedChannelKeyExchange( + [in] ID3D11AuthenticatedChannel *channel, + [in] UINT data_size, + [in, out] void *data + ); + HRESULT QueryAuthenticatedChannel( + [in] ID3D11AuthenticatedChannel *channel, + [in] UINT input_size, + [in] const void *input, + [in] UINT output_size, + [out] void *output + ); + HRESULT ConfigureAuthenticatedChannel( + [in] ID3D11AuthenticatedChannel *channel, + [in] UINT input_size, + [in] const void *input, + [out] D3D11_AUTHENTICATED_CONFIGURE_OUTPUT *output + ); + void VideoProcessorSetStreamRotation( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [in] BOOL enable, + [in] D3D11_VIDEO_PROCESSOR_ROTATION rotation + ); + void VideoProcessorGetStreamRotation( + [in] ID3D11VideoProcessor *processor, + [in] UINT stream_idx, + [out] BOOL *enable, + [out] D3D11_VIDEO_PROCESSOR_ROTATION *rotation + ); +} + +[ object, local, uuid(db6f6ddb-ac77-4e88-8253-819df9bbf140) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/d3d9types.h wine-staging-1.9.3~ubuntu12.04.1/include/d3d9types.h --- wine-staging-1.9.0~ubuntu12.04.1/include/d3d9types.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/d3d9types.h 2016-02-08 19:32:34.000000000 +0000 @@ -113,6 +113,14 @@ #define D3DUSAGE_AUTOGENMIPMAP __MSABI_LONG(0x00000400) #define D3DUSAGE_DMAP __MSABI_LONG(0x00004000) +/* Parts added with d3d9ex */ +#if !defined(D3D_DISABLE_9EX) +#define D3DUSAGE_RESTRICTED_CONTENT __MSABI_LONG(0x00000800) +#define D3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER __MSABI_LONG(0x00001000) +#define D3DUSAGE_RESTRICT_SHARED_RESOURCE __MSABI_LONG(0x00002000) +#define D3DUSAGE_TEXTAPI __MSABI_LONG(0x10000000) +#endif /* D3D_DISABLE_9EX */ + #define D3DUSAGE_QUERY_FILTER __MSABI_LONG(0x00020000) #define D3DUSAGE_QUERY_LEGACYBUMPMAP __MSABI_LONG(0x00008000) #define D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING __MSABI_LONG(0x00080000) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/d3dx9anim.h wine-staging-1.9.3~ubuntu12.04.1/include/d3dx9anim.h --- wine-staging-1.9.0~ubuntu12.04.1/include/d3dx9anim.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/d3dx9anim.h 2016-02-08 19:32:34.000000000 +0000 @@ -327,37 +327,37 @@ STDMETHOD_(UINT, GetNumAnimationSets)(THIS) PURE; STDMETHOD(GetAnimationSet)(THIS_ UINT index, ID3DXAnimationSet **anim_set) PURE; STDMETHOD(GetAnimationSetByName)(THIS_ const char *name, ID3DXAnimationSet **anim_set) PURE; - STDMETHOD(AdvanceTime)(THIS_ double time_delta, ID3DXAnimationCallbackHandler **callback_handler) PURE; + STDMETHOD(AdvanceTime)(THIS_ double time_delta, ID3DXAnimationCallbackHandler *callback_handler) PURE; STDMETHOD(ResetTime)(THIS) PURE; - STDMETHOD_(DOUBLE, GetTime)(THIS) PURE; + STDMETHOD_(double, GetTime)(THIS) PURE; STDMETHOD(SetTrackAnimationSet)(THIS_ UINT track, ID3DXAnimationSet *anim_set) PURE; STDMETHOD(GetTrackAnimationSet)(THIS_ UINT track, ID3DXAnimationSet **anim_set) PURE; - STDMETHOD(GetTrackPriority)(THIS_ UINT track, D3DXPRIORITY_TYPE *priority) PURE; - STDMETHOD(SetTrackSpeed)(THIS_ UINT track, FLOAT speed) PURE; - STDMETHOD(SetTrackWeight)(THIS_ UINT track, FLOAT weight) PURE; - STDMETHOD(SetTrackPosition)(THIS_ UINT track, DOUBLE position) PURE; + STDMETHOD(SetTrackPriority)(THIS_ UINT track, D3DXPRIORITY_TYPE priority) PURE; + STDMETHOD(SetTrackSpeed)(THIS_ UINT track, float speed) PURE; + STDMETHOD(SetTrackWeight)(THIS_ UINT track, float weight) PURE; + STDMETHOD(SetTrackPosition)(THIS_ UINT track, double position) PURE; STDMETHOD(SetTrackEnable)(THIS_ UINT track, BOOL enable) PURE; - STDMETHOD(SetTrackDesc)(THIS_ UINT track, LPD3DXTRACK_DESC desc) PURE; - STDMETHOD(GetTrackDesc)(THIS_ UINT track, LPD3DXTRACK_DESC desc) PURE; - STDMETHOD(SetPriorityBlend)(THIS_ FLOAT blend_weight) PURE; - STDMETHOD_(FLOAT, GetPriorityBlend)(THIS) PURE; - STDMETHOD_(D3DXEVENTHANDLE, KeyTrackSpeed)(THIS_ UINT track, FLOAT new_speed, - DOUBLE start_time, DOUBLE duration, D3DXTRANSITION_TYPE transition) PURE; - STDMETHOD_(D3DXEVENTHANDLE, KeyTrackWeight)(THIS_ UINT track, FLOAT new_weight, - DOUBLE start_time, DOUBLE duration, D3DXTRANSITION_TYPE transition) PURE; - STDMETHOD_(D3DXEVENTHANDLE, KeyTrackPosition)(THIS_ UINT track, DOUBLE new_position, DOUBLE start_time) PURE; - STDMETHOD_(D3DXEVENTHANDLE, KeyTrackEnable)(THIS_ UINT track, BOOL new_enable, DOUBLE start_time) PURE; - STDMETHOD_(D3DXEVENTHANDLE, KeyPriorityBlend)(THIS_ FLOAT new_blend_weight, - DOUBLE start_time, DOUBLE duration, D3DXTRANSITION_TYPE transition) PURE; + STDMETHOD(SetTrackDesc)(THIS_ UINT track, D3DXTRACK_DESC *desc) PURE; + STDMETHOD(GetTrackDesc)(THIS_ UINT track, D3DXTRACK_DESC *desc) PURE; + STDMETHOD(SetPriorityBlend)(THIS_ float blend_weight) PURE; + STDMETHOD_(float, GetPriorityBlend)(THIS) PURE; + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackSpeed)(THIS_ UINT track, float new_speed, + double start_time, double duration, D3DXTRANSITION_TYPE transition) PURE; + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackWeight)(THIS_ UINT track, float new_weight, + double start_time, double duration, D3DXTRANSITION_TYPE transition) PURE; + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackPosition)(THIS_ UINT track, double new_position, double start_time) PURE; + STDMETHOD_(D3DXEVENTHANDLE, KeyTrackEnable)(THIS_ UINT track, BOOL new_enable, double start_time) PURE; + STDMETHOD_(D3DXEVENTHANDLE, KeyPriorityBlend)(THIS_ float new_blend_weight, + double start_time, double duration, D3DXTRANSITION_TYPE transition) PURE; STDMETHOD(UnkeyEvent)(THIS_ D3DXEVENTHANDLE event) PURE; STDMETHOD(UnkeyAllTrackEvents)(THIS_ UINT track) PURE; STDMETHOD(UnkeyAllPriorityBlends)(THIS) PURE; STDMETHOD_(D3DXEVENTHANDLE, GetCurrentTrackEvent)(THIS_ UINT track, D3DXEVENT_TYPE event_type) PURE; STDMETHOD_(D3DXEVENTHANDLE, GetCurrentPriorityBlend)(THIS) PURE; STDMETHOD_(D3DXEVENTHANDLE, GetUpcomingTrackEvent)(THIS_ UINT track, D3DXEVENTHANDLE event) PURE; - STDMETHOD_(D3DXEVENTHANDLE, GetUpcomingPriorityBlend)(THIS_ D3DXEVENTHANDLE handle) PURE; + STDMETHOD_(D3DXEVENTHANDLE, GetUpcomingPriorityBlend)(THIS_ D3DXEVENTHANDLE event) PURE; STDMETHOD(ValidateEvent)(THIS_ D3DXEVENTHANDLE event) PURE; - STDMETHOD(GetEventDesc)(THIS_ D3DXEVENTHANDLE event, LPD3DXEVENT_DESC desc) PURE; + STDMETHOD(GetEventDesc)(THIS_ D3DXEVENTHANDLE event, D3DXEVENT_DESC *desc) PURE; STDMETHOD(CloneAnimationController)(THIS_ UINT max_num_anim_outputs, UINT max_num_anim_sets, UINT max_num_tracks, UINT max_num_events, ID3DXAnimationController **anim_controller) PURE; }; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/d3dx9effect.h wine-staging-1.9.3~ubuntu12.04.1/include/d3dx9effect.h --- wine-staging-1.9.0~ubuntu12.04.1/include/d3dx9effect.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/d3dx9effect.h 2016-02-08 19:32:34.000000000 +0000 @@ -425,6 +425,8 @@ ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors); #define D3DXCreateEffectCompilerFromResource WINELIB_NAME_AW(D3DXCreateEffectCompilerFromResource) +HRESULT WINAPI D3DXDisassembleEffect(ID3DXEffect *effect, BOOL enable_color_code, ID3DXBuffer **disassembly); + #ifdef __cplusplus } #endif diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/dbt.h wine-staging-1.9.3~ubuntu12.04.1/include/dbt.h --- wine-staging-1.9.0~ubuntu12.04.1/include/dbt.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/dbt.h 2016-02-08 19:32:34.000000000 +0000 @@ -30,6 +30,10 @@ # define DECL_WINELIB_DBT_TYPE_AW(type) typedef WINELIB_NAME_AW(type##_) type; #endif +#define DBT_DEVNODES_CHANGED 0x0007 +#define DBT_QUERYCHANGECONFIG 0x0017 +#define DBT_CONFIGCHANGED 0x0018 +#define DBT_CONFIGCHANGECANCELED 0x0019 #define DBT_NO_DISK_SPACE 0x0047 #define DBT_LOW_DISK_SPACE 0x0048 #define DBT_CONFIGMGPRIVATE 0x7FFF diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/ddk/ndis.h wine-staging-1.9.3~ubuntu12.04.1/include/ddk/ndis.h --- wine-staging-1.9.0~ubuntu12.04.1/include/ddk/ndis.h 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/ddk/ndis.h 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * ndis.h + * + * Copyright 2015 Austin English + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#ifndef _NDIS_ +#define _NDIS_ + +typedef void *NDIS_HANDLE, *PNDIS_HANDLE; +typedef int NDIS_STATUS, *PNDIS_STATUS; + +typedef struct _NDIS_SPIN_LOCK +{ + KSPIN_LOCK SpinLock; + KIRQL OldIrql; +} NDIS_SPIN_LOCK, *PNDIS_SPIN_LOCK; + +#define NDIS_STATUS_FAILURE ((NDIS_STATUS) STATUS_UNSUCCESSFUL) + +NDIS_STATUS WINAPI NdisAllocateMemoryWithTag(void **, UINT, ULONG); +void WINAPI NdisAllocateSpinLock(NDIS_SPIN_LOCK *); + +#endif /* _NDIS_ */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/gdiplusflat.h wine-staging-1.9.3~ubuntu12.04.1/include/gdiplusflat.h --- wine-staging-1.9.0~ubuntu12.04.1/include/gdiplusflat.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/gdiplusflat.h 2016-02-08 19:32:34.000000000 +0000 @@ -619,6 +619,7 @@ GpStatus WINGDIPAPI GdipGetPenDashOffset(GpPen*,REAL*); GpStatus WINGDIPAPI GdipGetPenDashStyle(GpPen*,GpDashStyle*); GpStatus WINGDIPAPI GdipGetPenMode(GpPen*,GpPenAlignment*); +GpStatus WINGDIPAPI GdipGetPenTransform(GpPen *, GpMatrix *); GpStatus WINGDIPAPI GdipResetPenTransform(GpPen*); GpStatus WINGDIPAPI GdipScalePenTransform(GpPen*,REAL,REAL,GpMatrixOrder); GpStatus WINGDIPAPI GdipSetPenBrushFill(GpPen*,GpBrush*); @@ -637,6 +638,7 @@ GpStatus WINGDIPAPI GdipSetPenMode(GpPen*,GpPenAlignment); GpStatus WINGDIPAPI GdipSetPenMiterLimit(GpPen*,REAL); GpStatus WINGDIPAPI GdipSetPenStartCap(GpPen*,GpLineCap); +GpStatus WINGDIPAPI GdipSetPenTransform(GpPen *, GpMatrix *); GpStatus WINGDIPAPI GdipSetPenWidth(GpPen*,REAL); GpStatus WINGDIPAPI GdipGetPenDashCap197819(GpPen*,GpDashCap*); GpStatus WINGDIPAPI GdipGetPenEndCap(GpPen*,GpLineCap*); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/include/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/include/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -276,6 +276,7 @@ ddk/hidtypes.h \ ddk/imm.h \ ddk/mountmgr.h \ + ddk/ndis.h \ ddk/ntddcdvd.h \ ddk/ntddk.h \ ddk/ntddser.h \ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/msvcrt/crtdefs.h wine-staging-1.9.3~ubuntu12.04.1/include/msvcrt/crtdefs.h --- wine-staging-1.9.0~ubuntu12.04.1/include/msvcrt/crtdefs.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/msvcrt/crtdefs.h 2016-02-08 19:32:34.000000000 +0000 @@ -44,7 +44,7 @@ #ifndef __stdcall # ifdef __i386__ # ifdef __GNUC__ -# ifdef __APPLE__ /* Mac OS X uses a 16-byte aligned stack and not a 4-byte one */ +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) || defined(__APPLE__) # define __stdcall __attribute__((__stdcall__)) __attribute__((__force_align_arg_pointer__)) # else # define __stdcall __attribute__((__stdcall__)) @@ -55,21 +55,29 @@ # error You need to define __stdcall for your compiler # endif # elif defined(__x86_64__) && defined (__GNUC__) -# define __stdcall __attribute__((ms_abi)) -# else +# if (__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3)) +# define __stdcall __attribute__((ms_abi)) __attribute__((__force_align_arg_pointer__)) +# else +# define __stdcall __attribute__((ms_abi)) +# endif +# else /* __i386__ */ # define __stdcall -# endif +# endif /* __i386__ */ #endif /* __stdcall */ #ifndef __cdecl # if defined(__i386__) && defined(__GNUC__) -# ifdef __APPLE__ /* Mac OS X uses 16-byte aligned stack and not a 4-byte one */ +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) || defined(__APPLE__) # define __cdecl __attribute__((__cdecl__)) __attribute__((__force_align_arg_pointer__)) # else # define __cdecl __attribute__((__cdecl__)) # endif # elif defined(__x86_64__) && defined (__GNUC__) -# define __cdecl __attribute__((ms_abi)) +# if (__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3)) +# define __cdecl __attribute__((ms_abi)) __attribute__((__force_align_arg_pointer__)) +# else +# define __cdecl __attribute__((ms_abi)) +# endif # elif !defined(_MSC_VER) # define __cdecl # endif diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/ntddndis.h wine-staging-1.9.3~ubuntu12.04.1/include/ntddndis.h --- wine-staging-1.9.0~ubuntu12.04.1/include/ntddndis.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/ntddndis.h 2016-02-08 19:32:34.000000000 +0000 @@ -57,6 +57,62 @@ #define IOCTL_NDIS_RESERVED12 _NDIS_CONTROL_CODE(0x14, METHOD_BUFFERED) #define IOCTL_NDIS_RESERVED13 _NDIS_CONTROL_CODE(0x15, METHOD_BUFFERED) +#define OID_GEN_SUPPORTED_LIST 0x00010101 +#define OID_GEN_HARDWARE_STATUS 0x00010102 +#define OID_GEN_MEDIA_SUPPORTED 0x00010103 +#define OID_GEN_MEDIA_IN_USE 0x00010104 +#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 +#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 +#define OID_GEN_LINK_SPEED 0x00010107 +#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 +#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 +#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010a +#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010b +#define OID_GEN_VENDOR_ID 0x0001010c +#define OID_GEN_VENDOR_DESCRIPTION 0x0001010d +#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010e +#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010f +#define OID_GEN_DRIVER_VERSION 0x00010110 +#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 +#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 +#define OID_GEN_MAC_OPTIONS 0x00010113 +#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 +#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 + +#define OID_802_3_PERMANENT_ADDRESS 0x01010101 +#define OID_802_3_CURRENT_ADDRESS 0x01010102 +#define OID_802_3_MULTICAST_LIST 0x01010103 +#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 +#define OID_802_3_MAC_OPTIONS 0x01010105 +#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 +#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 +#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 +#define OID_802_3_XMIT_DEFERRED 0x01020201 +#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 +#define OID_802_3_RCV_OVERRUN 0x01020203 +#define OID_802_3_XMIT_UNDERRUN 0x01020204 +#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 +#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 +#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 +#define OID_802_3_ADD_MULTICAST_ADDRESS 0x01010208 +#define OID_802_3_DELETE_MULTICAST_ADDRESS 0x01010209 + +#define OID_802_5_PERMANENT_ADDRESS 0x02010101 +#define OID_802_5_CURRENT_ADDRESS 0x02010102 +#define OID_802_5_CURRENT_FUNCTIONAL 0x02010103 +#define OID_802_5_CURRENT_GROUP 0x02010104 +#define OID_802_5_LAST_OPEN_STATUS 0x02010105 +#define OID_802_5_CURRENT_RING_STATUS 0x02010106 +#define OID_802_5_CURRENT_RING_STATE 0x02010107 +#define OID_802_5_LINE_ERRORS 0x02020101 +#define OID_802_5_LOST_FRAMES 0x02020102 +#define OID_802_5_BURST_ERRORS 0x02020201 +#define OID_802_5_AC_ERRORS 0x02020202 +#define OID_802_5_ABORT_DELIMETERS 0x02020203 +#define OID_802_5_FRAME_COPIED_ERRORS 0x02020204 +#define OID_802_5_FREQUENCY_ERRORS 0x02020205 +#define OID_802_5_TOKEN_ERRORS 0x02020206 +#define OID_802_5_INTERNAL_ERRORS 0x02020207 #define OID_802_11_BSSID 0x0d010101 #define OID_802_11_SSID 0x0d010102 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/objbase.h wine-staging-1.9.3~ubuntu12.04.1/include/objbase.h --- wine-staging-1.9.0~ubuntu12.04.1/include/objbase.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/objbase.h 2016-02-08 19:32:34.000000000 +0000 @@ -304,9 +304,9 @@ HRESULT WINAPI CoGetInstanceFromIStorage(COSERVERINFO* pServerInfo, CLSID* pClsid, IUnknown* punkOuter, DWORD dwClsCtx, IStorage* pstg, DWORD dwCount, MULTI_QI* pResults); HRESULT WINAPI CoGetMalloc(DWORD dwMemContext, LPMALLOC* lpMalloc); -LPVOID WINAPI CoTaskMemAlloc(ULONG size) __WINE_ALLOC_SIZE(1); +LPVOID WINAPI CoTaskMemAlloc(SIZE_T size) __WINE_ALLOC_SIZE(1); void WINAPI CoTaskMemFree(LPVOID ptr); -LPVOID WINAPI CoTaskMemRealloc(LPVOID ptr, ULONG size); +LPVOID WINAPI CoTaskMemRealloc(LPVOID ptr, SIZE_T size); HRESULT WINAPI CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy); HRESULT WINAPI CoRevokeMallocSpy(void); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/objidl.idl wine-staging-1.9.3~ubuntu12.04.1/include/objidl.idl --- wine-staging-1.9.0~ubuntu12.04.1/include/objidl.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/objidl.idl 2016-02-08 19:32:34.000000000 +0000 @@ -162,16 +162,16 @@ typedef [unique] IMalloc *LPMALLOC; LPVOID Alloc( - [in] ULONG cb); + [in] SIZE_T cb); LPVOID Realloc( [in] LPVOID pv, - [in] ULONG cb); + [in] SIZE_T cb); void Free( [in] LPVOID pv); - ULONG GetSize( + SIZE_T GetSize( [in] LPVOID pv); int DidAlloc(LPVOID pv); @@ -188,8 +188,8 @@ { typedef [unique] IMallocSpy *LPMALLOCSPY; - ULONG PreAlloc( - [in] ULONG cbRequest); + SIZE_T PreAlloc( + [in] SIZE_T cbRequest); LPVOID PostAlloc( [in] LPVOID pActual); @@ -201,9 +201,9 @@ void PostFree( [in] BOOL fSpyed); - ULONG PreRealloc( + SIZE_T PreRealloc( [in] LPVOID pRequest, - [in] ULONG cbRequest, + [in] SIZE_T cbRequest, [out] LPVOID *ppNewRequest, [in] BOOL fSpyed); @@ -215,8 +215,8 @@ [in] LPVOID pRequest, [in] BOOL fSpyed); - ULONG PostGetSize( - [in] ULONG cbActual, + SIZE_T PostGetSize( + [in] SIZE_T cbActual, [in] BOOL fSpyed); LPVOID PreDidAlloc( diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/oleidl.idl wine-staging-1.9.3~ubuntu12.04.1/include/oleidl.idl --- wine-staging-1.9.0~ubuntu12.04.1/include/oleidl.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/oleidl.idl 2016-02-08 19:32:34.000000000 +0000 @@ -956,3 +956,18 @@ [in] POINTL pt, [in, out] DWORD *pdwEffect); } + +/***************************************************************************** + * IDropSourceNotify interface + */ +[ + object, + uuid(0000012b-0000-0000-c000-000000000046), + pointer_default(unique), + local +] +interface IDropSourceNotify : IUnknown +{ + HRESULT DragTargetEnter( [in] HWND hwnd ); + HRESULT DragTargetLeave( void ); +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/pdh.h wine-staging-1.9.3~ubuntu12.04.1/include/pdh.h --- wine-staging-1.9.0~ubuntu12.04.1/include/pdh.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/pdh.h 2016-02-08 19:32:34.000000000 +0000 @@ -200,6 +200,9 @@ PDH_STATUS WINAPI PdhAddEnglishCounterA(PDH_HQUERY, LPCSTR, DWORD_PTR, PDH_HCOUNTER *); PDH_STATUS WINAPI PdhAddEnglishCounterW(PDH_HQUERY, LPCWSTR, DWORD_PTR, PDH_HCOUNTER *); #define PdhAddEnglishCounter WINELIB_NAME_AW(PdhAddEnglishCounter) +PDH_STATUS WINAPI PdhBindInputDataSourceA(PDH_HLOG *, const char *); +PDH_STATUS WINAPI PdhBindInputDataSourceW(PDH_HLOG *, const WCHAR *); +#define PdhBindInputDataSource WINELIB_NAME_AW(PdhBindInputDataSource) PDH_STATUS WINAPI PdhCloseQuery(PDH_HQUERY); PDH_STATUS WINAPI PdhCollectQueryData(PDH_HQUERY); PDH_STATUS WINAPI PdhCollectQueryDataEx(PDH_HQUERY, DWORD, HANDLE); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/ras.h wine-staging-1.9.3~ubuntu12.04.1/include/ras.h --- wine-staging-1.9.0~ubuntu12.04.1/include/ras.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/ras.h 2016-02-08 19:32:34.000000000 +0000 @@ -493,6 +493,9 @@ DWORD WINAPI RasSetAutodialParamA(DWORD,LPVOID,DWORD); DWORD WINAPI RasSetAutodialParamW(DWORD,LPVOID,DWORD); #define RasSetAutodialParam WINELIB_NAME_AW(RasSetAutodialParam) +DWORD WINAPI RasSetCustomAuthDataA(const CHAR *,const CHAR *,BYTE *,DWORD); +DWORD WINAPI RasSetCustomAuthDataW(const WCHAR *,const WCHAR *,BYTE *,DWORD); +#define RasSetCustomAuthData WINELIB_NAME_AW(RasSetCustomAuthData) DWORD WINAPI RasSetEntryDialParamsA(LPCSTR,LPRASDIALPARAMSA,BOOL); DWORD WINAPI RasSetEntryDialParamsW(LPCWSTR,LPRASDIALPARAMSW,BOOL); #define RasSetEntryDialParams WINELIB_NAME_AW(RasSetEntryDialParams) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/shlwapi.h wine-staging-1.9.3~ubuntu12.04.1/include/shlwapi.h --- wine-staging-1.9.0~ubuntu12.04.1/include/shlwapi.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/shlwapi.h 2016-02-08 19:32:34.000000000 +0000 @@ -646,6 +646,7 @@ #define URL_UNESCAPE_INPLACE 0x00100000 #define URL_FILE_USE_PATHURL 0x00010000 +#define URL_ESCAPE_AS_UTF8 0x00040000 #define URL_ESCAPE_SEGMENT_ONLY 0x00002000 #define URL_ESCAPE_PERCENT 0x00001000 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/tchar.h wine-staging-1.9.3~ubuntu12.04.1/include/tchar.h --- wine-staging-1.9.0~ubuntu12.04.1/include/tchar.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/tchar.h 2016-02-08 19:32:34.000000000 +0000 @@ -23,8 +23,8 @@ #error Wine should not include tchar.h internally #endif -#if defined(_UNICODE) || defined(_MBCS) -#error You must use msvcrt when building in Unicode/MBCS mode +#if !defined(__MSVCRT__) && (defined(_UNICODE) || defined(_MBCS)) +#error You must use msvcrt when building in Unicode/MBCS mode [-mno-cygwin] #endif #ifdef __cplusplus diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/webservices.h wine-staging-1.9.3~ubuntu12.04.1/include/webservices.h --- wine-staging-1.9.0~ubuntu12.04.1/include/webservices.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/webservices.h 2016-02-08 19:32:34.000000000 +0000 @@ -290,6 +290,55 @@ WS_WRITE_NILLABLE_POINTER = 4 } WS_WRITE_OPTION; +typedef struct _WS_BOOL_DESCRIPTION { + BOOL value; +} WS_BOOL_DESCRIPTION; + +typedef struct _WS_INT8_DESCRIPTION { + char minValue; + char maxValue; +} WS_INT8_DESCRIPTION; + +typedef struct _WS_INT16_DESCRIPTION { + short minValue; + short maxValue; +} WS_INT16_DESCRIPTION; + +typedef struct _WS_INT32_DESCRIPTION { + int minValue; + int maxValue; +} WS_INT32_DESCRIPTION; + +typedef struct _WS_INT64_DESCRIPTION { + __int64 minValue; + __int64 maxValue; +} WS_INT64_DESCRIPTION; + +typedef struct _WS_UINT8_DESCRIPTION { + BYTE minValue; + BYTE maxValue; +} WS_UINT8_DESCRIPTION; + +typedef struct _WS_UINT16_DESCRIPTION { + USHORT minValue; + USHORT maxValue; +} WS_UINT16_DESCRIPTION; + +typedef struct _WS_UINT32_DESCRIPTION { + ULONG minValue; + ULONG maxValue; +} WS_UINT32_DESCRIPTION; + +typedef struct _WS_UINT64_DESCRIPTION { + unsigned __int64 minValue; + unsigned __int64 maxValue; +} WS_UINT64_DESCRIPTION; + +typedef struct _WS_WSZ_DESCRIPTION { + ULONG minCharCount; + ULONG maxCharCount; +} WS_WSZ_DESCRIPTION; + typedef enum { WS_TYPE_ATTRIBUTE_FIELD_MAPPING, WS_ATTRIBUTE_FIELD_MAPPING, @@ -367,6 +416,13 @@ void *typeDescription; } WS_ATTRIBUTE_DESCRIPTION; +typedef struct _WS_ELEMENT_DESCRIPTION { + WS_XML_STRING *elementLocalName; + WS_XML_STRING *elementNs; + WS_TYPE type; + void *typeDescription; +} WS_ELEMENT_DESCRIPTION; + typedef struct _WS_STRING { ULONG length; WCHAR *chars; @@ -430,6 +486,25 @@ WS_XML_STRING value; } WS_XML_UTF8_TEXT; +typedef enum { + WS_BOOL_VALUE_TYPE, + WS_INT8_VALUE_TYPE, + WS_INT16_VALUE_TYPE, + WS_INT32_VALUE_TYPE, + WS_INT64_VALUE_TYPE, + WS_UINT8_VALUE_TYPE, + WS_UINT16_VALUE_TYPE, + WS_UINT32_VALUE_TYPE, + WS_UINT64_VALUE_TYPE, + WS_FLOAT_VALUE_TYPE, + WS_DOUBLE_VALUE_TYPE, + WS_DECIMAL_VALUE_TYPE, + WS_DATETIME_VALUE_TYPE, + WS_TIMESPAN_VALUE_TYPE, + WS_GUID_VALUE_TYPE, + WS_DURATION_VALUE_TYPE +} WS_VALUE_TYPE; + typedef struct _WS_XML_ATTRIBUTE { BYTE singleQuote; BYTE isXmlNs; @@ -491,6 +566,7 @@ HRESULT WINAPI WsMoveWriter(WS_XML_WRITER*, WS_MOVE_TO, BOOL*, WS_ERROR*); HRESULT WINAPI WsReadAttribute(WS_XML_READER*, const WS_ATTRIBUTE_DESCRIPTION*, WS_READ_OPTION, WS_HEAP*, void*, ULONG, WS_ERROR*); +HRESULT WINAPI WsReadEndAttribute(WS_XML_READER*, WS_ERROR*); HRESULT WINAPI WsReadEndElement(WS_XML_READER*, WS_ERROR*); HRESULT WINAPI WsReadNode(WS_XML_READER*, WS_ERROR*); HRESULT WINAPI WsReadStartAttribute(WS_XML_READER*, ULONG, WS_ERROR*); @@ -508,16 +584,28 @@ const WS_XML_WRITER_PROPERTY*, ULONG, WS_ERROR*); HRESULT WINAPI WsSetOutputToBuffer(WS_XML_WRITER*, WS_XML_BUFFER*, const WS_XML_WRITER_PROPERTY*, ULONG, WS_ERROR*); +HRESULT WINAPI WsSkipNode(WS_XML_READER*, WS_ERROR*); +HRESULT WINAPI WsWriteAttribute(WS_XML_WRITER*, const WS_ATTRIBUTE_DESCRIPTION*, WS_WRITE_OPTION, + const void*, ULONG, WS_ERROR*); +HRESULT WINAPI WsWriteElement(WS_XML_WRITER*, const WS_ELEMENT_DESCRIPTION*, WS_WRITE_OPTION, + const void*, ULONG, WS_ERROR*); HRESULT WINAPI WsWriteEndAttribute(WS_XML_WRITER*, WS_ERROR*); +HRESULT WINAPI WsWriteEndCData(WS_XML_WRITER*, WS_ERROR*); HRESULT WINAPI WsWriteEndElement(WS_XML_WRITER*, WS_ERROR*); HRESULT WINAPI WsWriteEndStartElement(WS_XML_WRITER*, WS_ERROR*); HRESULT WINAPI WsWriteStartAttribute(WS_XML_WRITER*, const WS_XML_STRING*, const WS_XML_STRING*, const WS_XML_STRING*, BOOL, WS_ERROR*); +HRESULT WINAPI WsWriteStartCData(WS_XML_WRITER*, WS_ERROR*); HRESULT WINAPI WsWriteStartElement(WS_XML_WRITER*, const WS_XML_STRING*, const WS_XML_STRING*, const WS_XML_STRING*, WS_ERROR*); HRESULT WINAPI WsWriteText(WS_XML_WRITER*, const WS_XML_TEXT*, WS_ERROR*); HRESULT WINAPI WsWriteType(WS_XML_WRITER*, WS_TYPE_MAPPING, WS_TYPE, const void*, WS_WRITE_OPTION, const void*, ULONG, WS_ERROR*); +HRESULT WINAPI WsWriteValue(WS_XML_WRITER*, WS_VALUE_TYPE, const void*, ULONG, WS_ERROR*); +HRESULT WINAPI WsWriteXmlBuffer(WS_XML_WRITER*, WS_XML_BUFFER*, WS_ERROR*); +HRESULT WINAPI WsWriteXmlBufferToBytes(WS_XML_WRITER*, WS_XML_BUFFER*, const WS_XML_WRITER_ENCODING*, + const WS_XML_WRITER_PROPERTY*, ULONG, WS_HEAP*, void**, + ULONG*, WS_ERROR*); HRESULT WINAPI WsXmlStringEquals(const WS_XML_STRING*, const WS_XML_STRING*, WS_ERROR*); #define WS_S_ASYNC 0x003d0000 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/winbase.h wine-staging-1.9.3~ubuntu12.04.1/include/winbase.h --- wine-staging-1.9.0~ubuntu12.04.1/include/winbase.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/winbase.h 2016-02-08 19:32:34.000000000 +0000 @@ -2545,6 +2545,7 @@ WINBASEAPI BOOLEAN WINAPI TryAcquireSRWLockExclusive(PSRWLOCK); WINBASEAPI BOOLEAN WINAPI TryAcquireSRWLockShared(PSRWLOCK); WINBASEAPI BOOL WINAPI TryEnterCriticalSection(CRITICAL_SECTION *lpCrit); +WINBASEAPI BOOL WINAPI TrySubmitThreadpoolCallback(PTP_SIMPLE_CALLBACK,void*,TP_CALLBACK_ENVIRON*); WINBASEAPI BOOL WINAPI TzSpecificLocalTimeToSystemTime(const TIME_ZONE_INFORMATION*,const SYSTEMTIME*,LPSYSTEMTIME); WINBASEAPI LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS); WINBASEAPI BOOL WINAPI UnlockFile(HANDLE,DWORD,DWORD,DWORD,DWORD); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/windef.h wine-staging-1.9.3~ubuntu12.04.1/include/windef.h --- wine-staging-1.9.0~ubuntu12.04.1/include/windef.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/windef.h 2016-02-08 19:32:34.000000000 +0000 @@ -64,7 +64,11 @@ # error You need to define __stdcall for your compiler # endif # elif defined(__x86_64__) && defined (__GNUC__) -# define __stdcall __attribute__((ms_abi)) +# if (__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3)) +# define __stdcall __attribute__((ms_abi)) __attribute__((__force_align_arg_pointer__)) +# else +# define __stdcall __attribute__((ms_abi)) +# endif # else /* __i386__ */ # define __stdcall # endif /* __i386__ */ @@ -78,7 +82,11 @@ # define __cdecl __attribute__((__cdecl__)) # endif # elif defined(__x86_64__) && defined (__GNUC__) -# define __cdecl __attribute__((ms_abi)) +# if (__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 3)) +# define __cdecl __attribute__((ms_abi)) __attribute__((__force_align_arg_pointer__)) +# else +# define __cdecl __attribute__((ms_abi)) +# endif # elif !defined(_MSC_VER) # define __cdecl # endif diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/wine/server_protocol.h wine-staging-1.9.3~ubuntu12.04.1/include/wine/server_protocol.h --- wine-staging-1.9.0~ubuntu12.04.1/include/wine/server_protocol.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/wine/server_protocol.h 2016-02-08 19:32:34.000000000 +0000 @@ -377,8 +377,9 @@ struct object_attributes { obj_handle_t rootdir; - data_size_t sd_len; - data_size_t name_len; + unsigned int attributes; + data_size_t sd_len; + data_size_t name_len; }; @@ -1157,11 +1158,9 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; int manual_reset; int initial_state; /* VARARG(objattr,object_attributes); */ - char __pad_28[4]; }; struct create_event_reply { @@ -1218,9 +1217,7 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; /* VARARG(objattr,object_attributes); */ - char __pad_20[4]; }; struct create_keyed_event_reply { @@ -1251,9 +1248,9 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; int owned; /* VARARG(objattr,object_attributes); */ + char __pad_20[4]; }; struct create_mutex_reply { @@ -1299,11 +1296,9 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; unsigned int initial; unsigned int max; /* VARARG(objattr,object_attributes); */ - char __pad_28[4]; }; struct create_semaphore_reply { @@ -1362,14 +1357,12 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; unsigned int sharing; int create; unsigned int options; unsigned int attrs; /* VARARG(objattr,object_attributes); */ /* VARARG(filename,string); */ - char __pad_36[4]; }; struct create_file_reply { @@ -2105,8 +2098,8 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; unsigned int protect; + char __pad_20[4]; mem_size_t size; obj_handle_t file_handle; /* VARARG(objattr,object_attributes); */ @@ -2400,13 +2393,11 @@ struct create_key_request { struct request_header __header; - obj_handle_t parent; unsigned int access; - unsigned int attributes; unsigned int options; - data_size_t namelen; - /* VARARG(name,unicode_str,namelen); */ + /* VARARG(objattr,object_attributes); */ /* VARARG(class,unicode_str); */ + char __pad_20[4]; }; struct create_key_reply { @@ -2550,10 +2541,8 @@ struct load_registry_request { struct request_header __header; - obj_handle_t hkey; obj_handle_t file; - /* VARARG(name,unicode_str); */ - char __pad_20[4]; + /* VARARG(objattr,object_attributes); */ }; struct load_registry_reply { @@ -2608,11 +2597,9 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; - obj_handle_t rootdir; int manual; - /* VARARG(name,unicode_str); */ - char __pad_28[4]; + /* VARARG(objattr,object_attributes); */ + char __pad_20[4]; }; struct create_timer_reply { @@ -3267,12 +3254,12 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; unsigned int options; unsigned int sharing; unsigned int maxinstances; unsigned int outsize; unsigned int insize; + char __pad_36[4]; timeout_t timeout; unsigned int flags; /* VARARG(objattr,object_attributes); */ @@ -3808,7 +3795,9 @@ unsigned int flags; unsigned int access; unsigned int attributes; + obj_handle_t rootdir; /* VARARG(name,unicode_str); */ + char __pad_28[4]; }; struct create_winstation_reply { @@ -3824,8 +3813,8 @@ struct request_header __header; unsigned int access; unsigned int attributes; + obj_handle_t rootdir; /* VARARG(name,unicode_str); */ - char __pad_20[4]; }; struct open_winstation_reply { @@ -4233,6 +4222,13 @@ #define SET_CARET_POS 0x01 #define SET_CARET_HIDE 0x02 #define SET_CARET_STATE 0x04 +enum caret_state +{ + CARET_STATE_OFF, + CARET_STATE_ON, + CARET_STATE_TOGGLE, + CARET_STATE_ON_IF_MOVED +}; @@ -4655,16 +4651,37 @@ }; +struct handle_info +{ + process_id_t owner; + obj_handle_t handle; + unsigned int access; +}; + + +struct get_system_handles_request +{ + struct request_header __header; + char __pad_12[4]; +}; +struct get_system_handles_reply +{ + struct reply_header __header; + unsigned int count; + /* VARARG(data,handle_infos); */ + char __pad_12[4]; +}; + + + struct create_mailslot_request { struct request_header __header; unsigned int access; - unsigned int attributes; - obj_handle_t rootdir; timeout_t read_timeout; unsigned int max_msgsize; - /* VARARG(name,unicode_str); */ - char __pad_36[4]; + /* VARARG(objattr,object_attributes); */ + char __pad_28[4]; }; struct create_mailslot_reply { @@ -4698,9 +4715,7 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; - obj_handle_t rootdir; - /* VARARG(directory_name,unicode_str); */ + /* VARARG(objattr,object_attributes); */ }; struct create_directory_reply { @@ -4750,12 +4765,8 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; - obj_handle_t rootdir; - data_size_t name_len; - /* VARARG(name,unicode_str,name_len); */ + /* VARARG(objattr,object_attributes); */ /* VARARG(target_name,unicode_str); */ - char __pad_28[4]; }; struct create_symlink_reply { @@ -4974,11 +4985,9 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; unsigned int concurrent; - obj_handle_t rootdir; - /* VARARG(filename,unicode_str); */ - char __pad_28[4]; + /* VARARG(objattr,object_attributes); */ + char __pad_20[4]; }; struct create_completion_reply { @@ -5248,9 +5257,7 @@ { struct request_header __header; unsigned int access; - unsigned int attributes; /* VARARG(objattr,object_attributes); */ - char __pad_20[4]; }; struct create_job_reply { @@ -5261,6 +5268,23 @@ +struct open_job_request +{ + struct request_header __header; + unsigned int access; + unsigned int attributes; + obj_handle_t rootdir; + /* VARARG(name,unicode_str); */ +}; +struct open_job_reply +{ + struct reply_header __header; + obj_handle_t handle; + char __pad_12[4]; +}; + + + struct assign_job_request { struct request_header __header; @@ -5560,6 +5584,7 @@ REQ_set_token_default_dacl, REQ_set_security_object, REQ_get_security_object, + REQ_get_system_handles, REQ_create_mailslot, REQ_set_mailslot_info, REQ_create_directory, @@ -5597,6 +5622,7 @@ REQ_get_suspend_context, REQ_set_suspend_context, REQ_create_job, + REQ_open_job, REQ_assign_job, REQ_process_in_job, REQ_set_job_limits, @@ -5836,6 +5862,7 @@ struct set_token_default_dacl_request set_token_default_dacl_request; struct set_security_object_request set_security_object_request; struct get_security_object_request get_security_object_request; + struct get_system_handles_request get_system_handles_request; struct create_mailslot_request create_mailslot_request; struct set_mailslot_info_request set_mailslot_info_request; struct create_directory_request create_directory_request; @@ -5873,6 +5900,7 @@ struct get_suspend_context_request get_suspend_context_request; struct set_suspend_context_request set_suspend_context_request; struct create_job_request create_job_request; + struct open_job_request open_job_request; struct assign_job_request assign_job_request; struct process_in_job_request process_in_job_request; struct set_job_limits_request set_job_limits_request; @@ -6110,6 +6138,7 @@ struct set_token_default_dacl_reply set_token_default_dacl_reply; struct set_security_object_reply set_security_object_reply; struct get_security_object_reply get_security_object_reply; + struct get_system_handles_reply get_system_handles_reply; struct create_mailslot_reply create_mailslot_reply; struct set_mailslot_info_reply set_mailslot_info_reply; struct create_directory_reply create_directory_reply; @@ -6147,6 +6176,7 @@ struct get_suspend_context_reply get_suspend_context_reply; struct set_suspend_context_reply set_suspend_context_reply; struct create_job_reply create_job_reply; + struct open_job_reply open_job_reply; struct assign_job_reply assign_job_reply; struct process_in_job_reply process_in_job_reply; struct set_job_limits_reply set_job_limits_reply; @@ -6154,6 +6184,6 @@ struct terminate_job_reply terminate_job_reply; }; -#define SERVER_PROTOCOL_VERSION 491 +#define SERVER_PROTOCOL_VERSION 502 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/wine/test.h wine-staging-1.9.3~ubuntu12.04.1/include/wine/test.h --- wine-staging-1.9.0~ubuntu12.04.1/include/wine/test.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/wine/test.h 2016-02-08 19:32:34.000000000 +0000 @@ -98,20 +98,15 @@ extern void winetest_vskip( const char *msg, __winetest_va_list ap ); #ifdef __GNUC__ +# define WINETEST_PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args))) +#else +# define WINETEST_PRINTF_ATTR(fmt,args) +#endif -extern void __winetest_cdecl winetest_ok( int condition, const char *msg, ... ) __attribute__((format (printf,2,3) )); -extern void __winetest_cdecl winetest_skip( const char *msg, ... ) __attribute__((format (printf,1,2))); -extern void __winetest_cdecl winetest_win_skip( const char *msg, ... ) __attribute__((format (printf,1,2))); -extern void __winetest_cdecl winetest_trace( const char *msg, ... ) __attribute__((format (printf,1,2))); - -#else /* __GNUC__ */ - -extern void __winetest_cdecl winetest_ok( int condition, const char *msg, ... ); -extern void __winetest_cdecl winetest_skip( const char *msg, ... ); -extern void __winetest_cdecl winetest_win_skip( const char *msg, ... ); -extern void __winetest_cdecl winetest_trace( const char *msg, ... ); - -#endif /* __GNUC__ */ +extern void __winetest_cdecl winetest_ok( int condition, const char *msg, ... ) WINETEST_PRINTF_ATTR(2,3); +extern void __winetest_cdecl winetest_skip( const char *msg, ... ) WINETEST_PRINTF_ATTR(1,2); +extern void __winetest_cdecl winetest_win_skip( const char *msg, ... ) WINETEST_PRINTF_ATTR(1,2); +extern void __winetest_cdecl winetest_trace( const char *msg, ... ) WINETEST_PRINTF_ATTR(1,2); #define ok_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_ok #define skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_skip @@ -310,9 +305,9 @@ { if (condition) { - fprintf( stdout, "%s:%d: Test succeeded inside todo block: ", - data->current_file, data->current_line ); - vfprintf(stdout, msg, args); + printf( "%s:%d: Test succeeded inside todo block: ", + data->current_file, data->current_line ); + vprintf(msg, args); InterlockedIncrement(&todo_failures); return 0; } @@ -320,9 +315,9 @@ { if (winetest_debug > 0) { - fprintf( stdout, "%s:%d: Test marked todo: ", - data->current_file, data->current_line ); - vfprintf(stdout, msg, args); + printf( "%s:%d: Test marked todo: ", + data->current_file, data->current_line ); + vprintf(msg, args); } InterlockedIncrement(&todo_successes); return 1; @@ -332,17 +327,17 @@ { if (!condition) { - fprintf( stdout, "%s:%d: Test failed: ", - data->current_file, data->current_line ); - vfprintf(stdout, msg, args); + printf( "%s:%d: Test failed: ", + data->current_file, data->current_line ); + vprintf(msg, args); InterlockedIncrement(&failures); return 0; } else { if (report_success) - fprintf( stdout, "%s:%d: Test succeeded\n", - data->current_file, data->current_line); + printf( "%s:%d: Test succeeded\n", + data->current_file, data->current_line); InterlockedIncrement(&successes); return 1; } @@ -365,9 +360,9 @@ if (winetest_debug > 0) { - fprintf( stdout, "%s:%d: ", data->current_file, data->current_line ); + printf( "%s:%d: ", data->current_file, data->current_line ); __winetest_va_start(valist, msg); - vfprintf(stdout, msg, valist); + vprintf(msg, valist); __winetest_va_end(valist); } } @@ -376,8 +371,8 @@ { tls_data* data=get_tls_data(); - fprintf( stdout, "%s:%d: Tests skipped: ", data->current_file, data->current_line ); - vfprintf(stdout, msg, args); + printf( "%s:%d: Tests skipped: ", data->current_file, data->current_line ); + vprintf(msg, args); skipped++; } @@ -447,7 +442,7 @@ DWORD exit_code = 1; if (WaitForSingleObject( process, 30000 )) - fprintf( stdout, "%s: child process wait failed\n", current_test->name ); + printf( "%s: child process wait failed\n", current_test->name ); else GetExitCodeProcess( process, &exit_code ); @@ -455,13 +450,13 @@ { if (exit_code > 255) { - fprintf( stdout, "%s: exception 0x%08x in child process\n", current_test->name, exit_code ); + printf( "%s: exception 0x%08x in child process\n", current_test->name, exit_code ); InterlockedIncrement( &failures ); } else { - fprintf( stdout, "%s: %u failures in child process\n", - current_test->name, exit_code ); + printf( "%s: %u failures in child process\n", + current_test->name, exit_code ); while (exit_code-- > 0) InterlockedIncrement(&failures); } @@ -562,8 +557,9 @@ { const struct test *test; - fprintf( stdout, "Valid test names:\n" ); - for (test = winetest_testlist; test->name; test++) fprintf( stdout, " %s\n", test->name ); + printf( "Valid test names:\n" ); + for (test = winetest_testlist; test->name; test++) + printf( " %s\n", test->name ); } @@ -575,7 +571,7 @@ if (!(test = find_test( name ))) { - fprintf( stdout, "Fatal: test '%s' does not exist.\n", name ); + printf( "Fatal: test '%s' does not exist.\n", name ); exit_process(1); } successes = failures = todo_successes = todo_failures = 0; @@ -585,11 +581,11 @@ if (winetest_debug) { - fprintf( stdout, "%s: %d tests executed (%d marked as todo, %d %s), %d skipped.\n", - test->name, successes + failures + todo_successes + todo_failures, - todo_successes, failures + todo_failures, - (failures + todo_failures != 1) ? "failures" : "failure", - skipped ); + printf( "%s: %d tests executed (%d marked as todo, %d %s), %d skipped.\n", + test->name, successes + failures + todo_successes + todo_failures, + todo_successes, failures + todo_failures, + (failures + todo_failures != 1) ? "failures" : "failure", + skipped ); } status = (failures + todo_failures < 255) ? failures + todo_failures : 255; return status; @@ -599,7 +595,7 @@ /* Display usage and exit */ static void usage( const char *argv0 ) { - fprintf( stdout, "Usage: %s test_name\n\n", argv0 ); + printf( "Usage: %s test_name\n\n", argv0 ); list_tests(); exit_process(1); } @@ -610,10 +606,10 @@ tls_data *data = get_tls_data(); if (data->current_file) - fprintf( stdout, "%s:%d: this is the last test seen before the exception\n", - data->current_file, data->current_line ); - fprintf( stdout, "%s: unhandled exception %08x at %p\n", current_test->name, - ptrs->ExceptionRecord->ExceptionCode, ptrs->ExceptionRecord->ExceptionAddress ); + printf( "%s:%d: this is the last test seen before the exception\n", + data->current_file, data->current_line ); + printf( "%s: unhandled exception %08x at %p\n", current_test->name, + ptrs->ExceptionRecord->ExceptionCode, ptrs->ExceptionRecord->ExceptionAddress ); fflush( stdout ); return EXCEPTION_EXECUTE_HANDLER; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/wine/wine_common_ver.rc wine-staging-1.9.3~ubuntu12.04.1/include/wine/wine_common_ver.rc --- wine-staging-1.9.0~ubuntu12.04.1/include/wine/wine_common_ver.rc 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/wine/wine_common_ver.rc 2016-02-08 19:32:34.000000000 +0000 @@ -74,7 +74,7 @@ #endif #ifndef WINE_LEGALCOPYRIGHT -#define WINE_LEGALCOPYRIGHT "Copyright (c) 1993-2015 the Wine project authors (see the file AUTHORS for a complete list)" +#define WINE_LEGALCOPYRIGHT "Copyright (c) 1993-2016 the Wine project authors (see the file AUTHORS for a complete list)" #endif #ifndef WINE_PRODUCTVERSION diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/wine/wined3d.h wine-staging-1.9.3~ubuntu12.04.1/include/wine/wined3d.h --- wine-staging-1.9.0~ubuntu12.04.1/include/wine/wined3d.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/wine/wined3d.h 2016-02-08 19:32:34.000000000 +0000 @@ -39,35 +39,17 @@ #define WINED3DOK_NOAUTOGEN MAKE_WINED3DSTATUS(2159) #define MAKE_WINED3DHRESULT(code) MAKE_HRESULT(1, _FACWINED3D, code) -#define WINED3DERR_WRONGTEXTUREFORMAT MAKE_WINED3DHRESULT(2072) -#define WINED3DERR_UNSUPPORTEDCOLOROPERATION MAKE_WINED3DHRESULT(2073) -#define WINED3DERR_UNSUPPORTEDCOLORARG MAKE_WINED3DHRESULT(2074) -#define WINED3DERR_UNSUPPORTEDALPHAOPERATION MAKE_WINED3DHRESULT(2075) -#define WINED3DERR_UNSUPPORTEDALPHAARG MAKE_WINED3DHRESULT(2076) -#define WINED3DERR_TOOMANYOPERATIONS MAKE_WINED3DHRESULT(2077) -#define WINED3DERR_CONFLICTINGTEXTUREFILTER MAKE_WINED3DHRESULT(2078) -#define WINED3DERR_UNSUPPORTEDFACTORVALUE MAKE_WINED3DHRESULT(2079) #define WINED3DERR_CONFLICTINGRENDERSTATE MAKE_WINED3DHRESULT(2081) #define WINED3DERR_UNSUPPORTEDTEXTUREFILTER MAKE_WINED3DHRESULT(2082) -#define WINED3DERR_CONFLICTINGTEXTUREPALETTE MAKE_WINED3DHRESULT(2086) -#define WINED3DERR_DRIVERINTERNALERROR MAKE_WINED3DHRESULT(2087) -#define WINED3DERR_NOTFOUND MAKE_WINED3DHRESULT(2150) -#define WINED3DERR_MOREDATA MAKE_WINED3DHRESULT(2151) -#define WINED3DERR_DEVICENOTRESET MAKE_WINED3DHRESULT(2153) #define WINED3DERR_NOTAVAILABLE MAKE_WINED3DHRESULT(2154) #define WINED3DERR_OUTOFVIDEOMEMORY MAKE_WINED3DHRESULT(380) -#define WINED3DERR_INVALIDDEVICE MAKE_WINED3DHRESULT(2155) #define WINED3DERR_INVALIDCALL MAKE_WINED3DHRESULT(2156) -#define WINED3DERR_DRIVERINVALIDCALL MAKE_WINED3DHRESULT(2157) -#define WINED3DERR_WASSTILLDRAWING MAKE_WINED3DHRESULT(540) #define WINEDDERR_NOTAOVERLAYSURFACE MAKE_WINED3DHRESULT(580) #define WINEDDERR_NOTLOCKED MAKE_WINED3DHRESULT(584) #define WINEDDERR_NODC MAKE_WINED3DHRESULT(586) #define WINEDDERR_DCALREADYCREATED MAKE_WINED3DHRESULT(620) -#define WINEDDERR_NOTFLIPPABLE MAKE_WINED3DHRESULT(582) #define WINEDDERR_SURFACEBUSY MAKE_WINED3DHRESULT(430) #define WINEDDERR_INVALIDRECT MAKE_WINED3DHRESULT(150) -#define WINEDDERR_NOCLIPLIST MAKE_WINED3DHRESULT(205) #define WINEDDERR_OVERLAYNOTVISIBLE MAKE_WINED3DHRESULT(577) enum wined3d_light_type @@ -675,10 +657,9 @@ { WINED3D_RTYPE_SURFACE = 1, WINED3D_RTYPE_VOLUME = 2, - WINED3D_RTYPE_TEXTURE = 3, - WINED3D_RTYPE_VOLUME_TEXTURE = 4, - WINED3D_RTYPE_CUBE_TEXTURE = 5, - WINED3D_RTYPE_BUFFER = 6, + WINED3D_RTYPE_BUFFER = 3, + WINED3D_RTYPE_TEXTURE_2D = 4, + WINED3D_RTYPE_TEXTURE_3D = 5, }; enum wined3d_pool @@ -760,7 +741,10 @@ enum wined3d_sysval_semantic { WINED3D_SV_POSITION = 1, + WINED3D_SV_PRIMITIVEID = 7, WINED3D_SV_INSTANCEID = 8, + WINED3D_SV_ISFRONTFACE = 9, + WINED3D_SV_SAMPLEINDEX = 10, WINED3D_SV_DEPTH = 0xffffffff, WINED3D_SV_TARGET0 = 0, @@ -833,12 +817,18 @@ #define WINED3DUSAGE_NPATCHES 0x00000100 #define WINED3DUSAGE_DYNAMIC 0x00000200 #define WINED3DUSAGE_AUTOGENMIPMAP 0x00000400 +#define WINED3DUSAGE_RESTRICTED_CONTENT 0x00000800 +#define WINED3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER 0x00001000 +#define WINED3DUSAGE_RESTRICT_SHARED_RESOURCE 0x00002000 #define WINED3DUSAGE_DMAP 0x00004000 -#define WINED3DUSAGE_MASK 0x00004fff -#define WINED3DUSAGE_TEXTURE 0x10000000 -#define WINED3DUSAGE_OWNDC 0x20000000 -#define WINED3DUSAGE_STATICDECL 0x40000000 -#define WINED3DUSAGE_OVERLAY 0x80000000 +#define WINED3DUSAGE_TEXTAPI 0x10000000 +#define WINED3DUSAGE_MASK 0x10007fff + +#define WINED3DUSAGE_LEGACY_CUBEMAP 0x00800000 +#define WINED3DUSAGE_TEXTURE 0x01000000 +#define WINED3DUSAGE_OWNDC 0x02000000 +#define WINED3DUSAGE_STATICDECL 0x04000000 +#define WINED3DUSAGE_OVERLAY 0x08000000 #define WINED3DUSAGE_QUERY_LEGACYBUMPMAP 0x00008000 #define WINED3DUSAGE_QUERY_FILTER 0x00020000 @@ -1485,9 +1475,9 @@ #define WINED3D_PALETTE_ALLOW_256 0x00000002 #define WINED3D_PALETTE_ALPHA 0x00000004 -#define WINED3D_SURFACE_MAPPABLE 0x00000001 -#define WINED3D_SURFACE_DISCARD 0x00000002 -#define WINED3D_SURFACE_PIN_SYSMEM 0x00000004 +#define WINED3D_TEXTURE_CREATE_MAPPABLE 0x00000001 +#define WINED3D_TEXTURE_CREATE_DISCARD 0x00000002 +#define WINED3D_TEXTURE_CREATE_PIN_SYSMEM 0x00000004 #define WINED3D_APPEND_ALIGNED_ELEMENT 0xffffffff @@ -2233,6 +2223,7 @@ struct wined3d_shader_resource_view * __cdecl wined3d_device_get_vs_resource_view(const struct wined3d_device *device, UINT idx); struct wined3d_sampler * __cdecl wined3d_device_get_vs_sampler(const struct wined3d_device *device, UINT idx); +struct wined3d * __cdecl wined3d_device_get_wined3d(const struct wined3d_device *device); ULONG __cdecl wined3d_device_incref(struct wined3d_device *device); HRESULT __cdecl wined3d_device_init_3d(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc); HRESULT __cdecl wined3d_device_init_gdi(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc); @@ -2440,8 +2431,6 @@ HRESULT __cdecl wined3d_rendertarget_view_create(const struct wined3d_rendertarget_view_desc *desc, struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_rendertarget_view **view); -HRESULT __cdecl wined3d_rendertarget_view_create_from_surface(struct wined3d_surface *surface, - void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_rendertarget_view **view); HRESULT __cdecl wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture *texture, unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_rendertarget_view **view); @@ -2485,23 +2474,10 @@ ULONG __cdecl wined3d_stateblock_decref(struct wined3d_stateblock *stateblock); ULONG __cdecl wined3d_stateblock_incref(struct wined3d_stateblock *stateblock); -HRESULT __cdecl wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const WINEDDBLTFX *blt_fx, enum wined3d_texture_filter_type filter); -ULONG __cdecl wined3d_surface_decref(struct wined3d_surface *surface); -struct wined3d_surface * __cdecl wined3d_surface_from_resource(struct wined3d_resource *resource); HRESULT __cdecl wined3d_surface_get_overlay_position(const struct wined3d_surface *surface, LONG *x, LONG *y); void * __cdecl wined3d_surface_get_parent(const struct wined3d_surface *surface); DWORD __cdecl wined3d_surface_get_pitch(const struct wined3d_surface *surface); -struct wined3d_resource * __cdecl wined3d_surface_get_resource(struct wined3d_surface *surface); -HRESULT __cdecl wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc); -ULONG __cdecl wined3d_surface_incref(struct wined3d_surface *surface); -HRESULT __cdecl wined3d_surface_map(struct wined3d_surface *surface, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); -void __cdecl wined3d_surface_preload(struct wined3d_surface *surface); -HRESULT __cdecl wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc); HRESULT __cdecl wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y); -HRESULT __cdecl wined3d_surface_unmap(struct wined3d_surface *surface); HRESULT __cdecl wined3d_surface_update_overlay(struct wined3d_surface *surface, const RECT *src_rect, struct wined3d_surface *dst_surface, const RECT *dst_rect, DWORD flags, const WINEDDOVERLAYFX *fx); HRESULT __cdecl wined3d_surface_update_overlay_z_order(struct wined3d_surface *surface, @@ -2542,7 +2518,7 @@ struct wined3d_texture *src_texture, unsigned int src_idx, const RECT *src_rect_in, DWORD flags, const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter); HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc, - UINT level_count, DWORD surface_flags, const struct wined3d_sub_resource_data *data, void *parent, + UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture); ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture); void __cdecl wined3d_texture_generate_mipmaps(struct wined3d_texture *texture); @@ -2552,7 +2528,7 @@ DWORD __cdecl wined3d_texture_get_lod(const struct wined3d_texture *texture); void * __cdecl wined3d_texture_get_parent(const struct wined3d_texture *texture); struct wined3d_resource * __cdecl wined3d_texture_get_resource(struct wined3d_texture *texture); -struct wined3d_resource * __cdecl wined3d_texture_get_sub_resource(struct wined3d_texture *texture, +struct wined3d_resource * __cdecl wined3d_texture_get_sub_resource(const struct wined3d_texture *texture, UINT sub_resource_idx); ULONG __cdecl wined3d_texture_incref(struct wined3d_texture *texture); void __cdecl wined3d_texture_preload(struct wined3d_texture *texture); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/winnls.h wine-staging-1.9.3~ubuntu12.04.1/include/winnls.h --- wine-staging-1.9.0~ubuntu12.04.1/include/winnls.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/winnls.h 2016-02-08 19:32:34.000000000 +0000 @@ -906,6 +906,7 @@ WINBASEAPI LANGID WINAPI GetSystemDefaultLangID(void); WINBASEAPI LCID WINAPI GetSystemDefaultLCID(void); WINBASEAPI LANGID WINAPI GetSystemDefaultUILanguage(void); +WINBASEAPI BOOL WINAPI GetSystemPreferredUILanguages(DWORD,ULONG*,WCHAR*,ULONG*); WINBASEAPI LCID WINAPI GetThreadLocale(void); WINBASEAPI INT WINAPI GetTimeFormatA(LCID,DWORD,const SYSTEMTIME*,LPCSTR,LPSTR,INT); WINBASEAPI INT WINAPI GetTimeFormatEx(LPCWSTR,DWORD,const SYSTEMTIME*,LPCWSTR,LPWSTR,INT); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/winnt.h wine-staging-1.9.3~ubuntu12.04.1/include/winnt.h --- wine-staging-1.9.0~ubuntu12.04.1/include/winnt.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/winnt.h 2016-02-08 19:32:34.000000000 +0000 @@ -3549,6 +3549,7 @@ COMIMAGE_FLAGS_32BITREQUIRED = 0x00000002, COMIMAGE_FLAGS_IL_LIBRARY = 0x00000004, COMIMAGE_FLAGS_STRONGNAMESIGNED = 0x00000008, + COMIMAGE_FLAGS_NATIVE_ENTRYPOINT= 0x00000010, COMIMAGE_FLAGS_TRACKDEBUGDATA = 0x00010000, COR_VERSION_MAJOR_V2 = 2, diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/winspool.h wine-staging-1.9.3~ubuntu12.04.1/include/winspool.h --- wine-staging-1.9.0~ubuntu12.04.1/include/winspool.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/winspool.h 2016-02-08 19:32:34.000000000 +0000 @@ -1789,6 +1789,12 @@ LPWSTR pPrintProvidorName); #define DeletePrintProvidor WINELIB_NAME_AW(DeletePrintProvidor) +DWORD WINAPI EnumPrinterKeyA(HANDLE printer, const CHAR *key, + CHAR *subkey, DWORD size, DWORD *needed); +DWORD WINAPI EnumPrinterKeyW(HANDLE printer, const WCHAR *key, + WCHAR *subkey, DWORD size, DWORD *needed); +#define EnumPrinterKey WINELIB_NAME_AW(EnumPrinterKey) + DWORD WINAPI EnumPrinterDataExA(HANDLE hPrinter, LPCSTR pKeyName, LPBYTE pEnumValues, DWORD cbEnumValues, LPDWORD pcbEnumValues, LPDWORD pnEnumValues); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/winternl.h wine-staging-1.9.3~ubuntu12.04.1/include/winternl.h --- wine-staging-1.9.0~ubuntu12.04.1/include/winternl.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/winternl.h 2016-02-08 19:32:34.000000000 +0000 @@ -842,6 +842,7 @@ Unknown71, Unknown72, SystemLogicalProcessorInformation = 73, + SystemLogicalProcessorInformationEx = 107, SystemInformationClassMax } SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS; @@ -1892,6 +1893,15 @@ UCHAR Data[ANYSIZE_ARRAY]; } LPC_MESSAGE, *PLPC_MESSAGE; +typedef struct _RTL_USER_PROCESS_INFORMATION +{ + ULONG Length; + HANDLE Process; + HANDLE Thread; + CLIENT_ID ClientId; + SECTION_IMAGE_INFORMATION ImageInformation; +} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION; + typedef enum _SHUTDOWN_ACTION { ShutdownNoReboot, ShutdownReboot, @@ -2181,11 +2191,11 @@ NTSYSAPI NTSTATUS WINAPI NtNotifyChangeDirectoryFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,ULONG,BOOLEAN); NTSYSAPI NTSTATUS WINAPI NtNotifyChangeKey(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,BOOLEAN,PVOID,ULONG,BOOLEAN); NTSYSAPI NTSTATUS WINAPI NtNotifyChangeMultipleKeys(HANDLE,ULONG,OBJECT_ATTRIBUTES*,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,BOOLEAN,PVOID,ULONG,BOOLEAN); -NTSYSAPI NTSTATUS WINAPI NtOpenDirectoryObject(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES); +NTSYSAPI NTSTATUS WINAPI NtOpenDirectoryObject(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*); NTSYSAPI NTSTATUS WINAPI NtOpenEvent(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES *); -NTSYSAPI NTSTATUS WINAPI NtOpenEventPair(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES); +NTSYSAPI NTSTATUS WINAPI NtOpenEventPair(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*); NTSYSAPI NTSTATUS WINAPI NtOpenFile(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,ULONG,ULONG); -NTSYSAPI NTSTATUS WINAPI NtOpenIoCompletion(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES); +NTSYSAPI NTSTATUS WINAPI NtOpenIoCompletion(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*); NTSYSAPI NTSTATUS WINAPI NtOpenJobObject(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*); NTSYSAPI NTSTATUS WINAPI NtOpenKey(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES *); NTSYSAPI NTSTATUS WINAPI NtOpenKeyEx(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,ULONG); @@ -2199,7 +2209,7 @@ NTSYSAPI NTSTATUS WINAPI NtOpenProcessTokenEx(HANDLE,DWORD,DWORD,HANDLE *); NTSYSAPI NTSTATUS WINAPI NtOpenSection(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*); NTSYSAPI NTSTATUS WINAPI NtOpenSemaphore(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*); -NTSYSAPI NTSTATUS WINAPI NtOpenSymbolicLinkObject(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES); +NTSYSAPI NTSTATUS WINAPI NtOpenSymbolicLinkObject(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*); NTSYSAPI NTSTATUS WINAPI NtOpenThread(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*,const CLIENT_ID*); NTSYSAPI NTSTATUS WINAPI NtOpenThreadToken(HANDLE,DWORD,BOOLEAN,HANDLE *); NTSYSAPI NTSTATUS WINAPI NtOpenThreadTokenEx(HANDLE,DWORD,BOOLEAN,DWORD,HANDLE *); @@ -2241,6 +2251,7 @@ NTSYSAPI NTSTATUS WINAPI NtQuerySymbolicLinkObject(HANDLE,PUNICODE_STRING,PULONG); NTSYSAPI NTSTATUS WINAPI NtQuerySystemEnvironmentValue(PUNICODE_STRING,PWCHAR,ULONG,PULONG); NTSYSAPI NTSTATUS WINAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS,PVOID,ULONG,PULONG); +NTSYSAPI NTSTATUS WINAPI NtQuerySystemInformationEx(SYSTEM_INFORMATION_CLASS,void*,ULONG,void*,ULONG,ULONG*); NTSYSAPI NTSTATUS WINAPI NtQuerySystemTime(PLARGE_INTEGER); NTSYSAPI NTSTATUS WINAPI NtQueryTimer(HANDLE,TIMER_INFORMATION_CLASS,PVOID,ULONG,PULONG); NTSYSAPI NTSTATUS WINAPI NtQueryTimerResolution(PULONG,PULONG,PULONG); @@ -2391,6 +2402,7 @@ NTSYSAPI NTSTATUS WINAPI RtlCreateTimer(PHANDLE, HANDLE, RTL_WAITORTIMERCALLBACKFUNC, PVOID, DWORD, DWORD, ULONG); NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeString(PUNICODE_STRING,LPCWSTR); NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR); +NTSYSAPI NTSTATUS WINAPI RtlCreateUserProcess(UNICODE_STRING*,ULONG,RTL_USER_PROCESS_PARAMETERS*,SECURITY_DESCRIPTOR*,SECURITY_DESCRIPTOR*,HANDLE,BOOLEAN,HANDLE,HANDLE,RTL_USER_PROCESS_INFORMATION*); NTSYSAPI NTSTATUS WINAPI RtlCreateUserThread(HANDLE,const SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*); NTSYSAPI void WINAPI RtlDeactivateActivationContext(DWORD,ULONG_PTR); NTSYSAPI PVOID WINAPI RtlDecodePointer(PVOID); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/winuser.h wine-staging-1.9.3~ubuntu12.04.1/include/winuser.h --- wine-staging-1.9.0~ubuntu12.04.1/include/winuser.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/winuser.h 2016-02-08 19:32:34.000000000 +0000 @@ -385,6 +385,17 @@ ULONG_PTR dwExtraInfo; } MOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT, *LPMOUSEHOOKSTRUCT; +typedef struct +{ + struct { /* MOUSEHOOKSTRUCT */ + POINT pt; + HWND hwnd; + UINT wHitTestCode; + ULONG_PTR dwExtraInfo; + } DUMMYSTRUCTNAME; + DWORD mouseData; +} MOUSEHOOKSTRUCTEX, *PMOUSEHOOKSTRUCTEX, *LPMOUSEHOOKSTRUCTEX; + /* Hardware hook structure */ @@ -766,6 +777,21 @@ #define RT_ANIICON MAKEINTRESOURCE(22) #define RT_HTML MAKEINTRESOURCE(23) +#ifdef RC_INVOKED +#define RT_MANIFEST 24 +#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 +#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID 2 +#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID 3 +#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID 1 +#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID 16 +#else +#define RT_MANIFEST MAKEINTRESOURCE(24) +#define CREATEPROCESS_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1) +#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(2) +#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(3) +#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1) +#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(16) +#endif /* cbWndExtra bytes for dialog class */ #define DLGWINDOWEXTRA 30 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/xapofx.h wine-staging-1.9.3~ubuntu12.04.1/include/xapofx.h --- wine-staging-1.9.0~ubuntu12.04.1/include/xapofx.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/xapofx.h 2016-02-08 19:32:34.000000000 +0000 @@ -23,54 +23,22 @@ /* xapofx 1.0 through 1.5 */ DEFINE_GUID(CLSID_FXEQ27, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0x55, 0x00, 0x00, 0x00, 0x00); -/* xaudio 2.8 */ +/* xaudio >= 2.8 */ DEFINE_GUID(CLSID_FXEQ, 0xf5e01117, 0xd6c4, 0x485a, 0xa3, 0xf5, 0x69, 0x51, 0x96, 0xf3, 0xdb, 0xfa); -/* wine internal */ -DEFINE_GUID(CLSID_WINE_FXEQ10, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x00, 0x00, 0x01, 0x00); -DEFINE_GUID(CLSID_WINE_FXEQ11, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x00, 0x00, 0x01, 0x01); -DEFINE_GUID(CLSID_WINE_FXEQ12, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x00, 0x00, 0x01, 0x02); -DEFINE_GUID(CLSID_WINE_FXEQ13, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x00, 0x00, 0x01, 0x03); -DEFINE_GUID(CLSID_WINE_FXEQ14, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x00, 0x00, 0x01, 0x04); -DEFINE_GUID(CLSID_WINE_FXEQ15, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x00, 0x00, 0x01, 0x05); -DEFINE_GUID(CLSID_WINE_FXEQ28, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x00, 0x00, 0x02, 0x08); /* xapofx 1.0 through 1.5 */ DEFINE_GUID(CLSID_FXMasteringLimiter27, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0x55, 0x00, 0x00, 0x00, 0x01); -/* xaudio 2.8 */ +/* xaudio >= 2.8 */ DEFINE_GUID(CLSID_FXMasteringLimiter, 0xc4137916, 0x2be1, 0x46fd, 0x85, 0x99, 0x44, 0x15, 0x36, 0xf4, 0x98, 0x56); -/* wine internal */ -DEFINE_GUID(CLSID_WINE_FXMasteringLimiter10, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x01, 0x00, 0x01, 0x00); -DEFINE_GUID(CLSID_WINE_FXMasteringLimiter11, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x01, 0x00, 0x01, 0x01); -DEFINE_GUID(CLSID_WINE_FXMasteringLimiter12, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x01, 0x00, 0x01, 0x02); -DEFINE_GUID(CLSID_WINE_FXMasteringLimiter13, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x01, 0x00, 0x01, 0x03); -DEFINE_GUID(CLSID_WINE_FXMasteringLimiter14, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x01, 0x00, 0x01, 0x04); -DEFINE_GUID(CLSID_WINE_FXMasteringLimiter15, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x01, 0x00, 0x01, 0x05); -DEFINE_GUID(CLSID_WINE_FXMasteringLimiter28, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x01, 0x00, 0x02, 0x08); /* xapofx 1.0 through 1.5 */ DEFINE_GUID(CLSID_FXReverb27, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0x55, 0x00, 0x00, 0x00, 0x02); -/* xaudio 2.8 */ +/* xaudio >= 2.8 */ DEFINE_GUID(CLSID_FXReverb, 0x7d9aca56, 0xcb68, 0x4807, 0xb6, 0x32, 0xb1, 0x37, 0x35, 0x2e, 0x85, 0x96); -/* wine internal */ -DEFINE_GUID(CLSID_WINE_FXReverb10, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x02, 0x00, 0x01, 0x00); -DEFINE_GUID(CLSID_WINE_FXReverb11, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x02, 0x00, 0x01, 0x01); -DEFINE_GUID(CLSID_WINE_FXReverb12, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x02, 0x00, 0x01, 0x02); -DEFINE_GUID(CLSID_WINE_FXReverb13, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x02, 0x00, 0x01, 0x03); -DEFINE_GUID(CLSID_WINE_FXReverb14, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x02, 0x00, 0x01, 0x04); -DEFINE_GUID(CLSID_WINE_FXReverb15, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x02, 0x00, 0x01, 0x05); -DEFINE_GUID(CLSID_WINE_FXReverb28, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x02, 0x00, 0x02, 0x08); /* xapofx 1.0 through 1.5 */ DEFINE_GUID(CLSID_FXEcho27, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0x55, 0x00, 0x00, 0x00, 0x03); -/* xaudio 2.8 */ +/* xaudio >= 2.8 */ DEFINE_GUID(CLSID_FXEcho, 0x5039d740, 0xf736, 0x449a, 0x84, 0xd3, 0xa5, 0x62, 0x02, 0x55, 0x7b, 0x87); -/* wine internal */ -DEFINE_GUID(CLSID_WINE_FXEcho10, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x03, 0x00, 0x01, 0x00); -DEFINE_GUID(CLSID_WINE_FXEcho11, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x03, 0x00, 0x01, 0x01); -DEFINE_GUID(CLSID_WINE_FXEcho12, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x03, 0x00, 0x01, 0x02); -DEFINE_GUID(CLSID_WINE_FXEcho13, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x03, 0x00, 0x01, 0x03); -DEFINE_GUID(CLSID_WINE_FXEcho14, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x03, 0x00, 0x01, 0x04); -DEFINE_GUID(CLSID_WINE_FXEcho15, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x03, 0x00, 0x01, 0x05); -DEFINE_GUID(CLSID_WINE_FXEcho28, 0xa90bc001, 0xe897, 0xe897, 0x74, 0x39, 0x43, 0xFF, 0x03, 0x00, 0x02, 0x08); #endif diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/xaudio2fx.idl wine-staging-1.9.3~ubuntu12.04.1/include/xaudio2fx.idl --- wine-staging-1.9.0~ubuntu12.04.1/include/xaudio2fx.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/xaudio2fx.idl 2016-02-08 19:32:34.000000000 +0000 @@ -19,13 +19,6 @@ import "unknwn.idl"; [ - uuid(cac1105f-619b-4d04-831a-44e1cbf12d57) -] -coclass AudioVolumeMeter { - interface IUnknown; -} - -[ uuid(c0c56f46-29b1-44e9-9939-a32ce86867e2) ] coclass AudioVolumeMeter20 { @@ -75,9 +68,9 @@ } [ - uuid(6a93130e-1d53-41d1-a9cf-e758800bb179) + uuid(cac1105f-619b-4d04-831a-44e1cbf12d57) ] -coclass AudioReverb { +coclass AudioVolumeMeter27 { interface IUnknown; } @@ -129,3 +122,10 @@ coclass AudioReverb26 { interface IUnknown; } + +[ + uuid(6a93130e-1d53-41d1-a9cf-e758800bb179) +] +coclass AudioReverb27 { + interface IUnknown; +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/include/xaudio2.idl wine-staging-1.9.3~ubuntu12.04.1/include/xaudio2.idl --- wine-staging-1.9.0~ubuntu12.04.1/include/xaudio2.idl 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/include/xaudio2.idl 2016-02-08 19:32:34.000000000 +0000 @@ -24,13 +24,6 @@ cpp_quote("#include ") [ - uuid(5a508685-a254-4fba-9b82-9a24b00306af) -] -coclass XAudio2 { - interface IUnknown; -} - -[ uuid(fac23f48-31f5-45a8-b49b-5225d61401aa) ] coclass XAudio20 { @@ -80,6 +73,13 @@ } [ + uuid(5a508685-a254-4fba-9b82-9a24b00306af) +] +coclass XAudio27 { + interface IUnknown; +} + +[ uuid(db05ea35-0329-4d4b-a53a-6dead03d3852) ] coclass XAudio2Debug { @@ -1001,11 +1001,14 @@ [in, defaultvalue(NULL)] void* pReserved); } +/* XAudio2 2.8's IXAudio2 is identical to 2.9's */ +cpp_quote("DEFINE_GUID(IID_IXAudio28, 0x60d8dac8, 0x5aa1, 0x4e8e, 0xb5, 0x97, 0x2f, 0x5e, 0x28, 0x83, 0xd4, 0x84);") + [ object, - uuid(60d8dac8-5aa1-4e8e-b597-2f5e2883d484), + uuid(2b02e3cf-2e0b-4ec3-be45-1b2a3fe7210d) ] -/* XAudio2 2.8's IXAudio2 interface. */ +/* XAudio2 2.9's IXAudio2 interface. */ interface IXAudio2 : IUnknown { HRESULT RegisterForCallbacks([in] IXAudio2EngineCallback* pCallback); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/LICENSE wine-staging-1.9.3~ubuntu12.04.1/LICENSE --- wine-staging-1.9.0~ubuntu12.04.1/LICENSE 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/LICENSE 2016-02-08 19:32:34.000000000 +0000 @@ -1,4 +1,4 @@ -Copyright (c) 1993-2015 the Wine project authors (see the file AUTHORS +Copyright (c) 1993-2016 the Wine project authors (see the file AUTHORS for a complete list) Wine is free software; you can redistribute it and/or modify it under diff -Nru wine-staging-1.9.0~ubuntu12.04.1/LICENSE.md wine-staging-1.9.3~ubuntu12.04.1/LICENSE.md --- wine-staging-1.9.0~ubuntu12.04.1/LICENSE.md 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/LICENSE.md 2016-02-08 20:07:32.000000000 +0000 @@ -7,7 +7,7 @@ [LGPLv2.1](#gnu-lgpl-version-21), to stay compatible with Wine: ``` -Copyright (C) 2014-2015 the Wine Staging project authors. +Copyright (C) 2014-2016 the Wine Staging project authors. Wine Staging is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff -Nru wine-staging-1.9.0~ubuntu12.04.1/loader/wine.fr.UTF-8.man.in wine-staging-1.9.3~ubuntu12.04.1/loader/wine.fr.UTF-8.man.in --- wine-staging-1.9.0~ubuntu12.04.1/loader/wine.fr.UTF-8.man.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/loader/wine.fr.UTF-8.man.in 2016-02-08 19:32:34.000000000 +0000 @@ -24,11 +24,11 @@ Pour exécuter des applications en ligne de commande (programmes Windows console), préférez .BR wineconsole . -Cela permet d'afficher la sortie dans une fenêtre séparée (nécessite X11). +Cela permet d'afficher la sortie dans une fenêtre séparée. Si vous n'utilisez pas .B wineconsole pour les programmes en ligne de commande, le support console sera très limité et votre -programme peut ne pas fonctionner correctement. +programme pourrait ne pas fonctionner correctement. .PP Lorsque wine est invoqué avec .B --help diff -Nru wine-staging-1.9.0~ubuntu12.04.1/loader/wine.inf.in wine-staging-1.9.3~ubuntu12.04.1/loader/wine.inf.in --- wine-staging-1.9.0~ubuntu12.04.1/loader/wine.inf.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/loader/wine.inf.in 2016-02-08 19:32:34.000000000 +0000 @@ -218,13 +218,13 @@ HKCR,Msi.Patch\DefaultIcon,,2,"msiexec.exe" HKCR,Msi.Patch\shell\Open\command,,2,"%11%\msiexec.exe /p ""%1""" HKCR,rtffile,,2,"Rich Text Document" -HKCR,rtffile\shell\open\command,,2,"%11%\wordpad.exe %1" -HKCR,rtffile\shell\print\command,,2,"%11%\wordpad.exe /p %1" +HKCR,rtffile\shell\open\command,,2,"""%16422%\Windows NT\Accessories\wordpad.exe"" %1" +HKCR,rtffile\shell\print\command,,2,"""%16422%\Windows NT\Accessories\wordpad.exe"" /p %1" HKCR,txtfile,,2,"Text Document" HKCR,txtfile\shell\open\command,,2,"%11%\notepad.exe %1" HKCR,txtfile\shell\print\command,,2,"%11%\notepad.exe /p %1" -HKCR,wrifile\shell\open\command,,2,"%11%\wordpad.exe %1" -HKCR,wrifile\shell\print\command,,2,"%11%\wordpad.exe /p %1" +HKCR,wrifile\shell\open\command,,2,"""%16422%\Windows NT\Accessories\wordpad.exe"" %1" +HKCR,wrifile\shell\print\command,,2,"""%16422%\Windows NT\Accessories\wordpad.exe"" /p %1" HKCR,xmlfile,,2,"XML Document" HKCR,xmlfile\shell\open\command,,2,"""%11%\winebrowser.exe"" -nohome" HKCR,xmlfile\shell\open\ddeexec,,2,"""%1"",,-1,0,,,," @@ -491,7 +491,7 @@ HKLM,%CurrentVersionNT%\Gre_Initialize,,16 HKLM,%CurrentVersionNT%\Hotfix\Q246009,"Installed",,"1" HKLM,%CurrentVersionNT%\Image File Execution Options,,16 -HKLM,%CurrentVersionNT%\Language Pack,,16 +HKLM,%CurrentVersionNT%\LanguagePack,,16 HKLM,%CurrentVersionNT%\NetworkCards,,16 HKLM,%CurrentVersionNT%\OpenGLDrivers,,16 HKLM,%CurrentVersionNT%\Perflib,,16 @@ -3334,7 +3334,7 @@ HKLM,Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\FontSubstitutes,"SymbolicLinkValue",0x60000,"\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes" HKLM,Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Gre_Initialize,"SymbolicLinkValue",0x60000,"\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\Gre_Initialize" HKLM,Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options,"SymbolicLinkValue",0x60000,"\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options" -HKLM,Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Language Pack,"SymbolicLinkValue",0x60000,"\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\Language Pack" +HKLM,Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\LanguagePack,"SymbolicLinkValue",0x60000,"\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\LanguagePack" HKLM,Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\NetworkCards,"SymbolicLinkValue",0x60000,"\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\NetworkCards" HKLM,Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Perflib,"SymbolicLinkValue",0x60000,"\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\Perflib" HKLM,Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Ports,"SymbolicLinkValue",0x60000,"\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\Ports" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/MAINTAINERS wine-staging-1.9.3~ubuntu12.04.1/MAINTAINERS --- wine-staging-1.9.0~ubuntu12.04.1/MAINTAINERS 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/MAINTAINERS 2016-02-08 19:32:34.000000000 +0000 @@ -90,6 +90,17 @@ P: Andrew Eikum F: dlls/dinput/ +DirectShow +P: Andrew Eikum +F: dlls/amstream/ +F: dlls/mciqtz32/ +F: dlls/qcap/ +F: dlls/qedit/ +F: dlls/quartz/ +F: dlls/strmbase/ +F: dlls/winegstreamer/ +F: dlls/wineqtdecoder/ + DirectWrite M: Nikolay Sivov F: dlls/dwrite/ @@ -266,3 +277,9 @@ Stable Branch M: Michael Stefaniuc W: http://wiki.winehq.org/StableRules + +Staging Branch +M: Sebastian Lackner +M: Michael Müller +P: Erich E. Hoover +W: https://wine-staging.com/ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/Makefile.in wine-staging-1.9.3~ubuntu12.04.1/Makefile.in --- wine-staging-1.9.0~ubuntu12.04.1/Makefile.in 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/Makefile.in 2016-02-08 19:32:34.000000000 +0000 @@ -72,6 +72,7 @@ MSGFMT = @MSGFMT@ CROSSTARGET = @CROSSTARGET@ LINGUAS = @LINGUAS@ +SUBDIRS = @SUBDIRS@ RUNTESTFLAGS = -q -P wine MAKEDEP = $(TOOLSDIR)/tools/makedep$(TOOLSEXT) WINEBUILD = $(TOOLSDIR)/tools/winebuild/winebuild$(TOOLSEXT) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-crt-Stub_DLLs/0001-ucrtbase-Hook-up-some-functions-with-new-names-to-ex.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-crt-Stub_DLLs/0001-ucrtbase-Hook-up-some-functions-with-new-names-to-ex.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-crt-Stub_DLLs/0001-ucrtbase-Hook-up-some-functions-with-new-names-to-ex.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-crt-Stub_DLLs/0001-ucrtbase-Hook-up-some-functions-with-new-names-to-ex.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -From fe4c1e1f10f8edc76c5dad994ed2e5202f9c2821 Mon Sep 17 00:00:00 2001 -From: Martin Storsjo -Date: Mon, 3 Aug 2015 22:26:01 +0300 -Subject: ucrtbase: Hook up some functions with new names to existing - implementations - -These are some functions that on a first glance seem to have a -matching signature even though the name has changed. ---- - dlls/ucrtbase/ucrtbase.spec | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec -index bb56408..cee094d 100644 ---- a/dlls/ucrtbase/ucrtbase.spec -+++ b/dlls/ucrtbase/ucrtbase.spec -@@ -211,7 +211,7 @@ - @ cdecl _c_exit() MSVCRT__c_exit - @ cdecl _cabs(long) MSVCRT__cabs - @ cdecl _callnewh(long) --@ stub _calloc_base -+@ cdecl _calloc_base(long long) MSVCRT_calloc - @ cdecl _cexit() MSVCRT__cexit - @ cdecl _cgets(ptr) - @ stub _cgets_s -@@ -333,7 +333,7 @@ - @ cdecl _fputwchar(long) MSVCRT__fputwchar - @ cdecl _fread_nolock(ptr long long ptr) MSVCRT__fread_nolock - @ cdecl _fread_nolock_s(ptr long long long ptr) MSVCRT__fread_nolock_s --@ stub _free_base -+@ cdecl _free_base(ptr) MSVCRT_free - @ cdecl _free_locale(ptr) MSVCRT__free_locale - @ cdecl _fseek_nolock(ptr long long) MSVCRT__fseek_nolock - @ cdecl _fseeki64(ptr int64 long) MSVCRT__fseeki64 -@@ -580,7 +580,7 @@ - @ cdecl _ltow_s(long ptr long long) MSVCRT__ltow_s - @ cdecl _makepath(ptr str str str str) MSVCRT__makepath - @ cdecl _makepath_s(ptr long str str str str) MSVCRT__makepath_s --@ stub _malloc_base -+@ cdecl _malloc_base(long) MSVCRT_malloc - @ cdecl _mbbtombc(long) - @ stub _mbbtombc_l - @ cdecl _mbbtype(long long) --- -2.5.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-crt-Stub_DLLs/definition wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-crt-Stub_DLLs/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-crt-Stub_DLLs/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-crt-Stub_DLLs/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Fixes: Add stub dlls required for MSVC 2015 runtime library (Windows 10) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0001-api-ms-win-core-com-l1-1-1-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0001-api-ms-win-core-com-l1-1-1-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0001-api-ms-win-core-com-l1-1-1-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0001-api-ms-win-core-com-l1-1-1-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,136 @@ +From 06a2d09b5e443d01c7177d6e74e7e5a43fb4ce26 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 15 Jan 2016 12:20:06 +0100 +Subject: api-ms-win-core-com-l1-1-1: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-core-com-l1-1-1/Makefile.in | 1 + + .../api-ms-win-core-com-l1-1-1.spec | 82 ++++++++++++++++++++++ + tools/make_specfiles | 1 + + 4 files changed, 85 insertions(+) + create mode 100644 dlls/api-ms-win-core-com-l1-1-1/Makefile.in + create mode 100644 dlls/api-ms-win-core-com-l1-1-1/api-ms-win-core-com-l1-1-1.spec + +diff --git a/configure.ac b/configure.ac +index 8aca9a1..09d62ae 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2617,6 +2617,7 @@ WINE_CONFIG_TEST(dlls/advpack/tests) + WINE_CONFIG_DLL(amstream,,[clean]) + WINE_CONFIG_TEST(dlls/amstream/tests) + WINE_CONFIG_DLL(api-ms-win-core-com-l1-1-0) ++WINE_CONFIG_DLL(api-ms-win-core-com-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-console-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-datetime-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-datetime-l1-1-1) +diff --git a/dlls/api-ms-win-core-com-l1-1-1/Makefile.in b/dlls/api-ms-win-core-com-l1-1-1/Makefile.in +new file mode 100644 +index 0000000..a37f743 +--- /dev/null ++++ b/dlls/api-ms-win-core-com-l1-1-1/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-com-l1-1-1.dll +diff --git a/dlls/api-ms-win-core-com-l1-1-1/api-ms-win-core-com-l1-1-1.spec b/dlls/api-ms-win-core-com-l1-1-1/api-ms-win-core-com-l1-1-1.spec +new file mode 100644 +index 0000000..d2914f0 +--- /dev/null ++++ b/dlls/api-ms-win-core-com-l1-1-1/api-ms-win-core-com-l1-1-1.spec +@@ -0,0 +1,82 @@ ++@ stdcall CLSIDFromProgID(wstr ptr) ole32.CLSIDFromProgID ++@ stdcall CLSIDFromString(wstr ptr) ole32.CLSIDFromString ++@ stdcall CoAddRefServerProcess() ole32.CoAddRefServerProcess ++@ stub CoAllowUnmarshalerCLSID ++@ stub CoCancelCall ++@ stdcall CoCopyProxy(ptr ptr) ole32.CoCopyProxy ++@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr) ole32.CoCreateFreeThreadedMarshaler ++@ stdcall CoCreateGuid(ptr) ole32.CoCreateGuid ++@ stdcall CoCreateInstance(ptr ptr long ptr ptr) ole32.CoCreateInstance ++@ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr) ole32.CoCreateInstanceEx ++@ stub CoCreateInstanceFromApp ++@ stub CoDecodeProxy ++@ stub CoDecrementMTAUsage ++@ stub CoDisableCallCancellation ++@ stub CoDisconnectContext ++@ stdcall CoDisconnectObject(ptr long) ole32.CoDisconnectObject ++@ stub CoEnableCallCancellation ++@ stdcall CoFreeUnusedLibraries() ole32.CoFreeUnusedLibraries ++@ stdcall CoFreeUnusedLibrariesEx(long long) ole32.CoFreeUnusedLibrariesEx ++@ stdcall CoGetApartmentType(ptr ptr) ole32.CoGetApartmentType ++@ stdcall CoGetCallContext(ptr ptr) ole32.CoGetCallContext ++@ stdcall CoGetCallerTID(ptr) ole32.CoGetCallerTID ++@ stub CoGetCancelObject ++@ stdcall CoGetClassObject(ptr long ptr ptr ptr) ole32.CoGetClassObject ++@ stdcall CoGetContextToken(ptr) ole32.CoGetContextToken ++@ stdcall CoGetCurrentLogicalThreadId(ptr) ole32.CoGetCurrentLogicalThreadId ++@ stdcall CoGetCurrentProcess() ole32.CoGetCurrentProcess ++@ stdcall CoGetDefaultContext(long ptr ptr) ole32.CoGetDefaultContext ++@ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr) ole32.CoGetInterfaceAndReleaseStream ++@ stdcall CoGetMalloc(long ptr) ole32.CoGetMalloc ++@ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long) ole32.CoGetMarshalSizeMax ++@ stdcall CoGetObjectContext(ptr ptr) ole32.CoGetObjectContext ++@ stdcall CoGetPSClsid(ptr ptr) ole32.CoGetPSClsid ++@ stdcall CoGetStandardMarshal(ptr ptr long ptr long ptr) ole32.CoGetStandardMarshal ++@ stub CoGetStdMarshalEx ++@ stdcall CoGetTreatAsClass(ptr ptr) ole32.CoGetTreatAsClass ++@ stdcall CoImpersonateClient() ole32.CoImpersonateClient ++@ stub CoIncrementMTAUsage ++@ stdcall CoInitializeEx(ptr long) ole32.CoInitializeEx ++@ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr) ole32.CoInitializeSecurity ++@ stub CoInvalidateRemoteMachineBindings ++@ stdcall CoIsHandlerConnected(ptr) ole32.CoIsHandlerConnected ++@ stdcall CoLockObjectExternal(ptr long long) ole32.CoLockObjectExternal ++@ stdcall CoMarshalHresult(ptr long) ole32.CoMarshalHresult ++@ stdcall CoMarshalInterThreadInterfaceInStream(ptr ptr ptr) ole32.CoMarshalInterThreadInterfaceInStream ++@ stdcall CoMarshalInterface(ptr ptr ptr long ptr long) ole32.CoMarshalInterface ++@ stub CoQueryAuthenticationServices ++@ stdcall CoQueryClientBlanket(ptr ptr ptr ptr ptr ptr ptr) ole32.CoQueryClientBlanket ++@ stdcall CoQueryProxyBlanket(ptr ptr ptr ptr ptr ptr ptr ptr) ole32.CoQueryProxyBlanket ++@ stub CoRegisterActivationFilter ++@ stdcall CoRegisterClassObject(ptr ptr long long ptr) ole32.CoRegisterClassObject ++@ stdcall CoRegisterPSClsid(ptr ptr) ole32.CoRegisterPSClsid ++@ stub CoRegisterSurrogate ++@ stdcall CoReleaseMarshalData(ptr) ole32.CoReleaseMarshalData ++@ stdcall CoReleaseServerProcess() ole32.CoReleaseServerProcess ++@ stdcall CoResumeClassObjects() ole32.CoResumeClassObjects ++@ stdcall CoRevertToSelf() ole32.CoRevertToSelf ++@ stdcall CoRevokeClassObject(long) ole32.CoRevokeClassObject ++@ stub CoSetCancelObject ++@ stdcall CoSetProxyBlanket(ptr long long ptr long long ptr long) ole32.CoSetProxyBlanket ++@ stdcall CoSuspendClassObjects() ole32.CoSuspendClassObjects ++@ stdcall CoSwitchCallContext(ptr ptr) ole32.CoSwitchCallContext ++@ stdcall CoTaskMemAlloc(long) ole32.CoTaskMemAlloc ++@ stdcall CoTaskMemFree(ptr) ole32.CoTaskMemFree ++@ stdcall CoTaskMemRealloc(ptr long) ole32.CoTaskMemRealloc ++@ stub CoTestCancel ++@ stdcall CoUninitialize() ole32.CoUninitialize ++@ stdcall CoUnmarshalHresult(ptr ptr) ole32.CoUnmarshalHresult ++@ stdcall CoUnmarshalInterface(ptr ptr ptr) ole32.CoUnmarshalInterface ++@ stdcall CoWaitForMultipleHandles(long long long ptr ptr) ole32.CoWaitForMultipleHandles ++@ stub CoWaitForMultipleObjects ++@ stdcall CreateStreamOnHGlobal(ptr long ptr) ole32.CreateStreamOnHGlobal ++@ stdcall FreePropVariantArray(long ptr) ole32.FreePropVariantArray ++@ stdcall GetHGlobalFromStream(ptr ptr) ole32.GetHGlobalFromStream ++@ stdcall IIDFromString(wstr ptr) ole32.IIDFromString ++@ stdcall ProgIDFromCLSID(ptr ptr) ole32.ProgIDFromCLSID ++@ stdcall PropVariantClear(ptr) ole32.PropVariantClear ++@ stdcall PropVariantCopy(ptr ptr) ole32.PropVariantCopy ++@ stub RoGetAgileReference ++@ stdcall StringFromCLSID(ptr ptr) ole32.StringFromCLSID ++@ stdcall StringFromGUID2(ptr ptr long) ole32.StringFromGUID2 ++@ stdcall StringFromIID(ptr ptr) ole32.StringFromIID +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 16db908..e50ba18 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -224,6 +224,7 @@ my @dll_groups = + "ole32", + "api-ms-win-downlevel-ole32-l1-1-0", + "api-ms-win-core-com-l1-1-0", ++ "api-ms-win-core-com-l1-1-1", + "combase", + ], + [ +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0002-kernelbase-Add-dll-and-add-stub-for-QuirkIsEnabled.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0002-kernelbase-Add-dll-and-add-stub-for-QuirkIsEnabled.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0002-kernelbase-Add-dll-and-add-stub-for-QuirkIsEnabled.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0002-kernelbase-Add-dll-and-add-stub-for-QuirkIsEnabled.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,1848 @@ +From d15b2a48d5caa7e642e66d3fb1e4bdbe56b8b8f7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 15 Jan 2016 13:01:15 +0100 +Subject: kernelbase: Add dll and add stub for QuirkIsEnabled. + +--- + configure.ac | 1 + + dlls/kernelbase/Makefile.in | 4 + + dlls/kernelbase/kernelbase.spec | 1726 +++++++++++++++++++++++++++++++++++++++ + dlls/kernelbase/misc.c | 37 + + dlls/shlwapi/shlwapi.spec | 2 +- + tools/make_specfiles | 7 + + 6 files changed, 1776 insertions(+), 1 deletion(-) + create mode 100644 dlls/kernelbase/Makefile.in + create mode 100644 dlls/kernelbase/kernelbase.spec + create mode 100644 dlls/kernelbase/misc.c + +diff --git a/configure.ac b/configure.ac +index c47c0fd..dc89f99 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2989,6 +2989,7 @@ WINE_CONFIG_TEST(dlls/jscript/tests) + WINE_CONFIG_DLL(jsproxy,,[implib]) + WINE_CONFIG_DLL(kernel32,,[clean,implib,mc]) + WINE_CONFIG_TEST(dlls/kernel32/tests) ++WINE_CONFIG_DLL(kernelbase) + WINE_CONFIG_DLL(keyboard.drv16,enable_win16) + WINE_CONFIG_DLL(krnl386.exe16,enable_win16,[implib],[kernel]) + WINE_CONFIG_DLL(ksuser) +diff --git a/dlls/kernelbase/Makefile.in b/dlls/kernelbase/Makefile.in +new file mode 100644 +index 0000000..2beb34b +--- /dev/null ++++ b/dlls/kernelbase/Makefile.in +@@ -0,0 +1,4 @@ ++MODULE = kernelbase.dll ++ ++C_SRCS = \ ++ misc.c +diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec +new file mode 100644 +index 0000000..392637b +--- /dev/null ++++ b/dlls/kernelbase/kernelbase.spec +@@ -0,0 +1,1726 @@ ++# On Windows 10 kernelbase contains the implementation and kernel32 is redirected ++# but this breaks some old applications which can't handle redirections. ++ ++@ stub PackageSidFromProductId ++@ stub GetCPHashNode ++@ stub GetNamedLocaleHashNode ++@ stdcall InterlockedPushListSList(ptr ptr ptr long) kernel32.InterlockedPushListSList ++@ stub InternalLcidToName ++@ stdcall AccessCheck(ptr long long ptr ptr ptr ptr ptr) advapi32.AccessCheck ++@ stdcall AccessCheckAndAuditAlarmW(wstr ptr wstr wstr ptr long ptr long ptr ptr ptr) advapi32.AccessCheckAndAuditAlarmW ++@ stdcall AccessCheckByType(ptr ptr long long ptr long ptr ptr ptr ptr ptr) advapi32.AccessCheckByType ++@ stub AccessCheckByTypeAndAuditAlarmW ++@ stub AccessCheckByTypeResultList ++@ stub AccessCheckByTypeResultListAndAuditAlarmByHandleW ++@ stub AccessCheckByTypeResultListAndAuditAlarmW ++@ stdcall AcquireSRWLockExclusive(ptr) kernel32.AcquireSRWLockExclusive ++@ stdcall AcquireSRWLockShared(ptr) kernel32.AcquireSRWLockShared ++@ stub AcquireStateLock ++@ stdcall ActivateActCtx(ptr ptr) kernel32.ActivateActCtx ++@ stdcall AddAccessAllowedAce(ptr long long ptr) advapi32.AddAccessAllowedAce ++@ stdcall AddAccessAllowedAceEx(ptr long long long ptr) advapi32.AddAccessAllowedAceEx ++@ stub AddAccessAllowedObjectAce ++@ stdcall AddAccessDeniedAce(ptr long long ptr) advapi32.AddAccessDeniedAce ++@ stdcall AddAccessDeniedAceEx(ptr long long long ptr) advapi32.AddAccessDeniedAceEx ++@ stub AddAccessDeniedObjectAce ++@ stdcall AddAce(ptr long long ptr long) advapi32.AddAce ++@ stdcall AddAuditAccessAce(ptr long long ptr long long) advapi32.AddAuditAccessAce ++@ stdcall AddAuditAccessAceEx(ptr long long long ptr long long) advapi32.AddAuditAccessAceEx ++@ stub AddAuditAccessObjectAce ++@ stub AddDllDirectory ++@ stdcall AddMandatoryAce(ptr long long long ptr) advapi32.AddMandatoryAce ++@ stdcall AddRefActCtx(ptr) kernel32.AddRefActCtx ++@ stub AddResourceAttributeAce ++@ stub AddSIDToBoundaryDescriptor ++@ stub AddScopedPolicyIDAce ++@ stdcall AddVectoredContinueHandler(long ptr) kernel32.AddVectoredContinueHandler ++@ stdcall AddVectoredExceptionHandler(long ptr) kernel32.AddVectoredExceptionHandler ++@ stdcall AdjustTokenGroups(long long ptr long ptr ptr) advapi32.AdjustTokenGroups ++@ stdcall AdjustTokenPrivileges(long long ptr long ptr ptr) advapi32.AdjustTokenPrivileges ++@ stdcall AllocConsole() kernel32.AllocConsole ++@ stdcall AllocateAndInitializeSid(ptr long long long long long long long long long ptr) advapi32.AllocateAndInitializeSid ++@ stdcall AllocateLocallyUniqueId(ptr) advapi32.AllocateLocallyUniqueId ++@ stdcall AllocateUserPhysicalPages(long ptr ptr) kernel32.AllocateUserPhysicalPages ++@ stub AllocateUserPhysicalPagesNuma ++@ stub AppContainerDeriveSidFromMoniker ++@ stub AppContainerFreeMemory ++@ stub AppContainerLookupDisplayNameMrtReference ++@ stub AppContainerLookupMoniker ++@ stub AppContainerRegisterSid ++@ stub AppContainerUnregisterSid ++@ stub AppXFreeMemory ++@ stub AppXGetApplicationData ++@ stub AppXGetDevelopmentMode ++@ stub AppXGetOSMaxVersionTested ++@ stub AppXGetOSMinVersion ++@ stub AppXGetPackageCapabilities ++@ stub AppXGetPackageSid ++@ stub AppXLookupDisplayName ++@ stub AppXLookupMoniker ++@ stub AppXPostSuccessExtension ++@ stub AppXPreCreationExtension ++@ stub AppXReleaseAppXContext ++@ stub AppXUpdatePackageCapabilities ++@ stub ApplicationUserModelIdFromProductId ++@ stdcall AreAllAccessesGranted(long long) advapi32.AreAllAccessesGranted ++@ stdcall AreAnyAccessesGranted(long long) advapi32.AreAnyAccessesGranted ++@ stdcall AreFileApisANSI() kernel32.AreFileApisANSI ++@ stub AreThereVisibleLogoffScriptsInternal ++@ stub AreThereVisibleShutdownScriptsInternal ++@ stdcall AttachConsole(long) kernel32.AttachConsole ++@ stub BaseCheckAppcompatCache ++@ stub BaseCheckAppcompatCacheEx ++@ stub BaseCleanupAppcompatCacheSupport ++@ stub BaseDllFreeResourceId ++@ stub BaseDllMapResourceIdW ++@ stub BaseDumpAppcompatCache ++@ stub BaseFlushAppcompatCache ++@ stub BaseFormatObjectAttributes ++@ stub BaseFreeAppCompatDataForProcess ++@ stub BaseGetNamedObjectDirectory ++@ stub BaseInitAppcompatCacheSupport ++@ stub BaseIsAppcompatInfrastructureDisabled ++@ stub BaseMarkFileForDelete ++@ stub BaseReadAppCompatDataForProcess ++@ stub BaseUpdateAppcompatCache ++@ stub BasepAdjustObjectAttributesForPrivateNamespace ++@ stub BasepCopyFileCallback ++@ stub BasepCopyFileExW ++@ stub BasepNotifyTrackingService ++@ stdcall Beep(long long) kernel32.Beep ++@ stub CLOSE_LOCAL_HANDLE_INTERNAL ++@ stdcall CallbackMayRunLong(ptr) kernel32.CallbackMayRunLong ++@ stub CalloutOnFiberStack ++@ stdcall CancelIo(long) kernel32.CancelIo ++@ stdcall CancelIoEx(long ptr) kernel32.CancelIoEx ++@ stdcall CancelSynchronousIo(long) kernel32.CancelSynchronousIo ++@ stub CancelThreadpoolIo ++@ stdcall CancelWaitableTimer(long) kernel32.CancelWaitableTimer ++@ stub CeipIsOptedIn ++@ stdcall ChangeTimerQueueTimer(ptr ptr long long) kernel32.ChangeTimerQueueTimer ++@ stdcall CharLowerA(str) user32.CharLowerA ++@ stdcall CharLowerBuffA(str long) user32.CharLowerBuffA ++@ stdcall CharLowerBuffW(wstr long) user32.CharLowerBuffW ++@ stdcall CharLowerW(wstr) user32.CharLowerW ++@ stdcall CharNextA(str) user32.CharNextA ++@ stdcall CharNextExA(long str long) user32.CharNextExA ++@ stdcall CharNextW(wstr) user32.CharNextW ++@ stdcall CharPrevA(str str) user32.CharPrevA ++@ stdcall CharPrevExA(long str str long) user32.CharPrevExA ++@ stdcall CharPrevW(wstr wstr) user32.CharPrevW ++@ stdcall CharUpperA(str) user32.CharUpperA ++@ stdcall CharUpperBuffA(str long) user32.CharUpperBuffA ++@ stdcall CharUpperBuffW(wstr long) user32.CharUpperBuffW ++@ stdcall CharUpperW(wstr) user32.CharUpperW ++@ stub CheckGroupPolicyEnabled ++@ stub CheckIfStateChangeNotificationExists ++@ stdcall CheckRemoteDebuggerPresent(long ptr) kernel32.CheckRemoteDebuggerPresent ++@ stub CheckTokenCapability ++@ stdcall CheckTokenMembership(long ptr ptr) advapi32.CheckTokenMembership ++@ stub CheckTokenMembershipEx ++@ stdcall ChrCmpIA(long long) shlwapi.ChrCmpIA ++@ stdcall ChrCmpIW(long long) shlwapi.ChrCmpIW ++@ stdcall ClearCommBreak(long) kernel32.ClearCommBreak ++@ stdcall ClearCommError(long ptr ptr) kernel32.ClearCommError ++@ stub CloseGlobalizationUserSettingsKey ++@ stdcall CloseHandle(long) kernel32.CloseHandle ++@ stub ClosePackageInfo ++@ stub ClosePrivateNamespace ++@ stub CloseState ++@ stub CloseStateAtom ++@ stub CloseStateChangeNotification ++@ stub CloseStateContainer ++@ stub CloseStateLock ++@ stdcall CloseThreadpool(ptr) kernel32.CloseThreadpool ++@ stdcall CloseThreadpoolCleanupGroup(ptr) kernel32.CloseThreadpoolCleanupGroup ++@ stdcall CloseThreadpoolCleanupGroupMembers(ptr long ptr) kernel32.CloseThreadpoolCleanupGroupMembers ++@ stub CloseThreadpoolIo ++@ stdcall CloseThreadpoolTimer(ptr) kernel32.CloseThreadpoolTimer ++@ stdcall CloseThreadpoolWait(ptr) kernel32.CloseThreadpoolWait ++@ stdcall CloseThreadpoolWork(ptr) kernel32.CloseThreadpoolWork ++@ stub CommitStateAtom ++@ stdcall CompareFileTime(ptr ptr) kernel32.CompareFileTime ++@ stub CompareObjectHandles ++@ stdcall CompareStringA(long long str long str long) kernel32.CompareStringA ++@ stdcall CompareStringEx(wstr long wstr long wstr long ptr ptr long) kernel32.CompareStringEx ++@ stdcall CompareStringOrdinal(wstr long wstr long long) kernel32.CompareStringOrdinal ++@ stdcall CompareStringW(long long wstr long wstr long) kernel32.CompareStringW ++@ stdcall ConnectNamedPipe(long ptr) kernel32.ConnectNamedPipe ++@ stdcall ContinueDebugEvent(long long long) kernel32.ContinueDebugEvent ++@ stdcall ConvertDefaultLocale(long) kernel32.ConvertDefaultLocale ++@ stdcall ConvertFiberToThread() kernel32.ConvertFiberToThread ++@ stdcall ConvertThreadToFiber(ptr) kernel32.ConvertThreadToFiber ++@ stdcall ConvertThreadToFiberEx(ptr long) kernel32.ConvertThreadToFiberEx ++@ stdcall ConvertToAutoInheritPrivateObjectSecurity(ptr ptr ptr ptr long ptr) advapi32.ConvertToAutoInheritPrivateObjectSecurity ++@ stub CopyContext ++@ stub CopyFile2 ++@ stdcall CopyFileExW(wstr wstr ptr ptr ptr long) kernel32.CopyFileExW ++@ stdcall CopyFileW(wstr wstr long) kernel32.CopyFileW ++@ stdcall CopySid(long ptr ptr) advapi32.CopySid ++@ stdcall CreateActCtxW(ptr) kernel32.CreateActCtxW ++@ stub CreateAppContainerToken ++@ stub CreateBoundaryDescriptorW ++@ stdcall CreateConsoleScreenBuffer(long long ptr long ptr) kernel32.CreateConsoleScreenBuffer ++@ stdcall CreateDirectoryA(str ptr) kernel32.CreateDirectoryA ++@ stdcall CreateDirectoryExW(wstr wstr ptr) kernel32.CreateDirectoryExW ++@ stdcall CreateDirectoryW(wstr ptr) kernel32.CreateDirectoryW ++@ stdcall CreateEventA(ptr long long str) kernel32.CreateEventA ++@ stdcall CreateEventExA(ptr str long long) kernel32.CreateEventExA ++@ stdcall CreateEventExW(ptr wstr long long) kernel32.CreateEventExW ++@ stdcall CreateEventW(ptr long long wstr) kernel32.CreateEventW ++@ stdcall CreateFiber(long ptr ptr) kernel32.CreateFiber ++@ stdcall CreateFiberEx(long long long ptr ptr) kernel32.CreateFiberEx ++@ stdcall CreateFile2(wstr long long long ptr) kernel32.CreateFile2 ++@ stdcall CreateFileA(str long long ptr long long long) kernel32.CreateFileA ++@ stub CreateFileMappingFromApp ++@ stub CreateFileMappingNumaW ++@ stdcall CreateFileMappingW(long ptr long long long wstr) kernel32.CreateFileMappingW ++@ stdcall CreateFileW(wstr long long ptr long long long) kernel32.CreateFileW ++@ stdcall CreateHardLinkA(str str ptr) kernel32.CreateHardLinkA ++@ stdcall CreateHardLinkW(wstr wstr ptr) kernel32.CreateHardLinkW ++@ stdcall CreateIoCompletionPort(long long long long) kernel32.CreateIoCompletionPort ++@ stdcall CreateMemoryResourceNotification(long) kernel32.CreateMemoryResourceNotification ++@ stdcall CreateMutexA(ptr long str) kernel32.CreateMutexA ++@ stdcall CreateMutexExA(ptr str long long) kernel32.CreateMutexExA ++@ stdcall CreateMutexExW(ptr wstr long long) kernel32.CreateMutexExW ++@ stdcall CreateMutexW(ptr long wstr) kernel32.CreateMutexW ++@ stdcall CreateNamedPipeW(wstr long long long long long long ptr) kernel32.CreateNamedPipeW ++@ stdcall CreatePipe(ptr ptr ptr long) kernel32.CreatePipe ++@ stub CreatePrivateNamespaceW ++@ stdcall CreatePrivateObjectSecurity(ptr ptr ptr long long ptr) advapi32.CreatePrivateObjectSecurity ++@ stub CreatePrivateObjectSecurityEx ++@ stdcall CreatePrivateObjectSecurityWithMultipleInheritance(ptr ptr ptr ptr long long long long ptr) advapi32.CreatePrivateObjectSecurityWithMultipleInheritance ++@ stdcall CreateProcessA(str str ptr ptr long long ptr str ptr ptr) kernel32.CreateProcessA ++@ stdcall CreateProcessAsUserA(long str str ptr ptr long long ptr str ptr ptr) advapi32.CreateProcessAsUserA ++@ stdcall CreateProcessAsUserW(long wstr wstr ptr ptr long long ptr wstr ptr ptr) advapi32.CreateProcessAsUserW ++@ stub CreateProcessInternalA ++@ stub CreateProcessInternalW ++@ stdcall CreateProcessW(wstr wstr ptr ptr long long ptr wstr ptr ptr) kernel32.CreateProcessW ++@ stdcall CreateRemoteThread(long ptr long ptr long long ptr) kernel32.CreateRemoteThread ++@ stub CreateRemoteThreadEx ++@ stdcall CreateRestrictedToken(long long long ptr long ptr long ptr ptr) advapi32.CreateRestrictedToken ++@ stdcall CreateSemaphoreExW(ptr long long wstr long long) kernel32.CreateSemaphoreExW ++@ stdcall CreateSemaphoreW(ptr long long wstr) kernel32.CreateSemaphoreW ++@ stub CreateStateAtom ++@ stub CreateStateChangeNotification ++@ stub CreateStateContainer ++@ stub CreateStateLock ++@ stub CreateStateSubcontainer ++@ stdcall CreateSymbolicLinkW(wstr wstr long) kernel32.CreateSymbolicLinkW ++@ stdcall CreateThread(ptr long ptr long long ptr) kernel32.CreateThread ++@ stdcall CreateThreadpool(ptr) kernel32.CreateThreadpool ++@ stdcall CreateThreadpoolCleanupGroup() kernel32.CreateThreadpoolCleanupGroup ++@ stub CreateThreadpoolIo ++@ stdcall CreateThreadpoolTimer(ptr ptr ptr) kernel32.CreateThreadpoolTimer ++@ stdcall CreateThreadpoolWait(ptr ptr ptr) kernel32.CreateThreadpoolWait ++@ stdcall CreateThreadpoolWork(ptr ptr ptr) kernel32.CreateThreadpoolWork ++@ stdcall CreateTimerQueue() kernel32.CreateTimerQueue ++@ stdcall CreateTimerQueueTimer(ptr long ptr ptr long long long) kernel32.CreateTimerQueueTimer ++@ stdcall CreateWaitableTimerExW(ptr wstr long long) kernel32.CreateWaitableTimerExW ++@ stdcall CreateWaitableTimerW(ptr long wstr) kernel32.CreateWaitableTimerW ++@ stdcall CreateWellKnownSid(long ptr ptr ptr) advapi32.CreateWellKnownSid ++@ stub CtrlRoutine ++@ stdcall DeactivateActCtx(long ptr) kernel32.DeactivateActCtx ++@ stdcall DebugActiveProcess(long) kernel32.DebugActiveProcess ++@ stdcall DebugActiveProcessStop(long) kernel32.DebugActiveProcessStop ++@ stdcall DebugBreak() kernel32.DebugBreak ++@ stdcall DecodePointer(ptr) kernel32.DecodePointer ++@ stub DecodeRemotePointer ++@ stub DecodeSystemPointer ++@ stdcall DefineDosDeviceW(long wstr wstr) kernel32.DefineDosDeviceW ++@ stdcall DelayLoadFailureHook(str str) kernel32.DelayLoadFailureHook ++@ stub DelayLoadFailureHookLookup ++@ stdcall DeleteAce(ptr long) advapi32.DeleteAce ++@ stub DeleteBoundaryDescriptor ++@ stdcall DeleteCriticalSection(ptr) kernel32.DeleteCriticalSection ++@ stdcall DeleteFiber(ptr) kernel32.DeleteFiber ++@ stdcall DeleteFileA(str) kernel32.DeleteFileA ++@ stdcall DeleteFileW(wstr) kernel32.DeleteFileW ++@ stub DeleteProcThreadAttributeList ++@ stub DeleteStateAtomValue ++@ stub DeleteStateContainer ++@ stub DeleteStateContainerValue ++@ stub DeleteSynchronizationBarrier ++@ stdcall DeleteTimerQueueEx(long long) kernel32.DeleteTimerQueueEx ++@ stdcall DeleteTimerQueueTimer(long long long) kernel32.DeleteTimerQueueTimer ++@ stdcall DeleteVolumeMountPointW(wstr) kernel32.DeleteVolumeMountPointW ++@ stdcall DestroyPrivateObjectSecurity(ptr) advapi32.DestroyPrivateObjectSecurity ++@ stdcall DeviceIoControl(long long ptr long ptr long ptr ptr) kernel32.DeviceIoControl ++@ stub DisablePredefinedHandleTableInternal ++@ stdcall DisableThreadLibraryCalls(long) kernel32.DisableThreadLibraryCalls ++@ stdcall DisassociateCurrentThreadFromCallback(ptr) kernel32.DisassociateCurrentThreadFromCallback ++@ stub DiscardVirtualMemory ++@ stdcall DisconnectNamedPipe(long) kernel32.DisconnectNamedPipe ++@ stub DnsHostnameToComputerNameExW ++@ stub DsBindWithSpnExW ++@ stub DsCrackNamesW ++@ stub DsFreeDomainControllerInfoW ++@ stub DsFreeNameResultW ++@ stub DsFreeNgcKey ++@ stub DsFreePasswordCredentials ++@ stub DsGetDomainControllerInfoW ++@ stub DsMakePasswordCredentialsW ++@ stub DsReadNgcKeyW ++@ stub DsUnBindW ++@ stub DsWriteNgcKeyW ++@ stdcall DuplicateHandle(long long long ptr long long long) kernel32.DuplicateHandle ++@ stub DuplicateStateContainerHandle ++@ stdcall DuplicateToken(long long ptr) advapi32.DuplicateToken ++@ stdcall DuplicateTokenEx(long long ptr long long ptr) advapi32.DuplicateTokenEx ++@ stub EmptyWorkingSet ++@ stdcall EncodePointer(ptr) kernel32.EncodePointer ++@ stub EncodeRemotePointer ++@ stub EncodeSystemPointer ++@ stub EnterCriticalPolicySectionInternal ++@ stdcall EnterCriticalSection(ptr) kernel32.EnterCriticalSection ++@ stub EnterSynchronizationBarrier ++@ stdcall EnumCalendarInfoExEx(ptr wstr long wstr long long) kernel32.EnumCalendarInfoExEx ++@ stdcall EnumCalendarInfoExW(ptr long long long) kernel32.EnumCalendarInfoExW ++@ stdcall EnumCalendarInfoW(ptr long long long) kernel32.EnumCalendarInfoW ++@ stdcall EnumDateFormatsExEx(ptr wstr long long) kernel32.EnumDateFormatsExEx ++@ stdcall EnumDateFormatsExW(ptr long long) kernel32.EnumDateFormatsExW ++@ stdcall EnumDateFormatsW(ptr long long) kernel32.EnumDateFormatsW ++@ stub EnumDeviceDrivers ++@ stub EnumDynamicTimeZoneInformation ++@ stdcall EnumLanguageGroupLocalesW(ptr long long ptr) kernel32.EnumLanguageGroupLocalesW ++@ stub EnumPageFilesA ++@ stub EnumPageFilesW ++@ stub EnumProcessModules ++@ stub EnumProcessModulesEx ++@ stub EnumProcesses ++@ stdcall EnumResourceLanguagesExA(long str str ptr long long long) kernel32.EnumResourceLanguagesExA ++@ stdcall EnumResourceLanguagesExW(long wstr wstr ptr long long long) kernel32.EnumResourceLanguagesExW ++@ stub EnumResourceNamesExA ++@ stub EnumResourceNamesExW ++@ stub EnumResourceTypesExA ++@ stub EnumResourceTypesExW ++@ stdcall EnumSystemCodePagesW(ptr long) kernel32.EnumSystemCodePagesW ++@ stub EnumSystemFirmwareTables ++@ stdcall EnumSystemGeoID(long long ptr) kernel32.EnumSystemGeoID ++@ stdcall EnumSystemLanguageGroupsW(ptr long ptr) kernel32.EnumSystemLanguageGroupsW ++@ stdcall EnumSystemLocalesA(ptr long) kernel32.EnumSystemLocalesA ++@ stdcall EnumSystemLocalesEx(ptr long long ptr) kernel32.EnumSystemLocalesEx ++@ stdcall EnumSystemLocalesW(ptr long) kernel32.EnumSystemLocalesW ++@ stdcall EnumTimeFormatsEx(ptr wstr long long) kernel32.EnumTimeFormatsEx ++@ stdcall EnumTimeFormatsW(ptr long long) kernel32.EnumTimeFormatsW ++@ stdcall EnumUILanguagesW(ptr long long) kernel32.EnumUILanguagesW ++@ stub EnumerateStateAtomValues ++@ stub EnumerateStateContainerItems ++@ stub EqualDomainSid ++@ stdcall EqualPrefixSid(ptr ptr) advapi32.EqualPrefixSid ++@ stdcall EqualSid(ptr ptr) advapi32.EqualSid ++@ stdcall EscapeCommFunction(long long) kernel32.EscapeCommFunction ++@ stdcall EventActivityIdControl(long ptr) advapi32.EventActivityIdControl ++@ stdcall EventEnabled(int64 ptr) advapi32.EventEnabled ++@ stdcall EventProviderEnabled(int64 long int64) advapi32.EventProviderEnabled ++@ stdcall EventRegister(ptr ptr ptr ptr) advapi32.EventRegister ++@ stdcall EventSetInformation(int64 long ptr long) advapi32.EventSetInformation ++@ stdcall EventUnregister(int64) advapi32.EventUnregister ++@ stdcall EventWrite(int64 ptr long ptr) advapi32.EventWrite ++@ stub EventWriteEx ++@ stub EventWriteString ++@ stub EventWriteTransfer ++@ stdcall ExitProcess(long) kernel32.ExitProcess ++@ stdcall ExitThread(long) kernel32.ExitThread ++@ stdcall ExpandEnvironmentStringsA(str ptr long) kernel32.ExpandEnvironmentStringsA ++@ stdcall ExpandEnvironmentStringsW(wstr ptr long) kernel32.ExpandEnvironmentStringsW ++@ stdcall FatalAppExitA(long str) kernel32.FatalAppExitA ++@ stdcall FatalAppExitW(long wstr) kernel32.FatalAppExitW ++@ stdcall FileTimeToLocalFileTime(ptr ptr) kernel32.FileTimeToLocalFileTime ++@ stdcall FileTimeToSystemTime(ptr ptr) kernel32.FileTimeToSystemTime ++@ stdcall FillConsoleOutputAttribute(long long long long ptr) kernel32.FillConsoleOutputAttribute ++@ stdcall FillConsoleOutputCharacterA(long long long long ptr) kernel32.FillConsoleOutputCharacterA ++@ stdcall FillConsoleOutputCharacterW(long long long long ptr) kernel32.FillConsoleOutputCharacterW ++@ stdcall FindActCtxSectionGuid(long ptr long ptr ptr) kernel32.FindActCtxSectionGuid ++@ stdcall FindActCtxSectionStringW(long ptr long wstr ptr) kernel32.FindActCtxSectionStringW ++@ stdcall FindClose(long) kernel32.FindClose ++@ stdcall FindCloseChangeNotification(long) kernel32.FindCloseChangeNotification ++@ stdcall FindFirstChangeNotificationA(str long long) kernel32.FindFirstChangeNotificationA ++@ stdcall FindFirstChangeNotificationW(wstr long long) kernel32.FindFirstChangeNotificationW ++@ stdcall FindFirstFileA(str ptr) kernel32.FindFirstFileA ++@ stdcall FindFirstFileExA(str long ptr long ptr long) kernel32.FindFirstFileExA ++@ stdcall FindFirstFileExW(wstr long ptr long ptr long) kernel32.FindFirstFileExW ++@ stub FindFirstFileNameW ++@ stdcall FindFirstFileW(wstr ptr) kernel32.FindFirstFileW ++@ stdcall FindFirstFreeAce(ptr ptr) advapi32.FindFirstFreeAce ++@ stub FindFirstStreamW ++@ stdcall FindFirstVolumeW(ptr long) kernel32.FindFirstVolumeW ++@ stub FindNLSString ++@ stub FindNLSStringEx ++@ stdcall FindNextChangeNotification(long) kernel32.FindNextChangeNotification ++@ stdcall FindNextFileA(long ptr) kernel32.FindNextFileA ++@ stub FindNextFileNameW ++@ stdcall FindNextFileW(long ptr) kernel32.FindNextFileW ++@ stub FindNextStreamW ++@ stdcall FindNextVolumeW(long ptr long) kernel32.FindNextVolumeW ++@ stub FindPackagesByPackageFamily ++@ stdcall FindResourceExW(long wstr wstr long) kernel32.FindResourceExW ++@ stdcall FindResourceW(long wstr wstr) kernel32.FindResourceW ++@ stub FindStringOrdinal ++@ stdcall FindVolumeClose(ptr) kernel32.FindVolumeClose ++@ stdcall FlsAlloc(ptr) kernel32.FlsAlloc ++@ stdcall FlsFree(long) kernel32.FlsFree ++@ stdcall FlsGetValue(long) kernel32.FlsGetValue ++@ stdcall FlsSetValue(long ptr) kernel32.FlsSetValue ++@ stdcall FlushConsoleInputBuffer(long) kernel32.FlushConsoleInputBuffer ++@ stdcall FlushFileBuffers(long) kernel32.FlushFileBuffers ++@ stdcall FlushInstructionCache(long long long) kernel32.FlushInstructionCache ++@ stdcall FlushProcessWriteBuffers() kernel32.FlushProcessWriteBuffers ++@ stdcall FlushViewOfFile(ptr long) kernel32.FlushViewOfFile ++@ stdcall FoldStringW(long wstr long ptr long) kernel32.FoldStringW ++@ stub ForceSyncFgPolicyInternal ++@ stub FormatApplicationUserModelId ++@ stdcall FormatMessageA(long ptr long long ptr long ptr) kernel32.FormatMessageA ++@ stdcall FormatMessageW(long ptr long long ptr long ptr) kernel32.FormatMessageW ++@ stdcall FreeConsole() kernel32.FreeConsole ++@ stdcall FreeEnvironmentStringsA(ptr) kernel32.FreeEnvironmentStringsA ++@ stdcall FreeEnvironmentStringsW(ptr) kernel32.FreeEnvironmentStringsW ++@ stub FreeGPOListInternalA ++@ stub FreeGPOListInternalW ++@ stdcall FreeLibrary(long) kernel32.FreeLibrary ++@ stdcall FreeLibraryAndExitThread(long long) kernel32.FreeLibraryAndExitThread ++@ stdcall FreeLibraryWhenCallbackReturns(ptr ptr) kernel32.FreeLibraryWhenCallbackReturns ++@ stdcall FreeResource(long) kernel32.FreeResource ++@ stdcall FreeSid(ptr) advapi32.FreeSid ++@ stdcall FreeUserPhysicalPages(long ptr ptr) kernel32.FreeUserPhysicalPages ++@ stdcall GenerateConsoleCtrlEvent(long long) kernel32.GenerateConsoleCtrlEvent ++@ stub GenerateGPNotificationInternal ++@ stdcall GetACP() kernel32.GetACP ++@ stdcall GetAcceptLanguagesA(ptr ptr) shlwapi.GetAcceptLanguagesA ++@ stdcall GetAcceptLanguagesW(ptr ptr) shlwapi.GetAcceptLanguagesW ++@ stdcall GetAce(ptr long ptr) advapi32.GetAce ++@ stdcall GetAclInformation(ptr ptr long long) advapi32.GetAclInformation ++@ stub GetAdjustObjectAttributesForPrivateNamespaceRoutine ++@ stub GetAlternatePackageRoots ++@ stub GetAppContainerAce ++@ stub GetAppContainerNamedObjectPath ++@ stub GetAppDataFolder ++@ stub GetAppModelVersion ++@ stub GetApplicationRecoveryCallback ++@ stub GetApplicationRestartSettings ++@ stub GetApplicationUserModelId ++@ stub GetApplicationUserModelIdFromToken ++@ stub GetAppliedGPOListInternalA ++@ stub GetAppliedGPOListInternalW ++@ stub GetCPFileNameFromRegistry ++@ stdcall GetCPInfo(long ptr) kernel32.GetCPInfo ++@ stdcall GetCPInfoExW(long long ptr) kernel32.GetCPInfoExW ++@ stub GetCachedSigningLevel ++@ stub GetCalendar ++@ stdcall GetCalendarInfoEx(wstr long ptr long ptr long ptr) kernel32.GetCalendarInfoEx ++@ stdcall GetCalendarInfoW(long long long ptr long ptr) kernel32.GetCalendarInfoW ++@ stdcall GetCommConfig(long ptr long) kernel32.GetCommConfig ++@ stdcall GetCommMask(long ptr) kernel32.GetCommMask ++@ stdcall GetCommModemStatus(long ptr) kernel32.GetCommModemStatus ++@ stdcall GetCommProperties(long ptr) kernel32.GetCommProperties ++@ stdcall GetCommState(long ptr) kernel32.GetCommState ++@ stdcall GetCommTimeouts(long ptr) kernel32.GetCommTimeouts ++@ stdcall GetCommandLineA() kernel32.GetCommandLineA ++@ stdcall GetCommandLineW() kernel32.GetCommandLineW ++@ stdcall GetCompressedFileSizeA(long ptr) kernel32.GetCompressedFileSizeA ++@ stdcall GetCompressedFileSizeW(long ptr) kernel32.GetCompressedFileSizeW ++@ stdcall GetComputerNameExA(long ptr ptr) kernel32.GetComputerNameExA ++@ stdcall GetComputerNameExW(long ptr ptr) kernel32.GetComputerNameExW ++@ stdcall GetConsoleCP() kernel32.GetConsoleCP ++@ stdcall GetConsoleCursorInfo(long ptr) kernel32.GetConsoleCursorInfo ++@ stdcall GetConsoleInputExeNameA(long ptr) kernel32.GetConsoleInputExeNameA ++@ stdcall GetConsoleInputExeNameW(long ptr) kernel32.GetConsoleInputExeNameW ++@ stdcall GetConsoleMode(long ptr) kernel32.GetConsoleMode ++@ stdcall GetConsoleOutputCP() kernel32.GetConsoleOutputCP ++@ stdcall GetConsoleScreenBufferInfo(long ptr) kernel32.GetConsoleScreenBufferInfo ++@ stdcall GetConsoleScreenBufferInfoEx(long ptr) kernel32.GetConsoleScreenBufferInfoEx ++@ stdcall GetConsoleTitleW(ptr long) kernel32.GetConsoleTitleW ++@ stub GetCurrencyFormatEx ++@ stdcall GetCurrencyFormatW(long long str ptr str long) kernel32.GetCurrencyFormatW ++@ stdcall GetCurrentActCtx(ptr) kernel32.GetCurrentActCtx ++@ stub GetCurrentApplicationUserModelId ++@ stdcall GetCurrentDirectoryA(long ptr) kernel32.GetCurrentDirectoryA ++@ stdcall GetCurrentDirectoryW(long ptr) kernel32.GetCurrentDirectoryW ++@ stub GetCurrentPackageApplicationContext ++@ stub GetCurrentPackageApplicationResourcesContext ++@ stub GetCurrentPackageContext ++@ stdcall GetCurrentPackageFamilyName(ptr ptr) kernel32.GetCurrentPackageFamilyName ++@ stub GetCurrentPackageFullName ++@ stdcall GetCurrentPackageId(ptr ptr) kernel32.GetCurrentPackageId ++@ stub GetCurrentPackageInfo ++@ stub GetCurrentPackagePath ++@ stub GetCurrentPackageResourcesContext ++@ stub GetCurrentPackageSecurityContext ++@ stdcall -norelay GetCurrentProcess() kernel32.GetCurrentProcess ++@ stdcall -norelay GetCurrentProcessId() kernel32.GetCurrentProcessId ++@ stdcall GetCurrentProcessorNumber() kernel32.GetCurrentProcessorNumber ++@ stdcall GetCurrentProcessorNumberEx(ptr) kernel32.GetCurrentProcessorNumberEx ++@ stub GetCurrentTargetPlatformContext ++@ stdcall -norelay GetCurrentThread() kernel32.GetCurrentThread ++@ stdcall -norelay GetCurrentThreadId() kernel32.GetCurrentThreadId ++@ stub GetCurrentThreadStackLimits ++@ stdcall GetDateFormatA(long long ptr str ptr long) kernel32.GetDateFormatA ++@ stdcall GetDateFormatEx(wstr long ptr wstr ptr long wstr) kernel32.GetDateFormatEx ++@ stdcall GetDateFormatW(long long ptr wstr ptr long) kernel32.GetDateFormatW ++@ stub GetDeviceDriverBaseNameA ++@ stub GetDeviceDriverBaseNameW ++@ stub GetDeviceDriverFileNameA ++@ stub GetDeviceDriverFileNameW ++@ stdcall GetDiskFreeSpaceA(str ptr ptr ptr ptr) kernel32.GetDiskFreeSpaceA ++@ stdcall GetDiskFreeSpaceExA(str ptr ptr ptr) kernel32.GetDiskFreeSpaceExA ++@ stdcall GetDiskFreeSpaceExW(wstr ptr ptr ptr) kernel32.GetDiskFreeSpaceExW ++@ stdcall GetDiskFreeSpaceW(wstr ptr ptr ptr ptr) kernel32.GetDiskFreeSpaceW ++@ stdcall GetDriveTypeA(str) kernel32.GetDriveTypeA ++@ stdcall GetDriveTypeW(wstr) kernel32.GetDriveTypeW ++@ stub GetDurationFormatEx ++@ stdcall GetDynamicTimeZoneInformation(ptr) kernel32.GetDynamicTimeZoneInformation ++@ stub GetDynamicTimeZoneInformationEffectiveYears ++@ stub GetEffectivePackageStatusForUser ++@ stub GetEightBitStringToUnicodeSizeRoutine ++@ stub GetEightBitStringToUnicodeStringRoutine ++@ stub GetEnabledXStateFeatures ++@ stdcall GetEnvironmentStrings() kernel32.GetEnvironmentStrings ++@ stdcall GetEnvironmentStringsA() kernel32.GetEnvironmentStringsA ++@ stdcall GetEnvironmentStringsW() kernel32.GetEnvironmentStringsW ++@ stdcall GetEnvironmentVariableA(str ptr long) kernel32.GetEnvironmentVariableA ++@ stdcall GetEnvironmentVariableW(wstr ptr long) kernel32.GetEnvironmentVariableW ++@ stub GetEraNameCountedString ++@ stdcall GetErrorMode() kernel32.GetErrorMode ++@ stdcall GetExitCodeProcess(long ptr) kernel32.GetExitCodeProcess ++@ stdcall GetExitCodeThread(long ptr) kernel32.GetExitCodeThread ++@ stub GetFallbackDisplayName ++@ stdcall GetFileAttributesA(str) kernel32.GetFileAttributesA ++@ stdcall GetFileAttributesExA(str long ptr) kernel32.GetFileAttributesExA ++@ stdcall GetFileAttributesExW(wstr long ptr) kernel32.GetFileAttributesExW ++@ stdcall GetFileAttributesW(wstr) kernel32.GetFileAttributesW ++@ stdcall GetFileInformationByHandle(long ptr) kernel32.GetFileInformationByHandle ++@ stdcall GetFileInformationByHandleEx(long long ptr long) kernel32.GetFileInformationByHandleEx ++@ stdcall GetFileMUIInfo(long wstr ptr ptr) kernel32.GetFileMUIInfo ++@ stdcall GetFileMUIPath(long wstr wstr ptr ptr ptr ptr) kernel32.GetFileMUIPath ++@ stdcall GetFileSecurityW(wstr long ptr long ptr) advapi32.GetFileSecurityW ++@ stdcall GetFileSize(long ptr) kernel32.GetFileSize ++@ stdcall GetFileSizeEx(long ptr) kernel32.GetFileSizeEx ++@ stdcall GetFileTime(long ptr ptr ptr) kernel32.GetFileTime ++@ stdcall GetFileType(long) kernel32.GetFileType ++@ stub GetFileVersionInfoA ++@ stub GetFileVersionInfoByHandle ++@ stub GetFileVersionInfoExA ++@ stub GetFileVersionInfoExW ++@ stub GetFileVersionInfoSizeA ++@ stub GetFileVersionInfoSizeExA ++@ stub GetFileVersionInfoSizeExW ++@ stub GetFileVersionInfoSizeW ++@ stub GetFileVersionInfoW ++@ stdcall GetFinalPathNameByHandleA(long ptr long long) kernel32.GetFinalPathNameByHandleA ++@ stdcall GetFinalPathNameByHandleW(long ptr long long) kernel32.GetFinalPathNameByHandleW ++@ stdcall GetFullPathNameA(str long ptr ptr) kernel32.GetFullPathNameA ++@ stdcall GetFullPathNameW(wstr long ptr ptr) kernel32.GetFullPathNameW ++@ stub GetGPOListInternalA ++@ stub GetGPOListInternalW ++@ stdcall GetGeoInfoW(long long ptr long long) kernel32.GetGeoInfoW ++@ stdcall GetHandleInformation(long ptr) kernel32.GetHandleInformation ++@ stub GetHivePath ++@ stub GetIntegratedDisplaySize ++@ stdcall GetKernelObjectSecurity(long long ptr long ptr) advapi32.GetKernelObjectSecurity ++@ stub GetLargePageMinimum ++@ stdcall GetLargestConsoleWindowSize(long) kernel32.GetLargestConsoleWindowSize ++@ stdcall GetLastError() kernel32.GetLastError ++@ stdcall GetLengthSid(ptr) advapi32.GetLengthSid ++@ stdcall GetLocalTime(ptr) kernel32.GetLocalTime ++@ stdcall GetLocaleInfoA(long long ptr long) kernel32.GetLocaleInfoA ++@ stdcall GetLocaleInfoEx(wstr long ptr long) kernel32.GetLocaleInfoEx ++@ stub GetLocaleInfoHelper ++@ stdcall GetLocaleInfoW(long long ptr long) kernel32.GetLocaleInfoW ++@ stdcall GetLogicalDriveStringsW(long ptr) kernel32.GetLogicalDriveStringsW ++@ stdcall GetLogicalDrives() kernel32.GetLogicalDrives ++@ stdcall GetLogicalProcessorInformation(ptr ptr) kernel32.GetLogicalProcessorInformation ++@ stdcall GetLogicalProcessorInformationEx(long ptr ptr) kernel32.GetLogicalProcessorInformationEx ++@ stdcall GetLongPathNameA(str long long) kernel32.GetLongPathNameA ++@ stdcall GetLongPathNameW(wstr long long) kernel32.GetLongPathNameW ++@ stub GetMappedFileNameA ++@ stub GetMappedFileNameW ++@ stub GetMemoryErrorHandlingCapabilities ++@ stub GetModuleBaseNameA ++@ stub GetModuleBaseNameW ++@ stdcall GetModuleFileNameA(long ptr long) kernel32.GetModuleFileNameA ++@ stub GetModuleFileNameExA ++@ stub GetModuleFileNameExW ++@ stdcall GetModuleFileNameW(long ptr long) kernel32.GetModuleFileNameW ++@ stdcall GetModuleHandleA(str) kernel32.GetModuleHandleA ++@ stdcall GetModuleHandleExA(long ptr ptr) kernel32.GetModuleHandleExA ++@ stdcall GetModuleHandleExW(long ptr ptr) kernel32.GetModuleHandleExW ++@ stdcall GetModuleHandleW(wstr) kernel32.GetModuleHandleW ++@ stub GetModuleInformation ++@ stub GetNLSVersion ++@ stub GetNLSVersionEx ++@ stub GetNamedPipeAttribute ++@ stub GetNamedPipeClientComputerNameW ++@ stdcall GetNamedPipeHandleStateW(long ptr ptr ptr ptr wstr long) kernel32.GetNamedPipeHandleStateW ++@ stdcall GetNamedPipeInfo(long ptr ptr ptr ptr) kernel32.GetNamedPipeInfo ++@ stdcall GetNativeSystemInfo(ptr) kernel32.GetNativeSystemInfo ++@ stub GetNextFgPolicyRefreshInfoInternal ++@ stdcall GetNumaHighestNodeNumber(ptr) kernel32.GetNumaHighestNodeNumber ++@ stub GetNumaNodeProcessorMaskEx ++@ stub GetNumberFormatEx ++@ stdcall GetNumberFormatW(long long wstr ptr ptr long) kernel32.GetNumberFormatW ++@ stdcall GetNumberOfConsoleInputEvents(long ptr) kernel32.GetNumberOfConsoleInputEvents ++@ stdcall GetOEMCP() kernel32.GetOEMCP ++@ stub GetOsManufacturingMode ++@ stub GetOsSafeBootMode ++@ stdcall GetOverlappedResult(long ptr ptr long) kernel32.GetOverlappedResult ++@ stub GetOverlappedResultEx ++@ stub GetPackageApplicationContext ++@ stub GetPackageApplicationIds ++@ stub GetPackageApplicationProperty ++@ stub GetPackageApplicationPropertyString ++@ stub GetPackageApplicationResourcesContext ++@ stub GetPackageContext ++@ stub GetPackageFamilyName ++@ stub GetPackageFamilyNameFromToken ++@ stub GetPackageFullName ++@ stub GetPackageFullNameFromToken ++@ stub GetPackageId ++@ stub GetPackageInfo ++@ stub GetPackageInstallTime ++@ stub GetPackageOSMaxVersionTested ++@ stub GetPackagePath ++@ stub GetPackagePathByFullName ++@ stub GetPackagePathOnVolume ++@ stub GetPackageProperty ++@ stub GetPackagePropertyString ++@ stub GetPackageResourcesContext ++@ stub GetPackageResourcesProperty ++@ stub GetPackageSecurityContext ++@ stub GetPackageSecurityProperty ++@ stub GetPackageStatus ++@ stub GetPackageStatusForUser ++@ stub GetPackageTargetPlatformProperty ++@ stub GetPackageVolumeSisPath ++@ stub GetPackagesByPackageFamily ++@ stub GetPerformanceInfo ++@ stdcall GetPhysicallyInstalledSystemMemory(ptr) kernel32.GetPhysicallyInstalledSystemMemory ++@ stub GetPreviousFgPolicyRefreshInfoInternal ++@ stdcall GetPriorityClass(long) kernel32.GetPriorityClass ++@ stdcall GetPrivateObjectSecurity(ptr long ptr long ptr) advapi32.GetPrivateObjectSecurity ++@ stdcall GetProcAddress(long str) kernel32.GetProcAddress ++@ stub GetProcAddressForCaller ++@ stub GetProcessDefaultCpuSets ++@ stub GetProcessGroupAffinity ++@ stdcall GetProcessHandleCount(long ptr) kernel32.GetProcessHandleCount ++@ stdcall -norelay GetProcessHeap() kernel32.GetProcessHeap ++@ stdcall GetProcessHeaps(long ptr) kernel32.GetProcessHeaps ++@ stdcall GetProcessId(long) kernel32.GetProcessId ++@ stdcall GetProcessIdOfThread(long) kernel32.GetProcessIdOfThread ++@ stub GetProcessImageFileNameA ++@ stub GetProcessImageFileNameW ++@ stub GetProcessInformation ++@ stub GetProcessMemoryInfo ++@ stub GetProcessMitigationPolicy ++@ stub GetProcessPreferredUILanguages ++@ stdcall GetProcessPriorityBoost(long ptr) kernel32.GetProcessPriorityBoost ++@ stdcall GetProcessShutdownParameters(ptr ptr) kernel32.GetProcessShutdownParameters ++@ stdcall GetProcessTimes(long ptr ptr ptr ptr) kernel32.GetProcessTimes ++@ stdcall GetProcessVersion(long) kernel32.GetProcessVersion ++@ stub GetProcessWorkingSetSizeEx ++@ stub GetProcessorSystemCycleTime ++@ stdcall GetProductInfo(long long long long ptr) kernel32.GetProductInfo ++@ stub GetPtrCalData ++@ stub GetPtrCalDataArray ++@ stub GetPublisherCacheFolder ++@ stub GetPublisherRootFolder ++@ stdcall GetQueuedCompletionStatus(long ptr ptr ptr long) kernel32.GetQueuedCompletionStatus ++@ stub GetQueuedCompletionStatusEx ++@ stub GetRegistryExtensionFlags ++@ stub GetRoamingLastObservedChangeTime ++@ stdcall GetSecurityDescriptorControl(ptr ptr ptr) advapi32.GetSecurityDescriptorControl ++@ stdcall GetSecurityDescriptorDacl(ptr ptr ptr ptr) advapi32.GetSecurityDescriptorDacl ++@ stdcall GetSecurityDescriptorGroup(ptr ptr ptr) advapi32.GetSecurityDescriptorGroup ++@ stdcall GetSecurityDescriptorLength(ptr) advapi32.GetSecurityDescriptorLength ++@ stdcall GetSecurityDescriptorOwner(ptr ptr ptr) advapi32.GetSecurityDescriptorOwner ++@ stub GetSecurityDescriptorRMControl ++@ stdcall GetSecurityDescriptorSacl(ptr ptr ptr ptr) advapi32.GetSecurityDescriptorSacl ++@ stub GetSerializedAtomBytes ++@ stub GetSharedLocalFolder ++@ stdcall GetShortPathNameW(wstr ptr long) kernel32.GetShortPathNameW ++@ stdcall GetSidIdentifierAuthority(ptr) advapi32.GetSidIdentifierAuthority ++@ stdcall GetSidLengthRequired(long) advapi32.GetSidLengthRequired ++@ stdcall GetSidSubAuthority(ptr long) advapi32.GetSidSubAuthority ++@ stdcall GetSidSubAuthorityCount(ptr) advapi32.GetSidSubAuthorityCount ++@ stub GetStagedPackageOrigin ++@ stub GetStagedPackagePathByFullName ++@ stdcall GetStartupInfoW(ptr) kernel32.GetStartupInfoW ++@ stub GetStateContainerDepth ++@ stub GetStateFolder ++@ stub GetStateRootFolder ++@ stub GetStateRootFolderBase ++@ stub GetStateSettingsFolder ++@ stub GetStateVersion ++@ stdcall GetStdHandle(long) kernel32.GetStdHandle ++@ stub GetStringScripts ++@ stub GetStringTableEntry ++@ stdcall GetStringTypeA(long long str long ptr) kernel32.GetStringTypeA ++@ stdcall GetStringTypeExW(long long wstr long ptr) kernel32.GetStringTypeExW ++@ stdcall GetStringTypeW(long wstr long ptr) kernel32.GetStringTypeW ++@ stub GetSystemAppDataFolder ++@ stub GetSystemAppDataKey ++@ stub GetSystemCpuSetInformation ++@ stdcall GetSystemDefaultLCID() kernel32.GetSystemDefaultLCID ++@ stdcall GetSystemDefaultLangID() kernel32.GetSystemDefaultLangID ++@ stdcall GetSystemDefaultLocaleName(ptr long) kernel32.GetSystemDefaultLocaleName ++@ stdcall GetSystemDefaultUILanguage() kernel32.GetSystemDefaultUILanguage ++@ stdcall GetSystemDirectoryA(ptr long) kernel32.GetSystemDirectoryA ++@ stdcall GetSystemDirectoryW(ptr long) kernel32.GetSystemDirectoryW ++@ stdcall GetSystemFileCacheSize(ptr ptr ptr) kernel32.GetSystemFileCacheSize ++@ stdcall GetSystemFirmwareTable(long long ptr long) kernel32.GetSystemFirmwareTable ++@ stdcall GetSystemInfo(ptr) kernel32.GetSystemInfo ++@ stub GetSystemMetadataPath ++@ stub GetSystemMetadataPathForPackage ++@ stub GetSystemMetadataPathForPackageFamily ++@ stdcall GetSystemPreferredUILanguages(long ptr ptr ptr) kernel32.GetSystemPreferredUILanguages ++@ stub GetSystemStateRootFolder ++@ stdcall GetSystemTime(ptr) kernel32.GetSystemTime ++@ stdcall GetSystemTimeAdjustment(ptr ptr ptr) kernel32.GetSystemTimeAdjustment ++@ stdcall GetSystemTimeAsFileTime(ptr) kernel32.GetSystemTimeAsFileTime ++@ stdcall GetSystemTimePreciseAsFileTime(ptr) kernel32.GetSystemTimePreciseAsFileTime ++@ stdcall GetSystemTimes(ptr ptr ptr) kernel32.GetSystemTimes ++@ stdcall GetSystemWindowsDirectoryA(ptr long) kernel32.GetSystemWindowsDirectoryA ++@ stdcall GetSystemWindowsDirectoryW(ptr long) kernel32.GetSystemWindowsDirectoryW ++@ stdcall GetSystemWow64DirectoryA(ptr long) kernel32.GetSystemWow64DirectoryA ++@ stdcall GetSystemWow64DirectoryW(ptr long) kernel32.GetSystemWow64DirectoryW ++@ stub GetTargetPlatformContext ++@ stdcall GetTempFileNameA(str str long ptr) kernel32.GetTempFileNameA ++@ stdcall GetTempFileNameW(wstr wstr long ptr) kernel32.GetTempFileNameW ++@ stdcall GetTempPathA(long ptr) kernel32.GetTempPathA ++@ stdcall GetTempPathW(long ptr) kernel32.GetTempPathW ++@ stdcall GetThreadContext(long ptr) kernel32.GetThreadContext ++@ stdcall GetThreadErrorMode() kernel32.GetThreadErrorMode ++@ stdcall GetThreadGroupAffinity(long ptr) kernel32.GetThreadGroupAffinity ++@ stdcall GetThreadIOPendingFlag(long ptr) kernel32.GetThreadIOPendingFlag ++@ stdcall GetThreadId(ptr) kernel32.GetThreadId ++@ stub GetThreadIdealProcessorEx ++@ stub GetThreadInformation ++@ stdcall GetThreadLocale() kernel32.GetThreadLocale ++@ stdcall GetThreadPreferredUILanguages(long ptr ptr ptr) kernel32.GetThreadPreferredUILanguages ++@ stdcall GetThreadPriority(long) kernel32.GetThreadPriority ++@ stdcall GetThreadPriorityBoost(long ptr) kernel32.GetThreadPriorityBoost ++@ stub GetThreadSelectedCpuSets ++@ stdcall GetThreadTimes(long ptr ptr ptr ptr) kernel32.GetThreadTimes ++@ stdcall GetThreadUILanguage() kernel32.GetThreadUILanguage ++@ stdcall -ret64 GetTickCount64() kernel32.GetTickCount64 ++@ stdcall GetTickCount() kernel32.GetTickCount ++@ stdcall GetTimeFormatA(long long ptr str ptr long) kernel32.GetTimeFormatA ++@ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long) kernel32.GetTimeFormatEx ++@ stdcall GetTimeFormatW(long long ptr wstr ptr long) kernel32.GetTimeFormatW ++@ stdcall GetTimeZoneInformation(ptr) kernel32.GetTimeZoneInformation ++@ stdcall GetTimeZoneInformationForYear(long ptr ptr) kernel32.GetTimeZoneInformationForYear ++@ stdcall GetTokenInformation(long long ptr long ptr) advapi32.GetTokenInformation ++@ stdcall GetTraceEnableFlags(int64) advapi32.GetTraceEnableFlags ++@ stdcall GetTraceEnableLevel(int64) advapi32.GetTraceEnableLevel ++@ stdcall -ret64 GetTraceLoggerHandle(ptr) advapi32.GetTraceLoggerHandle ++@ stub GetUILanguageInfo ++@ stub GetUnicodeStringToEightBitSizeRoutine ++@ stub GetUnicodeStringToEightBitStringRoutine ++@ stdcall GetUserDefaultLCID() kernel32.GetUserDefaultLCID ++@ stdcall GetUserDefaultLangID() kernel32.GetUserDefaultLangID ++@ stdcall GetUserDefaultLocaleName(ptr long) kernel32.GetUserDefaultLocaleName ++@ stdcall GetUserDefaultUILanguage() kernel32.GetUserDefaultUILanguage ++@ stdcall GetUserGeoID(long) kernel32.GetUserGeoID ++@ stub GetUserInfo ++@ stub GetUserInfoWord ++@ stub GetUserOverrideString ++@ stub GetUserOverrideWord ++@ stdcall GetUserPreferredUILanguages(long ptr ptr ptr) kernel32.GetUserPreferredUILanguages ++@ stdcall GetVersion() kernel32.GetVersion ++@ stdcall GetVersionExA(ptr) kernel32.GetVersionExA ++@ stdcall GetVersionExW(ptr) kernel32.GetVersionExW ++@ stdcall GetVolumeInformationA(str ptr long ptr ptr ptr ptr long) kernel32.GetVolumeInformationA ++@ stub GetVolumeInformationByHandleW ++@ stdcall GetVolumeInformationW(wstr ptr long ptr ptr ptr ptr long) kernel32.GetVolumeInformationW ++@ stdcall GetVolumeNameForVolumeMountPointW(wstr ptr long) kernel32.GetVolumeNameForVolumeMountPointW ++@ stdcall GetVolumePathNameW(wstr ptr long) kernel32.GetVolumePathNameW ++@ stdcall GetVolumePathNamesForVolumeNameW(wstr ptr long ptr) kernel32.GetVolumePathNamesForVolumeNameW ++@ stdcall GetWindowsAccountDomainSid(ptr ptr ptr) advapi32.GetWindowsAccountDomainSid ++@ stdcall GetWindowsDirectoryA(ptr long) kernel32.GetWindowsDirectoryA ++@ stdcall GetWindowsDirectoryW(ptr long) kernel32.GetWindowsDirectoryW ++@ stdcall GetWriteWatch(long ptr long ptr ptr ptr) kernel32.GetWriteWatch ++@ stub GetWsChanges ++@ stub GetWsChangesEx ++@ stub GetXStateFeaturesMask ++@ stdcall GlobalAlloc(long long) kernel32.GlobalAlloc ++@ stdcall GlobalFree(long) kernel32.GlobalFree ++@ stdcall GlobalMemoryStatusEx(ptr) kernel32.GlobalMemoryStatusEx ++@ stub HasPolicyForegroundProcessingCompletedInternal ++@ stdcall HashData(ptr long ptr long) shlwapi.HashData ++@ stdcall HeapAlloc(long long long) kernel32.HeapAlloc ++@ stdcall HeapCompact(long long) kernel32.HeapCompact ++@ stdcall HeapCreate(long long long) kernel32.HeapCreate ++@ stdcall HeapDestroy(long) kernel32.HeapDestroy ++@ stdcall HeapFree(long long ptr) kernel32.HeapFree ++@ stdcall HeapLock(long) kernel32.HeapLock ++@ stdcall HeapQueryInformation(long long ptr long ptr) kernel32.HeapQueryInformation ++@ stdcall HeapReAlloc(long long ptr long) kernel32.HeapReAlloc ++@ stdcall HeapSetInformation(ptr long ptr long) kernel32.HeapSetInformation ++@ stdcall HeapSize(long long ptr) kernel32.HeapSize ++@ stub HeapSummary ++@ stdcall HeapUnlock(long) kernel32.HeapUnlock ++@ stdcall HeapValidate(long long ptr) kernel32.HeapValidate ++@ stdcall HeapWalk(long ptr) kernel32.HeapWalk ++@ stdcall IdnToAscii(long wstr long ptr long) kernel32.IdnToAscii ++@ stdcall IdnToNameprepUnicode(long wstr long ptr long) kernel32.IdnToNameprepUnicode ++@ stdcall IdnToUnicode(long wstr long ptr long) kernel32.IdnToUnicode ++@ stdcall ImpersonateAnonymousToken(long) advapi32.ImpersonateAnonymousToken ++@ stdcall ImpersonateLoggedOnUser(long) advapi32.ImpersonateLoggedOnUser ++@ stdcall ImpersonateNamedPipeClient(long) advapi32.ImpersonateNamedPipeClient ++@ stdcall ImpersonateSelf(long) advapi32.ImpersonateSelf ++@ stub IncrementPackageStatusVersion ++@ stdcall InitOnceBeginInitialize(ptr long ptr ptr) kernel32.InitOnceBeginInitialize ++@ stdcall InitOnceComplete(ptr long ptr) kernel32.InitOnceComplete ++@ stdcall InitOnceExecuteOnce(ptr ptr ptr ptr) kernel32.InitOnceExecuteOnce ++@ stdcall InitOnceInitialize(ptr) kernel32.InitOnceInitialize ++@ stdcall InitializeAcl(ptr long long) advapi32.InitializeAcl ++@ stdcall InitializeConditionVariable(ptr) kernel32.InitializeConditionVariable ++@ stub InitializeContext ++@ stdcall InitializeCriticalSection(ptr) kernel32.InitializeCriticalSection ++@ stdcall InitializeCriticalSectionAndSpinCount(ptr long) kernel32.InitializeCriticalSectionAndSpinCount ++@ stdcall InitializeCriticalSectionEx(ptr long long) kernel32.InitializeCriticalSectionEx ++@ stub InitializeProcThreadAttributeList ++@ stub InitializeProcessForWsWatch ++@ stdcall InitializeSListHead(ptr) kernel32.InitializeSListHead ++@ stdcall InitializeSRWLock(ptr) kernel32.InitializeSRWLock ++@ stdcall InitializeSecurityDescriptor(ptr long) advapi32.InitializeSecurityDescriptor ++@ stdcall InitializeSid(ptr ptr long) advapi32.InitializeSid ++@ stub InitializeSynchronizationBarrier ++@ stub InstallELAMCertificateInfo ++@ stdcall -arch=i386 -ret64 InterlockedCompareExchange64(ptr int64 int64) kernel32.InterlockedCompareExchange64 ++@ stdcall -arch=i386 InterlockedCompareExchange(ptr long long) kernel32.InterlockedCompareExchange ++@ stdcall -arch=i386 InterlockedDecrement(ptr) kernel32.InterlockedDecrement ++@ stdcall -arch=i386 InterlockedExchange(ptr long) kernel32.InterlockedExchange ++@ stdcall -arch=i386 InterlockedExchangeAdd(ptr long ) kernel32.InterlockedExchangeAdd ++@ stdcall InterlockedFlushSList(ptr) kernel32.InterlockedFlushSList ++@ stdcall -arch=i386 InterlockedIncrement(ptr) kernel32.InterlockedIncrement ++@ stdcall InterlockedPopEntrySList(ptr) kernel32.InterlockedPopEntrySList ++@ stdcall InterlockedPushEntrySList(ptr ptr) kernel32.InterlockedPushEntrySList ++@ stub InterlockedPushListSListEx ++@ stub Internal_EnumCalendarInfo ++@ stub Internal_EnumDateFormats ++@ stub Internal_EnumLanguageGroupLocales ++@ stub Internal_EnumSystemCodePages ++@ stub Internal_EnumSystemLanguageGroups ++@ stub Internal_EnumSystemLocales ++@ stub Internal_EnumTimeFormats ++@ stub Internal_EnumUILanguages ++@ stub InternetTimeFromSystemTimeA ++@ stub InternetTimeFromSystemTimeW ++@ stub InternetTimeToSystemTimeA ++@ stub InternetTimeToSystemTimeW ++@ stub InvalidateAppModelVersionCache ++@ stdcall IsCharAlphaA(long) user32.IsCharAlphaA ++@ stdcall IsCharAlphaNumericA(long) user32.IsCharAlphaNumericA ++@ stdcall IsCharAlphaNumericW(long) user32.IsCharAlphaNumericW ++@ stdcall IsCharAlphaW(long) user32.IsCharAlphaW ++@ stdcall IsCharBlankW(long) shlwapi.IsCharBlankW ++@ stdcall IsCharCntrlW(ptr) shlwapi.IsCharCntrlW ++@ stdcall IsCharDigitW(long) shlwapi.IsCharDigitW ++@ stdcall IsCharLowerA(long) user32.IsCharLowerA ++@ stdcall IsCharLowerW(long) user32.IsCharLowerW ++@ stdcall IsCharPunctW(long) shlwapi.IsCharPunctW ++@ stdcall IsCharSpaceA(long) shlwapi.IsCharSpaceA ++@ stdcall IsCharSpaceW(long) shlwapi.IsCharSpaceW ++@ stdcall IsCharUpperA(long) user32.IsCharUpperA ++@ stdcall IsCharUpperW(long) user32.IsCharUpperW ++@ stdcall IsCharXDigitW(long) shlwapi.IsCharXDigitW ++@ stdcall IsDBCSLeadByte(long) kernel32.IsDBCSLeadByte ++@ stdcall IsDBCSLeadByteEx(long long) kernel32.IsDBCSLeadByteEx ++@ stdcall IsDebuggerPresent() kernel32.IsDebuggerPresent ++@ stub IsDeveloperModeEnabled ++@ stub IsDeveloperModePolicyApplied ++@ stdcall IsInternetESCEnabled() shlwapi.IsInternetESCEnabled ++@ stub IsNLSDefinedString ++@ stdcall IsNormalizedString(long wstr long) kernel32.IsNormalizedString ++@ stub IsProcessCritical ++@ stdcall IsProcessInJob(long long ptr) kernel32.IsProcessInJob ++@ stdcall IsProcessorFeaturePresent(long) kernel32.IsProcessorFeaturePresent ++@ stub IsSideloadingEnabled ++@ stub IsSideloadingPolicyApplied ++@ stub IsSyncForegroundPolicyRefresh ++@ stdcall IsThreadAFiber() kernel32.IsThreadAFiber ++@ stdcall IsThreadpoolTimerSet(ptr) kernel32.IsThreadpoolTimerSet ++@ stub IsTimeZoneRedirectionEnabled ++@ stdcall IsTokenRestricted(long) advapi32.IsTokenRestricted ++@ stdcall IsValidAcl(ptr) advapi32.IsValidAcl ++@ stdcall IsValidCodePage(long) kernel32.IsValidCodePage ++@ stdcall IsValidLanguageGroup(long long) kernel32.IsValidLanguageGroup ++@ stdcall IsValidLocale(long long) kernel32.IsValidLocale ++@ stdcall IsValidLocaleName(wstr) kernel32.IsValidLocaleName ++@ stub IsValidNLSVersion ++@ stub IsValidRelativeSecurityDescriptor ++@ stdcall IsValidSecurityDescriptor(ptr) advapi32.IsValidSecurityDescriptor ++@ stdcall IsValidSid(ptr) advapi32.IsValidSid ++@ stdcall IsWellKnownSid(ptr long) advapi32.IsWellKnownSid ++@ stdcall IsWow64Process(ptr ptr) kernel32.IsWow64Process ++@ stdcall K32EmptyWorkingSet(long) kernel32.K32EmptyWorkingSet ++@ stdcall K32EnumDeviceDrivers(ptr long ptr) kernel32.K32EnumDeviceDrivers ++@ stdcall K32EnumPageFilesA(ptr ptr) kernel32.K32EnumPageFilesA ++@ stdcall K32EnumPageFilesW(ptr ptr) kernel32.K32EnumPageFilesW ++@ stdcall K32EnumProcessModules(long ptr long ptr) kernel32.K32EnumProcessModules ++@ stdcall K32EnumProcessModulesEx(long ptr long ptr long) kernel32.K32EnumProcessModulesEx ++@ stdcall K32EnumProcesses(ptr long ptr) kernel32.K32EnumProcesses ++@ stdcall K32GetDeviceDriverBaseNameA(ptr ptr long) kernel32.K32GetDeviceDriverBaseNameA ++@ stdcall K32GetDeviceDriverBaseNameW(ptr ptr long) kernel32.K32GetDeviceDriverBaseNameW ++@ stdcall K32GetDeviceDriverFileNameA(ptr ptr long) kernel32.K32GetDeviceDriverFileNameA ++@ stdcall K32GetDeviceDriverFileNameW(ptr ptr long) kernel32.K32GetDeviceDriverFileNameW ++@ stdcall K32GetMappedFileNameA(long ptr ptr long) kernel32.K32GetMappedFileNameA ++@ stdcall K32GetMappedFileNameW(long ptr ptr long) kernel32.K32GetMappedFileNameW ++@ stdcall K32GetModuleBaseNameA(long long ptr long) kernel32.K32GetModuleBaseNameA ++@ stdcall K32GetModuleBaseNameW(long long ptr long) kernel32.K32GetModuleBaseNameW ++@ stdcall K32GetModuleFileNameExA(long long ptr long) kernel32.K32GetModuleFileNameExA ++@ stdcall K32GetModuleFileNameExW(long long ptr long) kernel32.K32GetModuleFileNameExW ++@ stdcall K32GetModuleInformation(long long ptr long) kernel32.K32GetModuleInformation ++@ stdcall K32GetPerformanceInfo(ptr long) kernel32.K32GetPerformanceInfo ++@ stdcall K32GetProcessImageFileNameA(long ptr long) kernel32.K32GetProcessImageFileNameA ++@ stdcall K32GetProcessImageFileNameW(long ptr long) kernel32.K32GetProcessImageFileNameW ++@ stdcall K32GetProcessMemoryInfo(long ptr long) kernel32.K32GetProcessMemoryInfo ++@ stdcall K32GetWsChanges(long ptr long) kernel32.K32GetWsChanges ++@ stub K32GetWsChangesEx ++@ stdcall K32InitializeProcessForWsWatch(long) kernel32.K32InitializeProcessForWsWatch ++@ stdcall K32QueryWorkingSet(long ptr long) kernel32.K32QueryWorkingSet ++@ stdcall K32QueryWorkingSetEx(long ptr long) kernel32.K32QueryWorkingSetEx ++@ stub KernelBaseGetGlobalData ++@ stdcall LCIDToLocaleName(long ptr long long) kernel32.LCIDToLocaleName ++@ stdcall LCMapStringA(long long str long ptr long) kernel32.LCMapStringA ++@ stdcall LCMapStringEx(wstr long wstr long ptr long ptr ptr long) kernel32.LCMapStringEx ++@ stdcall LCMapStringW(long long wstr long ptr long) kernel32.LCMapStringW ++@ stub LeaveCriticalPolicySectionInternal ++@ stdcall LeaveCriticalSection(ptr) kernel32.LeaveCriticalSection ++@ stdcall LeaveCriticalSectionWhenCallbackReturns(ptr ptr) kernel32.LeaveCriticalSectionWhenCallbackReturns ++@ stub LoadAppInitDlls ++@ stdcall LoadLibraryA(str) kernel32.LoadLibraryA ++@ stdcall LoadLibraryExA( str long long) kernel32.LoadLibraryExA ++@ stdcall LoadLibraryExW(wstr long long) kernel32.LoadLibraryExW ++@ stdcall LoadLibraryW(wstr) kernel32.LoadLibraryW ++@ stub LoadPackagedLibrary ++@ stdcall LoadResource(long long) kernel32.LoadResource ++@ stdcall LoadStringA(long long ptr long) user32.LoadStringA ++@ stub LoadStringBaseExW ++@ stub LoadStringByReference ++@ stdcall LoadStringW(long long ptr long) user32.LoadStringW ++@ stdcall LocalAlloc(long long) kernel32.LocalAlloc ++@ stdcall LocalFileTimeToFileTime(ptr ptr) kernel32.LocalFileTimeToFileTime ++@ stdcall LocalFree(long) kernel32.LocalFree ++@ stdcall LocalLock(long) kernel32.LocalLock ++@ stdcall LocalReAlloc(long long long) kernel32.LocalReAlloc ++@ stdcall LocalUnlock(long) kernel32.LocalUnlock ++@ stdcall LocaleNameToLCID(wstr long) kernel32.LocaleNameToLCID ++@ stub LocateXStateFeature ++@ stdcall LockFile(long long long long long) kernel32.LockFile ++@ stdcall LockFileEx(long long long long long ptr) kernel32.LockFileEx ++@ stdcall LockResource(long) kernel32.LockResource ++@ stub MakeAbsoluteSD2 ++@ stdcall MakeAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) advapi32.MakeAbsoluteSD ++@ stdcall MakeSelfRelativeSD(ptr ptr ptr) advapi32.MakeSelfRelativeSD ++@ stdcall MapGenericMask(ptr ptr) advapi32.MapGenericMask ++@ stub MapPredefinedHandleInternal ++@ stub MapUserPhysicalPages ++@ stdcall MapViewOfFile(long long long long long) kernel32.MapViewOfFile ++@ stdcall MapViewOfFileEx(long long long long long ptr) kernel32.MapViewOfFileEx ++@ stub MapViewOfFileExNuma ++@ stub MapViewOfFileFromApp ++@ stdcall MoveFileExW(wstr wstr long) kernel32.MoveFileExW ++@ stub MoveFileWithProgressTransactedW ++@ stdcall MoveFileWithProgressW(wstr wstr ptr ptr long) kernel32.MoveFileWithProgressW ++@ stdcall MulDiv(long long long) kernel32.MulDiv ++@ stdcall MultiByteToWideChar(long long str long ptr long) kernel32.MultiByteToWideChar ++@ stub NamedPipeEventEnum ++@ stub NamedPipeEventSelect ++@ stdcall NeedCurrentDirectoryForExePathA(str) kernel32.NeedCurrentDirectoryForExePathA ++@ stdcall NeedCurrentDirectoryForExePathW(wstr) kernel32.NeedCurrentDirectoryForExePathW ++@ stub NlsCheckPolicy ++@ stub NlsDispatchAnsiEnumProc ++@ stub NlsEventDataDescCreate ++@ stub NlsGetACPFromLocale ++@ stub NlsGetCacheUpdateCount ++@ stub NlsIsUserDefaultLocale ++@ stub NlsUpdateLocale ++@ stub NlsUpdateSystemLocale ++@ stub NlsValidateLocale ++@ stub NlsWriteEtwEvent ++@ stdcall NormalizeString(long wstr long ptr long) kernel32.NormalizeString ++@ stub NotifyMountMgr ++@ stub NotifyRedirectedStringChange ++@ stdcall ObjectCloseAuditAlarmW(wstr ptr long) advapi32.ObjectCloseAuditAlarmW ++@ stdcall ObjectDeleteAuditAlarmW(wstr ptr long) advapi32.ObjectDeleteAuditAlarmW ++@ stdcall ObjectOpenAuditAlarmW(wstr ptr wstr wstr ptr long long long ptr long long ptr) advapi32.ObjectOpenAuditAlarmW ++@ stdcall ObjectPrivilegeAuditAlarmW(wstr ptr long long ptr long) advapi32.ObjectPrivilegeAuditAlarmW ++@ stub OfferVirtualMemory ++@ stdcall OpenEventA(long long str) kernel32.OpenEventA ++@ stdcall OpenEventW(long long wstr) kernel32.OpenEventW ++@ stdcall OpenFileById(long ptr long long ptr long) kernel32.OpenFileById ++@ stub OpenFileMappingFromApp ++@ stdcall OpenFileMappingW(long long wstr) kernel32.OpenFileMappingW ++@ stub OpenGlobalizationUserSettingsKey ++@ stdcall OpenMutexW(long long wstr) kernel32.OpenMutexW ++@ stub OpenPackageInfoByFullName ++@ stub OpenPackageInfoByFullNameForUser ++@ stub OpenPrivateNamespaceW ++@ stdcall OpenProcess(long long long) kernel32.OpenProcess ++@ stdcall OpenProcessToken(long long ptr) advapi32.OpenProcessToken ++@ stub OpenRegKey ++@ stdcall OpenSemaphoreW(long long wstr) kernel32.OpenSemaphoreW ++@ stub OpenState ++@ stub OpenStateAtom ++@ stub OpenStateExplicit ++@ stub OpenStateExplicitForUserSid ++@ stub OpenStateExplicitForUserSidString ++@ stdcall OpenThread(long long long) kernel32.OpenThread ++@ stdcall OpenThreadToken(long long long ptr) advapi32.OpenThreadToken ++@ stdcall OpenWaitableTimerW(long long wstr) kernel32.OpenWaitableTimerW ++@ stdcall OutputDebugStringA(str) kernel32.OutputDebugStringA ++@ stdcall OutputDebugStringW(wstr) kernel32.OutputDebugStringW ++@ stub OverrideRoamingDataModificationTimesInRange ++@ stub PackageFamilyNameFromFullName ++@ stub PackageFamilyNameFromId ++@ stub PackageFamilyNameFromProductId ++@ stub PackageFullNameFromId ++@ stub PackageFullNameFromProductId ++@ stub PackageIdFromFullName ++@ stub PackageIdFromProductId ++@ stub PackageNameAndPublisherIdFromFamilyName ++@ stub PackageRelativeApplicationIdFromProductId ++@ stub PackageSidFromFamilyName ++@ stub ParseApplicationUserModelId ++@ stdcall ParseURLA(str ptr) shlwapi.ParseURLA ++@ stdcall ParseURLW(wstr ptr) shlwapi.ParseURLW ++@ stdcall PathAddBackslashA(str) shlwapi.PathAddBackslashA ++@ stdcall PathAddBackslashW(wstr) shlwapi.PathAddBackslashW ++@ stdcall PathAddExtensionA(str str) shlwapi.PathAddExtensionA ++@ stdcall PathAddExtensionW(wstr wstr) shlwapi.PathAddExtensionW ++@ stub PathAllocCanonicalize ++@ stub PathAllocCombine ++@ stdcall PathAppendA(str str) shlwapi.PathAppendA ++@ stdcall PathAppendW(wstr wstr) shlwapi.PathAppendW ++@ stdcall PathCanonicalizeA(ptr str) shlwapi.PathCanonicalizeA ++@ stdcall PathCanonicalizeW(ptr wstr) shlwapi.PathCanonicalizeW ++@ stub PathCchAddBackslash ++@ stub PathCchAddBackslashEx ++@ stub PathCchAddExtension ++@ stub PathCchAppend ++@ stub PathCchAppendEx ++@ stub PathCchCanonicalize ++@ stub PathCchCanonicalizeEx ++@ stub PathCchCombine ++@ stub PathCchCombineEx ++@ stub PathCchFindExtension ++@ stub PathCchIsRoot ++@ stub PathCchRemoveBackslash ++@ stub PathCchRemoveBackslashEx ++@ stub PathCchRemoveExtension ++@ stub PathCchRemoveFileSpec ++@ stub PathCchRenameExtension ++@ stub PathCchSkipRoot ++@ stub PathCchStripPrefix ++@ stub PathCchStripToRoot ++@ stdcall PathCombineA(ptr str str) shlwapi.PathCombineA ++@ stdcall PathCombineW(ptr wstr wstr) shlwapi.PathCombineW ++@ stdcall PathCommonPrefixA(str str ptr) shlwapi.PathCommonPrefixA ++@ stdcall PathCommonPrefixW(wstr wstr ptr) shlwapi.PathCommonPrefixW ++@ stdcall PathCreateFromUrlA(str ptr ptr long) shlwapi.PathCreateFromUrlA ++@ stdcall PathCreateFromUrlAlloc(wstr ptr long) shlwapi.PathCreateFromUrlAlloc ++@ stdcall PathCreateFromUrlW(wstr ptr ptr long) shlwapi.PathCreateFromUrlW ++@ stdcall PathFileExistsA(str) shlwapi.PathFileExistsA ++@ stdcall PathFileExistsW(wstr) shlwapi.PathFileExistsW ++@ stdcall PathFindExtensionA(str) shlwapi.PathFindExtensionA ++@ stdcall PathFindExtensionW(wstr) shlwapi.PathFindExtensionW ++@ stdcall PathFindFileNameA(str) shlwapi.PathFindFileNameA ++@ stdcall PathFindFileNameW(wstr) shlwapi.PathFindFileNameW ++@ stdcall PathFindNextComponentA(str) shlwapi.PathFindNextComponentA ++@ stdcall PathFindNextComponentW(wstr) shlwapi.PathFindNextComponentW ++@ stdcall PathGetArgsA(str) shlwapi.PathGetArgsA ++@ stdcall PathGetArgsW(wstr) shlwapi.PathGetArgsW ++@ stdcall PathGetCharTypeA(long) shlwapi.PathGetCharTypeA ++@ stdcall PathGetCharTypeW(long) shlwapi.PathGetCharTypeW ++@ stdcall PathGetDriveNumberA(str) shlwapi.PathGetDriveNumberA ++@ stdcall PathGetDriveNumberW(wstr) shlwapi.PathGetDriveNumberW ++@ stdcall PathIsFileSpecA(str) shlwapi.PathIsFileSpecA ++@ stdcall PathIsFileSpecW(wstr) shlwapi.PathIsFileSpecW ++@ stdcall PathIsLFNFileSpecA(str) shlwapi.PathIsLFNFileSpecA ++@ stdcall PathIsLFNFileSpecW(wstr) shlwapi.PathIsLFNFileSpecW ++@ stdcall PathIsPrefixA(str str) shlwapi.PathIsPrefixA ++@ stdcall PathIsPrefixW(wstr wstr) shlwapi.PathIsPrefixW ++@ stdcall PathIsRelativeA(str) shlwapi.PathIsRelativeA ++@ stdcall PathIsRelativeW(wstr) shlwapi.PathIsRelativeW ++@ stdcall PathIsRootA(str) shlwapi.PathIsRootA ++@ stdcall PathIsRootW(wstr) shlwapi.PathIsRootW ++@ stdcall PathIsSameRootA(str str) shlwapi.PathIsSameRootA ++@ stdcall PathIsSameRootW(wstr wstr) shlwapi.PathIsSameRootW ++@ stdcall PathIsUNCA(str) shlwapi.PathIsUNCA ++@ stub PathIsUNCEx ++@ stdcall PathIsUNCServerA(str) shlwapi.PathIsUNCServerA ++@ stdcall PathIsUNCServerShareA(str) shlwapi.PathIsUNCServerShareA ++@ stdcall PathIsUNCServerShareW(wstr) shlwapi.PathIsUNCServerShareW ++@ stdcall PathIsUNCServerW(wstr) shlwapi.PathIsUNCServerW ++@ stdcall PathIsUNCW(wstr) shlwapi.PathIsUNCW ++@ stdcall PathIsURLA(str) shlwapi.PathIsURLA ++@ stdcall PathIsURLW(wstr) shlwapi.PathIsURLW ++@ stdcall PathIsValidCharA(long long) shlwapi.PathIsValidCharA ++@ stdcall PathIsValidCharW(long long) shlwapi.PathIsValidCharW ++@ stdcall PathMatchSpecA(str str) shlwapi.PathMatchSpecA ++@ stub PathMatchSpecExA ++@ stub PathMatchSpecExW ++@ stdcall PathMatchSpecW(wstr wstr) shlwapi.PathMatchSpecW ++@ stdcall PathParseIconLocationA(str) shlwapi.PathParseIconLocationA ++@ stdcall PathParseIconLocationW(wstr) shlwapi.PathParseIconLocationW ++@ stdcall PathQuoteSpacesA(str) shlwapi.PathQuoteSpacesA ++@ stdcall PathQuoteSpacesW(wstr) shlwapi.PathQuoteSpacesW ++@ stdcall PathRelativePathToA(ptr str long str long) shlwapi.PathRelativePathToA ++@ stdcall PathRelativePathToW(ptr wstr long wstr long) shlwapi.PathRelativePathToW ++@ stdcall PathRemoveBackslashA(str) shlwapi.PathRemoveBackslashA ++@ stdcall PathRemoveBackslashW(wstr) shlwapi.PathRemoveBackslashW ++@ stdcall PathRemoveBlanksA(str) shlwapi.PathRemoveBlanksA ++@ stdcall PathRemoveBlanksW(wstr) shlwapi.PathRemoveBlanksW ++@ stdcall PathRemoveExtensionA(str) shlwapi.PathRemoveExtensionA ++@ stdcall PathRemoveExtensionW(wstr) shlwapi.PathRemoveExtensionW ++@ stdcall PathRemoveFileSpecA(str) shlwapi.PathRemoveFileSpecA ++@ stdcall PathRemoveFileSpecW(wstr) shlwapi.PathRemoveFileSpecW ++@ stdcall PathRenameExtensionA(str str) shlwapi.PathRenameExtensionA ++@ stdcall PathRenameExtensionW(wstr wstr) shlwapi.PathRenameExtensionW ++@ stdcall PathSearchAndQualifyA(str ptr long) shlwapi.PathSearchAndQualifyA ++@ stdcall PathSearchAndQualifyW(wstr ptr long) shlwapi.PathSearchAndQualifyW ++@ stdcall PathSkipRootA(str) shlwapi.PathSkipRootA ++@ stdcall PathSkipRootW(wstr) shlwapi.PathSkipRootW ++@ stdcall PathStripPathA(str) shlwapi.PathStripPathA ++@ stdcall PathStripPathW(wstr) shlwapi.PathStripPathW ++@ stdcall PathStripToRootA(str) shlwapi.PathStripToRootA ++@ stdcall PathStripToRootW(wstr) shlwapi.PathStripToRootW ++@ stdcall PathUnExpandEnvStringsA(str ptr long) shlwapi.PathUnExpandEnvStringsA ++@ stdcall PathUnExpandEnvStringsW(wstr ptr long) shlwapi.PathUnExpandEnvStringsW ++@ stdcall PathUnquoteSpacesA(str) shlwapi.PathUnquoteSpacesA ++@ stdcall PathUnquoteSpacesW(wstr) shlwapi.PathUnquoteSpacesW ++@ stub PcwAddQueryItem ++@ stub PcwClearCounterSetSecurity ++@ stub PcwCollectData ++@ stub PcwCompleteNotification ++@ stub PcwCreateNotifier ++@ stub PcwCreateQuery ++@ stub PcwDisconnectCounterSet ++@ stub PcwEnumerateInstances ++@ stub PcwIsNotifierAlive ++@ stub PcwQueryCounterSetSecurity ++@ stub PcwReadNotificationData ++@ stub PcwRegisterCounterSet ++@ stub PcwRemoveQueryItem ++@ stub PcwSendNotification ++@ stub PcwSendStatelessNotification ++@ stub PcwSetCounterSetSecurity ++@ stub PcwSetQueryItemUserData ++@ stdcall PeekConsoleInputA(ptr ptr long ptr) kernel32.PeekConsoleInputA ++@ stdcall PeekConsoleInputW(ptr ptr long ptr) kernel32.PeekConsoleInputW ++@ stdcall PeekNamedPipe(long ptr long ptr ptr ptr) kernel32.PeekNamedPipe ++@ stub PerfCreateInstance ++@ stub PerfDecrementULongCounterValue ++@ stub PerfDecrementULongLongCounterValue ++@ stub PerfDeleteInstance ++@ stub PerfIncrementULongCounterValue ++@ stub PerfIncrementULongLongCounterValue ++@ stub PerfQueryInstance ++@ stub PerfSetCounterRefValue ++@ stub PerfSetCounterSetInfo ++@ stub PerfSetULongCounterValue ++@ stub PerfSetULongLongCounterValue ++@ stub PerfStartProvider ++@ stub PerfStartProviderEx ++@ stub PerfStopProvider ++@ stub PoolPerAppKeyStateInternal ++@ stdcall PostQueuedCompletionStatus(long long ptr ptr) kernel32.PostQueuedCompletionStatus ++@ stub PrefetchVirtualMemory ++@ stub PrivCopyFileExW ++@ stdcall PrivilegeCheck(ptr ptr ptr) advapi32.PrivilegeCheck ++@ stdcall PrivilegedServiceAuditAlarmW(wstr wstr long ptr long) advapi32.PrivilegedServiceAuditAlarmW ++@ stdcall ProcessIdToSessionId(long ptr) kernel32.ProcessIdToSessionId ++@ stub ProductIdFromPackageFamilyName ++@ stub PsmCreateKey ++@ stub PsmCreateKeyWithDynamicId ++@ stub PsmEqualApplication ++@ stub PsmEqualPackage ++@ stub PsmGetApplicationNameFromKey ++@ stub PsmGetKeyFromProcess ++@ stub PsmGetKeyFromToken ++@ stub PsmGetPackageFullNameFromKey ++@ stub PsmIsChildKey ++@ stub PsmIsDynamicKey ++@ stub PsmIsValidKey ++@ stub PssCaptureSnapshot ++@ stub PssDuplicateSnapshot ++@ stub PssFreeSnapshot ++@ stub PssQuerySnapshot ++@ stub PssWalkMarkerCreate ++@ stub PssWalkMarkerFree ++@ stub PssWalkMarkerGetPosition ++@ stub PssWalkMarkerSeekToBeginning ++@ stub PssWalkMarkerSetPosition ++@ stub PssWalkSnapshot ++@ stub PublishStateChangeNotification ++@ stdcall PulseEvent(long) kernel32.PulseEvent ++@ stdcall PurgeComm(long long) kernel32.PurgeComm ++@ stdcall QISearch(long long long long) shlwapi.QISearch ++@ stub QueryActCtxSettingsW ++@ stdcall QueryActCtxW(long ptr ptr long ptr long ptr) kernel32.QueryActCtxW ++@ stdcall QueryDepthSList(ptr) kernel32.QueryDepthSList ++@ stdcall QueryDosDeviceW(wstr ptr long) kernel32.QueryDosDeviceW ++@ stdcall QueryFullProcessImageNameA(ptr long ptr ptr) kernel32.QueryFullProcessImageNameA ++@ stdcall QueryFullProcessImageNameW(ptr long ptr ptr) kernel32.QueryFullProcessImageNameW ++@ stub QueryIdleProcessorCycleTime ++@ stub QueryIdleProcessorCycleTimeEx ++@ stub QueryInterruptTime ++@ stub QueryInterruptTimePrecise ++@ stdcall QueryMemoryResourceNotification(ptr ptr) kernel32.QueryMemoryResourceNotification ++@ stub QueryOptionalDelayLoadedAPI ++@ stdcall QueryPerformanceCounter(ptr) kernel32.QueryPerformanceCounter ++@ stdcall QueryPerformanceFrequency(ptr) kernel32.QueryPerformanceFrequency ++@ stub QueryProcessAffinityUpdateMode ++@ stub QueryProcessCycleTime ++@ stub QueryProtectedPolicy ++@ stub QuerySecurityAccessMask ++@ stub QueryStateAtomValueInfo ++@ stub QueryStateContainerItemInfo ++@ stdcall QueryThreadCycleTime(long ptr) kernel32.QueryThreadCycleTime ++@ stub QueryThreadpoolStackInformation ++@ stdcall QueryUnbiasedInterruptTime(ptr) kernel32.QueryUnbiasedInterruptTime ++@ stub QueryUnbiasedInterruptTimePrecise ++@ stub QueryWorkingSet ++@ stub QueryWorkingSetEx ++@ stdcall QueueUserAPC(ptr long long) kernel32.QueueUserAPC ++@ stdcall QueueUserWorkItem(ptr ptr long) kernel32.QueueUserWorkItem ++@ stub QuirkGetData2 ++@ stub QuirkGetData ++@ stub QuirkIsEnabled2 ++@ stub QuirkIsEnabled3 ++@ stdcall QuirkIsEnabled(ptr) ++@ stub QuirkIsEnabledForPackage2 ++@ stub QuirkIsEnabledForPackage3 ++@ stub QuirkIsEnabledForPackage4 ++@ stub QuirkIsEnabledForPackage ++@ stub QuirkIsEnabledForProcess ++@ stdcall RaiseException(long long long ptr) kernel32.RaiseException ++@ stub RaiseFailFastException ++@ stub ReOpenFile ++@ stdcall ReadConsoleA(long ptr long ptr ptr) kernel32.ReadConsoleA ++@ stdcall ReadConsoleInputA(long ptr long ptr) kernel32.ReadConsoleInputA ++@ stub ReadConsoleInputExA ++@ stub ReadConsoleInputExW ++@ stdcall ReadConsoleInputW(long ptr long ptr) kernel32.ReadConsoleInputW ++@ stdcall ReadConsoleOutputA(long ptr long long ptr) kernel32.ReadConsoleOutputA ++@ stdcall ReadConsoleOutputAttribute(long ptr long long ptr) kernel32.ReadConsoleOutputAttribute ++@ stdcall ReadConsoleOutputCharacterA(long ptr long long ptr) kernel32.ReadConsoleOutputCharacterA ++@ stdcall ReadConsoleOutputCharacterW(long ptr long long ptr) kernel32.ReadConsoleOutputCharacterW ++@ stdcall ReadConsoleOutputW(long ptr long long ptr) kernel32.ReadConsoleOutputW ++@ stdcall ReadConsoleW(long ptr long ptr ptr) kernel32.ReadConsoleW ++@ stdcall ReadDirectoryChangesW(long ptr long long long ptr ptr ptr) kernel32.ReadDirectoryChangesW ++@ stdcall ReadFile(long ptr long ptr ptr) kernel32.ReadFile ++@ stdcall ReadFileEx(long ptr long ptr ptr) kernel32.ReadFileEx ++@ stdcall ReadFileScatter(long ptr long ptr ptr) kernel32.ReadFileScatter ++@ stdcall ReadProcessMemory(long ptr ptr long ptr) kernel32.ReadProcessMemory ++@ stub ReadStateAtomValue ++@ stub ReadStateContainerValue ++@ stub ReclaimVirtualMemory ++@ stub RefreshPolicyExInternal ++@ stub RefreshPolicyInternal ++@ stdcall -private RegCloseKey(long) kernel32.RegCloseKey ++@ stub RegCopyTreeW ++@ stdcall -private RegCreateKeyExA(long str long ptr long long ptr ptr ptr) kernel32.RegCreateKeyExA ++@ stub RegCreateKeyExInternalA ++@ stub RegCreateKeyExInternalW ++@ stdcall -private RegCreateKeyExW(long wstr long ptr long long ptr ptr ptr) kernel32.RegCreateKeyExW ++@ stdcall -private RegDeleteKeyExA(long str long long) kernel32.RegDeleteKeyExA ++@ stub RegDeleteKeyExInternalA ++@ stub RegDeleteKeyExInternalW ++@ stdcall -private RegDeleteKeyExW(long wstr long long) kernel32.RegDeleteKeyExW ++@ stdcall RegDeleteKeyValueA(long str str) advapi32.RegDeleteKeyValueA ++@ stdcall RegDeleteKeyValueW(long wstr wstr) advapi32.RegDeleteKeyValueW ++@ stdcall -private RegDeleteTreeA(long str) kernel32.RegDeleteTreeA ++@ stdcall -private RegDeleteTreeW(long wstr) kernel32.RegDeleteTreeW ++@ stdcall -private RegDeleteValueA(long str) kernel32.RegDeleteValueA ++@ stdcall -private RegDeleteValueW(long wstr) kernel32.RegDeleteValueW ++@ stub RegDisablePredefinedCacheEx ++@ stdcall -private RegEnumKeyExA(long long ptr ptr ptr ptr ptr ptr) kernel32.RegEnumKeyExA ++@ stdcall -private RegEnumKeyExW(long long ptr ptr ptr ptr ptr ptr) kernel32.RegEnumKeyExW ++@ stdcall -private RegEnumValueA(long long ptr ptr ptr ptr ptr ptr) kernel32.RegEnumValueA ++@ stdcall -private RegEnumValueW(long long ptr ptr ptr ptr ptr ptr) kernel32.RegEnumValueW ++@ stdcall -private RegFlushKey(long) kernel32.RegFlushKey ++@ stdcall -private RegGetKeySecurity(long long ptr ptr) kernel32.RegGetKeySecurity ++@ stdcall -private RegGetValueA(long str str long ptr ptr ptr) kernel32.RegGetValueA ++@ stdcall -private RegGetValueW(long wstr wstr long ptr ptr ptr) kernel32.RegGetValueW ++@ stub RegKrnGetAppKeyEventAddressInternal ++@ stub RegKrnGetAppKeyLoaded ++@ stub RegKrnGetClassesEnumTableAddressInternal ++@ stub RegKrnGetHKEY_ClassesRootAddress ++@ stub RegKrnGetTermsrvRegistryExtensionFlags ++@ stub RegKrnResetAppKeyLoaded ++@ stub RegKrnSetDllHasThreadStateGlobal ++@ stub RegKrnSetTermsrvRegistryExtensionFlags ++@ stub RegLoadAppKeyA ++@ stub RegLoadAppKeyW ++@ stdcall -private RegLoadKeyA(long str str) kernel32.RegLoadKeyA ++@ stdcall -private RegLoadKeyW(long wstr wstr) kernel32.RegLoadKeyW ++@ stdcall -private RegLoadMUIStringA(long str str long ptr long str) kernel32.RegLoadMUIStringA ++@ stdcall -private RegLoadMUIStringW(long wstr wstr long ptr long wstr) kernel32.RegLoadMUIStringW ++@ stdcall -private RegNotifyChangeKeyValue(long long long long long) kernel32.RegNotifyChangeKeyValue ++@ stdcall -private RegOpenCurrentUser(long ptr) kernel32.RegOpenCurrentUser ++@ stdcall -private RegOpenKeyExA(long str long long ptr) kernel32.RegOpenKeyExA ++@ stub RegOpenKeyExInternalA ++@ stub RegOpenKeyExInternalW ++@ stdcall -private RegOpenKeyExW(long wstr long long ptr) kernel32.RegOpenKeyExW ++@ stdcall -private RegOpenUserClassesRoot(ptr long long ptr) kernel32.RegOpenUserClassesRoot ++@ stdcall -private RegQueryInfoKeyA(long ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) kernel32.RegQueryInfoKeyA ++@ stdcall -private RegQueryInfoKeyW(long ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) kernel32.RegQueryInfoKeyW ++@ stdcall -private RegQueryValueExA(long str ptr ptr ptr ptr) kernel32.RegQueryValueExA ++@ stdcall -private RegQueryValueExW(long wstr ptr ptr ptr ptr) kernel32.RegQueryValueExW ++@ stdcall -private RegRestoreKeyA(long str long) kernel32.RegRestoreKeyA ++@ stdcall -private RegRestoreKeyW(long wstr long) kernel32.RegRestoreKeyW ++@ stub RegSaveKeyExA ++@ stub RegSaveKeyExW ++@ stdcall -private RegSetKeySecurity(long long ptr) kernel32.RegSetKeySecurity ++@ stdcall RegSetKeyValueA(long str str long ptr long) advapi32.RegSetKeyValueA ++@ stdcall RegSetKeyValueW(long wstr wstr long ptr long) advapi32.RegSetKeyValueW ++@ stdcall -private RegSetValueExA(long str long long ptr long) kernel32.RegSetValueExA ++@ stdcall -private RegSetValueExW(long wstr long long ptr long) kernel32.RegSetValueExW ++@ stdcall -private RegUnLoadKeyA(long str) kernel32.RegUnLoadKeyA ++@ stdcall -private RegUnLoadKeyW(long wstr) kernel32.RegUnLoadKeyW ++@ stub RegisterBadMemoryNotification ++@ stub RegisterGPNotificationInternal ++@ stub RegisterStateChangeNotification ++@ stub RegisterStateLock ++@ stdcall RegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) advapi32.RegisterTraceGuidsW ++@ stdcall RegisterWaitForSingleObjectEx(long ptr ptr long long) kernel32.RegisterWaitForSingleObjectEx ++@ stdcall ReleaseActCtx(ptr) kernel32.ReleaseActCtx ++@ stdcall ReleaseMutex(long) kernel32.ReleaseMutex ++@ stdcall ReleaseMutexWhenCallbackReturns(ptr long) kernel32.ReleaseMutexWhenCallbackReturns ++@ stdcall ReleaseSRWLockExclusive(ptr) kernel32.ReleaseSRWLockExclusive ++@ stdcall ReleaseSRWLockShared(ptr) kernel32.ReleaseSRWLockShared ++@ stdcall ReleaseSemaphore(long long ptr) kernel32.ReleaseSemaphore ++@ stdcall ReleaseSemaphoreWhenCallbackReturns(ptr long long) kernel32.ReleaseSemaphoreWhenCallbackReturns ++@ stub ReleaseStateLock ++@ stub RemapPredefinedHandleInternal ++@ stdcall RemoveDirectoryA(str) kernel32.RemoveDirectoryA ++@ stdcall RemoveDirectoryW(wstr) kernel32.RemoveDirectoryW ++@ stub RemoveDllDirectory ++@ stub RemovePackageStatus ++@ stub RemovePackageStatusForUser ++@ stdcall RemoveVectoredContinueHandler(ptr) kernel32.RemoveVectoredContinueHandler ++@ stdcall RemoveVectoredExceptionHandler(ptr) kernel32.RemoveVectoredExceptionHandler ++@ stub ReplaceFileExInternal ++@ stdcall ReplaceFileW(wstr wstr wstr long ptr ptr) kernel32.ReplaceFileW ++@ stdcall ResetEvent(long) kernel32.ResetEvent ++@ stub ResetState ++@ stdcall ResetWriteWatch(ptr long) kernel32.ResetWriteWatch ++@ stdcall ResolveDelayLoadedAPI(ptr ptr ptr ptr ptr long) kernel32.ResolveDelayLoadedAPI ++@ stub ResolveDelayLoadsFromDll ++@ stub ResolveLocaleName ++@ stdcall RestoreLastError(long) kernel32.RestoreLastError ++@ stdcall ResumeThread(long) kernel32.ResumeThread ++@ stdcall RevertToSelf() advapi32.RevertToSelf ++@ stub RsopLoggingEnabledInternal ++@ stub SHCoCreateInstance ++@ stdcall SHExpandEnvironmentStringsA(str ptr long) kernel32.ExpandEnvironmentStringsA ++@ stdcall SHExpandEnvironmentStringsW(wstr ptr long) kernel32.ExpandEnvironmentStringsW ++@ stdcall SHLoadIndirectString(wstr ptr long ptr) shlwapi.SHLoadIndirectString ++@ stub SHLoadIndirectStringInternal ++@ stdcall SHRegCloseUSKey(ptr) shlwapi.SHRegCloseUSKey ++@ stdcall SHRegCreateUSKeyA(str long long ptr long) shlwapi.SHRegCreateUSKeyA ++@ stdcall SHRegCreateUSKeyW(wstr long long ptr long) shlwapi.SHRegCreateUSKeyW ++@ stdcall SHRegDeleteEmptyUSKeyA(long str long) shlwapi.SHRegDeleteEmptyUSKeyA ++@ stdcall SHRegDeleteEmptyUSKeyW(long wstr long) shlwapi.SHRegDeleteEmptyUSKeyW ++@ stdcall SHRegDeleteUSValueA(long str long) shlwapi.SHRegDeleteUSValueA ++@ stdcall SHRegDeleteUSValueW(long wstr long) shlwapi.SHRegDeleteUSValueW ++@ stdcall SHRegEnumUSKeyA(long long str ptr long) shlwapi.SHRegEnumUSKeyA ++@ stdcall SHRegEnumUSKeyW(long long wstr ptr long) shlwapi.SHRegEnumUSKeyW ++@ stdcall SHRegEnumUSValueA(long long ptr ptr ptr ptr ptr long) shlwapi.SHRegEnumUSValueA ++@ stdcall SHRegEnumUSValueW(long long ptr ptr ptr ptr ptr long) shlwapi.SHRegEnumUSValueW ++@ stdcall SHRegGetBoolUSValueA(str str long long) shlwapi.SHRegGetBoolUSValueA ++@ stdcall SHRegGetBoolUSValueW(wstr wstr long long) shlwapi.SHRegGetBoolUSValueW ++@ stdcall SHRegGetUSValueA( str str ptr ptr ptr long ptr long ) shlwapi.SHRegGetUSValueA ++@ stdcall SHRegGetUSValueW( wstr wstr ptr ptr ptr long ptr long ) shlwapi.SHRegGetUSValueW ++@ stdcall SHRegOpenUSKeyA( str long long long long ) shlwapi.SHRegOpenUSKeyA ++@ stdcall SHRegOpenUSKeyW( wstr long long long long ) shlwapi.SHRegOpenUSKeyW ++@ stdcall SHRegQueryInfoUSKeyA( long ptr ptr ptr ptr long ) shlwapi.SHRegQueryInfoUSKeyA ++@ stdcall SHRegQueryInfoUSKeyW( long ptr ptr ptr ptr long ) shlwapi.SHRegQueryInfoUSKeyW ++@ stdcall SHRegQueryUSValueA( long str ptr ptr ptr long ptr long ) shlwapi.SHRegQueryUSValueA ++@ stdcall SHRegQueryUSValueW( long wstr ptr ptr ptr long ptr long ) shlwapi.SHRegQueryUSValueW ++@ stdcall SHRegSetUSValueA( str str long ptr long long) shlwapi.SHRegSetUSValueA ++@ stdcall SHRegSetUSValueW( wstr wstr long ptr long long) shlwapi.SHRegSetUSValueW ++@ stdcall SHRegWriteUSValueA(long str long ptr long long) shlwapi.SHRegWriteUSValueA ++@ stdcall SHRegWriteUSValueW(long wstr long ptr long long) shlwapi.SHRegWriteUSValueW ++@ stdcall SHTruncateString(str long) shlwapi.SHTruncateString ++@ stub SaveAlternatePackageRootPath ++@ stub SaveStateRootFolderPath ++@ stdcall ScrollConsoleScreenBufferA(long ptr ptr ptr ptr) kernel32.ScrollConsoleScreenBufferA ++@ stdcall ScrollConsoleScreenBufferW(long ptr ptr ptr ptr) kernel32.ScrollConsoleScreenBufferW ++@ stdcall SearchPathA(str str str long ptr ptr) kernel32.SearchPathA ++@ stdcall SearchPathW(wstr wstr wstr long ptr ptr) kernel32.SearchPathW ++@ stdcall SetAclInformation(ptr ptr long long) advapi32.SetAclInformation ++@ stub SetCachedSigningLevel ++@ stdcall SetCalendarInfoW(long long long wstr) kernel32.SetCalendarInfoW ++@ stub SetClientDynamicTimeZoneInformation ++@ stub SetClientTimeZoneInformation ++@ stdcall SetCommBreak(long) kernel32.SetCommBreak ++@ stdcall SetCommConfig(long ptr long) kernel32.SetCommConfig ++@ stdcall SetCommMask(long ptr) kernel32.SetCommMask ++@ stdcall SetCommState(long ptr) kernel32.SetCommState ++@ stdcall SetCommTimeouts(long ptr) kernel32.SetCommTimeouts ++@ stdcall SetComputerNameA(str) kernel32.SetComputerNameA ++@ stub SetComputerNameEx2W ++@ stdcall SetComputerNameExA(long str) kernel32.SetComputerNameExA ++@ stdcall SetComputerNameExW(long wstr) kernel32.SetComputerNameExW ++@ stdcall SetComputerNameW(wstr) kernel32.SetComputerNameW ++@ stdcall SetConsoleActiveScreenBuffer(long) kernel32.SetConsoleActiveScreenBuffer ++@ stdcall SetConsoleCP(long) kernel32.SetConsoleCP ++@ stdcall SetConsoleCtrlHandler(ptr long) kernel32.SetConsoleCtrlHandler ++@ stdcall SetConsoleCursorInfo(long ptr) kernel32.SetConsoleCursorInfo ++@ stdcall SetConsoleCursorPosition(long long) kernel32.SetConsoleCursorPosition ++@ stdcall SetConsoleInputExeNameA(ptr) kernel32.SetConsoleInputExeNameA ++@ stdcall SetConsoleInputExeNameW(ptr) kernel32.SetConsoleInputExeNameW ++@ stdcall SetConsoleMode(long long) kernel32.SetConsoleMode ++@ stdcall SetConsoleOutputCP(long) kernel32.SetConsoleOutputCP ++@ stdcall SetConsoleScreenBufferInfoEx(long ptr) kernel32.SetConsoleScreenBufferInfoEx ++@ stdcall SetConsoleScreenBufferSize(long long) kernel32.SetConsoleScreenBufferSize ++@ stdcall SetConsoleTextAttribute(long long) kernel32.SetConsoleTextAttribute ++@ stdcall SetConsoleTitleW(wstr) kernel32.SetConsoleTitleW ++@ stdcall SetConsoleWindowInfo(long long ptr) kernel32.SetConsoleWindowInfo ++@ stdcall SetCriticalSectionSpinCount(ptr long) kernel32.SetCriticalSectionSpinCount ++@ stdcall SetCurrentDirectoryA(str) kernel32.SetCurrentDirectoryA ++@ stdcall SetCurrentDirectoryW(wstr) kernel32.SetCurrentDirectoryW ++@ stub SetDefaultDllDirectories ++@ stub SetDynamicTimeZoneInformation ++@ stdcall SetEndOfFile(long) kernel32.SetEndOfFile ++@ stub SetEnvironmentStringsW ++@ stdcall SetEnvironmentVariableA(str str) kernel32.SetEnvironmentVariableA ++@ stdcall SetEnvironmentVariableW(wstr wstr) kernel32.SetEnvironmentVariableW ++@ stdcall SetErrorMode(long) kernel32.SetErrorMode ++@ stdcall SetEvent(long) kernel32.SetEvent ++@ stdcall SetEventWhenCallbackReturns(ptr long) kernel32.SetEventWhenCallbackReturns ++@ stdcall SetFileApisToANSI() kernel32.SetFileApisToANSI ++@ stdcall SetFileApisToOEM() kernel32.SetFileApisToOEM ++@ stdcall SetFileAttributesA(str long) kernel32.SetFileAttributesA ++@ stdcall SetFileAttributesW(wstr long) kernel32.SetFileAttributesW ++@ stdcall SetFileInformationByHandle(long long ptr long) kernel32.SetFileInformationByHandle ++@ stub SetFileIoOverlappedRange ++@ stdcall SetFilePointer(long long ptr long) kernel32.SetFilePointer ++@ stdcall SetFilePointerEx(long int64 ptr long) kernel32.SetFilePointerEx ++@ stdcall SetFileSecurityW(wstr long ptr) advapi32.SetFileSecurityW ++@ stdcall SetFileTime(long ptr ptr ptr) kernel32.SetFileTime ++@ stdcall SetFileValidData(ptr int64) kernel32.SetFileValidData ++@ stdcall SetHandleCount(long) kernel32.SetHandleCount ++@ stdcall SetHandleInformation(long long long) kernel32.SetHandleInformation ++@ stub SetIsDeveloperModeEnabled ++@ stub SetIsSideloadingEnabled ++@ stdcall SetKernelObjectSecurity(long long ptr) advapi32.SetKernelObjectSecurity ++@ stub SetLastConsoleEventActive ++@ stdcall SetLastError(long) kernel32.SetLastError ++@ stdcall SetLocalTime(ptr) kernel32.SetLocalTime ++@ stdcall SetLocaleInfoW(long long wstr) kernel32.SetLocaleInfoW ++@ stdcall SetNamedPipeHandleState(long ptr ptr ptr) kernel32.SetNamedPipeHandleState ++@ stdcall SetPriorityClass(long long) kernel32.SetPriorityClass ++@ stdcall SetPrivateObjectSecurity(long ptr ptr ptr long) advapi32.SetPrivateObjectSecurity ++@ stub SetPrivateObjectSecurityEx ++@ stub SetProcessAffinityUpdateMode ++@ stub SetProcessDefaultCpuSets ++@ stub SetProcessGroupAffinity ++@ stub SetProcessInformation ++@ stub SetProcessMitigationPolicy ++@ stub SetProcessPreferredUILanguages ++@ stdcall SetProcessPriorityBoost(long long) kernel32.SetProcessPriorityBoost ++@ stdcall SetProcessShutdownParameters(long long) kernel32.SetProcessShutdownParameters ++@ stub SetProcessValidCallTargets ++@ stub SetProcessWorkingSetSizeEx ++@ stub SetProtectedPolicy ++@ stub SetRoamingLastObservedChangeTime ++@ stub SetSecurityAccessMask ++@ stdcall SetSecurityDescriptorControl(ptr long long) advapi32.SetSecurityDescriptorControl ++@ stdcall SetSecurityDescriptorDacl(ptr long ptr long) advapi32.SetSecurityDescriptorDacl ++@ stdcall SetSecurityDescriptorGroup(ptr ptr long) advapi32.SetSecurityDescriptorGroup ++@ stdcall SetSecurityDescriptorOwner(ptr ptr long) advapi32.SetSecurityDescriptorOwner ++@ stub SetSecurityDescriptorRMControl ++@ stdcall SetSecurityDescriptorSacl(ptr long ptr long) advapi32.SetSecurityDescriptorSacl ++@ stub SetStateVersion ++@ stdcall SetStdHandle(long long) kernel32.SetStdHandle ++@ stub SetStdHandleEx ++@ stdcall SetSystemFileCacheSize(long long long) kernel32.SetSystemFileCacheSize ++@ stdcall SetSystemTime(ptr) kernel32.SetSystemTime ++@ stdcall SetSystemTimeAdjustment(long long) kernel32.SetSystemTimeAdjustment ++@ stdcall SetThreadContext(long ptr) kernel32.SetThreadContext ++@ stdcall SetThreadErrorMode(long ptr) kernel32.SetThreadErrorMode ++@ stdcall SetThreadGroupAffinity(long ptr ptr) kernel32.SetThreadGroupAffinity ++@ stdcall SetThreadIdealProcessor(long long) kernel32.SetThreadIdealProcessor ++@ stub SetThreadIdealProcessorEx ++@ stub SetThreadInformation ++@ stdcall SetThreadLocale(long) kernel32.SetThreadLocale ++@ stdcall SetThreadPreferredUILanguages(long ptr ptr) kernel32.SetThreadPreferredUILanguages ++@ stdcall SetThreadPriority(long long) kernel32.SetThreadPriority ++@ stdcall SetThreadPriorityBoost(long long) kernel32.SetThreadPriorityBoost ++@ stub SetThreadSelectedCpuSets ++@ stdcall SetThreadStackGuarantee(ptr) kernel32.SetThreadStackGuarantee ++@ stdcall SetThreadToken(ptr ptr) advapi32.SetThreadToken ++@ stdcall SetThreadUILanguage(long) kernel32.SetThreadUILanguage ++@ stub SetThreadpoolStackInformation ++@ stdcall SetThreadpoolThreadMaximum(ptr long) kernel32.SetThreadpoolThreadMaximum ++@ stdcall SetThreadpoolThreadMinimum(ptr long) kernel32.SetThreadpoolThreadMinimum ++@ stdcall SetThreadpoolTimer(ptr ptr long long) kernel32.SetThreadpoolTimer ++@ stub SetThreadpoolTimerEx ++@ stdcall SetThreadpoolWait(ptr long ptr) kernel32.SetThreadpoolWait ++@ stub SetThreadpoolWaitEx ++@ stdcall SetTimeZoneInformation(ptr) kernel32.SetTimeZoneInformation ++@ stdcall SetTokenInformation(long long ptr long) advapi32.SetTokenInformation ++@ stdcall SetUnhandledExceptionFilter(ptr) kernel32.SetUnhandledExceptionFilter ++@ stdcall SetUserGeoID(long) kernel32.SetUserGeoID ++@ stdcall SetWaitableTimer(long ptr long ptr ptr long) kernel32.SetWaitableTimer ++@ stdcall SetWaitableTimerEx(long ptr long ptr ptr ptr long) kernel32.SetWaitableTimerEx ++@ stub SetXStateFeaturesMask ++@ stdcall SetupComm(long long long) kernel32.SetupComm ++@ stub SharedLocalIsEnabled ++@ stdcall SignalObjectAndWait(long long long long) kernel32.SignalObjectAndWait ++@ stdcall SizeofResource(long long) kernel32.SizeofResource ++@ stdcall Sleep(long) kernel32.Sleep ++@ stdcall SleepConditionVariableCS(ptr ptr long) kernel32.SleepConditionVariableCS ++@ stdcall SleepConditionVariableSRW(ptr ptr long long) kernel32.SleepConditionVariableSRW ++@ stdcall SleepEx(long long) kernel32.SleepEx ++@ stub SpecialMBToWC ++@ stub StartThreadpoolIo ++@ stub StmAlignSize ++@ stub StmAllocateFlat ++@ stub StmCoalesceChunks ++@ stub StmDeinitialize ++@ stub StmInitialize ++@ stub StmReduceSize ++@ stub StmReserve ++@ stub StmWrite ++@ stdcall StrCSpnA(str str) shlwapi.StrCSpnA ++@ stdcall StrCSpnIA(str str) shlwapi.StrCSpnIA ++@ stdcall StrCSpnIW(wstr wstr) shlwapi.StrCSpnIW ++@ stdcall StrCSpnW(wstr wstr) shlwapi.StrCSpnW ++@ stdcall StrCatBuffA(str str long) shlwapi.StrCatBuffA ++@ stdcall StrCatBuffW(wstr wstr long) shlwapi.StrCatBuffW ++@ stdcall StrCatChainW(ptr long long wstr) shlwapi.StrCatChainW ++@ stdcall StrChrA(str long) shlwapi.StrChrA ++@ stub StrChrA_MB ++@ stdcall StrChrIA(str long) shlwapi.StrChrIA ++@ stdcall StrChrIW(wstr long) shlwapi.StrChrIW ++@ stub StrChrNIW ++@ stdcall StrChrNW(wstr long long) shlwapi.StrChrNW ++@ stdcall StrChrW(wstr long) shlwapi.StrChrW ++@ stdcall StrCmpCA(str str) shlwapi.StrCmpCA ++@ stdcall StrCmpCW(wstr wstr) shlwapi.StrCmpCW ++@ stdcall StrCmpICA(str str) shlwapi.StrCmpICA ++@ stdcall StrCmpICW(wstr wstr) shlwapi.StrCmpICW ++@ stdcall StrCmpIW(wstr wstr) shlwapi.StrCmpIW ++@ stdcall StrCmpLogicalW(wstr wstr) shlwapi.StrCmpLogicalW ++@ stdcall StrCmpNA(str str long) shlwapi.StrCmpNA ++@ stdcall StrCmpNCA(str ptr long) shlwapi.StrCmpNCA ++@ stdcall StrCmpNCW(wstr wstr long) shlwapi.StrCmpNCW ++@ stdcall StrCmpNIA(str str long) shlwapi.StrCmpNIA ++@ stdcall StrCmpNICA(long long long) shlwapi.StrCmpNICA ++@ stdcall StrCmpNICW(wstr wstr long) shlwapi.StrCmpNICW ++@ stdcall StrCmpNIW(wstr wstr long) shlwapi.StrCmpNIW ++@ stdcall StrCmpNW(wstr wstr long) shlwapi.StrCmpNW ++@ stdcall StrCmpW(wstr wstr) shlwapi.StrCmpW ++@ stdcall StrCpyNW(ptr wstr long) shlwapi.StrCpyNW ++@ stdcall StrCpyNXA(ptr str long) shlwapi.StrCpyNXA ++@ stdcall StrCpyNXW(ptr wstr long) shlwapi.StrCpyNXW ++@ stdcall StrDupA(str) shlwapi.StrDupA ++@ stdcall StrDupW(wstr) shlwapi.StrDupW ++@ stdcall StrIsIntlEqualA(long str str long) shlwapi.StrIsIntlEqualA ++@ stdcall StrIsIntlEqualW(long wstr wstr long) shlwapi.StrIsIntlEqualW ++@ stdcall StrPBrkA(str str) shlwapi.StrPBrkA ++@ stdcall StrPBrkW(wstr wstr) shlwapi.StrPBrkW ++@ stdcall StrRChrA(str str long) shlwapi.StrRChrA ++@ stdcall StrRChrIA(str str long) shlwapi.StrRChrIA ++@ stdcall StrRChrIW(wstr wstr long) shlwapi.StrRChrIW ++@ stdcall StrRChrW(wstr wstr long) shlwapi.StrRChrW ++@ stdcall StrRStrIA(str str str) shlwapi.StrRStrIA ++@ stdcall StrRStrIW(wstr wstr wstr) shlwapi.StrRStrIW ++@ stdcall StrSpnA(str str) shlwapi.StrSpnA ++@ stdcall StrSpnW(wstr wstr) shlwapi.StrSpnW ++@ stdcall StrStrA(str str) shlwapi.StrStrA ++@ stdcall StrStrIA(str str) shlwapi.StrStrIA ++@ stdcall StrStrIW(wstr wstr) shlwapi.StrStrIW ++@ stdcall StrStrNIW(wstr wstr long) shlwapi.StrStrNIW ++@ stdcall StrStrNW(wstr wstr long) shlwapi.StrStrNW ++@ stdcall StrStrW(wstr wstr) shlwapi.StrStrW ++@ stdcall StrToInt64ExA(str long ptr) shlwapi.StrToInt64ExA ++@ stdcall StrToInt64ExW(wstr long ptr) shlwapi.StrToInt64ExW ++@ stdcall StrToIntA(str) shlwapi.StrToIntA ++@ stdcall StrToIntExA(str long ptr) shlwapi.StrToIntExA ++@ stdcall StrToIntExW(wstr long ptr) shlwapi.StrToIntExW ++@ stdcall StrToIntW(wstr) shlwapi.StrToIntW ++@ stdcall StrTrimA(str str) shlwapi.StrTrimA ++@ stdcall StrTrimW(wstr wstr) shlwapi.StrTrimW ++@ stdcall SubmitThreadpoolWork(ptr) kernel32.SubmitThreadpoolWork ++@ stub SubscribeStateChangeNotification ++@ stdcall SuspendThread(long) kernel32.SuspendThread ++@ stdcall SwitchToFiber(ptr) kernel32.SwitchToFiber ++@ stdcall SwitchToThread() kernel32.SwitchToThread ++@ stdcall SystemTimeToFileTime(ptr ptr) kernel32.SystemTimeToFileTime ++@ stdcall SystemTimeToTzSpecificLocalTime(ptr ptr ptr) kernel32.SystemTimeToTzSpecificLocalTime ++@ stub SystemTimeToTzSpecificLocalTimeEx ++@ stdcall TerminateProcess(long long) kernel32.TerminateProcess ++@ stub TerminateProcessOnMemoryExhaustion ++@ stdcall TerminateThread(long long) kernel32.TerminateThread ++@ stdcall TlsAlloc() kernel32.TlsAlloc ++@ stdcall TlsFree(long) kernel32.TlsFree ++@ stdcall TlsGetValue(long) kernel32.TlsGetValue ++@ stdcall TlsSetValue(long ptr) kernel32.TlsSetValue ++@ stdcall TraceEvent(int64 ptr) advapi32.TraceEvent ++@ varargs TraceMessage(int64 long ptr long) advapi32.TraceMessage ++@ stdcall TraceMessageVa(int64 long ptr long ptr) advapi32.TraceMessageVa ++@ stdcall TransactNamedPipe(long ptr long ptr long ptr ptr) kernel32.TransactNamedPipe ++@ stdcall TransmitCommChar(long long) kernel32.TransmitCommChar ++@ stdcall TryAcquireSRWLockExclusive(ptr) kernel32.TryAcquireSRWLockExclusive ++@ stdcall TryAcquireSRWLockShared(ptr) kernel32.TryAcquireSRWLockShared ++@ stdcall TryEnterCriticalSection(ptr) kernel32.TryEnterCriticalSection ++@ stdcall TrySubmitThreadpoolCallback(ptr ptr ptr) kernel32.TrySubmitThreadpoolCallback ++@ stdcall TzSpecificLocalTimeToSystemTime(ptr ptr ptr) kernel32.TzSpecificLocalTimeToSystemTime ++@ stub TzSpecificLocalTimeToSystemTimeEx ++@ stdcall UnhandledExceptionFilter(ptr) kernel32.UnhandledExceptionFilter ++@ stdcall UnlockFile(long long long long long) kernel32.UnlockFile ++@ stdcall UnlockFileEx(long long long long ptr) kernel32.UnlockFileEx ++@ stdcall UnmapViewOfFile(ptr) kernel32.UnmapViewOfFile ++@ stub UnmapViewOfFileEx ++@ stub UnregisterBadMemoryNotification ++@ stub UnregisterGPNotificationInternal ++@ stub UnregisterStateChangeNotification ++@ stub UnregisterStateLock ++@ stdcall UnregisterTraceGuids(int64) advapi32.UnregisterTraceGuids ++@ stdcall UnregisterWaitEx(long long) kernel32.UnregisterWaitEx ++@ stub UnsubscribeStateChangeNotification ++@ stub UpdatePackageStatus ++@ stub UpdatePackageStatusForUser ++@ stub UpdateProcThreadAttribute ++@ stdcall UrlApplySchemeA(str ptr ptr long) shlwapi.UrlApplySchemeA ++@ stdcall UrlApplySchemeW(wstr ptr ptr long) shlwapi.UrlApplySchemeW ++@ stdcall UrlCanonicalizeA(str ptr ptr long) shlwapi.UrlCanonicalizeA ++@ stdcall UrlCanonicalizeW(wstr ptr ptr long) shlwapi.UrlCanonicalizeW ++@ stdcall UrlCombineA(str str ptr ptr long) shlwapi.UrlCombineA ++@ stdcall UrlCombineW(wstr wstr ptr ptr long) shlwapi.UrlCombineW ++@ stdcall UrlCompareA(str str long) shlwapi.UrlCompareA ++@ stdcall UrlCompareW(wstr wstr long) shlwapi.UrlCompareW ++@ stdcall UrlCreateFromPathA(str ptr ptr long) shlwapi.UrlCreateFromPathA ++@ stdcall UrlCreateFromPathW(wstr ptr ptr long) shlwapi.UrlCreateFromPathW ++@ stdcall UrlEscapeA(str ptr ptr long) shlwapi.UrlEscapeA ++@ stdcall UrlEscapeW(wstr ptr ptr long) shlwapi.UrlEscapeW ++@ stdcall UrlFixupW(wstr wstr long) shlwapi.UrlFixupW ++@ stdcall UrlGetLocationA(str) shlwapi.UrlGetLocationA ++@ stdcall UrlGetLocationW(wstr) shlwapi.UrlGetLocationW ++@ stdcall UrlGetPartA(str ptr ptr long long) shlwapi.UrlGetPartA ++@ stdcall UrlGetPartW(wstr ptr ptr long long) shlwapi.UrlGetPartW ++@ stdcall UrlHashA(str ptr long) shlwapi.UrlHashA ++@ stdcall UrlHashW(wstr ptr long) shlwapi.UrlHashW ++@ stdcall UrlIsA(str long) shlwapi.UrlIsA ++@ stdcall UrlIsNoHistoryA(str) shlwapi.UrlIsNoHistoryA ++@ stdcall UrlIsNoHistoryW(wstr) shlwapi.UrlIsNoHistoryW ++@ stdcall UrlIsOpaqueA(str) shlwapi.UrlIsOpaqueA ++@ stdcall UrlIsOpaqueW(wstr) shlwapi.UrlIsOpaqueW ++@ stdcall UrlIsW(wstr long) shlwapi.UrlIsW ++@ stdcall UrlUnescapeA(str ptr ptr long) shlwapi.UrlUnescapeA ++@ stdcall UrlUnescapeW(wstr ptr ptr long) shlwapi.UrlUnescapeW ++@ stub VerFindFileA ++@ stub VerFindFileW ++@ stdcall VerLanguageNameA(long str long) kernel32.VerLanguageNameA ++@ stdcall VerLanguageNameW(long wstr long) kernel32.VerLanguageNameW ++@ stub VerQueryValueA ++@ stub VerQueryValueW ++@ stdcall -ret64 VerSetConditionMask(long long long long) kernel32.VerSetConditionMask ++@ stub VerifyApplicationUserModelId ++@ stub VerifyPackageFamilyName ++@ stub VerifyPackageFullName ++@ stub VerifyPackageId ++@ stub VerifyPackageRelativeApplicationId ++@ stub VerifyScripts ++@ stdcall VirtualAlloc(ptr long long long) kernel32.VirtualAlloc ++@ stdcall VirtualAllocEx(long ptr long long long) kernel32.VirtualAllocEx ++@ stub VirtualAllocExNuma ++@ stub VirtualAllocFromApp ++@ stdcall VirtualFree(ptr long long) kernel32.VirtualFree ++@ stdcall VirtualFreeEx(long ptr long long) kernel32.VirtualFreeEx ++@ stdcall VirtualLock(ptr long) kernel32.VirtualLock ++@ stdcall VirtualProtect(ptr long long ptr) kernel32.VirtualProtect ++@ stdcall VirtualProtectEx(long ptr long long ptr) kernel32.VirtualProtectEx ++@ stub VirtualProtectFromApp ++@ stdcall VirtualQuery(ptr ptr long) kernel32.VirtualQuery ++@ stdcall VirtualQueryEx(long ptr ptr long) kernel32.VirtualQueryEx ++@ stdcall VirtualUnlock(ptr long) kernel32.VirtualUnlock ++@ stub WTSGetServiceSessionId ++@ stub WTSIsServerContainer ++@ stdcall WaitCommEvent(long ptr ptr) kernel32.WaitCommEvent ++@ stdcall WaitForDebugEvent(ptr long) kernel32.WaitForDebugEvent ++@ stub WaitForDebugEventEx ++@ stub WaitForMachinePolicyForegroundProcessingInternal ++@ stdcall WaitForMultipleObjects(long ptr long long) kernel32.WaitForMultipleObjects ++@ stdcall WaitForMultipleObjectsEx(long ptr long long long) kernel32.WaitForMultipleObjectsEx ++@ stdcall WaitForSingleObject(long long) kernel32.WaitForSingleObject ++@ stdcall WaitForSingleObjectEx(long long long) kernel32.WaitForSingleObjectEx ++@ stub WaitForThreadpoolIoCallbacks ++@ stdcall WaitForThreadpoolTimerCallbacks(ptr long) kernel32.WaitForThreadpoolTimerCallbacks ++@ stdcall WaitForThreadpoolWaitCallbacks(ptr long) kernel32.WaitForThreadpoolWaitCallbacks ++@ stdcall WaitForThreadpoolWorkCallbacks(ptr long) kernel32.WaitForThreadpoolWorkCallbacks ++@ stub WaitForUserPolicyForegroundProcessingInternal ++@ stdcall WaitNamedPipeW(wstr long) kernel32.WaitNamedPipeW ++@ stub WaitOnAddress ++@ stdcall WakeAllConditionVariable(ptr) kernel32.WakeAllConditionVariable ++@ stub WakeByAddressAll ++@ stub WakeByAddressSingle ++@ stdcall WakeConditionVariable(ptr) kernel32.WakeConditionVariable ++@ stub WerGetFlags ++@ stdcall WerRegisterFile(wstr long long) kernel32.WerRegisterFile ++@ stdcall WerRegisterMemoryBlock(ptr long) kernel32.WerRegisterMemoryBlock ++@ stdcall WerRegisterRuntimeExceptionModule(wstr ptr) kernel32.WerRegisterRuntimeExceptionModule ++@ stdcall WerSetFlags(long) kernel32.WerSetFlags ++@ stub WerUnregisterFile ++@ stdcall WerUnregisterMemoryBlock(ptr) kernel32.WerUnregisterMemoryBlock ++@ stub WerUnregisterRuntimeExceptionModule ++@ stub WerpNotifyLoadStringResource ++@ stub WerpNotifyUseStringResource ++@ stdcall WideCharToMultiByte(long long wstr long ptr long ptr ptr) kernel32.WideCharToMultiByte ++@ stdcall Wow64DisableWow64FsRedirection(ptr) kernel32.Wow64DisableWow64FsRedirection ++@ stdcall Wow64RevertWow64FsRedirection(ptr) kernel32.Wow64RevertWow64FsRedirection ++@ stdcall WriteConsoleA(long ptr long ptr ptr) kernel32.WriteConsoleA ++@ stdcall WriteConsoleInputA(long ptr long ptr) kernel32.WriteConsoleInputA ++@ stdcall WriteConsoleInputW(long ptr long ptr) kernel32.WriteConsoleInputW ++@ stdcall WriteConsoleOutputA(long ptr long long ptr) kernel32.WriteConsoleOutputA ++@ stdcall WriteConsoleOutputAttribute(long ptr long long ptr) kernel32.WriteConsoleOutputAttribute ++@ stdcall WriteConsoleOutputCharacterA(long ptr long long ptr) kernel32.WriteConsoleOutputCharacterA ++@ stdcall WriteConsoleOutputCharacterW(long ptr long long ptr) kernel32.WriteConsoleOutputCharacterW ++@ stdcall WriteConsoleOutputW(long ptr long long ptr) kernel32.WriteConsoleOutputW ++@ stdcall WriteConsoleW(long ptr long ptr ptr) kernel32.WriteConsoleW ++@ stdcall WriteFile(long ptr long ptr ptr) kernel32.WriteFile ++@ stdcall WriteFileEx(long ptr long ptr ptr) kernel32.WriteFileEx ++@ stdcall WriteFileGather(long ptr long ptr ptr) kernel32.WriteFileGather ++@ stdcall WriteProcessMemory(long ptr ptr long ptr) kernel32.WriteProcessMemory ++@ stub WriteStateAtomValue ++@ stub WriteStateContainerValue ++@ stdcall ZombifyActCtx(ptr) kernel32.ZombifyActCtx ++@ stub _AddMUIStringToCache ++@ stub _GetMUIStringFromCache ++@ stub _OpenMuiStringCache ++@ stub __dllonexit3 ++@ stub __wgetmainargs ++@ stub _amsg_exit ++@ stub _c_exit ++@ stub _cexit ++@ stub _exit ++@ stub _initterm ++@ stub _initterm_e ++@ stub _invalid_parameter ++@ stub _onexit ++@ stub _purecall ++@ stub _time64 ++@ stub atexit ++@ stub exit ++@ stub hgets ++@ stub hwprintf ++@ stdcall lstrcmp(str str) kernel32.lstrcmp ++@ stdcall lstrcmpA(str str) kernel32.lstrcmpA ++@ stdcall lstrcmpW(wstr wstr) kernel32.lstrcmpW ++@ stdcall lstrcmpi(str str) kernel32.lstrcmpi ++@ stdcall lstrcmpiA(str str) kernel32.lstrcmpiA ++@ stdcall lstrcmpiW(wstr wstr) kernel32.lstrcmpiW ++@ stdcall lstrcpyn(ptr str long) kernel32.lstrcpyn ++@ stdcall lstrcpynA(ptr str long) kernel32.lstrcpynA ++@ stdcall lstrcpynW(ptr wstr long) kernel32.lstrcpynW ++@ stdcall lstrlen(str) kernel32.lstrlen ++@ stdcall lstrlenA(str) kernel32.lstrlenA ++@ stdcall lstrlenW(wstr) kernel32.lstrlenW ++@ stub time ++@ stub wprintf +diff --git a/dlls/kernelbase/misc.c b/dlls/kernelbase/misc.c +new file mode 100644 +index 0000000..be1591a +--- /dev/null ++++ b/dlls/kernelbase/misc.c +@@ -0,0 +1,37 @@ ++/* ++ * kernelbase ++ * ++ * Copyright (c) 2016 Michael Müller ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include ++#include "windef.h" ++#include "winbase.h" ++ ++#include "wine/debug.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(kernelbase); ++ ++/*********************************************************************** ++ * QuirkIsEnabled (KERNELBASE.@) ++ */ ++BOOL WINAPI QuirkIsEnabled(void *arg) ++{ ++ FIXME("(%p): stub\n", arg); ++ return FALSE; ++} +diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec +index 6b6ead2..7c2a9d1 100644 +--- a/dlls/shlwapi/shlwapi.spec ++++ b/dlls/shlwapi/shlwapi.spec +@@ -417,7 +417,7 @@ + 417 stdcall -noname SHWinHelpOnDemandA(long str long ptr long) + 418 stdcall -ordinal MLFreeLibrary(long) + 419 stdcall -noname SHFlushSFCacheWrap() +-420 stub @ # CMemStream::Commit ++420 stub @ # CMemStream::Commit, don't forward + 421 stub -noname SHLoadPersistedDataObject + 422 stdcall -noname SHGlobalCounterCreateNamedA(str long) + 423 stdcall -noname SHGlobalCounterCreateNamedW(wstr long) +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 808d159..ae316a0 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -221,6 +221,13 @@ my @dll_groups = + "api-ms-win-core-processthreads-l1-1-1", + ], + [ ++ "kernel32", ++ "advapi32", ++ "shlwapi", ++ "user32", ++ "kernelbase", ++ ], ++ [ + "ole32", + "api-ms-win-downlevel-ole32-l1-1-0", + "api-ms-win-core-com-l1-1-0", +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0003-api-ms-win-core-quirks-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0003-api-ms-win-core-quirks-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0003-api-ms-win-core-quirks-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0003-api-ms-win-core-quirks-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,65 @@ +From 2f51e46724cd93eedfa9024dc3f88bfdd2eb3172 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 15 Jan 2016 13:07:09 +0100 +Subject: api-ms-win-core-quirks-l1-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-core-quirks-l1-1-0/Makefile.in | 1 + + .../api-ms-win-core-quirks-l1-1-0.spec | 8 ++++++++ + tools/make_specfiles | 4 ++++ + 4 files changed, 14 insertions(+) + create mode 100644 dlls/api-ms-win-core-quirks-l1-1-0/Makefile.in + create mode 100644 dlls/api-ms-win-core-quirks-l1-1-0/api-ms-win-core-quirks-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 7374b74..1cf8036 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2729,6 +2729,7 @@ WINE_CONFIG_DLL(api-ms-win-core-processthreads-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-processthreads-l1-1-2) + WINE_CONFIG_DLL(api-ms-win-core-profile-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-psapi-l1-1-0) ++WINE_CONFIG_DLL(api-ms-win-core-quirks-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-registry-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-rtlsupport-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-rtlsupport-l1-2-0) +diff --git a/dlls/api-ms-win-core-quirks-l1-1-0/Makefile.in b/dlls/api-ms-win-core-quirks-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..9486e8b +--- /dev/null ++++ b/dlls/api-ms-win-core-quirks-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-quirks-l1-1-0.dll +diff --git a/dlls/api-ms-win-core-quirks-l1-1-0/api-ms-win-core-quirks-l1-1-0.spec b/dlls/api-ms-win-core-quirks-l1-1-0/api-ms-win-core-quirks-l1-1-0.spec +new file mode 100644 +index 0000000..54ce373 +--- /dev/null ++++ b/dlls/api-ms-win-core-quirks-l1-1-0/api-ms-win-core-quirks-l1-1-0.spec +@@ -0,0 +1,8 @@ ++@ stub QuirkGetData ++@ stub QuirkGetData2 ++@ stdcall QuirkIsEnabled(ptr) kernelbase.QuirkIsEnabled ++@ stub QuirkIsEnabled2 ++@ stub QuirkIsEnabled3 ++@ stub QuirkIsEnabledForPackage ++@ stub QuirkIsEnabledForPackage2 ++@ stub QuirkIsEnabledForProcess +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 572c0b8..e62c2cd 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -225,6 +225,10 @@ my @dll_groups = + "kernelbase", + ], + [ ++ "kernelbase", ++ "api-ms-win-core-quirks-l1-1-0", ++ ], ++ [ + "ole32", + "api-ms-win-downlevel-ole32-l1-1-0", + "api-ms-win-core-com-l1-1-0", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0004-api-ms-win-core-delayload-l1-1-1-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0004-api-ms-win-core-delayload-l1-1-1-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0004-api-ms-win-core-delayload-l1-1-1-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0004-api-ms-win-core-delayload-l1-1-1-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,57 @@ +From 4535655125fb462a4a3651f3ecbfab07d35c5ba7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 15 Jan 2016 13:31:22 +0100 +Subject: api-ms-win-core-delayload-l1-1-1: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-core-delayload-l1-1-1/Makefile.in | 1 + + .../api-ms-win-core-delayload-l1-1-1.spec | 3 +++ + tools/make_specfiles | 1 + + 4 files changed, 6 insertions(+) + create mode 100644 dlls/api-ms-win-core-delayload-l1-1-1/Makefile.in + create mode 100644 dlls/api-ms-win-core-delayload-l1-1-1/api-ms-win-core-delayload-l1-1-1.spec + +diff --git a/configure.ac b/configure.ac +index 462850e..01afeda 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2700,6 +2700,7 @@ WINE_CONFIG_DLL(api-ms-win-core-datetime-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-datetime-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-debug-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-debug-l1-1-1) ++WINE_CONFIG_DLL(api-ms-win-core-delayload-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-errorhandling-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-errorhandling-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-errorhandling-l1-1-2) +diff --git a/dlls/api-ms-win-core-delayload-l1-1-1/Makefile.in b/dlls/api-ms-win-core-delayload-l1-1-1/Makefile.in +new file mode 100644 +index 0000000..bccec10 +--- /dev/null ++++ b/dlls/api-ms-win-core-delayload-l1-1-1/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-delayload-l1-1-1.dll +diff --git a/dlls/api-ms-win-core-delayload-l1-1-1/api-ms-win-core-delayload-l1-1-1.spec b/dlls/api-ms-win-core-delayload-l1-1-1/api-ms-win-core-delayload-l1-1-1.spec +new file mode 100644 +index 0000000..fe2b354 +--- /dev/null ++++ b/dlls/api-ms-win-core-delayload-l1-1-1/api-ms-win-core-delayload-l1-1-1.spec +@@ -0,0 +1,3 @@ ++@ stdcall DelayLoadFailureHook(str str) kernel32.DelayLoadFailureHook ++@ stdcall ResolveDelayLoadedAPI(ptr ptr ptr ptr ptr long) kernel32.ResolveDelayLoadedAPI ++@ stub ResolveDelayLoadsFromDll +diff --git a/tools/make_specfiles b/tools/make_specfiles +index e62c2cd..05010cc 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -165,6 +165,7 @@ my @dll_groups = + "api-ms-win-core-processthreads-l1-1-0", + "api-ms-win-core-debug-l1-1-0", + "api-ms-win-core-debug-l1-1-1", ++ "api-ms-win-core-delayload-l1-1-1", + "api-ms-win-core-errorhandling-l1-1-0", + "api-ms-win-core-errorhandling-l1-1-1", + "api-ms-win-core-interlocked-l1-1-0", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0005-api-ms-win-appmodel-runtime-l1-1-1-Add-new-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0005-api-ms-win-appmodel-runtime-l1-1-1-Add-new-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0005-api-ms-win-appmodel-runtime-l1-1-1-Add-new-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0005-api-ms-win-appmodel-runtime-l1-1-1-Add-new-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,90 @@ +From fa095669c3bad1091523c6133c6a12541555dfbd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 15 Jan 2016 13:37:26 +0100 +Subject: api-ms-win-appmodel-runtime-l1-1-1: Add new dll. + +--- + configure.ac | 1 + + .../api-ms-win-appmodel-runtime-l1-1-1/Makefile.in | 1 + + .../api-ms-win-appmodel-runtime-l1-1-1.spec | 36 ++++++++++++++++++++++ + tools/make_specfiles | 1 + + 4 files changed, 39 insertions(+) + create mode 100644 dlls/api-ms-win-appmodel-runtime-l1-1-1/Makefile.in + create mode 100644 dlls/api-ms-win-appmodel-runtime-l1-1-1/api-ms-win-appmodel-runtime-l1-1-1.spec + +diff --git a/configure.ac b/configure.ac +index 1ebf17a..2d2108b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2623,6 +2623,7 @@ WINE_CONFIG_DLL(advpack,,[implib]) + WINE_CONFIG_TEST(dlls/advpack/tests) + WINE_CONFIG_DLL(amstream,,[clean]) + WINE_CONFIG_TEST(dlls/amstream/tests) ++WINE_CONFIG_DLL(api-ms-win-appmodel-runtime-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-com-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-com-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-console-l1-1-0) +diff --git a/dlls/api-ms-win-appmodel-runtime-l1-1-1/Makefile.in b/dlls/api-ms-win-appmodel-runtime-l1-1-1/Makefile.in +new file mode 100644 +index 0000000..289d96f +--- /dev/null ++++ b/dlls/api-ms-win-appmodel-runtime-l1-1-1/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-appmodel-runtime-l1-1-1.dll +diff --git a/dlls/api-ms-win-appmodel-runtime-l1-1-1/api-ms-win-appmodel-runtime-l1-1-1.spec b/dlls/api-ms-win-appmodel-runtime-l1-1-1/api-ms-win-appmodel-runtime-l1-1-1.spec +new file mode 100644 +index 0000000..2e5fbf1 +--- /dev/null ++++ b/dlls/api-ms-win-appmodel-runtime-l1-1-1/api-ms-win-appmodel-runtime-l1-1-1.spec +@@ -0,0 +1,36 @@ ++@ stub ClosePackageInfo ++@ stub FindPackagesByPackageFamily ++@ stub FormatApplicationUserModelId ++@ stub GetApplicationUserModelId ++@ stub GetApplicationUserModelIdFromToken ++@ stub GetCurrentApplicationUserModelId ++@ stdcall GetCurrentPackageFamilyName(ptr ptr) kernel32.GetCurrentPackageFamilyName ++@ stub GetCurrentPackageFullName ++@ stdcall GetCurrentPackageId(ptr ptr) kernel32.GetCurrentPackageId ++@ stub GetCurrentPackageInfo ++@ stub GetCurrentPackagePath ++@ stub GetPackageApplicationIds ++@ stub GetPackageFamilyName ++@ stub GetPackageFamilyNameFromToken ++@ stub GetPackageFullName ++@ stub GetPackageFullNameFromToken ++@ stub GetPackageId ++@ stub GetPackageInfo ++@ stub GetPackagePath ++@ stub GetPackagePathByFullName ++@ stub GetPackagesByPackageFamily ++@ stub GetStagedPackageOrigin ++@ stub GetStagedPackagePathByFullName ++@ stub OpenPackageInfoByFullName ++@ stub OpenPackageInfoByFullNameForUser ++@ stub PackageFamilyNameFromFullName ++@ stub PackageFamilyNameFromId ++@ stub PackageFullNameFromId ++@ stub PackageIdFromFullName ++@ stub PackageNameAndPublisherIdFromFamilyName ++@ stub ParseApplicationUserModelId ++@ stub VerifyApplicationUserModelId ++@ stub VerifyPackageFamilyName ++@ stub VerifyPackageFullName ++@ stub VerifyPackageId ++@ stub VerifyPackageRelativeApplicationId +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 05010cc..d2158d8 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -161,6 +161,7 @@ my @dll_groups = + ], + [ + "kernel32", ++ "api-ms-win-appmodel-runtime-l1-1-1", + "api-ms-win-downlevel-normaliz-l1-1-0", + "api-ms-win-core-processthreads-l1-1-0", + "api-ms-win-core-debug-l1-1-0", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0006-api-ms-win-core-apiquery-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0006-api-ms-win-core-apiquery-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0006-api-ms-win-core-apiquery-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0006-api-ms-win-core-apiquery-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,55 @@ +From 60ecb8d166d2b940052160dcb250cc458ba2f728 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 15 Jan 2016 13:45:05 +0100 +Subject: api-ms-win-core-apiquery-l1-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-core-apiquery-l1-1-0/Makefile.in | 1 + + .../api-ms-win-core-apiquery-l1-1-0/api-ms-win-core-apiquery-l1-1-0.spec | 1 + + tools/make_specfiles | 1 + + 4 files changed, 4 insertions(+) + create mode 100644 dlls/api-ms-win-core-apiquery-l1-1-0/Makefile.in + create mode 100644 dlls/api-ms-win-core-apiquery-l1-1-0/api-ms-win-core-apiquery-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 6ab0640..ce22c64 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2626,6 +2626,7 @@ WINE_CONFIG_TEST(dlls/advpack/tests) + WINE_CONFIG_DLL(amstream,,[clean]) + WINE_CONFIG_TEST(dlls/amstream/tests) + WINE_CONFIG_DLL(api-ms-win-appmodel-runtime-l1-1-1) ++WINE_CONFIG_DLL(api-ms-win-core-apiquery-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-com-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-com-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-console-l1-1-0) +diff --git a/dlls/api-ms-win-core-apiquery-l1-1-0/Makefile.in b/dlls/api-ms-win-core-apiquery-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..492a265 +--- /dev/null ++++ b/dlls/api-ms-win-core-apiquery-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-apiquery-l1-1-0.dll +diff --git a/dlls/api-ms-win-core-apiquery-l1-1-0/api-ms-win-core-apiquery-l1-1-0.spec b/dlls/api-ms-win-core-apiquery-l1-1-0/api-ms-win-core-apiquery-l1-1-0.spec +new file mode 100644 +index 0000000..1d99dd7 +--- /dev/null ++++ b/dlls/api-ms-win-core-apiquery-l1-1-0/api-ms-win-core-apiquery-l1-1-0.spec +@@ -0,0 +1 @@ ++@ stdcall ApiSetQueryApiSetPresence(ptr ptr) ntdll.ApiSetQueryApiSetPresence +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 13a5674..cd0d761 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -264,6 +264,7 @@ my @dll_groups = + "msvcrt", + "ntdll", + "ntoskrnl.exe", ++ "api-ms-win-core-apiquery-l1-1-0", + "api-ms-win-core-rtlsupport-l1-1-0", + "api-ms-win-core-rtlsupport-l1-2-0", + ], +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0007-api-ms-win-core-libraryloader-l1-2-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0007-api-ms-win-core-libraryloader-l1-2-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0007-api-ms-win-core-libraryloader-l1-2-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0007-api-ms-win-core-libraryloader-l1-2-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,83 @@ +From 5ec2d0aa8425dcc9a80a0693946973ca36207e76 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 15 Jan 2016 13:48:54 +0100 +Subject: api-ms-win-core-libraryloader-l1-2-0: Add dll. + +--- + configure.ac | 1 + + .../Makefile.in | 1 + + .../api-ms-win-core-libraryloader-l1-2-0.spec | 29 ++++++++++++++++++++++ + tools/make_specfiles | 1 + + 4 files changed, 32 insertions(+) + create mode 100644 dlls/api-ms-win-core-libraryloader-l1-2-0/Makefile.in + create mode 100644 dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec + +diff --git a/configure.ac b/configure.ac +index aca3374..be563ca 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2652,6 +2652,7 @@ WINE_CONFIG_DLL(api-ms-win-core-io-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-kernel32-legacy-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-libraryloader-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-libraryloader-l1-1-1) ++WINE_CONFIG_DLL(api-ms-win-core-libraryloader-l1-2-0) + WINE_CONFIG_DLL(api-ms-win-core-localization-l1-2-0) + WINE_CONFIG_DLL(api-ms-win-core-localization-l1-2-1) + WINE_CONFIG_DLL(api-ms-win-core-localization-obsolete-l1-1-0) +diff --git a/dlls/api-ms-win-core-libraryloader-l1-2-0/Makefile.in b/dlls/api-ms-win-core-libraryloader-l1-2-0/Makefile.in +new file mode 100644 +index 0000000..5552133 +--- /dev/null ++++ b/dlls/api-ms-win-core-libraryloader-l1-2-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-libraryloader-l1-2-0.dll +diff --git a/dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec b/dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec +new file mode 100644 +index 0000000..6c385b6 +--- /dev/null ++++ b/dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec +@@ -0,0 +1,29 @@ ++@ stub AddDllDirectory ++@ stdcall DisableThreadLibraryCalls(long) kernel32.DisableThreadLibraryCalls ++@ stdcall EnumResourceLanguagesExA(long str str ptr long long long) kernel32.EnumResourceLanguagesExA ++@ stdcall EnumResourceLanguagesExW(long wstr wstr ptr long long long) kernel32.EnumResourceLanguagesExW ++@ stub EnumResourceNamesExA ++@ stub EnumResourceNamesExW ++@ stub EnumResourceTypesExA ++@ stub EnumResourceTypesExW ++@ stdcall FindResourceExW(long wstr wstr long) kernel32.FindResourceExW ++@ stub FindStringOrdinal ++@ stdcall FreeLibrary(long) kernel32.FreeLibrary ++@ stdcall FreeLibraryAndExitThread(long long) kernel32.FreeLibraryAndExitThread ++@ stdcall FreeResource(long) kernel32.FreeResource ++@ stdcall GetModuleFileNameA(long ptr long) kernel32.GetModuleFileNameA ++@ stdcall GetModuleFileNameW(long ptr long) kernel32.GetModuleFileNameW ++@ stdcall GetModuleHandleA(str) kernel32.GetModuleHandleA ++@ stdcall GetModuleHandleExA(long ptr ptr) kernel32.GetModuleHandleExA ++@ stdcall GetModuleHandleExW(long ptr ptr) kernel32.GetModuleHandleExW ++@ stdcall GetModuleHandleW(wstr) kernel32.GetModuleHandleW ++@ stdcall GetProcAddress(long str) kernel32.GetProcAddress ++@ stdcall LoadLibraryExA( str long long) kernel32.LoadLibraryExA ++@ stdcall LoadLibraryExW(wstr long long) kernel32.LoadLibraryExW ++@ stdcall LoadResource(long long) kernel32.LoadResource ++@ stdcall LoadStringA(long long ptr long) user32.LoadStringA ++@ stdcall LoadStringW(long long ptr long) user32.LoadStringW ++@ stdcall LockResource(long) kernel32.LockResource ++@ stub RemoveDllDirectory ++@ stub SetDefaultDllDirectories ++@ stdcall SizeofResource(long long) kernel32.SizeofResource +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 6456efe..09cc4d4 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -214,6 +214,7 @@ my @dll_groups = + "user32", + "api-ms-win-core-libraryloader-l1-1-0", + "api-ms-win-core-libraryloader-l1-1-1", ++ "api-ms-win-core-libraryloader-l1-2-0", + ], + [ + "kernel32", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0008-api-ms-win-core-kernel32-legacy-l1-1-1-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0008-api-ms-win-core-kernel32-legacy-l1-1-1-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0008-api-ms-win-core-kernel32-legacy-l1-1-1-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0008-api-ms-win-core-kernel32-legacy-l1-1-1-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,69 @@ +From 786eb78cf9eff284eae02b88bdefebad21b1fab5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 16 Jan 2016 20:01:49 +0100 +Subject: api-ms-win-core-kernel32-legacy-l1-1-1: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-core-kernel32-legacy-l1-1-1/Makefile.in | 1 + + .../api-ms-win-core-kernel32-legacy-l1-1-1.spec | 15 +++++++++++++++ + tools/make_specfiles | 1 + + 4 files changed, 18 insertions(+) + create mode 100644 dlls/api-ms-win-core-kernel32-legacy-l1-1-1/Makefile.in + create mode 100644 dlls/api-ms-win-core-kernel32-legacy-l1-1-1/api-ms-win-core-kernel32-legacy-l1-1-1.spec + +diff --git a/configure.ac b/configure.ac +index be563ca..36d95c9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2650,6 +2650,7 @@ WINE_CONFIG_DLL(api-ms-win-core-interlocked-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-interlocked-l1-2-0) + WINE_CONFIG_DLL(api-ms-win-core-io-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-kernel32-legacy-l1-1-0) ++WINE_CONFIG_DLL(api-ms-win-core-kernel32-legacy-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-libraryloader-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-libraryloader-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-libraryloader-l1-2-0) +diff --git a/dlls/api-ms-win-core-kernel32-legacy-l1-1-1/Makefile.in b/dlls/api-ms-win-core-kernel32-legacy-l1-1-1/Makefile.in +new file mode 100644 +index 0000000..c4a5c44 +--- /dev/null ++++ b/dlls/api-ms-win-core-kernel32-legacy-l1-1-1/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-kernel32-legacy-l1-1-1.dll +diff --git a/dlls/api-ms-win-core-kernel32-legacy-l1-1-1/api-ms-win-core-kernel32-legacy-l1-1-1.spec b/dlls/api-ms-win-core-kernel32-legacy-l1-1-1/api-ms-win-core-kernel32-legacy-l1-1-1.spec +new file mode 100644 +index 0000000..579e254 +--- /dev/null ++++ b/dlls/api-ms-win-core-kernel32-legacy-l1-1-1/api-ms-win-core-kernel32-legacy-l1-1-1.spec +@@ -0,0 +1,15 @@ ++@ stdcall FindFirstVolumeMountPointW(wstr ptr long) kernel32.FindFirstVolumeMountPointW ++@ stub FindNextVolumeMountPointW ++@ stdcall FindVolumeMountPointClose(ptr) kernel32.FindVolumeMountPointClose ++@ stub GetFileAttributesTransactedW ++@ stub GetFirmwareType ++@ stub GetNumaAvailableMemoryNodeEx ++@ stdcall GetNumaNodeProcessorMask(long ptr) kernel32.GetNumaNodeProcessorMask ++@ stub GetNumaProcessorNodeEx ++@ stdcall PowerClearRequest(long long) kernel32.PowerClearRequest ++@ stdcall PowerCreateRequest(ptr) kernel32.PowerCreateRequest ++@ stdcall PowerSetRequest(long long) kernel32.PowerSetRequest ++@ stdcall SetDllDirectoryW(wstr) kernel32.SetDllDirectoryW ++@ stdcall SetThreadIdealProcessor(long long) kernel32.SetThreadIdealProcessor ++@ stdcall SetVolumeMountPointW(wstr wstr) kernel32.SetVolumeMountPointW ++@ stdcall VerifyVersionInfoW(long long int64) kernel32.VerifyVersionInfoW +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 09cc4d4..03e753f 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -188,6 +188,7 @@ my @dll_groups = + "api-ms-win-core-heap-obsolete-l1-1-0", + "api-ms-win-core-io-l1-1-1", + "api-ms-win-core-kernel32-legacy-l1-1-0", ++ "api-ms-win-core-kernel32-legacy-l1-1-1", + "api-ms-win-core-localization-l1-2-0", + "api-ms-win-core-localization-obsolete-l1-1-0", + "api-ms-win-core-memory-l1-1-0", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0009-api-ms-win-core-heap-l2-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0009-api-ms-win-core-heap-l2-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0009-api-ms-win-core-heap-l2-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0009-api-ms-win-core-heap-l2-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,61 @@ +From d8b9e665f8ec796e7232700e0cc9df5b6b945c77 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 16 Jan 2016 20:03:48 +0100 +Subject: api-ms-win-core-heap-l2-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-core-heap-l2-1-0/Makefile.in | 1 + + dlls/api-ms-win-core-heap-l2-1-0/api-ms-win-core-heap-l2-1-0.spec | 7 +++++++ + tools/make_specfiles | 1 + + 4 files changed, 10 insertions(+) + create mode 100644 dlls/api-ms-win-core-heap-l2-1-0/Makefile.in + create mode 100644 dlls/api-ms-win-core-heap-l2-1-0/api-ms-win-core-heap-l2-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 36d95c9..4fe0992 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2645,6 +2645,7 @@ WINE_CONFIG_DLL(api-ms-win-core-file-l2-1-1) + WINE_CONFIG_DLL(api-ms-win-core-handle-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-heap-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-heap-l1-2-0) ++WINE_CONFIG_DLL(api-ms-win-core-heap-l2-1-0) + WINE_CONFIG_DLL(api-ms-win-core-heap-obsolete-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-interlocked-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-interlocked-l1-2-0) +diff --git a/dlls/api-ms-win-core-heap-l2-1-0/Makefile.in b/dlls/api-ms-win-core-heap-l2-1-0/Makefile.in +new file mode 100644 +index 0000000..3caed9e +--- /dev/null ++++ b/dlls/api-ms-win-core-heap-l2-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-heap-l2-1-0.dll +diff --git a/dlls/api-ms-win-core-heap-l2-1-0/api-ms-win-core-heap-l2-1-0.spec b/dlls/api-ms-win-core-heap-l2-1-0/api-ms-win-core-heap-l2-1-0.spec +new file mode 100644 +index 0000000..81308d2 +--- /dev/null ++++ b/dlls/api-ms-win-core-heap-l2-1-0/api-ms-win-core-heap-l2-1-0.spec +@@ -0,0 +1,7 @@ ++@ stdcall GlobalAlloc(long long) kernel32.GlobalAlloc ++@ stdcall GlobalFree(long) kernel32.GlobalFree ++@ stdcall LocalAlloc(long long) kernel32.LocalAlloc ++@ stdcall LocalFree(long) kernel32.LocalFree ++@ stdcall LocalLock(long) kernel32.LocalLock ++@ stdcall LocalReAlloc(long long long) kernel32.LocalReAlloc ++@ stdcall LocalUnlock(long) kernel32.LocalUnlock +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 03e753f..d945fbe 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -185,6 +185,7 @@ my @dll_groups = + "api-ms-win-core-handle-l1-1-0", + "api-ms-win-core-heap-l1-1-0", + "api-ms-win-core-heap-l1-2-0", ++ "api-ms-win-core-heap-l2-1-0", + "api-ms-win-core-heap-obsolete-l1-1-0", + "api-ms-win-core-io-l1-1-1", + "api-ms-win-core-kernel32-legacy-l1-1-0", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0010-api-ms-win-eventing-classicprovider-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0010-api-ms-win-eventing-classicprovider-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0010-api-ms-win-eventing-classicprovider-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0010-api-ms-win-eventing-classicprovider-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,62 @@ +From fb5ae0f86e24be8fb4ec8f6210d3a5dd9fb0bff9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 16 Jan 2016 20:09:22 +0100 +Subject: api-ms-win-eventing-classicprovider-l1-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-eventing-classicprovider-l1-1-0/Makefile.in | 1 + + .../api-ms-win-eventing-classicprovider-l1-1-0.spec | 8 ++++++++ + tools/make_specfiles | 1 + + 4 files changed, 11 insertions(+) + create mode 100644 dlls/api-ms-win-eventing-classicprovider-l1-1-0/Makefile.in + create mode 100644 dlls/api-ms-win-eventing-classicprovider-l1-1-0/api-ms-win-eventing-classicprovider-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 4fe0992..5c1e959 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2716,6 +2716,7 @@ WINE_CONFIG_DLL(api-ms-win-downlevel-shlwapi-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-downlevel-shlwapi-l2-1-0) + WINE_CONFIG_DLL(api-ms-win-downlevel-user32-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-downlevel-version-l1-1-0) ++WINE_CONFIG_DLL(api-ms-win-eventing-classicprovider-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-eventing-provider-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-ntuser-dc-access-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-security-base-l1-1-0) +diff --git a/dlls/api-ms-win-eventing-classicprovider-l1-1-0/Makefile.in b/dlls/api-ms-win-eventing-classicprovider-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..a0f628b +--- /dev/null ++++ b/dlls/api-ms-win-eventing-classicprovider-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-eventing-classicprovider-l1-1-0.dll +diff --git a/dlls/api-ms-win-eventing-classicprovider-l1-1-0/api-ms-win-eventing-classicprovider-l1-1-0.spec b/dlls/api-ms-win-eventing-classicprovider-l1-1-0/api-ms-win-eventing-classicprovider-l1-1-0.spec +new file mode 100644 +index 0000000..9b19435 +--- /dev/null ++++ b/dlls/api-ms-win-eventing-classicprovider-l1-1-0/api-ms-win-eventing-classicprovider-l1-1-0.spec +@@ -0,0 +1,8 @@ ++@ stdcall GetTraceEnableFlags(int64) advapi32.GetTraceEnableFlags ++@ stdcall GetTraceEnableLevel(int64) advapi32.GetTraceEnableLevel ++@ stdcall -ret64 GetTraceLoggerHandle(ptr) advapi32.GetTraceLoggerHandle ++@ stdcall RegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) advapi32.RegisterTraceGuidsW ++@ stdcall TraceEvent(int64 ptr) advapi32.TraceEvent ++@ varargs TraceMessage(int64 long ptr long) advapi32.TraceMessage ++@ stdcall TraceMessageVa(int64 long ptr long ptr) advapi32.TraceMessageVa ++@ stdcall UnregisterTraceGuids(int64) advapi32.UnregisterTraceGuids +diff --git a/tools/make_specfiles b/tools/make_specfiles +index d945fbe..0e9d47a 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -151,6 +151,7 @@ my @dll_groups = + "api-ms-win-downlevel-advapi32-l2-1-0", + "api-ms-win-security-base-l1-1-0", + "api-ms-win-core-registry-l1-1-0", ++ "api-ms-win-eventing-classicprovider-l1-1-0", + "api-ms-win-eventing-provider-l1-1-0", + "api-ms-win-security-base-l1-2-0", + "api-ms-win-security-lsalookup-l1-1-0", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0011-iertutil-Add-dll-and-add-stub-for-ordinal-811.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0011-iertutil-Add-dll-and-add-stub-for-ordinal-811.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0011-iertutil-Add-dll-and-add-stub-for-ordinal-811.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0011-iertutil-Add-dll-and-add-stub-for-ordinal-811.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,621 @@ +From 35889173d6a36887a9fdd08e49d3d5776f9680b9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 01:11:46 +0100 +Subject: iertutil: Add dll and add stub for ordinal 811. + +--- + configure.ac | 1 + + dlls/iertutil/Makefile.in | 4 + + dlls/iertutil/iertutil.spec | 521 ++++++++++++++++++++++++++++++++++++++++++++ + dlls/iertutil/main.c | 48 ++++ + 4 files changed, 574 insertions(+) + create mode 100644 dlls/iertutil/Makefile.in + create mode 100644 dlls/iertutil/iertutil.spec + create mode 100644 dlls/iertutil/main.c + +diff --git a/configure.ac b/configure.ac +index 0766edf..786a250 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2949,6 +2949,7 @@ WINE_CONFIG_DLL(iccvid,,[po]) + WINE_CONFIG_DLL(icmp) + WINE_CONFIG_DLL(ieframe,,[clean,implib,po]) + WINE_CONFIG_TEST(dlls/ieframe/tests) ++WINE_CONFIG_DLL(iertutil) + WINE_CONFIG_DLL(ifsmgr.vxd,enable_win16) + WINE_CONFIG_DLL(imaadp32.acm) + WINE_CONFIG_DLL(imagehlp,,[implib]) +diff --git a/dlls/iertutil/Makefile.in b/dlls/iertutil/Makefile.in +new file mode 100644 +index 0000000..268026e +--- /dev/null ++++ b/dlls/iertutil/Makefile.in +@@ -0,0 +1,4 @@ ++MODULE = iertutil.dll ++ ++C_SRCS = \ ++ main.c +diff --git a/dlls/iertutil/iertutil.spec b/dlls/iertutil/iertutil.spec +new file mode 100644 +index 0000000..a13779b +--- /dev/null ++++ b/dlls/iertutil/iertutil.spec +@@ -0,0 +1,521 @@ ++16 stub @ ++17 stub @ ++18 stub @ ++19 stub @ ++20 stub @ ++21 stub @ ++24 stub @ ++25 stub @ ++26 stub @ ++28 stub @ ++29 stub @ ++30 stub @ ++32 stub @ ++33 stub @ ++34 stub @ ++35 stub @ ++36 stub @ ++37 stub @ ++38 stub @ ++39 stub @ ++40 stub @ ++41 stub @ ++42 stub @ ++43 stub @ ++44 stub @ ++45 stub @ ++46 stub @ ++48 stub @ ++49 stub @ ++50 stub @ ++51 stub @ ++52 stub @ ++53 stub @ ++54 stub @ ++55 stub @ ++56 stub @ ++57 stub @ ++58 stub @ ++59 stub @ ++60 stub @ ++61 stub @ ++62 stub @ ++63 stub @ ++64 stub @ ++65 stub @ ++66 stub @ ++67 stub @ ++68 stub @ ++69 stub @ ++70 stub @ ++71 stub @ ++72 stub @ ++73 stub @ ++74 stub @ ++75 stub @ ++76 stub @ ++77 stub @ ++78 stub @ ++79 stub @ ++80 stub @ ++81 stub @ ++82 stub @ ++83 stub @ ++84 stub @ ++85 stub @ ++86 stub @ ++87 stub @ ++88 stub @ ++89 stub @ ++90 stub @ ++91 stub @ ++92 stub @ ++93 stub @ ++94 stub @ ++95 stub @ ++96 stub @ ++97 stub @ ++98 stub @ ++99 stub @ ++100 stub @ ++101 stub @ ++110 stub @ ++111 stub @ ++112 stub @ ++123 stub @ ++124 stub @ ++125 stub @ ++126 stub @ ++127 stub @ ++128 stub @ ++129 stub @ ++130 stub @ ++131 stub @ ++132 stub @ ++133 stub @ ++134 stub @ ++135 stub @ ++136 stub @ ++137 stub @ ++138 stub @ ++139 stub @ ++140 stub @ ++141 stub @ ++142 stub @ ++143 stub @ ++144 stub @ ++145 stub @ ++146 stub @ ++150 stub @ ++151 stub @ ++152 stub @ ++153 stub @ ++154 stub @ ++155 stub @ ++156 stub @ ++157 stub @ ++158 stub @ ++159 stub @ ++160 stub @ ++161 stub @ ++162 stub @ ++163 stub @ ++164 stub @ ++165 stub @ ++166 stub @ ++167 stub @ ++168 stub @ ++169 stub @ ++170 stub @ ++171 stub @ ++172 stub @ ++173 stub @ ++174 stub @ ++175 stub @ ++176 stub @ ++177 stub @ ++200 stub @ ++201 stub @ ++202 stub @ ++203 stub @ ++204 stub @ ++205 stub @ ++206 stub @ ++207 stub @ ++208 stub @ ++209 stub @ ++210 stub @ ++211 stub @ ++220 stub @ ++221 stub @ ++222 stub @ ++223 stub @ ++224 stub @ ++225 stub @ ++230 stub @ ++231 stub @ ++232 stub @ ++280 stub @ ++281 stub @ ++282 stub @ ++300 stub @ ++301 stub @ ++302 stub @ ++303 stub @ ++304 stub @ ++311 stub @ ++312 stub @ ++314 stub @ ++325 stub @ ++326 stub @ ++327 stub @ ++328 stub @ ++329 stub @ ++330 stub @ ++331 stub @ ++332 stub @ ++334 stub @ ++335 stub @ ++336 stub @ ++337 stub @ ++338 stub @ ++340 stub @ ++341 stub @ ++342 stub @ ++343 stub @ ++345 stub @ ++346 stub @ ++347 stub @ ++350 stub @ ++351 stub @ ++352 stub @ ++353 stub @ ++354 stub @ ++355 stub @ ++356 stub @ ++357 stub @ ++358 stub @ ++359 stub @ ++362 stub @ ++363 stub @ ++364 stub @ ++365 stub @ ++366 stub @ ++367 stub @ ++368 stub @ ++369 stub @ ++370 stub @ ++371 stub @ ++372 stub @ ++375 stub @ ++376 stub @ ++377 stub @ ++378 stub @ ++379 stub @ ++380 stub @ ++381 stub @ ++382 stub @ ++384 stub @ ++385 stub @ ++386 stub @ ++387 stub @ ++388 stub @ ++389 stub @ ++390 stub @ ++391 stub @ ++392 stub @ ++393 stub @ ++397 stub @ ++398 stub @ ++399 stub @ ++400 stub @ ++401 stub @ ++402 stub @ ++403 stub @ ++404 stub @ ++405 stub @ ++406 stub @ ++410 stub @ ++411 stub @ ++412 stub @ ++413 stub @ ++414 stub @ ++415 stub @ ++416 stub @ ++417 stub @ ++420 stub @ ++421 stub @ ++422 stub @ ++423 stub @ ++424 stub @ ++425 stub @ ++430 stub @ ++431 stub @ ++432 stub @ ++433 stub @ ++434 stub @ ++435 stub @ ++436 stub @ ++437 stub @ ++438 stub @ ++440 stub @ ++441 stub @ ++442 stub @ ++443 stub @ ++444 stub @ ++445 stub @ ++450 stub @ ++451 stub @ ++452 stub @ ++453 stub @ ++454 stub @ ++455 stub @ ++456 stub @ ++457 stub @ ++458 stub @ ++459 stub @ ++460 stub @ ++461 stub @ ++462 stub @ ++463 stub @ ++464 stub @ ++465 stub @ ++466 stub @ ++467 stub @ ++468 stub @ ++469 stub @ ++470 stub @ ++471 stub @ ++472 stub @ ++473 stub @ ++474 stub @ ++475 stub @ ++476 stub @ ++477 stub @ ++478 stub @ ++479 stub @ ++480 stub @ ++481 stub @ ++482 stub @ ++500 stub @ ++501 stub @ ++502 stub @ ++503 stub @ ++504 stub @ ++505 stub @ ++506 stub @ ++507 stub @ ++508 stub @ ++509 stub @ ++510 stub @ ++511 stub @ ++512 stub @ ++513 stub @ ++514 stub @ ++515 stub @ ++516 stub @ ++517 stub @ ++518 stub @ ++519 stub @ ++520 stub @ ++521 stub @ ++525 stub @ ++526 stub @ ++527 stub @ ++528 stub @ ++529 stub @ ++530 stub @ ++531 stub @ ++533 stub @ ++534 stub @ ++535 stub @ ++536 stub @ ++537 stub @ ++538 stub @ ++539 stub @ ++540 stub @ ++541 stub @ ++550 stub @ ++551 stub @ ++552 stub @ ++553 stub @ ++554 stub @ ++555 stub @ ++556 stub @ ++557 stub @ ++558 stub @ ++559 stub @ ++560 stub @ ++561 stub @ ++562 stub @ ++563 stub @ ++564 stub @ ++565 stub @ ++566 stub @ ++567 stub @ ++568 stub @ ++569 stub @ ++570 stub @ ++574 stub @ ++575 stub @ ++576 stub @ ++577 stub @ ++578 stub @ ++579 stub @ ++580 stub @ ++582 stub @ ++583 stub @ ++584 stub @ ++585 stub @ ++590 stub @ ++591 stub @ ++592 stub @ ++593 stub @ ++594 stub @ ++595 stub @ ++596 stub @ ++597 stub @ ++600 stub @ ++601 stub @ ++602 stub @ ++603 stub @ ++604 stub @ ++605 stub @ ++606 stub @ ++607 stub @ ++608 stub @ ++609 stub @ ++650 stub @ ++651 stub @ ++652 stub @ ++653 stub @ ++654 stub @ ++655 stub @ ++656 stub @ ++657 stub @ ++658 stub @ ++659 stub @ ++660 stub @ ++661 stub @ ++662 stub @ ++663 stub @ ++664 stub @ ++665 stub @ ++666 stub @ ++667 stub @ ++668 stub @ ++669 stub @ ++670 stub @ ++671 stub @ ++672 stub @ ++673 stub @ ++674 stub @ ++675 stub @ ++676 stub @ ++677 stub @ ++678 stub @ ++679 stub @ ++680 stub @ ++681 stub @ ++682 stub @ ++683 stub @ ++684 stub @ ++685 stub @ ++686 stub @ ++687 stub @ ++688 stub @ ++689 stub @ ++690 stub @ ++691 stub @ ++692 stub @ ++693 stub @ ++700 stub @ ++701 stub @ ++702 stub @ ++703 stub @ ++705 stub @ ++706 stub @ ++707 stub @ ++750 stub @ ++751 stub @ ++752 stub @ ++753 stub @ ++754 stub @ ++755 stub @ ++763 stub @ ++764 stub @ ++765 stub @ ++771 stub @ ++772 stub @ ++774 stub @ ++775 stub @ ++776 stub @ ++779 stub @ ++780 stub @ ++781 stub @ ++782 stub @ ++783 stub @ ++790 stub @ ++791 stub @ ++792 stub @ ++793 stub @ ++794 stub @ ++795 stub @ ++796 stub @ ++797 stub @ ++798 stub @ ++799 stub @ ++810 stub @ ++811 stdcall @(ptr) IERTUTIL_811 ++820 stub @ ++830 stub @ ++840 stub @ ++850 stub @ ++851 stub @ ++852 stub @ ++854 stub @ ++855 stub @ ++910 stub @ ++911 stub @ ++ ++@ stub CreateIUriBuilder ++@ stub CreateStringHashN ++@ stub CreateUri ++@ stub CreateUriFromMultiByteString ++@ stub CreateUriPriv ++@ stub CreateUriWithFragment ++@ stub DllCanUnloadNow ++@ stub DllGetActivationFactory ++@ stub DllGetClassObject ++@ stub FastMimeGetFileExtension ++@ stub FastMimeGetIsMimeFilterEnabled ++@ stub FastMimeLookupKnownType ++@ stub FastMimeSetIsMimeFilterEnabled ++@ stub GetIDNSettingsForIE ++@ stub GetIUriPriv ++@ stub GetIUriPriv2 ++@ stub GetPortFromUrlScheme ++@ stub GetPropertyFromName ++@ stub GetPropertyName ++@ stub IEDllLoader ++@ stub IEGetFrameUtilExports ++@ stub IEGetProcessModule ++@ stub IEGetTabWindowExports ++@ stub IERT_DelayLoadFailureHook ++@ stub IUriBuilderInternalCreateDomain ++@ stub ImpersonateUser ++@ stub IntlPercentEncodeNormalize ++@ stub IsDWORDProperty ++@ stub IsStringProperty ++@ stub LCIECalculatePackedStringSize ++@ stub LCIEPackString ++@ stub LCIEUnpackString ++@ stub PrivateCoInternetCanonicalizeIUri ++@ stub PrivateCoInternetCombineIUri ++@ stub PrivateCoInternetParseIUri ++@ stub ResetIDNLanguageData ++@ stub ResetIEExtensibility ++@ stub ResetIERegistrySettings ++@ stub RetiredOrdinal ++@ stub RevertImpersonate ++@ stub UriFromHostAndScheme +diff --git a/dlls/iertutil/main.c b/dlls/iertutil/main.c +new file mode 100644 +index 0000000..2b993a4 +--- /dev/null ++++ b/dlls/iertutil/main.c +@@ -0,0 +1,48 @@ ++/* ++ * Copyright 2016 Michael Müller ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include ++ ++#include "windef.h" ++#include "winbase.h" ++#include "wine/debug.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(iertutil); ++ ++BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) ++{ ++ TRACE("(%p, %u, %p)\n", instance, reason, reserved); ++ ++ switch (reason) ++ { ++ case DLL_WINE_PREATTACH: ++ return FALSE; /* prefer native version */ ++ case DLL_PROCESS_ATTACH: ++ DisableThreadLibraryCalls(instance); ++ break; ++ } ++ ++ return TRUE; ++} ++ ++BOOL WINAPI IERTUTIL_811(void *unknown) ++{ ++ FIXME("(%p): stub\n", unknown); ++ return FALSE; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0012-api-ms-win-core-winrt-registration-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0012-api-ms-win-core-winrt-registration-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0012-api-ms-win-core-winrt-registration-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0012-api-ms-win-core-winrt-registration-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,56 @@ +From ba9d632e784136f5a6bee1bbc3606dd09fed698e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 16:13:29 +0100 +Subject: api-ms-win-core-winrt-registration-l1-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-core-winrt-registration-l1-1-0/Makefile.in | 1 + + .../api-ms-win-core-winrt-registration-l1-1-0.spec | 2 ++ + tools/make_specfiles | 1 + + 4 files changed, 5 insertions(+) + create mode 100644 dlls/api-ms-win-core-winrt-registration-l1-1-0/Makefile.in + create mode 100644 dlls/api-ms-win-core-winrt-registration-l1-1-0/api-ms-win-core-winrt-registration-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 978b3fd..893f176 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2690,6 +2690,7 @@ WINE_CONFIG_DLL(api-ms-win-core-util-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-winrt-error-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-winrt-error-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-winrt-l1-1-0) ++WINE_CONFIG_DLL(api-ms-win-core-winrt-registration-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-winrt-string-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-xstate-l2-1-0) + WINE_CONFIG_DLL(api-ms-win-crt-conio-l1-1-0) +diff --git a/dlls/api-ms-win-core-winrt-registration-l1-1-0/Makefile.in b/dlls/api-ms-win-core-winrt-registration-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..3c0c04d +--- /dev/null ++++ b/dlls/api-ms-win-core-winrt-registration-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-winrt-registration-l1-1-0.dll +diff --git a/dlls/api-ms-win-core-winrt-registration-l1-1-0/api-ms-win-core-winrt-registration-l1-1-0.spec b/dlls/api-ms-win-core-winrt-registration-l1-1-0/api-ms-win-core-winrt-registration-l1-1-0.spec +new file mode 100644 +index 0000000..20c8d9c +--- /dev/null ++++ b/dlls/api-ms-win-core-winrt-registration-l1-1-0/api-ms-win-core-winrt-registration-l1-1-0.spec +@@ -0,0 +1,2 @@ ++@ stub RoGetActivatableClassRegistration ++@ stdcall RoGetServerActivatableClasses(ptr ptr ptr) combase.RoGetServerActivatableClasses +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 476dc85..042cdb2 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -280,6 +280,7 @@ my @dll_groups = + "combase", + "api-ms-win-core-winrt-l1-1-0", + "api-ms-win-core-winrt-string-l1-1-0", ++ "api-ms-win-core-winrt-registration-l1-1-0", + ], + [ + "bthprops.cpl", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0013-shcore-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0013-shcore-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0013-shcore-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0013-shcore-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,141 @@ +From 9f681980f083dd1243453e266cd132185aedd435 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sun, 17 Jan 2016 20:17:46 +0100 +Subject: shcore: Add dll. + +--- + configure.ac | 1 + + dlls/shcore/Makefile.in | 1 + + dlls/shcore/shcore.spec | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ + tools/make_specfiles | 5 +++ + 4 files changed, 90 insertions(+) + create mode 100644 dlls/shcore/Makefile.in + create mode 100644 dlls/shcore/shcore.spec + +diff --git a/configure.ac b/configure.ac +index cf39973..24ce204 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3231,6 +3231,7 @@ WINE_CONFIG_TEST(dlls/setupapi/tests) + WINE_CONFIG_DLL(setupx.dll16,enable_win16) + WINE_CONFIG_DLL(sfc,,[implib]) + WINE_CONFIG_DLL(sfc_os,,[implib]) ++WINE_CONFIG_DLL(shcore) + WINE_CONFIG_DLL(shdoclc,,[po]) + WINE_CONFIG_DLL(shdocvw,,[clean,implib]) + WINE_CONFIG_TEST(dlls/shdocvw/tests) +diff --git a/dlls/shcore/Makefile.in b/dlls/shcore/Makefile.in +new file mode 100644 +index 0000000..dd5f08f +--- /dev/null ++++ b/dlls/shcore/Makefile.in +@@ -0,0 +1 @@ ++MODULE = shcore.dll +diff --git a/dlls/shcore/shcore.spec b/dlls/shcore/shcore.spec +new file mode 100644 +index 0000000..12a4ef3 +--- /dev/null ++++ b/dlls/shcore/shcore.spec +@@ -0,0 +1,83 @@ ++@ stdcall CommandLineToArgvW(wstr ptr) shell32.CommandLineToArgvW ++@ stub CreateRandomAccessStreamOnFile ++@ stub CreateRandomAccessStreamOverStream ++@ stub CreateStreamOverRandomAccessStream ++@ stdcall -private DllCanUnloadNow() shell32.DllCanUnloadNow ++@ stub DllGetActivationFactory ++@ stdcall -private DllGetClassObject(ptr ptr ptr) shell32.DllGetClassObject ++@ stdcall GetCurrentProcessExplicitAppUserModelID(ptr) shell32.GetCurrentProcessExplicitAppUserModelID ++@ stub GetDpiForMonitor ++@ stub GetDpiForShellUIComponent ++@ stub GetProcessDpiAwareness ++@ stub GetProcessReference ++@ stub GetScaleFactorForDevice ++@ stub GetScaleFactorForMonitor ++@ stub IStream_Copy ++@ stdcall IStream_Read(ptr ptr long) shlwapi.IStream_Read ++@ stub IStream_ReadStr ++@ stdcall IStream_Reset(ptr) shlwapi.IStream_Reset ++@ stdcall IStream_Size(ptr ptr) shlwapi.IStream_Size ++@ stdcall IStream_Write(ptr ptr long) shlwapi.IStream_Write ++@ stub IStream_WriteStr ++@ stdcall IUnknown_AtomicRelease(long) shlwapi.IUnknown_AtomicRelease ++@ stdcall IUnknown_GetSite(ptr ptr ptr) shlwapi.IUnknown_GetSite ++@ stdcall IUnknown_QueryService(ptr ptr ptr ptr) shlwapi.IUnknown_QueryService ++@ stdcall IUnknown_Set(ptr ptr) shlwapi.IUnknown_Set ++@ stdcall IUnknown_SetSite(ptr ptr) shlwapi.IUnknown_SetSite ++@ stdcall IsOS(long) shlwapi.IsOS ++@ stub RegisterScaleChangeEvent ++@ stub RegisterScaleChangeNotifications ++@ stub RevokeScaleChangeNotifications ++@ stdcall SHAnsiToAnsi(str ptr long) shlwapi.SHAnsiToAnsi ++@ stdcall SHAnsiToUnicode(str ptr long) shlwapi.SHAnsiToUnicode ++@ stdcall SHCopyKeyA(long str long long) shlwapi.SHCopyKeyA ++@ stdcall SHCopyKeyW(long wstr long long) shlwapi.SHCopyKeyW ++@ stdcall SHCreateMemStream(ptr long) shlwapi.SHCreateMemStream ++@ stdcall SHCreateStreamOnFileA(str long ptr) shlwapi.SHCreateStreamOnFileA ++@ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) shlwapi.SHCreateStreamOnFileEx ++@ stdcall SHCreateStreamOnFileW(wstr long ptr) shlwapi.SHCreateStreamOnFileW ++@ stdcall SHCreateThread(ptr ptr long ptr) shlwapi.SHCreateThread ++@ stdcall SHCreateThreadRef(ptr ptr) shlwapi.SHCreateThreadRef ++@ stub SHCreateThreadWithHandle ++@ stdcall SHDeleteEmptyKeyA(long ptr) shlwapi.SHDeleteEmptyKeyA ++@ stdcall SHDeleteEmptyKeyW(long ptr) shlwapi.SHDeleteEmptyKeyW ++@ stdcall SHDeleteKeyA(long str) shlwapi.SHDeleteKeyA ++@ stdcall SHDeleteKeyW(long wstr) shlwapi.SHDeleteKeyW ++@ stdcall SHDeleteValueA(long str str) shlwapi.SHDeleteValueA ++@ stdcall SHDeleteValueW(long wstr wstr) shlwapi.SHDeleteValueW ++@ stdcall SHEnumKeyExA(long long str ptr) shlwapi.SHEnumKeyExA ++@ stdcall SHEnumKeyExW(long long wstr ptr) shlwapi.SHEnumKeyExW ++@ stdcall SHEnumValueA(long long str ptr ptr ptr ptr) shlwapi.SHEnumValueA ++@ stdcall SHEnumValueW(long long wstr ptr ptr ptr ptr) shlwapi.SHEnumValueW ++@ stdcall SHGetThreadRef(ptr) shlwapi.SHGetThreadRef ++@ stdcall SHGetValueA( long str str ptr ptr ptr ) shlwapi.SHGetValueA ++@ stdcall SHGetValueW( long wstr wstr ptr ptr ptr ) shlwapi.SHGetValueW ++@ stdcall SHOpenRegStream2A(long str str long) shlwapi.SHOpenRegStream2A ++@ stdcall SHOpenRegStream2W(long wstr wstr long) shlwapi.SHOpenRegStream2W ++@ stdcall SHOpenRegStreamA(long str str long) shlwapi.SHOpenRegStreamA ++@ stdcall SHOpenRegStreamW(long wstr wstr long) shlwapi.SHOpenRegStreamW ++@ stdcall SHQueryInfoKeyA(long ptr ptr ptr ptr) shlwapi.SHQueryInfoKeyA ++@ stdcall SHQueryInfoKeyW(long ptr ptr ptr ptr) shlwapi.SHQueryInfoKeyW ++@ stdcall SHQueryValueExA(long str ptr ptr ptr ptr) shlwapi.SHQueryValueExA ++@ stdcall SHQueryValueExW(long wstr ptr ptr ptr ptr) shlwapi.SHQueryValueExW ++@ stdcall SHRegDuplicateHKey(long) shlwapi.SHRegDuplicateHKey ++@ stdcall SHRegGetIntW(ptr wstr long) shlwapi.SHRegGetIntW ++@ stdcall SHRegGetPathA(long str str ptr long) shlwapi.SHRegGetPathA ++@ stdcall SHRegGetPathW(long wstr wstr ptr long) shlwapi.SHRegGetPathW ++@ stdcall SHRegGetValueA( long str str long ptr ptr ptr ) shlwapi.SHRegGetValueA ++@ stub SHRegGetValueFromHKCUHKLM ++@ stdcall SHRegGetValueW( long wstr wstr long ptr ptr ptr ) shlwapi.SHRegGetValueW ++@ stdcall SHRegSetPathA(long str str str long) shlwapi.SHRegSetPathA ++@ stdcall SHRegSetPathW(long wstr wstr wstr long) shlwapi.SHRegSetPathW ++@ stdcall SHReleaseThreadRef() shlwapi.SHReleaseThreadRef ++@ stdcall SHSetThreadRef(ptr) shlwapi.SHSetThreadRef ++@ stdcall SHSetValueA(long str str long ptr long) shlwapi.SHSetValueA ++@ stdcall SHSetValueW(long wstr wstr long ptr long) shlwapi.SHSetValueW ++@ stdcall SHStrDupA(str ptr) shlwapi.SHStrDupA ++@ stdcall SHStrDupW(wstr ptr) shlwapi.SHStrDupW ++@ stdcall SHUnicodeToAnsi(wstr ptr ptr) shlwapi.SHUnicodeToAnsi ++@ stdcall SHUnicodeToUnicode(wstr ptr long) shlwapi.SHUnicodeToUnicode ++@ stdcall SetCurrentProcessExplicitAppUserModelID(wstr) shell32.SetCurrentProcessExplicitAppUserModelID ++@ stub SetProcessDpiAwareness ++@ stub SetProcessReference ++@ stub UnregisterScaleChangeEvent +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 759fd9e..c4c4e07 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -256,6 +256,11 @@ my @dll_groups = + "api-ms-win-core-url-l1-1-0", + ], + [ ++ "shell32", ++ "shlwapi", ++ "shcore", ++ ], ++ [ + "user32", + "api-ms-win-downlevel-user32-l1-1-0", + "api-ms-win-ntuser-dc-access-l1-1-0", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0014-api-ms-win-shcore-obsolete-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0014-api-ms-win-shcore-obsolete-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0014-api-ms-win-shcore-obsolete-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0014-api-ms-win-shcore-obsolete-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,60 @@ +From aa8264fadf5a344a0af523cf8bc0c9c0e0d472f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 17:02:41 +0100 +Subject: api-ms-win-shcore-obsolete-l1-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-shcore-obsolete-l1-1-0/Makefile.in | 1 + + .../api-ms-win-shcore-obsolete-l1-1-0.spec | 3 +++ + tools/make_specfiles | 4 ++++ + 4 files changed, 9 insertions(+) + create mode 100644 dlls/api-ms-win-shcore-obsolete-l1-1-0/Makefile.in + create mode 100644 dlls/api-ms-win-shcore-obsolete-l1-1-0/api-ms-win-shcore-obsolete-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 24ce204..e8129b2 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2730,6 +2730,7 @@ WINE_CONFIG_DLL(api-ms-win-security-sddl-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-service-core-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-service-management-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-service-winsvc-l1-2-0) ++WINE_CONFIG_DLL(api-ms-win-shcore-obsolete-l1-1-0) + WINE_CONFIG_DLL(apphelp) + WINE_CONFIG_TEST(dlls/apphelp/tests) + WINE_CONFIG_DLL(appwiz.cpl,,[po]) +diff --git a/dlls/api-ms-win-shcore-obsolete-l1-1-0/Makefile.in b/dlls/api-ms-win-shcore-obsolete-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..6588d13 +--- /dev/null ++++ b/dlls/api-ms-win-shcore-obsolete-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-shcore-obsolete-l1-1-0.dll +diff --git a/dlls/api-ms-win-shcore-obsolete-l1-1-0/api-ms-win-shcore-obsolete-l1-1-0.spec b/dlls/api-ms-win-shcore-obsolete-l1-1-0/api-ms-win-shcore-obsolete-l1-1-0.spec +new file mode 100644 +index 0000000..edb8143 +--- /dev/null ++++ b/dlls/api-ms-win-shcore-obsolete-l1-1-0/api-ms-win-shcore-obsolete-l1-1-0.spec +@@ -0,0 +1,3 @@ ++@ stdcall CommandLineToArgvW(wstr ptr) shcore.CommandLineToArgvW ++@ stdcall SHStrDupA(str ptr) shcore.SHStrDupA ++@ stdcall SHStrDupW(wstr ptr) shcore.SHStrDupW +diff --git a/tools/make_specfiles b/tools/make_specfiles +index c4c4e07..0c07edb 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -261,6 +261,10 @@ my @dll_groups = + "shcore", + ], + [ ++ "shcore", ++ "api-ms-win-shcore-obsolete-l1-1-0", ++ ], ++ [ + "user32", + "api-ms-win-downlevel-user32-l1-1-0", + "api-ms-win-ntuser-dc-access-l1-1-0", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0015-ext-ms-win-xaml-pal-l1-1-0-Add-dll-and-add-stub-for-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0015-ext-ms-win-xaml-pal-l1-1-0-Add-dll-and-add-stub-for-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0015-ext-ms-win-xaml-pal-l1-1-0-Add-dll-and-add-stub-for-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0015-ext-ms-win-xaml-pal-l1-1-0-Add-dll-and-add-stub-for-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,94 @@ +From 26c9cf2b9b71306ebb6c19c6b0838a8ca91f3613 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 17:07:35 +0100 +Subject: ext-ms-win-xaml-pal-l1-1-0: Add dll and add stub for + XamlBehaviorEnabled. + +--- + configure.ac | 1 + + dlls/ext-ms-win-xaml-pal-l1-1-0/Makefile.in | 4 +++ + .../ext-ms-win-xaml-pal-l1-1-0.spec | 6 ++++ + dlls/ext-ms-win-xaml-pal-l1-1-0/main.c | 35 ++++++++++++++++++++++ + 4 files changed, 46 insertions(+) + create mode 100644 dlls/ext-ms-win-xaml-pal-l1-1-0/Makefile.in + create mode 100644 dlls/ext-ms-win-xaml-pal-l1-1-0/ext-ms-win-xaml-pal-l1-1-0.spec + create mode 100644 dlls/ext-ms-win-xaml-pal-l1-1-0/main.c + +diff --git a/configure.ac b/configure.ac +index 1ac07ff..049de86 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2929,6 +2929,7 @@ WINE_CONFIG_DLL(evr) + WINE_CONFIG_DLL(explorerframe,,[clean]) + WINE_CONFIG_TEST(dlls/explorerframe/tests) + WINE_CONFIG_DLL(ext-ms-win-gdi-devcaps-l1-1-0) ++WINE_CONFIG_DLL(ext-ms-win-xaml-pal-l1-1-0) + WINE_CONFIG_DLL(faultrep,,[implib]) + WINE_CONFIG_TEST(dlls/faultrep/tests) + WINE_CONFIG_DLL(fltlib) +diff --git a/dlls/ext-ms-win-xaml-pal-l1-1-0/Makefile.in b/dlls/ext-ms-win-xaml-pal-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..6382d85 +--- /dev/null ++++ b/dlls/ext-ms-win-xaml-pal-l1-1-0/Makefile.in +@@ -0,0 +1,4 @@ ++MODULE = ext-ms-win-xaml-pal-l1-1-0.dll ++ ++C_SRCS = \ ++ main.c +diff --git a/dlls/ext-ms-win-xaml-pal-l1-1-0/ext-ms-win-xaml-pal-l1-1-0.spec b/dlls/ext-ms-win-xaml-pal-l1-1-0/ext-ms-win-xaml-pal-l1-1-0.spec +new file mode 100644 +index 0000000..c167f5e +--- /dev/null ++++ b/dlls/ext-ms-win-xaml-pal-l1-1-0/ext-ms-win-xaml-pal-l1-1-0.spec +@@ -0,0 +1,6 @@ ++@ stub CreatePhoneAppBarProxy ++@ stub CreateWinTextBoxProxy ++@ stub GetThemeServices ++@ stdcall XamlBehaviorEnabled(ptr) ++@ stub XamlPalInitialize ++@ stub XamlPalUninitialize +diff --git a/dlls/ext-ms-win-xaml-pal-l1-1-0/main.c b/dlls/ext-ms-win-xaml-pal-l1-1-0/main.c +new file mode 100644 +index 0000000..3e28275 +--- /dev/null ++++ b/dlls/ext-ms-win-xaml-pal-l1-1-0/main.c +@@ -0,0 +1,35 @@ ++/* ++ * ext-ms-win-xaml-pal-l1-1-0 ++ * ++ * Copyright 2016 Michael Müller ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include ++#include ++ ++#include "windef.h" ++#include "winbase.h" ++#include "winuser.h" ++#include "wine/debug.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(xaml); ++ ++BOOL WINAPI XamlBehaviorEnabled(void *unknown) ++{ ++ FIXME("(%p): stub\n", unknown); ++ return TRUE; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0016-ext-ms-win-appmodel-usercontext-l1-1-0-Add-dll-and-a.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0016-ext-ms-win-appmodel-usercontext-l1-1-0-Add-dll-and-a.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0016-ext-ms-win-appmodel-usercontext-l1-1-0-Add-dll-and-a.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0016-ext-ms-win-appmodel-usercontext-l1-1-0-Add-dll-and-a.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,91 @@ +From 16af0df00d70307dd90c7dd836de57376b185844 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 17:12:45 +0100 +Subject: ext-ms-win-appmodel-usercontext-l1-1-0: Add dll and add stub for + UserContextExtInitialize. + +--- + configure.ac | 1 + + .../Makefile.in | 4 +++ + .../ext-ms-win-appmodel-usercontext-l1-1-0.spec | 3 ++ + dlls/ext-ms-win-appmodel-usercontext-l1-1-0/main.c | 35 ++++++++++++++++++++++ + 4 files changed, 43 insertions(+) + create mode 100644 dlls/ext-ms-win-appmodel-usercontext-l1-1-0/Makefile.in + create mode 100644 dlls/ext-ms-win-appmodel-usercontext-l1-1-0/ext-ms-win-appmodel-usercontext-l1-1-0.spec + create mode 100644 dlls/ext-ms-win-appmodel-usercontext-l1-1-0/main.c + +diff --git a/configure.ac b/configure.ac +index 049de86..36924eb 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2928,6 +2928,7 @@ WINE_CONFIG_DLL(esent) + WINE_CONFIG_DLL(evr) + WINE_CONFIG_DLL(explorerframe,,[clean]) + WINE_CONFIG_TEST(dlls/explorerframe/tests) ++WINE_CONFIG_DLL(ext-ms-win-appmodel-usercontext-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-gdi-devcaps-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-xaml-pal-l1-1-0) + WINE_CONFIG_DLL(faultrep,,[implib]) +diff --git a/dlls/ext-ms-win-appmodel-usercontext-l1-1-0/Makefile.in b/dlls/ext-ms-win-appmodel-usercontext-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..16eee75 +--- /dev/null ++++ b/dlls/ext-ms-win-appmodel-usercontext-l1-1-0/Makefile.in +@@ -0,0 +1,4 @@ ++MODULE = ext-ms-win-appmodel-usercontext-l1-1-0.dll ++ ++C_SRCS = \ ++ main.c +diff --git a/dlls/ext-ms-win-appmodel-usercontext-l1-1-0/ext-ms-win-appmodel-usercontext-l1-1-0.spec b/dlls/ext-ms-win-appmodel-usercontext-l1-1-0/ext-ms-win-appmodel-usercontext-l1-1-0.spec +new file mode 100644 +index 0000000..7642d15 +--- /dev/null ++++ b/dlls/ext-ms-win-appmodel-usercontext-l1-1-0/ext-ms-win-appmodel-usercontext-l1-1-0.spec +@@ -0,0 +1,3 @@ ++@ stub UserContextExtCleanup ++@ stdcall UserContextExtInitialize() ++@ stub UserContextExtSetToken +diff --git a/dlls/ext-ms-win-appmodel-usercontext-l1-1-0/main.c b/dlls/ext-ms-win-appmodel-usercontext-l1-1-0/main.c +new file mode 100644 +index 0000000..7a9e75f +--- /dev/null ++++ b/dlls/ext-ms-win-appmodel-usercontext-l1-1-0/main.c +@@ -0,0 +1,35 @@ ++/* ++ * ext-ms-win-appmodel-usercontext-l1-1-0 ++ * ++ * Copyright 2016 Michael Müller ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include ++#include ++ ++#include "windef.h" ++#include "winbase.h" ++#include "winuser.h" ++#include "wine/debug.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(usercontext); ++ ++HRESULT WINAPI UserContextExtInitialize(void) ++{ ++ FIXME("(): stub\n"); ++ return S_OK; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0017-api-ms-win-shcore-thread-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0017-api-ms-win-shcore-thread-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0017-api-ms-win-shcore-thread-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0017-api-ms-win-shcore-thread-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,62 @@ +From 4ec5001da925dfb1f9506539d93c4c2297c53e16 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Tue, 19 Jan 2016 16:19:11 +0100 +Subject: api-ms-win-shcore-thread-l1-1-0: Add dll + +--- + configure.ac | 1 + + dlls/api-ms-win-shcore-thread-l1-1-0/Makefile.in | 1 + + .../api-ms-win-shcore-thread-l1-1-0.spec | 8 ++++++++ + tools/make_specfiles | 1 + + 4 files changed, 11 insertions(+) + create mode 100644 dlls/api-ms-win-shcore-thread-l1-1-0/Makefile.in + create mode 100644 dlls/api-ms-win-shcore-thread-l1-1-0/api-ms-win-shcore-thread-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 363b78c..37ff44d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2801,6 +2801,7 @@ WINE_CONFIG_DLL(api-ms-win-service-core-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-service-management-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-service-winsvc-l1-2-0) + WINE_CONFIG_DLL(api-ms-win-shcore-obsolete-l1-1-0) ++WINE_CONFIG_DLL(api-ms-win-shcore-thread-l1-1-0) + WINE_CONFIG_DLL(apphelp) + WINE_CONFIG_TEST(dlls/apphelp/tests) + WINE_CONFIG_DLL(appwiz.cpl,,[po]) +diff --git a/dlls/api-ms-win-shcore-thread-l1-1-0/Makefile.in b/dlls/api-ms-win-shcore-thread-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..0a20ccf +--- /dev/null ++++ b/dlls/api-ms-win-shcore-thread-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-shcore-thread-l1-1-0.dll +diff --git a/dlls/api-ms-win-shcore-thread-l1-1-0/api-ms-win-shcore-thread-l1-1-0.spec b/dlls/api-ms-win-shcore-thread-l1-1-0/api-ms-win-shcore-thread-l1-1-0.spec +new file mode 100644 +index 0000000..1533005 +--- /dev/null ++++ b/dlls/api-ms-win-shcore-thread-l1-1-0/api-ms-win-shcore-thread-l1-1-0.spec +@@ -0,0 +1,8 @@ ++@ stub GetProcessReference ++@ stdcall SHCreateThread(ptr ptr long ptr) shcore.SHCreateThread ++@ stdcall SHCreateThreadRef(ptr ptr) shcore.SHCreateThreadRef ++@ stub SHCreateThreadWithHandle ++@ stdcall SHGetThreadRef(ptr) shcore.SHGetThreadRef ++@ stdcall SHReleaseThreadRef() shcore.SHReleaseThreadRef ++@ stdcall SHSetThreadRef(ptr) shcore.SHSetThreadRef ++@ stub SetProcessReference +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 197ff73..fc2cf66 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -262,6 +262,7 @@ my @dll_groups = + [ + "shcore", + "api-ms-win-shcore-obsolete-l1-1-0", ++ "api-ms-win-shcore-thread-l1-1-0", + ], + [ + "user32", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0018-ext-ms-win-xaml-pal-l1-1-0-Add-stub-for-GetThemeServ.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0018-ext-ms-win-xaml-pal-l1-1-0-Add-stub-for-GetThemeServ.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0018-ext-ms-win-xaml-pal-l1-1-0-Add-stub-for-GetThemeServ.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0018-ext-ms-win-xaml-pal-l1-1-0-Add-stub-for-GetThemeServ.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,41 @@ +From fd2f3c0b9b2f46dd2e0e114d678c555b59adae8d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 21 Jan 2016 00:40:29 +0100 +Subject: ext-ms-win-xaml-pal-l1-1-0: Add stub for GetThemeServices. + +--- + dlls/ext-ms-win-xaml-pal-l1-1-0/ext-ms-win-xaml-pal-l1-1-0.spec | 2 +- + dlls/ext-ms-win-xaml-pal-l1-1-0/main.c | 8 ++++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/dlls/ext-ms-win-xaml-pal-l1-1-0/ext-ms-win-xaml-pal-l1-1-0.spec b/dlls/ext-ms-win-xaml-pal-l1-1-0/ext-ms-win-xaml-pal-l1-1-0.spec +index c167f5e..042e037 100644 +--- a/dlls/ext-ms-win-xaml-pal-l1-1-0/ext-ms-win-xaml-pal-l1-1-0.spec ++++ b/dlls/ext-ms-win-xaml-pal-l1-1-0/ext-ms-win-xaml-pal-l1-1-0.spec +@@ -1,6 +1,6 @@ + @ stub CreatePhoneAppBarProxy + @ stub CreateWinTextBoxProxy +-@ stub GetThemeServices ++@ stdcall GetThemeServices(ptr) + @ stdcall XamlBehaviorEnabled(ptr) + @ stub XamlPalInitialize + @ stub XamlPalUninitialize +diff --git a/dlls/ext-ms-win-xaml-pal-l1-1-0/main.c b/dlls/ext-ms-win-xaml-pal-l1-1-0/main.c +index 3e28275..45353ba 100644 +--- a/dlls/ext-ms-win-xaml-pal-l1-1-0/main.c ++++ b/dlls/ext-ms-win-xaml-pal-l1-1-0/main.c +@@ -33,3 +33,11 @@ BOOL WINAPI XamlBehaviorEnabled(void *unknown) + FIXME("(%p): stub\n", unknown); + return TRUE; + } ++ ++HRESULT WINAPI GetThemeServices(void **interface) ++{ ++ FIXME("(%p): stub\n", interface); ++ ++ *interface = NULL; ++ return E_NOTIMPL; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0019-api-ms-win-core-memory-l1-1-2-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0019-api-ms-win-core-memory-l1-1-2-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0019-api-ms-win-core-memory-l1-1-2-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0019-api-ms-win-core-memory-l1-1-2-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,94 @@ +From c61580a063cac3a8ed54afb5df03ab1ccf60f1df Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 21 Jan 2016 00:42:35 +0100 +Subject: api-ms-win-core-memory-l1-1-2: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-core-memory-l1-1-2/Makefile.in | 1 + + .../api-ms-win-core-memory-l1-1-2.spec | 40 ++++++++++++++++++++++ + tools/make_specfiles | 1 + + 4 files changed, 43 insertions(+) + create mode 100644 dlls/api-ms-win-core-memory-l1-1-2/Makefile.in + create mode 100644 dlls/api-ms-win-core-memory-l1-1-2/api-ms-win-core-memory-l1-1-2.spec + +diff --git a/configure.ac b/configure.ac +index 09332f4..67fd5d5 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2664,6 +2664,7 @@ WINE_CONFIG_DLL(api-ms-win-core-localization-obsolete-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-localregistry-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-memory-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-memory-l1-1-1) ++WINE_CONFIG_DLL(api-ms-win-core-memory-l1-1-2) + WINE_CONFIG_DLL(api-ms-win-core-misc-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-namedpipe-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-namedpipe-l1-2-0) +diff --git a/dlls/api-ms-win-core-memory-l1-1-2/Makefile.in b/dlls/api-ms-win-core-memory-l1-1-2/Makefile.in +new file mode 100644 +index 0000000..d76aa0c +--- /dev/null ++++ b/dlls/api-ms-win-core-memory-l1-1-2/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-memory-l1-1-2.dll +diff --git a/dlls/api-ms-win-core-memory-l1-1-2/api-ms-win-core-memory-l1-1-2.spec b/dlls/api-ms-win-core-memory-l1-1-2/api-ms-win-core-memory-l1-1-2.spec +new file mode 100644 +index 0000000..c563507 +--- /dev/null ++++ b/dlls/api-ms-win-core-memory-l1-1-2/api-ms-win-core-memory-l1-1-2.spec +@@ -0,0 +1,40 @@ ++@ stdcall AllocateUserPhysicalPages(long ptr ptr) kernel32.AllocateUserPhysicalPages ++@ stub AllocateUserPhysicalPagesNuma ++@ stub CreateFileMappingFromApp ++@ stub CreateFileMappingNumaW ++@ stdcall CreateFileMappingW(long ptr long long long wstr) kernel32.CreateFileMappingW ++@ stdcall CreateMemoryResourceNotification(long) kernel32.CreateMemoryResourceNotification ++@ stdcall FlushViewOfFile(ptr long) kernel32.FlushViewOfFile ++@ stdcall FreeUserPhysicalPages(long ptr ptr) kernel32.FreeUserPhysicalPages ++@ stub GetLargePageMinimum ++@ stub GetMemoryErrorHandlingCapabilities ++@ stub GetProcessWorkingSetSizeEx ++@ stdcall GetSystemFileCacheSize(ptr ptr ptr) kernel32.GetSystemFileCacheSize ++@ stdcall GetWriteWatch(long ptr long ptr ptr ptr) kernel32.GetWriteWatch ++@ stub MapUserPhysicalPages ++@ stdcall MapViewOfFile(long long long long long) kernel32.MapViewOfFile ++@ stdcall MapViewOfFileEx(long long long long long ptr) kernel32.MapViewOfFileEx ++@ stub MapViewOfFileFromApp ++@ stdcall OpenFileMappingW(long long wstr) kernel32.OpenFileMappingW ++@ stub PrefetchVirtualMemory ++@ stdcall QueryMemoryResourceNotification(ptr ptr) kernel32.QueryMemoryResourceNotification ++@ stdcall ReadProcessMemory(long ptr ptr long ptr) kernel32.ReadProcessMemory ++@ stub RegisterBadMemoryNotification ++@ stdcall ResetWriteWatch(ptr long) kernel32.ResetWriteWatch ++@ stub SetProcessWorkingSetSizeEx ++@ stdcall SetSystemFileCacheSize(long long long) kernel32.SetSystemFileCacheSize ++@ stdcall UnmapViewOfFile(ptr) kernel32.UnmapViewOfFile ++@ stub UnmapViewOfFileEx ++@ stub UnregisterBadMemoryNotification ++@ stdcall VirtualAlloc(ptr long long long) kernel32.VirtualAlloc ++@ stdcall VirtualAllocEx(long ptr long long long) kernel32.VirtualAllocEx ++@ stub VirtualAllocExNuma ++@ stdcall VirtualFree(ptr long long) kernel32.VirtualFree ++@ stdcall VirtualFreeEx(long ptr long long) kernel32.VirtualFreeEx ++@ stdcall VirtualLock(ptr long) kernel32.VirtualLock ++@ stdcall VirtualProtect(ptr long long ptr) kernel32.VirtualProtect ++@ stdcall VirtualProtectEx(long ptr long long ptr) kernel32.VirtualProtectEx ++@ stdcall VirtualQuery(ptr ptr long) kernel32.VirtualQuery ++@ stdcall VirtualQueryEx(long ptr ptr long) kernel32.VirtualQueryEx ++@ stdcall VirtualUnlock(ptr long) kernel32.VirtualUnlock ++@ stdcall WriteProcessMemory(long ptr ptr long ptr) kernel32.WriteProcessMemory +diff --git a/tools/make_specfiles b/tools/make_specfiles +index f972879..8498606 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -195,6 +195,7 @@ my @dll_groups = + "api-ms-win-core-localization-obsolete-l1-1-0", + "api-ms-win-core-memory-l1-1-0", + "api-ms-win-core-memory-l1-1-1", ++ "api-ms-win-core-memory-l1-1-2", + "api-ms-win-core-processenvironment-l1-1-0", + "api-ms-win-core-processenvironment-l1-2-0", + "api-ms-win-core-psapi-l1-1-0", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0020-api-ms-win-core-wow64-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0020-api-ms-win-core-wow64-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0020-api-ms-win-core-wow64-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0020-api-ms-win-core-wow64-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,57 @@ +From 59d8094be6c648259ebaabb39c06c41f1e227490 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 21 Jan 2016 00:48:48 +0100 +Subject: api-ms-win-core-wow64-l1-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-core-wow64-l1-1-0/Makefile.in | 1 + + dlls/api-ms-win-core-wow64-l1-1-0/api-ms-win-core-wow64-l1-1-0.spec | 3 +++ + tools/make_specfiles | 1 + + 4 files changed, 6 insertions(+) + create mode 100644 dlls/api-ms-win-core-wow64-l1-1-0/Makefile.in + create mode 100644 dlls/api-ms-win-core-wow64-l1-1-0/api-ms-win-core-wow64-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 67fd5d5..e10e890 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2696,6 +2696,7 @@ WINE_CONFIG_DLL(api-ms-win-core-winrt-error-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-core-winrt-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-winrt-registration-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-winrt-string-l1-1-0) ++WINE_CONFIG_DLL(api-ms-win-core-wow64-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-xstate-l2-1-0) + WINE_CONFIG_DLL(api-ms-win-crt-conio-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-crt-convert-l1-1-0) +diff --git a/dlls/api-ms-win-core-wow64-l1-1-0/Makefile.in b/dlls/api-ms-win-core-wow64-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..3e3d74f +--- /dev/null ++++ b/dlls/api-ms-win-core-wow64-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-wow64-l1-1-0.dll +diff --git a/dlls/api-ms-win-core-wow64-l1-1-0/api-ms-win-core-wow64-l1-1-0.spec b/dlls/api-ms-win-core-wow64-l1-1-0/api-ms-win-core-wow64-l1-1-0.spec +new file mode 100644 +index 0000000..c1df1cf +--- /dev/null ++++ b/dlls/api-ms-win-core-wow64-l1-1-0/api-ms-win-core-wow64-l1-1-0.spec +@@ -0,0 +1,3 @@ ++@ stdcall IsWow64Process(ptr ptr) kernel32.IsWow64Process ++@ stdcall Wow64DisableWow64FsRedirection(ptr) kernel32.Wow64DisableWow64FsRedirection ++@ stdcall Wow64RevertWow64FsRedirection(ptr) kernel32.Wow64RevertWow64FsRedirection +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 8498606..b9a96c7 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -210,6 +210,7 @@ my @dll_groups = + "api-ms-win-core-localization-l1-2-1", + "api-ms-win-core-datetime-l1-1-0", + "api-ms-win-core-datetime-l1-1-1", ++ "api-ms-win-core-wow64-l1-1-0", + "api-ms-win-core-xstate-l2-1-0", + "api-ms-win-core-errorhandling-l1-1-2", + ], +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0021-api-ms-win-core-shlwapi-obsolete-l1-2-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0021-api-ms-win-core-shlwapi-obsolete-l1-2-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0021-api-ms-win-core-shlwapi-obsolete-l1-2-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0021-api-ms-win-core-shlwapi-obsolete-l1-2-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,113 @@ +From 5d0b4a27e9ed7d0ee6a763586715c8d9d7f424ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 21 Jan 2016 00:52:33 +0100 +Subject: api-ms-win-core-shlwapi-obsolete-l1-2-0: Add dll. + +--- + configure.ac | 1 + + .../Makefile.in | 1 + + .../api-ms-win-core-shlwapi-obsolete-l1-2-0.spec | 58 ++++++++++++++++++++++ + tools/make_specfiles | 1 + + 4 files changed, 61 insertions(+) + create mode 100644 dlls/api-ms-win-core-shlwapi-obsolete-l1-2-0/Makefile.in + create mode 100644 dlls/api-ms-win-core-shlwapi-obsolete-l1-2-0/api-ms-win-core-shlwapi-obsolete-l1-2-0.spec + +diff --git a/configure.ac b/configure.ac +index e10e890..e329038 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2681,6 +2681,7 @@ WINE_CONFIG_DLL(api-ms-win-core-registry-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-rtlsupport-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-rtlsupport-l1-2-0) + WINE_CONFIG_DLL(api-ms-win-core-shlwapi-legacy-l1-1-0) ++WINE_CONFIG_DLL(api-ms-win-core-shlwapi-obsolete-l1-2-0) + WINE_CONFIG_DLL(api-ms-win-core-string-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-synch-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-synch-l1-2-0) +diff --git a/dlls/api-ms-win-core-shlwapi-obsolete-l1-2-0/Makefile.in b/dlls/api-ms-win-core-shlwapi-obsolete-l1-2-0/Makefile.in +new file mode 100644 +index 0000000..3f39b0b +--- /dev/null ++++ b/dlls/api-ms-win-core-shlwapi-obsolete-l1-2-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-shlwapi-obsolete-l1-2-0.dll +\ No newline at end of file +diff --git a/dlls/api-ms-win-core-shlwapi-obsolete-l1-2-0/api-ms-win-core-shlwapi-obsolete-l1-2-0.spec b/dlls/api-ms-win-core-shlwapi-obsolete-l1-2-0/api-ms-win-core-shlwapi-obsolete-l1-2-0.spec +new file mode 100644 +index 0000000..8b8b520 +--- /dev/null ++++ b/dlls/api-ms-win-core-shlwapi-obsolete-l1-2-0/api-ms-win-core-shlwapi-obsolete-l1-2-0.spec +@@ -0,0 +1,58 @@ ++@ stdcall QISearch(long long long long) shlwapi.QISearch ++@ stdcall StrCSpnA(str str) shlwapi.StrCSpnA ++@ stdcall StrCSpnIA(str str) shlwapi.StrCSpnIA ++@ stdcall StrCSpnIW(wstr wstr) shlwapi.StrCSpnIW ++@ stdcall StrCSpnW(wstr wstr) shlwapi.StrCSpnW ++@ stdcall StrCatBuffA(str str long) shlwapi.StrCatBuffA ++@ stdcall StrCatBuffW(wstr wstr long) shlwapi.StrCatBuffW ++@ stdcall StrCatChainW(ptr long long wstr) shlwapi.StrCatChainW ++@ stdcall StrChrA(str long) shlwapi.StrChrA ++@ stdcall StrChrIA(str long) shlwapi.StrChrIA ++@ stdcall StrChrIW(wstr long) shlwapi.StrChrIW ++@ stub StrChrNIW ++@ stdcall StrChrNW(wstr long long) shlwapi.StrChrNW ++@ stdcall StrChrW(wstr long) shlwapi.StrChrW ++@ stdcall StrCmpCA(str str) shlwapi.StrCmpCA ++@ stdcall StrCmpCW(wstr wstr) shlwapi.StrCmpCW ++@ stdcall StrCmpICA(str str) shlwapi.StrCmpICA ++@ stdcall StrCmpICW(wstr wstr) shlwapi.StrCmpICW ++@ stdcall StrCmpIW(wstr wstr) shlwapi.StrCmpIW ++@ stdcall StrCmpLogicalW(wstr wstr) shlwapi.StrCmpLogicalW ++@ stdcall StrCmpNA(str str long) shlwapi.StrCmpNA ++@ stdcall StrCmpNCA(str ptr long) shlwapi.StrCmpNCA ++@ stdcall StrCmpNCW(wstr wstr long) shlwapi.StrCmpNCW ++@ stdcall StrCmpNIA(str str long) shlwapi.StrCmpNIA ++@ stdcall StrCmpNICA(long long long) shlwapi.StrCmpNICA ++@ stdcall StrCmpNICW(wstr wstr long) shlwapi.StrCmpNICW ++@ stdcall StrCmpNIW(wstr wstr long) shlwapi.StrCmpNIW ++@ stdcall StrCmpNW(wstr wstr long) shlwapi.StrCmpNW ++@ stdcall StrCmpW(wstr wstr) shlwapi.StrCmpW ++@ stdcall StrCpyNW(ptr wstr long) shlwapi.StrCpyNW ++@ stdcall StrDupA(str) shlwapi.StrDupA ++@ stdcall StrDupW(wstr) shlwapi.StrDupW ++@ stdcall StrIsIntlEqualA(long str str long) shlwapi.StrIsIntlEqualA ++@ stdcall StrIsIntlEqualW(long wstr wstr long) shlwapi.StrIsIntlEqualW ++@ stdcall StrPBrkA(str str) shlwapi.StrPBrkA ++@ stdcall StrPBrkW(wstr wstr) shlwapi.StrPBrkW ++@ stdcall StrRChrA(str str long) shlwapi.StrRChrA ++@ stdcall StrRChrIA(str str long) shlwapi.StrRChrIA ++@ stdcall StrRChrIW(wstr wstr long) shlwapi.StrRChrIW ++@ stdcall StrRChrW(wstr wstr long) shlwapi.StrRChrW ++@ stdcall StrRStrIA(str str str) shlwapi.StrRStrIA ++@ stdcall StrRStrIW(wstr wstr wstr) shlwapi.StrRStrIW ++@ stdcall StrSpnA(str str) shlwapi.StrSpnA ++@ stdcall StrSpnW(wstr wstr) shlwapi.StrSpnW ++@ stdcall StrStrA(str str) shlwapi.StrStrA ++@ stdcall StrStrIA(str str) shlwapi.StrStrIA ++@ stdcall StrStrIW(wstr wstr) shlwapi.StrStrIW ++@ stdcall StrStrNIW(wstr wstr long) shlwapi.StrStrNIW ++@ stdcall StrStrNW(wstr wstr long) shlwapi.StrStrNW ++@ stdcall StrStrW(wstr wstr) shlwapi.StrStrW ++@ stdcall StrToInt64ExA(str long ptr) shlwapi.StrToInt64ExA ++@ stdcall StrToInt64ExW(wstr long ptr) shlwapi.StrToInt64ExW ++@ stdcall StrToIntA(str) shlwapi.StrToIntA ++@ stdcall StrToIntExA(str long ptr) shlwapi.StrToIntExA ++@ stdcall StrToIntExW(wstr long ptr) shlwapi.StrToIntExW ++@ stdcall StrToIntW(wstr) shlwapi.StrToIntW ++@ stdcall StrTrimA(str str) shlwapi.StrTrimA ++@ stdcall StrTrimW(wstr wstr) shlwapi.StrTrimW +diff --git a/tools/make_specfiles b/tools/make_specfiles +index b9a96c7..8b63c60 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -255,6 +255,7 @@ my @dll_groups = + "api-ms-win-downlevel-shlwapi-l1-1-0", + "api-ms-win-downlevel-shlwapi-l2-1-0", + "api-ms-win-core-shlwapi-legacy-l1-1-0", ++ "api-ms-win-core-shlwapi-obsolete-l1-2-0", + "api-ms-win-core-url-l1-1-0", + ], + [ +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0022-api-ms-win-core-threadpool-l1-2-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0022-api-ms-win-core-threadpool-l1-2-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0022-api-ms-win-core-threadpool-l1-2-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0022-api-ms-win-core-threadpool-l1-2-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,91 @@ +From cc03b0abbb80b0d3295db9d89a140208bf55d9f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 21 Jan 2016 00:54:28 +0100 +Subject: api-ms-win-core-threadpool-l1-2-0: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-core-threadpool-l1-2-0/Makefile.in | 1 + + .../api-ms-win-core-threadpool-l1-2-0.spec | 37 ++++++++++++++++++++++ + tools/make_specfiles | 1 + + 4 files changed, 40 insertions(+) + create mode 100644 dlls/api-ms-win-core-threadpool-l1-2-0/Makefile.in + create mode 100644 dlls/api-ms-win-core-threadpool-l1-2-0/api-ms-win-core-threadpool-l1-2-0.spec + +diff --git a/configure.ac b/configure.ac +index e329038..e66f269 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2688,6 +2688,7 @@ WINE_CONFIG_DLL(api-ms-win-core-synch-l1-2-0) + WINE_CONFIG_DLL(api-ms-win-core-sysinfo-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-sysinfo-l1-2-0) + WINE_CONFIG_DLL(api-ms-win-core-sysinfo-l1-2-1) ++WINE_CONFIG_DLL(api-ms-win-core-threadpool-l1-2-0) + WINE_CONFIG_DLL(api-ms-win-core-threadpool-legacy-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-timezone-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-core-url-l1-1-0) +diff --git a/dlls/api-ms-win-core-threadpool-l1-2-0/Makefile.in b/dlls/api-ms-win-core-threadpool-l1-2-0/Makefile.in +new file mode 100644 +index 0000000..fa2c09e +--- /dev/null ++++ b/dlls/api-ms-win-core-threadpool-l1-2-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-core-threadpool-l1-2-0.dll +diff --git a/dlls/api-ms-win-core-threadpool-l1-2-0/api-ms-win-core-threadpool-l1-2-0.spec b/dlls/api-ms-win-core-threadpool-l1-2-0/api-ms-win-core-threadpool-l1-2-0.spec +new file mode 100644 +index 0000000..870becc +--- /dev/null ++++ b/dlls/api-ms-win-core-threadpool-l1-2-0/api-ms-win-core-threadpool-l1-2-0.spec +@@ -0,0 +1,37 @@ ++@ stdcall CallbackMayRunLong(ptr) kernel32.CallbackMayRunLong ++@ stub CancelThreadpoolIo ++@ stdcall CloseThreadpool(ptr) kernel32.CloseThreadpool ++@ stdcall CloseThreadpoolCleanupGroup(ptr) kernel32.CloseThreadpoolCleanupGroup ++@ stdcall CloseThreadpoolCleanupGroupMembers(ptr long ptr) kernel32.CloseThreadpoolCleanupGroupMembers ++@ stub CloseThreadpoolIo ++@ stdcall CloseThreadpoolTimer(ptr) kernel32.CloseThreadpoolTimer ++@ stdcall CloseThreadpoolWait(ptr) kernel32.CloseThreadpoolWait ++@ stdcall CloseThreadpoolWork(ptr) kernel32.CloseThreadpoolWork ++@ stdcall CreateThreadpool(ptr) kernel32.CreateThreadpool ++@ stdcall CreateThreadpoolCleanupGroup() kernel32.CreateThreadpoolCleanupGroup ++@ stub CreateThreadpoolIo ++@ stdcall CreateThreadpoolTimer(ptr ptr ptr) kernel32.CreateThreadpoolTimer ++@ stdcall CreateThreadpoolWait(ptr ptr ptr) kernel32.CreateThreadpoolWait ++@ stdcall CreateThreadpoolWork(ptr ptr ptr) kernel32.CreateThreadpoolWork ++@ stdcall DisassociateCurrentThreadFromCallback(ptr) kernel32.DisassociateCurrentThreadFromCallback ++@ stdcall FreeLibraryWhenCallbackReturns(ptr ptr) kernel32.FreeLibraryWhenCallbackReturns ++@ stdcall IsThreadpoolTimerSet(ptr) kernel32.IsThreadpoolTimerSet ++@ stdcall LeaveCriticalSectionWhenCallbackReturns(ptr ptr) kernel32.LeaveCriticalSectionWhenCallbackReturns ++@ stub QueryThreadpoolStackInformation ++@ stdcall ReleaseMutexWhenCallbackReturns(ptr long) kernel32.ReleaseMutexWhenCallbackReturns ++@ stdcall ReleaseSemaphoreWhenCallbackReturns(ptr long long) kernel32.ReleaseSemaphoreWhenCallbackReturns ++@ stdcall SetEventWhenCallbackReturns(ptr long) kernel32.SetEventWhenCallbackReturns ++@ stub SetThreadpoolStackInformation ++@ stdcall SetThreadpoolThreadMaximum(ptr long) kernel32.SetThreadpoolThreadMaximum ++@ stdcall SetThreadpoolThreadMinimum(ptr long) kernel32.SetThreadpoolThreadMinimum ++@ stdcall SetThreadpoolTimer(ptr ptr long long) kernel32.SetThreadpoolTimer ++@ stub SetThreadpoolTimerEx ++@ stdcall SetThreadpoolWait(ptr long ptr) kernel32.SetThreadpoolWait ++@ stub SetThreadpoolWaitEx ++@ stub StartThreadpoolIo ++@ stdcall SubmitThreadpoolWork(ptr) kernel32.SubmitThreadpoolWork ++@ stdcall TrySubmitThreadpoolCallback(ptr ptr ptr) kernel32.TrySubmitThreadpoolCallback ++@ stub WaitForThreadpoolIoCallbacks ++@ stdcall WaitForThreadpoolTimerCallbacks(ptr long) kernel32.WaitForThreadpoolTimerCallbacks ++@ stdcall WaitForThreadpoolWaitCallbacks(ptr long) kernel32.WaitForThreadpoolWaitCallbacks ++@ stdcall WaitForThreadpoolWorkCallbacks(ptr long) kernel32.WaitForThreadpoolWorkCallbacks +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 8b63c60..7761136 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -199,6 +199,7 @@ my @dll_groups = + "api-ms-win-core-processenvironment-l1-1-0", + "api-ms-win-core-processenvironment-l1-2-0", + "api-ms-win-core-psapi-l1-1-0", ++ "api-ms-win-core-threadpool-l1-2-0", + "api-ms-win-core-threadpool-legacy-l1-1-0", + "api-ms-win-core-timezone-l1-1-0", + "api-ms-win-core-file-l2-1-1", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0023-api-ms-win-shcore-stream-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0023-api-ms-win-shcore-stream-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0023-api-ms-win-shcore-stream-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0023-api-ms-win-shcore-stream-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,69 @@ +From 3c6d2e90631603492ca4aab85db1369f6b8377ac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 23 Jan 2016 20:56:53 +0100 +Subject: api-ms-win-shcore-stream-l1-1-0: Add dll + +--- + configure.ac | 1 + + dlls/api-ms-win-shcore-stream-l1-1-0/Makefile.in | 1 + + .../api-ms-win-shcore-stream-l1-1-0.spec | 15 +++++++++++++++ + tools/make_specfiles | 1 + + 4 files changed, 18 insertions(+) + create mode 100644 dlls/api-ms-win-shcore-stream-l1-1-0/Makefile.in + create mode 100644 dlls/api-ms-win-shcore-stream-l1-1-0/api-ms-win-shcore-stream-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 0aeb5dd..ecd03c7 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2734,6 +2734,7 @@ WINE_CONFIG_DLL(api-ms-win-service-core-l1-1-1) + WINE_CONFIG_DLL(api-ms-win-service-management-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-service-winsvc-l1-2-0) + WINE_CONFIG_DLL(api-ms-win-shcore-obsolete-l1-1-0) ++WINE_CONFIG_DLL(api-ms-win-shcore-stream-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-shcore-thread-l1-1-0) + WINE_CONFIG_DLL(apphelp) + WINE_CONFIG_TEST(dlls/apphelp/tests) +diff --git a/dlls/api-ms-win-shcore-stream-l1-1-0/Makefile.in b/dlls/api-ms-win-shcore-stream-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..df2caad +--- /dev/null ++++ b/dlls/api-ms-win-shcore-stream-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-shcore-stream-l1-1-0.dll +diff --git a/dlls/api-ms-win-shcore-stream-l1-1-0/api-ms-win-shcore-stream-l1-1-0.spec b/dlls/api-ms-win-shcore-stream-l1-1-0/api-ms-win-shcore-stream-l1-1-0.spec +new file mode 100644 +index 0000000..1ee9dd3 +--- /dev/null ++++ b/dlls/api-ms-win-shcore-stream-l1-1-0/api-ms-win-shcore-stream-l1-1-0.spec +@@ -0,0 +1,15 @@ ++@ stub IStream_Copy ++@ stdcall IStream_Read(ptr ptr long) shcore.IStream_Read ++@ stub IStream_ReadStr ++@ stdcall IStream_Reset(ptr) shcore.IStream_Reset ++@ stdcall IStream_Size(ptr ptr) shcore.IStream_Size ++@ stdcall IStream_Write(ptr ptr long) shcore.IStream_Write ++@ stub IStream_WriteStr ++@ stdcall SHCreateMemStream(ptr long) shcore.SHCreateMemStream ++@ stdcall SHCreateStreamOnFileA(str long ptr) shcore.SHCreateStreamOnFileA ++@ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) shcore.SHCreateStreamOnFileEx ++@ stdcall SHCreateStreamOnFileW(wstr long ptr) shcore.SHCreateStreamOnFileW ++@ stdcall SHOpenRegStream2A(long str str long) shcore.SHOpenRegStream2A ++@ stdcall SHOpenRegStream2W(long wstr wstr long) shcore.SHOpenRegStream2W ++@ stdcall SHOpenRegStreamA(long str str long) shcore.SHOpenRegStreamA ++@ stdcall SHOpenRegStreamW(long wstr wstr long) shcore.SHOpenRegStreamW +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 46284d5..289b980 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -268,6 +268,7 @@ my @dll_groups = + "shcore", + "api-ms-win-shcore-obsolete-l1-1-0", + "api-ms-win-shcore-thread-l1-1-0", ++ "api-ms-win-shcore-stream-l1-1-0", + ], + [ + "user32", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0024-ext-ms-win-ntuser-mouse-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0024-ext-ms-win-ntuser-mouse-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0024-ext-ms-win-ntuser-mouse-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0024-ext-ms-win-ntuser-mouse-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,59 @@ +From 26424422874fe4adece3ac6f9ac9b1264e4e3b52 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 23 Jan 2016 21:00:39 +0100 +Subject: ext-ms-win-ntuser-mouse-l1-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/ext-ms-win-ntuser-mouse-l1-1-0/Makefile.in | 1 + + .../ext-ms-win-ntuser-mouse-l1-1-0.spec | 5 +++++ + tools/make_specfiles | 1 + + 4 files changed, 8 insertions(+) + create mode 100644 dlls/ext-ms-win-ntuser-mouse-l1-1-0/Makefile.in + create mode 100644 dlls/ext-ms-win-ntuser-mouse-l1-1-0/ext-ms-win-ntuser-mouse-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index ecd03c7..566b8f1 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2937,6 +2937,7 @@ WINE_CONFIG_DLL(explorerframe,,[clean]) + WINE_CONFIG_TEST(dlls/explorerframe/tests) + WINE_CONFIG_DLL(ext-ms-win-appmodel-usercontext-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-gdi-devcaps-l1-1-0) ++WINE_CONFIG_DLL(ext-ms-win-ntuser-mouse-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-xaml-pal-l1-1-0) + WINE_CONFIG_DLL(faultrep,,[implib]) + WINE_CONFIG_TEST(dlls/faultrep/tests) +diff --git a/dlls/ext-ms-win-ntuser-mouse-l1-1-0/Makefile.in b/dlls/ext-ms-win-ntuser-mouse-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..c408dbb +--- /dev/null ++++ b/dlls/ext-ms-win-ntuser-mouse-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = ext-ms-win-ntuser-mouse-l1-1-0.dll +diff --git a/dlls/ext-ms-win-ntuser-mouse-l1-1-0/ext-ms-win-ntuser-mouse-l1-1-0.spec b/dlls/ext-ms-win-ntuser-mouse-l1-1-0/ext-ms-win-ntuser-mouse-l1-1-0.spec +new file mode 100644 +index 0000000..22128a2 +--- /dev/null ++++ b/dlls/ext-ms-win-ntuser-mouse-l1-1-0/ext-ms-win-ntuser-mouse-l1-1-0.spec +@@ -0,0 +1,5 @@ ++@ stdcall GetCapture() user32.GetCapture ++@ stdcall GetDoubleClickTime() user32.GetDoubleClickTime ++@ stdcall ReleaseCapture() user32.ReleaseCapture ++@ stdcall SetCapture(long) user32.SetCapture ++@ stdcall TrackMouseEvent(ptr) user32.TrackMouseEvent +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 289b980..692acd8 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -274,6 +274,7 @@ my @dll_groups = + "user32", + "api-ms-win-downlevel-user32-l1-1-0", + "api-ms-win-ntuser-dc-access-l1-1-0", ++ "ext-ms-win-ntuser-mouse-l1-1-0", + ], + [ + "version", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0025-ext-ms-win-uxtheme-themes-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0025-ext-ms-win-uxtheme-themes-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0025-ext-ms-win-uxtheme-themes-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0025-ext-ms-win-uxtheme-themes-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,81 @@ +From 5924dd86f8e06484443e0bf2390a80a321ec4f0c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 23 Jan 2016 21:02:52 +0100 +Subject: ext-ms-win-uxtheme-themes-l1-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/ext-ms-win-uxtheme-themes-l1-1-0/Makefile.in | 1 + + .../ext-ms-win-uxtheme-themes-l1-1-0.spec | 24 ++++++++++++++++++++++ + tools/make_specfiles | 4 ++++ + 4 files changed, 30 insertions(+) + create mode 100644 dlls/ext-ms-win-uxtheme-themes-l1-1-0/Makefile.in + create mode 100644 dlls/ext-ms-win-uxtheme-themes-l1-1-0/ext-ms-win-uxtheme-themes-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 566b8f1..308f04e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2938,6 +2938,7 @@ WINE_CONFIG_TEST(dlls/explorerframe/tests) + WINE_CONFIG_DLL(ext-ms-win-appmodel-usercontext-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-gdi-devcaps-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-ntuser-mouse-l1-1-0) ++WINE_CONFIG_DLL(ext-ms-win-uxtheme-themes-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-xaml-pal-l1-1-0) + WINE_CONFIG_DLL(faultrep,,[implib]) + WINE_CONFIG_TEST(dlls/faultrep/tests) +diff --git a/dlls/ext-ms-win-uxtheme-themes-l1-1-0/Makefile.in b/dlls/ext-ms-win-uxtheme-themes-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..588d200 +--- /dev/null ++++ b/dlls/ext-ms-win-uxtheme-themes-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = ext-ms-win-uxtheme-themes-l1-1-0.dll +diff --git a/dlls/ext-ms-win-uxtheme-themes-l1-1-0/ext-ms-win-uxtheme-themes-l1-1-0.spec b/dlls/ext-ms-win-uxtheme-themes-l1-1-0/ext-ms-win-uxtheme-themes-l1-1-0.spec +new file mode 100644 +index 0000000..0a96983 +--- /dev/null ++++ b/dlls/ext-ms-win-uxtheme-themes-l1-1-0/ext-ms-win-uxtheme-themes-l1-1-0.spec +@@ -0,0 +1,24 @@ ++@ stdcall CloseThemeData(ptr) uxtheme.CloseThemeData ++@ stdcall DrawThemeBackground(ptr ptr long long ptr ptr) uxtheme.DrawThemeBackground ++@ stub GetColorFromPreference ++@ stub GetImmersiveColorFromColorSetEx ++@ stub GetImmersiveUserColorSetPreference ++@ stub GetThemeAnimationProperty ++@ stub GetThemeAnimationTransform ++@ stdcall GetThemeBackgroundExtent(ptr ptr long long ptr ptr) uxtheme.GetThemeBackgroundExtent ++@ stub GetThemeBitmap ++@ stdcall GetThemeColor(ptr long long long ptr) uxtheme.GetThemeColor ++@ stdcall GetThemeEnumValue(ptr long long long ptr) uxtheme.GetThemeEnumValue ++@ stdcall GetThemeFont(ptr ptr long long long ptr) uxtheme.GetThemeFont ++@ stdcall GetThemeInt(ptr long long long ptr) uxtheme.GetThemeInt ++@ stdcall GetThemeMargins(ptr ptr long long long ptr ptr) uxtheme.GetThemeMargins ++@ stdcall GetThemePartSize(ptr ptr long long ptr long ptr) uxtheme.GetThemePartSize ++@ stdcall GetThemePosition(ptr long long long ptr) uxtheme.GetThemePosition ++@ stub GetThemeTimingFunction ++@ stub GetUserColorPreference ++@ stdcall IsAppThemed() uxtheme.IsAppThemed ++@ stdcall IsThemeActive() uxtheme.IsThemeActive ++@ stdcall IsThemePartDefined(ptr long long) uxtheme.IsThemePartDefined ++@ stdcall OpenThemeData(ptr wstr) uxtheme.OpenThemeData ++@ stdcall OpenThemeDataEx(ptr wstr long) uxtheme.OpenThemeDataEx ++@ stdcall SetWindowTheme(ptr wstr wstr) uxtheme.SetWindowTheme +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 692acd8..7afc0c1 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -299,6 +299,10 @@ my @dll_groups = + "api-ms-win-core-winrt-registration-l1-1-0", + ], + [ ++ "uxtheme", ++ "ext-ms-win-uxtheme-themes-l1-1-0", ++ ], ++ [ + "bthprops.cpl", + "irprops.cpl", + ], +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0026-api-ms-win-rtcore-ntuser-window-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0026-api-ms-win-rtcore-ntuser-window-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0026-api-ms-win-rtcore-ntuser-window-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0026-api-ms-win-rtcore-ntuser-window-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,135 @@ +From 94e15216c8b2079c5b1b503594ead6f548158f57 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 23 Jan 2016 21:05:14 +0100 +Subject: api-ms-win-rtcore-ntuser-window-l1-1-0: Add dll + +--- + configure.ac | 1 + + .../Makefile.in | 1 + + .../api-ms-win-rtcore-ntuser-window-l1-1-0.spec | 81 ++++++++++++++++++++++ + tools/make_specfiles | 1 + + 4 files changed, 84 insertions(+) + create mode 100644 dlls/api-ms-win-rtcore-ntuser-window-l1-1-0/Makefile.in + create mode 100644 dlls/api-ms-win-rtcore-ntuser-window-l1-1-0/api-ms-win-rtcore-ntuser-window-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 308f04e..9ee4464 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2725,6 +2725,7 @@ WINE_CONFIG_DLL(api-ms-win-downlevel-version-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-eventing-classicprovider-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-eventing-provider-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-ntuser-dc-access-l1-1-0) ++WINE_CONFIG_DLL(api-ms-win-rtcore-ntuser-window-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-security-base-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-security-base-l1-2-0) + WINE_CONFIG_DLL(api-ms-win-security-lsalookup-l1-1-0) +diff --git a/dlls/api-ms-win-rtcore-ntuser-window-l1-1-0/Makefile.in b/dlls/api-ms-win-rtcore-ntuser-window-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..9641c2a +--- /dev/null ++++ b/dlls/api-ms-win-rtcore-ntuser-window-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-rtcore-ntuser-window-l1-1-0.dll +diff --git a/dlls/api-ms-win-rtcore-ntuser-window-l1-1-0/api-ms-win-rtcore-ntuser-window-l1-1-0.spec b/dlls/api-ms-win-rtcore-ntuser-window-l1-1-0/api-ms-win-rtcore-ntuser-window-l1-1-0.spec +new file mode 100644 +index 0000000..b7575c6 +--- /dev/null ++++ b/dlls/api-ms-win-rtcore-ntuser-window-l1-1-0/api-ms-win-rtcore-ntuser-window-l1-1-0.spec +@@ -0,0 +1,81 @@ ++@ stdcall AllowSetForegroundWindow(long) user32.AllowSetForegroundWindow ++@ stdcall BeginDeferWindowPos(long) user32.BeginDeferWindowPos ++@ stdcall CallWindowProcW(ptr long long long long) user32.CallWindowProcW ++@ stdcall ChildWindowFromPoint(long int64) user32.ChildWindowFromPoint ++@ stdcall ChildWindowFromPointEx(long int64 long) user32.ChildWindowFromPointEx ++@ stdcall ClientToScreen(long ptr) user32.ClientToScreen ++@ stdcall CreateWindowExW(long wstr wstr long long long long long long long long ptr) user32.CreateWindowExW ++@ stdcall DefWindowProcW(long long long long) user32.DefWindowProcW ++@ stdcall DeferWindowPos(long long long long long long long long) user32.DeferWindowPos ++@ stdcall DestroyWindow(long) user32.DestroyWindow ++@ stdcall DispatchMessageW(ptr) user32.DispatchMessageW ++@ stdcall EnableWindow(long long) user32.EnableWindow ++@ stdcall EndDeferWindowPos(long) user32.EndDeferWindowPos ++@ stdcall EnumChildWindows(long ptr long) user32.EnumChildWindows ++@ stdcall EnumPropsExW(long ptr long) user32.EnumPropsExW ++@ stdcall EnumPropsW(long ptr) user32.EnumPropsW ++@ stdcall EnumWindows(ptr long) user32.EnumWindows ++@ stdcall FindWindowExW(long long wstr wstr) user32.FindWindowExW ++@ stdcall FindWindowW(wstr wstr) user32.FindWindowW ++@ stdcall GetActiveWindow() user32.GetActiveWindow ++@ stdcall GetAncestor(long long) user32.GetAncestor ++@ stdcall GetClassInfoExW(long wstr ptr) user32.GetClassInfoExW ++@ stdcall GetClassInfoW(long wstr ptr) user32.GetClassInfoW ++@ stdcall GetClassNameW(long ptr long) user32.GetClassNameW ++@ stdcall GetClientRect(long long) user32.GetClientRect ++@ stdcall GetCursorPos(ptr) user32.GetCursorPos ++@ stdcall GetDesktopWindow() user32.GetDesktopWindow ++@ stdcall GetFocus() user32.GetFocus ++@ stdcall GetForegroundWindow() user32.GetForegroundWindow ++@ stdcall GetMessageExtraInfo() user32.GetMessageExtraInfo ++@ stdcall GetMessagePos() user32.GetMessagePos ++@ stdcall GetMessageTime() user32.GetMessageTime ++@ stdcall GetMessageW(ptr long long long) user32.GetMessageW ++@ stdcall GetParent(long) user32.GetParent ++@ stdcall GetPropW(long wstr) user32.GetPropW ++@ stdcall GetQueueStatus(long) user32.GetQueueStatus ++@ stdcall GetTopWindow(long) user32.GetTopWindow ++@ stdcall GetWindow(long long) user32.GetWindow ++@ stdcall GetWindowLongA(long long) user32.GetWindowLongA ++@ stdcall GetWindowLongW(long long) user32.GetWindowLongW ++@ stdcall GetWindowRect(long ptr) user32.GetWindowRect ++@ stdcall GetWindowTextW(long ptr long) user32.GetWindowTextW ++@ stdcall GetWindowThreadProcessId(long ptr) user32.GetWindowThreadProcessId ++@ stdcall InSendMessage() user32.InSendMessage ++@ stdcall InSendMessageEx(ptr) user32.InSendMessageEx ++@ stdcall IsChild(long long) user32.IsChild ++@ stdcall IsWindow(long) user32.IsWindow ++@ stdcall IsWindowEnabled(long) user32.IsWindowEnabled ++@ stdcall IsWindowVisible(long) user32.IsWindowVisible ++@ stdcall KillTimer(long long) user32.KillTimer ++@ stdcall MoveWindow(long long long long long long) user32.MoveWindow ++@ stdcall PeekMessageW(ptr long long long long) user32.PeekMessageW ++@ stdcall PostMessageW(long long long long) user32.PostMessageW ++@ stdcall PostQuitMessage(long) user32.PostQuitMessage ++@ stdcall PostThreadMessageW(long long long long) user32.PostThreadMessageW ++@ stdcall RegisterClassExW(ptr) user32.RegisterClassExW ++@ stdcall RegisterClassW(ptr) user32.RegisterClassW ++@ stdcall RegisterWindowMessageW(wstr) user32.RegisterWindowMessageW ++@ stdcall RemovePropW(long wstr) user32.RemovePropW ++@ stdcall ScreenToClient(long ptr) user32.ScreenToClient ++@ stdcall SendMessageCallbackW(long long long long ptr long) user32.SendMessageCallbackW ++@ stdcall SendMessageTimeoutW(long long long long long long ptr) user32.SendMessageTimeoutW ++@ stdcall SendMessageW(long long long long) user32.SendMessageW ++@ stdcall SendNotifyMessageW(long long long long) user32.SendNotifyMessageW ++@ stdcall SetActiveWindow(long) user32.SetActiveWindow ++@ stdcall SetCursorPos(long long) user32.SetCursorPos ++@ stdcall SetFocus(long) user32.SetFocus ++@ stdcall SetForegroundWindow(long) user32.SetForegroundWindow ++@ stdcall SetMessageExtraInfo(long) user32.SetMessageExtraInfo ++@ stdcall SetParent(long long) user32.SetParent ++@ stdcall SetPropW(long wstr long) user32.SetPropW ++@ stdcall SetTimer(long long long ptr) user32.SetTimer ++@ stdcall SetWindowLongA(long long long) user32.SetWindowLongA ++@ stdcall SetWindowLongW(long long long) user32.SetWindowLongW ++@ stdcall SetWindowPos(long long long long long long long) user32.SetWindowPos ++@ stdcall SetWindowTextW(long wstr) user32.SetWindowTextW ++@ stdcall ShowWindow(long long) user32.ShowWindow ++@ stdcall TranslateMessage(ptr) user32.TranslateMessage ++@ stdcall UnregisterClassW(wstr long) user32.UnregisterClassW ++@ stdcall WaitMessage() user32.WaitMessage ++@ stdcall WindowFromPoint(int64) user32.WindowFromPoint +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 7afc0c1..c88a32c 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -274,6 +274,7 @@ my @dll_groups = + "user32", + "api-ms-win-downlevel-user32-l1-1-0", + "api-ms-win-ntuser-dc-access-l1-1-0", ++ "api-ms-win-rtcore-ntuser-window-l1-1-0", + "ext-ms-win-ntuser-mouse-l1-1-0", + ], + [ +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0027-ext-ms-win-rtcore-ntuser-syscolors-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0027-ext-ms-win-rtcore-ntuser-syscolors-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0027-ext-ms-win-rtcore-ntuser-syscolors-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0027-ext-ms-win-rtcore-ntuser-syscolors-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,56 @@ +From 53a6d2753fe70e58d14e366c88dac1c8e65ea6aa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 23 Jan 2016 21:06:59 +0100 +Subject: ext-ms-win-rtcore-ntuser-syscolors-l1-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0/Makefile.in | 1 + + .../ext-ms-win-rtcore-ntuser-syscolors-l1-1-0.spec | 2 ++ + tools/make_specfiles | 1 + + 4 files changed, 5 insertions(+) + create mode 100644 dlls/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0/Makefile.in + create mode 100644 dlls/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 9ee4464..f38d37a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2939,6 +2939,7 @@ WINE_CONFIG_TEST(dlls/explorerframe/tests) + WINE_CONFIG_DLL(ext-ms-win-appmodel-usercontext-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-gdi-devcaps-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-ntuser-mouse-l1-1-0) ++WINE_CONFIG_DLL(ext-ms-win-rtcore-ntuser-syscolors-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-uxtheme-themes-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-xaml-pal-l1-1-0) + WINE_CONFIG_DLL(faultrep,,[implib]) +diff --git a/dlls/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0/Makefile.in b/dlls/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..3e6b6e8 +--- /dev/null ++++ b/dlls/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = ext-ms-win-rtcore-ntuser-syscolors-l1-1-0.dll +diff --git a/dlls/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0.spec b/dlls/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0.spec +new file mode 100644 +index 0000000..626c778 +--- /dev/null ++++ b/dlls/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0.spec +@@ -0,0 +1,2 @@ ++@ stdcall GetSysColor(long) user32.GetSysColor ++@ stdcall SetSysColors(long ptr ptr) user32.SetSysColors +diff --git a/tools/make_specfiles b/tools/make_specfiles +index c88a32c..a602e5d 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -276,6 +276,7 @@ my @dll_groups = + "api-ms-win-ntuser-dc-access-l1-1-0", + "api-ms-win-rtcore-ntuser-window-l1-1-0", + "ext-ms-win-ntuser-mouse-l1-1-0", ++ "ext-ms-win-rtcore-ntuser-syscolors-l1-1-0", + ], + [ + "version", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0028-api-ms-win-rtcore-ntuser-draw-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0028-api-ms-win-rtcore-ntuser-draw-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0028-api-ms-win-rtcore-ntuser-draw-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0028-api-ms-win-rtcore-ntuser-draw-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,55 @@ +From 509aeb70de5e2efb1a2e2c36263991392767bafa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 23 Jan 2016 21:08:48 +0100 +Subject: api-ms-win-rtcore-ntuser-draw-l1-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/api-ms-win-rtcore-ntuser-draw-l1-1-0/Makefile.in | 1 + + .../api-ms-win-rtcore-ntuser-draw-l1-1-0.spec | 1 + + tools/make_specfiles | 1 + + 4 files changed, 4 insertions(+) + create mode 100644 dlls/api-ms-win-rtcore-ntuser-draw-l1-1-0/Makefile.in + create mode 100644 dlls/api-ms-win-rtcore-ntuser-draw-l1-1-0/api-ms-win-rtcore-ntuser-draw-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index f38d37a..4c803cc 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2725,6 +2725,7 @@ WINE_CONFIG_DLL(api-ms-win-downlevel-version-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-eventing-classicprovider-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-eventing-provider-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-ntuser-dc-access-l1-1-0) ++WINE_CONFIG_DLL(api-ms-win-rtcore-ntuser-draw-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-rtcore-ntuser-window-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-security-base-l1-1-0) + WINE_CONFIG_DLL(api-ms-win-security-base-l1-2-0) +diff --git a/dlls/api-ms-win-rtcore-ntuser-draw-l1-1-0/Makefile.in b/dlls/api-ms-win-rtcore-ntuser-draw-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..956f2f3 +--- /dev/null ++++ b/dlls/api-ms-win-rtcore-ntuser-draw-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = api-ms-win-rtcore-ntuser-draw-l1-1-0.dll +diff --git a/dlls/api-ms-win-rtcore-ntuser-draw-l1-1-0/api-ms-win-rtcore-ntuser-draw-l1-1-0.spec b/dlls/api-ms-win-rtcore-ntuser-draw-l1-1-0/api-ms-win-rtcore-ntuser-draw-l1-1-0.spec +new file mode 100644 +index 0000000..59900a9 +--- /dev/null ++++ b/dlls/api-ms-win-rtcore-ntuser-draw-l1-1-0/api-ms-win-rtcore-ntuser-draw-l1-1-0.spec +@@ -0,0 +1 @@ ++@ stdcall RedrawWindow(long ptr long long) user32.RedrawWindow +diff --git a/tools/make_specfiles b/tools/make_specfiles +index a602e5d..f482264 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -274,6 +274,7 @@ my @dll_groups = + "user32", + "api-ms-win-downlevel-user32-l1-1-0", + "api-ms-win-ntuser-dc-access-l1-1-0", ++ "api-ms-win-rtcore-ntuser-draw-l1-1-0", + "api-ms-win-rtcore-ntuser-window-l1-1-0", + "ext-ms-win-ntuser-mouse-l1-1-0", + "ext-ms-win-rtcore-ntuser-syscolors-l1-1-0", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0029-ext-ms-win-rtcore-ntuser-sysparams-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0029-ext-ms-win-rtcore-ntuser-sysparams-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0029-ext-ms-win-rtcore-ntuser-sysparams-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0029-ext-ms-win-rtcore-ntuser-sysparams-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,74 @@ +From 1ab24ab7e6d2ef9915e7881bc36853edfc52d1ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 23 Jan 2016 21:10:37 +0100 +Subject: ext-ms-win-rtcore-ntuser-sysparams-l1-1-0: Add dll. + +--- + configure.ac | 1 + + .../Makefile.in | 1 + + .../ext-ms-win-rtcore-ntuser-sysparams-l1-1-0.spec | 20 ++++++++++++++++++++ + tools/make_specfiles | 1 + + 4 files changed, 23 insertions(+) + create mode 100644 dlls/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0/Makefile.in + create mode 100644 dlls/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index 4c803cc..bb63b0d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2941,6 +2941,7 @@ WINE_CONFIG_DLL(ext-ms-win-appmodel-usercontext-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-gdi-devcaps-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-ntuser-mouse-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-rtcore-ntuser-syscolors-l1-1-0) ++WINE_CONFIG_DLL(ext-ms-win-rtcore-ntuser-sysparams-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-uxtheme-themes-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-xaml-pal-l1-1-0) + WINE_CONFIG_DLL(faultrep,,[implib]) +diff --git a/dlls/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0/Makefile.in b/dlls/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..18a0b1f +--- /dev/null ++++ b/dlls/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = ext-ms-win-rtcore-ntuser-sysparams-l1-1-0.dll +diff --git a/dlls/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0.spec b/dlls/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0.spec +new file mode 100644 +index 0000000..9d2af72 +--- /dev/null ++++ b/dlls/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0.spec +@@ -0,0 +1,20 @@ ++@ stdcall ChangeDisplaySettingsExW(wstr ptr long long ptr) user32.ChangeDisplaySettingsExW ++@ stub DisplayConfigGetDeviceInfo ++@ stub DisplayConfigSetDeviceInfo ++@ stdcall EnumDisplayDevicesW(ptr long ptr long) user32.EnumDisplayDevicesW ++@ stdcall EnumDisplayMonitors(long ptr ptr long) user32.EnumDisplayMonitors ++@ stdcall EnumDisplaySettingsExW(wstr long ptr long) user32.EnumDisplaySettingsExW ++@ stdcall EnumDisplaySettingsW(wstr long ptr ) user32.EnumDisplaySettingsW ++@ stdcall GetDisplayConfigBufferSizes(long ptr ptr) user32.GetDisplayConfigBufferSizes ++@ stdcall GetMonitorInfoW(long ptr) user32.GetMonitorInfoW ++@ stdcall GetSysColor(long) user32.GetSysColor ++@ stdcall GetSystemMetrics(long) user32.GetSystemMetrics ++@ stub IsProcessDPIAware ++@ stdcall MonitorFromPoint(int64 long) user32.MonitorFromPoint ++@ stdcall MonitorFromRect(ptr long) user32.MonitorFromRect ++@ stdcall MonitorFromWindow(long long) user32.MonitorFromWindow ++@ stub QueryDisplayConfig ++@ stdcall SetProcessDPIAware() user32.SetProcessDPIAware ++@ stdcall SetSysColors(long ptr ptr) user32.SetSysColors ++@ stdcall SystemParametersInfoA(long long ptr long) user32.SystemParametersInfoA ++@ stdcall SystemParametersInfoW(long long ptr long) user32.SystemParametersInfoW +diff --git a/tools/make_specfiles b/tools/make_specfiles +index f482264..b364446 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -278,6 +278,7 @@ my @dll_groups = + "api-ms-win-rtcore-ntuser-window-l1-1-0", + "ext-ms-win-ntuser-mouse-l1-1-0", + "ext-ms-win-rtcore-ntuser-syscolors-l1-1-0", ++ "ext-ms-win-rtcore-ntuser-sysparams-l1-1-0", + ], + [ + "version", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0030-ext-ms-win-kernel32-package-current-l1-1-0-Add-dll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0030-ext-ms-win-kernel32-package-current-l1-1-0-Add-dll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0030-ext-ms-win-kernel32-package-current-l1-1-0-Add-dll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0030-ext-ms-win-kernel32-package-current-l1-1-0-Add-dll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,56 @@ +From 88367d179496bb178f97591000ef5e56e58a9322 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 23 Jan 2016 21:13:02 +0100 +Subject: ext-ms-win-kernel32-package-current-l1-1-0: Add dll. + +--- + configure.ac | 1 + + dlls/ext-ms-win-kernel32-package-current-l1-1-0/Makefile.in | 1 + + .../ext-ms-win-kernel32-package-current-l1-1-0.spec | 2 ++ + tools/make_specfiles | 1 + + 4 files changed, 5 insertions(+) + create mode 100644 dlls/ext-ms-win-kernel32-package-current-l1-1-0/Makefile.in + create mode 100644 dlls/ext-ms-win-kernel32-package-current-l1-1-0/ext-ms-win-kernel32-package-current-l1-1-0.spec + +diff --git a/configure.ac b/configure.ac +index bb63b0d..e7c55db 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2939,6 +2939,7 @@ WINE_CONFIG_DLL(explorerframe,,[clean]) + WINE_CONFIG_TEST(dlls/explorerframe/tests) + WINE_CONFIG_DLL(ext-ms-win-appmodel-usercontext-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-gdi-devcaps-l1-1-0) ++WINE_CONFIG_DLL(ext-ms-win-kernel32-package-current-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-ntuser-mouse-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-rtcore-ntuser-syscolors-l1-1-0) + WINE_CONFIG_DLL(ext-ms-win-rtcore-ntuser-sysparams-l1-1-0) +diff --git a/dlls/ext-ms-win-kernel32-package-current-l1-1-0/Makefile.in b/dlls/ext-ms-win-kernel32-package-current-l1-1-0/Makefile.in +new file mode 100644 +index 0000000..c4699b1 +--- /dev/null ++++ b/dlls/ext-ms-win-kernel32-package-current-l1-1-0/Makefile.in +@@ -0,0 +1 @@ ++MODULE = ext-ms-win-kernel32-package-current-l1-1-0.dll +diff --git a/dlls/ext-ms-win-kernel32-package-current-l1-1-0/ext-ms-win-kernel32-package-current-l1-1-0.spec b/dlls/ext-ms-win-kernel32-package-current-l1-1-0/ext-ms-win-kernel32-package-current-l1-1-0.spec +new file mode 100644 +index 0000000..2156c27 +--- /dev/null ++++ b/dlls/ext-ms-win-kernel32-package-current-l1-1-0/ext-ms-win-kernel32-package-current-l1-1-0.spec +@@ -0,0 +1,2 @@ ++@ stdcall GetCurrentPackageId(ptr ptr) kernel32.GetCurrentPackageId ++@ stub GetCurrentPackageInfo +diff --git a/tools/make_specfiles b/tools/make_specfiles +index b364446..5b2418b 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -214,6 +214,7 @@ my @dll_groups = + "api-ms-win-core-wow64-l1-1-0", + "api-ms-win-core-xstate-l2-1-0", + "api-ms-win-core-errorhandling-l1-1-2", ++ "ext-ms-win-kernel32-package-current-l1-1-0", + ], + [ + "kernel32", +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0031-shcore-Add-SetProcessDpiAwareness-stub.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0031-shcore-Add-SetProcessDpiAwareness-stub.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0031-shcore-Add-SetProcessDpiAwareness-stub.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0031-shcore-Add-SetProcessDpiAwareness-stub.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,141 @@ +From f84cb2913cb755152d98c278f3ed6927167c9b2b Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sun, 24 Jan 2016 16:06:47 +0100 +Subject: shcore: Add SetProcessDpiAwareness stub. + +--- + dlls/shcore/Makefile.in | 3 +++ + dlls/shcore/main.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ + dlls/shcore/shcore.spec | 2 +- + include/Makefile.in | 1 + + include/shellscalingapi.h | 29 ++++++++++++++++++++++++++++ + 5 files changed, 83 insertions(+), 1 deletion(-) + create mode 100644 dlls/shcore/main.c + create mode 100644 include/shellscalingapi.h + +diff --git a/dlls/shcore/Makefile.in b/dlls/shcore/Makefile.in +index dd5f08f..ec2e95f 100644 +--- a/dlls/shcore/Makefile.in ++++ b/dlls/shcore/Makefile.in +@@ -1 +1,4 @@ + MODULE = shcore.dll ++ ++C_SRCS = \ ++ main.c +diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c +new file mode 100644 +index 0000000..0e59d38 +--- /dev/null ++++ b/dlls/shcore/main.c +@@ -0,0 +1,49 @@ ++/* ++ * Copyright 2016 Sebastian Lackner ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include ++ ++#include "windef.h" ++#include "winbase.h" ++#include "shellscalingapi.h" ++#include "wine/debug.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(shcore); ++ ++BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) ++{ ++ TRACE("(%p, %u, %p)\n", instance, reason, reserved); ++ ++ switch (reason) ++ { ++ case DLL_WINE_PREATTACH: ++ return FALSE; /* prefer native version */ ++ case DLL_PROCESS_ATTACH: ++ DisableThreadLibraryCalls(instance); ++ break; ++ } ++ ++ return TRUE; ++} ++ ++HRESULT WINAPI SetProcessDpiAwareness(PROCESS_DPI_AWARENESS value) ++{ ++ FIXME("(%u): stub\n", value); ++ return E_NOTIMPL; ++} +diff --git a/dlls/shcore/shcore.spec b/dlls/shcore/shcore.spec +index 12a4ef3..1624319 100644 +--- a/dlls/shcore/shcore.spec ++++ b/dlls/shcore/shcore.spec +@@ -78,6 +78,6 @@ + @ stdcall SHUnicodeToAnsi(wstr ptr ptr) shlwapi.SHUnicodeToAnsi + @ stdcall SHUnicodeToUnicode(wstr ptr long) shlwapi.SHUnicodeToUnicode + @ stdcall SetCurrentProcessExplicitAppUserModelID(wstr) shell32.SetCurrentProcessExplicitAppUserModelID +-@ stub SetProcessDpiAwareness ++@ stdcall SetProcessDpiAwareness(long) + @ stub SetProcessReference + @ stub UnregisterScaleChangeEvent +diff --git a/include/Makefile.in b/include/Makefile.in +index 199de7a..c907afe4 100644 +--- a/include/Makefile.in ++++ b/include/Makefile.in +@@ -570,6 +570,7 @@ HEADER_SRCS = \ + sfc.h \ + shdispid.h \ + shellapi.h \ ++ shellscalingapi.h \ + shlguid.h \ + shlobj.h \ + shlwapi.h \ +diff --git a/include/shellscalingapi.h b/include/shellscalingapi.h +new file mode 100644 +index 0000000..6d7a167 +--- /dev/null ++++ b/include/shellscalingapi.h +@@ -0,0 +1,29 @@ ++/* ++ * Copyright 2016 Sebastian Lackner ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#ifndef __WINE_SHELLSCALINGAPI_H ++#define __WINE_SHELLSCALINGAPI_H ++ ++typedef enum PROCESS_DPI_AWARENESS ++{ ++ PROCESS_DPI_UNAWARE = 0, ++ PROCESS_SYSTEM_DPI_AWARE = 1, ++ PROCESS_PER_MONITOR_DPI_AWARE = 2, ++} PROCESS_DPI_AWARENESS; ++ ++#endif /* __WINE_SHELLSCALINGAPI_H */ +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0032-shcore-Implement-stub-for-GetDpiForMonitor.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0032-shcore-Implement-stub-for-GetDpiForMonitor.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0032-shcore-Implement-stub-for-GetDpiForMonitor.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0032-shcore-Implement-stub-for-GetDpiForMonitor.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,86 @@ +From 0effbe0e3eeb84626ec6b64848fe6cfb1279dc02 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Tue, 26 Jan 2016 15:39:10 +0100 +Subject: shcore: Implement stub for GetDpiForMonitor. + +--- + dlls/shcore/Makefile.in | 1 + + dlls/shcore/main.c | 16 ++++++++++++++++ + dlls/shcore/shcore.spec | 2 +- + include/shellscalingapi.h | 8 ++++++++ + 4 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/dlls/shcore/Makefile.in b/dlls/shcore/Makefile.in +index ec2e95f..0b172fc 100644 +--- a/dlls/shcore/Makefile.in ++++ b/dlls/shcore/Makefile.in +@@ -1,4 +1,5 @@ + MODULE = shcore.dll ++IMPORTS = gdi32 user32 + + C_SRCS = \ + main.c +diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c +index 0e59d38..ce0d9ed 100644 +--- a/dlls/shcore/main.c ++++ b/dlls/shcore/main.c +@@ -21,6 +21,8 @@ + + #include "windef.h" + #include "winbase.h" ++#include "wingdi.h" ++#include "winuser.h" + #include "shellscalingapi.h" + #include "wine/debug.h" + +@@ -47,3 +49,17 @@ HRESULT WINAPI SetProcessDpiAwareness(PROCESS_DPI_AWARENESS value) + FIXME("(%u): stub\n", value); + return E_NOTIMPL; + } ++ ++HRESULT WINAPI GetDpiForMonitor(HMONITOR monitor, MONITOR_DPI_TYPE type, UINT *x, UINT *y) ++{ ++ HDC hDC; ++ ++ TRACE("(%p, %u, %p, %p): semi-stub\n", monitor, type, x, y); ++ ++ hDC = GetDC(0); ++ if (x) *x = GetDeviceCaps(hDC, LOGPIXELSX); ++ if (y) *y = GetDeviceCaps(hDC, LOGPIXELSY); ++ ReleaseDC(0, hDC); ++ ++ return S_OK; ++} +diff --git a/dlls/shcore/shcore.spec b/dlls/shcore/shcore.spec +index 1624319..4d6e845 100644 +--- a/dlls/shcore/shcore.spec ++++ b/dlls/shcore/shcore.spec +@@ -6,7 +6,7 @@ + @ stub DllGetActivationFactory + @ stdcall -private DllGetClassObject(ptr ptr ptr) shell32.DllGetClassObject + @ stdcall GetCurrentProcessExplicitAppUserModelID(ptr) shell32.GetCurrentProcessExplicitAppUserModelID +-@ stub GetDpiForMonitor ++@ stdcall GetDpiForMonitor(long long ptr ptr) + @ stub GetDpiForShellUIComponent + @ stub GetProcessDpiAwareness + @ stub GetProcessReference +diff --git a/include/shellscalingapi.h b/include/shellscalingapi.h +index 6d7a167..56ae94a 100644 +--- a/include/shellscalingapi.h ++++ b/include/shellscalingapi.h +@@ -26,4 +26,12 @@ typedef enum PROCESS_DPI_AWARENESS + PROCESS_PER_MONITOR_DPI_AWARE = 2, + } PROCESS_DPI_AWARENESS; + ++typedef enum MONITOR_DPI_TYPE ++{ ++ MDT_EFFECTIVE_DPI = 0, ++ MDT_ANGULAR_DPI = 1, ++ MDT_RAW_DPI = 2, ++ MDT_DEFAULT = MDT_EFFECTIVE_DPI, ++} MONITOR_DPI_TYPE; ++ + #endif /* __WINE_SHELLSCALINGAPI_H */ +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0033-kernelbase-Add-stub-for-QuirkIsEnabled3.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0033-kernelbase-Add-stub-for-QuirkIsEnabled3.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0033-kernelbase-Add-stub-for-QuirkIsEnabled3.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0033-kernelbase-Add-stub-for-QuirkIsEnabled3.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,58 @@ +From d1cb153363aec82f8b7c5dbb0f382880e01fc2d4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 4 Feb 2016 06:19:57 +0100 +Subject: kernelbase: Add stub for QuirkIsEnabled3. + +--- + .../api-ms-win-core-quirks-l1-1-0.spec | 2 +- + dlls/kernelbase/kernelbase.spec | 2 +- + dlls/kernelbase/misc.c | 10 ++++++++++ + 3 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/dlls/api-ms-win-core-quirks-l1-1-0/api-ms-win-core-quirks-l1-1-0.spec b/dlls/api-ms-win-core-quirks-l1-1-0/api-ms-win-core-quirks-l1-1-0.spec +index 54ce373..1485512 100644 +--- a/dlls/api-ms-win-core-quirks-l1-1-0/api-ms-win-core-quirks-l1-1-0.spec ++++ b/dlls/api-ms-win-core-quirks-l1-1-0/api-ms-win-core-quirks-l1-1-0.spec +@@ -2,7 +2,7 @@ + @ stub QuirkGetData2 + @ stdcall QuirkIsEnabled(ptr) kernelbase.QuirkIsEnabled + @ stub QuirkIsEnabled2 +-@ stub QuirkIsEnabled3 ++@ stdcall QuirkIsEnabled3(ptr ptr) kernelbase.QuirkIsEnabled3 + @ stub QuirkIsEnabledForPackage + @ stub QuirkIsEnabledForPackage2 + @ stub QuirkIsEnabledForProcess +diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec +index 83fff3e..dbba3cc 100644 +--- a/dlls/kernelbase/kernelbase.spec ++++ b/dlls/kernelbase/kernelbase.spec +@@ -1188,7 +1188,7 @@ + @ stub QuirkGetData2 + @ stub QuirkGetData + @ stub QuirkIsEnabled2 +-@ stub QuirkIsEnabled3 ++@ stdcall QuirkIsEnabled3(ptr ptr) + @ stdcall QuirkIsEnabled(ptr) + @ stub QuirkIsEnabledForPackage2 + @ stub QuirkIsEnabledForPackage3 +diff --git a/dlls/kernelbase/misc.c b/dlls/kernelbase/misc.c +index be1591a..e703e6d 100644 +--- a/dlls/kernelbase/misc.c ++++ b/dlls/kernelbase/misc.c +@@ -35,3 +35,13 @@ BOOL WINAPI QuirkIsEnabled(void *arg) + FIXME("(%p): stub\n", arg); + return FALSE; + } ++ ++/*********************************************************************** ++ * QuirkIsEnabled3 (KERNELBASE.@) ++ */ ++BOOL WINAPI QuirkIsEnabled3(void *arg1, void *arg2) ++{ ++ static int once; ++ if (!once++) FIXME("(%p, %p): stub\n", arg1, arg2); ++ return FALSE; ++} +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0034-shcore-Add-stub-for-GetProcessDpiAwareness.patch wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0034-shcore-Add-stub-for-GetProcessDpiAwareness.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0034-shcore-Add-stub-for-GetProcessDpiAwareness.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/0034-shcore-Add-stub-for-GetProcessDpiAwareness.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,44 @@ +From 3d855b15e9f99f1cc3168cc9e606cb698e078a4b Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 6 Feb 2016 02:38:14 +0100 +Subject: shcore: Add stub for GetProcessDpiAwareness. + +--- + dlls/shcore/main.c | 7 +++++++ + dlls/shcore/shcore.spec | 2 +- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c +index ce0d9ed..f2d362d 100644 +--- a/dlls/shcore/main.c ++++ b/dlls/shcore/main.c +@@ -50,6 +50,13 @@ HRESULT WINAPI SetProcessDpiAwareness(PROCESS_DPI_AWARENESS value) + return E_NOTIMPL; + } + ++HRESULT WINAPI GetProcessDpiAwareness(HANDLE process, PROCESS_DPI_AWARENESS *value) ++{ ++ FIXME("(%p, %p): stub\n", process, value); ++ if (value) *value = PROCESS_DPI_UNAWARE; ++ return S_OK; ++} ++ + HRESULT WINAPI GetDpiForMonitor(HMONITOR monitor, MONITOR_DPI_TYPE type, UINT *x, UINT *y) + { + HDC hDC; +diff --git a/dlls/shcore/shcore.spec b/dlls/shcore/shcore.spec +index 4d6e845..34f989f 100644 +--- a/dlls/shcore/shcore.spec ++++ b/dlls/shcore/shcore.spec +@@ -8,7 +8,7 @@ + @ stdcall GetCurrentProcessExplicitAppUserModelID(ptr) shell32.GetCurrentProcessExplicitAppUserModelID + @ stdcall GetDpiForMonitor(long long ptr ptr) + @ stub GetDpiForShellUIComponent +-@ stub GetProcessDpiAwareness ++@ stdcall GetProcessDpiAwareness(long ptr) + @ stub GetProcessReference + @ stub GetScaleFactorForDevice + @ stub GetScaleFactorForMonitor +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/definition wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/api-ms-win-Stub_DLLs/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,35 @@ +Fixes: Add api-ms-win-core-com-l1-1-1 dll +Fixes: Add api-ms-win-core-quirks-l1-1-0 dll +Fixes: Add api-ms-win-core-delayload-l1-1-1 dll +Fixes: Add api-ms-win-appmodel-runtime-l1-1-1 dll +Fixes: Add api-ms-win-core-apiquery-l1-1-0 dll +Fixes: Add api-ms-win-core-libraryloader-l1-2-0 dll +Fixes: Add api-ms-win-core-kernel32-legacy-l1-1-1 dll +Fixes: Add api-ms-win-core-heap-l2-1-0 dll +Fixes: Add api-ms-win-eventing-classicprovider-l1-1-0 dll +Fixes: Add api-ms-win-core-winrt-registration-l1-1-0 dll +Fixes: Add api-ms-win-shcore-obsolete-l1-1-0 dll +Fixes: Add ext-ms-win-xaml-pal-l1-1-0 dll +Fixes: Add ext-ms-win-appmodel-usercontext-l1-1-0 dll +Fixes: Add api-ms-win-shcore-thread-l1-1-0 dll +Fixes: Add api-ms-win-core-memory-l1-1-2 dll +Fixes: Add api-ms-win-core-wow64-l1-1-0 dll +Fixes: Add api-ms-win-core-shlwapi-obsolete-l1-2-0 dll +Fixes: Add api-ms-win-core-threadpool-l1-2-0 dll +Fixes: Add api-ms-win-shcore-stream-l1-1-0 dll +Fixes: Add ext-ms-win-ntuser-mouse-l1-1-0 dll +Fixes: Add ext-ms-win-uxtheme-themes-l1-1-0 dll +Fixes: Add api-ms-win-rtcore-ntuser-window-l1-1-0 dll +Fixes: Add ext-ms-win-rtcore-ntuser-syscolors-l1-1-0 dll +Fixes: Add api-ms-win-rtcore-ntuser-draw-l1-1-0 dll +Fixes: Add ext-ms-win-rtcore-ntuser-sysparams-l1-1-0 dll +Fixes: Add ext-ms-win-kernel32-package-current-l1-1-0 dll +Fixes: Add kernelbase dll +Fixes: Add iertutil dll +Fixes: Add shcore dll +Depends: ole32-CoGetApartmentType +Depends: kernel32-GetFinalPathNameByHandle +Depends: kernel32-FreeUserPhysicalPages +Depends: kernel32-InterlockedPushListSList +Depends: kernel32-GetCurrentPackageFamilyName +Depends: combase-RoApi diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/avifil32-AVIFile_Proxies/0001-avifil32-Add-support-for-AVIFile-interface-proxies.-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/avifil32-AVIFile_Proxies/0001-avifil32-Add-support-for-AVIFile-interface-proxies.-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/avifil32-AVIFile_Proxies/0001-avifil32-Add-support-for-AVIFile-interface-proxies.-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/avifil32-AVIFile_Proxies/0001-avifil32-Add-support-for-AVIFile-interface-proxies.-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,239 @@ +From a33160eef805e950e8b3c36c74f0688ca9e2328e Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sun, 7 Feb 2016 12:52:26 +0800 +Subject: avifil32: Add support for AVIFile interface proxies. [v2] + +--- + dlls/avifil32/Makefile.in | 4 +- + dlls/avifil32/avifil32.idl | 25 ++++++---- + dlls/avifil32/avifile_ifaces.idl | 105 +++++++++++++++++++++++++++++++++++++++ + dlls/avifil32/avifile_private.h | 1 + + dlls/avifil32/factory.c | 8 ++- + 5 files changed, 130 insertions(+), 13 deletions(-) + create mode 100644 dlls/avifil32/avifile_ifaces.idl + +diff --git a/dlls/avifil32/Makefile.in b/dlls/avifil32/Makefile.in +index 81d2ff8..4030514 100644 +--- a/dlls/avifil32/Makefile.in ++++ b/dlls/avifil32/Makefile.in +@@ -1,6 +1,6 @@ + MODULE = avifil32.dll + IMPORTLIB = avifil32 +-IMPORTS = uuid msacm32 msvfw32 winmm ole32 user32 advapi32 ++IMPORTS = uuid msacm32 msvfw32 winmm ole32 user32 advapi32 rpcrt4 + + C_SRCS = \ + acmstream.c \ +@@ -17,3 +17,5 @@ C_SRCS = \ + IDL_SRCS = avifil32.idl + + RC_SRCS = avifil32.rc ++ ++dlldata_EXTRADEFS = -DENTRY_PREFIX=avifil32_ +diff --git a/dlls/avifil32/avifil32.idl b/dlls/avifil32/avifil32.idl +index 1f50f15..e23c176 100644 +--- a/dlls/avifil32/avifil32.idl ++++ b/dlls/avifil32/avifil32.idl +@@ -18,39 +18,42 @@ + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + ++#pragma makedep proxy + #pragma makedep register + ++#include "avifile_ifaces.idl" ++ ++[ ++ helpstring("IAVIStream & IAVIFile Proxy"), ++ threading(both), ++ uuid(0002000d-0000-0000-c000-000000000046) ++] ++coclass PSFactoryBuffer { interface IFactoryBuffer; } ++ + [ + helpstring("Microsoft AVI Files"), +- threading(apartment), ++ threading(both), + uuid(00020000-0000-0000-C000-000000000046) + ] + coclass AVIFile { interface IAVIFile; } + + [ + helpstring("AVI Compressed Stream"), +- threading(apartment), ++ threading(both), + uuid(00020001-0000-0000-c000-000000000046) + ] + coclass ICMStream { interface IAVIStream; } + + [ + helpstring("Microsoft Wave File"), +- threading(apartment), ++ threading(both), + uuid(00020003-0000-0000-c000-000000000046) + ] + coclass WAVFile { interface IAVIFile; } + + [ +- helpstring("IAVIStream & IAVIFile Proxy"), +- threading(apartment), +- uuid(0002000d-0000-0000-c000-000000000046) +-] +-coclass AVIProxy { } +- +-[ + helpstring("ACM Compressed Audio Stream"), +- threading(apartment), ++ threading(both), + uuid(0002000f-0000-0000-c000-000000000046) + ] + coclass ACMStream { interface IAVIStream; } +diff --git a/dlls/avifil32/avifile_ifaces.idl b/dlls/avifil32/avifile_ifaces.idl +new file mode 100644 +index 0000000..f9280e5 +--- /dev/null ++++ b/dlls/avifil32/avifile_ifaces.idl +@@ -0,0 +1,105 @@ ++/* ++ * Proxy support for avifil32 ++ * ++ * Copyright 2016 Dmitry Timoshkov ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++/* ++ * These interface descriptions are supposed to be used for automatic proxy ++ * generation by an IDL compiler. ++ * ++ * While it's possible to convert include/vfw.h to an .idl, that's proved to ++ * be a major waste of an effort because the resulting interface descriptions ++ * can't be used for automatic proxy generation since they are not compatible ++ * with IDL compiler restrictions for proxies, and fixing them up would make ++ * generated vfw.h source incompatible with PSDK's equivalent. ++ */ ++ ++import "wtypes.idl"; ++import "unknwn.idl"; ++ ++typedef struct _AVISTREAMINFOW ++{ ++ DWORD fccType; ++ DWORD fccHandler; ++ DWORD dwFlags; ++ DWORD dwCaps; ++ WORD wPriority; ++ WORD wLanguage; ++ DWORD dwScale; ++ DWORD dwRate; ++ DWORD dwStart; ++ DWORD dwLength; ++ DWORD dwInitialFrames; ++ DWORD dwSuggestedBufferSize; ++ DWORD dwQuality; ++ DWORD dwSampleSize; ++ RECT rcFrame; ++ DWORD dwEditCount; ++ DWORD dwFormatChangeCount; ++ WCHAR szName[64]; ++} AVISTREAMINFOW; ++ ++[ ++ object, ++ uuid(00020021-0000-0000-c000-000000000046) ++] ++interface IAVIStream : IUnknown ++{ ++ HRESULT Create(LPARAM lParam1, LPARAM lParam2); ++ HRESULT Info(AVISTREAMINFOW *psi, LONG lSize); ++ LONG FindSample(LONG lPos, LONG lFlags); ++ HRESULT ReadFormat(LONG lPos, [out,size_is(*lpcbFormat)] char *lpFormat, [in,out] LONG *lpcbFormat); ++ HRESULT SetFormat(LONG lPos, [in,size_is(cbFormat)] char *lpFormat, LONG cbFormat); ++ HRESULT Read(LONG lStart, LONG lSamples, [out,size_is(cbBuffer)] char *lpBuffer, LONG cbBuffer, LONG *plBytes, LONG *plSamples); ++ HRESULT Write(LONG lStart, LONG lSamples, [in,size_is(cbBuffer)] char *lpBuffer, LONG cbBuffer, DWORD dwFlags, LONG *plSampWritten, LONG *plBytesWritten); ++ HRESULT Delete(LONG lStart, LONG lSamples); ++ HRESULT ReadData(DWORD fcc, [out,size_is(*lpcbBuffer)] char *lpBuffer, [in,out] LONG *lpcbBuffer); ++ HRESULT WriteData(DWORD fcc, [in,size_is(cbBuffer)] char *lpBuffer, LONG cbBuffer); ++ HRESULT SetInfo(AVISTREAMINFOW *plInfo, LONG cbInfo); ++}; ++ ++typedef struct _AVIFILEINFOW ++{ ++ DWORD dwMaxBytesPerSec; ++ DWORD dwFlags; ++ DWORD dwCaps; ++ DWORD dwStreams; ++ DWORD dwSuggestedBufferSize; ++ DWORD dwWidth; ++ DWORD dwHeight; ++ DWORD dwScale; ++ DWORD dwRate; ++ DWORD dwLength; ++ DWORD dwEditCount; ++ WCHAR szFileType[64]; ++} AVIFILEINFOW; ++ ++[ ++ object, ++ uuid(00020020-0000-0000-c000-000000000046) ++] ++interface IAVIFile : IUnknown ++{ ++ HRESULT Info(AVIFILEINFOW *pfi, LONG lSize); ++ HRESULT GetStream(IAVIStream **ppStream, DWORD fccType, LONG lParam); ++ HRESULT CreateStream(IAVIStream **ppStream, AVISTREAMINFOW *psi); ++ HRESULT WriteData(DWORD fcc, [in,size_is(cbBuffer)] char *lpBuffer, LONG cbBuffer); ++ HRESULT ReadData(DWORD fcc, [out,size_is(*lpcbBuffer)] char *lpBuffer, [in,out] LONG *lpcbBuffer); ++ HRESULT EndRecord(void); ++ HRESULT DeleteStream(DWORD fccType, LONG lParam); ++}; +diff --git a/dlls/avifil32/avifile_private.h b/dlls/avifil32/avifile_private.h +index 0fd74c4..9cce2d3 100644 +--- a/dlls/avifil32/avifile_private.h ++++ b/dlls/avifil32/avifile_private.h +@@ -67,5 +67,6 @@ extern PGETFRAME AVIFILE_CreateGetFrame(PAVISTREAM pstream) DECLSPEC_HIDDEN; + extern PAVIFILE AVIFILE_CreateAVITempFile(int nStreams, const PAVISTREAM *ppStreams) DECLSPEC_HIDDEN; + + extern LPCWSTR AVIFILE_BasenameW(LPCWSTR szFileName) DECLSPEC_HIDDEN; ++extern HRESULT WINAPI avifil32_DllGetClassObject(REFCLSID pclsid, REFIID piid, LPVOID *ppv) DECLSPEC_HIDDEN; + + #endif +diff --git a/dlls/avifil32/factory.c b/dlls/avifil32/factory.c +index c74a716..1b8988d 100644 +--- a/dlls/avifil32/factory.c ++++ b/dlls/avifil32/factory.c +@@ -195,12 +195,18 @@ LPCWSTR AVIFILE_BasenameW(LPCWSTR szPath) + */ + HRESULT WINAPI DllGetClassObject(REFCLSID pclsid, REFIID piid, LPVOID *ppv) + { ++ HRESULT hr; ++ + TRACE("(%s,%s,%p)\n", debugstr_guid(pclsid), debugstr_guid(piid), ppv); + + if (pclsid == NULL || piid == NULL || ppv == NULL) + return E_FAIL; + +- return AVIFILE_CreateClassFactory(pclsid,piid,ppv); ++ hr = AVIFILE_CreateClassFactory(pclsid,piid,ppv); ++ if (SUCCEEDED(hr)) ++ return hr; ++ ++ return avifil32_DllGetClassObject(pclsid,piid,ppv); + } + + /***************************************************************************** +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/avifil32-AVIFile_Proxies/definition wine-staging-1.9.3~ubuntu12.04.1/patches/avifil32-AVIFile_Proxies/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/avifil32-AVIFile_Proxies/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/avifil32-AVIFile_Proxies/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [38564] Add support for AVIFile interface proxies diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/avifil32-IGetFrame_fnSetFormat/0001-avifil32-Correctly-handle-compressed-frames-when-des.patch wine-staging-1.9.3~ubuntu12.04.1/patches/avifil32-IGetFrame_fnSetFormat/0001-avifil32-Correctly-handle-compressed-frames-when-des.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/avifil32-IGetFrame_fnSetFormat/0001-avifil32-Correctly-handle-compressed-frames-when-des.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/avifil32-IGetFrame_fnSetFormat/0001-avifil32-Correctly-handle-compressed-frames-when-des.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,141 @@ +From 23ce6bcd9ebd67d6b5ed991bad555ecbc014a08d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Mon, 8 Feb 2016 04:55:07 +0100 +Subject: avifil32: Correctly handle compressed frames when desired format is + specified. + +--- + dlls/avifil32/getframe.c | 102 +++++++++++++++++++++++------------------------ + 1 file changed, 50 insertions(+), 52 deletions(-) + +diff --git a/dlls/avifil32/getframe.c b/dlls/avifil32/getframe.c +index 46b1683..7d98d2e 100644 +--- a/dlls/avifil32/getframe.c ++++ b/dlls/avifil32/getframe.c +@@ -406,8 +406,6 @@ static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame *iface, + lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD)); + if (lpbi->biBitCount <= 8) + ICDecompressGetPalette(This->hic, This->lpInFormat, This->lpOutFormat); +- +- return AVIERR_OK; + } else { + if (bBestDisplay) { + ICGetDisplayFormat(This->hic, This->lpInFormat, +@@ -417,64 +415,64 @@ static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame *iface, + AVIFILE_CloseCompressor(This); + return AVIERR_NOCOMPRESSOR; + } ++ } + +- /* check output format */ +- if (This->lpOutFormat->biClrUsed == 0 && +- This->lpOutFormat->biBitCount <= 8) +- This->lpOutFormat->biClrUsed = 1u << This->lpOutFormat->biBitCount; +- if (This->lpOutFormat->biSizeImage == 0 && +- This->lpOutFormat->biCompression == BI_RGB) { +- This->lpOutFormat->biSizeImage = +- DIBWIDTHBYTES(*This->lpOutFormat) * This->lpOutFormat->biHeight; +- } ++ /* check output format */ ++ if (This->lpOutFormat->biClrUsed == 0 && ++ This->lpOutFormat->biBitCount <= 8) ++ This->lpOutFormat->biClrUsed = 1u << This->lpOutFormat->biBitCount; ++ if (This->lpOutFormat->biSizeImage == 0 && ++ This->lpOutFormat->biCompression == BI_RGB) { ++ This->lpOutFormat->biSizeImage = ++ DIBWIDTHBYTES(*This->lpOutFormat) * This->lpOutFormat->biHeight; ++ } + +- if (lpBits == NULL) { +- DWORD size = This->lpOutFormat->biClrUsed * sizeof(RGBQUAD); ++ if (lpBits == NULL) { ++ DWORD size = This->lpOutFormat->biClrUsed * sizeof(RGBQUAD); + +- size += This->lpOutFormat->biSize + This->lpOutFormat->biSizeImage; +- This->lpOutFormat = HeapReAlloc(GetProcessHeap(), 0, This->lpOutFormat, size); +- if (This->lpOutFormat == NULL) { +- AVIFILE_CloseCompressor(This); +- return AVIERR_MEMORY; +- } +- This->lpOutBuffer = DIBPTR(This->lpOutFormat); +- } else +- This->lpOutBuffer = lpBits; +- +- /* for user size was irrelevant */ +- if (dx == -1) +- dx = This->lpOutFormat->biWidth; +- if (dy == -1) +- dy = This->lpOutFormat->biHeight; +- +- /* need to resize? */ +- if (x != 0 || y != 0) { +- if (dy == This->lpOutFormat->biHeight && +- dx == This->lpOutFormat->biWidth) +- This->bResize = FALSE; +- else +- This->bResize = TRUE; ++ size += This->lpOutFormat->biSize + This->lpOutFormat->biSizeImage; ++ This->lpOutFormat = HeapReAlloc(GetProcessHeap(), 0, This->lpOutFormat, size); ++ if (This->lpOutFormat == NULL) { ++ AVIFILE_CloseCompressor(This); ++ return AVIERR_MEMORY; + } ++ This->lpOutBuffer = DIBPTR(This->lpOutFormat); ++ } else ++ This->lpOutBuffer = lpBits; ++ ++ /* for user size was irrelevant */ ++ if (dx == -1) ++ dx = This->lpOutFormat->biWidth; ++ if (dy == -1) ++ dy = This->lpOutFormat->biHeight; ++ ++ /* need to resize? */ ++ if (x != 0 || y != 0) { ++ if (dy == This->lpOutFormat->biHeight && ++ dx == This->lpOutFormat->biWidth) ++ This->bResize = FALSE; ++ else ++ This->bResize = TRUE; ++ } + +- if (This->bResize) { +- This->x = x; +- This->y = y; +- This->dx = dx; +- This->dy = dy; +- +- if (ICDecompressExBegin(This->hic,0,This->lpInFormat,This->lpInBuffer,0, +- 0,This->lpInFormat->biWidth, +- This->lpInFormat->biHeight,This->lpOutFormat, +- This->lpOutBuffer, x, y, dx, dy) == ICERR_OK) +- return AVIERR_OK; +- } else if (ICDecompressBegin(This->hic, This->lpInFormat, +- This->lpOutFormat) == ICERR_OK) ++ if (This->bResize) { ++ This->x = x; ++ This->y = y; ++ This->dx = dx; ++ This->dy = dy; ++ ++ if (ICDecompressExBegin(This->hic,0,This->lpInFormat,This->lpInBuffer,0, ++ 0,This->lpInFormat->biWidth, ++ This->lpInFormat->biHeight,This->lpOutFormat, ++ This->lpOutBuffer, x, y, dx, dy) == ICERR_OK) + return AVIERR_OK; ++ } else if (ICDecompressBegin(This->hic, This->lpInFormat, ++ This->lpOutFormat) == ICERR_OK) ++ return AVIERR_OK; + +- AVIFILE_CloseCompressor(This); ++ AVIFILE_CloseCompressor(This); + +- return AVIERR_COMPRESSOR; +- } ++ return AVIERR_COMPRESSOR; + } + + static const struct IGetFrameVtbl igetframeVtbl = { +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/avifil32-IGetFrame_fnSetFormat/definition wine-staging-1.9.3~ubuntu12.04.1/patches/avifil32-IGetFrame_fnSetFormat/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/avifil32-IGetFrame_fnSetFormat/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/avifil32-IGetFrame_fnSetFormat/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Correctly handle compressed frames when desired format is specified diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/0001-avifile-Correctly-convert-result-of-AVIStreamGetFram.patch wine-staging-1.9.3~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/0001-avifile-Correctly-convert-result-of-AVIStreamGetFram.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/0001-avifile-Correctly-convert-result-of-AVIStreamGetFram.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/0001-avifile-Correctly-convert-result-of-AVIStreamGetFram.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,186 @@ +From e68b9f65a4f9c7f9c10b11152cac04bcdf6facf9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Mon, 8 Feb 2016 04:44:24 +0100 +Subject: avifile.dll16: Correctly convert result of AVIStreamGetFrame to a segptr. + +--- + dlls/avifile.dll16/Makefile.in | 3 + + dlls/avifile.dll16/avifile.dll16.spec | 6 +- + dlls/avifile.dll16/main.c | 137 ++++++++++++++++++++++++++++++++++ + 3 files changed, 143 insertions(+), 3 deletions(-) + create mode 100644 dlls/avifile.dll16/main.c + +diff --git a/dlls/avifile.dll16/Makefile.in b/dlls/avifile.dll16/Makefile.in +index 6050c6c..4152c2f 100644 +--- a/dlls/avifile.dll16/Makefile.in ++++ b/dlls/avifile.dll16/Makefile.in +@@ -1,3 +1,6 @@ + MODULE = avifile.dll16 + IMPORTS = avifil32 + EXTRADLLFLAGS = -m16 -Wb,--main-module,avifil32.dll ++ ++C_SRCS = \ ++ main.c +diff --git a/dlls/avifile.dll16/avifile.dll16.spec b/dlls/avifile.dll16/avifile.dll16.spec +index 71a6c74..0e19413 100644 +--- a/dlls/avifile.dll16/avifile.dll16.spec ++++ b/dlls/avifile.dll16/avifile.dll16.spec +@@ -20,9 +20,9 @@ + 105 stub AVIMAKECOMPRESSEDSTREAM + 106 stub AVIMAKEFILEFROMSTREAMS + 107 stub AVIMAKESTREAMFROMCLIPBOARD +-110 pascal AVIStreamGetFrame(long long) AVIStreamGetFrame +-111 pascal AVIStreamGetFrameClose(long) AVIStreamGetFrameClose +-112 pascal AVIStreamGetFrameOpen(long ptr) AVIStreamGetFrameOpen ++110 pascal AVIStreamGetFrame(long long) AVIStreamGetFrame16 ++111 pascal AVIStreamGetFrameClose(long) AVIStreamGetFrameClose16 ++112 pascal AVIStreamGetFrameOpen(long ptr) AVIStreamGetFrameOpen16 + 120 stub _AVISAVE + 121 stub AVISAVEV + 122 stub AVISAVEOPTIONS +diff --git a/dlls/avifile.dll16/main.c b/dlls/avifile.dll16/main.c +new file mode 100644 +index 0000000..f780c43 +--- /dev/null ++++ b/dlls/avifile.dll16/main.c +@@ -0,0 +1,137 @@ ++/* ++ * Wrapper for 16 bit avifile functions ++ * ++ * Copyright 2016 Michael Müller ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "wine/winbase16.h" ++#include "winternl.h" ++#include "wingdi.h" ++#include "vfw.h" ++ ++#include "wine/debug.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(avifile16); ++ ++struct frame_wrapper16 ++{ ++ PGETFRAME pg; ++ PVOID ptr; ++ DWORD size; ++ WORD sel; ++ WORD count; ++}; ++ ++static void free_segptr_frame(struct frame_wrapper16 *wrapper) ++{ ++ int i; ++ ++ if (!wrapper->sel) ++ return; ++ ++ for (i = 0; i < wrapper->count; i++) ++ FreeSelector16(wrapper->sel + (i << __AHSHIFT)); ++ ++ wrapper->sel = 0; ++} ++ ++static SEGPTR alloc_segptr_frame(struct frame_wrapper16 *wrapper, void *ptr, DWORD size) ++{ ++ int i; ++ ++ if (wrapper->sel) ++ { ++ if (wrapper->ptr == ptr && wrapper->size == size) ++ return MAKESEGPTR(wrapper->sel, 0); ++ free_segptr_frame(wrapper); ++ } ++ ++ wrapper->ptr = ptr; ++ wrapper->size = size; ++ wrapper->count = (size + 0xffff) / 0x10000; ++ wrapper->sel = AllocSelectorArray16(wrapper->count); ++ if (!wrapper->sel) ++ return 0; ++ ++ for (i = 0; i < wrapper->count; i++) ++ { ++ SetSelectorBase(wrapper->sel + (i << __AHSHIFT), (DWORD)ptr + i * 0x10000); ++ SetSelectorLimit16(wrapper->sel + (i << __AHSHIFT), size - 1); ++ size -= 0x10000; ++ } ++ ++ return MAKESEGPTR(wrapper->sel, 0); ++} ++ ++/*********************************************************************** ++ * AVIStreamGetFrameOpen (AVIFILE.112) ++ */ ++PGETFRAME WINAPI AVIStreamGetFrameOpen16(PAVISTREAM pstream, LPBITMAPINFOHEADER lpbiWanted) ++{ ++ struct frame_wrapper16 *wrapper; ++ PGETFRAME pg; ++ ++ pg = AVIStreamGetFrameOpen(pstream, lpbiWanted); ++ if (!pg) return NULL; ++ ++ wrapper = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wrapper)); ++ if (!wrapper) ++ { ++ AVIStreamGetFrameClose(pg); ++ return NULL; ++ } ++ ++ wrapper->pg = pg; ++ return (PGETFRAME)wrapper; ++} ++ ++/*********************************************************************** ++ * AVIStreamGetFrame (AVIFILE.110) ++ */ ++SEGPTR WINAPI AVIStreamGetFrame16(PGETFRAME pg, LONG pos) ++{ ++ struct frame_wrapper16 *wrapper = (void *)pg; ++ BITMAPINFOHEADER *bih; ++ ++ if (!pg) return 0; ++ ++ bih = AVIStreamGetFrame(wrapper->pg, pos); ++ if (bih) ++ { ++ DWORD size = bih->biSize + bih->biSizeImage; ++ return alloc_segptr_frame(wrapper, bih, size); ++ } ++ ++ return 0; ++} ++ ++ ++/*********************************************************************** ++ * AVIStreamGetFrameClose (AVIFILE.111) ++ */ ++HRESULT WINAPI AVIStreamGetFrameClose16(PGETFRAME pg) ++{ ++ struct frame_wrapper16 *wrapper = (void *)pg; ++ HRESULT hr; ++ ++ if (!pg) return S_OK; ++ ++ hr = AVIStreamGetFrameClose(wrapper->pg); ++ free_segptr_frame(wrapper); ++ HeapFree(GetProcessHeap(), 0, wrapper); ++ return hr; ++} +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/0002-avifile-Convert-between-AVISTREAMINFO-16-bit-and-AVI.patch wine-staging-1.9.3~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/0002-avifile-Convert-between-AVISTREAMINFO-16-bit-and-AVI.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/0002-avifile-Convert-between-AVISTREAMINFO-16-bit-and-AVI.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/0002-avifile-Convert-between-AVISTREAMINFO-16-bit-and-AVI.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,148 @@ +From 3cdd530b2c17ee0cdc6a1fcc37b28c180310656a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Mon, 8 Feb 2016 14:02:09 +0100 +Subject: avifile.dll16: Convert between AVISTREAMINFO (16 bit) and AVISTREAMINFOA. + +--- + dlls/avifile.dll16/avifile.dll16.spec | 4 +- + dlls/avifile.dll16/main.c | 100 ++++++++++++++++++++++++++++++++++ + 2 files changed, 102 insertions(+), 2 deletions(-) + +diff --git a/dlls/avifile.dll16/avifile.dll16.spec b/dlls/avifile.dll16/avifile.dll16.spec +index 0e19413..7a1aaea 100644 +--- a/dlls/avifile.dll16/avifile.dll16.spec ++++ b/dlls/avifile.dll16/avifile.dll16.spec +@@ -36,13 +36,13 @@ + 141 pascal AVIFileRelease(long) AVIFileRelease + 142 pascal AVIFileInfo(long ptr long) AVIFileInfoA + 143 pascal AVIFileGetStream(long ptr long long) AVIFileGetStream +-144 pascal AVIFileCreateStream(long ptr ptr) AVIFileCreateStreamA ++144 pascal AVIFileCreateStream(long ptr ptr) AVIFileCreateStream16 + 146 pascal AVIFileWriteData(long long ptr long) AVIFileWriteData + 147 pascal AVIFileReadData(long long ptr ptr) AVIFileReadData + 148 pascal AVIFileEndRecord(long) AVIFileEndRecord + 160 pascal AVIStreamAddRef(long) AVIStreamAddRef + 161 pascal AVIStreamRelease(long) AVIStreamRelease +-162 pascal AVIStreamInfo(long ptr long) AVIStreamInfoA ++162 pascal AVIStreamInfo(long ptr long) AVIStreamInfo16 + 163 pascal AVIStreamFindSample(long long long) AVIStreamFindSample + 164 pascal AVIStreamReadFormat(long long ptr ptr) AVIStreamReadFormat + 165 pascal AVIStreamReadData(long long ptr ptr) AVIStreamReadData +diff --git a/dlls/avifile.dll16/main.c b/dlls/avifile.dll16/main.c +index f780c43..8df1fe5 100644 +--- a/dlls/avifile.dll16/main.c ++++ b/dlls/avifile.dll16/main.c +@@ -27,6 +27,27 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(avifile16); + ++typedef struct _AVISTREAMINFO16 { ++ DWORD fccType; ++ DWORD fccHandler; ++ DWORD dwFlags; ++ DWORD dwCaps; ++ WORD wPriority; ++ WORD wLanguage; ++ DWORD dwScale; ++ DWORD dwRate; ++ DWORD dwStart; ++ DWORD dwLength; ++ DWORD dwInitialFrames; ++ DWORD dwSuggestedBufferSize; ++ DWORD dwQuality; ++ DWORD dwSampleSize; ++ RECT16 rcFrame; ++ DWORD dwEditCount; ++ DWORD dwFormatChangeCount; ++ CHAR szName[64]; ++} AVISTREAMINFO16, *LPAVISTREAMINFO16, *PAVISTREAMINFO16; ++ + struct frame_wrapper16 + { + PGETFRAME pg; +@@ -135,3 +156,82 @@ HRESULT WINAPI AVIStreamGetFrameClose16(PGETFRAME pg) + HeapFree(GetProcessHeap(), 0, wrapper); + return hr; + } ++ ++/*********************************************************************** ++ * AVIFileCreateStream (AVIFILE.144) ++ */ ++HRESULT WINAPI AVIFileCreateStream16(PAVIFILE pfile, PAVISTREAM *ppavi, LPAVISTREAMINFO16 asi16) ++{ ++ AVISTREAMINFOA asi; ++ ++ if (!asi16) ++ return AVIFileCreateStreamA(pfile, ppavi, NULL); ++ ++ asi.fccType = asi16->fccType; ++ asi.fccHandler = asi16->fccHandler; ++ asi.dwFlags = asi16->dwFlags; ++ asi.dwCaps = asi16->dwCaps; ++ asi.wPriority = asi16->wPriority; ++ asi.wLanguage = asi16->wLanguage; ++ asi.dwScale = asi16->dwScale; ++ asi.dwRate = asi16->dwRate; ++ asi.dwStart = asi16->dwStart; ++ asi.dwLength = asi16->dwLength; ++ asi.dwInitialFrames = asi16->dwInitialFrames; ++ asi.dwSuggestedBufferSize = asi16->dwSuggestedBufferSize; ++ asi.dwQuality = asi16->dwQuality; ++ asi.dwSampleSize = asi16->dwSampleSize; ++ asi.rcFrame.left = asi16->rcFrame.left; ++ asi.rcFrame.top = asi16->rcFrame.top; ++ asi.rcFrame.right = asi16->rcFrame.right; ++ asi.rcFrame.bottom = asi16->rcFrame.bottom; ++ asi.dwEditCount = asi16->dwEditCount; ++ asi.dwFormatChangeCount = asi16->dwFormatChangeCount; ++ memcpy(&asi.szName, &asi16->szName, sizeof(asi.szName)); ++ ++ return AVIFileCreateStreamA(pfile, ppavi, &asi); ++} ++ ++ ++/*********************************************************************** ++ * AVIStreamInfo (AVIFILE.162) ++ */ ++HRESULT WINAPI AVIStreamInfo16(PAVISTREAM pstream, LPAVISTREAMINFO16 asi16, LONG size) ++{ ++ AVISTREAMINFOA asi; ++ HRESULT hr; ++ ++ if (!asi16) ++ return AVIStreamInfoA(pstream, NULL, size); ++ ++ if (size < sizeof(AVISTREAMINFO16)) ++ return AVIERR_BADSIZE; ++ ++ hr = AVIStreamInfoA(pstream, &asi, sizeof(asi)); ++ if (SUCCEEDED(hr)) ++ { ++ asi16->fccType = asi.fccType; ++ asi16->fccHandler = asi.fccHandler; ++ asi16->dwFlags = asi.dwFlags; ++ asi16->dwCaps = asi.dwCaps; ++ asi16->wPriority = asi.wPriority; ++ asi16->wLanguage = asi.wLanguage; ++ asi16->dwScale = asi.dwScale; ++ asi16->dwRate = asi.dwRate; ++ asi16->dwStart = asi.dwStart; ++ asi16->dwLength = asi.dwLength; ++ asi16->dwInitialFrames = asi.dwInitialFrames; ++ asi16->dwSuggestedBufferSize = asi.dwSuggestedBufferSize; ++ asi16->dwQuality = asi.dwQuality; ++ asi16->dwSampleSize = asi.dwSampleSize; ++ asi16->rcFrame.left = asi.rcFrame.left; ++ asi16->rcFrame.top = asi.rcFrame.top; ++ asi16->rcFrame.right = asi.rcFrame.right; ++ asi16->rcFrame.bottom = asi.rcFrame.bottom; ++ asi16->dwEditCount = asi.dwEditCount; ++ asi16->dwFormatChangeCount = asi.dwFormatChangeCount; ++ memcpy(&asi16->szName, &asi.szName, sizeof(asi.szName)); ++ } ++ ++ return hr; ++} +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/definition wine-staging-1.9.3~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/avifile.dll16-AVIStreamGetFrame/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,2 @@ +Fixes: Correctly convert result of AVIStreamGetFrame to a segptr in avifile.dll16 +Fixes: Convert between AVISTREAMINFO (16 bit) and AVISTREAMINFOA in avifile.dll16 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0001-include-Add-activation.idl-with-IActivationFactory-i.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0001-include-Add-activation.idl-with-IActivationFactory-i.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0001-include-Add-activation.idl-with-IActivationFactory-i.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0001-include-Add-activation.idl-with-IActivationFactory-i.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,62 @@ +From dd6fc285ffa83e8eb9dce0aa482df44288faa2ea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 01:36:08 +0100 +Subject: include: Add activation.idl with IActivationFactory interface. + +--- + include/Makefile.in | 1 + + include/activation.idl | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 32 insertions(+) + create mode 100644 include/activation.idl + +diff --git a/include/Makefile.in b/include/Makefile.in +index 129ff6d..14e934c 100644 +--- a/include/Makefile.in ++++ b/include/Makefile.in +@@ -1,5 +1,6 @@ + IDL_SRCS = \ + access.idl \ ++ activation.idl \ + activaut.idl \ + activdbg.idl \ + activscp.idl \ +diff --git a/include/activation.idl b/include/activation.idl +new file mode 100644 +index 0000000..b86c9f6 +--- /dev/null ++++ b/include/activation.idl +@@ -0,0 +1,31 @@ ++/* ++ * Copyright 2016 Michael Müller ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#ifndef DO_NO_IMPORTS ++import "inspectable.idl"; ++#endif ++ ++[ ++ object, ++ uuid(00000035-0000-0000-c000-000000000046), ++ pointer_default(unique) ++] ++interface IActivationFactory : IInspectable ++{ ++ HRESULT ActivateInstance([out] IInspectable **instance); ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0002-include-roapi.h-Add-further-typedefs.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0002-include-roapi.h-Add-further-typedefs.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0002-include-roapi.h-Add-further-typedefs.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0002-include-roapi.h-Add-further-typedefs.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,43 @@ +From ab3de1775fa8321218d5712b7562b8575a222a31 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 01:37:09 +0100 +Subject: include/roapi.h: Add further typedefs. + +--- + include/roapi.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/include/roapi.h b/include/roapi.h +index 0421fe9..f4154f8 100644 +--- a/include/roapi.h ++++ b/include/roapi.h +@@ -1,5 +1,6 @@ + /* + * Copyright (C) 2014 Martin Storsjo ++ * Copyright (C) 2016 Michael Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -20,6 +21,7 @@ + #define __WINE_ROAPI_H + + #include ++#include + + typedef enum + { +@@ -27,6 +29,11 @@ typedef enum + RO_INIT_MULTITHREADED = 1, + } RO_INIT_TYPE; + ++DECLARE_HANDLE(APARTMENT_SHUTDOWN_REGISTRATION_COOKIE); ++ ++typedef struct {} *RO_REGISTRATION_COOKIE; ++typedef HRESULT (WINAPI *PFNGETACTIVATIONFACTORY)(HSTRING, IActivationFactory **); ++ + #ifdef __cplusplus + extern "C" { + #endif +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0003-combase-Implement-RoGetActivationFactory.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0003-combase-Implement-RoGetActivationFactory.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0003-combase-Implement-RoGetActivationFactory.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0003-combase-Implement-RoGetActivationFactory.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,190 @@ +From a197dcbcf3f89fecd23028760bdc57502e0c7633 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 01:42:05 +0100 +Subject: combase: Implement RoGetActivationFactory. + +--- + dlls/combase/Makefile.in | 2 +- + dlls/combase/roapi.c | 137 +++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 134 insertions(+), 5 deletions(-) + +diff --git a/dlls/combase/Makefile.in b/dlls/combase/Makefile.in +index c5ab8d2..cf17a36 100644 +--- a/dlls/combase/Makefile.in ++++ b/dlls/combase/Makefile.in +@@ -1,5 +1,5 @@ + MODULE = combase.dll +-IMPORTS = ole32 ++IMPORTS = advapi32 ole32 + + C_SRCS = \ + roapi.c \ +diff --git a/dlls/combase/roapi.c b/dlls/combase/roapi.c +index a2dfd54..6fd4df5 100644 +--- a/dlls/combase/roapi.c ++++ b/dlls/combase/roapi.c +@@ -1,5 +1,6 @@ + /* + * Copyright 2014 Martin Storsjo ++ * Copyright 2016 Michael Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -17,13 +18,93 @@ + */ + + #include "objbase.h" ++#include "initguid.h" ++#define COBJMACROS + #include "roapi.h" +-#include "hstring.h" ++#include "winstring.h" + + #include "wine/debug.h" + + WINE_DEFAULT_DEBUG_CHANNEL(combase); + ++static const char *debugstr_hstring(HSTRING hstr) ++{ ++ const WCHAR *str; ++ UINT32 len; ++ if (hstr && !((ULONG_PTR)hstr >> 16)) return "(invalid)"; ++ str = WindowsGetStringRawBuffer(hstr, &len); ++ return wine_dbgstr_wn(str, len); ++} ++ ++static HRESULT get_library_for_classid(const WCHAR *classid, WCHAR **out) ++{ ++ static const WCHAR classkeyW[] = {'S','o','f','t','w','a','r','e','\\', ++ 'M','i','c','r','o','s','o','f','t','\\', ++ 'W','i','n','d','o','w','s','R','u','n','t','i','m','e','\\', ++ 'A','c','t','i','v','a','t','a','b','l','e','C','l','a','s','s','I','d',0}; ++ static const WCHAR dllpathW[] = {'D','l','l','P','a','t','h',0}; ++ HKEY hkey_root, hkey_class; ++ DWORD type, size; ++ HRESULT hr; ++ WCHAR *buf = NULL; ++ ++ *out = NULL; ++ ++ /* load class registry key */ ++ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, classkeyW, 0, KEY_READ, &hkey_root)) ++ return REGDB_E_READREGDB; ++ if (RegOpenKeyExW(hkey_root, classid, 0, KEY_READ, &hkey_class)) ++ { ++ WARN("Class %s not found in registry\n", debugstr_w(classid)); ++ RegCloseKey(hkey_root); ++ return REGDB_E_CLASSNOTREG; ++ } ++ RegCloseKey(hkey_root); ++ ++ /* load (and expand) DllPath registry value */ ++ if (RegQueryValueExW(hkey_class, dllpathW, NULL, &type, NULL, &size)) ++ { ++ hr = REGDB_E_READREGDB; ++ goto done; ++ } ++ if (type != REG_SZ && type != REG_EXPAND_SZ) ++ { ++ hr = REGDB_E_READREGDB; ++ goto done; ++ } ++ if (!(buf = HeapAlloc(GetProcessHeap(), 0, size))) ++ { ++ hr = E_OUTOFMEMORY; ++ goto done; ++ } ++ if (RegQueryValueExW(hkey_class, dllpathW, NULL, NULL, (BYTE *)buf, &size)) ++ { ++ hr = REGDB_E_READREGDB; ++ goto done; ++ } ++ if (type == REG_EXPAND_SZ) ++ { ++ WCHAR *expanded; ++ DWORD len = ExpandEnvironmentStringsW(buf, NULL, 0); ++ if (!(expanded = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) ++ { ++ hr = E_OUTOFMEMORY; ++ goto done; ++ } ++ ExpandEnvironmentStringsW(buf, expanded, len); ++ HeapFree(GetProcessHeap(), 0, buf); ++ buf = expanded; ++ } ++ ++ *out = buf; ++ return S_OK; ++ ++done: ++ HeapFree(GetProcessHeap(), 0, buf); ++ RegCloseKey(hkey_class); ++ return hr; ++} ++ + /*********************************************************************** + * RoInitialize (combase.@) + */ +@@ -50,8 +131,56 @@ void WINAPI RoUninitialize(void) + /*********************************************************************** + * RoGetActivationFactory (combase.@) + */ +-HRESULT WINAPI RoGetActivationFactory(HSTRING classid, REFIID iid, void **factory) ++HRESULT WINAPI RoGetActivationFactory(HSTRING classid, REFIID iid, void **class_factory) + { +- FIXME("stub: %p %p %p\n", classid, iid, factory); +- return E_NOTIMPL; ++ PFNGETACTIVATIONFACTORY pDllGetActivationFactory; ++ IActivationFactory *factory; ++ WCHAR *library; ++ HMODULE module; ++ HRESULT hr; ++ ++ FIXME("(%s, %s, %p): semi-stub\n", debugstr_hstring(classid), debugstr_guid(iid), class_factory); ++ ++ if (!iid || !class_factory) ++ return E_INVALIDARG; ++ ++ hr = get_library_for_classid(WindowsGetStringRawBuffer(classid, NULL), &library); ++ if (FAILED(hr)) ++ { ++ ERR("Failed to find library for %s\n", debugstr_hstring(classid)); ++ return hr; ++ } ++ ++ if (!(module = LoadLibraryW(library))) ++ { ++ ERR("Failed to load module %s\n", debugstr_w(library)); ++ hr = HRESULT_FROM_WIN32(GetLastError()); ++ goto done; ++ } ++ ++ if (!(pDllGetActivationFactory = (void *)GetProcAddress(module, "DllGetActivationFactory"))) ++ { ++ ERR("Module %s does not implement DllGetActivationFactory\n", debugstr_w(library)); ++ hr = E_FAIL; ++ goto done; ++ } ++ ++ TRACE("Found library %s for class %s\n", debugstr_w(library), debugstr_hstring(classid)); ++ ++ hr = pDllGetActivationFactory(classid, &factory); ++ if (SUCCEEDED(hr)) ++ { ++ hr = IActivationFactory_QueryInterface(factory, iid, class_factory); ++ if (SUCCEEDED(hr)) ++ { ++ TRACE("Created interface %p\n", *class_factory); ++ module = NULL; ++ } ++ IActivationFactory_Release(factory); ++ } ++ ++done: ++ HeapFree(GetProcessHeap(), 0, library); ++ if (module) FreeLibrary(module); ++ return hr; + } +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0004-combase-Implement-RoActivateInstance.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0004-combase-Implement-RoActivateInstance.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0004-combase-Implement-RoActivateInstance.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0004-combase-Implement-RoActivateInstance.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,65 @@ +From c78968d3484d613945a0ee33eeb4df5d96a7c406 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 01:45:30 +0100 +Subject: combase: Implement RoActivateInstance. + +--- + .../api-ms-win-core-winrt-l1-1-0.spec | 2 +- + dlls/combase/combase.spec | 2 +- + dlls/combase/roapi.c | 20 ++++++++++++++++++++ + 3 files changed, 22 insertions(+), 2 deletions(-) + +diff --git a/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec b/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec +index 74c9d27..978c3dc 100644 +--- a/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec ++++ b/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec +@@ -1,4 +1,4 @@ +-@ stub RoActivateInstance ++@ stdcall RoActivateInstance(ptr ptr) combase.RoActivateInstance + @ stdcall RoGetActivationFactory(ptr ptr ptr) combase.RoGetActivationFactory + @ stub RoGetApartmentIdentifier + @ stdcall RoInitialize(long) combase.RoInitialize +diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec +index 5082f39..9b1ab30 100644 +--- a/dlls/combase/combase.spec ++++ b/dlls/combase/combase.spec +@@ -242,7 +242,7 @@ + @ stdcall PropVariantClear(ptr) ole32.PropVariantClear + @ stdcall PropVariantCopy(ptr ptr) ole32.PropVariantCopy + @ stub ReleaseFuncDescs +-@ stub RoActivateInstance ++@ stdcall RoActivateInstance(ptr ptr) + @ stub RoCaptureErrorContext + @ stub RoClearError + @ stub RoFailFastWithErrorContext +diff --git a/dlls/combase/roapi.c b/dlls/combase/roapi.c +index 6fd4df5..695b6fd 100644 +--- a/dlls/combase/roapi.c ++++ b/dlls/combase/roapi.c +@@ -184,3 +184,23 @@ done: + if (module) FreeLibrary(module); + return hr; + } ++ ++/*********************************************************************** ++ * RoActivateInstance (combase.@) ++ */ ++HRESULT WINAPI RoActivateInstance(HSTRING classid, IInspectable **instance) ++{ ++ IActivationFactory *factory; ++ HRESULT hr; ++ ++ FIXME("(%s, %p): semi-stub\n", debugstr_hstring(classid), instance); ++ ++ hr = RoGetActivationFactory(classid, &IID_IActivationFactory, (void **)&factory); ++ if (SUCCEEDED(hr)) ++ { ++ hr = IActivationFactory_ActivateInstance(factory, instance); ++ IActivationFactory_Release(factory); ++ } ++ ++ return hr; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0005-combase-Add-stub-for-RoGetApartmentIdentifier.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0005-combase-Add-stub-for-RoGetApartmentIdentifier.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0005-combase-Add-stub-for-RoGetApartmentIdentifier.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0005-combase-Add-stub-for-RoGetApartmentIdentifier.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,61 @@ +From 493d757c594d0eccce55e29fc6e5ef574fc7446f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 01:47:08 +0100 +Subject: combase: Add stub for RoGetApartmentIdentifier. + +--- + .../api-ms-win-core-winrt-l1-1-0.spec | 2 +- + dlls/combase/combase.spec | 2 +- + dlls/combase/roapi.c | 14 ++++++++++++++ + 3 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec b/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec +index 978c3dc..88139fb 100644 +--- a/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec ++++ b/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec +@@ -1,6 +1,6 @@ + @ stdcall RoActivateInstance(ptr ptr) combase.RoActivateInstance + @ stdcall RoGetActivationFactory(ptr ptr ptr) combase.RoGetActivationFactory +-@ stub RoGetApartmentIdentifier ++@ stdcall RoGetApartmentIdentifier(ptr) combase.RoGetApartmentIdentifier + @ stdcall RoInitialize(long) combase.RoInitialize + @ stub RoRegisterActivationFactories + @ stub RoRegisterForApartmentShutdown +diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec +index 9b1ab30..3bf0bf2 100644 +--- a/dlls/combase/combase.spec ++++ b/dlls/combase/combase.spec +@@ -250,7 +250,7 @@ + @ stub RoGetActivatableClassRegistration + @ stdcall RoGetActivationFactory(ptr ptr ptr) + @ stub RoGetAgileReference +-@ stub RoGetApartmentIdentifier ++@ stdcall RoGetApartmentIdentifier(ptr) + @ stub RoGetErrorReportingFlags + @ stub RoGetMatchingRestrictedErrorInfo + @ stub RoGetParameterizedTypeInstanceIID +diff --git a/dlls/combase/roapi.c b/dlls/combase/roapi.c +index 695b6fd..cd545f1 100644 +--- a/dlls/combase/roapi.c ++++ b/dlls/combase/roapi.c +@@ -204,3 +204,17 @@ HRESULT WINAPI RoActivateInstance(HSTRING classid, IInspectable **instance) + + return hr; + } ++ ++/*********************************************************************** ++ * RoGetApartmentIdentifier (combase.@) ++ */ ++HRESULT WINAPI RoGetApartmentIdentifier(UINT64 *identifier) ++{ ++ FIXME("(%p): stub\n", identifier); ++ ++ if (!identifier) ++ return E_INVALIDARG; ++ ++ *identifier = 0xdeadbeef; ++ return S_OK; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0006-include-objidl.idl-Add-IApartmentShutdown-interface.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0006-include-objidl.idl-Add-IApartmentShutdown-interface.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0006-include-objidl.idl-Add-IApartmentShutdown-interface.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0006-include-objidl.idl-Add-IApartmentShutdown-interface.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,34 @@ +From 2ad226c2f25a9bd0130f5ae8393e719b37a36afc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 02:00:04 +0100 +Subject: include/objidl.idl: Add IApartmentShutdown interface. + +--- + include/objidl.idl | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/include/objidl.idl b/include/objidl.idl +index c18442f..4388bab 100644 +--- a/include/objidl.idl ++++ b/include/objidl.idl +@@ -2451,6 +2451,17 @@ interface IDummyHICONIncluder : IUnknown + HRESULT Dummy([in] HICON hIcon, [in] HDC hdc); + } + ++[ ++ object, ++ local, ++ pointer_default(unique), ++ uuid(a2f05a09-27a2-42b5-bc0e-ac163ef49d9b) ++] ++interface IApartmentShutdown : IUnknown ++{ ++ void OnUninitialize([in] UINT64 identifier); ++} ++ + cpp_quote("#ifdef USE_COM_CONTEXT_DEF") + + typedef DWORD CPFLAGS; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0007-combase-Add-stub-for-RoRegisterForApartmentShutdown.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0007-combase-Add-stub-for-RoRegisterForApartmentShutdown.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0007-combase-Add-stub-for-RoRegisterForApartmentShutdown.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0007-combase-Add-stub-for-RoRegisterForApartmentShutdown.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,66 @@ +From c57255b7bcbe0b456e4934de9fb0efa123e369ef Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 02:01:59 +0100 +Subject: combase: Add stub for RoRegisterForApartmentShutdown. + +--- + .../api-ms-win-core-winrt-l1-1-0.spec | 2 +- + dlls/combase/combase.spec | 2 +- + dlls/combase/roapi.c | 18 ++++++++++++++++++ + 3 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec b/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec +index 88139fb..d27130c 100644 +--- a/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec ++++ b/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec +@@ -3,7 +3,7 @@ + @ stdcall RoGetApartmentIdentifier(ptr) combase.RoGetApartmentIdentifier + @ stdcall RoInitialize(long) combase.RoInitialize + @ stub RoRegisterActivationFactories +-@ stub RoRegisterForApartmentShutdown ++@ stdcall RoRegisterForApartmentShutdown(ptr ptr ptr) combase.RoRegisterForApartmentShutdown + @ stub RoRevokeActivationFactories + @ stdcall RoUninitialize() combase.RoUninitialize + @ stub RoUnregisterForApartmentShutdown +diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec +index 3bf0bf2..7ae1f6e 100644 +--- a/dlls/combase/combase.spec ++++ b/dlls/combase/combase.spec +@@ -263,7 +263,7 @@ + @ stub RoOriginateLanguageException + @ stub RoParameterizedTypeExtraGetTypeSignature + @ stub RoRegisterActivationFactories +-@ stub RoRegisterForApartmentShutdown ++@ stdcall RoRegisterForApartmentShutdown(ptr ptr ptr) + @ stub RoReportCapabilityCheckFailure + @ stub RoReportFailedDelegate + @ stub RoReportUnhandledError +diff --git a/dlls/combase/roapi.c b/dlls/combase/roapi.c +index cd545f1..035fa47 100644 +--- a/dlls/combase/roapi.c ++++ b/dlls/combase/roapi.c +@@ -218,3 +218,21 @@ HRESULT WINAPI RoGetApartmentIdentifier(UINT64 *identifier) + *identifier = 0xdeadbeef; + return S_OK; + } ++ ++/*********************************************************************** ++ * RoRegisterForApartmentShutdown (combase.@) ++ */ ++HRESULT WINAPI RoRegisterForApartmentShutdown(IApartmentShutdown *callback, ++ UINT64 *identifier, APARTMENT_SHUTDOWN_REGISTRATION_COOKIE *cookie) ++{ ++ HRESULT hr; ++ ++ FIXME("(%p, %p, %p): stub\n", callback, identifier, cookie); ++ ++ hr = RoGetApartmentIdentifier(identifier); ++ if (FAILED(hr)) ++ return hr; ++ ++ *cookie = (void *)0xcafecafe; ++ return S_OK; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0008-combase-Add-stub-for-RoGetServerActivatableClasses.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0008-combase-Add-stub-for-RoGetServerActivatableClasses.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0008-combase-Add-stub-for-RoGetServerActivatableClasses.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0008-combase-Add-stub-for-RoGetServerActivatableClasses.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,45 @@ +From ce24c3401d5a103c9cf8e7e6a82cdb61026741fb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 02:03:47 +0100 +Subject: combase: Add stub for RoGetServerActivatableClasses. + +--- + dlls/combase/combase.spec | 2 +- + dlls/combase/roapi.c | 11 +++++++++++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec +index 7ae1f6e..3a17e4a 100644 +--- a/dlls/combase/combase.spec ++++ b/dlls/combase/combase.spec +@@ -254,7 +254,7 @@ + @ stub RoGetErrorReportingFlags + @ stub RoGetMatchingRestrictedErrorInfo + @ stub RoGetParameterizedTypeInstanceIID +-@ stub RoGetServerActivatableClasses ++@ stdcall RoGetServerActivatableClasses(ptr ptr ptr) + @ stdcall RoInitialize(long) + @ stub RoInspectCapturedStackBackTrace + @ stub RoInspectThreadErrorInfo +diff --git a/dlls/combase/roapi.c b/dlls/combase/roapi.c +index 035fa47..832ec67 100644 +--- a/dlls/combase/roapi.c ++++ b/dlls/combase/roapi.c +@@ -236,3 +236,14 @@ HRESULT WINAPI RoRegisterForApartmentShutdown(IApartmentShutdown *callback, + *cookie = (void *)0xcafecafe; + return S_OK; + } ++ ++/*********************************************************************** ++ * RoGetServerActivatableClasses (combase.@) ++ */ ++HRESULT WINAPI RoGetServerActivatableClasses(HSTRING name, HSTRING **classes, DWORD *count) ++{ ++ FIXME("(%s, %p, %p): stub\n", debugstr_hstring(name), classes, count); ++ ++ *count = 0; ++ return S_OK; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0009-combase-Add-stub-for-RoRegisterActivationFactories.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0009-combase-Add-stub-for-RoRegisterActivationFactories.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0009-combase-Add-stub-for-RoRegisterActivationFactories.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0009-combase-Add-stub-for-RoRegisterActivationFactories.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,64 @@ +From b13790d7bcd47d1bf1985258cc3ea6c4edb96d1f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 02:20:39 +0100 +Subject: combase: Add stub for RoRegisterActivationFactories. + +--- + .../api-ms-win-core-winrt-l1-1-0.spec | 2 +- + dlls/combase/combase.spec | 2 +- + dlls/combase/roapi.c | 16 ++++++++++++++++ + 3 files changed, 18 insertions(+), 2 deletions(-) + +diff --git a/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec b/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec +index d27130c..32b9474 100644 +--- a/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec ++++ b/dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec +@@ -2,7 +2,7 @@ + @ stdcall RoGetActivationFactory(ptr ptr ptr) combase.RoGetActivationFactory + @ stdcall RoGetApartmentIdentifier(ptr) combase.RoGetApartmentIdentifier + @ stdcall RoInitialize(long) combase.RoInitialize +-@ stub RoRegisterActivationFactories ++@ stdcall RoRegisterActivationFactories(ptr ptr long ptr) combase.RoRegisterActivationFactories + @ stdcall RoRegisterForApartmentShutdown(ptr ptr ptr) combase.RoRegisterForApartmentShutdown + @ stub RoRevokeActivationFactories + @ stdcall RoUninitialize() combase.RoUninitialize +diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec +index 3a17e4a..7a0decd 100644 +--- a/dlls/combase/combase.spec ++++ b/dlls/combase/combase.spec +@@ -262,7 +262,7 @@ + @ stub RoOriginateErrorW + @ stub RoOriginateLanguageException + @ stub RoParameterizedTypeExtraGetTypeSignature +-@ stub RoRegisterActivationFactories ++@ stdcall RoRegisterActivationFactories(ptr ptr long ptr) + @ stdcall RoRegisterForApartmentShutdown(ptr ptr ptr) + @ stub RoReportCapabilityCheckFailure + @ stub RoReportFailedDelegate +diff --git a/dlls/combase/roapi.c b/dlls/combase/roapi.c +index 832ec67..e8629cd 100644 +--- a/dlls/combase/roapi.c ++++ b/dlls/combase/roapi.c +@@ -247,3 +247,19 @@ HRESULT WINAPI RoGetServerActivatableClasses(HSTRING name, HSTRING **classes, DW + *count = 0; + return S_OK; + } ++ ++/*********************************************************************** ++ * RoRegisterActivationFactories (combase.@) ++ */ ++HRESULT WINAPI RoRegisterActivationFactories(HSTRING *classes, PFNGETACTIVATIONFACTORY *callbacks, ++ UINT32 count, RO_REGISTRATION_COOKIE *cookie) ++{ ++ UINT32 i; ++ ++ FIXME("(%p, %p, %d, %p): stub\n", classes, callbacks, count, cookie); ++ ++ for (i = 0; i < count; i++) ++ FIXME(" %s\n", debugstr_hstring(classes[i])); ++ ++ return S_OK; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0010-combase-Add-stub-for-CleanupTlsOleState.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0010-combase-Add-stub-for-CleanupTlsOleState.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/0010-combase-Add-stub-for-CleanupTlsOleState.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/0010-combase-Add-stub-for-CleanupTlsOleState.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,42 @@ +From 718d3be80d5d8d89f3a120ee6c0a5977390cc26d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 02:21:48 +0100 +Subject: combase: Add stub for CleanupTlsOleState. + +--- + dlls/combase/combase.spec | 2 +- + dlls/combase/roapi.c | 8 ++++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec +index 7a0decd..d03287b 100644 +--- a/dlls/combase/combase.spec ++++ b/dlls/combase/combase.spec +@@ -66,7 +66,7 @@ + @ stdcall CLSIDFromProgID(wstr ptr) ole32.CLSIDFromProgID + @ stdcall CLSIDFromString(wstr ptr) ole32.CLSIDFromString + @ stub CleanupOleStateInAllTls +-@ stub CleanupTlsOleState ++@ stdcall CleanupTlsOleState(ptr) + @ stub ClearCleanupFlag + @ stdcall CoAddRefServerProcess() ole32.CoAddRefServerProcess + @ stub CoAllowUnmarshalerCLSID +diff --git a/dlls/combase/roapi.c b/dlls/combase/roapi.c +index e8629cd..e838412 100644 +--- a/dlls/combase/roapi.c ++++ b/dlls/combase/roapi.c +@@ -263,3 +263,11 @@ HRESULT WINAPI RoRegisterActivationFactories(HSTRING *classes, PFNGETACTIVATIONF + + return S_OK; + } ++ ++/*********************************************************************** ++ * CleanupTlsOleState (combase.@) ++ */ ++void WINAPI CleanupTlsOleState(void *unknown) ++{ ++ FIXME("(%p): stub\n", unknown); ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/definition wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-RoApi/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-RoApi/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,3 @@ +Fixes: Implement semi-stub for RoGetActivationFactory +Fixes: Implement semi-stub for RoActivateInstance +Fixes: Implement stubs for further combase Ro* functions diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/0001-combase-Implement-WindowsCompareStringOrdinal.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/0001-combase-Implement-WindowsCompareStringOrdinal.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/0001-combase-Implement-WindowsCompareStringOrdinal.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/0001-combase-Implement-WindowsCompareStringOrdinal.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,94 @@ +From 70e8a8c08aa3ef0ac48d267d5917f998f4f09b16 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 16 Jan 2016 16:12:47 +0100 +Subject: combase: Implement WindowsCompareStringOrdinal. (v2) + +--- + .../api-ms-win-core-winrt-string-l1-1-0.spec | 2 +- + dlls/combase/combase.spec | 2 +- + dlls/combase/string.c | 33 ++++++++++++++++++++++ + include/winnls.h | 1 + + 4 files changed, 36 insertions(+), 2 deletions(-) + +diff --git a/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec b/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec +index fa048d8..1b661aa 100644 +--- a/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec ++++ b/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec +@@ -6,7 +6,7 @@ + @ stub HSTRING_UserSize64 + @ stub HSTRING_UserUnmarshal + @ stub HSTRING_UserUnmarshal64 +-@ stub WindowsCompareStringOrdinal ++@ stdcall WindowsCompareStringOrdinal(ptr ptr ptr) combase.WindowsCompareStringOrdinal + @ stdcall WindowsConcatString(ptr ptr ptr) combase.WindowsConcatString + @ stdcall WindowsCreateString(wstr long ptr) combase.WindowsCreateString + @ stdcall WindowsCreateStringReference(wstr long ptr ptr) combase.WindowsCreateStringReference +diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec +index 5082f39..430ca95 100644 +--- a/dlls/combase/combase.spec ++++ b/dlls/combase/combase.spec +@@ -287,7 +287,7 @@ + @ stub WdtpInterfacePointer_UserSize64 + @ stdcall WdtpInterfacePointer_UserUnmarshal(ptr ptr ptr ptr) ole32.WdtpInterfacePointer_UserUnmarshal + @ stub WdtpInterfacePointer_UserUnmarshal64 +-@ stub WindowsCompareStringOrdinal ++@ stdcall WindowsCompareStringOrdinal(ptr ptr ptr) + @ stdcall WindowsConcatString(ptr ptr ptr) + @ stdcall WindowsCreateString(wstr long ptr) + @ stdcall WindowsCreateStringReference(wstr long ptr ptr) +diff --git a/dlls/combase/string.c b/dlls/combase/string.c +index dd7c8e9..bd18a73 100644 +--- a/dlls/combase/string.c ++++ b/dlls/combase/string.c +@@ -372,3 +372,36 @@ BOOL WINAPI WindowsIsStringEmpty(HSTRING str) + return TRUE; + return priv->length == 0; + } ++ ++/*********************************************************************** ++ * WindowsCompareStringOrdinal (combase.@) ++ */ ++HRESULT WINAPI WindowsCompareStringOrdinal(HSTRING str1, HSTRING str2, INT32 *res) ++{ ++ struct hstring_private *priv1 = impl_from_HSTRING(str1); ++ struct hstring_private *priv2 = impl_from_HSTRING(str2); ++ const WCHAR *buf1 = empty, *buf2 = empty; ++ UINT32 len1 = 0, len2 = 0; ++ ++ TRACE("(%p, %p, %p)\n", str1, str2, res); ++ ++ if (res == NULL) ++ return E_INVALIDARG; ++ if (str1 == str2) ++ { ++ *res = 0; ++ return S_OK; ++ } ++ if (str1) ++ { ++ buf1 = priv1->buffer; ++ len1 = priv1->length; ++ } ++ if (str2) ++ { ++ buf2 = priv2->buffer; ++ len2 = priv2->length; ++ } ++ *res = CompareStringOrdinal(buf1, len1, buf2, len2, FALSE) - CSTR_EQUAL; ++ return S_OK; ++} +diff --git a/include/winnls.h b/include/winnls.h +index 4b4eb77..0370572 100644 +--- a/include/winnls.h ++++ b/include/winnls.h +@@ -831,6 +831,7 @@ WINBASEAPI INT WINAPI CompareStringA(LCID,DWORD,LPCSTR,INT,LPCSTR,INT); + WINBASEAPI INT WINAPI CompareStringW(LCID,DWORD,LPCWSTR,INT,LPCWSTR,INT); + #define CompareString WINELIB_NAME_AW(CompareString) + WINBASEAPI INT WINAPI CompareStringEx(LPCWSTR,DWORD,LPCWSTR,INT,LPCWSTR,INT,LPNLSVERSIONINFO,LPVOID,LPARAM); ++WINBASEAPI INT WINAPI CompareStringOrdinal(const WCHAR *,INT,const WCHAR *,INT,BOOL); + WINBASEAPI LCID WINAPI ConvertDefaultLocale(LCID); + WINBASEAPI BOOL WINAPI EnumCalendarInfoA(CALINFO_ENUMPROCA,LCID,CALID,CALTYPE); + WINBASEAPI BOOL WINAPI EnumCalendarInfoW(CALINFO_ENUMPROCW,LCID,CALID,CALTYPE); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/0002-combase-tests-Add-tests-for-WindowsCompareStringOrdi.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/0002-combase-tests-Add-tests-for-WindowsCompareStringOrdi.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/0002-combase-tests-Add-tests-for-WindowsCompareStringOrdi.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/0002-combase-tests-Add-tests-for-WindowsCompareStringOrdi.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,105 @@ +From aa2897cf754969a7108c4b139f03bfb95c4a5ddb Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 16 Jan 2016 16:13:45 +0100 +Subject: combase/tests: Add tests for WindowsCompareStringOrdinal. + +--- + dlls/combase/tests/string.c | 63 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 63 insertions(+) + +diff --git a/dlls/combase/tests/string.c b/dlls/combase/tests/string.c +index 8e112c3..db6c8f5 100644 +--- a/dlls/combase/tests/string.c ++++ b/dlls/combase/tests/string.c +@@ -27,6 +27,7 @@ + + #include "wine/test.h" + ++static HRESULT (WINAPI *pWindowsCompareStringOrdinal)(HSTRING, HSTRING, INT32 *); + static HRESULT (WINAPI *pWindowsConcatString)(HSTRING, HSTRING, HSTRING *); + static HRESULT (WINAPI *pWindowsCreateString)(LPCWSTR, UINT32, HSTRING *); + static HRESULT (WINAPI *pWindowsCreateStringReference)(LPCWSTR, UINT32, HSTRING_HEADER *, HSTRING *); +@@ -52,6 +53,7 @@ static BOOL init_functions(void) + win_skip("Failed to load combase.dll, skipping tests\n"); + return FALSE; + } ++ SET(WindowsCompareStringOrdinal); + SET(WindowsConcatString); + SET(WindowsCreateString); + SET(WindowsCreateStringReference); +@@ -394,6 +396,66 @@ static void test_concat(void) + ok(concat == NULL, "Concatenate created new string\n"); + } + ++static void test_compare(void) ++{ ++ HSTRING str1, str2; ++ HSTRING_HEADER header1, header2; ++ INT32 res; ++ ++ /* Test comparison of string buffers */ ++ ok(pWindowsCreateString(input_string1, 3, &str1) == S_OK, "Failed to create string\n"); ++ ok(pWindowsCreateString(input_string2, 3, &str2) == S_OK, "Failed to create string\n"); ++ ++ ok(pWindowsCompareStringOrdinal(str1, str1, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == 0, "Expected 0, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(str1, str2, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == -1, "Expected -1, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(str2, str1, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == 1, "Expected 1, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(str2, str2, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == 0, "Expected 0, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(str1, NULL, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == 1, "Expected 1, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(NULL, str1, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == -1, "Expected -1, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(str2, NULL, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == 1, "Expected 1, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(NULL, str2, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == -1, "Expected -1, got %d\n", res); ++ ++ ok(pWindowsDeleteString(str2) == S_OK, "Failed to delete string\n"); ++ ok(pWindowsDeleteString(str1) == S_OK, "Failed to delete string\n"); ++ ++ /* Test comparison of string references */ ++ ok(pWindowsCreateStringReference(input_string1, 3, &header1, &str1) == S_OK, "Failed to create string ref\n"); ++ ok(pWindowsCreateStringReference(input_string2, 3, &header2, &str2) == S_OK, "Failed to create string ref\n"); ++ ++ ok(pWindowsCompareStringOrdinal(str1, str1, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == 0, "Expected 0, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(str1, str2, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == -1, "Expected -1, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(str2, str1, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == 1, "Expected 1, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(str2, str2, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == 0, "Expected 0, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(str1, NULL, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == 1, "Expected 1, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(NULL, str1, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == -1, "Expected -1, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(str2, NULL, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == 1, "Expected 1, got %d\n", res); ++ ok(pWindowsCompareStringOrdinal(NULL, str2, &res) == S_OK, "Failed to compare string\n"); ++ ok(res == -1, "Expected -1, got %d\n", res); ++ ++ ok(pWindowsDeleteString(str2) == S_OK, "Failed to delete string ref\n"); ++ ok(pWindowsDeleteString(str1) == S_OK, "Failed to delete string ref\n"); ++ ++ /* Test comparison of two empty strings */ ++ ok(pWindowsCompareStringOrdinal(NULL, NULL, NULL) == E_INVALIDARG, "Incorrect error handling\n"); ++ ok(pWindowsCompareStringOrdinal(NULL, NULL, &res) == S_OK, "Failed to compare NULL string\n"); ++ ok(res == 0, "Expected 0, got %d\n", res); ++} ++ + START_TEST(string) + { + if (!init_functions()) +@@ -404,4 +466,5 @@ START_TEST(string) + test_string_buffer(); + test_substring(); + test_concat(); ++ test_compare(); + } +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/0003-combase-Implement-WindowsTrimStringStart.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/0003-combase-Implement-WindowsTrimStringStart.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/0003-combase-Implement-WindowsTrimStringStart.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/0003-combase-Implement-WindowsTrimStringStart.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,77 @@ +From 6b4166e822951ced51c2ac5637f37427a3a640a5 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sun, 17 Jan 2016 05:55:43 +0100 +Subject: combase: Implement WindowsTrimStringStart. + +--- + .../api-ms-win-core-winrt-string-l1-1-0.spec | 2 +- + dlls/combase/combase.spec | 2 +- + dlls/combase/string.c | 28 ++++++++++++++++++++++ + 3 files changed, 30 insertions(+), 2 deletions(-) + +diff --git a/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec b/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec +index 1b661aa..fe63810 100644 +--- a/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec ++++ b/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec +@@ -24,4 +24,4 @@ + @ stdcall WindowsSubstring(ptr long ptr) combase.WindowsSubstring + @ stdcall WindowsSubstringWithSpecifiedLength(ptr long long ptr) combase.WindowsSubstringWithSpecifiedLength + @ stub WindowsTrimStringEnd +-@ stub WindowsTrimStringStart ++@ stdcall WindowsTrimStringStart(ptr ptr ptr) combase.WindowsTrimStringStart +diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec +index 430ca95..69f47d0 100644 +--- a/dlls/combase/combase.spec ++++ b/dlls/combase/combase.spec +@@ -305,4 +305,4 @@ + @ stdcall WindowsSubstring(ptr long ptr) + @ stdcall WindowsSubstringWithSpecifiedLength(ptr long long ptr) + @ stub WindowsTrimStringEnd +-@ stub WindowsTrimStringStart ++@ stdcall WindowsTrimStringStart(ptr ptr ptr) +diff --git a/dlls/combase/string.c b/dlls/combase/string.c +index bd18a73..868411c 100644 +--- a/dlls/combase/string.c ++++ b/dlls/combase/string.c +@@ -21,6 +21,7 @@ + #include "windows.h" + #include "winerror.h" + #include "hstring.h" ++#include "wine/unicode.h" + #include "wine/debug.h" + + WINE_DEFAULT_DEBUG_CHANNEL(winstring); +@@ -405,3 +406,30 @@ HRESULT WINAPI WindowsCompareStringOrdinal(HSTRING str1, HSTRING str2, INT32 *re + *res = CompareStringOrdinal(buf1, len1, buf2, len2, FALSE) - CSTR_EQUAL; + return S_OK; + } ++ ++/*********************************************************************** ++ * WindowsTrimStringStart (combase.@) ++ */ ++HRESULT WINAPI WindowsTrimStringStart(HSTRING str1, HSTRING str2, HSTRING *out) ++{ ++ struct hstring_private *priv1 = impl_from_HSTRING(str1); ++ struct hstring_private *priv2 = impl_from_HSTRING(str2); ++ UINT32 start = 0; ++ ++ TRACE("(%p, %p, %p)\n", str1, str2, out); ++ ++ if (!out || !str2 || !priv2->length) ++ return E_INVALIDARG; ++ if (!str1) ++ { ++ *out = NULL; ++ return S_OK; ++ } ++ for (start = 0; start < priv1->length; start++) ++ { ++ if (!memchrW(priv2->buffer, priv1->buffer[start], priv2->length)) ++ break; ++ } ++ return start ? WindowsCreateString(&priv1->buffer[start], priv1->length - start, out) : ++ WindowsDuplicateString(str1, out); ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/0004-combase-Implement-WindowsTrimStringEnd.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/0004-combase-Implement-WindowsTrimStringEnd.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/0004-combase-Implement-WindowsTrimStringEnd.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/0004-combase-Implement-WindowsTrimStringEnd.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,71 @@ +From ea49da0c37d81de96f1789306cca9322cf93e3e5 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sun, 17 Jan 2016 05:56:50 +0100 +Subject: combase: Implement WindowsTrimStringEnd. + +--- + .../api-ms-win-core-winrt-string-l1-1-0.spec | 2 +- + dlls/combase/combase.spec | 2 +- + dlls/combase/string.c | 27 ++++++++++++++++++++++ + 3 files changed, 29 insertions(+), 2 deletions(-) + +diff --git a/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec b/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec +index fe63810..8b60a91 100644 +--- a/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec ++++ b/dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec +@@ -23,5 +23,5 @@ + @ stdcall WindowsStringHasEmbeddedNull(ptr ptr) combase.WindowsStringHasEmbeddedNull + @ stdcall WindowsSubstring(ptr long ptr) combase.WindowsSubstring + @ stdcall WindowsSubstringWithSpecifiedLength(ptr long long ptr) combase.WindowsSubstringWithSpecifiedLength +-@ stub WindowsTrimStringEnd ++@ stdcall WindowsTrimStringEnd(ptr ptr ptr) combase.WindowsTrimStringEnd + @ stdcall WindowsTrimStringStart(ptr ptr ptr) combase.WindowsTrimStringStart +diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec +index 69f47d0..4bda470 100644 +--- a/dlls/combase/combase.spec ++++ b/dlls/combase/combase.spec +@@ -304,5 +304,5 @@ + @ stdcall WindowsStringHasEmbeddedNull(ptr ptr) + @ stdcall WindowsSubstring(ptr long ptr) + @ stdcall WindowsSubstringWithSpecifiedLength(ptr long long ptr) +-@ stub WindowsTrimStringEnd ++@ stdcall WindowsTrimStringEnd(ptr ptr ptr) + @ stdcall WindowsTrimStringStart(ptr ptr ptr) +diff --git a/dlls/combase/string.c b/dlls/combase/string.c +index 868411c..56d84ad 100644 +--- a/dlls/combase/string.c ++++ b/dlls/combase/string.c +@@ -433,3 +433,30 @@ HRESULT WINAPI WindowsTrimStringStart(HSTRING str1, HSTRING str2, HSTRING *out) + return start ? WindowsCreateString(&priv1->buffer[start], priv1->length - start, out) : + WindowsDuplicateString(str1, out); + } ++ ++/*********************************************************************** ++ * WindowsTrimStringEnd (combase.@) ++ */ ++HRESULT WINAPI WindowsTrimStringEnd(HSTRING str1, HSTRING str2, HSTRING *out) ++{ ++ struct hstring_private *priv1 = impl_from_HSTRING(str1); ++ struct hstring_private *priv2 = impl_from_HSTRING(str2); ++ UINT32 len; ++ ++ TRACE("(%p, %p, %p)\n", str1, str2, out); ++ ++ if (!out || !str2 || !priv2->length) ++ return E_INVALIDARG; ++ if (!str1) ++ { ++ *out = NULL; ++ return S_OK; ++ } ++ for (len = priv1->length; len > 0; len--) ++ { ++ if (!memchrW(priv2->buffer, priv1->buffer[len - 1], priv2->length)) ++ break; ++ } ++ return (len < priv1->length) ? WindowsCreateString(priv1->buffer, len, out) : ++ WindowsDuplicateString(str1, out); ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/0005-combase-tests-Add-tests-for-WindowsTrimString-Start-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/0005-combase-tests-Add-tests-for-WindowsTrimString-Start-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/0005-combase-tests-Add-tests-for-WindowsTrimString-Start-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/0005-combase-tests-Add-tests-for-WindowsTrimString-Start-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,119 @@ +From 6a3505cc0e0a632cdf9fb10c0b38b8f0a435a13d Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sun, 17 Jan 2016 05:58:08 +0100 +Subject: combase/tests: Add tests for WindowsTrimString{Start,End}. + +--- + dlls/combase/tests/string.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 77 insertions(+) + +diff --git a/dlls/combase/tests/string.c b/dlls/combase/tests/string.c +index db6c8f5..ac6c587 100644 +--- a/dlls/combase/tests/string.c ++++ b/dlls/combase/tests/string.c +@@ -42,6 +42,8 @@ static HRESULT (WINAPI *pWindowsPromoteStringBuffer)(HSTRING_BUFFER, HSTRING *); + static HRESULT (WINAPI *pWindowsStringHasEmbeddedNull)(HSTRING, BOOL *); + static HRESULT (WINAPI *pWindowsSubstring)(HSTRING, UINT32, HSTRING *); + static HRESULT (WINAPI *pWindowsSubstringWithSpecifiedLength)(HSTRING, UINT32, UINT32, HSTRING *); ++static HRESULT (WINAPI *pWindowsTrimStringEnd)(HSTRING, HSTRING, HSTRING *); ++static HRESULT (WINAPI *pWindowsTrimStringStart)(HSTRING, HSTRING, HSTRING *); + + #define SET(x) p##x = (void*)GetProcAddress(hmod, #x) + +@@ -68,6 +70,8 @@ static BOOL init_functions(void) + SET(WindowsStringHasEmbeddedNull); + SET(WindowsSubstring); + SET(WindowsSubstringWithSpecifiedLength); ++ SET(WindowsTrimStringEnd); ++ SET(WindowsTrimStringStart); + return TRUE; + } + +@@ -456,6 +460,78 @@ static void test_compare(void) + ok(res == 0, "Expected 0, got %d\n", res); + } + ++static void test_trim(void) ++{ ++ HSTRING str1, str2, trimmed; ++ HSTRING_HEADER header1, header2; ++ ++ /* Test trimming of string buffers */ ++ ok(pWindowsCreateString(input_string, 6, &str1) == S_OK, "Failed to create string\n"); ++ ok(pWindowsCreateString(input_string1, 3, &str2) == S_OK, "Failed to create string\n"); ++ ++ ok(pWindowsTrimStringStart(str1, str2, &trimmed) == S_OK, "Failed to trim string\n"); ++ check_string(trimmed, input_string2, 3, FALSE); ++ ok(pWindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n"); ++ ok(pWindowsTrimStringEnd(str1, str2, &trimmed) == S_OK, "Failed to trim string\n"); ++ ok(trimmed == str1, "Trimmed string created new string\n"); ++ check_string(trimmed, input_string, 6, FALSE); ++ ok(pWindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n"); ++ ++ ok(pWindowsDeleteString(str2) == S_OK, "Failed to delete string\n"); ++ ok(pWindowsCreateString(input_string2, 3, &str2) == S_OK, "Failed to create string\n"); ++ ++ ok(pWindowsTrimStringStart(str1, str2, &trimmed) == S_OK, "Failed to trim string\n"); ++ ok(trimmed == str1, "Trimmed string created new string\n"); ++ check_string(trimmed, input_string, 6, FALSE); ++ ok(pWindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n"); ++ ok(pWindowsTrimStringEnd(str1, str2, &trimmed) == S_OK, "Failed to trim string\n"); ++ check_string(trimmed, input_string1, 3, FALSE); ++ ok(pWindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n"); ++ ++ ok(pWindowsDeleteString(str2) == S_OK, "Failed to delete string\n"); ++ ok(pWindowsDeleteString(str1) == S_OK, "Failed to delete string\n"); ++ ++ /* Test trimming of string references */ ++ ok(pWindowsCreateStringReference(input_string, 6, &header1, &str1) == S_OK, "Failed to create string ref\n"); ++ ok(pWindowsCreateStringReference(input_string1, 3, &header2, &str2) == S_OK, "Failed to create string ref\n"); ++ ++ ok(pWindowsTrimStringStart(str1, str2, &trimmed) == S_OK, "Failed to trim string\n"); ++ check_string(trimmed, input_string2, 3, FALSE); ++ ok(pWindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n"); ++ ok(pWindowsTrimStringEnd(str1, str2, &trimmed) == S_OK, "Failed to trim string\n"); ++ ok(trimmed != str1, "Trimmed string ref didn't create new string\n"); ++ check_string(trimmed, input_string, 6, FALSE); ++ ok(pWindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n"); ++ ++ ok(pWindowsDeleteString(str2) == S_OK, "Failed to delete string ref\n"); ++ ok(pWindowsCreateStringReference(input_string2, 3, &header2, &str2) == S_OK, "Failed to create string ref\n"); ++ ++ ok(pWindowsTrimStringStart(str1, str2, &trimmed) == S_OK, "Failed to trim string\n"); ++ ok(trimmed != str1, "Trimmed string ref didn't create new string\n"); ++ check_string(trimmed, input_string, 6, FALSE); ++ ok(pWindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n"); ++ ok(pWindowsTrimStringEnd(str1, str2, &trimmed) == S_OK, "Failed to trim string\n"); ++ check_string(trimmed, input_string1, 3, FALSE); ++ ok(pWindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n"); ++ ++ ok(pWindowsDeleteString(str2) == S_OK, "Failed to delete string ref\n"); ++ ok(pWindowsDeleteString(str1) == S_OK, "Failed to delete string ref\n"); ++ ++ /* Test handling of a NULL string */ ++ ok(pWindowsCreateString(input_string, 6, &str1) == S_OK, "Failed to create string\n"); ++ ok(pWindowsTrimStringStart(NULL, NULL, NULL) == E_INVALIDARG, "Incorrect error handling\n"); ++ ok(pWindowsTrimStringStart(NULL, str1, NULL) == E_INVALIDARG, "Incorrect error handling\n"); ++ ok(pWindowsTrimStringStart(NULL, NULL, &trimmed) == E_INVALIDARG, "Incorrect error handling\n"); ++ ok(pWindowsTrimStringStart(NULL, str1, &trimmed) == S_OK, "Failed to trim empty string\n"); ++ ok(trimmed == NULL, "Trimming created new string\n"); ++ ok(pWindowsTrimStringEnd(NULL, NULL, NULL) == E_INVALIDARG, "Incorrect error handling\n"); ++ ok(pWindowsTrimStringEnd(NULL, str1, NULL) == E_INVALIDARG, "Incorrect error handling\n"); ++ ok(pWindowsTrimStringEnd(NULL, NULL, &trimmed) == E_INVALIDARG, "Incorrect error handling\n"); ++ ok(pWindowsTrimStringEnd(NULL, str1, &trimmed) == S_OK, "Failed to trim empty string\n"); ++ ok(trimmed == NULL, "Trimming created new string\n"); ++ ok(pWindowsDeleteString(str1) == S_OK, "Failed to delete string\n"); ++} ++ + START_TEST(string) + { + if (!init_functions()) +@@ -467,4 +543,5 @@ START_TEST(string) + test_substring(); + test_concat(); + test_compare(); ++ test_trim(); + } +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/definition wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/combase-WindowsString/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/combase-WindowsString/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,3 @@ +Fixes: Implement combase.WindowsCompareStringOrdinal +Fixes: Implement combase.WindowsTrimStringStart +Fixes: Implement combase.WindowsTrimStringEnd diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/comctl32-TTM_ADDTOOLW/0001-comctl32-tooltip-Protect-TTM_ADDTOOLW-from-invalid-t.patch wine-staging-1.9.3~ubuntu12.04.1/patches/comctl32-TTM_ADDTOOLW/0001-comctl32-tooltip-Protect-TTM_ADDTOOLW-from-invalid-t.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/comctl32-TTM_ADDTOOLW/0001-comctl32-tooltip-Protect-TTM_ADDTOOLW-from-invalid-t.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/comctl32-TTM_ADDTOOLW/0001-comctl32-tooltip-Protect-TTM_ADDTOOLW-from-invalid-t.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,90 @@ +From 6a2ce8e894076cbc50ec1cda81fd00ad6d7ea68c Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Thu, 14 Jan 2016 17:56:00 +1100 +Subject: comctl32/tooltip: Protect TTM_ADDTOOLW from invalid text pointers + +Fixes https://bugs.winehq.org/show_bug.cgi?id=10347 + +Signed-off-by: Alistair Leslie-Hughes +--- + dlls/comctl32/tests/tooltips.c | 27 +++++++++++++++++++++++++++ + dlls/comctl32/tooltips.c | 18 ++++++++++++++---- + 2 files changed, 41 insertions(+), 4 deletions(-) + +diff --git a/dlls/comctl32/tests/tooltips.c b/dlls/comctl32/tests/tooltips.c +index 3382fce..2a0f855 100644 +--- a/dlls/comctl32/tests/tooltips.c ++++ b/dlls/comctl32/tests/tooltips.c +@@ -446,6 +446,33 @@ static void test_gettext(void) + r = SendMessageW(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&toolinfoW); + ok(!r, "Adding the tool to the tooltip succeeded!\n"); + ++ /* lpszText with an invalid address */ ++ toolinfoW.cbSize = sizeof(TTTOOLINFOW); ++ toolinfoW.hwnd = notify; ++ toolinfoW.hinst = GetModuleHandleA(NULL); ++ toolinfoW.uFlags = 0; ++ toolinfoW.uId = 0; ++ toolinfoW.lpszText = (LPWSTR)0xdeadbeef; ++ toolinfoW.lParam = 0; ++ GetClientRect(hwnd, &toolinfoW.rect); ++ r = SendMessageA(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&toolinfoW); ++ ok(!r, "Adding the tool to the tooltip succeeded!\n"); ++ ++ /* lpszText with an invalid address. Crashes using TTTOOLINFOA message */ ++ if(0) ++ { ++ toolinfoA.cbSize = sizeof(TTTOOLINFOA); ++ toolinfoA.hwnd = notify; ++ toolinfoA.hinst = GetModuleHandleA(NULL); ++ toolinfoA.uFlags = 0; ++ toolinfoA.uId = 0; ++ toolinfoA.lpszText = (LPSTR)0xdeadbeef; ++ toolinfoA.lParam = 0; ++ GetClientRect(hwnd, &toolinfoA.rect); ++ r = SendMessageA(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&toolinfoA); ++ ok(!r, "Adding the tool to the tooltip succeeded!\n"); ++ } ++ + if (0) /* crashes on NT4 */ + { + toolinfoW.hwnd = NULL; +diff --git a/dlls/comctl32/tooltips.c b/dlls/comctl32/tooltips.c +index 8bf6919..eea1d2e 100644 +--- a/dlls/comctl32/tooltips.c ++++ b/dlls/comctl32/tooltips.c +@@ -103,6 +103,7 @@ + #include "commctrl.h" + #include "comctl32.h" + #include "wine/debug.h" ++#include "wine/exception.h" + + WINE_DEFAULT_DEBUG_CHANNEL(tooltips); + +@@ -1076,10 +1077,19 @@ TOOLTIPS_AddToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW) + toolPtr->lpszText = LPSTR_TEXTCALLBACKW; + } + else if (isW) { +- INT len = lstrlenW (ti->lpszText); +- TRACE("add text %s!\n", debugstr_w(ti->lpszText)); +- toolPtr->lpszText = Alloc ((len + 1)*sizeof(WCHAR)); +- strcpyW (toolPtr->lpszText, ti->lpszText); ++ __TRY ++ { ++ INT len = lstrlenW (ti->lpszText); ++ TRACE("add text %s!\n", debugstr_w(ti->lpszText)); ++ toolPtr->lpszText = Alloc ((len + 1)*sizeof(WCHAR)); ++ strcpyW (toolPtr->lpszText, ti->lpszText); ++ } ++ __EXCEPT_PAGE_FAULT ++ { ++ WARN("Invalid lpszText.\n"); ++ return FALSE; ++ } ++ __ENDTRY + } + else { + INT len = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ti->lpszText, -1, NULL, 0); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/comctl32-TTM_ADDTOOLW/definition wine-staging-1.9.3~ubuntu12.04.1/patches/comctl32-TTM_ADDTOOLW/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/comctl32-TTM_ADDTOOLW/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/comctl32-TTM_ADDTOOLW/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [10347] Protect TTM_ADDTOOLW from invalid text pointers diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_24-ID3DXEffect/0001-d3dx9_24-Add-an-interface-wrapper-for-different-vers.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_24-ID3DXEffect/0001-d3dx9_24-Add-an-interface-wrapper-for-different-vers.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_24-ID3DXEffect/0001-d3dx9_24-Add-an-interface-wrapper-for-different-vers.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_24-ID3DXEffect/0001-d3dx9_24-Add-an-interface-wrapper-for-different-vers.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 103ca35d4ed896961341134083aea44ff7267cd2 Mon Sep 17 00:00:00 2001 +From 07b257223fda63414f00f3a658fcdce83a7991e4 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 14 Mar 2015 05:01:05 +0100 Subject: d3dx9_24: Add an interface wrapper for different version of @@ -9,7 +9,7 @@ 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dlls/d3dx9_24/d3dx9_24.spec b/dlls/d3dx9_24/d3dx9_24.spec -index f111618..d1c5b21 100644 +index cfe26ce..1ddf219 100644 --- a/dlls/d3dx9_24/d3dx9_24.spec +++ b/dlls/d3dx9_24/d3dx9_24.spec @@ -43,21 +43,21 @@ @@ -17,7 +17,7 @@ @ stdcall D3DXCreateCubeTextureFromResourceW(ptr long ptr ptr) d3dx9_36.D3DXCreateCubeTextureFromResourceW @ stdcall D3DXCreateCylinder(ptr long long long long long ptr ptr) d3dx9_36.D3DXCreateCylinder -@ stdcall D3DXCreateEffect(ptr ptr long ptr ptr long ptr ptr ptr) d3dx9_36.D3DXCreateEffect -+@ stdcall D3DXCreateEffect(ptr ptr long ptr ptr long ptr ptr ptr) d3dx9_25.D3DXCreateEffect ++@ stdcall D3DXCreateEffect(ptr ptr long ptr ptr long ptr ptr ptr) d3dx9_25.D3DXCreateEffect # don't forward @ stdcall D3DXCreateEffectCompiler(ptr long ptr ptr long ptr ptr) d3dx9_36.D3DXCreateEffectCompiler @ stdcall D3DXCreateEffectCompilerFromFileA(str ptr ptr long ptr ptr) d3dx9_36.D3DXCreateEffectCompilerFromFileA @ stdcall D3DXCreateEffectCompilerFromFileW(wstr ptr ptr long ptr ptr) d3dx9_36.D3DXCreateEffectCompilerFromFileW @@ -32,15 +32,15 @@ -@ stdcall D3DXCreateEffectFromResourceExA(ptr long str ptr ptr str long ptr ptr ptr) d3dx9_36.D3DXCreateEffectFromResourceExA -@ stdcall D3DXCreateEffectFromResourceExW(ptr long str ptr ptr str long ptr ptr ptr) d3dx9_36.D3DXCreateEffectFromResourceExW -@ stdcall D3DXCreateEffectFromResourceW(ptr long wstr ptr ptr long ptr ptr ptr) d3dx9_36.D3DXCreateEffectFromResourceW -+@ stdcall D3DXCreateEffectEx(ptr ptr long ptr ptr str long ptr ptr ptr) d3dx9_25.D3DXCreateEffectEx -+@ stdcall D3DXCreateEffectFromFileA(ptr str ptr ptr long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromFileA -+@ stdcall D3DXCreateEffectFromFileExA(ptr str ptr ptr str long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromFileExA -+@ stdcall D3DXCreateEffectFromFileExW(ptr str ptr ptr str long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromFileExW -+@ stdcall D3DXCreateEffectFromFileW(ptr wstr ptr ptr long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromFileW -+@ stdcall D3DXCreateEffectFromResourceA(ptr long str ptr ptr long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromResourceA -+@ stdcall D3DXCreateEffectFromResourceExA(ptr long str ptr ptr str long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromResourceExA -+@ stdcall D3DXCreateEffectFromResourceExW(ptr long str ptr ptr str long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromResourceExW -+@ stdcall D3DXCreateEffectFromResourceW(ptr long wstr ptr ptr long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromResourceW ++@ stdcall D3DXCreateEffectEx(ptr ptr long ptr ptr str long ptr ptr ptr) d3dx9_25.D3DXCreateEffectEx # don't forward ++@ stdcall D3DXCreateEffectFromFileA(ptr str ptr ptr long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromFileA # don't forward ++@ stdcall D3DXCreateEffectFromFileExA(ptr str ptr ptr str long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromFileExA # don't forward ++@ stdcall D3DXCreateEffectFromFileExW(ptr str ptr ptr str long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromFileExW # don't forward ++@ stdcall D3DXCreateEffectFromFileW(ptr wstr ptr ptr long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromFileW # don't forward ++@ stdcall D3DXCreateEffectFromResourceA(ptr long str ptr ptr long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromResourceA # don't forward ++@ stdcall D3DXCreateEffectFromResourceExA(ptr long str ptr ptr str long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromResourceExA # don't forward ++@ stdcall D3DXCreateEffectFromResourceExW(ptr long str ptr ptr str long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromResourceExW # don't forward ++@ stdcall D3DXCreateEffectFromResourceW(ptr long wstr ptr ptr long ptr ptr ptr) d3dx9_25.D3DXCreateEffectFromResourceW # don't forward @ stdcall D3DXCreateEffectPool(ptr) d3dx9_36.D3DXCreateEffectPool @ stdcall D3DXCreateFontA(ptr long long long long long long long long long str ptr) d3dx9_36.D3DXCreateFontA @ stdcall D3DXCreateFontIndirectA(ptr ptr ptr) d3dx9_36.D3DXCreateFontIndirectA @@ -49,10 +49,10 @@ @ stdcall D3DXDebugMute(long) d3dx9_36.D3DXDebugMute @ stdcall D3DXDeclaratorFromFVF(long ptr) d3dx9_36.D3DXDeclaratorFromFVF -@ stdcall D3DXDisassembleEffect(ptr long ptr) d3dx9_36.D3DXDisassembleEffect -+@ stdcall D3DXDisassembleEffect(ptr long ptr) d3dx9_25.D3DXDisassembleEffect ++@ stdcall D3DXDisassembleEffect(ptr long ptr) d3dx9_25.D3DXDisassembleEffect # don't forward @ stdcall D3DXDisassembleShader(ptr long str ptr) d3dx9_36.D3DXDisassembleShader @ stdcall D3DXFileCreate(ptr) d3dx9_36.D3DXFileCreate @ stdcall D3DXFillCubeTexture(ptr ptr ptr) d3dx9_36.D3DXFillCubeTexture -- -2.3.2 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_25-ID3DXEffect/0001-d3dx9_25-Add-an-interface-wrapper-for-different-vers.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_25-ID3DXEffect/0001-d3dx9_25-Add-an-interface-wrapper-for-different-vers.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_25-ID3DXEffect/0001-d3dx9_25-Add-an-interface-wrapper-for-different-vers.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_25-ID3DXEffect/0001-d3dx9_25-Add-an-interface-wrapper-for-different-vers.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From f6cede1ccb8f108b155b52211f1f1555f0c6935a Mon Sep 17 00:00:00 2001 +From 4a59723740ee7f599520d75ce8a019504629091d Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 14 Mar 2015 04:48:38 +0100 Subject: d3dx9_25: Add an interface wrapper for different version of @@ -8,8 +8,7 @@ dlls/d3dx9_25/Makefile.in | 5 +- dlls/d3dx9_25/d3dx9_25.spec | 22 +- dlls/d3dx9_25/effect.c | 1282 +++++++++++++++++++++++++++++++++++++++++++ - include/d3dx9effect.h | 2 + - 4 files changed, 1298 insertions(+), 13 deletions(-) + 3 files changed, 1296 insertions(+), 13 deletions(-) create mode 100644 dlls/d3dx9_25/effect.c diff --git a/dlls/d3dx9_25/Makefile.in b/dlls/d3dx9_25/Makefile.in @@ -28,7 +27,7 @@ RC_SRCS = version.rc diff --git a/dlls/d3dx9_25/d3dx9_25.spec b/dlls/d3dx9_25/d3dx9_25.spec -index c328108..515be27 100644 +index 7f18290..d342265 100644 --- a/dlls/d3dx9_25/d3dx9_25.spec +++ b/dlls/d3dx9_25/d3dx9_25.spec @@ -43,21 +43,21 @@ @@ -1360,19 +1359,6 @@ + + return D3DXDisassembleEffect(object->effect, enable_color_code, disassembly); +} -diff --git a/include/d3dx9effect.h b/include/d3dx9effect.h -index 25d1fd2..3f527ed 100644 ---- a/include/d3dx9effect.h -+++ b/include/d3dx9effect.h -@@ -425,6 +425,8 @@ HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, const WC - ID3DXEffectCompiler **effectcompiler, ID3DXBuffer **parseerrors); - #define D3DXCreateEffectCompilerFromResource WINELIB_NAME_AW(D3DXCreateEffectCompilerFromResource) - -+HRESULT WINAPI D3DXDisassembleEffect(ID3DXEffect *effect, BOOL enable_color_code, ID3DXBuffer **disassembly); -+ - #ifdef __cplusplus - } - #endif -- -2.3.2 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_33-Share_Source/0001-d3dx9_33-Share-the-source-with-d3dx9_36.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_33-Share_Source/0001-d3dx9_33-Share-the-source-with-d3dx9_36.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_33-Share_Source/0001-d3dx9_33-Share-the-source-with-d3dx9_36.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_33-Share_Source/0001-d3dx9_33-Share-the-source-with-d3dx9_36.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,19 +1,20 @@ -From ee0c88cdf8f9daad656c55790e4ca8c3fcddd2a9 Mon Sep 17 00:00:00 2001 +From 756f4d6d55f13e5112213562d13db7f33adbdf7f Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 13 Jul 2015 20:38:04 +1000 Subject: d3dx9_33: Share the source with d3dx9_36 --- - dlls/d3dx9_33/Makefile.in | 20 +- - dlls/d3dx9_33/d3dx9_33.spec | 666 +++++++++++++++++++++--------------------- + dlls/d3dx9_33/Makefile.in | 21 +- + dlls/d3dx9_33/d3dx9_33.spec | 667 +++++++++++++++++++++--------------------- dlls/d3dx9_33/d3dx9_33_main.c | 19 ++ - 3 files changed, 370 insertions(+), 335 deletions(-) + tools/make_specfiles | 1 - + 4 files changed, 372 insertions(+), 336 deletions(-) diff --git a/dlls/d3dx9_33/Makefile.in b/dlls/d3dx9_33/Makefile.in -index 0934eab..c3c1ed4 100644 +index 0934eab..7b0151d 100644 --- a/dlls/d3dx9_33/Makefile.in +++ b/dlls/d3dx9_33/Makefile.in -@@ -1,7 +1,23 @@ +@@ -1,7 +1,24 @@ MODULE = d3dx9_33.dll -IMPORTS = d3d9 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d @@ -21,6 +22,7 @@ C_SRCS = \ - d3dx9_33_main.c ++ animation.c \ + core.c \ + d3dx9_33_main.c \ + effect.c \ @@ -40,10 +42,10 @@ RC_SRCS = version.rc diff --git a/dlls/d3dx9_33/d3dx9_33.spec b/dlls/d3dx9_33/d3dx9_33.spec -index 35cb0b6..d0f1f5c 100644 +index 35cb0b6..2790d1a 100644 --- a/dlls/d3dx9_33/d3dx9_33.spec +++ b/dlls/d3dx9_33/d3dx9_33.spec -@@ -1,334 +1,334 @@ +@@ -1,334 +1,335 @@ -@ stdcall D3DXAssembleShader(ptr long ptr ptr long ptr ptr) d3dx9_36.D3DXAssembleShader -@ stdcall D3DXAssembleShaderFromFileA(str ptr ptr long ptr ptr) d3dx9_36.D3DXAssembleShaderFromFileA -@ stdcall D3DXAssembleShaderFromFileW(wstr ptr ptr long ptr ptr) d3dx9_36.D3DXAssembleShaderFromFileW @@ -407,9 +409,9 @@ +@ stub D3DXComputeTangentFrame(ptr long) +@ stdcall D3DXComputeTangentFrameEx(ptr long long long long long long long long long ptr float float float ptr ptr) +@ stub D3DXConcatenateMeshes(ptr long long ptr ptr ptr ptr ptr) -+@ stub D3DXConvertMeshSubsetToSingleStrip(ptr long long ptr ptr) ++@ stdcall D3DXConvertMeshSubsetToSingleStrip(ptr long long ptr ptr) +@ stub D3DXConvertMeshSubsetToStrips(ptr long long ptr ptr ptr ptr) -+@ stub D3DXCreateAnimationController(long long long long ptr) ++@ stdcall D3DXCreateAnimationController(long long long long ptr) +@ stdcall D3DXCreateBox(ptr float float float ptr ptr) +@ stdcall D3DXCreateBuffer(long ptr) +@ stub D3DXCreateCompressedAnimationSet(ptr long long ptr long ptr ptr) @@ -445,7 +447,7 @@ +@ stdcall D3DXCreateFontIndirectA(ptr ptr ptr) +@ stdcall D3DXCreateFontIndirectW(ptr ptr ptr) +@ stdcall D3DXCreateFontW(ptr long long long long long long long long long wstr ptr) -+@ stub D3DXCreateFragmentLinker(ptr long ptr) ++@ stdcall D3DXCreateFragmentLinker(ptr long ptr) +@ stub D3DXCreateKeyframedAnimationSet(ptr long long long long ptr ptr) +@ stdcall D3DXCreateLine(ptr ptr) +@ stdcall D3DXCreateMatrixStack(long ptr) @@ -536,6 +538,7 @@ +@ stdcall D3DXGetImageInfoFromResourceW(long wstr ptr) +@ stdcall D3DXGetPixelShaderProfile(ptr) +@ stdcall D3DXGetShaderConstantTable(ptr ptr) ++@ stdcall D3DXGetShaderConstantTableEx(ptr long ptr) +@ stub D3DXGetShaderInputSemantics(ptr ptr ptr) +@ stub D3DXGetShaderOutputSemantics(ptr ptr ptr) +@ stdcall D3DXGetShaderSamplers(ptr ptr ptr) @@ -745,6 +748,18 @@ +{ + return 900; +} +diff --git a/tools/make_specfiles b/tools/make_specfiles +index 16db908..9367107 100755 +--- a/tools/make_specfiles ++++ b/tools/make_specfiles +@@ -83,7 +83,6 @@ my @dll_groups = + "d3dx9_37", + "d3dx9_35", + "d3dx9_34", +- "d3dx9_33", + "d3dx9_32", + "d3dx9_31", + "d3dx9_30", -- -2.4.5 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0001-d3dx9_36-Implement-D3DXCreateAnimationController-wit.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0001-d3dx9_36-Implement-D3DXCreateAnimationController-wit.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0001-d3dx9_36-Implement-D3DXCreateAnimationController-wit.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0001-d3dx9_36-Implement-D3DXCreateAnimationController-wit.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,536 +0,0 @@ -From 9ec1a00c3d775cd5abd91ec88af216d669136152 Mon Sep 17 00:00:00 2001 -From: Christian Costa -Date: Sat, 17 Jan 2015 23:54:14 +0100 -Subject: d3dx9_36: Implement D3DXCreateAnimationController with a stubbed - ID3DXAnimationController interface. - ---- - dlls/d3dx9_36/Makefile.in | 1 + - dlls/d3dx9_36/animation.c | 455 ++++++++++++++++++++++++++++++++++++++++++++ - dlls/d3dx9_36/d3dx9_36.spec | 2 +- - include/d3dx9anim.h | 8 +- - 4 files changed, 461 insertions(+), 5 deletions(-) - create mode 100644 dlls/d3dx9_36/animation.c - -diff --git a/dlls/d3dx9_36/Makefile.in b/dlls/d3dx9_36/Makefile.in -index aa387b5..fd710c2 100644 ---- a/dlls/d3dx9_36/Makefile.in -+++ b/dlls/d3dx9_36/Makefile.in -@@ -3,6 +3,7 @@ IMPORTLIB = d3dx9 - IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d - - C_SRCS = \ -+ animation.c \ - core.c \ - d3dx9_36_main.c \ - effect.c \ -diff --git a/dlls/d3dx9_36/animation.c b/dlls/d3dx9_36/animation.c -new file mode 100644 -index 0000000..72f685f ---- /dev/null -+++ b/dlls/d3dx9_36/animation.c -@@ -0,0 +1,455 @@ -+/* -+ * Animation Controller operations specific to D3DX9. -+ * -+ * Copyright (C) 2015 Christian Costa -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "wine/debug.h" -+#include "d3dx9_36_private.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(d3dx); -+ -+struct d3dx9_animation_controller -+{ -+ ID3DXAnimationController ID3DXAnimationController_iface; -+ LONG ref; -+}; -+ -+static inline struct d3dx9_animation_controller *impl_from_ID3DXAnimationController(ID3DXAnimationController *iface) -+{ -+ return CONTAINING_RECORD(iface, struct d3dx9_animation_controller, ID3DXAnimationController_iface); -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_QueryInterface(ID3DXAnimationController *iface, REFIID riid, void **out) -+{ -+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); -+ -+ if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ID3DXAnimationController)) -+ { -+ IUnknown_AddRef(iface); -+ *out = iface; -+ return D3D_OK; -+ } -+ -+ WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); -+ -+ *out = NULL; -+ return E_NOINTERFACE; -+} -+ -+static ULONG WINAPI d3dx9_animation_controller_AddRef(ID3DXAnimationController *iface) -+{ -+ struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); -+ ULONG refcount = InterlockedIncrement(&animation->ref); -+ -+ TRACE("%p increasing refcount to %u.\n", animation, refcount); -+ -+ return refcount; -+} -+ -+static ULONG WINAPI d3dx9_animation_controller_Release(ID3DXAnimationController *iface) -+{ -+ struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); -+ ULONG refcount = InterlockedDecrement(&animation->ref); -+ -+ TRACE("%p decreasing refcount to %u.\n", animation, refcount); -+ -+ if (!refcount) -+ { -+ HeapFree(GetProcessHeap(), 0, animation); -+ } -+ -+ return refcount; -+} -+ -+static UINT WINAPI d3dx9_animation_controller_GetMaxNumAnimationOutputs(ID3DXAnimationController *iface) -+{ -+ FIXME("iface %p stub.\n", iface); -+ -+ return 0; -+} -+ -+static UINT WINAPI d3dx9_animation_controller_GetMaxNumAnimationSets(ID3DXAnimationController *iface) -+{ -+ FIXME("iface %p stub.\n", iface); -+ -+ return 0; -+} -+ -+static UINT WINAPI d3dx9_animation_controller_GetMaxNumTracks(ID3DXAnimationController *iface) -+{ -+ FIXME("iface %p stub.\n", iface); -+ -+ return 0; -+} -+ -+static UINT WINAPI d3dx9_animation_controller_GetMaxNumEvents(ID3DXAnimationController *iface) -+{ -+ FIXME("iface %p stub.\n", iface); -+ -+ return 0; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_RegisterAnimationOutput(ID3DXAnimationController *iface, -+ const char *name, D3DXMATRIX *matrix, D3DXVECTOR3 *scale, D3DXQUATERNION *rotation, D3DXVECTOR3 *translation) -+{ -+ FIXME("iface %p, name %s, matrix %p, scale %p, rotation %p, translation %p stub.\n", iface, wine_dbgstr_a(name), -+ matrix, scale, rotation, translation); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_RegisterAnimationSet(ID3DXAnimationController *iface, -+ ID3DXAnimationSet *anim_set) -+{ -+ FIXME("iface %p, anim_set %p stub.\n", iface, anim_set); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_UnregisterAnimationSet(ID3DXAnimationController *iface, -+ ID3DXAnimationSet *anim_set) -+{ -+ FIXME("iface %p, anim_set %p stub.\n", iface, anim_set); -+ -+ return E_NOTIMPL; -+} -+ -+static UINT WINAPI d3dx9_animation_controller_GetNumAnimationSets(ID3DXAnimationController *iface) -+{ -+ FIXME("iface %p stub.\n", iface); -+ -+ return 0; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_GetAnimationSet(ID3DXAnimationController *iface, -+ UINT index, ID3DXAnimationSet **anim_set) -+{ -+ FIXME("iface %p, index %u, anim_set %p stub.\n", iface, index, anim_set); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_GetAnimationSetByName(ID3DXAnimationController *iface, -+ const char *name, ID3DXAnimationSet **anim_set) -+{ -+ FIXME("iface %p, name %s, anim_set %p stub.\n", iface, wine_dbgstr_a(name), anim_set); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_AdvanceTime(ID3DXAnimationController *iface, DOUBLE time_delta, -+ ID3DXAnimationCallbackHandler **callback_handler) -+{ -+ FIXME("iface %p, time_delta %g, callback_handler %p stub.\n", iface, time_delta, callback_handler); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_Reset(ID3DXAnimationController *iface) -+{ -+ FIXME("iface %p stub.\n", iface); -+ -+ return E_NOTIMPL; -+} -+ -+static DOUBLE WINAPI d3dx9_animation_controller_GetTime(ID3DXAnimationController *iface) -+{ -+ FIXME("iface %p stub.\n", iface); -+ -+ return 0.0; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_SetTrackAnimationSet(ID3DXAnimationController *iface, -+ UINT track, ID3DXAnimationSet *anim_set) -+{ -+ FIXME("iface %p, track %u, anim_set %p stub.\n", iface, track, anim_set); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_GetTrackAnimationSet(ID3DXAnimationController *iface, -+ UINT track, ID3DXAnimationSet **anim_set) -+{ -+ FIXME("iface %p, track %u, anim_set %p stub.\n", iface, track, anim_set); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_GetTrackPriority(ID3DXAnimationController *iface, -+ UINT track, D3DXPRIORITY_TYPE *priority) -+{ -+ FIXME("iface %p, track %u, priority %p stub.\n", iface, track, priority); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_SetTrackSpeed(ID3DXAnimationController *iface, -+ UINT track, FLOAT speed) -+{ -+ FIXME("iface %p, track %u, speed %f stub.\n", iface, track, speed); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_SetTrackWeight(ID3DXAnimationController *iface, -+ UINT track, FLOAT weight) -+{ -+ FIXME("iface %p, track %u, weight %f stub.\n", iface, track, weight); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_SetTrackPosition(ID3DXAnimationController *iface, -+ UINT track, DOUBLE position) -+{ -+ FIXME("iface %p, track %u, position %g stub.\n", iface, track, position); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_SetTrackEnable(ID3DXAnimationController *iface, -+ UINT track, BOOL enable) -+{ -+ FIXME("iface %p, track %u, enable %u stub.\n", iface, track, enable); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_SetTrackDesc(ID3DXAnimationController *iface, -+ UINT track, D3DXTRACK_DESC *desc) -+{ -+ FIXME("iface %p, track %u, desc %p stub.\n", iface, track, desc); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_GetTrackDesc(ID3DXAnimationController *iface, -+ UINT track, D3DXTRACK_DESC *desc) -+{ -+ FIXME("iface %p, track %u, desc %p stub.\n", iface, track, desc); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_SetPriorityBlend(ID3DXAnimationController *iface, -+ FLOAT blend_weight) -+{ -+ FIXME("iface %p, blend_weight %f stub.\n", iface, blend_weight); -+ -+ return E_NOTIMPL; -+} -+ -+static FLOAT WINAPI d3dx9_animation_controller_GetPriorityBlend(ID3DXAnimationController *iface) -+{ -+ FIXME("iface %p stub.\n", iface); -+ -+ return 0.0; -+} -+ -+static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_KeyTrackSpeed(ID3DXAnimationController *iface, -+ UINT track, FLOAT new_speed, DOUBLE start_time, DOUBLE duration, D3DXTRANSITION_TYPE transition) -+{ -+ FIXME("iface %p, track %u, new_speed %f, start_time %g, duration %g, transition %u stub.\n", iface, -+ track, new_speed, start_time, duration, transition); -+ -+ return 0; -+} -+ -+static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_KeyTrackWeight(ID3DXAnimationController *iface, -+ UINT track, FLOAT new_weight, DOUBLE start_time, DOUBLE duration, D3DXTRANSITION_TYPE transition) -+{ -+ FIXME("iface %p, track %u, new_weight %f, start_time %g, duration %g, transition %u stub.\n", iface, -+ track, new_weight, start_time, duration, transition); -+ -+ return 0; -+} -+ -+static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_KeyTrackPosition(ID3DXAnimationController *iface, -+ UINT track, DOUBLE new_position, DOUBLE start_time) -+{ -+ FIXME("iface %p, track %u, new_position %g, start_time %g stub.\n", iface, -+ track, new_position, start_time); -+ -+ return 0; -+} -+ -+static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_KeyTrackEnable(ID3DXAnimationController *iface, -+ UINT track, BOOL new_enable, DOUBLE start_time) -+{ -+ FIXME("iface %p, track %u, new_enable %u, start_time %g stub.\n", iface, -+ track, new_enable, start_time); -+ -+ return 0; -+} -+ -+static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_KeyTrackBlend(ID3DXAnimationController *iface, -+ FLOAT new_blend_weight, DOUBLE start_time, DOUBLE duration, D3DXTRANSITION_TYPE transition) -+{ -+ FIXME("iface %p, new_blend_weight %f, start_time %g, duration %g, transition %u stub.\n", iface, -+ new_blend_weight, start_time, duration, transition); -+ -+ return 0; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_UnkeyEvent(ID3DXAnimationController *iface, D3DXEVENTHANDLE event) -+{ -+ FIXME("iface %p, event %u stub.\n", iface, event); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_UnkeyAllTrackEvents(ID3DXAnimationController *iface, UINT track) -+{ -+ FIXME("iface %p, track %u stub.\n", iface, track); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_UnkeyAllPriorityBlends(ID3DXAnimationController *iface) -+{ -+ FIXME("iface %p stub.\n", iface); -+ -+ return E_NOTIMPL; -+} -+ -+static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_GetCurrentTrackEvent(ID3DXAnimationController *iface, -+ UINT track, D3DXEVENT_TYPE event_type) -+{ -+ FIXME("iface %p, track %u, event_type %u stub.\n", iface, track, event_type); -+ -+ return 0; -+} -+ -+static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_GetCurrentPriorityBlend(ID3DXAnimationController *iface) -+{ -+ FIXME("iface %p stub.\n", iface); -+ -+ return 0; -+} -+ -+static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_GetUpcomingTrackEvent(ID3DXAnimationController *iface, -+ UINT track, D3DXEVENTHANDLE event) -+{ -+ FIXME("iface %p, track %u, event %u stub.\n", iface, track, event); -+ -+ return 0; -+} -+ -+static D3DXEVENTHANDLE WINAPI d3dx9_animation_controller_GetUpcomingPriorityBlend(ID3DXAnimationController *iface, -+ D3DXEVENTHANDLE handle) -+{ -+ FIXME("iface %p, handle %u stub.\n", iface, handle); -+ -+ return 0; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_ValidateEvent(ID3DXAnimationController *iface, D3DXEVENTHANDLE event) -+{ -+ FIXME("iface %p, event %u stub.\n", iface, event); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_GetEventDesc(ID3DXAnimationController *iface, -+ D3DXEVENTHANDLE event, D3DXEVENT_DESC *desc) -+{ -+ FIXME("iface %p, event %u, desc %p stub.\n", iface, event, desc); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI d3dx9_animation_controller_CloneAnimationController(ID3DXAnimationController *iface, UINT max_num_anim_outputs, -+ UINT max_num_anim_sets, UINT max_num_tracks, UINT max_num_events, ID3DXAnimationController **anim_controller) -+{ -+ FIXME("iface %p, max_num_anim_outputs %u, max_num_anim_sets %u, max_num_tracks %u, max_num_events %u, anim_controller %p stub.\n", -+ iface, max_num_anim_outputs, max_num_anim_sets, max_num_tracks, max_num_events, anim_controller); -+ -+ return E_NOTIMPL; -+} -+ -+static const struct ID3DXAnimationControllerVtbl d3dx9_animation_controller_vtbl = -+{ -+ d3dx9_animation_controller_QueryInterface, -+ d3dx9_animation_controller_AddRef, -+ d3dx9_animation_controller_Release, -+ d3dx9_animation_controller_GetMaxNumAnimationOutputs, -+ d3dx9_animation_controller_GetMaxNumAnimationSets, -+ d3dx9_animation_controller_GetMaxNumTracks, -+ d3dx9_animation_controller_GetMaxNumEvents, -+ d3dx9_animation_controller_RegisterAnimationOutput, -+ d3dx9_animation_controller_RegisterAnimationSet, -+ d3dx9_animation_controller_UnregisterAnimationSet, -+ d3dx9_animation_controller_GetNumAnimationSets, -+ d3dx9_animation_controller_GetAnimationSet, -+ d3dx9_animation_controller_GetAnimationSetByName, -+ d3dx9_animation_controller_AdvanceTime, -+ d3dx9_animation_controller_Reset, -+ d3dx9_animation_controller_GetTime, -+ d3dx9_animation_controller_SetTrackAnimationSet, -+ d3dx9_animation_controller_GetTrackAnimationSet, -+ d3dx9_animation_controller_GetTrackPriority, -+ d3dx9_animation_controller_SetTrackSpeed, -+ d3dx9_animation_controller_SetTrackWeight, -+ d3dx9_animation_controller_SetTrackPosition, -+ d3dx9_animation_controller_SetTrackEnable, -+ d3dx9_animation_controller_SetTrackDesc, -+ d3dx9_animation_controller_GetTrackDesc, -+ d3dx9_animation_controller_SetPriorityBlend, -+ d3dx9_animation_controller_GetPriorityBlend, -+ d3dx9_animation_controller_KeyTrackSpeed, -+ d3dx9_animation_controller_KeyTrackWeight, -+ d3dx9_animation_controller_KeyTrackPosition, -+ d3dx9_animation_controller_KeyTrackEnable, -+ d3dx9_animation_controller_KeyTrackBlend, -+ d3dx9_animation_controller_UnkeyEvent, -+ d3dx9_animation_controller_UnkeyAllTrackEvents, -+ d3dx9_animation_controller_UnkeyAllPriorityBlends, -+ d3dx9_animation_controller_GetCurrentTrackEvent, -+ d3dx9_animation_controller_GetCurrentPriorityBlend, -+ d3dx9_animation_controller_GetUpcomingTrackEvent, -+ d3dx9_animation_controller_GetUpcomingPriorityBlend, -+ d3dx9_animation_controller_ValidateEvent, -+ d3dx9_animation_controller_GetEventDesc, -+ d3dx9_animation_controller_CloneAnimationController -+}; -+ -+/*********************************************************************** -+ * D3DXCreateAnimationController (D3DX9_36.@) -+ */ -+HRESULT WINAPI D3DXCreateAnimationController(UINT MaxNumAnimationOutputs, UINT MaxNumAnimationSets, -+ UINT MaxNumTracks, UINT MaxNumEvents, ID3DXAnimationController **AnimationController) -+{ -+ struct d3dx9_animation_controller* object; -+ -+ TRACE("MaxNumAnimationOutputs %u, MaxNumAnimationSets %u, MaxNumTracks %u, MaxNumEvents %u, AnimationController %p.\n", -+ MaxNumAnimationOutputs, MaxNumAnimationSets, MaxNumTracks, MaxNumEvents, AnimationController); -+ -+ if (!AnimationController) -+ return D3DERR_INVALIDCALL; -+ -+ object = HeapAlloc(GetProcessHeap(), 0, sizeof(*object)); -+ if (!object) -+ return E_OUTOFMEMORY; -+ -+ object->ID3DXAnimationController_iface.lpVtbl = &d3dx9_animation_controller_vtbl; -+ object->ref = 1; -+ -+ *AnimationController = &object->ID3DXAnimationController_iface; -+ -+ return D3D_OK; -+} -diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec -index 13f0d99..4182f59 100644 ---- a/dlls/d3dx9_36/d3dx9_36.spec -+++ b/dlls/d3dx9_36/d3dx9_36.spec -@@ -30,7 +30,7 @@ - @ stub D3DXConcatenateMeshes(ptr long long ptr ptr ptr ptr ptr) - @ stub D3DXConvertMeshSubsetToSingleStrip(ptr long long ptr ptr) - @ stub D3DXConvertMeshSubsetToStrips(ptr long long ptr ptr ptr ptr) --@ stub D3DXCreateAnimationController(long long long long ptr) -+@ stdcall D3DXCreateAnimationController(long long long long ptr) - @ stdcall D3DXCreateBox(ptr float float float ptr ptr) - @ stdcall D3DXCreateBuffer(long ptr) - @ stub D3DXCreateCompressedAnimationSet(ptr long long ptr long ptr ptr) -diff --git a/include/d3dx9anim.h b/include/d3dx9anim.h -index b5f2232..c4d4d64 100644 ---- a/include/d3dx9anim.h -+++ b/include/d3dx9anim.h -@@ -327,7 +327,7 @@ DECLARE_INTERFACE_(ID3DXAnimationController, IUnknown) - STDMETHOD_(UINT, GetNumAnimationSets)(THIS) PURE; - STDMETHOD(GetAnimationSet)(THIS_ UINT index, ID3DXAnimationSet **anim_set) PURE; - STDMETHOD(GetAnimationSetByName)(THIS_ const char *name, ID3DXAnimationSet **anim_set) PURE; -- STDMETHOD(AdvanceTime)(THIS_ double time_delta, ID3DXAnimationCallbackHandler **callback_handler) PURE; -+ STDMETHOD(AdvanceTime)(THIS_ DOUBLE time_delta, ID3DXAnimationCallbackHandler **callback_handler) PURE; - STDMETHOD(ResetTime)(THIS) PURE; - STDMETHOD_(DOUBLE, GetTime)(THIS) PURE; - STDMETHOD(SetTrackAnimationSet)(THIS_ UINT track, ID3DXAnimationSet *anim_set) PURE; -@@ -337,8 +337,8 @@ DECLARE_INTERFACE_(ID3DXAnimationController, IUnknown) - STDMETHOD(SetTrackWeight)(THIS_ UINT track, FLOAT weight) PURE; - STDMETHOD(SetTrackPosition)(THIS_ UINT track, DOUBLE position) PURE; - STDMETHOD(SetTrackEnable)(THIS_ UINT track, BOOL enable) PURE; -- STDMETHOD(SetTrackDesc)(THIS_ UINT track, LPD3DXTRACK_DESC desc) PURE; -- STDMETHOD(GetTrackDesc)(THIS_ UINT track, LPD3DXTRACK_DESC desc) PURE; -+ STDMETHOD(SetTrackDesc)(THIS_ UINT track, D3DXTRACK_DESC *desc) PURE; -+ STDMETHOD(GetTrackDesc)(THIS_ UINT track, D3DXTRACK_DESC *desc) PURE; - STDMETHOD(SetPriorityBlend)(THIS_ FLOAT blend_weight) PURE; - STDMETHOD_(FLOAT, GetPriorityBlend)(THIS) PURE; - STDMETHOD_(D3DXEVENTHANDLE, KeyTrackSpeed)(THIS_ UINT track, FLOAT new_speed, -@@ -357,7 +357,7 @@ DECLARE_INTERFACE_(ID3DXAnimationController, IUnknown) - STDMETHOD_(D3DXEVENTHANDLE, GetUpcomingTrackEvent)(THIS_ UINT track, D3DXEVENTHANDLE event) PURE; - STDMETHOD_(D3DXEVENTHANDLE, GetUpcomingPriorityBlend)(THIS_ D3DXEVENTHANDLE handle) PURE; - STDMETHOD(ValidateEvent)(THIS_ D3DXEVENTHANDLE event) PURE; -- STDMETHOD(GetEventDesc)(THIS_ D3DXEVENTHANDLE event, LPD3DXEVENT_DESC desc) PURE; -+ STDMETHOD(GetEventDesc)(THIS_ D3DXEVENTHANDLE event, D3DXEVENT_DESC *desc) PURE; - STDMETHOD(CloneAnimationController)(THIS_ UINT max_num_anim_outputs, UINT max_num_anim_sets, - UINT max_num_tracks, UINT max_num_events, ID3DXAnimationController **anim_controller) PURE; - }; --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0002-d3dx9_36-Store-all-values-passed-to-the-create-and-r.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0002-d3dx9_36-Store-all-values-passed-to-the-create-and-r.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0002-d3dx9_36-Store-all-values-passed-to-the-create-and-r.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0002-d3dx9_36-Store-all-values-passed-to-the-create-and-r.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -From a719ecc33b789c26eb75b1eb27523f47cb02df5c Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Fri, 21 Aug 2015 15:05:51 +1000 -Subject: d3dx9_36: Store all values passed to the create and return them in - the correct functions - -Signed-off-by: Alistair Leslie-Hughes ---- - dlls/d3dx9_36/animation.c | 47 ++++++++++++++++++++++++++++++++--------------- - 1 file changed, 32 insertions(+), 15 deletions(-) - -diff --git a/dlls/d3dx9_36/animation.c b/dlls/d3dx9_36/animation.c -index 72f685f..042079d 100644 ---- a/dlls/d3dx9_36/animation.c -+++ b/dlls/d3dx9_36/animation.c -@@ -27,6 +27,11 @@ struct d3dx9_animation_controller - { - ID3DXAnimationController ID3DXAnimationController_iface; - LONG ref; -+ -+ UINT max_outputs; -+ UINT max_sets; -+ UINT max_tracks; -+ UINT max_events; - }; - - static inline struct d3dx9_animation_controller *impl_from_ID3DXAnimationController(ID3DXAnimationController *iface) -@@ -53,24 +58,24 @@ static HRESULT WINAPI d3dx9_animation_controller_QueryInterface(ID3DXAnimationCo - - static ULONG WINAPI d3dx9_animation_controller_AddRef(ID3DXAnimationController *iface) - { -- struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); -- ULONG refcount = InterlockedIncrement(&animation->ref); -+ struct d3dx9_animation_controller *This = impl_from_ID3DXAnimationController(iface); -+ ULONG refcount = InterlockedIncrement(&This->ref); - -- TRACE("%p increasing refcount to %u.\n", animation, refcount); -+ TRACE("%p increasing refcount to %u.\n", This, refcount); - - return refcount; - } - - static ULONG WINAPI d3dx9_animation_controller_Release(ID3DXAnimationController *iface) - { -- struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); -- ULONG refcount = InterlockedDecrement(&animation->ref); -+ struct d3dx9_animation_controller *This = impl_from_ID3DXAnimationController(iface); -+ ULONG refcount = InterlockedDecrement(&This->ref); - -- TRACE("%p decreasing refcount to %u.\n", animation, refcount); -+ TRACE("%p decreasing refcount to %u.\n", This, refcount); - - if (!refcount) - { -- HeapFree(GetProcessHeap(), 0, animation); -+ HeapFree(GetProcessHeap(), 0, This); - } - - return refcount; -@@ -78,30 +83,38 @@ static ULONG WINAPI d3dx9_animation_controller_Release(ID3DXAnimationController - - static UINT WINAPI d3dx9_animation_controller_GetMaxNumAnimationOutputs(ID3DXAnimationController *iface) - { -- FIXME("iface %p stub.\n", iface); -+ struct d3dx9_animation_controller *This = impl_from_ID3DXAnimationController(iface); - -- return 0; -+ TRACE("iface %p.\n", iface); -+ -+ return This->max_outputs; - } - - static UINT WINAPI d3dx9_animation_controller_GetMaxNumAnimationSets(ID3DXAnimationController *iface) - { -- FIXME("iface %p stub.\n", iface); -+ struct d3dx9_animation_controller *This = impl_from_ID3DXAnimationController(iface); - -- return 0; -+ TRACE("iface %p.\n", iface); -+ -+ return This->max_sets; - } - - static UINT WINAPI d3dx9_animation_controller_GetMaxNumTracks(ID3DXAnimationController *iface) - { -- FIXME("iface %p stub.\n", iface); -+ struct d3dx9_animation_controller *This = impl_from_ID3DXAnimationController(iface); - -- return 0; -+ FIXME("iface %p.\n", iface); -+ -+ return This->max_tracks; - } - - static UINT WINAPI d3dx9_animation_controller_GetMaxNumEvents(ID3DXAnimationController *iface) - { -- FIXME("iface %p stub.\n", iface); -+ struct d3dx9_animation_controller *This = impl_from_ID3DXAnimationController(iface); - -- return 0; -+ FIXME("iface %p.\n", iface); -+ -+ return This->max_events; - } - - static HRESULT WINAPI d3dx9_animation_controller_RegisterAnimationOutput(ID3DXAnimationController *iface, -@@ -448,6 +461,10 @@ HRESULT WINAPI D3DXCreateAnimationController(UINT MaxNumAnimationOutputs, UINT M - - object->ID3DXAnimationController_iface.lpVtbl = &d3dx9_animation_controller_vtbl; - object->ref = 1; -+ object->max_outputs = MaxNumAnimationOutputs; -+ object->max_sets = MaxNumAnimationSets; -+ object->max_tracks = MaxNumTracks; -+ object->max_events = MaxNumEvents; - - *AnimationController = &object->ID3DXAnimationController_iface; - --- -2.6.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0003-d3dx9_36-Add-D3DXCreateAnimationController-tests.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0003-d3dx9_36-Add-D3DXCreateAnimationController-tests.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0003-d3dx9_36-Add-D3DXCreateAnimationController-tests.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-AnimationController/0003-d3dx9_36-Add-D3DXCreateAnimationController-tests.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -From 151b9f248ad985bb545541fbc4a0096e53385505 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 25 Aug 2015 14:34:43 +1000 -Subject: d3dx9_36: Add D3DXCreateAnimationController tests - -Signed-off-by: Alistair Leslie-Hughes ---- - dlls/d3dx9_36/tests/mesh.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 52 insertions(+) - -diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c -index 4186e19..fd764df 100644 ---- a/dlls/d3dx9_36/tests/mesh.c -+++ b/dlls/d3dx9_36/tests/mesh.c -@@ -10959,6 +10959,57 @@ static void test_compute_normals(void) - free_test_context(test_context); - } - -+static void D3DXCreateAnimationControllerTest(void) -+{ -+ HRESULT hr; -+ ID3DXAnimationController *animation; -+ UINT value; -+ -+ hr = D3DXCreateAnimationController(0, 0, 0, 0, NULL); -+ todo_wine ok(hr == D3D_OK, "D3DXCreateAnimationController returned %#x, expected D3D_OK\n", hr); -+ -+if (0) /* Crashes when animation is Released */ -+{ -+ hr = D3DXCreateAnimationController(0, 0, 0, 0, &animation); -+ ok(hr == D3D_OK, "D3DXCreateAnimationController returned %#x, expected D3D_OK\n", hr); -+ animation->lpVtbl->Release(animation); -+} -+ -+ hr = D3DXCreateAnimationController(1, 1, 1, 1, &animation); -+ ok(hr == D3D_OK, "D3DXCreateAnimationController returned %#x, expected D3D_OK\n", hr); -+ -+ value = animation->lpVtbl->GetMaxNumAnimationOutputs(animation); -+ ok(value == 1, "returned %u, expected 1\n", value); -+ -+ value = animation->lpVtbl->GetMaxNumAnimationSets(animation); -+ ok(value == 1, "returned %u, expected 1\n", value); -+ -+ value = animation->lpVtbl->GetMaxNumTracks(animation); -+ ok(value == 1, "returned %u, expected 1\n", value); -+ -+ value = animation->lpVtbl->GetMaxNumEvents(animation); -+ ok(value == 1, "returned %u, expected 1\n", value); -+ -+ animation->lpVtbl->Release(animation); -+ -+ hr = D3DXCreateAnimationController(100, 101, 102, 103, &animation); -+ ok(hr == D3D_OK, "D3DXCreateAnimationController returned %#x, expected D3D_OK\n", hr); -+ -+ value = animation->lpVtbl->GetMaxNumAnimationOutputs(animation); -+ ok(value == 100, "returned %u, expected 100\n", value); -+ -+ value = animation->lpVtbl->GetMaxNumAnimationSets(animation); -+ ok(value == 101, "returned %u, expected 101\n", value); -+ -+ value = animation->lpVtbl->GetMaxNumTracks(animation); -+ ok(value == 102, "returned %u, expected 102\n", value); -+ -+ value = animation->lpVtbl->GetMaxNumEvents(animation); -+ ok(value == 103, "returned %u, expected 103\n", value); -+ -+ animation->lpVtbl->Release(animation); -+} -+ - START_TEST(mesh) - { - D3DXBoundProbeTest(); -@@ -10975,6 +11026,7 @@ START_TEST(mesh) - D3DXCreateCylinderTest(); - D3DXCreateTextTest(); - D3DXCreateTorusTest(); -+ D3DXCreateAnimationControllerTest(); - test_get_decl_length(); - test_get_decl_vertex_size(); - test_fvf_decl_conversion(); --- -2.6.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-AnimationController/definition wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-AnimationController/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-AnimationController/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-AnimationController/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -Fixes: Add stubs for D3DXCreateAnimationController interface -Depends: d3dx9_36-DXTn -Category: stable diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0001-d3dx9_36-Add-support-for-FOURCC-surface-to-save_dds_.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0001-d3dx9_36-Add-support-for-FOURCC-surface-to-save_dds_.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0001-d3dx9_36-Add-support-for-FOURCC-surface-to-save_dds_.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0001-d3dx9_36-Add-support-for-FOURCC-surface-to-save_dds_.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,32 @@ +From cfbee3f0f952769dbf663489c2a209493c7412d3 Mon Sep 17 00:00:00 2001 +From: Christian Costa +Date: Sun, 11 Jan 2015 16:18:03 +0100 +Subject: d3dx9_36: Add support for FOURCC surface to + save_dds_surface_to_memory. + +--- + dlls/d3dx9_36/surface.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c +index 4fa2a76..58b676d 100644 +--- a/dlls/d3dx9_36/surface.c ++++ b/dlls/d3dx9_36/surface.c +@@ -311,6 +311,14 @@ static HRESULT d3dformat_to_dds_pixel_format(struct dds_pixel_format *pixel_form + } + } + ++ /* Reuse dds_fourcc_to_d3dformat as D3DFORMAT and FOURCC are DWORD with same values */ ++ if (dds_fourcc_to_d3dformat(d3dformat) != D3DFMT_UNKNOWN) ++ { ++ pixel_format->flags |= DDS_PF_FOURCC; ++ pixel_format->fourcc = d3dformat; ++ return D3D_OK; ++ } ++ + WARN("Unknown pixel format %#x\n", d3dformat); + return E_NOTIMPL; + } +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0001-d3dx9_36-tests-Add-D3DXSaveSurfaceToFileInMemory-D3D.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0001-d3dx9_36-tests-Add-D3DXSaveSurfaceToFileInMemory-D3D.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0001-d3dx9_36-tests-Add-D3DXSaveSurfaceToFileInMemory-D3D.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0001-d3dx9_36-tests-Add-D3DXSaveSurfaceToFileInMemory-D3D.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -From 68efe5449591b9b1366d66d87fff1a8c9f8002e5 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Fri, 16 Oct 2015 14:06:30 +1100 -Subject: d3dx9_36/tests: Add D3DXSaveSurfaceToFileInMemory D3DXIFF_DDS tests - -Also updates the structure dds_header to be the same as d3dx9_36/surface.c. - -Signed-off-by: Alistair Leslie-Hughes ---- - dlls/d3dx9_36/tests/surface.c | 34 +++++++++++++++++++++++++++++++++- - 1 file changed, 33 insertions(+), 1 deletion(-) - -diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c -index 1697a03..77bd142 100644 ---- a/dlls/d3dx9_36/tests/surface.c -+++ b/dlls/d3dx9_36/tests/surface.c -@@ -211,7 +211,9 @@ struct dds_header - struct dds_pixel_format pixel_format; - DWORD caps; - DWORD caps2; -- DWORD reserved2[3]; -+ DWORD caps3; -+ DWORD caps4; -+ DWORD reserved2; - }; - - /* fills dds_header with reasonable default values */ -@@ -1231,6 +1233,7 @@ static void test_D3DXSaveSurfaceToFileInMemory(IDirect3DDevice9 *device) - RECT rect; - ID3DXBuffer *buffer; - IDirect3DSurface9 *surface; -+ struct dds_header *header; - - hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL); - if (FAILED(hr)) { -@@ -1248,6 +1251,35 @@ static void test_D3DXSaveSurfaceToFileInMemory(IDirect3DDevice9 *device) - ID3DXBuffer_Release(buffer); - } - -+ SetRect(&rect, 0, 0, 0, 0); -+ hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, NULL, &rect); -+ todo_wine ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "D3DXSaveSurfaceToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK); -+ if (SUCCEEDED(hr)) { -+ header = ID3DXBuffer_GetBufferPointer(buffer); -+ -+ ok(header->magic == MAKEFOURCC('D','D','S',' '), "Invalid DDS signature\n"); -+ todo_wine ok(header->size == 124, "Invalid DDS size %d\n", header->size); -+ ok(header->height == 0, "Wrong height %d\n", header->height); -+ ok(header->width == 0, "Wrong width %d\n", header->width); -+ ok(header->flags == (DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT), -+ "Wrong flags %x\n", header->flags); -+ ID3DXBuffer_Release(buffer); -+ } -+ -+ hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, NULL, NULL); -+ ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "D3DXSaveSurfaceToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK); -+ if (SUCCEEDED(hr)) { -+ header = ID3DXBuffer_GetBufferPointer(buffer); -+ -+ ok(header->magic == MAKEFOURCC('D','D','S',' '), "Invalid DDS signature\n"); -+ todo_wine ok(header->size == 124, "Invalid DDS size %d\n", header->size); -+ ok(header->height == 4, "Wrong height %d\n", header->height); -+ ok(header->width == 4, "Wrong width %d\n", header->width); -+ todo_wine ok(header->flags == (DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT), -+ "Wrong flags %x\n", header->flags); -+ ID3DXBuffer_Release(buffer); -+ } -+ - IDirect3DSurface9_Release(surface); - } - --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0002-d3dx9_36-Fix-several-issues-in-save_dds_surface_to_m.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0002-d3dx9_36-Fix-several-issues-in-save_dds_surface_to_m.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0002-d3dx9_36-Fix-several-issues-in-save_dds_surface_to_m.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0002-d3dx9_36-Fix-several-issues-in-save_dds_surface_to_m.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -From 88f02c608de86c125cbddd543c34ea2bfce30993 Mon Sep 17 00:00:00 2001 -From: Christian Costa -Date: Sun, 11 Jan 2015 16:09:43 +0100 -Subject: d3dx9_36: Fix several issues in save_dds_surface_to_memory. - -The different fixes are: -- Fix header size of the DDS file -- Remove DDS_MIPMAPCOUNT as mipmap levels are not supported yet -- Fix DDS_WIDTH define to correct value 4 -- Do not set depth and miplevels fields as their flags are not set (to match native) ---- - dlls/d3dx9_36/surface.c | 7 +++---- - dlls/d3dx9_36/tests/surface.c | 2 +- - 2 files changed, 4 insertions(+), 5 deletions(-) - -diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c -index b8bb710..6f6132c 100644 ---- a/dlls/d3dx9_36/surface.c -+++ b/dlls/d3dx9_36/surface.c -@@ -487,13 +487,12 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur - - memset(header, 0, sizeof(*header)); - header->signature = MAKEFOURCC('D','D','S',' '); -- header->size = sizeof(*header); -- header->flags = DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PITCH | DDS_PIXELFORMAT | DDS_MIPMAPCOUNT; -+ /* The signature is not really part of the DDS header */ -+ header->size = sizeof(*header) - sizeof(header->signature); -+ header->flags = DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PITCH | DDS_PIXELFORMAT; - header->height = src_desc.Height; - header->width = src_desc.Width; - header->pitch_or_linear_size = dst_pitch; -- header->depth = 1; -- header->miplevels = 1; - header->caps = DDS_CAPS_TEXTURE; - hr = d3dformat_to_dds_pixel_format(&header->pixel_format, src_desc.Format); - if (FAILED(hr)) -diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c -index 77bd142..f04fa67 100644 ---- a/dlls/d3dx9_36/tests/surface.c -+++ b/dlls/d3dx9_36/tests/surface.c -@@ -1272,7 +1272,7 @@ static void test_D3DXSaveSurfaceToFileInMemory(IDirect3DDevice9 *device) - header = ID3DXBuffer_GetBufferPointer(buffer); - - ok(header->magic == MAKEFOURCC('D','D','S',' '), "Invalid DDS signature\n"); -- todo_wine ok(header->size == 124, "Invalid DDS size %d\n", header->size); -+ ok(header->size == 124, "Invalid DDS size %d\n", header->size); - ok(header->height == 4, "Wrong height %d\n", header->height); - ok(header->width == 4, "Wrong width %d\n", header->width); - todo_wine ok(header->flags == (DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT), --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0002-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0002-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0002-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0002-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,117 @@ +From f9702dad952fdc873a72b4a2781bf2171ff3f814 Mon Sep 17 00:00:00 2001 +From: Christian Costa +Date: Sun, 11 Jan 2015 16:29:30 +0100 +Subject: d3dx9_36: Improve D3DXSaveTextureToFile to save simple texture to dds + file. + +--- + dlls/d3dx9_36/d3dx9_36_private.h | 2 ++ + dlls/d3dx9_36/surface.c | 62 ++++++++++++++++++++++++++++++++++++++++ + dlls/d3dx9_36/texture.c | 5 +--- + 3 files changed, 65 insertions(+), 4 deletions(-) + +diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h +index 79f3b76..41bed31 100644 +--- a/dlls/d3dx9_36/d3dx9_36_private.h ++++ b/dlls/d3dx9_36/d3dx9_36_private.h +@@ -97,6 +97,8 @@ HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *d + const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN; + HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, const void *src_data, + const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN; ++HRESULT save_dds_texture_to_memory(ID3DXBuffer **dst_buffer, IDirect3DBaseTexture9 *src_texture, ++ const PALETTEENTRY *src_palette) DECLSPEC_HIDDEN; + + unsigned short float_32_to_16(const float in) DECLSPEC_HIDDEN; + float float_16_to_32(const unsigned short in) DECLSPEC_HIDDEN; +diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c +index 58b676d..79e8d53 100644 +--- a/dlls/d3dx9_36/surface.c ++++ b/dlls/d3dx9_36/surface.c +@@ -527,6 +527,68 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur + return D3D_OK; + } + ++static HRESULT get_surface(D3DRESOURCETYPE type, struct IDirect3DBaseTexture9 *tex, ++ int face, UINT level, struct IDirect3DSurface9 **surf) ++{ ++ switch (type) ++ { ++ case D3DRTYPE_TEXTURE: ++ return IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) tex, level, surf); ++ case D3DRTYPE_CUBETEXTURE: ++ return IDirect3DCubeTexture9_GetCubeMapSurface((IDirect3DCubeTexture9*) tex, face, level, surf); ++ default: ++ ERR("Unexpected texture type\n"); ++ return E_NOTIMPL; ++ } ++} ++ ++HRESULT save_dds_texture_to_memory(ID3DXBuffer **dst_buffer, IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette) ++{ ++ HRESULT hr; ++ D3DRESOURCETYPE type; ++ UINT mip_levels; ++ IDirect3DSurface9 *surface; ++ ++ type = IDirect3DBaseTexture9_GetType(src_texture); ++ ++ if ((type != D3DRTYPE_TEXTURE) && (type != D3DRTYPE_CUBETEXTURE) && (type != D3DRTYPE_VOLUMETEXTURE)) ++ return D3DERR_INVALIDCALL; ++ ++ if (type == D3DRTYPE_CUBETEXTURE) ++ { ++ FIXME("Cube texture not supported yet\n"); ++ return E_NOTIMPL; ++ } ++ else if (type == D3DRTYPE_VOLUMETEXTURE) ++ { ++ FIXME("Volume texture not supported yet\n"); ++ return E_NOTIMPL; ++ } ++ ++ mip_levels = IDirect3DTexture9_GetLevelCount(src_texture); ++ ++ if (mip_levels > 1) ++ { ++ FIXME("Mipmap not supported yet\n"); ++ return E_NOTIMPL; ++ } ++ ++ if (src_palette) ++ { ++ FIXME("Saving surfaces with palettized pixel formats not implemented yet\n"); ++ return E_NOTIMPL; ++ } ++ ++ hr = get_surface(type, src_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface); ++ ++ if (SUCCEEDED(hr)) ++ { ++ hr = save_dds_surface_to_memory(dst_buffer, surface, NULL); ++ IDirect3DSurface9_Release(surface); ++ } ++ ++ return hr; ++} + HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette, + const D3DBOX *dst_box, const void *src_data, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key, + const D3DXIMAGE_INFO *src_info) +diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c +index 38349e2..5c06700 100644 +--- a/dlls/d3dx9_36/texture.c ++++ b/dlls/d3dx9_36/texture.c +@@ -1873,10 +1873,7 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE + if (!dst_buffer || !src_texture) return D3DERR_INVALIDCALL; + + if (file_format == D3DXIFF_DDS) +- { +- FIXME("DDS file format isn't supported yet\n"); +- return E_NOTIMPL; +- } ++ return save_dds_texture_to_memory(dst_buffer, src_texture, src_palette); + + type = IDirect3DBaseTexture9_GetType(src_texture); + switch (type) +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0003-d3dx9_36-Add-support-for-FOURCC-surface-to-save_dds_.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0003-d3dx9_36-Add-support-for-FOURCC-surface-to-save_dds_.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0003-d3dx9_36-Add-support-for-FOURCC-surface-to-save_dds_.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0003-d3dx9_36-Add-support-for-FOURCC-surface-to-save_dds_.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -From 26c87c400c478b878b72b9cb7d216f89a9a58d1f Mon Sep 17 00:00:00 2001 -From: Christian Costa -Date: Sun, 11 Jan 2015 16:18:03 +0100 -Subject: d3dx9_36: Add support for FOURCC surface to - save_dds_surface_to_memory. - ---- - dlls/d3dx9_36/surface.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c -index ae10adc..629c94c 100644 ---- a/dlls/d3dx9_36/surface.c -+++ b/dlls/d3dx9_36/surface.c -@@ -311,6 +311,14 @@ static HRESULT d3dformat_to_dds_pixel_format(struct dds_pixel_format *pixel_form - } - } - -+ /* Reuse dds_fourcc_to_d3dformat as D3DFORMAT and FOURCC are DWORD with same values */ -+ if (dds_fourcc_to_d3dformat(d3dformat) != D3DFMT_UNKNOWN) -+ { -+ pixel_format->flags |= DDS_PF_FOURCC; -+ pixel_format->fourcc = d3dformat; -+ return D3D_OK; -+ } -+ - WARN("Unknown pixel format %#x\n", d3dformat); - return E_NOTIMPL; - } -@@ -489,7 +497,9 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur - header->signature = MAKEFOURCC('D','D','S',' '); - /* The signature is not really part of the DDS header */ - header->size = sizeof(*header) - sizeof(header->signature); -- header->flags = DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PITCH | DDS_PIXELFORMAT; -+ header->flags = DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT; -+ /* Note that native does not set DDS_LINEARSIZE flag nor pitch_or_linear_size field for DXTn */ -+ header->flags |= (pixel_format->block_width != 1) || (pixel_format->block_height != 1) ? DDS_LINEARSIZE : DDS_PITCH; - header->height = src_desc.Height; - header->width = src_desc.Width; - header->pitch_or_linear_size = dst_pitch; --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0004-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0004-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DDS/0004-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DDS/0004-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -From 560676d5a7e14b73de4a1be6e47ee37754c0c331 Mon Sep 17 00:00:00 2001 -From: Christian Costa -Date: Sun, 11 Jan 2015 16:29:30 +0100 -Subject: d3dx9_36: Improve D3DXSaveTextureToFile to save simple texture to dds - file. - ---- - dlls/d3dx9_36/d3dx9_36_private.h | 2 ++ - dlls/d3dx9_36/surface.c | 62 ++++++++++++++++++++++++++++++++++++++++ - dlls/d3dx9_36/texture.c | 5 +--- - 3 files changed, 65 insertions(+), 4 deletions(-) - -diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h -index 79f3b76..41bed31 100644 ---- a/dlls/d3dx9_36/d3dx9_36_private.h -+++ b/dlls/d3dx9_36/d3dx9_36_private.h -@@ -97,6 +97,8 @@ HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *d - const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN; - HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, const void *src_data, - const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN; -+HRESULT save_dds_texture_to_memory(ID3DXBuffer **dst_buffer, IDirect3DBaseTexture9 *src_texture, -+ const PALETTEENTRY *src_palette) DECLSPEC_HIDDEN; - - unsigned short float_32_to_16(const float in) DECLSPEC_HIDDEN; - float float_16_to_32(const unsigned short in) DECLSPEC_HIDDEN; -diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c -index 629c94c..0a9c177 100644 ---- a/dlls/d3dx9_36/surface.c -+++ b/dlls/d3dx9_36/surface.c -@@ -530,6 +530,68 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur - return D3D_OK; - } - -+static HRESULT get_surface(D3DRESOURCETYPE type, struct IDirect3DBaseTexture9 *tex, -+ int face, UINT level, struct IDirect3DSurface9 **surf) -+{ -+ switch (type) -+ { -+ case D3DRTYPE_TEXTURE: -+ return IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) tex, level, surf); -+ case D3DRTYPE_CUBETEXTURE: -+ return IDirect3DCubeTexture9_GetCubeMapSurface((IDirect3DCubeTexture9*) tex, face, level, surf); -+ default: -+ ERR("Unexpected texture type\n"); -+ return E_NOTIMPL; -+ } -+} -+ -+HRESULT save_dds_texture_to_memory(ID3DXBuffer **dst_buffer, IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette) -+{ -+ HRESULT hr; -+ D3DRESOURCETYPE type; -+ UINT mip_levels; -+ IDirect3DSurface9 *surface; -+ -+ type = IDirect3DBaseTexture9_GetType(src_texture); -+ -+ if ((type != D3DRTYPE_TEXTURE) && (type != D3DRTYPE_CUBETEXTURE) && (type != D3DRTYPE_VOLUMETEXTURE)) -+ return D3DERR_INVALIDCALL; -+ -+ if (type == D3DRTYPE_CUBETEXTURE) -+ { -+ FIXME("Cube texture not supported yet\n"); -+ return E_NOTIMPL; -+ } -+ else if (type == D3DRTYPE_VOLUMETEXTURE) -+ { -+ FIXME("Volume texture not supported yet\n"); -+ return E_NOTIMPL; -+ } -+ -+ mip_levels = IDirect3DTexture9_GetLevelCount(src_texture); -+ -+ if (mip_levels > 1) -+ { -+ FIXME("Mipmap not supported yet\n"); -+ return E_NOTIMPL; -+ } -+ -+ if (src_palette) -+ { -+ FIXME("Saving surfaces with palettized pixel formats not implemented yet\n"); -+ return E_NOTIMPL; -+ } -+ -+ hr = get_surface(type, src_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface); -+ -+ if (SUCCEEDED(hr)) -+ { -+ hr = save_dds_surface_to_memory(dst_buffer, surface, NULL); -+ IDirect3DSurface9_Release(surface); -+ } -+ -+ return hr; -+} - HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette, - const D3DBOX *dst_box, const void *src_data, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key, - const D3DXIMAGE_INFO *src_info) -diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c -index de42307..e062379 100644 ---- a/dlls/d3dx9_36/texture.c -+++ b/dlls/d3dx9_36/texture.c -@@ -1873,10 +1873,7 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE - if (!dst_buffer || !src_texture) return D3DERR_INVALIDCALL; - - if (file_format == D3DXIFF_DDS) -- { -- FIXME("DDS file format isn't supported yet\n"); -- return E_NOTIMPL; -- } -+ return save_dds_texture_to_memory(dst_buffer, src_texture, src_palette); - - type = IDirect3DBaseTexture9_GetType(src_texture); - switch (type) --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DXTn/0001-d3dx9_36-Add-dxtn-support.patch wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DXTn/0001-d3dx9_36-Add-dxtn-support.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/d3dx9_36-DXTn/0001-d3dx9_36-Add-dxtn-support.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/d3dx9_36-DXTn/0001-d3dx9_36-Add-dxtn-support.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 2774478cc69a3305989724186a0b68ca99f1fe61 Mon Sep 17 00:00:00 2001 +From ee84dfd270e8bd762acf6589fe697cdcfc6b431b Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Sat, 1 Nov 2014 13:08:05 +0100 Subject: d3dx9_36: Add dxtn support. @@ -10,7 +10,7 @@ 3 files changed, 102 insertions(+), 12 deletions(-) diff --git a/dlls/d3dx9_36/Makefile.in b/dlls/d3dx9_36/Makefile.in -index 5958c57..aa387b5 100644 +index 95e3045..fd710c2 100644 --- a/dlls/d3dx9_36/Makefile.in +++ b/dlls/d3dx9_36/Makefile.in @@ -1,6 +1,6 @@ @@ -20,9 +20,9 @@ +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d C_SRCS = \ - core.c \ + animation.c \ diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c -index 295ef63..ed1caff 100644 +index 4fa2a76..832698e 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -18,6 +18,7 @@ @@ -42,7 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx); -@@ -1716,6 +1719,27 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic +@@ -1714,6 +1717,27 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic } } @@ -70,7 +70,7 @@ /************************************************************ * D3DXLoadSurfaceFromMemory * -@@ -1757,6 +1781,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, +@@ -1755,6 +1779,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, D3DSURFACE_DESC surfdesc; D3DLOCKED_RECT lockrect; struct volume src_size, dst_size; @@ -78,7 +78,7 @@ TRACE("(%p, %p, %s, %p, %#x, %u, %p, %s, %#x, 0x%08x)\n", dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), src_memory, src_format, -@@ -1838,8 +1863,15 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, +@@ -1836,8 +1861,15 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, } else /* Stretching or format conversion. */ { @@ -96,7 +96,7 @@ { FIXME("Format conversion missing %#x -> %#x\n", src_format, surfdesc.Format); return E_NOTIMPL; -@@ -1848,10 +1880,52 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, +@@ -1846,10 +1878,52 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, if (FAILED(IDirect3DSurface9_LockRect(dst_surface, &lockrect, dst_rect, 0))) return D3DXERR_INVALIDDATA; @@ -151,7 +151,7 @@ } else /* if ((filter & 0xf) == D3DX_FILTER_POINT) */ { -@@ -1860,14 +1934,30 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, +@@ -1858,14 +1932,30 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, /* Always apply a point filter until D3DX_FILTER_LINEAR, * D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented. */ @@ -186,10 +186,10 @@ /************************************************************ diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c -index 7a4dff8..87c3eb7 100644 +index 55e3d88..3c953b0 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c -@@ -1103,7 +1103,7 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) +@@ -1174,7 +1174,7 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf); ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr); hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0); @@ -198,7 +198,7 @@ check_release((IUnknown*)newsurf, 1); check_release((IUnknown*)tex, 0); } -@@ -1129,7 +1129,7 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) +@@ -1200,7 +1200,7 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf); ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr); hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0); @@ -207,7 +207,7 @@ check_release((IUnknown*)newsurf, 1); check_release((IUnknown*)tex, 0); } -@@ -1142,10 +1142,10 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) +@@ -1213,10 +1213,10 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf); ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr); hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0); @@ -221,5 +221,5 @@ check_release((IUnknown*)newsurf, 1); check_release((IUnknown*)tex, 0); -- -2.3.3 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-Device_Caps/0001-ddraw-Don-t-set-HWTRANSFORMANDLIGHT-flag-on-d3d7-RGB.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-Device_Caps/0001-ddraw-Don-t-set-HWTRANSFORMANDLIGHT-flag-on-d3d7-RGB.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-Device_Caps/0001-ddraw-Don-t-set-HWTRANSFORMANDLIGHT-flag-on-d3d7-RGB.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-Device_Caps/0001-ddraw-Don-t-set-HWTRANSFORMANDLIGHT-flag-on-d3d7-RGB.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,116 @@ +From 63d0af4a9607ae31514604032a5504457ad84097 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 6 Feb 2016 01:15:07 +0100 +Subject: ddraw: Don't set HWTRANSFORMANDLIGHT flag on d3d7 RGB device. + +--- + dlls/ddraw/ddraw.c | 9 +++++++++ + dlls/ddraw/tests/ddraw7.c | 18 ++++++++++++++++++ + 2 files changed, 27 insertions(+) + +diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c +index 89ce07a..64548a0 100644 +--- a/dlls/ddraw/ddraw.c ++++ b/dlls/ddraw/ddraw.c +@@ -48,6 +48,7 @@ static struct enum_device_entry + char interface_name[100]; + char device_name[100]; + const GUID *device_guid; ++ DWORD remove_caps; + } device_list7[] = + { + /* T&L HAL device */ +@@ -55,6 +56,7 @@ static struct enum_device_entry + "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D", + "Wine D3D7 T&L HAL", + &IID_IDirect3DTnLHalDevice, ++ 0, + }, + + /* HAL device */ +@@ -62,6 +64,7 @@ static struct enum_device_entry + "WINE Direct3D7 Hardware acceleration using WineD3D", + "Direct3D HAL", + &IID_IDirect3DHALDevice, ++ 0, + }, + + /* RGB device */ +@@ -69,6 +72,7 @@ static struct enum_device_entry + "WINE Direct3D7 RGB Software Emulation using WineD3D", + "Wine D3D7 RGB", + &IID_IDirect3DRGBDevice, ++ D3DDEVCAPS_HWTRANSFORMANDLIGHT, + }, + }; + +@@ -3565,6 +3569,7 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA + { + struct ddraw *ddraw = impl_from_IDirect3D7(iface); + D3DDEVICEDESC7 device_desc7; ++ DWORD dev_caps; + HRESULT hr; + size_t i; + +@@ -3581,11 +3586,15 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA + return hr; + } + ++ dev_caps = device_desc7.dwDevCaps; ++ + for (i = 0; i < sizeof(device_list7)/sizeof(device_list7[0]); i++) + { + HRESULT ret; + + device_desc7.deviceGUID = *device_list7[i].device_guid; ++ device_desc7.dwDevCaps = dev_caps & ~device_list7[i].remove_caps; ++ + ret = callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context); + if (ret != DDENUMRET_OK) + { +diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c +index 34167c1..76dabee 100644 +--- a/dlls/ddraw/tests/ddraw7.c ++++ b/dlls/ddraw/tests/ddraw7.c +@@ -230,6 +230,19 @@ static HRESULT WINAPI enum_devtype_cb(char *desc_str, char *name, D3DDEVICEDESC7 + return DDENUMRET_OK; + } + ++static HRESULT WINAPI enum_devtype_software_cb(char *desc_str, char *name, D3DDEVICEDESC7 *desc, void *ctx) ++{ ++ BOOL *software_ok = ctx; ++ if (IsEqualGUID(&desc->deviceGUID, &IID_IDirect3DRGBDevice)) ++ { ++ ok(!(desc->dwDevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT), ++ "RGB emulation device shouldn't have HWTRANSFORMANDLIGHT flag\n"); ++ *software_ok = TRUE; ++ return DDENUMRET_CANCEL; ++ } ++ return DDENUMRET_OK; ++} ++ + static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) + { + IDirectDrawSurface7 *surface, *ds; +@@ -240,6 +253,7 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) + IDirect3D7 *d3d7; + HRESULT hr; + BOOL hal_ok = FALSE; ++ BOOL software_ok = FALSE; + const GUID *devtype = &IID_IDirect3DHALDevice; + + if (!(ddraw = create_ddraw())) +@@ -283,6 +297,10 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level) + ok(SUCCEEDED(hr), "Failed to enumerate devices, hr %#x.\n", hr); + if (hal_ok) devtype = &IID_IDirect3DTnLHalDevice; + ++ hr = IDirect3D7_EnumDevices(d3d7, enum_devtype_software_cb , &software_ok); ++ ok(SUCCEEDED(hr), "Failed to enumerate devices, hr %#x.\n", hr); ++ if (!software_ok) win_skip("RGB device not found, unable to check flags\n"); ++ + memset(&z_fmt, 0, sizeof(z_fmt)); + hr = IDirect3D7_EnumZBufferFormats(d3d7, devtype, enum_z_fmt, &z_fmt); + if (FAILED(hr) || !z_fmt.dwSize) +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-Device_Caps/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-Device_Caps/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-Device_Caps/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-Device_Caps/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Don't set HWTRANSFORMANDLIGHT flag on d3d7 RGB device diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-IDirect3DTexture2_Load/0001-ddraw-Allow-size-and-format-conversions-in-IDirect3D.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-IDirect3DTexture2_Load/0001-ddraw-Allow-size-and-format-conversions-in-IDirect3D.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-IDirect3DTexture2_Load/0001-ddraw-Allow-size-and-format-conversions-in-IDirect3D.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-IDirect3DTexture2_Load/0001-ddraw-Allow-size-and-format-conversions-in-IDirect3D.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,17 +1,17 @@ -From f1ad7b7975ed611a4989986f35ea3695eca0f26c Mon Sep 17 00:00:00 2001 +From aee6d79ac93aecb6eb7927e42736609d0d473c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sat, 30 May 2015 02:55:03 +0200 Subject: ddraw: Allow size and format conversions in IDirect3DTexture2::Load. --- - dlls/ddraw/surface.c | 147 ++++++++++++++++++++++++++------------------------- - 1 file changed, 76 insertions(+), 71 deletions(-) + dlls/ddraw/surface.c | 151 +++++++++++++++++++++++++++------------------------ + 1 file changed, 80 insertions(+), 71 deletions(-) diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c -index 8a10eff..cb71a65 100644 +index 6a07cd7..cacf14c 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c -@@ -5062,6 +5062,46 @@ static struct ddraw_surface *get_sub_mimaplevel(struct ddraw_surface *surface) +@@ -5041,6 +5041,46 @@ static struct ddraw_surface *get_sub_mimaplevel(struct ddraw_surface *surface) return impl_from_IDirectDrawSurface7(next_level); } @@ -58,10 +58,22 @@ /***************************************************************************** * IDirect3DTexture2::Load * -@@ -5095,90 +5135,56 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu +@@ -5062,7 +5102,7 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu + { + struct ddraw_surface *dst_surface = impl_from_IDirect3DTexture2(iface); + struct ddraw_surface *src_surface = unsafe_impl_from_IDirect3DTexture2(src_texture); +- struct wined3d_resource *dst_resource, *src_resource; ++ RECT src_rect, dst_rect; + HRESULT hr; + + TRACE("iface %p, src_texture %p.\n", iface, src_texture); +@@ -5075,90 +5115,60 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu wined3d_mutex_lock(); +- dst_resource = wined3d_texture_get_resource(dst_surface->wined3d_texture); +- src_resource = wined3d_texture_get_resource(src_surface->wined3d_texture); +- - if (((src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) - != (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) - || (src_surface->surface_desc.u2.dwMipMapCount != dst_surface->surface_desc.u2.dwMipMapCount)) @@ -143,37 +155,37 @@ + return E_FAIL; + } -- /* Copy the main memory texture into the surface that corresponds -- * to the OpenGL texture object. */ -- -- hr = wined3d_surface_map(src_surface->wined3d_surface, &src_map_desc, NULL, 0); -- if (FAILED(hr)) +- if (FAILED(hr = wined3d_resource_sub_resource_map(src_resource, +- src_surface->sub_resource_idx, &src_map_desc, NULL, 0))) - { - ERR("Failed to lock source surface, hr %#x.\n", hr); - wined3d_mutex_unlock(); - return D3DERR_TEXTURE_LOAD_FAILED; - } - -- hr = wined3d_surface_map(dst_surface->wined3d_surface, &dst_map_desc, NULL, 0); -- if (FAILED(hr)) +- if (FAILED(hr = wined3d_resource_sub_resource_map(dst_resource, +- dst_surface->sub_resource_idx, &dst_map_desc, NULL, 0))) - { - ERR("Failed to lock destination surface, hr %#x.\n", hr); -- wined3d_surface_unmap(src_surface->wined3d_surface); +- wined3d_resource_sub_resource_unmap(src_resource, src_surface->sub_resource_idx); - wined3d_mutex_unlock(); - return D3DERR_TEXTURE_LOAD_FAILED; - } -- ++ /* Suppress the ALLOCONLOAD flag */ ++ dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; + - if (dst_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) - memcpy(dst_map_desc.data, src_map_desc.data, src_surface->surface_desc.u1.dwLinearSize); - else - memcpy(dst_map_desc.data, src_map_desc.data, src_map_desc.row_pitch * src_desc->dwHeight); -+ /* Suppress the ALLOCONLOAD flag */ -+ dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; ++ SetRect(&src_rect, 0, 0, src_surface->surface_desc.dwWidth, src_surface->surface_desc.dwHeight); ++ SetRect(&dst_rect, 0, 0, dst_surface->surface_desc.dwWidth, dst_surface->surface_desc.dwHeight); -- wined3d_surface_unmap(src_surface->wined3d_surface); -- wined3d_surface_unmap(dst_surface->wined3d_surface); -+ hr = wined3d_surface_blt(dst_surface->wined3d_surface, NULL, src_surface->wined3d_surface, -+ NULL, 0, NULL, WINED3D_TEXF_LINEAR); +- wined3d_resource_sub_resource_unmap(dst_resource, dst_surface->sub_resource_idx); +- wined3d_resource_sub_resource_unmap(src_resource, src_surface->sub_resource_idx); ++ hr = wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, &dst_rect, ++ src_surface->wined3d_texture, src_surface->sub_resource_idx, &src_rect, ++ 0, NULL, WINED3D_TEXF_LINEAR); + if (FAILED(hr)) + { + ERR("Failed to blit surface, hr %#x.\n", hr); @@ -182,7 +194,7 @@ } if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) -@@ -5191,12 +5197,11 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu +@@ -5171,12 +5181,11 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu else dst_surface = NULL; @@ -199,5 +211,5 @@ wined3d_mutex_unlock(); -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-IDirect3DTexture2_Load/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-IDirect3DTexture2_Load/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-IDirect3DTexture2_Load/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-IDirect3DTexture2_Load/definition 2016-02-08 20:07:32.000000000 +0000 @@ -1 +1,2 @@ Fixes: Fix scaling behaviour of images and mipmap levels in IDirect3DTexture2_Load (needed for example by Prezzie Hunt) +Depends: wined3d-resource_map diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/0001-Revert-ddraw-Use-wined3d_texture_get_sub_resource-in.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/0001-Revert-ddraw-Use-wined3d_texture_get_sub_resource-in.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/0001-Revert-ddraw-Use-wined3d_texture_get_sub_resource-in.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/0001-Revert-ddraw-Use-wined3d_texture_get_sub_resource-in.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,90 @@ +From 4227226984e3726aba1b0570db87679776842c5a Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sun, 7 Feb 2016 18:52:16 +0100 +Subject: Revert "ddraw: Use wined3d_texture_get_sub_resource() in + ddraw_surface7_Flip()." + +This reverts commit b1709522307a160a7c151f5293095a3c26ab998f. +--- + dlls/ddraw/surface.c | 6 +++--- + dlls/wined3d/surface.c | 7 +++++++ + dlls/wined3d/wined3d.spec | 1 + + include/wine/wined3d.h | 1 + + 4 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c +index f1ba858..a6fbceb 100644 +--- a/dlls/ddraw/surface.c ++++ b/dlls/ddraw/surface.c +@@ -1268,7 +1268,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 + wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE); + wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); + dst_impl->wined3d_rtv = src_rtv; +- wined3d_resource_set_parent(wined3d_texture_get_sub_resource(src_impl->wined3d_texture, 0), dst_impl); ++ wined3d_resource_set_parent(wined3d_surface_get_resource(src_impl->wined3d_surface), dst_impl); + dst_impl->wined3d_surface = src_impl->wined3d_surface; + prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); + wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), ddraw_texture); +@@ -1300,7 +1300,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 + wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE); + wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); + dst_impl->wined3d_rtv = src_rtv; +- wined3d_resource_set_parent(wined3d_texture_get_sub_resource(src_impl->wined3d_texture, 0), dst_impl); ++ wined3d_resource_set_parent(wined3d_surface_get_resource(src_impl->wined3d_surface), dst_impl); + dst_impl->wined3d_surface = src_impl->wined3d_surface; + prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture); + wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_texture), ddraw_texture); +@@ -1318,7 +1318,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 + wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, tmp_rtv, FALSE); + wined3d_rendertarget_view_set_parent(tmp_rtv, src_impl); + src_impl->wined3d_rtv = tmp_rtv; +- wined3d_resource_set_parent(wined3d_texture_get_sub_resource(texture, 0), src_impl); ++ wined3d_resource_set_parent(wined3d_surface_get_resource(tmp), src_impl); + src_impl->wined3d_surface = tmp; + wined3d_resource_set_parent(wined3d_texture_get_resource(texture), ddraw_texture); + src_impl->wined3d_texture = texture; +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 2a36619..e6c6258 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -1890,6 +1890,13 @@ void * CDECL wined3d_surface_get_parent(const struct wined3d_surface *surface) + return surface->resource.parent; + } + ++struct wined3d_resource * CDECL wined3d_surface_get_resource(struct wined3d_surface *surface) ++{ ++ TRACE("surface %p.\n", surface); ++ ++ return &surface->resource; ++} ++ + DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface) + { + unsigned int alignment; +diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec +index 86d03f0..c07e0ca 100644 +--- a/dlls/wined3d/wined3d.spec ++++ b/dlls/wined3d/wined3d.spec +@@ -225,6 +225,7 @@ + @ cdecl wined3d_surface_get_overlay_position(ptr ptr ptr) + @ cdecl wined3d_surface_get_parent(ptr) + @ cdecl wined3d_surface_get_pitch(ptr) ++@ cdecl wined3d_surface_get_resource(ptr) + @ cdecl wined3d_surface_set_overlay_position(ptr long long) + @ cdecl wined3d_surface_update_overlay(ptr ptr ptr ptr long ptr) + @ cdecl wined3d_surface_update_overlay_z_order(ptr long ptr) +diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h +index 8f9d80a..1b13a20 100644 +--- a/include/wine/wined3d.h ++++ b/include/wine/wined3d.h +@@ -2477,6 +2477,7 @@ ULONG __cdecl wined3d_stateblock_incref(struct wined3d_stateblock *stateblock); + HRESULT __cdecl wined3d_surface_get_overlay_position(const struct wined3d_surface *surface, LONG *x, LONG *y); + void * __cdecl wined3d_surface_get_parent(const struct wined3d_surface *surface); + DWORD __cdecl wined3d_surface_get_pitch(const struct wined3d_surface *surface); ++struct wined3d_resource * __cdecl wined3d_surface_get_resource(struct wined3d_surface *surface); + HRESULT __cdecl wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y); + HRESULT __cdecl wined3d_surface_update_overlay(struct wined3d_surface *surface, const RECT *src_rect, + struct wined3d_surface *dst_surface, const RECT *dst_rect, DWORD flags, const WINEDDOVERLAYFX *fx); +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/0002-Revert-ddraw-Move-the-mip-level-dimensions-fix-up-fr.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/0002-Revert-ddraw-Move-the-mip-level-dimensions-fix-up-fr.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/0002-Revert-ddraw-Move-the-mip-level-dimensions-fix-up-fr.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/0002-Revert-ddraw-Move-the-mip-level-dimensions-fix-up-fr.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,64 @@ +From e70e6047539d266d0b7101e92ba789eed5cf9928 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sun, 7 Feb 2016 18:52:49 +0100 +Subject: Revert "ddraw: Move the mip-level dimensions fix-up from + ddraw_surface_init() to ddraw_surface_create()." + +This reverts commit 7d45318aeac41e2efabb9ddfbf95ecbea103e67d. +--- + dlls/ddraw/surface.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c +index a6fbceb..923a935 100644 +--- a/dlls/ddraw/surface.c ++++ b/dlls/ddraw/surface.c +@@ -5643,8 +5643,8 @@ static HRESULT CDECL ddraw_reset_enum_callback(struct wined3d_resource *resource + HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc, + struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) + { +- struct wined3d_resource_desc wined3d_desc, wined3d_mip_desc; + struct ddraw_surface *root, *mip, **attach; ++ struct wined3d_resource_desc wined3d_desc; + struct wined3d_texture *wined3d_texture; + struct wined3d_resource *resource; + struct wined3d_display_mode mode; +@@ -6103,17 +6103,9 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ + mip_desc = &mip->surface_desc; + + if (j) +- { +- wined3d_resource_get_desc(resource, &wined3d_mip_desc); +- mip_desc->dwWidth = wined3d_mip_desc.width; +- mip_desc->dwHeight = wined3d_mip_desc.height; +- + mip_desc->ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL; +- } + else +- { + mip_desc->ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL; +- } + + if (mip_desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) + { +@@ -6241,6 +6233,7 @@ void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, + { + struct ddraw_texture *texture = wined3d_texture_get_parent(wined3d_texture); + DDSURFACEDESC2 *desc = &surface->surface_desc; ++ struct wined3d_resource_desc wined3d_desc; + unsigned int version = texture->version; + + surface->IDirectDrawSurface7_iface.lpVtbl = &ddraw_surface7_vtbl; +@@ -6272,6 +6265,9 @@ void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, + } + + *desc = texture->surface_desc; ++ wined3d_resource_get_desc(wined3d_surface_get_resource(wined3d_surface), &wined3d_desc); ++ desc->dwWidth = wined3d_desc.width; ++ desc->dwHeight = wined3d_desc.height; + surface->first_attached = surface; + + if (format_is_compressed(&desc->u4.ddpfPixelFormat)) +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ddraw-Revert_Surface_Init/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [40094] Revert patches to move mip-level dimensions fixup (causes regressions in multiple games) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/dxdiagn-Display_Information/0001-dxdiagn-Add-several-more-fields-for-DisplayDevices.patch wine-staging-1.9.3~ubuntu12.04.1/patches/dxdiagn-Display_Information/0001-dxdiagn-Add-several-more-fields-for-DisplayDevices.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/dxdiagn-Display_Information/0001-dxdiagn-Add-several-more-fields-for-DisplayDevices.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/dxdiagn-Display_Information/0001-dxdiagn-Add-several-more-fields-for-DisplayDevices.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,238 @@ +From 90a30be3a8ef4132092e26c05695521449e68d2c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 6 Feb 2016 17:48:00 +0100 +Subject: dxdiagn: Add several more fields for DisplayDevices. + +--- + dlls/dxdiagn/provider.c | 159 +++++++++++++++++++++++++++++++++++++++++ + dlls/dxdiagn/tests/container.c | 2 + + 2 files changed, 161 insertions(+) + +diff --git a/dlls/dxdiagn/provider.c b/dlls/dxdiagn/provider.c +index 5665d01..4f964ad 100644 +--- a/dlls/dxdiagn/provider.c ++++ b/dlls/dxdiagn/provider.c +@@ -60,6 +60,8 @@ static const WCHAR dwHeight[] = {'d','w','H','e','i','g','h','t',0}; + static const WCHAR dwBpp[] = {'d','w','B','p','p',0}; + static const WCHAR szDisplayMemoryLocalized[] = {'s','z','D','i','s','p','l','a','y','M','e','m','o','r','y','L','o','c','a','l','i','z','e','d',0}; + static const WCHAR szDisplayMemoryEnglish[] = {'s','z','D','i','s','p','l','a','y','M','e','m','o','r','y','E','n','g','l','i','s','h',0}; ++static const WCHAR szDisplayModeLocalized[] = {'s','z','D','i','s','p','l','a','y','M','o','d','e','L','o','c','a','l','i','z','e','d',0}; ++static const WCHAR szDisplayModeEnglish[] = {'s','z','D','i','s','p','l','a','y','M','o','d','e','E','n','g','l','i','s','h',0}; + static const WCHAR szDriverName[] = {'s','z','D','r','i','v','e','r','N','a','m','e',0}; + static const WCHAR szDriverVersion[] = {'s','z','D','r','i','v','e','r','V','e','r','s','i','o','n',0}; + static const WCHAR szSubSysId[] = {'s','z','S','u','b','S','y','s','I','d',0}; +@@ -69,6 +71,30 @@ static const WCHAR szManufacturer[] = {'s','z','M','a','n','u','f','a','c','t',' + static const WCHAR szChipType[] = {'s','z','C','h','i','p','T','y','p','e',0}; + static const WCHAR szDACType[] = {'s','z','D','A','C','T','y','p','e',0}; + static const WCHAR szRevision[] = {'s','z','R','e','v','i','s','i','o','n',0}; ++static const WCHAR szMonitorName[] = {'s','z','M','o','n','i','t','o','r','N','a','m','e',0}; ++static const WCHAR szMonitorMaxRes[] = {'s','z','M','o','n','i','t','o','r','M','a','x','R','e','s',0}; ++static const WCHAR szDriverAttributes[] = {'s','z','D','r','i','v','e','r','A','t','t','r','i','b','u','t','e','s',0}; ++static const WCHAR szDriverLanguageEnglish[] = {'s','z','D','r','i','v','e','r','L','a','n','g','u','a','g','e','E','n','g','l','i','s','h',0}; ++static const WCHAR szDriverLanguageLocalized[] = {'s','z','D','r','i','v','e','r','L','a','n','g','u','a','g','e','L','o','c','a','l','i','z','e','d',0}; ++static const WCHAR szDriverDateEnglish[] = {'s','z','D','r','i','v','e','r','D','a','t','e','E','n','g','l','i','s','h',0}; ++static const WCHAR szDriverDateLocalized[] = {'s','z','D','r','i','v','e','r','D','a','t','e','L','o','c','a','l','i','z','e','d',0}; ++static const WCHAR lDriverSize[] = {'l','D','r','i','v','e','r','S','i','z','e',0}; ++static const WCHAR szMiniVdd[] = {'s','z','M','i','n','i','V','d','d',0}; ++static const WCHAR szMiniVddDateLocalized[] = {'s','z','M','i','n','i','V','d','d','D','a','t','e','L','o','c','a','l','i','z','e','d',0}; ++static const WCHAR szMiniVddDateEnglish[] = {'s','z','M','i','n','i','V','d','d','D','a','t','e','E','n','g','l','i','s','h',0}; ++static const WCHAR lMiniVddSize[] = {'l','M','i','n','i','V','d','d','S','i','z','e',0}; ++static const WCHAR szVdd[] = {'s','z','V','d','d',0}; ++static const WCHAR bCanRenderWindow[] = {'b','C','a','n','R','e','n','d','e','r','W','i','n','d','o','w',0}; ++static const WCHAR bDriverBeta[] = {'b','D','r','i','v','e','r','B','e','t','a',0}; ++static const WCHAR bDriverDebug[] = {'b','D','r','i','v','e','r','D','e','b','u','g',0}; ++static const WCHAR bDriverSigned[] = {'b','D','r','i','v','e','r','S','i','g','n','e','d',0}; ++static const WCHAR bDriverSignedValid[] = {'b','D','r','i','v','e','r','S','i','g','n','e','d','V','a','l','i','d',0}; ++static const WCHAR szDriverSignDate[] = {'s','z','D','r','i','v','e','r','S','i','g','n','D','a','t','e',0}; ++static const WCHAR dwDDIVersion[] = {'d','w','D','D','I','V','e','r','s','i','o','n',0}; ++static const WCHAR szDDIVersionEnglish[] = {'s','z','D','D','I','V','e','r','s','i','o','n','E','n','g','l','i','s','h',0}; ++static const WCHAR szDDIVersionLocalized[] = {'s','z','D','D','I','V','e','r','s','i','o','n','L','o','c','a','l','i','z','e','d',0}; ++static const WCHAR iAdapter[] = {'i','A','d','a','p','t','e','r',0}; ++static const WCHAR dwWHQLLevel[] = {'d','w','W','H','Q','L','L','e','v','e','l',0}; + + struct IDxDiagProviderImpl + { +@@ -326,6 +352,23 @@ static inline HRESULT add_ui4_property(IDxDiagContainerImpl_Container *node, con + return S_OK; + } + ++static inline HRESULT add_i4_property(IDxDiagContainerImpl_Container *node, const WCHAR *propName, LONG data) ++{ ++ IDxDiagContainerImpl_Property *prop; ++ ++ prop = allocate_property_information(propName); ++ if (!prop) ++ return E_OUTOFMEMORY; ++ ++ V_VT(&prop->vProp) = VT_I4; ++ V_I4(&prop->vProp) = data; ++ ++ list_add_tail(&node->properties, &prop->entry); ++ ++node->nProperties; ++ ++ return S_OK; ++} ++ + static inline HRESULT add_bool_property(IDxDiagContainerImpl_Container *node, const WCHAR *propName, BOOL data) + { + IDxDiagContainerImpl_Property *prop; +@@ -925,6 +968,15 @@ static HRESULT fill_display_information_d3d(IDxDiagContainerImpl_Container *node + static const WCHAR b3DAccelerationEnabled[] = {'b','3','D','A','c','c','e','l','e','r','a','t','i','o','n','E','n','a','b','l','e','d',0}; + static const WCHAR bDDAccelerationEnabled[] = {'b','D','D','A','c','c','e','l','e','r','a','t','i','o','n','E','n','a','b','l','e','d',0}; + static const WCHAR bNoHardware[] = {'b','N','o','H','a','r','d','w','a','r','e',0}; ++ static const WCHAR mode_fmtW[] = {'%','d',' ','x',' ','%','d',' ','(','%','d',' ','b','i','t',')',' ','(','%','d','H','z',')',0}; ++ static const WCHAR gernericPNPMonitorW[] = {'G','e','n','e','r','i','c',' ','P','n','P',' ','M','o','n','i','t','o','r',0}; ++ static const WCHAR failedToGetParameterW[] = {'F','a','i','l','e','d',' ','t','o',' ','g','e','t',' ','p','a','r','a','m','e','t','e','r',0}; ++ static const WCHAR driverAttributesW[] = {'F','i','n','a','l',' ','R','e','t','a','i','l',0}; ++ static const WCHAR englishW[] = {'E','n','g','l','i','s','h',0}; ++ static const WCHAR driverDateEnglishW[] = {'1','/','1','/','2','0','1','6',' ','1','0',':','0','0',':','0','0',0}; ++ static const WCHAR driverDateLocalW[] = {'1','/','1','/','2','0','1','6',' ','1','0',':','0','0',':','0','0',' ','A','M',0}; ++ static const WCHAR naW[] = {'n','/','a',0}; ++ static const WCHAR ddi11W[] = {'1','1',0}; + + D3DADAPTER_IDENTIFIER9 adapter_info; + D3DDISPLAYMODE adapter_mode; +@@ -1021,6 +1073,17 @@ static HRESULT fill_display_information_d3d(IDxDiagContainerImpl_Container *node + hr = add_ui4_property(display_adapter, dwBpp, depth_for_pixelformat(adapter_mode.Format)); + if (FAILED(hr)) + goto cleanup; ++ ++ snprintfW(buffer, sizeof(buffer)/sizeof(WCHAR), mode_fmtW, adapter_mode.Width, adapter_mode.Height, ++ depth_for_pixelformat(adapter_mode.Format), adapter_mode.RefreshRate); ++ ++ hr = add_bstr_property(display_adapter, szDisplayModeLocalized, buffer); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szDisplayModeEnglish, buffer); ++ if (FAILED(hr)) ++ goto cleanup; + } + + hr = add_bstr_property(display_adapter, szKeyDeviceKey, szEmpty); +@@ -1074,6 +1137,102 @@ static HRESULT fill_display_information_d3d(IDxDiagContainerImpl_Container *node + hr = add_bool_property(display_adapter, bNoHardware, FALSE); + if (FAILED(hr)) + goto cleanup; ++ ++ hr = add_bool_property(display_adapter, bCanRenderWindow, TRUE); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szMonitorName, gernericPNPMonitorW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szMonitorMaxRes, failedToGetParameterW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szDriverAttributes, driverAttributesW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szDriverLanguageEnglish, englishW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szDriverLanguageLocalized, englishW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szDriverDateEnglish, driverDateEnglishW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szDriverDateLocalized, driverDateLocalW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_i4_property(display_adapter, lDriverSize, 10 * 1024 * 1024); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szMiniVdd, naW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szMiniVddDateLocalized, naW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szMiniVddDateEnglish, naW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_i4_property(display_adapter, lMiniVddSize, 0); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szVdd, naW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bool_property(display_adapter, bDriverBeta, FALSE); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bool_property(display_adapter, bDriverDebug, FALSE); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bool_property(display_adapter, bDriverSigned, TRUE); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bool_property(display_adapter, bDriverSignedValid, TRUE); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szDriverSignDate, naW); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_ui4_property(display_adapter, dwDDIVersion, 11); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szDDIVersionEnglish, ddi11W); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_bstr_property(display_adapter, szDDIVersionLocalized, ddi11W); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_ui4_property(display_adapter, iAdapter, index); ++ if (FAILED(hr)) ++ goto cleanup; ++ ++ hr = add_ui4_property(display_adapter, dwWHQLLevel, 0); ++ if (FAILED(hr)) ++ goto cleanup; + } + + hr = S_OK; +diff --git a/dlls/dxdiagn/tests/container.c b/dlls/dxdiagn/tests/container.c +index 5bc5161..e5afba7 100644 +--- a/dlls/dxdiagn/tests/container.c ++++ b/dlls/dxdiagn/tests/container.c +@@ -942,6 +942,7 @@ static void test_DxDiag_DisplayDevices(void) + static const WCHAR b3DAccelerationExists[] = {'b','3','D','A','c','c','e','l','e','r','a','t','i','o','n','E','x','i','s','t','s',0}; + static const WCHAR b3DAccelerationEnabled[] = {'b','3','D','A','c','c','e','l','e','r','a','t','i','o','n','E','n','a','b','l','e','d',0}; + static const WCHAR bDDAccelerationEnabled[] = {'b','D','D','A','c','c','e','l','e','r','a','t','i','o','n','E','n','a','b','l','e','d',0}; ++ static const WCHAR iAdapter[] = {'i','A','d','a','p','t','e','r',0}; + + static const struct property_test property_tests[] = + { +@@ -966,6 +967,7 @@ static void test_DxDiag_DisplayDevices(void) + {b3DAccelerationExists, VT_BOOL}, + {b3DAccelerationEnabled, VT_BOOL}, + {bDDAccelerationEnabled, VT_BOOL}, ++ {iAdapter, VT_UI4}, + }; + + IDxDiagContainer *display_cont = NULL; +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/dxdiagn-Display_Information/definition wine-staging-1.9.3~ubuntu12.04.1/patches/dxdiagn-Display_Information/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/dxdiagn-Display_Information/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/dxdiagn-Display_Information/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [34686] Return additional properties for display devices in dxdiagn diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/explorer-Video_Registry_Key/0001-explorer-Create-CurrentControlSet-Control-Video-regi.patch wine-staging-1.9.3~ubuntu12.04.1/patches/explorer-Video_Registry_Key/0001-explorer-Create-CurrentControlSet-Control-Video-regi.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/explorer-Video_Registry_Key/0001-explorer-Create-CurrentControlSet-Control-Video-regi.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/explorer-Video_Registry_Key/0001-explorer-Create-CurrentControlSet-Control-Video-regi.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,63 @@ +From cccf1b75e810985c817d34329878f497d853d3ac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 9 Jan 2016 16:57:49 +0100 +Subject: explorer: Create CurrentControlSet\Control\Video registry key as + non-volatile. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Michael Müller +--- + dlls/advapi32/tests/registry.c | 7 +++++++ + programs/explorer/desktop.c | 9 +++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c +index ef5d989..6387697 100644 +--- a/dlls/advapi32/tests/registry.c ++++ b/dlls/advapi32/tests/registry.c +@@ -1340,6 +1340,13 @@ static void test_reg_create_key(void) + RegDeleteKeyA(hkey1, ""); + RegCloseKey(hkey1); + ++ /* System\CurrentControlSet\Control\Video should be non-volatile */ ++ ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Video\\Wine", ++ 0, NULL, 0, KEY_NOTIFY, NULL, &hkey1, NULL); ++ ok(ret == ERROR_SUCCESS, "RegCreateKeyExA failed with error %d\n", ret); ++ RegDeleteKeyA(hkey1, ""); ++ RegCloseKey(hkey1); ++ + /* WOW64 flags - open an existing key */ + hkey1 = NULL; + ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, KEY_READ|KEY_WOW64_32KEY, NULL, &hkey1, NULL); +diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c +index 2b8502b..85cb4bc 100644 +--- a/programs/explorer/desktop.c ++++ b/programs/explorer/desktop.c +@@ -775,6 +775,11 @@ static BOOL get_default_enable_shell( const WCHAR *name ) + + static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid ) + { ++ static const WCHAR video_keyW[] = { ++ 'S','y','s','t','e','m','\\', ++ 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', ++ 'C','o','n','t','r','o','l','\\', ++ 'V','i','d','e','o',0}; + static const WCHAR device_keyW[] = { + 'S','y','s','t','e','m','\\', + 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', +@@ -838,6 +843,10 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid ) + TRACE( "display %s driver %s\n", debugstr_guid(guid), debugstr_w(buffer) ); + } + ++ /* create video key first without REG_OPTION_VOLATILE attribute */ ++ if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, video_keyW, 0, NULL, 0, KEY_SET_VALUE, NULL, &hkey, NULL )) ++ RegCloseKey( hkey ); ++ + sprintfW( key, device_keyW, guid->Data1, guid->Data2, guid->Data3, + guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], + guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] ); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/explorer-Video_Registry_Key/definition wine-staging-1.9.3~ubuntu12.04.1/patches/explorer-Video_Registry_Key/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/explorer-Video_Registry_Key/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/explorer-Video_Registry_Key/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Registry key System\CurrentControlSet\Control\Video should be non-volatile diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/fonts-Missing_Fonts/0005-Add-licenses-for-fonts-as-separate-files.patch wine-staging-1.9.3~ubuntu12.04.1/patches/fonts-Missing_Fonts/0005-Add-licenses-for-fonts-as-separate-files.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/fonts-Missing_Fonts/0005-Add-licenses-for-fonts-as-separate-files.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/fonts-Missing_Fonts/0005-Add-licenses-for-fonts-as-separate-files.patch 2016-02-08 20:07:32.000000000 +0000 @@ -918,7 +918,7 @@ + +----------------------------------------------------------------------- + - Copyright (c) 1993-2015 the Wine project authors (see the file AUTHORS + Copyright (c) 1993-2016 the Wine project authors (see the file AUTHORS for a complete list) Wine is free software; you can redistribute it and/or modify it under diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/gitapply.sh wine-staging-1.9.3~ubuntu12.04.1/patches/gitapply.sh --- wine-staging-1.9.0~ubuntu12.04.1/patches/gitapply.sh 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/gitapply.sh 2016-02-08 20:07:32.000000000 +0000 @@ -2,7 +2,7 @@ # # Wrapper to apply binary patches without git. # -# Copyright (C) 2014-2015 Sebastian Lackner +# Copyright (C) 2014-2016 Sebastian Lackner # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -237,7 +237,7 @@ BEGIN{ ofs=1; } -!/^(--- |\+\+\+ |old |new |copy |rename |similarity |index |GIT |literal |delta )/{ +!/^(--- |\+\+\+ |old |deleted |new |copy |rename |similarity |index |GIT |literal |delta )/{ ofs=0; exit 0; } END{ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/imm32-IMMDisableLegacyIME/0001-imm32-Add-stub-for-ImmDisableLegacyIME.patch wine-staging-1.9.3~ubuntu12.04.1/patches/imm32-IMMDisableLegacyIME/0001-imm32-Add-stub-for-ImmDisableLegacyIME.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/imm32-IMMDisableLegacyIME/0001-imm32-Add-stub-for-ImmDisableLegacyIME.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/imm32-IMMDisableLegacyIME/0001-imm32-Add-stub-for-ImmDisableLegacyIME.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,42 @@ +From 2f48b5b48caac9a9260577114fd9813aa499d01f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 21 Jan 2016 00:26:24 +0100 +Subject: imm32: Add stub for ImmDisableLegacyIME. + +--- + dlls/imm32/imm.c | 9 +++++++++ + dlls/imm32/imm32.spec | 1 + + 2 files changed, 10 insertions(+) + +diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c +index 3fab6fc..87c2fcd 100644 +--- a/dlls/imm32/imm.c ++++ b/dlls/imm32/imm.c +@@ -3036,3 +3036,12 @@ BOOL WINAPI ImmGetHotKey(DWORD hotkey, UINT *modifiers, UINT *key, HKL hkl) + FIXME("%x, %p, %p, %p: stub\n", hotkey, modifiers, key, hkl); + return FALSE; + } ++ ++/*********************************************************************** ++ * IMMDisableLegacyIME(IMM32.@) ++ */ ++BOOL WINAPI ImmDisableLegacyIME(void) ++{ ++ FIXME("stub\n"); ++ return TRUE; ++} +diff --git a/dlls/imm32/imm32.spec b/dlls/imm32/imm32.spec +index 0bee92a..b92cc1b 100644 +--- a/dlls/imm32/imm32.spec ++++ b/dlls/imm32/imm32.spec +@@ -11,6 +11,7 @@ + @ stdcall ImmDestroySoftKeyboard(long) + @ stdcall ImmDisableIME(long) + @ stdcall ImmDisableIme(long) ImmDisableIME ++@ stdcall ImmDisableLegacyIME() + @ stdcall ImmDisableTextFrameService(long) + @ stdcall ImmEnumInputContext(long ptr long) + @ stdcall ImmEnumRegisterWordA(long ptr str long str ptr) +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/imm32-IMMDisableLegacyIME/definition wine-staging-1.9.3~ubuntu12.04.1/patches/imm32-IMMDisableLegacyIME/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/imm32-IMMDisableLegacyIME/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/imm32-IMMDisableLegacyIME/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Add stub for imm32.IMMDisableLegacyIME diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Codepage_Conversion/0001-kernel32-Set-error-if-dstlen-0-in-codepage-conversio.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Codepage_Conversion/0001-kernel32-Set-error-if-dstlen-0-in-codepage-conversio.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Codepage_Conversion/0001-kernel32-Set-error-if-dstlen-0-in-codepage-conversio.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Codepage_Conversion/0001-kernel32-Set-error-if-dstlen-0-in-codepage-conversio.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,124 +0,0 @@ -From 351e216da1c1325ec354183ebf027b09b3d008c7 Mon Sep 17 00:00:00 2001 -From: Alex Henrie -Date: Sat, 19 Sep 2015 12:58:37 +0200 -Subject: kernel32: Set error if dstlen < 0 in codepage conversion functions - ---- - dlls/kernel32/locale.c | 4 ++-- - dlls/kernel32/tests/codepage.c | 48 +++++++++++++++++++++++++----------------- - 2 files changed, 31 insertions(+), 21 deletions(-) - -diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c -index c0a66ef..6ede521 100644 ---- a/dlls/kernel32/locale.c -+++ b/dlls/kernel32/locale.c -@@ -2125,7 +2125,7 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen, - const union cptable *table; - int ret; - -- if (!src || !srclen || (!dst && dstlen)) -+ if (!src || !srclen || (!dst && dstlen) || dstlen < 0) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return 0; -@@ -2341,7 +2341,7 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen, - const union cptable *table; - int ret, used_tmp; - -- if (!src || !srclen || (!dst && dstlen)) -+ if (!src || !srclen || (!dst && dstlen) || dstlen < 0) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return 0; -diff --git a/dlls/kernel32/tests/codepage.c b/dlls/kernel32/tests/codepage.c -index 54f62ae..6718a3b 100644 ---- a/dlls/kernel32/tests/codepage.c -+++ b/dlls/kernel32/tests/codepage.c -@@ -28,6 +28,7 @@ - #include "winbase.h" - #include "winnls.h" - -+static const char foobarA[] = "foobar"; - static const WCHAR foobarW[] = {'f','o','o','b','a','r',0}; - - static void test_destination_buffer(void) -@@ -144,48 +145,57 @@ static void test_negative_source_length(void) - static void test_negative_dest_length(void) - { - int len, i; -- static char buf[LONGBUFLEN]; -+ static WCHAR bufW[LONGBUFLEN]; -+ static char bufA[LONGBUFLEN]; - static WCHAR originalW[LONGBUFLEN]; - static char originalA[LONGBUFLEN]; - DWORD theError; - - /* Test return on -1 dest length */ - SetLastError( 0xdeadbeef ); -- memset(buf,'x',sizeof(buf)); -- len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buf, -1, NULL, NULL); -- todo_wine { -- ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, -- "WideCharToMultiByte(destlen -1): len=%d error=%x\n", len, GetLastError()); -- } -+ memset(bufA,'x',sizeof(bufA)); -+ len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, -1, NULL, NULL); -+ ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, -+ "WideCharToMultiByte(destlen -1): len=%d error=%x\n", len, GetLastError()); -+ -+ SetLastError( 0xdeadbeef ); -+ memset(bufW,'x',sizeof(bufW)); -+ len = MultiByteToWideChar(CP_ACP, 0, foobarA, -1, bufW, -1); -+ ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, -+ "MultiByteToWideChar(destlen -1): len=%d error=%x\n", len, GetLastError()); - - /* Test return on -1000 dest length */ - SetLastError( 0xdeadbeef ); -- memset(buf,'x',sizeof(buf)); -- len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buf, -1000, NULL, NULL); -- todo_wine { -- ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, -- "WideCharToMultiByte(destlen -1000): len=%d error=%x\n", len, GetLastError()); -- } -+ memset(bufA,'x',sizeof(bufA)); -+ len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, -1000, NULL, NULL); -+ ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, -+ "WideCharToMultiByte(destlen -1000): len=%d error=%x\n", len, GetLastError()); -+ -+ SetLastError( 0xdeadbeef ); -+ memset(bufW,'x',sizeof(bufW)); -+ len = MultiByteToWideChar(CP_ACP, 0, foobarA, -1000, bufW, -1); -+ ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, -+ "MultiByteToWideChar(destlen -1000): len=%d error=%x\n", len, GetLastError()); - - /* Test return on INT_MAX dest length */ - SetLastError( 0xdeadbeef ); -- memset(buf,'x',sizeof(buf)); -- len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buf, INT_MAX, NULL, NULL); -- ok(len == 7 && !lstrcmpA(buf, "foobar") && GetLastError() == 0xdeadbeef, -+ memset(bufA,'x',sizeof(bufA)); -+ len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, INT_MAX, NULL, NULL); -+ ok(len == 7 && !lstrcmpA(bufA, "foobar") && GetLastError() == 0xdeadbeef, - "WideCharToMultiByte(destlen INT_MAX): len=%d error=%x\n", len, GetLastError()); - - /* Test return on INT_MAX dest length and very long input */ - SetLastError( 0xdeadbeef ); -- memset(buf,'x',sizeof(buf)); -+ memset(bufA,'x',sizeof(bufA)); - for (i=0; i < LONGBUFLEN - 1; i++) { - originalW[i] = 'Q'; - originalA[i] = 'Q'; - } - originalW[LONGBUFLEN-1] = 0; - originalA[LONGBUFLEN-1] = 0; -- len = WideCharToMultiByte(CP_ACP, 0, originalW, -1, buf, INT_MAX, NULL, NULL); -+ len = WideCharToMultiByte(CP_ACP, 0, originalW, -1, bufA, INT_MAX, NULL, NULL); - theError = GetLastError(); -- ok(len == LONGBUFLEN && !lstrcmpA(buf, originalA) && theError == 0xdeadbeef, -+ ok(len == LONGBUFLEN && !lstrcmpA(bufA, originalA) && theError == 0xdeadbeef, - "WideCharToMultiByte(srclen %d, destlen INT_MAX): len %d error=%x\n", LONGBUFLEN, len, theError); - - } --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Codepage_Conversion/definition wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Codepage_Conversion/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Codepage_Conversion/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Codepage_Conversion/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Fixes: Codepage conversion should fail when destination length is < 0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-CompareString_Length/0001-kernel32-CompareStringW-should-abort-on-the-first-no.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-CompareString_Length/0001-kernel32-CompareStringW-should-abort-on-the-first-no.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-CompareString_Length/0001-kernel32-CompareStringW-should-abort-on-the-first-no.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-CompareString_Length/0001-kernel32-CompareStringW-should-abort-on-the-first-no.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,44 +1,72 @@ -From 8e2f184541d44755fa67a43e4d8cf8debeeafc82 Mon Sep 17 00:00:00 2001 +From f8acf44d20407c213dd1f48691b432c2e9f555df Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Fri, 13 Nov 2015 20:36:54 +0800 Subject: kernel32: CompareStringW should abort on the first nonmatching - character to avoid invalid memory access. + character to avoid invalid memory access. (v2) For bug 37556. +Changes in v2 (by Sebastian Lackner): +* Use loop to handle strings ending with multiple \0 characters correctly. + Signed-off-by: Dmitry Timoshkov +Signed-off-by: Sebastian Lackner --- - libs/wine/sortkey.c | 15 ++++++--------- - 1 file changed, 6 insertions(+), 9 deletions(-) + libs/wine/sortkey.c | 39 ++++++++++++++++++++++++++++++--------- + 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/libs/wine/sortkey.c b/libs/wine/sortkey.c -index 17b5537..c459cea 100644 +index 17b5537..7280501 100644 --- a/libs/wine/sortkey.c +++ b/libs/wine/sortkey.c -@@ -223,6 +223,8 @@ static inline int compare_unicode_weights(int flags, const WCHAR *str1, int len1 +@@ -223,6 +223,16 @@ static inline int compare_unicode_weights(int flags, const WCHAR *str1, int len1 len1--; len2--; } -+ if (len1 && !*str1) len1--; -+ if (len2 && !*str2) len2--; ++ while (len1 && !*str1) ++ { ++ str1++; ++ len1--; ++ } ++ while (len2 && !*str2) ++ { ++ str2++; ++ len2--; ++ } return len1 - len2; } -@@ -272,6 +274,8 @@ static inline int compare_diacritic_weights(int flags, const WCHAR *str1, int le +@@ -272,6 +282,16 @@ static inline int compare_diacritic_weights(int flags, const WCHAR *str1, int le len1--; len2--; } -+ if (len1 && !*str1) len1--; -+ if (len2 && !*str2) len2--; ++ while (len1 && !*str1) ++ { ++ str1++; ++ len1--; ++ } ++ while (len2 && !*str2) ++ { ++ str2++; ++ len2--; ++ } return len1 - len2; } -@@ -321,23 +325,16 @@ static inline int compare_case_weights(int flags, const WCHAR *str1, int len1, +@@ -321,23 +341,24 @@ static inline int compare_case_weights(int flags, const WCHAR *str1, int len1, len1--; len2--; } -+ if (len1 && !*str1) len1--; -+ if (len2 && !*str2) len2--; ++ while (len1 && !*str1) ++ { ++ str1++; ++ len1--; ++ } ++ while (len2 && !*str2) ++ { ++ str2++; ++ len2--; ++ } return len1 - len2; } @@ -60,5 +88,5 @@ if (!ret) { -- -2.6.2 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-CompareString_Length/0003-kenrel32-tests-Add-further-tests-for-comparing-strin.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-CompareString_Length/0003-kenrel32-tests-Add-further-tests-for-comparing-strin.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-CompareString_Length/0003-kenrel32-tests-Add-further-tests-for-comparing-strin.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-CompareString_Length/0003-kenrel32-tests-Add-further-tests-for-comparing-strin.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,32 @@ +From c855cfddc7853fa8aed1ce4aac9a85c7ff7cb1f1 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Fri, 22 Jan 2016 15:13:36 +0100 +Subject: kenrel32/tests: Add further tests for comparing strings ending with + multiple \0 characters. + +--- + dlls/kernel32/tests/locale.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c +index d531272..4a9e540 100644 +--- a/dlls/kernel32/tests/locale.c ++++ b/dlls/kernel32/tests/locale.c +@@ -1643,6 +1643,14 @@ static const struct comparestringa_entry comparestringa_data[] = { + { LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "a'", 3, "a\0", 3, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, NORM_IGNORESYMBOLS, "a.", 3, "a\0", 3, CSTR_EQUAL }, + { LOCALE_SYSTEM_DEFAULT, NORM_IGNORESYMBOLS, "a ", 3, "a\0", 3, CSTR_EQUAL }, ++ { LOCALE_SYSTEM_DEFAULT, 0, "a", 1, "a\0\0", 4, CSTR_EQUAL }, ++ { LOCALE_SYSTEM_DEFAULT, 0, "a", 2, "a\0\0", 4, CSTR_EQUAL }, ++ { LOCALE_SYSTEM_DEFAULT, 0, "a\0\0", 4, "a", 1, CSTR_EQUAL }, ++ { LOCALE_SYSTEM_DEFAULT, 0, "a\0\0", 4, "a", 2, CSTR_EQUAL }, ++ { LOCALE_SYSTEM_DEFAULT, 0, "a", 1, "a\0x", 4, CSTR_LESS_THAN }, ++ { LOCALE_SYSTEM_DEFAULT, 0, "a", 2, "a\0x", 4, CSTR_LESS_THAN }, ++ { LOCALE_SYSTEM_DEFAULT, 0, "a\0x", 4, "a", 1, CSTR_GREATER_THAN }, ++ { LOCALE_SYSTEM_DEFAULT, 0, "a\0x", 4, "a", 2, CSTR_GREATER_THAN }, + }; + + static void test_CompareStringA(void) +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-FindFirstFile/0001-kernel32-Strip-invalid-characters-from-mask-in-FindF.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-FindFirstFile/0001-kernel32-Strip-invalid-characters-from-mask-in-FindF.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-FindFirstFile/0001-kernel32-Strip-invalid-characters-from-mask-in-FindF.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-FindFirstFile/0001-kernel32-Strip-invalid-characters-from-mask-in-FindF.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,49 @@ +From 07791ffe43d1fda2618994f98986ab5e9cbf3c97 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 6 Feb 2016 18:31:25 +0100 +Subject: kernel32: Strip invalid characters from mask in FindFirstFileExW. + +--- + dlls/kernel32/file.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c +index b6dba6a..3297f4b 100644 +--- a/dlls/kernel32/file.c ++++ b/dlls/kernel32/file.c +@@ -2009,12 +2009,32 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR filename, FINDEX_INFO_LEVELS level, + } + else + { ++ static const WCHAR invalidW[] = { '<', '>', '\"', 0 }; ++ static const WCHAR wildcardW[] = { '*', 0 }; ++ DWORD mask_len; ++ + if (!RtlCreateUnicodeString( &info->mask, mask )) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + goto error; + } + ++ /* strip invalid characters from mask */ ++ mask_len = info->mask.Length / sizeof(WCHAR); ++ while (mask_len && strchrW(invalidW, mask[mask_len - 1])) ++ mask_len--; ++ ++ if (!mask_len) ++ { ++ strcpyW( info->mask.Buffer, wildcardW ); ++ info->mask.Length = strlenW(wildcardW) * sizeof(WCHAR); ++ } ++ else ++ { ++ info->mask.Buffer[mask_len] = 0; ++ info->mask.Length = mask_len * sizeof(WCHAR); ++ } ++ + /* truncate dir name before mask */ + *mask = 0; + nt_name.Length = (mask - nt_name.Buffer) * sizeof(WCHAR); +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-FindFirstFile/0002-kernel32-tests-Add-tests-for-FindFirstFileA-with-inv.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-FindFirstFile/0002-kernel32-tests-Add-tests-for-FindFirstFileA-with-inv.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-FindFirstFile/0002-kernel32-tests-Add-tests-for-FindFirstFileA-with-inv.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-FindFirstFile/0002-kernel32-tests-Add-tests-for-FindFirstFileA-with-inv.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,135 @@ +From 29a12264fdd49cdb5b815064c2767e7fc349133b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 6 Feb 2016 18:32:09 +0100 +Subject: kernel32/tests: Add tests for FindFirstFileA with invalid characters. + +Includes testcases by Vincent Pelletier. +--- + dlls/kernel32/tests/file.c | 100 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 99 insertions(+), 1 deletion(-) + +diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c +index 53dc04b..a7ac09c 100644 +--- a/dlls/kernel32/tests/file.c ++++ b/dlls/kernel32/tests/file.c +@@ -2517,11 +2517,85 @@ static char get_windows_drive(void) + return windowsdir[0]; + } + ++struct ++{ ++ const char *path; ++ BOOL expected; ++} ++static const invalid_char_tests[] = ++{ ++ { "./test-dir", TRUE }, ++ { "./test-dir/", FALSE }, ++ { ".\\test-dir", TRUE }, ++ { ".\\test-dir\\", FALSE }, ++ { "/>test-dir", FALSE }, ++ { "<\"test->dir", FALSE }, ++ { "dir", FALSE }, ++ { ">dir", FALSE }, ++ { ">>test-dir", FALSE }, ++ { ">test->dir", FALSE }, ++ { ">test-dir", FALSE }, ++ { "\"test-dir\"", FALSE }, ++ { "\"test-file\"", FALSE }, ++ { "test-/>dir", FALSE }, ++ { "test-dir/", FALSE }, ++ { "test-dir//", FALSE }, ++ { "test-dir/:", FALSE }, ++ { "test-dir/<", TRUE }, ++ { "test-dir/>", TRUE }, ++ { "test-dir/\"", TRUE }, ++ { "test-dir/\\", FALSE }, ++ { "test-dir/|", FALSE }, ++ { "test-dir<", TRUE }, ++ { "test-dir<><>\"\"\"\"<<<>", TRUE }, ++ { "test-dir<>", TRUE }, ++ { "test-dir<\"", TRUE }, ++ { "test-dir>", TRUE }, ++ { "test-dir>/", FALSE }, ++ { "test-dir><", TRUE }, ++ { "test-dir>>", TRUE }, ++ { "test-dir>\"", TRUE }, ++ { "test-dir\"", TRUE }, ++ { "test-dir\"/", FALSE }, ++ { "test-dir\"<", TRUE }, ++ { "test-dir\">", TRUE }, ++ { "test-dir\"\"", TRUE }, ++ { "test-dir\"\"\"\"\"", TRUE }, ++ { "test-dir\\", FALSE }, ++ { "test-dir\\/", FALSE }, ++ { "test-dir\\<", TRUE }, ++ { "test-dir\\>", TRUE }, ++ { "test-dir\\\"", TRUE }, ++ { "test-dir\\\\", FALSE }, ++ { "test-file/", FALSE }, ++ { "test-file/<", FALSE }, ++ { "test-file/>", FALSE }, ++ { "test-file/\"", FALSE }, ++ { "test-file<", TRUE }, ++ { "test-file<<", TRUE }, ++ { "test-file<>", TRUE }, ++ { "test-file<\"", TRUE }, ++ { "test-file>", TRUE }, ++ { "test-file><", TRUE }, ++ { "test-file>>", TRUE }, ++ { "test-file>\"", TRUE }, ++ { "test-file\"", TRUE }, ++ { "test-file\"<", TRUE }, ++ { "test-file\">", TRUE }, ++ { "test-file\"\"", TRUE }, ++ { "test-file\\", FALSE }, ++ { "test-file\\<", FALSE }, ++ { "test-file\\>", FALSE }, ++ { "test-file\\\"", FALSE }, ++}; ++ + static void test_FindFirstFileA(void) + { + HANDLE handle; + WIN32_FIND_DATAA data; +- int err; ++ int err, i; + char buffer[5] = "C:\\"; + char buffer2[100]; + char nonexistent[MAX_PATH]; +@@ -2689,6 +2763,30 @@ static void test_FindFirstFileA(void) + err = GetLastError(); + ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 ); + ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err ); ++ ++ /* try FindFirstFileA with invalid characters */ ++ CreateDirectoryA("test-dir", NULL); ++ _lclose(_lcreat("test-file", 0)); ++ ++ for (i = 0; i < sizeof(invalid_char_tests) / sizeof(invalid_char_tests[0]); i++) ++ { ++ handle = FindFirstFileA(invalid_char_tests[i].path, &data); ++ if (invalid_char_tests[i].expected) ++ { ++ ok(handle != INVALID_HANDLE_VALUE, "FindFirstFileA on %s should succeed\n", ++ invalid_char_tests[i].path); ++ } ++ else ++ { ++ ok(handle == INVALID_HANDLE_VALUE, "FindFirstFileA on %s should fail\n", ++ invalid_char_tests[i].path); ++ } ++ if (handle != INVALID_HANDLE_VALUE) ++ FindClose(handle); ++ } ++ ++ DeleteFileA("test-file"); ++ RemoveDirectoryA("test-dir"); + } + + static void test_FindNextFileA(void) +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-FindFirstFile/definition wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-FindFirstFile/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-FindFirstFile/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-FindFirstFile/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [22635] Strip invalid characters from mask in FindFirstFileExW diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetCurrentPackageFamilyName/0001-kernel32-Add-stub-for-GetCurrentPackageFamilyName-an.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetCurrentPackageFamilyName/0001-kernel32-Add-stub-for-GetCurrentPackageFamilyName-an.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetCurrentPackageFamilyName/0001-kernel32-Add-stub-for-GetCurrentPackageFamilyName-an.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetCurrentPackageFamilyName/0001-kernel32-Add-stub-for-GetCurrentPackageFamilyName-an.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,146 @@ +From b94bb9fb468540cc3482c6009d92600b0c1e37ed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 15 Jan 2016 13:23:02 +0100 +Subject: kernel32: Add stub for GetCurrentPackageFamilyName and add related + functions to spec file. + +--- + dlls/kernel32/kernel32.spec | 35 +++++++++++++++++++++++++++++++++++ + dlls/kernel32/version.c | 9 +++++++++ + 2 files changed, 44 insertions(+) + +diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec +index a28f8e8..c368780 100644 +--- a/dlls/kernel32/kernel32.spec ++++ b/dlls/kernel32/kernel32.spec +@@ -225,6 +225,7 @@ + @ stdcall ClearCommError(long ptr ptr) + @ stdcall CloseConsoleHandle(long) + @ stdcall CloseHandle(long) ++@ stub ClosePackageInfo + # @ stub ClosePrivateNamespace + @ stdcall CloseProfileUserMapping() + @ stub CloseSystemHandle +@@ -506,6 +507,7 @@ + @ stdcall FindNextVolumeW(long ptr long) + # @ stub FindNLSString + # @ stub FindNLSStringEx ++@ stub FindPackagesByPackageFamily + @ stdcall FindResourceA(long str str) + @ stdcall FindResourceExA(long str str long) + @ stdcall FindResourceExW(long wstr wstr long) +@@ -524,6 +526,7 @@ + @ stdcall FlushViewOfFile(ptr long) + @ stdcall FoldStringA(long str long ptr long) + @ stdcall FoldStringW(long wstr long ptr long) ++@ stub FormatApplicationUserModelId + @ stdcall FormatMessageA(long ptr long long ptr long ptr) + @ stdcall FormatMessageW(long ptr long long ptr long ptr) + @ stdcall FreeConsole() +@@ -544,6 +547,8 @@ + # @ stub GetActiveProcessorGroupCount + # @ stub GetApplicationRecoveryCallback + # @ stub GetApplicationRestartSettings ++@ stub GetApplicationUserModelId ++@ stub GetApplicationUserModelIdFromToken + @ stdcall GetAtomNameA(long ptr long) + @ stdcall GetAtomNameW(long ptr long) + @ stdcall GetBinaryType(str ptr) GetBinaryTypeA +@@ -624,11 +629,16 @@ + # @ stub GetCurrencyFormatEx + @ stdcall GetCurrencyFormatW(long long str ptr str long) + @ stdcall GetCurrentActCtx(ptr) ++@ stub GetCurrentApplicationUserModelId + @ stdcall GetCurrentConsoleFont(long long ptr) + # @ stub GetCurrentConsoleFontEx + @ stdcall GetCurrentDirectoryA(long ptr) + @ stdcall GetCurrentDirectoryW(long ptr) ++@ stdcall GetCurrentPackageFamilyName(ptr ptr) ++@ stub GetCurrentPackageFullName + @ stdcall GetCurrentPackageId(ptr ptr) ++@ stub GetCurrentPackageInfo ++@ stub GetCurrentPackagePath + @ stdcall -norelay GetCurrentProcess() + @ stdcall -norelay GetCurrentProcessId() + @ stdcall GetCurrentProcessorNumber() ntdll.NtGetCurrentProcessorNumber +@@ -759,6 +769,16 @@ + @ stdcall GetOEMCP() + @ stdcall GetOverlappedResult(long ptr ptr long) + @ stdcall GetUserPreferredUILanguages(long ptr ptr ptr) ++@ stub GetPackageApplicationIds ++@ stub GetPackageFamilyName ++@ stub GetPackageFamilyNameFromToken ++@ stub GetPackageFullName ++@ stub GetPackageFullNameFromToken ++@ stub GetPackageId ++@ stub GetPackageInfo ++@ stub GetPackagePath ++@ stub GetPackagePathByFullName ++@ stub GetPackagesByPackageFamily + @ stdcall GetPhysicallyInstalledSystemMemory(ptr) + @ stdcall GetPriorityClass(long) + @ stdcall GetPrivateProfileIntA(str str long str) +@@ -805,6 +825,8 @@ + @ stub -i386 GetSLCallbackTemplate + @ stdcall GetShortPathNameA(str ptr long) + @ stdcall GetShortPathNameW(wstr ptr long) ++@ stub GetStagedPackageOrigin ++@ stub GetStagedPackagePathByFullName + @ stdcall GetStartupInfoA(ptr) + @ stdcall GetStartupInfoW(ptr) + @ stdcall GetStdHandle(long) +@@ -1117,6 +1139,8 @@ + @ stdcall OpenJobObjectW(long long wstr) + @ stdcall OpenMutexA(long long str) + @ stdcall OpenMutexW(long long wstr) ++@ stub OpenPackageInfoByFullName ++@ stub OpenPackageInfoByFullNameForUser + # @ stub OpenPrivateNamespaceA + # @ stub OpenPrivateNamespaceW + @ stdcall OpenProcess(long long long) +@@ -1131,6 +1155,12 @@ + @ stdcall OpenWaitableTimerW(long long wstr) + @ stdcall OutputDebugStringA(str) + @ stdcall OutputDebugStringW(wstr) ++@ stub PackageFamilyNameFromFullName ++@ stub PackageFamilyNameFromId ++@ stub PackageFullNameFromId ++@ stub PackageIdFromFullName ++@ stub PackageNameAndPublisherIdFromFamilyName ++@ stub ParseApplicationUserModelId + @ stdcall PeekConsoleInputA(ptr ptr long ptr) + @ stdcall PeekConsoleInputW(ptr ptr long ptr) + @ stdcall PeekNamedPipe(long ptr long ptr ptr ptr) +@@ -1547,7 +1577,12 @@ + @ stdcall VerLanguageNameA(long str long) + @ stdcall VerLanguageNameW(long wstr long) + @ stdcall -ret64 VerSetConditionMask(long long long long) ntdll.VerSetConditionMask ++@ stub VerifyApplicationUserModelId + @ stdcall VerifyConsoleIoHandle(long) ++@ stub VerifyPackageFamilyName ++@ stub VerifyPackageFullName ++@ stub VerifyPackageId ++@ stub VerifyPackageRelativeApplicationId + # @ stub VerifyScripts + @ stdcall VerifyVersionInfoA(long long int64) + @ stdcall VerifyVersionInfoW(long long int64) +diff --git a/dlls/kernel32/version.c b/dlls/kernel32/version.c +index b9d13e4..53f594e 100644 +--- a/dlls/kernel32/version.c ++++ b/dlls/kernel32/version.c +@@ -207,3 +207,12 @@ LONG WINAPI GetCurrentPackageId(UINT32 *len, BYTE *buffer) + FIXME("(%p %p): stub\n", len, buffer); + return APPMODEL_ERROR_NO_PACKAGE; + } ++ ++/*********************************************************************** ++ * GetCurrentPackageFamilyName (KERNEL32.@) ++ */ ++LONG WINAPI GetCurrentPackageFamilyName(UINT32 *length, PWSTR name) ++{ ++ FIXME("(%p %p): stub\n", length, name); ++ return APPMODEL_ERROR_NO_PACKAGE; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetCurrentPackageFamilyName/definition wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetCurrentPackageFamilyName/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetCurrentPackageFamilyName/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetCurrentPackageFamilyName/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Add stub for kernel32.GetCurrentPackageFamilyName diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0001-wineconsole-Send-the-largest-console-window-size-inf.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0001-wineconsole-Send-the-largest-console-window-size-inf.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0001-wineconsole-Send-the-largest-console-window-size-inf.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0001-wineconsole-Send-the-largest-console-window-size-inf.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -From 621d31b627bd14ab424e20f76c9dc2d786e5ec9e Mon Sep 17 00:00:00 2001 -From: Hugh McMaster -Date: Fri, 4 Dec 2015 15:47:42 +1100 -Subject: wineconsole: Send the largest console window size information to the - server - -Signed-off-by: Hugh McMaster ---- - programs/wineconsole/wineconsole.c | 6 +++++- - server/console.c | 7 ------- - 2 files changed, 5 insertions(+), 8 deletions(-) - -diff --git a/programs/wineconsole/wineconsole.c b/programs/wineconsole/wineconsole.c -index 7a89eeb..729416f 100644 ---- a/programs/wineconsole/wineconsole.c -+++ b/programs/wineconsole/wineconsole.c -@@ -424,11 +424,15 @@ void WINECON_SetConfig(struct inner_data* data, const struct config_data* cf - if (strcmpiW(data->curcfg.face_name, cfg->face_name) || data->curcfg.cell_width != cfg->cell_width || - data->curcfg.cell_height != cfg->cell_height || data->curcfg.font_weight != cfg->font_weight) - { -+ RECT r; - data->fnSetFont(data, cfg->face_name, cfg->cell_height, cfg->font_weight); -+ SystemParametersInfoW(SPI_GETWORKAREA, 0, &r, 0); - SERVER_START_REQ(set_console_output_info) - { - req->handle = wine_server_obj_handle( data->hConOut ); -- req->mask = SET_CONSOLE_OUTPUT_INFO_FONT; -+ req->mask = SET_CONSOLE_OUTPUT_INFO_MAX_SIZE | SET_CONSOLE_OUTPUT_INFO_FONT; -+ req->max_width = (r.right - r.left) / cfg->cell_width; -+ req->max_height = (r.bottom - r.top - GetSystemMetrics(SM_CYCAPTION)) / cfg->cell_height; - req->font_width = cfg->cell_width; - req->font_height = cfg->cell_height; - wine_server_call( req ); -diff --git a/server/console.c b/server/console.c -index a57b2fe..9b01614 100644 ---- a/server/console.c -+++ b/server/console.c -@@ -1018,13 +1018,6 @@ static int set_console_output_info( struct screen_buffer *screen_buffer, - } - if (req->mask & SET_CONSOLE_OUTPUT_INFO_MAX_SIZE) - { -- /* can only be done by renderer */ -- if (current->process->console != screen_buffer->input) -- { -- set_error( STATUS_INVALID_PARAMETER ); -- return 0; -- } -- - screen_buffer->max_width = req->max_width; - screen_buffer->max_height = req->max_height; - } --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0002-kernel32-Implement-GetLargestConsoleWindowSize.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0002-kernel32-Implement-GetLargestConsoleWindowSize.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0002-kernel32-Implement-GetLargestConsoleWindowSize.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0002-kernel32-Implement-GetLargestConsoleWindowSize.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -From 56d5cc64d9047dc5f9866ff2542eb0f07f9ad75d Mon Sep 17 00:00:00 2001 -From: Hugh McMaster -Date: Fri, 4 Dec 2015 15:48:12 +1100 -Subject: kernel32: Implement GetLargestConsoleWindowSize - -Signed-off-by: Hugh McMaster ---- - dlls/kernel32/console.c | 24 +++++++++++++++++++----- - 1 file changed, 19 insertions(+), 5 deletions(-) - -diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c -index 51d6e60..f48bca7 100644 ---- a/dlls/kernel32/console.c -+++ b/dlls/kernel32/console.c -@@ -1360,6 +1360,22 @@ DWORD WINAPI GetConsoleTitleW(LPWSTR title, DWORD size) - return ret; - } - -+static COORD get_largest_console_window_size(HANDLE hConsole) -+{ -+ COORD c = {0,0}; -+ -+ SERVER_START_REQ(get_console_output_info) -+ { -+ req->handle = console_handle_unmap(hConsole); -+ if (!wine_server_call_err(req)) -+ { -+ c.X = reply->max_width; -+ c.Y = reply->max_height; -+ } -+ } -+ SERVER_END_REQ; -+ return c; -+} - - /*********************************************************************** - * GetLargestConsoleWindowSize (KERNEL32.@) -@@ -1378,8 +1394,7 @@ DWORD WINAPI GetLargestConsoleWindowSize(HANDLE hConsoleOutput) - COORD c; - DWORD w; - } x; -- x.c.X = 80; -- x.c.Y = 24; -+ x.c = get_largest_console_window_size(hConsoleOutput); - TRACE("(%p), returning %dx%d (%x)\n", hConsoleOutput, x.c.X, x.c.Y, x.w); - return x.w; - } -@@ -1399,12 +1414,11 @@ DWORD WINAPI GetLargestConsoleWindowSize(HANDLE hConsoleOutput) - COORD WINAPI GetLargestConsoleWindowSize(HANDLE hConsoleOutput) - { - COORD c; -- c.X = 80; -- c.Y = 24; -+ c = get_largest_console_window_size(hConsoleOutput); - TRACE("(%p), returning %dx%d\n", hConsoleOutput, c.X, c.Y); - return c; - } --#endif /* defined(__i386__) */ -+#endif /* !defined(__i386__) */ - - static WCHAR* S_EditString /* = NULL */; - static unsigned S_EditStrPos /* = 0 */; --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0003-kernel32-Add-a-stub-for-SetConsoleFont.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0003-kernel32-Add-a-stub-for-SetConsoleFont.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0003-kernel32-Add-a-stub-for-SetConsoleFont.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0003-kernel32-Add-a-stub-for-SetConsoleFont.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -From 0042b3a28cc7fbe462850eb600df0424a8dfb1e5 Mon Sep 17 00:00:00 2001 -From: Hugh McMaster -Date: Fri, 4 Dec 2015 16:00:27 +1100 -Subject: kernel32: Add a stub for SetConsoleFont - -Signed-off-by: Hugh McMaster ---- - dlls/kernel32/console.c | 6 ++++++ - dlls/kernel32/kernel32.spec | 2 +- - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c -index f48bca7..3c53b52 100644 ---- a/dlls/kernel32/console.c -+++ b/dlls/kernel32/console.c -@@ -3256,6 +3256,12 @@ DWORD WINAPI GetNumberOfConsoleFonts(void) - return 1; - } - -+BOOL WINAPI SetConsoleFont(HANDLE hConsole, DWORD index) -+{ -+ FIXME("(%p, %u): stub!\n", hConsole, index); -+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED); -+ return FALSE; -+} - - BOOL WINAPI SetConsoleKeyShortcuts(BOOL set, BYTE keys, VOID *a, DWORD b) - { -diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec -index ff67e54..d10e6bb 100644 ---- a/dlls/kernel32/kernel32.spec -+++ b/dlls/kernel32/kernel32.spec -@@ -1345,7 +1345,7 @@ - @ stub SetConsoleCursorMode - @ stdcall SetConsoleCursorPosition(long long) - @ stdcall SetConsoleDisplayMode(long long ptr) --@ stub SetConsoleFont -+@ stdcall SetConsoleFont(long long) - @ stub SetConsoleHardwareState - @ stdcall SetConsoleIcon(ptr) - @ stdcall SetConsoleInputExeNameA(ptr) --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0004-kernel32-tests-Refresh-the-console-to-clear-the-cons.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0004-kernel32-tests-Refresh-the-console-to-clear-the-cons.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0004-kernel32-tests-Refresh-the-console-to-clear-the-cons.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0004-kernel32-tests-Refresh-the-console-to-clear-the-cons.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -From 3935a3728751863c959f1f45e8e1866ed98c3ce4 Mon Sep 17 00:00:00 2001 -From: Hugh McMaster -Date: Fri, 4 Dec 2015 16:02:38 +1100 -Subject: kernel32/tests: Refresh the console to clear the console font table - -The testScreenBuffer function unintentionally causes the console -font table to duplicate. This patch clears the font table. - -Signed-off-by: Hugh McMaster ---- - dlls/kernel32/tests/console.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c -index 240d9d8..3ba1da5 100644 ---- a/dlls/kernel32/tests/console.c -+++ b/dlls/kernel32/tests/console.c -@@ -2787,6 +2787,17 @@ START_TEST(console) - testScroll(hConOut, sbi.dwSize); - /* will test sb creation / modification / codepage handling */ - testScreenBuffer(hConOut); -+ -+ /* clear duplicated console font table */ -+ CloseHandle(hConIn); -+ CloseHandle(hConOut); -+ FreeConsole(); -+ ok(AllocConsole(), "Couldn't alloc console\n"); -+ hConIn = CreateFileA("CONIN$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); -+ hConOut = CreateFileA("CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); -+ ok(hConIn != INVALID_HANDLE_VALUE, "Opening ConIn\n"); -+ ok(hConOut != INVALID_HANDLE_VALUE, "Opening ConOut\n"); -+ - testCtrlHandler(); - /* still to be done: access rights & access on objects */ - --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0005-kernel32-tests-Add-tests-for-GetLargestConsoleWindow.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0005-kernel32-tests-Add-tests-for-GetLargestConsoleWindow.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0005-kernel32-tests-Add-tests-for-GetLargestConsoleWindow.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0005-kernel32-tests-Add-tests-for-GetLargestConsoleWindow.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -From cea4e680a6e23edcbbba8d0457834ee15c2f7c3a Mon Sep 17 00:00:00 2001 -From: Hugh McMaster -Date: Fri, 4 Dec 2015 16:07:24 +1100 -Subject: kernel32/tests: Add tests for GetLargestConsoleWindowSize - -Signed-off-by: Hugh McMaster ---- - dlls/kernel32/tests/console.c | 64 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 64 insertions(+) - -diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c -index 3ba1da5..f362415 100644 ---- a/dlls/kernel32/tests/console.c -+++ b/dlls/kernel32/tests/console.c -@@ -2681,6 +2681,69 @@ static void test_GetConsoleFontSize(HANDLE std_output) - ok(!c.Y, "got %d, expected 0\n", c.Y); - } - -+static void test_GetLargestConsoleWindowSize(HANDLE std_output) -+{ -+ COORD c, font; -+ RECT r; -+ LONG workarea_w, workarea_h, maxcon_w, maxcon_h; -+ CONSOLE_FONT_INFO cfi; -+ DWORD index, i; -+ HMODULE hmod; -+ DWORD (WINAPI *pGetNumberOfConsoleFonts)(void); -+ BOOL (WINAPI *pSetConsoleFont)(HANDLE, DWORD); -+ -+ memset(&c, 10, sizeof(COORD)); -+ SetLastError(0xdeadbeef); -+ c = GetLargestConsoleWindowSize(NULL); -+ ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError()); -+ ok(!c.X, "got %d, expected 0\n", c.X); -+ ok(!c.Y, "got %d, expected 0\n", c.Y); -+ -+ memset(&c, 10, sizeof(COORD)); -+ SetLastError(0xdeadbeef); -+ c = GetLargestConsoleWindowSize(GetStdHandle(STD_INPUT_HANDLE)); -+ ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 6\n", GetLastError()); -+ ok(!c.X, "got %d, expected 0\n", c.X); -+ ok(!c.Y, "got %d, expected 0\n", c.Y); -+ -+ SystemParametersInfoW(SPI_GETWORKAREA, 0, &r, 0); -+ workarea_w = r.right - r.left; -+ workarea_h = r.bottom - r.top - GetSystemMetrics(SM_CYCAPTION); -+ -+ GetCurrentConsoleFont(std_output, FALSE, &cfi); -+ index = cfi.nFont; /* save current font index */ -+ -+ hmod = GetModuleHandleA("kernel32.dll"); -+ pGetNumberOfConsoleFonts = (void *)GetProcAddress(hmod, "GetNumberOfConsoleFonts"); -+ if (!pGetNumberOfConsoleFonts) -+ { -+ win_skip("GetNumberOfConsoleFonts is not available\n"); -+ return; -+ } -+ pSetConsoleFont = (void *)GetProcAddress(hmod, "SetConsoleFont"); -+ if (!pSetConsoleFont) -+ { -+ win_skip("SetConsoleFont is not available\n"); -+ return; -+ } -+ -+ for (i = 0; i < pGetNumberOfConsoleFonts(); i++) -+ { -+ pSetConsoleFont(std_output, i); -+ memset(&c, 10, sizeof(COORD)); -+ SetLastError(0xdeadbeef); -+ c = GetLargestConsoleWindowSize(std_output); -+ ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError()); -+ GetCurrentConsoleFont(std_output, FALSE, &cfi); -+ font = GetConsoleFontSize(std_output, cfi.nFont); -+ maxcon_w = workarea_w / font.X; -+ maxcon_h = workarea_h / font.Y; -+ ok(c.X == maxcon_w || c.X == maxcon_w - 1 /* Win10 */, "got %d, expected %d\n", c.X, maxcon_w); -+ ok(c.Y == maxcon_h || c.Y == maxcon_h - 1 /* Win10 */, "got %d, expected %d\n", c.Y, maxcon_h); -+ } -+ pSetConsoleFont(std_output, index); /* restore original font size */ -+} -+ - START_TEST(console) - { - static const char font_name[] = "Lucida Console"; -@@ -2826,4 +2889,5 @@ START_TEST(console) - test_ReadConsoleOutputAttribute(hConOut); - test_GetCurrentConsoleFont(hConOut); - test_GetConsoleFontSize(hConOut); -+ test_GetLargestConsoleWindowSize(hConOut); - } --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0006-kernel32-Clamp-maximum-window-size-to-screen-buffer-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0006-kernel32-Clamp-maximum-window-size-to-screen-buffer-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0006-kernel32-Clamp-maximum-window-size-to-screen-buffer-.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/0006-kernel32-Clamp-maximum-window-size-to-screen-buffer-.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -From d3a6fb5dc0a0494627c0980ca8d5e5ee89df4fbc Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 5 Dec 2015 19:36:20 +0100 -Subject: kernel32: Clamp maximum window size to screen buffer size. - ---- - dlls/kernel32/console.c | 4 ++-- - dlls/kernel32/tests/console.c | 9 +++++++++ - 2 files changed, 11 insertions(+), 2 deletions(-) - -diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c -index 3c53b52..85e4ba8 100644 ---- a/dlls/kernel32/console.c -+++ b/dlls/kernel32/console.c -@@ -2160,8 +2160,8 @@ BOOL WINAPI GetConsoleScreenBufferInfo(HANDLE hConsoleOutput, LPCONSOLE_SCREEN_B - csbi->srWindow.Right = reply->win_right; - csbi->srWindow.Top = reply->win_top; - csbi->srWindow.Bottom = reply->win_bottom; -- csbi->dwMaximumWindowSize.X = reply->max_width; -- csbi->dwMaximumWindowSize.Y = reply->max_height; -+ csbi->dwMaximumWindowSize.X = min(reply->width, reply->max_width); -+ csbi->dwMaximumWindowSize.Y = min(reply->height, reply->max_height); - } - } - SERVER_END_REQ; -diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c -index f362415..43a4b75 100644 ---- a/dlls/kernel32/tests/console.c -+++ b/dlls/kernel32/tests/console.c -@@ -2686,9 +2686,11 @@ static void test_GetLargestConsoleWindowSize(HANDLE std_output) - COORD c, font; - RECT r; - LONG workarea_w, workarea_h, maxcon_w, maxcon_h; -+ CONSOLE_SCREEN_BUFFER_INFO sbi; - CONSOLE_FONT_INFO cfi; - DWORD index, i; - HMODULE hmod; -+ BOOL ret; - DWORD (WINAPI *pGetNumberOfConsoleFonts)(void); - BOOL (WINAPI *pSetConsoleFont)(HANDLE, DWORD); - -@@ -2740,6 +2742,13 @@ static void test_GetLargestConsoleWindowSize(HANDLE std_output) - maxcon_h = workarea_h / font.Y; - ok(c.X == maxcon_w || c.X == maxcon_w - 1 /* Win10 */, "got %d, expected %d\n", c.X, maxcon_w); - ok(c.Y == maxcon_h || c.Y == maxcon_h - 1 /* Win10 */, "got %d, expected %d\n", c.Y, maxcon_h); -+ -+ ret = GetConsoleScreenBufferInfo(std_output, &sbi); -+ ok(ret, "GetConsoleScreenBufferInfo failed %u\n", GetLastError()); -+ ok(sbi.dwMaximumWindowSize.X == min(c.X, sbi.dwSize.X), "got %d, expected %d\n", -+ sbi.dwMaximumWindowSize.X, min(c.X, sbi.dwSize.X)); -+ ok(sbi.dwMaximumWindowSize.Y == min(c.Y, sbi.dwSize.Y), "got %d, expected %d\n", -+ sbi.dwMaximumWindowSize.Y, min(c.Y, sbi.dwSize.Y)); - } - pSetConsoleFont(std_output, index); /* restore original font size */ - } --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/definition wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLargestConsoleWindowSize/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Fixes: [10919] Properly implement GetLargestConsoleWindowSize diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLogicalProcessorInformationEx/0001-kernel32-Make-GetLogicalProcessorInformationEx-a-stu.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLogicalProcessorInformationEx/0001-kernel32-Make-GetLogicalProcessorInformationEx-a-stu.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLogicalProcessorInformationEx/0001-kernel32-Make-GetLogicalProcessorInformationEx-a-stu.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLogicalProcessorInformationEx/0001-kernel32-Make-GetLogicalProcessorInformationEx-a-stu.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -From f7ea420c1ca707503214eba3c9bfce6719e66fdc Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Fri, 20 Jun 2014 21:16:39 +0200 -Subject: kernel32: Make GetLogicalProcessorInformationEx a stub which returns - TRUE. - ---- - dlls/kernel32/process.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c -index b371e73..24da577 100644 ---- a/dlls/kernel32/process.c -+++ b/dlls/kernel32/process.c -@@ -3831,8 +3831,18 @@ BOOL WINAPI GetLogicalProcessorInformation(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION - BOOL WINAPI GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP relationship, PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX buffer, PDWORD pBufLen) - { - FIXME("(%u,%p,%p): stub\n", relationship, buffer, pBufLen); -- SetLastError(ERROR_CALL_NOT_IMPLEMENTED); -- return FALSE; -+ -+ if (!pBufLen) -+ { -+ SetLastError(ERROR_INVALID_PARAMETER); -+ return FALSE; -+ } -+ -+ /* MSDN says '[...] at least one SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX -+ * structure is written to the output buffer.' - don't be surprised if this -+ * stub doesn't work always. */ -+ *pBufLen = 0; -+ return TRUE; - } - - /*********************************************************************** --- -2.3.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLogicalProcessorInformationEx/definition wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLogicalProcessorInformationEx/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-GetLogicalProcessorInformationEx/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-GetLogicalProcessorInformationEx/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Fixes: CPU-Z fails to start because GetLogicalProcessorInformationEx returns FALSE diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-InterlockedPushListSList/0001-kernel32-Forward-InterlockedPushListSList-to-ntdll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-InterlockedPushListSList/0001-kernel32-Forward-InterlockedPushListSList-to-ntdll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-InterlockedPushListSList/0001-kernel32-Forward-InterlockedPushListSList-to-ntdll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-InterlockedPushListSList/0001-kernel32-Forward-InterlockedPushListSList-to-ntdll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,37 @@ +From 81cb0869aced99d1ff549b3f3ddc98e6ba0d1fc9 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Tue, 12 Jan 2016 05:30:09 +0100 +Subject: kernel32: Forward InterlockedPushListSList to ntdll. + +--- + .../api-ms-win-core-interlocked-l1-1-0.spec | 2 +- + dlls/kernel32/kernel32.spec | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/api-ms-win-core-interlocked-l1-1-0/api-ms-win-core-interlocked-l1-1-0.spec b/dlls/api-ms-win-core-interlocked-l1-1-0/api-ms-win-core-interlocked-l1-1-0.spec +index 9c6d25c..695e308 100644 +--- a/dlls/api-ms-win-core-interlocked-l1-1-0/api-ms-win-core-interlocked-l1-1-0.spec ++++ b/dlls/api-ms-win-core-interlocked-l1-1-0/api-ms-win-core-interlocked-l1-1-0.spec +@@ -8,5 +8,5 @@ + @ stdcall -arch=i386 InterlockedIncrement(ptr) kernel32.InterlockedIncrement + @ stdcall InterlockedPopEntrySList(ptr) kernel32.InterlockedPopEntrySList + @ stdcall InterlockedPushEntrySList(ptr ptr) kernel32.InterlockedPushEntrySList +-@ stub InterlockedPushListSList ++@ stdcall InterlockedPushListSList(ptr ptr ptr long) kernel32.InterlockedPushListSList + @ stdcall QueryDepthSList(ptr) kernel32.QueryDepthSList +diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec +index 68325ba..124bd74 100644 +--- a/dlls/kernel32/kernel32.spec ++++ b/dlls/kernel32/kernel32.spec +@@ -957,7 +957,7 @@ + @ stdcall -arch=i386 InterlockedIncrement(ptr) + @ stdcall InterlockedPopEntrySList(ptr) ntdll.RtlInterlockedPopEntrySList + @ stdcall InterlockedPushEntrySList(ptr ptr) ntdll.RtlInterlockedPushEntrySList +-# @ stub InterlockedPushListSList ++@ stdcall InterlockedPushListSList(ptr ptr ptr long) ntdll.RtlInterlockedPushListSList + @ stub InvalidateConsoleDIBits + @ stdcall InvalidateNLSCache() + @ stdcall IsBadCodePtr(ptr) +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-InterlockedPushListSList/definition wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-InterlockedPushListSList/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-InterlockedPushListSList/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-InterlockedPushListSList/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Forward InterlockedPushListSList to ntdll diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Named_Pipe/0005-server-Show-warning-if-message-mode-is-not-supported.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Named_Pipe/0005-server-Show-warning-if-message-mode-is-not-supported.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Named_Pipe/0005-server-Show-warning-if-message-mode-is-not-supported.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Named_Pipe/0005-server-Show-warning-if-message-mode-is-not-supported.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From db0a81d0a3513d169335286471969b1fb9c38be1 Mon Sep 17 00:00:00 2001 +From 630edc66479db789c7541e2c356a41090524d838 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 4 Aug 2014 00:29:26 +0200 Subject: server: Show warning if message mode is not supported. @@ -8,25 +8,25 @@ missing message mode support. --- dlls/ntdll/file.c | 14 ++++++++++---- - server/named_pipe.c | 1 + + server/named_pipe.c | 2 ++ server/protocol.def | 1 + - 3 files changed, 12 insertions(+), 4 deletions(-) + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 5232027..01cef2c 100644 +index 3883e5a..9e98f36 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c -@@ -3091,6 +3091,7 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, - { - struct security_descriptor *sd = NULL; - struct object_attributes objattr; -+ unsigned int flags; +@@ -3507,6 +3507,7 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, NTSTATUS status; + data_size_t len; + struct object_attributes *objattr; ++ unsigned int flags; TRACE("(%p %x %s %p %x %d %x %d %d %d %d %d %d %p)\n", -@@ -3109,16 +3110,17 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, - status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); - if (status != STATUS_SUCCESS) return status; + handle, access, debugstr_w(attr->ObjectName->Buffer), iosb, sharing, dispo, +@@ -3521,15 +3522,16 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, + + if ((status = alloc_object_attributes( attr, &objattr, &len ))) return status; + flags = (pipe_type ? NAMED_PIPE_MESSAGE_STREAM_WRITE : 0) | + (read_mode ? NAMED_PIPE_MESSAGE_STREAM_READ : 0) | @@ -35,7 +35,6 @@ SERVER_START_REQ( create_named_pipe ) { req->access = access; - req->attributes = attr->Attributes; req->options = options; req->sharing = sharing; - req->flags = @@ -46,8 +45,8 @@ req->maxinstances = max_inst; req->outsize = outbound_quota; req->insize = inbound_quota; -@@ -3128,9 +3130,13 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, - wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); +@@ -3537,9 +3539,13 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, + wine_server_add_data( req, objattr, len ); status = wine_server_call( req ); if (!status) *handle = wine_server_ptr_handle( reply->handle ); + flags &= ~reply->flags; /* contains now all unsupported flags */ @@ -57,26 +56,27 @@ + if (!status && (flags & (NAMED_PIPE_MESSAGE_STREAM_WRITE | NAMED_PIPE_MESSAGE_STREAM_READ))) + FIXME("Message mode not supported, falling back to byte mode.\n"); + - NTDLL_free_struct_sd( sd ); + RtlFreeHeap( GetProcessHeap(), 0, objattr ); return status; } diff --git a/server/named_pipe.c b/server/named_pipe.c -index 047b62c..81741de 100644 +index 7a97e35..ee6008c 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c -@@ -965,6 +965,7 @@ DECL_HANDLER(create_named_pipe) +@@ -934,6 +934,8 @@ DECL_HANDLER(create_named_pipe) return; } + reply->flags = req->flags & ~(NAMED_PIPE_MESSAGE_STREAM_WRITE | NAMED_PIPE_MESSAGE_STREAM_READ); - reply->handle = 0; - - if (!objattr_is_valid( objattr, get_req_data_size() )) ++ + if (!name.len) /* pipes need a root directory even without a name */ + { + if (!objattr->rootdir) diff --git a/server/protocol.def b/server/protocol.def -index fc6bec5..503b02f 100644 +index a5a45eb..2d87f03 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -2283,6 +2283,7 @@ enum message_type +@@ -2370,6 +2370,7 @@ enum message_type unsigned int flags; VARARG(objattr,object_attributes); /* object attributes */ @REPLY @@ -85,5 +85,5 @@ @END -- -2.1.3 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Named_Pipe/0006-ntdll-Unify-similar-code-in-NtReadFile-and-FILE_Asyn.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Named_Pipe/0006-ntdll-Unify-similar-code-in-NtReadFile-and-FILE_Asyn.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Named_Pipe/0006-ntdll-Unify-similar-code-in-NtReadFile-and-FILE_Asyn.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Named_Pipe/0006-ntdll-Unify-similar-code-in-NtReadFile-and-FILE_Asyn.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 8ad4ff3e0ed7e3065a1f408873a69d51cb6b3b51 Mon Sep 17 00:00:00 2001 +From 22c72712928594addc4e717d2bb3fd8185db4479 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 15 Aug 2014 22:23:08 +0200 Subject: ntdll: Unify similar code in NtReadFile and FILE_AsyncReadService. @@ -15,14 +15,14 @@ whereas NtReadFile uses different behaviour based on the fd type. Now both implementations match, and behave the same way. --- - dlls/ntdll/file.c | 108 +++++++++++++++++++++++------------------------------- - 1 file changed, 46 insertions(+), 62 deletions(-) + dlls/ntdll/file.c | 102 ++++++++++++++++++++++++------------------------------ + 1 file changed, 46 insertions(+), 56 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 79daec5..fd88777 100644 +index 4134b9b..72bbaa2 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c -@@ -471,6 +471,45 @@ NTSTATUS FILE_GetNtStatus(void) +@@ -486,6 +486,45 @@ NTSTATUS FILE_GetNtStatus(void) } } @@ -68,7 +68,7 @@ /*********************************************************************** * FILE_AsyncReadService (INTERNAL) */ -@@ -478,44 +517,19 @@ static NTSTATUS FILE_AsyncReadService( void *user, IO_STATUS_BLOCK *iosb, +@@ -493,38 +532,19 @@ static NTSTATUS FILE_AsyncReadService( void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status, void **apc, void **arg ) { struct async_fileio_read *fileio = user; @@ -107,18 +107,12 @@ - if (fileio->already >= fileio->count || fileio->avail_mode) - status = STATUS_SUCCESS; - else -- { -- /* if we only have to read the available data, and none is available, -- * simply cancel the request. If data was available, it has been read -- * while in by previous call (NtDelayExecution) -- */ -- status = (fileio->avail_mode) ? STATUS_SUCCESS : STATUS_PENDING; -- } +- status = STATUS_PENDING; - } break; case STATUS_TIMEOUT: -@@ -762,7 +776,6 @@ static NTSTATUS get_io_avail_mode( HANDLE handle, enum server_fd_type type, BOOL +@@ -771,7 +791,6 @@ static NTSTATUS get_io_avail_mode( HANDLE handle, enum server_fd_type type, BOOL return status; } @@ -126,7 +120,7 @@ /****************************************************************************** * NtReadFile [NTDLL.@] * ZwReadFile [NTDLL.@] -@@ -858,38 +871,9 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, +@@ -867,38 +886,9 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent, for (;;) { @@ -168,5 +162,5 @@ if (async_read) { -- -2.4.0 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Named_Pipe/0009-server-Use-SOCK_SEQPACKET-socket-in-combination-with.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Named_Pipe/0009-server-Use-SOCK_SEQPACKET-socket-in-combination-with.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Named_Pipe/0009-server-Use-SOCK_SEQPACKET-socket-in-combination-with.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Named_Pipe/0009-server-Use-SOCK_SEQPACKET-socket-in-combination-with.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From c36c3e7049560da14340b1e5ce390cd91ef90c08 Mon Sep 17 00:00:00 2001 +From 6f7aea78c09e8c1ef0e93aef214ac28fe223d544 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 4 Aug 2014 05:01:11 +0200 Subject: server: Use SOCK_SEQPACKET socket in combination with SO_PEEK_OFF to @@ -49,7 +49,7 @@ } else SetLastError( RtlNtStatusToDosError(status) ); diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c -index 1ac4ed1..fded318 100644 +index 544b7fa..5f5553b 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -286,7 +286,6 @@ static void test_CreateNamedPipe(int pipemode) @@ -149,7 +149,7 @@ ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL); ok(ret, "RpcReadFile 10\n"); diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index c0ca068..fd6c605 100644 +index eef36ad..420984c 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -91,6 +91,10 @@ @@ -163,7 +163,7 @@ #include "ntstatus.h" #define WIN32_NO_STATUS #define NONAMELESSUNION -@@ -511,18 +515,57 @@ static NTSTATUS unix_fd_avail(int fd, int *avail) +@@ -509,18 +513,57 @@ static NTSTATUS unix_fd_avail(int fd, int *avail) STATUS_PIPE_BROKEN : STATUS_SUCCESS; } @@ -224,7 +224,7 @@ { if (*total) return STATUS_SUCCESS; -@@ -538,16 +581,17 @@ static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, +@@ -536,16 +579,17 @@ static NTSTATUS read_unix_fd(int fd, char *buf, ULONG *total, ULONG length, return STATUS_PIPE_BROKEN; } } @@ -246,7 +246,7 @@ } /*********************************************************************** -@@ -1105,13 +1149,14 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap +@@ -1103,13 +1147,14 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap /* helper function for NtWriteFile and FILE_AsyncWriteService */ static NTSTATUS write_unix_fd(int fd, const char *buf, ULONG *total, ULONG length, enum server_fd_type type) { @@ -262,7 +262,7 @@ if (result >= 0) { *total += result; -@@ -1120,6 +1165,17 @@ static NTSTATUS write_unix_fd(int fd, const char *buf, ULONG *total, ULONG lengt +@@ -1118,6 +1163,17 @@ static NTSTATUS write_unix_fd(int fd, const char *buf, ULONG *total, ULONG lengt else if (type != FD_TYPE_FILE) /* no async I/O on regular files */ return STATUS_PENDING; } @@ -280,7 +280,7 @@ else if (errno != EINTR) { if (errno == EAGAIN) -@@ -1710,20 +1766,40 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc +@@ -1708,20 +1764,40 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc status = unix_fd_avail( fd, &avail ); if (!status) { @@ -329,7 +329,7 @@ if (needs_close) close( fd ); } diff --git a/server/named_pipe.c b/server/named_pipe.c -index 494a3d8..9df5915 100644 +index 3e1eff0..3d9917f 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -42,6 +42,10 @@ @@ -351,8 +351,8 @@ #include "handle.h" #include "thread.h" #include "request.h" -@@ -783,14 +788,43 @@ static struct pipe_server *find_available_server( struct named_pipe *pipe ) - return NULL; +@@ -799,14 +804,43 @@ static int named_pipe_link_name( struct object *obj, struct object_name *name, s + return 1; } +/* check if message mode named pipes are supported */ @@ -396,7 +396,7 @@ if (!(server = find_available_server( pipe ))) { -@@ -809,7 +843,10 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc +@@ -825,7 +859,10 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc if ((client = create_pipe_client( options, pipe->flags ))) { @@ -408,7 +408,7 @@ { assert( !server->fd ); -@@ -819,32 +856,55 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc +@@ -835,32 +872,55 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc if (is_overlapped( options )) fcntl( fds[1], F_SETFL, O_NONBLOCK ); if (is_overlapped( server->options )) fcntl( fds[0], F_SETFL, O_NONBLOCK ); @@ -483,16 +483,16 @@ release_object( client ); client = NULL; } -@@ -933,7 +993,7 @@ DECL_HANDLER(create_named_pipe) +@@ -951,7 +1011,7 @@ DECL_HANDLER(create_named_pipe) return; } - reply->flags = req->flags & ~(NAMED_PIPE_MESSAGE_STREAM_WRITE | NAMED_PIPE_MESSAGE_STREAM_READ); + reply->flags = messagemode_flags(req->flags); - reply->handle = 0; - if (!objattr_is_valid( objattr, get_req_data_size() )) -@@ -1033,6 +1093,9 @@ DECL_HANDLER(set_named_pipe_info) + if (!name.len) /* pipes need a root directory even without a name */ + { +@@ -1054,6 +1114,9 @@ DECL_HANDLER(set_named_pipe_info) { struct pipe_server *server; struct pipe_client *client = NULL; @@ -502,7 +502,7 @@ server = get_pipe_server_obj( current->process, req->handle, FILE_WRITE_ATTRIBUTES ); if (!server) -@@ -1055,10 +1118,20 @@ DECL_HANDLER(set_named_pipe_info) +@@ -1080,10 +1143,20 @@ DECL_HANDLER(set_named_pipe_info) else if (client) { client->pipe_flags = server->pipe->flags | req->flags; @@ -524,7 +524,7 @@ if (client) diff --git a/server/sock.c b/server/sock.c -index 1767dea..095c569 100644 +index a11964f..0a2e079 100644 --- a/server/sock.c +++ b/server/sock.c @@ -61,6 +61,7 @@ @@ -543,7 +543,7 @@ static const struct object_ops sock_ops = { -@@ -955,7 +955,7 @@ static int sock_get_ntstatus( int err ) +@@ -958,7 +958,7 @@ static int sock_get_ntstatus( int err ) } /* set the last error depending on errno */ @@ -585,5 +585,5 @@ + +#endif /* __WINE_SERVER_SOCK_H */ -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Named_Pipe/0020-server-Return-correct-error-codes-for-NtWriteFile-wh.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Named_Pipe/0020-server-Return-correct-error-codes-for-NtWriteFile-wh.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-Named_Pipe/0020-server-Return-correct-error-codes-for-NtWriteFile-wh.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-Named_Pipe/0020-server-Return-correct-error-codes-for-NtWriteFile-wh.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From ffd7b942761e5010bdc234f10e5e9721c8d8159b Mon Sep 17 00:00:00 2001 +From f31780d39178e9e4aa98962d04a51e4f7440757d Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 6 Jun 2015 01:21:05 +0200 Subject: server: Return correct error codes for NtWriteFile when pipes are @@ -25,10 +25,10 @@ CloseHandle(hfile); diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 42d1fae..3bb2905 100644 +index a925899..af4b64e 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c -@@ -1213,6 +1213,9 @@ static NTSTATUS write_unix_fd(int fd, const char *buf, ULONG *total, ULONG lengt +@@ -1211,6 +1211,9 @@ static NTSTATUS write_unix_fd(int fd, const char *buf, ULONG *total, ULONG lengt return STATUS_SUCCESS; else if (errno == EFAULT) return STATUS_INVALID_USER_BUFFER; @@ -39,10 +39,10 @@ } } diff --git a/server/named_pipe.c b/server/named_pipe.c -index 37f97ed..28816a2 100644 +index 55c0db7..e4dbf26 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c -@@ -145,6 +145,7 @@ static const struct object_ops named_pipe_ops = +@@ -147,6 +147,7 @@ static const struct object_ops named_pipe_ops = /* server end functions */ static void pipe_server_dump( struct object *obj, int verbose ); static struct fd *pipe_server_get_fd( struct object *obj ); @@ -50,8 +50,8 @@ static void pipe_server_destroy( struct object *obj); static obj_handle_t pipe_server_flush( struct fd *fd, const async_data_t *async, int blocking ); static enum server_fd_type pipe_server_get_fd_type( struct fd *fd ); -@@ -168,7 +169,7 @@ static const struct object_ops pipe_server_ops = - no_lookup_name, /* lookup_name */ +@@ -172,7 +173,7 @@ static const struct object_ops pipe_server_ops = + NULL, /* unlink_name */ no_open_file, /* open_file */ no_alloc_handle, /* alloc_handle */ - fd_close_handle, /* close_handle */ @@ -59,7 +59,7 @@ pipe_server_destroy /* destroy */ }; -@@ -190,6 +191,7 @@ static const struct fd_ops pipe_server_fd_ops = +@@ -194,6 +195,7 @@ static const struct fd_ops pipe_server_fd_ops = static void pipe_client_dump( struct object *obj, int verbose ); static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *entry ); static struct fd *pipe_client_get_fd( struct object *obj ); @@ -67,8 +67,8 @@ static void pipe_client_destroy( struct object *obj ); static obj_handle_t pipe_client_flush( struct fd *fd, const async_data_t *async, int blocking ); static enum server_fd_type pipe_client_get_fd_type( struct fd *fd ); -@@ -211,7 +213,7 @@ static const struct object_ops pipe_client_ops = - no_lookup_name, /* lookup_name */ +@@ -217,7 +219,7 @@ static const struct object_ops pipe_client_ops = + NULL, /* unlink_name */ no_open_file, /* open_file */ no_alloc_handle, /* alloc_handle */ - fd_close_handle, /* close_handle */ @@ -76,7 +76,7 @@ pipe_client_destroy /* destroy */ }; -@@ -276,6 +278,8 @@ static const struct fd_ops named_pipe_device_fd_ops = +@@ -284,6 +286,8 @@ static const struct fd_ops named_pipe_device_fd_ops = default_fd_cancel_async /* cancel_async */ }; @@ -84,8 +84,8 @@ + static void named_pipe_dump( struct object *obj, int verbose ) { - struct named_pipe *pipe = (struct named_pipe *) obj; -@@ -390,6 +394,23 @@ static void do_disconnect( struct pipe_server *server ) + fputs( "Named pipe\n", stderr ); +@@ -394,6 +398,23 @@ static void do_disconnect( struct pipe_server *server ) server->fd = NULL; } @@ -109,7 +109,7 @@ static void pipe_server_destroy( struct object *obj) { struct pipe_server *server = (struct pipe_server *)obj; -@@ -416,6 +437,24 @@ static void pipe_server_destroy( struct object *obj) +@@ -420,6 +441,24 @@ static void pipe_server_destroy( struct object *obj) release_object( server->pipe ); } @@ -135,10 +135,10 @@ { struct pipe_client *client = (struct pipe_client *)obj; diff --git a/server/protocol.def b/server/protocol.def -index 6b2030b..390c09a 100644 +index 2d87f03..1dc70d4 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -2389,6 +2389,7 @@ enum message_type +@@ -2378,6 +2378,7 @@ enum message_type #define NAMED_PIPE_MESSAGE_STREAM_WRITE 0x0001 #define NAMED_PIPE_MESSAGE_STREAM_READ 0x0002 #define NAMED_PIPE_NONBLOCKING_MODE 0x0004 @@ -147,5 +147,5 @@ /* Get named pipe information by handle */ -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-QT_Environment_Variables/0001-kernel32-Do-not-inherit-QT_-environment-variables-to.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-QT_Environment_Variables/0001-kernel32-Do-not-inherit-QT_-environment-variables-to.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-QT_Environment_Variables/0001-kernel32-Do-not-inherit-QT_-environment-variables-to.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-QT_Environment_Variables/0001-kernel32-Do-not-inherit-QT_-environment-variables-to.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,29 @@ +From c62a9b8f39fcdd2209959e831e3801162b41420c Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 27 Jan 2016 06:56:09 +0100 +Subject: kernel32: Do not inherit QT_* environment variables to Windows + environment. + +If necessary, QT environment variables can still be set by adding a WINE +prefix, for example: WINEQT_QPA_PLATFORM=... +--- + dlls/kernel32/process.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c +index 6e7b23e..bb6c2dd 100644 +--- a/dlls/kernel32/process.c ++++ b/dlls/kernel32/process.c +@@ -135,7 +135,8 @@ static inline BOOL is_special_env_var( const char *var ) + !strncmp( var, "PWD=", sizeof("PWD=")-1 ) || + !strncmp( var, "HOME=", sizeof("HOME=")-1 ) || + !strncmp( var, "TEMP=", sizeof("TEMP=")-1 ) || +- !strncmp( var, "TMP=", sizeof("TMP=")-1 )); ++ !strncmp( var, "TMP=", sizeof("TMP=")-1 ) || ++ !strncmp( var, "QT_", sizeof("QT_")-1 )); + } + + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-QT_Environment_Variables/definition wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-QT_Environment_Variables/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-QT_Environment_Variables/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-QT_Environment_Variables/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Do not inherit QT_* environment variables to Windows environment diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-VirtualProtect/0001-kernel32-Allow-to-pass-NULL-as-old-protection-in-Vir.patch wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-VirtualProtect/0001-kernel32-Allow-to-pass-NULL-as-old-protection-in-Vir.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-VirtualProtect/0001-kernel32-Allow-to-pass-NULL-as-old-protection-in-Vir.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-VirtualProtect/0001-kernel32-Allow-to-pass-NULL-as-old-protection-in-Vir.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,33 @@ +From d14a5ed33cdc95ff03c64f6fa574d07da5515825 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 6 Feb 2016 21:23:10 +0100 +Subject: kernel32: Allow to pass NULL as old protection in VirtualProtect for + Win9X. + +--- + dlls/kernel32/virtual.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/dlls/kernel32/virtual.c b/dlls/kernel32/virtual.c +index 03ef38c..e164151 100644 +--- a/dlls/kernel32/virtual.c ++++ b/dlls/kernel32/virtual.c +@@ -235,7 +235,14 @@ BOOL WINAPI VirtualProtect( LPVOID addr, SIZE_T size, DWORD new_prot, LPDWORD ol + BOOL WINAPI VirtualProtectEx( HANDLE process, LPVOID addr, SIZE_T size, + DWORD new_prot, LPDWORD old_prot ) + { +- NTSTATUS status = NtProtectVirtualMemory( process, &addr, &size, new_prot, old_prot ); ++ NTSTATUS status; ++ DWORD dummy; ++ ++ /* Win9x allows to pass NULL as old_prot while it fails on NT */ ++ if (!old_prot && (GetVersion() & 0x80000000)) ++ old_prot = &dummy; ++ ++ status = NtProtectVirtualMemory( process, &addr, &size, new_prot, old_prot ); + if (status) SetLastError( RtlNtStatusToDosError(status) ); + return !status; + } +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-VirtualProtect/definition wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-VirtualProtect/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/kernel32-VirtualProtect/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/kernel32-VirtualProtect/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Allow to pass NULL as old protection in VirtualProtect for Win9X diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/libs-Unicode_Collation/0001-libs-Fix-most-problems-with-CompareString.patch wine-staging-1.9.3~ubuntu12.04.1/patches/libs-Unicode_Collation/0001-libs-Fix-most-problems-with-CompareString.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/libs-Unicode_Collation/0001-libs-Fix-most-problems-with-CompareString.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/libs-Unicode_Collation/0001-libs-Fix-most-problems-with-CompareString.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 9a4f8fae5a735a8ceeec6136b548420abb69f336 Mon Sep 17 00:00:00 2001 +From a72962dc4ff3d6126e105aec97cfcb88da535b81 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Mon, 28 Jul 2003 07:39:25 -0500 Subject: libs: Fix most problems with CompareString. @@ -9,10 +9,10 @@ 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c -index 7b0212e..cba3ebc 100644 +index b760e9a..6317112 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c -@@ -1759,13 +1759,13 @@ static void test_CompareStringA(void) +@@ -1761,13 +1761,13 @@ static void test_CompareStringA(void) todo_wine ok(ret != CSTR_EQUAL, "\\2 vs \\1 expected unequal\n"); ret = CompareStringA(lcid, NORM_IGNORECASE | LOCALE_USE_CP_ACP, "#", -1, ".", -1); @@ -29,10 +29,10 @@ lcid = MAKELCID(MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT), SORT_DEFAULT); -@@ -4600,6 +4600,5 @@ START_TEST(locale) - test_GetGeoInfo(); +@@ -4801,6 +4801,5 @@ START_TEST(locale) test_EnumSystemGeoID(); test_invariant(); + test_GetSystemPreferredUILanguages(); - /* this requires collation table patch to make it MS compatible */ - if (0) test_sorting(); + test_sorting(); @@ -168,5 +168,5 @@ 0x0a130121, 0x0a140121, 0x02370121, 0x02350121, 0x03a30121, 0x03a40121, 0x03a50121, 0x024e0121, 0x02a10121, 0x0a150161, 0x0a290151, 0x0a3d0161, 0x0a490161, 0x0a650161, 0x0a910161, 0x0a990161, -- -2.6.2 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/mmsystem.dll16-Fix_Argument_Order/0001-mmsystem.dll16-Fix-argument-order-in-GlobalAlloc16-c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/mmsystem.dll16-Fix_Argument_Order/0001-mmsystem.dll16-Fix-argument-order-in-GlobalAlloc16-c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/mmsystem.dll16-Fix_Argument_Order/0001-mmsystem.dll16-Fix-argument-order-in-GlobalAlloc16-c.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/mmsystem.dll16-Fix_Argument_Order/0001-mmsystem.dll16-Fix-argument-order-in-GlobalAlloc16-c.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,25 @@ +From f1183d4c50ba5fc854873bdc8a6c96ace56a2e00 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Mon, 8 Feb 2016 03:24:47 +0100 +Subject: mmsystem.dll16: Fix argument order in GlobalAlloc16 call. + +--- + dlls/mmsystem.dll16/mmsystem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/mmsystem.dll16/mmsystem.c b/dlls/mmsystem.dll16/mmsystem.c +index fdf1318..d90240d 100644 +--- a/dlls/mmsystem.dll16/mmsystem.c ++++ b/dlls/mmsystem.dll16/mmsystem.c +@@ -1943,7 +1943,7 @@ LRESULT WINAPI mmThreadCreate16(FARPROC16 fpThreadAddr, LPHANDLE16 lpHndl, DWORD + + TRACE("(%p, %p, %08x, %08x)!\n", fpThreadAddr, lpHndl, dwPmt, dwFlags); + +- hndl = GlobalAlloc16(sizeof(WINE_MMTHREAD), GMEM_SHARE|GMEM_ZEROINIT); ++ hndl = GlobalAlloc16(GMEM_SHARE|GMEM_ZEROINIT, sizeof(WINE_MMTHREAD)); + + if (hndl == 0) { + ret = 2; +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/msvcr120-_SetWinRTOutOfMemoryExceptionCallback/0001-msvcr120-Add-stub-for-_SetWinRTOutOfMemoryExceptionC.patch wine-staging-1.9.3~ubuntu12.04.1/patches/msvcr120-_SetWinRTOutOfMemoryExceptionCallback/0001-msvcr120-Add-stub-for-_SetWinRTOutOfMemoryExceptionC.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/msvcr120-_SetWinRTOutOfMemoryExceptionCallback/0001-msvcr120-Add-stub-for-_SetWinRTOutOfMemoryExceptionC.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/msvcr120-_SetWinRTOutOfMemoryExceptionCallback/0001-msvcr120-Add-stub-for-_SetWinRTOutOfMemoryExceptionC.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,56 @@ +From e10eaddb1261c79cb80fc99172e1f53b1b7daf53 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 15 Jan 2016 12:58:17 +0100 +Subject: msvcr120: Add stub for _SetWinRTOutOfMemoryExceptionCallback. + +--- + dlls/msvcr120/msvcr120.spec | 2 +- + dlls/msvcr120_app/msvcr120_app.spec | 2 +- + dlls/msvcrt/misc.c | 8 ++++++++ + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec +index 461b529..67c7fc4 100644 +--- a/dlls/msvcr120/msvcr120.spec ++++ b/dlls/msvcr120/msvcr120.spec +@@ -844,7 +844,7 @@ + @ stub -arch=i386 _NLG_Return + @ stub -arch=i386 _NLG_Return2 + @ stub -arch=arm,win64 __NLG_Return2 +-@ stub _SetWinRTOutOfMemoryExceptionCallback ++@ cdecl -arch=i386,x86_64,arm _SetWinRTOutOfMemoryExceptionCallback(ptr) MSVCR120__SetWinRTOutOfMemoryExceptionCallback + @ stub -arch=win64 _SetImageBase + @ stub -arch=win64 _SetThrowImageBase + @ cdecl _Strftime(str long str ptr ptr) +diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec +index 425c839..ff71998 100644 +--- a/dlls/msvcr120_app/msvcr120_app.spec ++++ b/dlls/msvcr120_app/msvcr120_app.spec +@@ -838,7 +838,7 @@ + @ stub -arch=i386 _NLG_Return + @ stub -arch=i386 _NLG_Return2 + @ stub -arch=arm,win64 __NLG_Return2 +-@ stub _SetWinRTOutOfMemoryExceptionCallback ++@ cdecl -arch=i386,x86_64,arm _SetWinRTOutOfMemoryExceptionCallback(ptr) msvcr120._SetWinRTOutOfMemoryExceptionCallback + @ stub -arch=win64 _SetImageBase + @ stub -arch=win64 _SetThrowImageBase + @ cdecl _Strftime(str long str ptr ptr) msvcr120._Strftime +diff --git a/dlls/msvcrt/misc.c b/dlls/msvcrt/misc.c +index c1510ef..6842f1e 100644 +--- a/dlls/msvcrt/misc.c ++++ b/dlls/msvcrt/misc.c +@@ -506,3 +506,11 @@ void CDECL MSVCRT__crt_debugger_hook(int reserved) + { + WARN("(%x)\n", reserved); + } ++ ++/********************************************************************* ++ * _SetWinRTOutOfMemoryExceptionCallback (MSVCR120.@) ++ */ ++void CDECL MSVCR120__SetWinRTOutOfMemoryExceptionCallback(void *callback) ++{ ++ FIXME("(%p): stub\n", callback); ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/msvcr120-_SetWinRTOutOfMemoryExceptionCallback/definition wine-staging-1.9.3~ubuntu12.04.1/patches/msvcr120-_SetWinRTOutOfMemoryExceptionCallback/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/msvcr120-_SetWinRTOutOfMemoryExceptionCallback/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/msvcr120-_SetWinRTOutOfMemoryExceptionCallback/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Add stub for _SetWinRTOutOfMemoryExceptionCallback diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/msvcr120-strof/0001-msvcr120-Implement-strtof-and-_strtof_l-try-3.patch wine-staging-1.9.3~ubuntu12.04.1/patches/msvcr120-strof/0001-msvcr120-Implement-strtof-and-_strtof_l-try-3.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/msvcr120-strof/0001-msvcr120-Implement-strtof-and-_strtof_l-try-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/msvcr120-strof/0001-msvcr120-Implement-strtof-and-_strtof_l-try-3.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,218 @@ +From 3643749b0652684231f2c3d7b522abac4adc239d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= +Date: Fri, 14 Aug 2015 04:44:07 +0200 +Subject: msvcr120: Implement strtof and _strtof_l (try 3) + +SuperTux 0.3.5a needs msvcr120.strtof. +Found during research for bug #39034. + +Changes try 3: +- Avoid almost_equal with float, instead use compare_float from ddraw7 tests + (thanks Henri Verbeet) +- Used functions should be available in all versions of msvcr120; + therefore avoid the win_skips. (thanks Piotr Caban) + +Changes try 2: +- In the test replaced the bit pattern comparison to detect + infinity by msvcr120._finite + (thanks Piotr Caban; _finitef is just available at arm and x86_64) + +A note to the tests: +It seems because the functions get dynamically loaded the functions +_errno() and p__errno() returning different variables. +Therefore using also the dynamically loaded p__errno() in tests. +The executable built via make crosstest is linked against msvcrt.dll. +--- + dlls/msvcr120/msvcr120.spec | 4 +-- + dlls/msvcr120/tests/msvcr120.c | 69 +++++++++++++++++++++++++++++++++++++ + dlls/msvcr120_app/msvcr120_app.spec | 4 +-- + dlls/msvcrt/string.c | 16 +++++++++ + 4 files changed, 89 insertions(+), 4 deletions(-) + +diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec +index 9931820..330a83f 100644 +--- a/dlls/msvcr120/msvcr120.spec ++++ b/dlls/msvcr120/msvcr120.spec +@@ -1731,7 +1731,7 @@ + @ cdecl _strtime(ptr) MSVCRT__strtime + @ cdecl _strtime_s(ptr long) + @ cdecl _strtod_l(str ptr ptr) MSVCRT_strtod_l +-@ stub _strtof_l ++@ cdecl _strtof_l(str ptr ptr) MSVCRT_strtof_l + @ cdecl -ret64 _strtoi64(str ptr long) MSVCRT_strtoi64 + @ cdecl -ret64 _strtoi64_l(str ptr long ptr) MSVCRT_strtoi64_l + @ stub _strtoimax_l +@@ -2386,7 +2386,7 @@ + @ cdecl strspn(str str) ntdll.strspn + @ cdecl strstr(str str) MSVCRT_strstr + @ cdecl strtod(str ptr) MSVCRT_strtod +-@ stub strtof ++@ cdecl strtof(str ptr) MSVCRT_strtof + @ stub strtoimax + @ cdecl strtok(str str) MSVCRT_strtok + @ cdecl strtok_s(ptr str ptr) MSVCRT_strtok_s +diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c +index aa78c4f..bce8aff 100644 +--- a/dlls/msvcr120/tests/msvcr120.c ++++ b/dlls/msvcr120/tests/msvcr120.c +@@ -21,6 +21,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -73,6 +75,11 @@ struct MSVCRT_lconv + wchar_t* _W_negative_sign; + }; + ++static inline BOOL almost_equal(float d1, float d2) ++{ ++ return (d1-d2 > -1e-15 && d1-d2 < 1e-15); ++} ++ + static char* (CDECL *p_setlocale)(int category, const char* locale); + static struct MSVCRT_lconv* (CDECL *p_localeconv)(void); + static size_t (CDECL *p_wcstombs_s)(size_t *ret, char* dest, size_t sz, const wchar_t* src, size_t max); +@@ -83,6 +90,8 @@ static wchar_t** (CDECL *p____lc_locale_name_func)(void); + static unsigned int (CDECL *p__GetConcurrency)(void); + static void* (CDECL *p__W_Gettnames)(void); + static void (CDECL *p_free)(void*); ++static float (CDECL *p__strtof_l)(const char *, char **, _locale_t); ++static float (CDECL *p_strtof)(const char *, char **); + + static BOOL init(void) + { +@@ -105,6 +114,8 @@ static BOOL init(void) + p__GetConcurrency = (void*)GetProcAddress(module,"?_GetConcurrency@details@Concurrency@@YAIXZ"); + p__W_Gettnames = (void*)GetProcAddress(module, "_W_Gettnames"); + p_free = (void*)GetProcAddress(module, "free"); ++ p__strtof_l = (void*)GetProcAddress(module, "_strtof_l"); ++ p_strtof = (void*)GetProcAddress(module, "strtof"); + return TRUE; + } + +@@ -321,6 +332,63 @@ static void test__W_Gettnames(void) + p_setlocale(LC_ALL, "C"); + } + ++static void test__strtof(void) ++{ ++ const char float1[] = "12.1"; ++ const char float2[] = "3.402823466e+38"; /* FLT_MAX */ ++ const char float3[] = "-3.402823466e+38"; ++ const char float4[] = "1.7976931348623158e+308"; /* DBL_MAX */ ++ const char float5[] = "-1.7976931348623158e+308"; ++ ++ char *end; ++ float f; ++ ++ f = FLT_MAX * FLT_MAX; ++ ok(_finite(f) == 0, "_finite failed\n"); ++ ++ /* strtof */ ++ f = p_strtof(float1, &end); ++ ok(almost_equal(f, 12.1), "f = %lf\n", f); ++ ok(end == float1+4, "incorrect end (%d)\n", (int)(end-float1)); ++ ++ f = p_strtof(float2, &end); ++ ok(almost_equal(f, FLT_MAX), "f = %lf\n", f); ++ ok(end == float2+15, "incorrect end (%d)\n", (int)(end-float2)); ++ ++ f = p_strtof(float3, &end); ++ ok(almost_equal(f, -FLT_MAX), "f = %lf\n", f); ++ ok(end == float3+16, "incorrect end (%d)\n", (int)(end-float3)); ++ ++ f = p_strtof(float4, &end); ++ ok(_finite(f) == 0, "f = %lf\n", f); ++ ok(end == float4+23, "incorrect end (%d)\n", (int)(end-float4)); ++ ++ f = p_strtof(float5, &end); ++ ok(_finite(f) == 0, "f = %lf\n", f); ++ ok(end == float5+24, "incorrect end (%d)\n", (int)(end-float5)); ++ ++ /* _strtof_l */ ++ f = p__strtof_l(float1, &end, NULL); ++ ok(almost_equal(f, 12.1), "f = %lf\n", f); ++ ok(end == float1+4, "incorrect end (%d)\n", (int)(end-float1)); ++ ++ f = p__strtof_l(float2, &end, NULL); ++ ok(almost_equal(f, FLT_MAX), "f = %lf\n", f); ++ ok(end == float2+15, "incorrect end (%d)\n", (int)(end-float2)); ++ ++ f = p__strtof_l(float3, &end, NULL); ++ ok(almost_equal(f, -FLT_MAX), "f = %lf\n", f); ++ ok(end == float3+16, "incorrect end (%d)\n", (int)(end-float3)); ++ ++ f = p__strtof_l(float4, &end, NULL); ++ ok(_finite(f) == 0, "f = %lf\n", f); ++ ok(end == float4+23, "incorrect end (%d)\n", (int)(end-float4)); ++ ++ f = p__strtof_l(float5, &end, NULL); ++ ok(_finite(f) == 0, "f = %lf\n", f); ++ ok(end == float5+24, "incorrect end (%d)\n", (int)(end-float5)); ++} ++ + START_TEST(msvcr120) + { + if (!init()) return; +@@ -330,4 +398,5 @@ START_TEST(msvcr120) + test____lc_locale_name_func(); + test__GetConcurrency(); + test__W_Gettnames(); ++ test__strtof(); + } +diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec +index 50066ed..28c929d 100644 +--- a/dlls/msvcr120_app/msvcr120_app.spec ++++ b/dlls/msvcr120_app/msvcr120_app.spec +@@ -1442,7 +1442,7 @@ + @ cdecl _strtime(ptr) msvcr120._strtime + @ cdecl _strtime_s(ptr long) msvcr120._strtime_s + @ cdecl _strtod_l(str ptr ptr) msvcr120._strtod_l +-@ stub _strtof_l ++@ cdecl _strtof_l(str ptr ptr) msvcr120._strtof_l + @ cdecl -ret64 _strtoi64(str ptr long) msvcr120._strtoi64 + @ cdecl -ret64 _strtoi64_l(str ptr long ptr) msvcr120._strtoi64_l + @ stub _strtoimax_l +@@ -2049,7 +2049,7 @@ + @ cdecl strspn(str str) msvcr120.strspn + @ cdecl strstr(str str) msvcr120.strstr + @ cdecl strtod(str ptr) msvcr120.strtod +-@ stub strtof ++@ cdecl strtof(str ptr) msvcr120.strtof + @ stub strtoimax + @ cdecl strtok(str str) msvcr120.strtok + @ cdecl strtok_s(ptr str ptr) msvcr120.strtok_s +diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c +index f44ac52..9961549 100644 +--- a/dlls/msvcrt/string.c ++++ b/dlls/msvcrt/string.c +@@ -497,6 +497,22 @@ double CDECL MSVCRT_strtod( const char *str, char **end ) + } + + /********************************************************************* ++ * strtof_l (MSVCRT.@) ++ */ ++float CDECL MSVCRT_strtof_l( const char *str, char **end, MSVCRT__locale_t locale ) ++{ ++ return MSVCRT_strtod_l(str, end, locale); ++} ++ ++/********************************************************************* ++ * strtof (MSVCRT.@) ++ */ ++float CDECL MSVCRT_strtof( const char *str, char **end ) ++{ ++ return MSVCRT_strtof_l(str, end, NULL); ++} ++ ++/********************************************************************* + * atof (MSVCRT.@) + */ + double CDECL MSVCRT_atof( const char *str ) +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/msvcr120-strof/definition wine-staging-1.9.3~ubuntu12.04.1/patches/msvcr120-strof/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/msvcr120-strof/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/msvcr120-strof/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [39908] Implement msvcr120.strtof and _strtof_l diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/msvideo-MCIWNDM_SETTIMEFORMATA/0001-msvideo.dll-Translate-16-bit-address-in-MCIWNDM_SETT.patch wine-staging-1.9.3~ubuntu12.04.1/patches/msvideo-MCIWNDM_SETTIMEFORMATA/0001-msvideo.dll-Translate-16-bit-address-in-MCIWNDM_SETT.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/msvideo-MCIWNDM_SETTIMEFORMATA/0001-msvideo.dll-Translate-16-bit-address-in-MCIWNDM_SETT.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/msvideo-MCIWNDM_SETTIMEFORMATA/0001-msvideo.dll-Translate-16-bit-address-in-MCIWNDM_SETT.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,28 @@ +From 3e131a30d2f1b69de3c378b54f82f03f45bba6bb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 6 Feb 2016 02:24:05 +0100 +Subject: msvideo.dll16: Translate 16 bit address in MCIWNDM_SETTIMEFORMATA + command. + +--- + dlls/msvideo.dll16/msvideo16.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/dlls/msvideo.dll16/msvideo16.c b/dlls/msvideo.dll16/msvideo16.c +index 1b715e4..f39b52d 100644 +--- a/dlls/msvideo.dll16/msvideo16.c ++++ b/dlls/msvideo.dll16/msvideo16.c +@@ -991,6 +991,10 @@ static LRESULT WINAPI MCIWndProc16(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp + lparam = (ULONG_PTR)MapSL(lparam); + break; + ++ case MCIWNDM_SETTIMEFORMATA: ++ lparam = (ULONG_PTR)MapSL(lparam); ++ break; ++ + default: + break; + } +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/msvideo-MCIWNDM_SETTIMEFORMATA/definition wine-staging-1.9.3~ubuntu12.04.1/patches/msvideo-MCIWNDM_SETTIMEFORMATA/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/msvideo-MCIWNDM_SETTIMEFORMATA/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/msvideo-MCIWNDM_SETTIMEFORMATA/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Translate 16 bit address in MCIWNDM_SETTIMEFORMATA MCIWndProc16 command diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-ApiSetQueryApiSetPresence/0001-ntdll-Add-stub-for-ApiSetQueryApiSetPresence.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-ApiSetQueryApiSetPresence/0001-ntdll-Add-stub-for-ApiSetQueryApiSetPresence.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-ApiSetQueryApiSetPresence/0001-ntdll-Add-stub-for-ApiSetQueryApiSetPresence.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-ApiSetQueryApiSetPresence/0001-ntdll-Add-stub-for-ApiSetQueryApiSetPresence.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,44 @@ +From 455be0d2473a895b51e83d4d8c882724fef6b118 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 15 Jan 2016 13:17:31 +0100 +Subject: ntdll: Add stub for ApiSetQueryApiSetPresence. + +--- + dlls/ntdll/misc.c | 11 +++++++++++ + dlls/ntdll/ntdll.spec | 1 + + 2 files changed, 12 insertions(+) + +diff --git a/dlls/ntdll/misc.c b/dlls/ntdll/misc.c +index 4517aec..5ad121d 100644 +--- a/dlls/ntdll/misc.c ++++ b/dlls/ntdll/misc.c +@@ -444,3 +444,14 @@ ULONG WINAPI EtwRegisterTraceGuidsA( WMIDPREQUEST RequestAddress, + debugstr_a(MofResourceName), RegistrationHandle); + return ERROR_SUCCESS; + } ++ ++/********************************************************************* ++ * ApiSetQueryApiSetPresence (NTDLL.@) ++ */ ++BOOL WINAPI ApiSetQueryApiSetPresence(const UNICODE_STRING *namespace, BOOLEAN *present) ++{ ++ FIXME("(%s, %p) stub!\n", debugstr_us(namespace), present); ++ ++ *present = TRUE; ++ return TRUE; ++} +diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec +index 0c23514..7cb46d3 100644 +--- a/dlls/ntdll/ntdll.spec ++++ b/dlls/ntdll/ntdll.spec +@@ -3,6 +3,7 @@ + #if you change a Nt.. function DON'T FORGET to change the + #Zw one too. + ++@ stdcall ApiSetQueryApiSetPresence(ptr ptr) + @ stub CsrAllocateCaptureBuffer + @ stub CsrAllocateCapturePointer + @ stub CsrAllocateMessagePointer +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-ApiSetQueryApiSetPresence/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-ApiSetQueryApiSetPresence/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-ApiSetQueryApiSetPresence/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-ApiSetQueryApiSetPresence/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,2 @@ +Fixes: Add stub for ntdll.ApiSetQueryApiSetPresence +Depends: ntdll-EtwRegisterTraceGuids diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-DOS_Attributes/0004-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-DOS_Attributes/0004-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-DOS_Attributes/0004-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-DOS_Attributes/0004-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,17 +1,17 @@ -From e3b53e0794d83fc9eb39d78ca673c9144dd9873d Mon Sep 17 00:00:00 2001 +From 536b80a9145b26aa771b390ec29978dfa6f45344 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Wed, 20 Aug 2014 15:28:00 -0600 Subject: ntdll: Implement storing DOS attributes in NtCreateFile. --- - dlls/ntdll/file.c | 79 ++++++++++++++++++++++++++++---------------- - dlls/ntdll/tests/directory.c | 24 +++++--------- + dlls/ntdll/file.c | 76 ++++++++++++++++++++++++++++---------------- + dlls/ntdll/tests/directory.c | 24 ++++++-------- include/wine/port.h | 2 ++ - libs/port/xattr.c | 20 +++++++++++ - 4 files changed, 81 insertions(+), 44 deletions(-) + libs/port/xattr.c | 20 ++++++++++++ + 4 files changed, 80 insertions(+), 42 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 7e32087..dd38995 100644 +index 3146926..2a71613 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -219,6 +219,21 @@ int get_file_info( const char *path, struct stat *st, ULONG *attr ) @@ -36,29 +36,31 @@ /************************************************************************** * FILE_CreateFile (internal) * Open a file. -@@ -230,6 +245,8 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT +@@ -230,6 +245,10 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT ULONG attributes, ULONG sharing, ULONG disposition, ULONG options, PVOID ea_buffer, ULONG ea_length ) { -+ struct object_attributes objattr; -+ struct security_descriptor *sd; ++ static UNICODE_STRING empty_string; ++ OBJECT_ATTRIBUTES unix_attr; ++ data_size_t len; ++ struct object_attributes *objattr; ANSI_STRING unix_name; BOOL created = FALSE; -@@ -273,39 +290,37 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT +@@ -273,37 +292,34 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT io->u.Status = STATUS_SUCCESS; } - if (io->u.Status == STATUS_SUCCESS) + if (io->u.Status != STATUS_SUCCESS) { -- struct security_descriptor *sd; -- struct object_attributes objattr; +- static UNICODE_STRING empty_string; +- OBJECT_ATTRIBUTES unix_attr = *attr; +- data_size_t len; +- struct object_attributes *objattr; - -- objattr.rootdir = wine_server_obj_handle( attr->RootDirectory ); -- objattr.name_len = 0; -- io->u.Status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); -- if (io->u.Status != STATUS_SUCCESS) +- unix_attr.ObjectName = &empty_string; /* we send the unix name instead */ +- if ((io->u.Status = alloc_object_attributes( &unix_attr, &objattr, &len ))) - { - RtlFreeAnsiString( &unix_name ); - return io->u.Status; @@ -70,23 +72,20 @@ - SERVER_START_REQ( create_file ) - { - req->access = access; -- req->attributes = attr->Attributes; - req->sharing = sharing; - req->create = disposition; - req->options = options; - req->attrs = attributes; -- wine_server_add_data( req, &objattr, sizeof(objattr) ); -- if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); +- wine_server_add_data( req, objattr, len ); - wine_server_add_data( req, unix_name.Buffer, unix_name.Length ); - io->u.Status = wine_server_call( req ); - *handle = wine_server_ptr_handle( reply->handle ); - } - SERVER_END_REQ; -- NTDLL_free_struct_sd( sd ); -+ objattr.rootdir = wine_server_obj_handle( attr->RootDirectory ); -+ objattr.name_len = 0; -+ io->u.Status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); -+ if (io->u.Status != STATUS_SUCCESS) +- RtlFreeHeap( GetProcessHeap(), 0, objattr ); ++ unix_attr = *attr; ++ unix_attr.ObjectName = &empty_string; /* we send the unix name instead */ ++ if ((io->u.Status = alloc_object_attributes( &unix_attr, &objattr, &len ))) + { RtlFreeAnsiString( &unix_name ); + return io->u.Status; @@ -96,23 +95,21 @@ + SERVER_START_REQ( create_file ) + { + req->access = access; -+ req->attributes = attr->Attributes; + req->sharing = sharing; + req->create = disposition; + req->options = options; + req->attrs = attributes; -+ wine_server_add_data( req, &objattr, sizeof(objattr) ); -+ if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); ++ wine_server_add_data( req, objattr, len ); + wine_server_add_data( req, unix_name.Buffer, unix_name.Length ); + io->u.Status = wine_server_call( req ); + *handle = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; -+ NTDLL_free_struct_sd( sd ); ++ RtlFreeHeap( GetProcessHeap(), 0, objattr ); if (io->u.Status == STATUS_SUCCESS) { -@@ -327,6 +342,11 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT +@@ -325,6 +341,11 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT io->Information = FILE_OVERWRITTEN; break; } @@ -124,7 +121,7 @@ } else if (io->u.Status == STATUS_TOO_MANY_OPENED_FILES) { -@@ -334,6 +354,7 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT +@@ -332,6 +353,7 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT if (!once++) ERR_(winediag)( "Too many open files, ulimit -n probably needs to be increased\n" ); } @@ -223,5 +220,5 @@ +#endif +} -- -2.6.4 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-DOS_Attributes/0008-ntdll-Always-store-SAMBA_XATTR_DOS_ATTRIB-when-path-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-DOS_Attributes/0008-ntdll-Always-store-SAMBA_XATTR_DOS_ATTRIB-when-path-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-DOS_Attributes/0008-ntdll-Always-store-SAMBA_XATTR_DOS_ATTRIB-when-path-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-DOS_Attributes/0008-ntdll-Always-store-SAMBA_XATTR_DOS_ATTRIB-when-path-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,46 @@ +From 5a419298c1871c0d71a2892d6ac4b517288b3563 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 14 Jan 2016 23:09:19 +0100 +Subject: ntdll: Always store SAMBA_XATTR_DOS_ATTRIB when path could be + interpreted as hidden. + +--- + dlls/ntdll/file.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c +index 50b0042..b38698f 100644 +--- a/dlls/ntdll/file.c ++++ b/dlls/ntdll/file.c +@@ -213,12 +213,15 @@ int get_file_info( const char *path, struct stat *st, ULONG *attr ) + if (S_ISDIR( st->st_mode )) *attr |= FILE_ATTRIBUTE_REPARSE_POINT; + } + *attr |= get_file_attributes( st ); +- /* convert Unix-style hidden files to a DOS hidden file attribute */ +- if (DIR_is_hidden_file( path )) +- *attr |= FILE_ATTRIBUTE_HIDDEN; + /* retrieve any stored DOS attributes */ + len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 ); +- if (len == -1) return ret; ++ if (len == -1) ++ { ++ /* convert Unix-style hidden files to a DOS hidden file attribute */ ++ if (DIR_is_hidden_file( path )) ++ *attr |= FILE_ATTRIBUTE_HIDDEN; ++ return ret; ++ } + *attr |= get_file_xattr( hexattr, len ); + return ret; + } +@@ -231,7 +234,7 @@ NTSTATUS set_file_info( const char *path, ULONG attr ) + /* Note: unix mode already set when called this way */ + attr &= ~FILE_ATTRIBUTE_NORMAL; /* do not store everything, but keep everything Samba can use */ + len = sprintf( hexattr, "0x%x", attr ); +- if (attr != 0) ++ if (attr != 0 || DIR_is_hidden_file( path )) + xattr_set( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, len ); + else + xattr_remove( path, SAMBA_XATTR_DOS_ATTRIB ); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0001-ntdll-Move-RegisterTraceGuids-from-advapi32-to-ntdll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0001-ntdll-Move-RegisterTraceGuids-from-advapi32-to-ntdll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0001-ntdll-Move-RegisterTraceGuids-from-advapi32-to-ntdll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0001-ntdll-Move-RegisterTraceGuids-from-advapi32-to-ntdll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,200 @@ +From da0ee9b66b05e52f3494181c74042e3c40d4f3a0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 01:01:56 +0100 +Subject: ntdll: Move RegisterTraceGuids from advapi32 to ntdll. + +--- + dlls/advapi32/advapi32.spec | 4 +-- + dlls/advapi32/eventlog.c | 64 ------------------------------------------- + dlls/ntdll/misc.c | 67 +++++++++++++++++++++++++++++++++++++++++++++ + dlls/ntdll/ntdll.spec | 2 ++ + 4 files changed, 71 insertions(+), 66 deletions(-) + +diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec +index 36f176b..88f7fee 100644 +--- a/dlls/advapi32/advapi32.spec ++++ b/dlls/advapi32/advapi32.spec +@@ -661,8 +661,8 @@ + @ stdcall RegisterServiceCtrlHandlerExA(str ptr ptr) + @ stdcall RegisterServiceCtrlHandlerExW(wstr ptr ptr) + @ stdcall RegisterServiceCtrlHandlerW(wstr ptr) +-@ stdcall RegisterTraceGuidsA(ptr ptr ptr long ptr str str ptr) +-@ stdcall RegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) ++@ stdcall RegisterTraceGuidsA(ptr ptr ptr long ptr str str ptr) ntdll.EtwRegisterTraceGuidsA ++@ stdcall RegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) ntdll.EtwRegisterTraceGuidsW + # @ stub RemoveTraceCallback + # @ stub RemoveUsersFromEncryptedFile + @ stdcall ReportEventA(long long long long ptr long long ptr ptr) +diff --git a/dlls/advapi32/eventlog.c b/dlls/advapi32/eventlog.c +index 7839fc4..93c164d 100644 +--- a/dlls/advapi32/eventlog.c ++++ b/dlls/advapi32/eventlog.c +@@ -742,70 +742,6 @@ BOOL WINAPI ReportEventW( HANDLE hEventLog, WORD wType, WORD wCategory, DWORD dw + } + + /****************************************************************************** +- * RegisterTraceGuidsW [ADVAPI32.@] +- * +- * Register an event trace provider and the event trace classes that it uses +- * to generate events. +- * +- * PARAMS +- * RequestAddress [I] ControlCallback function +- * RequestContext [I] Optional provider-defined context +- * ControlGuid [I] GUID of the registering provider +- * GuidCount [I] Number of elements in the TraceGuidReg array +- * TraceGuidReg [I/O] Array of TRACE_GUID_REGISTRATION structures +- * MofImagePath [I] not supported, set to NULL +- * MofResourceName [I] not supported, set to NULL +- * RegistrationHandle [O] Provider's registration handle +- * +- * RETURNS +- * Success: ERROR_SUCCESS +- * Failure: System error code +- * +- * FIXME +- * Stub. +- */ +-ULONG WINAPI RegisterTraceGuidsW( WMIDPREQUEST RequestAddress, +- PVOID RequestContext, LPCGUID ControlGuid, ULONG GuidCount, +- PTRACE_GUID_REGISTRATION TraceGuidReg, LPCWSTR MofImagePath, +- LPCWSTR MofResourceName, PTRACEHANDLE RegistrationHandle ) +-{ +- FIXME("(%p, %p, %s, %u, %p, %s, %s, %p): stub\n", RequestAddress, RequestContext, +- debugstr_guid(ControlGuid), GuidCount, TraceGuidReg, debugstr_w(MofImagePath), +- debugstr_w(MofResourceName), RegistrationHandle); +- +- if (TraceGuidReg) +- { +- ULONG i; +- for (i = 0; i < GuidCount; i++) +- { +- FIXME(" register trace class %s\n", debugstr_guid(TraceGuidReg[i].Guid)); +- TraceGuidReg[i].RegHandle = (HANDLE)0xdeadbeef; +- } +- } +- *RegistrationHandle = (TRACEHANDLE)0xdeadbeef; +- return ERROR_SUCCESS; +-} +- +-/****************************************************************************** +- * RegisterTraceGuidsA [ADVAPI32.@] +- * +- * See RegisterTraceGuidsW. +- * +- * FIXME +- * Stub. +- */ +-ULONG WINAPI RegisterTraceGuidsA( WMIDPREQUEST RequestAddress, +- PVOID RequestContext, LPCGUID ControlGuid, ULONG GuidCount, +- PTRACE_GUID_REGISTRATION TraceGuidReg, LPCSTR MofImagePath, +- LPCSTR MofResourceName, PTRACEHANDLE RegistrationHandle ) +-{ +- FIXME("(%p, %p, %s, %u, %p, %s, %s, %p): stub\n", RequestAddress, RequestContext, +- debugstr_guid(ControlGuid), GuidCount, TraceGuidReg, debugstr_a(MofImagePath), +- debugstr_a(MofResourceName), RegistrationHandle); +- return ERROR_SUCCESS; +-} +- +-/****************************************************************************** + * StartTraceW [ADVAPI32.@] + * + * Register and start an event trace session +diff --git a/dlls/ntdll/misc.c b/dlls/ntdll/misc.c +index 2cfa900..6d49882 100644 +--- a/dlls/ntdll/misc.c ++++ b/dlls/ntdll/misc.c +@@ -27,6 +27,9 @@ + #include + #endif + ++#include "windows.h" ++#include "wmistr.h" ++#include "evntrace.h" + #include "wine/library.h" + #include "wine/debug.h" + #include "ntdll_misc.h" +@@ -335,3 +338,67 @@ BOOL WINAPI WinSqmIsOptedIn(void) + FIXME("() stub\n"); + return FALSE; + } ++ ++/********************************************************************* ++ * EtwRegisterTraceGuidsW (NTDLL.@) ++ * ++ * Register an event trace provider and the event trace classes that it uses ++ * to generate events. ++ * ++ * PARAMS ++ * RequestAddress [I] ControlCallback function ++ * RequestContext [I] Optional provider-defined context ++ * ControlGuid [I] GUID of the registering provider ++ * GuidCount [I] Number of elements in the TraceGuidReg array ++ * TraceGuidReg [I/O] Array of TRACE_GUID_REGISTRATION structures ++ * MofImagePath [I] not supported, set to NULL ++ * MofResourceName [I] not supported, set to NULL ++ * RegistrationHandle [O] Provider's registration handle ++ * ++ * RETURNS ++ * Success: ERROR_SUCCESS ++ * Failure: System error code ++ * ++ * FIXME ++ * Stub. ++ */ ++ULONG WINAPI EtwRegisterTraceGuidsW( WMIDPREQUEST RequestAddress, ++ PVOID RequestContext, LPCGUID ControlGuid, ULONG GuidCount, ++ PTRACE_GUID_REGISTRATION TraceGuidReg, LPCWSTR MofImagePath, ++ LPCWSTR MofResourceName, PTRACEHANDLE RegistrationHandle ) ++{ ++ FIXME("(%p, %p, %s, %u, %p, %s, %s, %p): stub\n", RequestAddress, RequestContext, ++ debugstr_guid(ControlGuid), GuidCount, TraceGuidReg, debugstr_w(MofImagePath), ++ debugstr_w(MofResourceName), RegistrationHandle); ++ ++ if (TraceGuidReg) ++ { ++ ULONG i; ++ for (i = 0; i < GuidCount; i++) ++ { ++ FIXME(" register trace class %s\n", debugstr_guid(TraceGuidReg[i].Guid)); ++ TraceGuidReg[i].RegHandle = (HANDLE)0xdeadbeef; ++ } ++ } ++ *RegistrationHandle = (TRACEHANDLE)0xdeadbeef; ++ return ERROR_SUCCESS; ++} ++ ++/********************************************************************* ++ * EtwRegisterTraceGuidsA (NTDLL.@) ++ * ++ * See EtwRegisterTraceGuidsW. ++ * ++ * FIXME ++ * Stub. ++ */ ++ULONG WINAPI EtwRegisterTraceGuidsA( WMIDPREQUEST RequestAddress, ++ PVOID RequestContext, LPCGUID ControlGuid, ULONG GuidCount, ++ PTRACE_GUID_REGISTRATION TraceGuidReg, LPCSTR MofImagePath, ++ LPCSTR MofResourceName, PTRACEHANDLE RegistrationHandle ) ++{ ++ FIXME("(%p, %p, %s, %u, %p, %s, %s, %p): stub\n", RequestAddress, RequestContext, ++ debugstr_guid(ControlGuid), GuidCount, TraceGuidReg, debugstr_a(MofImagePath), ++ debugstr_a(MofResourceName), RegistrationHandle); ++ return ERROR_SUCCESS; ++} +diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec +index 4e49709..2b5c6cf 100644 +--- a/dlls/ntdll/ntdll.spec ++++ b/dlls/ntdll/ntdll.spec +@@ -41,6 +41,8 @@ + # @ stub DbgUiStopDebugging + @ stub DbgUiWaitStateChange + @ stdcall DbgUserBreakPoint() ++@ stdcall EtwRegisterTraceGuidsA(ptr ptr ptr long ptr str str ptr) ++@ stdcall EtwRegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) + # @ stub KiFastSystemCall + # @ stub KiFastSystemCallRet + # @ stub KiIntSystemCall +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0002-ntdll-Move-EventRegister-from-advapi32-to-ntdll.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0002-ntdll-Move-EventRegister-from-advapi32-to-ntdll.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0002-ntdll-Move-EventRegister-from-advapi32-to-ntdll.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0002-ntdll-Move-EventRegister-from-advapi32-to-ntdll.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,92 @@ +From 68e7778fafe734c25a8bb9e4499dbd3f87106751 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 03:02:57 +0100 +Subject: ntdll: Move EventRegister from advapi32 to ntdll. + +--- + dlls/advapi32/advapi32.spec | 2 +- + dlls/advapi32/eventlog.c | 11 ----------- + dlls/ntdll/misc.c | 12 ++++++++++++ + dlls/ntdll/ntdll.spec | 1 + + 4 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec +index 88f7fee..6a015e4 100644 +--- a/dlls/advapi32/advapi32.spec ++++ b/dlls/advapi32/advapi32.spec +@@ -272,7 +272,7 @@ + @ stdcall EventActivityIdControl(long ptr) + @ stdcall EventEnabled(int64 ptr) + @ stdcall EventProviderEnabled(int64 long int64) +-@ stdcall EventRegister(ptr ptr ptr ptr) ++@ stdcall EventRegister(ptr ptr ptr ptr) ntdll.EtwEventRegister + @ stdcall EventSetInformation(int64 long ptr long) + @ stdcall EventUnregister(int64) + @ stdcall EventWrite(int64 ptr long ptr) +diff --git a/dlls/advapi32/eventlog.c b/dlls/advapi32/eventlog.c +index 93c164d..4beda0f 100644 +--- a/dlls/advapi32/eventlog.c ++++ b/dlls/advapi32/eventlog.c +@@ -815,17 +815,6 @@ ULONG WINAPI UnregisterTraceGuids( TRACEHANDLE RegistrationHandle ) + } + + /****************************************************************************** +- * EventRegister [ADVAPI32.@] +- */ +-ULONG WINAPI EventRegister( LPCGUID provider, PENABLECALLBACK callback, PVOID context, PREGHANDLE handle ) +-{ +- FIXME("%s, %p, %p, %p\n", debugstr_guid(provider), callback, context, handle); +- +- *handle = 0xdeadbeef; +- return ERROR_SUCCESS; +-} +- +-/****************************************************************************** + * EventUnregister [ADVAPI32.@] + */ + ULONG WINAPI EventUnregister( REGHANDLE handle ) +diff --git a/dlls/ntdll/misc.c b/dlls/ntdll/misc.c +index 94fa72b..599822c 100644 +--- a/dlls/ntdll/misc.c ++++ b/dlls/ntdll/misc.c +@@ -32,6 +32,7 @@ + #include "windows.h" + #include "wmistr.h" + #include "evntrace.h" ++#include "evntprov.h" + #include "wine/library.h" + #include "wine/debug.h" + #include "ntdll_misc.h" +@@ -379,6 +380,17 @@ BOOL WINAPI ApiSetQueryApiSetPresence(const UNICODE_STRING *namespace, BOOLEAN * + } + + /********************************************************************* ++ * EtwEventRegister (NTDLL.@) ++ */ ++ULONG WINAPI EtwEventRegister( LPCGUID provider, PENABLECALLBACK callback, PVOID context, PREGHANDLE handle ) ++{ ++ FIXME("%s, %p, %p, %p\n", debugstr_guid(provider), callback, context, handle); ++ ++ *handle = 0xdeadbeef; ++ return ERROR_SUCCESS; ++} ++ ++/********************************************************************* + * EtwRegisterTraceGuidsW (NTDLL.@) + * + * Register an event trace provider and the event trace classes that it uses +diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec +index bbb2595..22d80be 100644 +--- a/dlls/ntdll/ntdll.spec ++++ b/dlls/ntdll/ntdll.spec +@@ -42,6 +42,7 @@ + # @ stub DbgUiStopDebugging + @ stub DbgUiWaitStateChange + @ stdcall DbgUserBreakPoint() ++@ stdcall EtwEventRegister(ptr ptr ptr ptr) + @ stdcall EtwRegisterTraceGuidsA(ptr ptr ptr long ptr str str ptr) + @ stdcall EtwRegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) + # @ stub KiFastSystemCall +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0003-ntdll-Move-EventSetInformation-from-advapi32-to-ntdl.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0003-ntdll-Move-EventSetInformation-from-advapi32-to-ntdl.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0003-ntdll-Move-EventSetInformation-from-advapi32-to-ntdl.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/0003-ntdll-Move-EventSetInformation-from-advapi32-to-ntdl.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,82 @@ +From 26422de432cbbb693de72652cf3035395d23c1c7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 03:08:07 +0100 +Subject: ntdll: Move EventSetInformation from advapi32 to ntdll. + +--- + dlls/advapi32/advapi32.spec | 2 +- + dlls/advapi32/eventlog.c | 10 ---------- + dlls/ntdll/misc.c | 10 ++++++++++ + dlls/ntdll/ntdll.spec | 1 + + 4 files changed, 12 insertions(+), 11 deletions(-) + +diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec +index 6a015e4..e38093e 100644 +--- a/dlls/advapi32/advapi32.spec ++++ b/dlls/advapi32/advapi32.spec +@@ -273,7 +273,7 @@ + @ stdcall EventEnabled(int64 ptr) + @ stdcall EventProviderEnabled(int64 long int64) + @ stdcall EventRegister(ptr ptr ptr ptr) ntdll.EtwEventRegister +-@ stdcall EventSetInformation(int64 long ptr long) ++@ stdcall EventSetInformation(int64 long ptr long) ntdll.EtwEventSetInformation + @ stdcall EventUnregister(int64) + @ stdcall EventWrite(int64 ptr long ptr) + # @ stub EventWriteEndScenario +diff --git a/dlls/advapi32/eventlog.c b/dlls/advapi32/eventlog.c +index 4beda0f..a48e016 100644 +--- a/dlls/advapi32/eventlog.c ++++ b/dlls/advapi32/eventlog.c +@@ -864,16 +864,6 @@ ULONG WINAPI EventWrite( REGHANDLE handle, PCEVENT_DESCRIPTOR descriptor, ULONG + } + + /****************************************************************************** +- * EventSetInformation [ADVAPI32.@] +- */ +-ULONG WINAPI EventSetInformation( REGHANDLE handle, EVENT_INFO_CLASS class, PVOID info, +- ULONG length ) +-{ +- FIXME("%u, %p, %u\n", class, info, length); +- return ERROR_SUCCESS; +-} +- +-/****************************************************************************** + * QueryTraceW [ADVAPI32.@] + */ + ULONG WINAPI QueryTraceW( TRACEHANDLE handle, LPCWSTR sessionname, PEVENT_TRACE_PROPERTIES properties ) +diff --git a/dlls/ntdll/misc.c b/dlls/ntdll/misc.c +index 599822c..aa9aff3 100644 +--- a/dlls/ntdll/misc.c ++++ b/dlls/ntdll/misc.c +@@ -391,6 +391,16 @@ ULONG WINAPI EtwEventRegister( LPCGUID provider, PENABLECALLBACK callback, PVOID + } + + /********************************************************************* ++ * EtwEventSetInformation (NTDLL.@) ++ */ ++ULONG WINAPI EtwEventSetInformation( REGHANDLE handle, EVENT_INFO_CLASS class, PVOID info, ++ ULONG length ) ++{ ++ FIXME("%u, %p, %u\n", class, info, length); ++ return ERROR_SUCCESS; ++} ++ ++/********************************************************************* + * EtwRegisterTraceGuidsW (NTDLL.@) + * + * Register an event trace provider and the event trace classes that it uses +diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec +index 22d80be..c1df843 100644 +--- a/dlls/ntdll/ntdll.spec ++++ b/dlls/ntdll/ntdll.spec +@@ -43,6 +43,7 @@ + @ stub DbgUiWaitStateChange + @ stdcall DbgUserBreakPoint() + @ stdcall EtwEventRegister(ptr ptr ptr ptr) ++@ stdcall EtwEventSetInformation(int64 long ptr long) + @ stdcall EtwRegisterTraceGuidsA(ptr ptr ptr long ptr str str ptr) + @ stdcall EtwRegisterTraceGuidsW(ptr ptr ptr long ptr wstr wstr ptr) + # @ stub KiFastSystemCall +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-EtwRegisterTraceGuids/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [34318] Move implementation of EtwRegisterTraceGuidsW to ntdll diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Exception/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Exception/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Exception/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Exception/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Depends: ntdll-x86_64_set_cpu_context diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,501 +0,0 @@ -From 14cab3188b8f83081a686892d94594a30abebf14 Mon Sep 17 00:00:00 2001 -From: Mark Jansen -Date: Sun, 8 Mar 2015 18:24:45 +0100 -Subject: ntdll/tests: Tests for RtlIpv6StringToAddress (try 6) - -Changes from try5: --Reformat ipv6 table to be less wide --Remove _s6_un from memcmp calls - -Changes from try4: --Use RtlMultiByteToUnicodeN for A->W conversion as suggested by stefand on - -Changes from try3: --Also test the W version against the A version --Expand the test with more corner cases --replace the 'broken' int with an enum as suggested by stefand --add comments to the flags, explaining their purpose. --initialize ipv6 from int array in a small function to avoid code -duplication ---- - dlls/ntdll/tests/rtl.c | 430 +++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 430 insertions(+) - -diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c -index 4903790..47acfe9 100644 ---- a/dlls/ntdll/tests/rtl.c -+++ b/dlls/ntdll/tests/rtl.c -@@ -25,6 +25,7 @@ - - #include "ntdll_test.h" - #include "inaddr.h" -+#include "in6addr.h" - - #ifndef __WINE_WINTERNL_H - -@@ -89,9 +90,12 @@ static IMAGE_BASE_RELOCATION *(WINAPI *pLdrProcessRelocationBlock)(void*,UINT,US - static CHAR * (WINAPI *pRtlIpv4AddressToStringA)(const IN_ADDR *, LPSTR); - static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG); - static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *); -+static NTSTATUS (WINAPI *pRtlIpv6StringToAddressA)(PCSTR, PCSTR *, struct in6_addr *); -+static NTSTATUS (WINAPI *pRtlIpv6StringToAddressW)(PCWSTR, PCWSTR *, struct in6_addr *); - static NTSTATUS (WINAPI *pLdrAddRefDll)(ULONG, HMODULE); - static NTSTATUS (WINAPI *pLdrLockLoaderLock)(ULONG, ULONG*, ULONG_PTR*); - static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG_PTR); -+static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD); - static NTSTATUS (WINAPI *pRtlGetCompressionWorkSpaceSize)(USHORT, PULONG, PULONG); - static NTSTATUS (WINAPI *pRtlDecompressBuffer)(USHORT, PUCHAR, ULONG, const UCHAR*, ULONG, PULONG); - static NTSTATUS (WINAPI *pRtlDecompressFragment)(USHORT, PUCHAR, ULONG, const UCHAR*, ULONG, ULONG, PULONG, PVOID); -@@ -140,9 +144,12 @@ static void InitFunctionPtrs(void) - pRtlIpv4AddressToStringA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringA"); - pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA"); - pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA"); -+ pRtlIpv6StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressA"); -+ pRtlIpv6StringToAddressW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressW"); - pLdrAddRefDll = (void *)GetProcAddress(hntdll, "LdrAddRefDll"); - pLdrLockLoaderLock = (void *)GetProcAddress(hntdll, "LdrLockLoaderLock"); - pLdrUnlockLoaderLock = (void *)GetProcAddress(hntdll, "LdrUnlockLoaderLock"); -+ pRtlMultiByteToUnicodeN = (void *)GetProcAddress(hntdll, "RtlMultiByteToUnicodeN"); - pRtlGetCompressionWorkSpaceSize = (void *)GetProcAddress(hntdll, "RtlGetCompressionWorkSpaceSize"); - pRtlDecompressBuffer = (void *)GetProcAddress(hntdll, "RtlDecompressBuffer"); - pRtlDecompressFragment = (void *)GetProcAddress(hntdll, "RtlDecompressFragment"); -@@ -1500,6 +1507,428 @@ static void test_RtlIpv4StringToAddress(void) - } - } - -+ -+/* ipv6 addresses based on the set from https://github.com/beaugunderson/javascript-ipv6/tree/master/test/data */ -+static const struct -+{ -+ PCSTR address; -+ NTSTATUS res; -+ int terminator_offset; -+ int ip[8]; -+ /* win_broken: older versions of windows do not handle this correct -+ ex_fail: Ex function does need the string to be terminated, non-Ex does not. -+ ex_skip: test doesnt make sense for Ex (f.e. it's invalid for non-Ex but valid for Ex) */ -+ enum { normal_6, win_broken_6 = 1, ex_fail_6 = 2, ex_skip_6 = 4 } flags; -+} ipv6_tests[] = -+{ -+ { "0000:0000:0000:0000:0000:0000:0000:0000", STATUS_SUCCESS, 39, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "0000:0000:0000:0000:0000:0000:0000:0001", STATUS_SUCCESS, 39, -+ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "0:0:0:0:0:0:0:0", STATUS_SUCCESS, 15, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "0:0:0:0:0:0:0:1", STATUS_SUCCESS, 15, -+ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "0:0:0:0:0:0:0::", STATUS_SUCCESS, 13, -+ { 0, 0, 0, 0, 0, 0, 0, 0 }, win_broken_6 }, -+ { "0:0:0:0:0:0:13.1.68.3", STATUS_SUCCESS, 21, -+ { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, -+ { "0:0:0:0:0:0::", STATUS_SUCCESS, 13, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "0:0:0:0:0::", STATUS_SUCCESS, 11, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "0:0:0:0:0:FFFF:129.144.52.38", STATUS_SUCCESS, 28, -+ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, -+ { "0::", STATUS_SUCCESS, 3, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "0:1:2:3:4:5:6:7", STATUS_SUCCESS, 15, -+ { 0, 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700 } }, -+ { "1080:0:0:0:8:800:200c:417a", STATUS_SUCCESS, 26, -+ { 0x8010, 0, 0, 0, 0x800, 0x8, 0x0c20, 0x7a41 } }, -+ { "0:a:b:c:d:e:f::", STATUS_SUCCESS, 13, -+ { 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00, 0xf00, 0 }, win_broken_6 }, -+ { "1111:2222:3333:4444:5555:6666:123.123.123.123", STATUS_SUCCESS, 45, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111:2222:3333:4444:5555:6666:7777:8888", STATUS_SUCCESS, 39, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, -+ { "1111:2222:3333:4444:0x5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 21, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:3333:4444:x555:6666:7777:8888", STATUS_INVALID_PARAMETER, 20, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:3333:4444:0r5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 21, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:3333:4444:r5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 20, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:3333:4444:5555:6666:7777::", STATUS_SUCCESS, 34, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0 }, win_broken_6 }, -+ { "1111:2222:3333:4444:5555:6666::", STATUS_SUCCESS, 31, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0 } }, -+ { "1111:2222:3333:4444:5555:6666::8888", STATUS_SUCCESS, 35, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0x8888 } }, -+ { "1111:2222:3333:4444:5555::", STATUS_SUCCESS, 26, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0 } }, -+ { "1111:2222:3333:4444:5555::123.123.123.123", STATUS_SUCCESS, 41, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7b7b, 0x7b7b } }, -+ { "1111:2222:3333:4444:5555::0x1.123.123.123", STATUS_SUCCESS, 27, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x100 }, ex_fail_6 }, -+ { "1111:2222:3333:4444:5555::0x88", STATUS_SUCCESS, 27, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8800 }, ex_fail_6 }, -+ { "1111:2222:3333:4444:5555::0X88", STATUS_SUCCESS, 27, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8800 }, ex_fail_6 }, -+ { "1111:2222:3333:4444:5555::0X", STATUS_SUCCESS, 27, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0 }, ex_fail_6 }, -+ { "1111:2222:3333:4444:5555::0X88:7777", STATUS_SUCCESS, 27, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8800 }, ex_fail_6 }, -+ { "1111:2222:3333:4444:5555::0x8888", STATUS_SUCCESS, 27, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8888 }, ex_fail_6 }, -+ { "1111:2222:3333:4444:5555::08888", STATUS_INVALID_PARAMETER, 31, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:3333:4444:5555::fffff", STATUS_INVALID_PARAMETER, 31, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:3333:4444::fffff", STATUS_INVALID_PARAMETER, 26, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:3333::fffff", STATUS_INVALID_PARAMETER, 21, -+ { 0x1111, 0x2222, 0x3333, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:3333:4444:5555::7777:8888", STATUS_SUCCESS, 35, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7777, 0x8888 } }, -+ { "1111:2222:3333:4444:5555::8888", STATUS_SUCCESS, 30, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8888 } }, -+ { "1111::", STATUS_SUCCESS, 6, -+ { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "1111::123.123.123.123", STATUS_SUCCESS, 21, -+ { 0x1111, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } }, -+ { "1111::3333:4444:5555:6666:123.123.123.123", STATUS_SUCCESS, 41, -+ { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111::3333:4444:5555:6666:7777:8888", STATUS_SUCCESS, 35, -+ { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, -+ { "1111::4444:5555:6666:123.123.123.123", STATUS_SUCCESS, 36, -+ { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111::4444:5555:6666:7777:8888", STATUS_SUCCESS, 30, -+ { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, -+ { "1111::5555:6666:123.123.123.123", STATUS_SUCCESS, 31, -+ { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111::5555:6666:7777:8888", STATUS_SUCCESS, 25, -+ { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7777, 0x8888 } }, -+ { "1111::6666:123.123.123.123", STATUS_SUCCESS, 26, -+ { 0x1111, 0, 0, 0, 0, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111::6666:7777:8888", STATUS_SUCCESS, 20, -+ { 0x1111, 0, 0, 0, 0, 0x6666, 0x7777, 0x8888 } }, -+ { "1111::7777:8888", STATUS_SUCCESS, 15, -+ { 0x1111, 0, 0, 0, 0, 0, 0x7777, 0x8888 } }, -+ { "1111::8888", STATUS_SUCCESS, 10, -+ { 0x1111, 0, 0, 0, 0, 0, 0, 0x8888 } }, -+ { "1:2:3:4:5:6:1.2.3.4", STATUS_SUCCESS, 19, -+ { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x201, 0x403 } }, -+ { "1:2:3:4:5:6:7:8", STATUS_SUCCESS, 15, -+ { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800 } }, -+ { "1:2:3:4:5:6::", STATUS_SUCCESS, 13, -+ { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0 } }, -+ { "1:2:3:4:5:6::8", STATUS_SUCCESS, 14, -+ { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0x800 } }, -+ { "2001:0000:1234:0000:0000:C1C0:ABCD:0876", STATUS_SUCCESS, 39, -+ { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 } }, -+ { "2001:0000:4136:e378:8000:63bf:3fff:fdd2", STATUS_SUCCESS, 39, -+ { 0x120, 0, 0x3641, 0x78e3, 0x80, 0xbf63, 0xff3f, 0xd2fd } }, -+ { "2001:0db8:0:0:0:0:1428:57ab", STATUS_SUCCESS, 27, -+ { 0x120, 0xb80d, 0, 0, 0, 0, 0x2814, 0xab57 } }, -+ { "2001:0db8:1234:ffff:ffff:ffff:ffff:ffff", STATUS_SUCCESS, 39, -+ { 0x120, 0xb80d, 0x3412, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } }, -+ { "2001::CE49:7601:2CAD:DFFF:7C94:FFFE", STATUS_SUCCESS, 35, -+ { 0x120, 0, 0x49ce, 0x176, 0xad2c, 0xffdf, 0x947c, 0xfeff } }, -+ { "2001:db8:85a3::8a2e:370:7334", STATUS_SUCCESS, 28, -+ { 0x120, 0xb80d, 0xa385, 0, 0, 0x2e8a, 0x7003, 0x3473 } }, -+ { "3ffe:0b00:0000:0000:0001:0000:0000:000a", STATUS_SUCCESS, 39, -+ { 0xfe3f, 0xb, 0, 0, 0x100, 0, 0, 0xa00 } }, -+ { "::", STATUS_SUCCESS, 2, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "::%16", STATUS_SUCCESS, 2, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "::/16", STATUS_SUCCESS, 2, -+ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, -+ { "::0", STATUS_SUCCESS, 3, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "::0:0", STATUS_SUCCESS, 5, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "::0:0:0", STATUS_SUCCESS, 7, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "::0:0:0:0", STATUS_SUCCESS, 9, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "::0:0:0:0:0", STATUS_SUCCESS, 11, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "::0:0:0:0:0:0", STATUS_SUCCESS, 13, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ /* this one and the next one are incorrectly parsed by windows, -+ it adds one zero too many in front, cutting off the last digit. */ -+ { "::0:0:0:0:0:0:0", STATUS_SUCCESS, 13, -+ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, -+ { "::0:a:b:c:d:e:f", STATUS_SUCCESS, 13, -+ { 0, 0, 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00 }, ex_fail_6 }, -+ { "::123.123.123.123", STATUS_SUCCESS, 17, -+ { 0, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } }, -+ { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", STATUS_SUCCESS, 39, -+ { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } }, -+ -+ { "':10.0.0.1", STATUS_INVALID_PARAMETER, 0, -+ { -1 } }, -+ { "-1", STATUS_INVALID_PARAMETER, 0, -+ { -1 } }, -+ { "02001:0000:1234:0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, -1, -+ { -1 } }, -+ { "2001:00000:1234:0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, -1, -+ { 0x120, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "2001:0000:01234:0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, -1, -+ { 0x120, 0, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1.2.3.4", STATUS_INVALID_PARAMETER, 7, -+ { 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1.2.3.4:1111::5555", STATUS_INVALID_PARAMETER, 7, -+ { 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1.2.3.4::5555", STATUS_INVALID_PARAMETER, 7, -+ { 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "11112222:3333:4444:5555:6666:1.2.3.4", STATUS_INVALID_PARAMETER, -1, -+ { -1 } }, -+ { "11112222:3333:4444:5555:6666:7777:8888", STATUS_INVALID_PARAMETER, -1, -+ { -1 } }, -+ { "1111", STATUS_INVALID_PARAMETER, 4, -+ { -1 } }, -+ { "1111:22223333:4444:5555:6666:1.2.3.4", STATUS_INVALID_PARAMETER, -1, -+ { 0x1111, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111:22223333:4444:5555:6666:7777:8888", STATUS_INVALID_PARAMETER, -1, -+ { 0x1111, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:", STATUS_INVALID_PARAMETER, 10, -+ { 0x1111, 0x2222, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:1.2.3.4", STATUS_INVALID_PARAMETER, 17, -+ { 0x1111, 0x2222, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:3333", STATUS_INVALID_PARAMETER, 14, -+ { 0x1111, 0x2222, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111:2222:3333:4444:5555:6666:7777:1.2.3.4", STATUS_SUCCESS, 36, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x100 }, ex_fail_6 }, -+ { "1111:2222:3333:4444:5555:6666:7777:8888:", STATUS_SUCCESS, 39, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, ex_fail_6 }, -+ { "1111:2222:3333:4444:5555:6666:7777:8888:1.2.3.4",STATUS_SUCCESS, 39, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, ex_fail_6 }, -+ { "1111:2222:3333:4444:5555:6666:7777:8888:9999", STATUS_SUCCESS, 39, -+ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, ex_fail_6 }, -+ { "1111:2222:::", STATUS_SUCCESS, 11, -+ { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, -+ { "1111::5555:", STATUS_INVALID_PARAMETER, 11, -+ { 0x1111, 0x5555, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1111::3333:4444:5555:6666:7777::", STATUS_SUCCESS, 30, -+ { 0x1111, 0, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777 }, ex_fail_6 }, -+ { "1111:2222:::4444:5555:6666:1.2.3.4", STATUS_SUCCESS, 11, -+ { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, -+ { "1111::3333::5555:6666:1.2.3.4", STATUS_SUCCESS, 10, -+ { 0x1111, 0, 0, 0, 0, 0, 0, 0x3333 }, ex_fail_6 }, -+ { "12345::6:7:8", STATUS_INVALID_PARAMETER, -1, -+ { -1 } }, -+ { "1::1.2.256.4", STATUS_INVALID_PARAMETER, -1, -+ { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::1.2.3.256", STATUS_INVALID_PARAMETER, 12, -+ { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::1.2.3.300", STATUS_INVALID_PARAMETER, 12, -+ { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::1.2::1", STATUS_INVALID_PARAMETER, 6, -+ { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::1.2.3.4::1", STATUS_SUCCESS, 10, -+ { 0x100, 0, 0, 0, 0, 0, 0x201, 0x403 }, ex_fail_6 }, -+ { "1::1.", STATUS_INVALID_PARAMETER, 5, -+ { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::1.2", STATUS_INVALID_PARAMETER, 6, -+ { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::1.2.", STATUS_INVALID_PARAMETER, 7, -+ { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::1.2.3", STATUS_INVALID_PARAMETER, 8, -+ { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::1.2.3.", STATUS_INVALID_PARAMETER, 9, -+ { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::1.2.3.4", STATUS_SUCCESS, 10, -+ { 0x100, 0, 0, 0, 0, 0, 0x201, 0x403 } }, -+ { "1::1.2.3.900", STATUS_INVALID_PARAMETER, 12, -+ { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::1.2.300.4", STATUS_INVALID_PARAMETER, -1, -+ { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::1.256.3.4", STATUS_INVALID_PARAMETER, -1, -+ { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::256.2.3.4", STATUS_INVALID_PARAMETER, -1, -+ { 0x100, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "1::2::3", STATUS_SUCCESS, 4, -+ { 0x100, 0, 0, 0, 0, 0, 0, 0x200 }, ex_fail_6 }, -+ { "2001:0000:1234: 0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, 15, -+ { 0x120, 0, 0x3412, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, -+ { "2001:0000:1234:0000:0000:C1C0:ABCD:0876 0", STATUS_SUCCESS, 39, -+ { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 }, ex_fail_6 }, -+ { "2001:1:1:1:1:1:255Z255X255Y255", STATUS_INVALID_PARAMETER, 18, -+ { 0x120, 0x100, 0x100, 0x100, 0x100, 0x100, 0xabab, 0xabab } }, -+ { "2001::FFD3::57ab", STATUS_SUCCESS, 10, -+ { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff }, ex_fail_6 }, -+ { ":", STATUS_INVALID_PARAMETER, 0, -+ { -1 } }, -+ { ":1111:2222:3333:4444:5555:6666:1.2.3.4", STATUS_INVALID_PARAMETER, 0, -+ { -1 } }, -+ { ":1111:2222:3333:4444:5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 0, -+ { -1 } }, -+ { ":1111::", STATUS_INVALID_PARAMETER, 0, -+ { -1 } }, -+ { "::-1", STATUS_SUCCESS, 2, -+ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, -+ { "::.", STATUS_SUCCESS, 2, -+ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, -+ { "::..", STATUS_SUCCESS, 2, -+ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, -+ { "::...", STATUS_SUCCESS, 2, -+ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, -+ { "XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:1.2.3.4", STATUS_INVALID_PARAMETER, 0, -+ { -1 } }, -+ { "[::]", STATUS_INVALID_PARAMETER, 0, -+ { -1 }, ex_skip_6 }, -+}; -+const unsigned int ipv6_testcount = sizeof(ipv6_tests) / sizeof(ipv6_tests[0]); -+ -+ -+static void init_ip6(IN6_ADDR* addr, const int src[8]) -+{ -+ unsigned int j; -+ if (!src || src[0] == -1) -+ { -+ for (j = 0; j < 8; ++j) -+ addr->s6_words[j] = 0xabab; -+ } -+ else -+ { -+ for (j = 0; j < 8; ++j) -+ addr->s6_words[j] = src[j]; -+ } -+} -+ -+static void compare_RtlIpv6StringToAddressW(PCSTR name_a, int terminator_offset_a, -+ const struct in6_addr *addr_a, NTSTATUS res_a) -+{ -+ WCHAR name[512]; -+ NTSTATUS res; -+ IN6_ADDR ip; -+ PCWSTR terminator; -+ -+ if (!pRtlIpv6StringToAddressW) -+ return; -+ -+ pRtlMultiByteToUnicodeN(name, sizeof(name), NULL, name_a, strlen(name_a) + 1); -+ -+ init_ip6(&ip, NULL); -+ terminator = (void *)0xdeadbeef; -+ res = pRtlIpv6StringToAddressW(name, &terminator, &ip); -+ ok(res == res_a, "[W:%s] res = 0x%08x, expected 0x%08x\n", name_a, res, res_a); -+ -+ if (terminator_offset_a < 0) -+ { -+ ok(terminator == (void *)0xdeadbeef, -+ "[W:%s] terminator = %p, expected it not to change\n", -+ name_a, terminator); -+ } -+ else -+ { -+ ok(terminator == name + terminator_offset_a, -+ "[W:%s] terminator = %p, expected %p\n", -+ name_a, terminator, name + terminator_offset_a); -+ } -+ -+ ok(!memcmp(&ip, addr_a, sizeof(ip)), -+ "[W:%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n", -+ name_a, -+ ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3], -+ ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7], -+ addr_a->s6_words[0], addr_a->s6_words[1], addr_a->s6_words[2], addr_a->s6_words[3], -+ addr_a->s6_words[4], addr_a->s6_words[5], addr_a->s6_words[6], addr_a->s6_words[7]); -+} -+ -+static void test_RtlIpv6StringToAddress(void) -+{ -+ NTSTATUS res; -+ IN6_ADDR ip, expected_ip; -+ PCSTR terminator; -+ unsigned int i; -+ -+ if (!pRtlIpv6StringToAddressW) -+ { -+ skip("RtlIpv6StringToAddressW not available\n"); -+ /* we can continue, just not test W */ -+ } -+ -+ if (!pRtlIpv6StringToAddressA) -+ { -+ skip("RtlIpv6StringToAddressA not available\n"); -+ return; /* all tests are centered around A, we cannot continue */ -+ } -+ -+ res = pRtlIpv6StringToAddressA("::", &terminator, &ip); -+ ok(res == STATUS_SUCCESS, "[validate] res = 0x%08x, expected STATUS_SUCCESS\n", res); -+ if (0) -+ { -+ /* any of these crash */ -+ res = pRtlIpv6StringToAddressA(NULL, &terminator, &ip); -+ ok(res == STATUS_INVALID_PARAMETER, "[null string] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); -+ res = pRtlIpv6StringToAddressA("::", NULL, &ip); -+ ok(res == STATUS_INVALID_PARAMETER, "[null terminator] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); -+ res = pRtlIpv6StringToAddressA("::", &terminator, NULL); -+ ok(res == STATUS_INVALID_PARAMETER, "[null result] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); -+ } -+ -+ /* sanity check */ -+ ok(sizeof(ip) == sizeof(USHORT)* 8, "sizeof(ip)\n"); -+ -+ for (i = 0; i < ipv6_testcount; i++) -+ { -+ init_ip6(&ip, NULL); -+ terminator = (void *)0xdeadbeef; -+ res = pRtlIpv6StringToAddressA(ipv6_tests[i].address, &terminator, &ip); -+ compare_RtlIpv6StringToAddressW(ipv6_tests[i].address, (terminator != (void *)0xdeadbeef) ? -+ (terminator - ipv6_tests[i].address) : -1, &ip, res); -+ -+ if (ipv6_tests[i].flags & win_broken_6) -+ { -+ ok(res == ipv6_tests[i].res || broken(res == STATUS_INVALID_PARAMETER), -+ "[%s] res = 0x%08x, expected 0x%08x\n", -+ ipv6_tests[i].address, res, ipv6_tests[i].res); -+ -+ if (res == STATUS_INVALID_PARAMETER) -+ continue; -+ } -+ else -+ { -+ ok(res == ipv6_tests[i].res, -+ "[%s] res = 0x%08x, expected 0x%08x\n", -+ ipv6_tests[i].address, res, ipv6_tests[i].res); -+ } -+ -+ if (ipv6_tests[i].terminator_offset < 0) -+ { -+ ok(terminator == (void *)0xdeadbeef, -+ "[%s] terminator = %p, expected it not to change\n", -+ ipv6_tests[i].address, terminator); -+ } -+ else if (ipv6_tests[i].flags & win_broken_6) -+ { -+ PCSTR expected = ipv6_tests[i].address + ipv6_tests[i].terminator_offset; -+ ok(terminator == expected || broken(terminator == expected + 2), -+ "[%s] terminator = %p, expected %p\n", -+ ipv6_tests[i].address, terminator, expected); -+ } -+ else -+ { -+ ok(terminator == ipv6_tests[i].address + ipv6_tests[i].terminator_offset, -+ "[%s] terminator = %p, expected %p\n", -+ ipv6_tests[i].address, terminator, ipv6_tests[i].address + ipv6_tests[i].terminator_offset); -+ } -+ -+ init_ip6(&expected_ip, ipv6_tests[i].ip); -+ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), -+ "[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n", -+ ipv6_tests[i].address, -+ ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3], -+ ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7], -+ expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3], -+ expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]); -+ } -+} -+ - static void test_LdrAddRefDll(void) - { - HMODULE mod, mod2; -@@ -2186,6 +2615,7 @@ START_TEST(rtl) - test_RtlIpv4AddressToString(); - test_RtlIpv4AddressToStringEx(); - test_RtlIpv4StringToAddress(); -+ test_RtlIpv6StringToAddress(); - test_LdrAddRefDll(); - test_LdrLockLoaderLock(); - test_RtlCompressBuffer(); --- -2.4.5 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,333 +0,0 @@ -From 7b6d523f37901554bfdb17e301dd25e50a899e22 Mon Sep 17 00:00:00 2001 -From: Mark Jansen -Date: Sun, 8 Mar 2015 18:24:50 +0100 -Subject: ntdll/tests: Tests for RtlIpv6StringToAddressEx (try 6) - -Changes from try5: --Reformat ipv6 table to be less wide --Remove _s6_un from memcmp calls - -Changes from try4 (all suggestions from stefand in #winehackers): --Use RtlMultiByteToUnicodeN for A->W conversion --Fix warning --Clarify comment / move init_ip6 inside if branch - -Changes from try3: --Also test the W version against the A version --Test the ip against the non-ex version as suggested by stefand --Add more testcases ---- - dlls/ntdll/tests/rtl.c | 269 ++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 268 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c -index 47acfe9..f5bbbb3 100644 ---- a/dlls/ntdll/tests/rtl.c -+++ b/dlls/ntdll/tests/rtl.c -@@ -92,6 +92,8 @@ static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, L - static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *); - static NTSTATUS (WINAPI *pRtlIpv6StringToAddressA)(PCSTR, PCSTR *, struct in6_addr *); - static NTSTATUS (WINAPI *pRtlIpv6StringToAddressW)(PCWSTR, PCWSTR *, struct in6_addr *); -+static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExA)(PCSTR, struct in6_addr *, PULONG, PUSHORT); -+static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExW)(PCWSTR, struct in6_addr *, PULONG, PUSHORT); - static NTSTATUS (WINAPI *pLdrAddRefDll)(ULONG, HMODULE); - static NTSTATUS (WINAPI *pLdrLockLoaderLock)(ULONG, ULONG*, ULONG_PTR*); - static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG_PTR); -@@ -146,6 +148,8 @@ static void InitFunctionPtrs(void) - pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA"); - pRtlIpv6StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressA"); - pRtlIpv6StringToAddressW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressW"); -+ pRtlIpv6StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExA"); -+ pRtlIpv6StringToAddressExW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExW"); - pLdrAddRefDll = (void *)GetProcAddress(hntdll, "LdrAddRefDll"); - pLdrLockLoaderLock = (void *)GetProcAddress(hntdll, "LdrLockLoaderLock"); - pLdrUnlockLoaderLock = (void *)GetProcAddress(hntdll, "LdrUnlockLoaderLock"); -@@ -1783,7 +1787,6 @@ static const struct - }; - const unsigned int ipv6_testcount = sizeof(ipv6_tests) / sizeof(ipv6_tests[0]); - -- - static void init_ip6(IN6_ADDR* addr, const int src[8]) - { - unsigned int j; -@@ -1929,6 +1932,269 @@ static void test_RtlIpv6StringToAddress(void) - } - } - -+static void compare_RtlIpv6StringToAddressExW(PCSTR name_a, const struct in6_addr *addr_a, HRESULT res_a, ULONG scope_a, USHORT port_a) -+{ -+ WCHAR name[512]; -+ NTSTATUS res; -+ IN6_ADDR ip; -+ ULONG scope = 0xbadf00d; -+ USHORT port = 0xbeef; -+ -+ if (!pRtlIpv6StringToAddressExW) -+ return; -+ -+ pRtlMultiByteToUnicodeN(name, sizeof(name), NULL, name_a, strlen(name_a) + 1); -+ -+ init_ip6(&ip, NULL); -+ res = pRtlIpv6StringToAddressExW(name, &ip, &scope, &port); -+ -+ ok(res == res_a, "[W:%s] res = 0x%08x, expected 0x%08x\n", name_a, res, res_a); -+ ok(scope == scope_a, "[W:%s] scope = 0x%08x, expected 0x%08x\n", name_a, scope, scope_a); -+ ok(port == port_a, "[W:%s] port = 0x%08x, expected 0x%08x\n", name_a, port, port_a); -+ -+ ok(!memcmp(&ip, addr_a, sizeof(ip)), -+ "[W:%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n", -+ name_a, -+ ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3], -+ ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7], -+ addr_a->s6_words[0], addr_a->s6_words[1], addr_a->s6_words[2], addr_a->s6_words[3], -+ addr_a->s6_words[4], addr_a->s6_words[5], addr_a->s6_words[6], addr_a->s6_words[7]); -+} -+ -+static void test_RtlIpv6StringToAddressEx(void) -+{ -+ NTSTATUS res; -+ IN6_ADDR ip, expected_ip; -+ ULONG scope; -+ USHORT port; -+ static const struct -+ { -+ PCSTR address; -+ NTSTATUS res; -+ ULONG scope; -+ USHORT port; -+ int ip[8]; -+ } ipv6_ex_tests[] = -+ { -+ { "[::]", STATUS_SUCCESS, 0, 0, -+ { 0, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "[::1]:8080", STATUS_SUCCESS, 0, 0x901f, -+ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "[::1]:0x80", STATUS_SUCCESS, 0, 0x8000, -+ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "[::1]:0X80", STATUS_SUCCESS, 0, 0x8000, -+ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "[::1]:080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "[::1]:800000000080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80", STATUS_SUCCESS, 0, 0x5000, -+ { 0xdcfe, 0x98ba, 0x5476, 0x1032, 0xdcfe, 0x98ba, 0x5476, 0x1032 } }, -+ { "[1080:0:0:0:8:800:200C:417A]:1234", STATUS_SUCCESS, 0, 0xd204, -+ { 0x8010, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[3ffe:2a00:100:7031::1]:8080", STATUS_SUCCESS, 0, 0x901f, -+ { 0xfe3f, 0x2a, 1, 0x3170, 0, 0, 0, 0x100 } }, -+ { "[ 3ffe:2a00:100:7031::1]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { -1 } }, -+ { "[3ffe:2a00:100:7031::1 ]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0xfe3f, 0x2a, 1, 0x3170, 0, 0, 0, 0x100 } }, -+ { "[3ffe:2a00:100:7031::1].8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0xfe3f, 0x2a, 1, 0x3170, 0, 0, 0, 0x100 } }, -+ { "[1080::8:800:200C:417A]:8080", STATUS_SUCCESS, 0, 0x901f, -+ { 0x8010, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[1080::8:800:200C:417A]!8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0x8010, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[::FFFF:129.144.52.38]:80", STATUS_SUCCESS, 0, 0x5000, -+ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, -+ { "[::FFFF:129.144.52.38]:-80", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, -+ { "[::FFFF:129.144.52.38]:999999999999", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, -+ { "[::FFFF:129.144.52.38%-8]:80", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, -+ { "[::FFFF:129.144.52.38]:80", STATUS_SUCCESS, 0, 0x5000, -+ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, -+ { "[12345::6:7:8]:80", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { -1 } }, -+ { "[ff01::8:800:200C:417A%16]:8080", STATUS_SUCCESS, 16, 0x901f, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[ff01::8:800:200C:417A%100]:8080", STATUS_SUCCESS, 100, 0x901f, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[ff01::8:800:200C:417A%1000]:8080", STATUS_SUCCESS, 1000, 0x901f, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[ff01::8:800:200C:417A%10000]:8080", STATUS_SUCCESS, 10000, 0x901f, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[ff01::8:800:200C:417A%1000000]:8080", STATUS_SUCCESS, 1000000, 0x901f, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[ff01::8:800:200C:417A%4294967295]:8080", STATUS_SUCCESS, 0xffffffff, 0x901f, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[ff01::8:800:200C:417A%4294967296]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[ff01::8:800:200C:417A%-1]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[ff01::8:800:200C:417A%0]:8080", STATUS_SUCCESS, 0, 0x901f, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[ff01::8:800:200C:417A%1", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[ff01::8:800:200C:417A%0x1000]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ { "[ff01::8:800:200C:417A/16]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, -+ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, -+ }; -+ const unsigned int ipv6_ex_testcount = sizeof(ipv6_ex_tests) / sizeof(ipv6_ex_tests[0]); -+ const char *simple_ip = "::"; -+ unsigned int i; -+ -+ if (!pRtlIpv6StringToAddressExW) -+ { -+ skip("RtlIpv6StringToAddressExW not available\n"); -+ /* we can continue, just not test W */ -+ } -+ -+ if (!pRtlIpv6StringToAddressExA) -+ { -+ skip("RtlIpv6StringToAddressExA not available\n"); -+ return; -+ } -+ -+ res = pRtlIpv6StringToAddressExA(simple_ip, &ip, &scope, &port); -+ ok(res == STATUS_SUCCESS, "[validate] res = 0x%08x, expected STATUS_SUCCESS\n", res); -+ -+ init_ip6(&ip, NULL); -+ init_ip6(&expected_ip, NULL); -+ scope = 0xbadf00d; -+ port = 0xbeef; -+ res = pRtlIpv6StringToAddressExA(NULL, &ip, &scope, &port); -+ ok(res == STATUS_INVALID_PARAMETER, -+ "[null string] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); -+ ok(scope == 0xbadf00d, "[null string] scope = 0x%08x, expected 0xbadf00d\n", scope); -+ ok(port == 0xbeef, "[null string] port = 0x%08x, expected 0xbeef\n", port); -+ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), -+ "[null string] ip is changed, expected it not to change\n"); -+ -+ -+ init_ip6(&ip, NULL); -+ scope = 0xbadf00d; -+ port = 0xbeef; -+ res = pRtlIpv6StringToAddressExA(simple_ip, NULL, &scope, &port); -+ ok(res == STATUS_INVALID_PARAMETER, -+ "[null result] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); -+ ok(scope == 0xbadf00d, "[null result] scope = 0x%08x, expected 0xbadf00d\n", scope); -+ ok(port == 0xbeef, "[null result] port = 0x%08x, expected 0xbeef\n", port); -+ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), -+ "[null result] ip is changed, expected it not to change\n"); -+ -+ init_ip6(&ip, NULL); -+ scope = 0xbadf00d; -+ port = 0xbeef; -+ res = pRtlIpv6StringToAddressExA(simple_ip, &ip, NULL, &port); -+ ok(res == STATUS_INVALID_PARAMETER, -+ "[null scope] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); -+ ok(scope == 0xbadf00d, "[null scope] scope = 0x%08x, expected 0xbadf00d\n", scope); -+ ok(port == 0xbeef, "[null scope] port = 0x%08x, expected 0xbeef\n", port); -+ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), -+ "[null scope] ip is changed, expected it not to change\n"); -+ -+ init_ip6(&ip, NULL); -+ scope = 0xbadf00d; -+ port = 0xbeef; -+ res = pRtlIpv6StringToAddressExA(simple_ip, &ip, &scope, NULL); -+ ok(res == STATUS_INVALID_PARAMETER, -+ "[null port] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); -+ ok(scope == 0xbadf00d, "[null port] scope = 0x%08x, expected 0xbadf00d\n", scope); -+ ok(port == 0xbeef, "[null port] port = 0x%08x, expected 0xbeef\n", port); -+ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), -+ "[null port] ip is changed, expected it not to change\n"); -+ -+ /* sanity check */ -+ ok(sizeof(ip) == sizeof(USHORT)* 8, "sizeof(ip)\n"); -+ -+ /* first we run all ip related tests, to make sure someone didnt accidentally reimplement instead of re-use. */ -+ for (i = 0; i < ipv6_testcount; i++) -+ { -+ ULONG scope = 0xbadf00d; -+ USHORT port = 0xbeef; -+ NTSTATUS expect_ret = (ipv6_tests[i].flags & ex_fail_6) ? STATUS_INVALID_PARAMETER : ipv6_tests[i].res; -+ -+ if (ipv6_tests[i].flags & ex_skip_6) -+ continue; -+ -+ init_ip6(&ip, NULL); -+ res = pRtlIpv6StringToAddressExA(ipv6_tests[i].address, &ip, &scope, &port); -+ compare_RtlIpv6StringToAddressExW(ipv6_tests[i].address, &ip, res, scope, port); -+ -+ /* make sure nothing was changed if this function fails. */ -+ if (res == STATUS_INVALID_PARAMETER) -+ { -+ ok(scope == 0xbadf00d, "[%s] scope = 0x%08x, expected 0xbadf00d\n", -+ ipv6_tests[i].address, scope); -+ ok(port == 0xbeef, "[%s] port = 0x%08x, expected 0xbeef\n", -+ ipv6_tests[i].address, port); -+ } -+ else -+ { -+ ok(scope != 0xbadf00d, "[%s] scope = 0x%08x, not expected 0xbadf00d\n", -+ ipv6_tests[i].address, scope); -+ ok(port != 0xbeef, "[%s] port = 0x%08x, not expected 0xbeef\n", -+ ipv6_tests[i].address, port); -+ } -+ -+ if (ipv6_tests[i].flags & win_broken_6) -+ { -+ ok(res == expect_ret || broken(res == STATUS_INVALID_PARAMETER), -+ "[%s] res = 0x%08x, expected 0x%08x\n", ipv6_tests[i].address, res, expect_ret); -+ -+ if (res == STATUS_INVALID_PARAMETER) -+ continue; -+ } -+ else -+ { -+ ok(res == expect_ret, "[%s] res = 0x%08x, expected 0x%08x\n", -+ ipv6_tests[i].address, res, expect_ret); -+ } -+ -+ /* If ex fails but non-ex does not we cannot check if the part that is converted -+ before it failed was correct, since there is no data for it in the table. */ -+ if (res == expect_ret) -+ { -+ init_ip6(&expected_ip, ipv6_tests[i].ip); -+ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), -+ "[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n", -+ ipv6_tests[i].address, -+ ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3], -+ ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7], -+ expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3], -+ expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]); -+ } -+ } -+ -+ /* now we run scope / port related tests */ -+ for (i = 0; i < ipv6_ex_testcount; i++) -+ { -+ scope = 0xbadf00d; -+ port = 0xbeef; -+ init_ip6(&ip, NULL); -+ res = pRtlIpv6StringToAddressExA(ipv6_ex_tests[i].address, &ip, &scope, &port); -+ compare_RtlIpv6StringToAddressExW(ipv6_ex_tests[i].address, &ip, res, scope, port); -+ -+ ok(res == ipv6_ex_tests[i].res, "[%s] res = 0x%08x, expected 0x%08x\n", -+ ipv6_ex_tests[i].address, res, ipv6_ex_tests[i].res); -+ ok(scope == ipv6_ex_tests[i].scope, "[%s] scope = 0x%08x, expected 0x%08x\n", -+ ipv6_ex_tests[i].address, scope, ipv6_ex_tests[i].scope); -+ ok(port == ipv6_ex_tests[i].port, "[%s] port = 0x%08x, expected 0x%08x\n", -+ ipv6_ex_tests[i].address, port, ipv6_ex_tests[i].port); -+ -+ init_ip6(&expected_ip, ipv6_ex_tests[i].ip); -+ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), -+ "[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n", -+ ipv6_ex_tests[i].address, -+ ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3], -+ ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7], -+ expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3], -+ expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]); -+ } -+} -+ - static void test_LdrAddRefDll(void) - { - HMODULE mod, mod2; -@@ -2616,6 +2882,7 @@ START_TEST(rtl) - test_RtlIpv4AddressToStringEx(); - test_RtlIpv4StringToAddress(); - test_RtlIpv6StringToAddress(); -+ test_RtlIpv6StringToAddressEx(); - test_LdrAddRefDll(); - test_LdrLockLoaderLock(); - test_RtlCompressBuffer(); --- -2.4.5 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0003-ntdll-tests-Tests-for-RtlIpv4StringToAddressEx-try-5.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0003-ntdll-tests-Tests-for-RtlIpv4StringToAddressEx-try-5.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0003-ntdll-tests-Tests-for-RtlIpv4StringToAddressEx-try-5.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0003-ntdll-tests-Tests-for-RtlIpv4StringToAddressEx-try-5.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,456 +0,0 @@ -From a2f2703bd49023e395090c6ed8b7b6d2e7722680 Mon Sep 17 00:00:00 2001 -From: Mark Jansen -Date: Sun, 8 Mar 2015 18:24:48 +0100 -Subject: ntdll/tests: Tests for RtlIpv4StringToAddressEx (try 5, resend) - -Changes from try4: --Remove leftover comments - -Changes from try3: --Test the ip against the non-ex version as suggested by stefand --Change strict_is_different to a flag --Add ipv4 init function to avoid code duplication ---- - dlls/ntdll/tests/rtl.c | 371 ++++++++++++++++++++++++++++++++----------------- - 1 file changed, 247 insertions(+), 124 deletions(-) - -diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c -index 5d789d1..79c4974 100644 ---- a/dlls/ntdll/tests/rtl.c -+++ b/dlls/ntdll/tests/rtl.c -@@ -90,6 +90,7 @@ static IMAGE_BASE_RELOCATION *(WINAPI *pLdrProcessRelocationBlock)(void*,UINT,US - static CHAR * (WINAPI *pRtlIpv4AddressToStringA)(const IN_ADDR *, LPSTR); - static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG); - static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *); -+static NTSTATUS (WINAPI *pRtlIpv4StringToAddressExA)(PCSTR, BOOLEAN, IN_ADDR *, PUSHORT); - static NTSTATUS (WINAPI *pRtlIpv6StringToAddressA)(PCSTR, PCSTR *, struct in6_addr *); - static NTSTATUS (WINAPI *pRtlIpv6StringToAddressW)(PCWSTR, PCWSTR *, struct in6_addr *); - static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExA)(PCSTR, struct in6_addr *, PULONG, PUSHORT); -@@ -142,6 +143,7 @@ static void InitFunctionPtrs(void) - pRtlIpv4AddressToStringA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringA"); - pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA"); - pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA"); -+ pRtlIpv4StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressExA"); - pRtlIpv6StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressA"); - pRtlIpv6StringToAddressW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressW"); - pRtlIpv6StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExA"); -@@ -1331,98 +1333,109 @@ static void test_RtlIpv4AddressToStringEx(void) - res, size, buffer); - } - -+static struct -+{ -+ PCSTR address; -+ NTSTATUS res; -+ int terminator_offset; -+ int ip[4]; -+ enum { normal_4, strict_diff_4 = 1, ex_fail_4 = 2 } flags; -+ NTSTATUS res_strict; -+ int terminator_offset_strict; -+ int ip_strict[4]; -+} ipv4_tests[] = -+{ -+ { "", STATUS_INVALID_PARAMETER, 0, { -1 } }, -+ { " ", STATUS_INVALID_PARAMETER, 0, { -1 } }, -+ { "1.1.1.1", STATUS_SUCCESS, 7, { 1, 1, 1, 1 } }, -+ { "0.0.0.0", STATUS_SUCCESS, 7, { 0, 0, 0, 0 } }, -+ { "255.255.255.255", STATUS_SUCCESS, 15, { 255, 255, 255, 255 } }, -+ { "255.255.255.255:123", STATUS_SUCCESS, 15, { 255, 255, 255, 255 } }, -+ { "255.255.255.256", STATUS_INVALID_PARAMETER, 15, { -1 } }, -+ { "255.255.255.4294967295", STATUS_INVALID_PARAMETER, 22, { -1 } }, -+ { "255.255.255.4294967296", STATUS_INVALID_PARAMETER, 21, { -1 } }, -+ { "255.255.255.4294967297", STATUS_INVALID_PARAMETER, 21, { -1 } }, -+ { "a", STATUS_INVALID_PARAMETER, 0, { -1 } }, -+ { "1.1.1.0xaA", STATUS_SUCCESS, 10, { 1, 1, 1, 170 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 8, { -1 } }, -+ { "1.1.1.0XaA", STATUS_SUCCESS, 10, { 1, 1, 1, 170 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 8, { -1 } }, -+ { "1.1.1.0x", STATUS_INVALID_PARAMETER, 8, { -1 } }, -+ { "1.1.1.0xff", STATUS_SUCCESS, 10, { 1, 1, 1, 255 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 8, { -1 } }, -+ { "1.1.1.0x100", STATUS_INVALID_PARAMETER, 11, { -1 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 8, { -1 } }, -+ { "1.1.1.0xffffffff", STATUS_INVALID_PARAMETER, 16, { -1 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 8, { -1 } }, -+ { "1.1.1.0x100000000", STATUS_INVALID_PARAMETER, 16, { -1, 0, 0, 0 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 8, { -1 } }, -+ { "1.1.1.010", STATUS_SUCCESS, 9, { 1, 1, 1, 8 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 7, { -1 } }, -+ { "1.1.1.00", STATUS_SUCCESS, 8, { 1, 1, 1, 0 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 7, { -1 } }, -+ { "1.1.1.007", STATUS_SUCCESS, 9, { 1, 1, 1, 7 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 7, { -1 } }, -+ { "1.1.1.08", STATUS_INVALID_PARAMETER, 7, { -1 } }, -+ { "1.1.1.008", STATUS_SUCCESS, 8, { 1, 1, 1, 0 }, strict_diff_4 | ex_fail_4, -+ STATUS_INVALID_PARAMETER, 7, { -1 } }, -+ { "1.1.1.0a", STATUS_SUCCESS, 7, { 1, 1, 1, 0 }, ex_fail_4 }, -+ { "1.1.1.0o10", STATUS_SUCCESS, 7, { 1, 1, 1, 0 }, ex_fail_4 }, -+ { "1.1.1.0b10", STATUS_SUCCESS, 7, { 1, 1, 1, 0 }, ex_fail_4 }, -+ { "1.1.1.-2", STATUS_INVALID_PARAMETER, 6, { -1 } }, -+ { "1", STATUS_SUCCESS, 1, { 0, 0, 0, 1 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 1, { -1 } }, -+ { "-1", STATUS_INVALID_PARAMETER, 0, { -1 } }, -+ { "203569230", STATUS_SUCCESS, 9, { 12, 34, 56, 78 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 9, { -1 } }, -+ { "1.223756", STATUS_SUCCESS, 8, { 1, 3, 106, 12 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 8, { -1 } }, -+ { "3.4.756", STATUS_SUCCESS, 7, { 3, 4, 2, 244 }, strict_diff_4, -+ STATUS_INVALID_PARAMETER, 7, { -1 } }, -+ { "3.4.756.1", STATUS_INVALID_PARAMETER, 9, { -1 } }, -+ { "3.4.65536", STATUS_INVALID_PARAMETER, 9, { -1 } }, -+ { "3.4.5.6.7", STATUS_INVALID_PARAMETER, 7, { -1 } }, -+ { "3.4.5.+6", STATUS_INVALID_PARAMETER, 6, { -1 } }, -+ { " 3.4.5.6", STATUS_INVALID_PARAMETER, 0, { -1 } }, -+ { "\t3.4.5.6", STATUS_INVALID_PARAMETER, 0, { -1 } }, -+ { "3.4.5.6 ", STATUS_SUCCESS, 7, { 3, 4, 5, 6 }, ex_fail_4 }, -+ { "3. 4.5.6", STATUS_INVALID_PARAMETER, 2, { -1 } }, -+ { ".", STATUS_INVALID_PARAMETER, 1, { -1 } }, -+ { "..", STATUS_INVALID_PARAMETER, 1, { -1 } }, -+ { "1.", STATUS_INVALID_PARAMETER, 2, { -1 } }, -+ { "1..", STATUS_INVALID_PARAMETER, 3, { -1 } }, -+ { ".1", STATUS_INVALID_PARAMETER, 1, { -1 } }, -+ { ".1.", STATUS_INVALID_PARAMETER, 1, { -1 } }, -+ { ".1.2.3", STATUS_INVALID_PARAMETER, 1, { -1 } }, -+ { "0.1.2.3", STATUS_SUCCESS, 7, { 0, 1, 2, 3 } }, -+ { "0.1.2.3.", STATUS_INVALID_PARAMETER, 7, { -1 } }, -+ { "[0.1.2.3]", STATUS_INVALID_PARAMETER, 0, { -1 } }, -+ { "::1", STATUS_INVALID_PARAMETER, 0, { -1 } }, -+ { ":1", STATUS_INVALID_PARAMETER, 0, { -1 } }, -+}; -+const unsigned int ipv4_testcount = sizeof(ipv4_tests) / sizeof(ipv4_tests[0]); -+ -+static void init_ip4(IN_ADDR* addr, const int src[4]) -+{ -+ if (!src || src[0] == -1) -+ { -+ addr->S_un.S_addr = 0xabababab; -+ } -+ else -+ { -+ addr->S_un.S_un_b.s_b1 = src[0]; -+ addr->S_un.S_un_b.s_b2 = src[1]; -+ addr->S_un.S_un_b.s_b3 = src[2]; -+ addr->S_un.S_un_b.s_b4 = src[3]; -+ } -+} -+ - static void test_RtlIpv4StringToAddress(void) - { - NTSTATUS res; - IN_ADDR ip, expected_ip; - PCSTR terminator; - CHAR dummy; -- struct -- { -- PCSTR address; -- NTSTATUS res; -- int terminator_offset; -- int ip[4]; -- BOOL strict_is_different; -- NTSTATUS res_strict; -- int terminator_offset_strict; -- int ip_strict[4]; -- } tests[] = -- { -- { "", STATUS_INVALID_PARAMETER, 0, { -1 } }, -- { " ", STATUS_INVALID_PARAMETER, 0, { -1 } }, -- { "1.1.1.1", STATUS_SUCCESS, 7, { 1, 1, 1, 1 } }, -- { "0.0.0.0", STATUS_SUCCESS, 7, { 0, 0, 0, 0 } }, -- { "255.255.255.255", STATUS_SUCCESS, 15, { 255, 255, 255, 255 } }, -- { "255.255.255.255:123", -- STATUS_SUCCESS, 15, { 255, 255, 255, 255 } }, -- { "255.255.255.256", STATUS_INVALID_PARAMETER, 15, { -1 } }, -- { "255.255.255.4294967295", -- STATUS_INVALID_PARAMETER, 22, { -1 } }, -- { "255.255.255.4294967296", -- STATUS_INVALID_PARAMETER, 21, { -1 } }, -- { "255.255.255.4294967297", -- STATUS_INVALID_PARAMETER, 21, { -1 } }, -- { "a", STATUS_INVALID_PARAMETER, 0, { -1 } }, -- { "1.1.1.0xaA", STATUS_SUCCESS, 10, { 1, 1, 1, 170 }, -- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, -- { "1.1.1.0XaA", STATUS_SUCCESS, 10, { 1, 1, 1, 170 }, -- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, -- { "1.1.1.0x", STATUS_INVALID_PARAMETER, 8, { -1 } }, -- { "1.1.1.0xff", STATUS_SUCCESS, 10, { 1, 1, 1, 255 }, -- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, -- { "1.1.1.0x100", STATUS_INVALID_PARAMETER, 11, { -1 }, -- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, -- { "1.1.1.0xffffffff",STATUS_INVALID_PARAMETER, 16, { -1 }, -- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, -- { "1.1.1.0x100000000", -- STATUS_INVALID_PARAMETER, 16, { -1, 0, 0, 0 }, -- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, -- { "1.1.1.010", STATUS_SUCCESS, 9, { 1, 1, 1, 8 }, -- TRUE, STATUS_INVALID_PARAMETER, 7, { -1 } }, -- { "1.1.1.00", STATUS_SUCCESS, 8, { 1, 1, 1, 0 }, -- TRUE, STATUS_INVALID_PARAMETER, 7, { -1 } }, -- { "1.1.1.007", STATUS_SUCCESS, 9, { 1, 1, 1, 7 }, -- TRUE, STATUS_INVALID_PARAMETER, 7, { -1 } }, -- { "1.1.1.08", STATUS_INVALID_PARAMETER, 7, { -1 } }, -- { "1.1.1.008", STATUS_SUCCESS, 8, { 1, 1, 1, 0 }, -- TRUE, STATUS_INVALID_PARAMETER, 7, { -1 } }, -- { "1.1.1.0a", STATUS_SUCCESS, 7, { 1, 1, 1, 0 } }, -- { "1.1.1.0o10", STATUS_SUCCESS, 7, { 1, 1, 1, 0 } }, -- { "1.1.1.0b10", STATUS_SUCCESS, 7, { 1, 1, 1, 0 } }, -- { "1.1.1.-2", STATUS_INVALID_PARAMETER, 6, { -1 } }, -- { "1", STATUS_SUCCESS, 1, { 0, 0, 0, 1 }, -- TRUE, STATUS_INVALID_PARAMETER, 1, { -1 } }, -- { "-1", STATUS_INVALID_PARAMETER, 0, { -1 } }, -- { "203569230", STATUS_SUCCESS, 9, { 12, 34, 56, 78 }, -- TRUE, STATUS_INVALID_PARAMETER, 9, { -1 } }, -- { "1.223756", STATUS_SUCCESS, 8, { 1, 3, 106, 12 }, -- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, -- { "3.4.756", STATUS_SUCCESS, 7, { 3, 4, 2, 244 }, -- TRUE, STATUS_INVALID_PARAMETER, 7, { -1 } }, -- { "3.4.756.1", STATUS_INVALID_PARAMETER, 9, { -1 } }, -- { "3.4.65536", STATUS_INVALID_PARAMETER, 9, { -1 } }, -- { "3.4.5.6.7", STATUS_INVALID_PARAMETER, 7, { -1 } }, -- { "3.4.5.+6", STATUS_INVALID_PARAMETER, 6, { -1 } }, -- { " 3.4.5.6", STATUS_INVALID_PARAMETER, 0, { -1 } }, -- { "\t3.4.5.6", STATUS_INVALID_PARAMETER, 0, { -1 } }, -- { "3.4.5.6 ", STATUS_SUCCESS, 7, { 3, 4, 5, 6 } }, -- { "3. 4.5.6", STATUS_INVALID_PARAMETER, 2, { -1 } }, -- { ".", STATUS_INVALID_PARAMETER, 1, { -1 } }, -- { "..", STATUS_INVALID_PARAMETER, 1, { -1 } }, -- { "1.", STATUS_INVALID_PARAMETER, 2, { -1 } }, -- { "1..", STATUS_INVALID_PARAMETER, 3, { -1 } }, -- { ".1", STATUS_INVALID_PARAMETER, 1, { -1 } }, -- { ".1.", STATUS_INVALID_PARAMETER, 1, { -1 } }, -- { ".1.2.3", STATUS_INVALID_PARAMETER, 1, { -1 } }, -- { "0.1.2.3", STATUS_SUCCESS, 7, { 0, 1, 2, 3 } }, -- { "0.1.2.3.", STATUS_INVALID_PARAMETER, 7, { -1 } }, -- { "[0.1.2.3]", STATUS_INVALID_PARAMETER, 0, { -1 } }, -- { "::1", STATUS_INVALID_PARAMETER, 0, { -1 } }, -- { ":1", STATUS_INVALID_PARAMETER, 0, { -1 } }, -- }; -- const int testcount = sizeof(tests) / sizeof(tests[0]); -- int i; -+ unsigned int i; - - if (!pRtlIpv4StringToAddressA) - { -@@ -1444,65 +1457,174 @@ static void test_RtlIpv4StringToAddress(void) - */ - } - -- for (i = 0; i < testcount; i++) -+ for (i = 0; i < ipv4_testcount; i++) - { - /* non-strict */ - terminator = &dummy; - ip.S_un.S_addr = 0xabababab; -- res = pRtlIpv4StringToAddressA(tests[i].address, FALSE, &terminator, &ip); -- ok(res == tests[i].res, -+ res = pRtlIpv4StringToAddressA(ipv4_tests[i].address, FALSE, &terminator, &ip); -+ ok(res == ipv4_tests[i].res, - "[%s] res = 0x%08x, expected 0x%08x\n", -- tests[i].address, res, tests[i].res); -- ok(terminator == tests[i].address + tests[i].terminator_offset, -+ ipv4_tests[i].address, res, ipv4_tests[i].res); -+ ok(terminator == ipv4_tests[i].address + ipv4_tests[i].terminator_offset, - "[%s] terminator = %p, expected %p\n", -- tests[i].address, terminator, tests[i].address + tests[i].terminator_offset); -- if (tests[i].ip[0] == -1) -- expected_ip.S_un.S_addr = 0xabababab; -- else -- { -- expected_ip.S_un.S_un_b.s_b1 = tests[i].ip[0]; -- expected_ip.S_un.S_un_b.s_b2 = tests[i].ip[1]; -- expected_ip.S_un.S_un_b.s_b3 = tests[i].ip[2]; -- expected_ip.S_un.S_un_b.s_b4 = tests[i].ip[3]; -- } -+ ipv4_tests[i].address, terminator, ipv4_tests[i].address + ipv4_tests[i].terminator_offset); -+ -+ init_ip4(&expected_ip, ipv4_tests[i].ip); - ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, - "[%s] ip = %08x, expected %08x\n", -- tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); -+ ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); - -- if (!tests[i].strict_is_different) -+ if (!(ipv4_tests[i].flags & strict_diff_4)) - { -- tests[i].res_strict = tests[i].res; -- tests[i].terminator_offset_strict = tests[i].terminator_offset; -- tests[i].ip_strict[0] = tests[i].ip[0]; -- tests[i].ip_strict[1] = tests[i].ip[1]; -- tests[i].ip_strict[2] = tests[i].ip[2]; -- tests[i].ip_strict[3] = tests[i].ip[3]; -+ ipv4_tests[i].res_strict = ipv4_tests[i].res; -+ ipv4_tests[i].terminator_offset_strict = ipv4_tests[i].terminator_offset; -+ ipv4_tests[i].ip_strict[0] = ipv4_tests[i].ip[0]; -+ ipv4_tests[i].ip_strict[1] = ipv4_tests[i].ip[1]; -+ ipv4_tests[i].ip_strict[2] = ipv4_tests[i].ip[2]; -+ ipv4_tests[i].ip_strict[3] = ipv4_tests[i].ip[3]; - } - /* strict */ - terminator = &dummy; - ip.S_un.S_addr = 0xabababab; -- res = pRtlIpv4StringToAddressA(tests[i].address, TRUE, &terminator, &ip); -- ok(res == tests[i].res_strict, -+ res = pRtlIpv4StringToAddressA(ipv4_tests[i].address, TRUE, &terminator, &ip); -+ ok(res == ipv4_tests[i].res_strict, - "[%s] res = 0x%08x, expected 0x%08x\n", -- tests[i].address, res, tests[i].res_strict); -- ok(terminator == tests[i].address + tests[i].terminator_offset_strict, -+ ipv4_tests[i].address, res, ipv4_tests[i].res_strict); -+ ok(terminator == ipv4_tests[i].address + ipv4_tests[i].terminator_offset_strict, - "[%s] terminator = %p, expected %p\n", -- tests[i].address, terminator, tests[i].address + tests[i].terminator_offset_strict); -- if (tests[i].ip_strict[0] == -1) -- expected_ip.S_un.S_addr = 0xabababab; -- else -- { -- expected_ip.S_un.S_un_b.s_b1 = tests[i].ip_strict[0]; -- expected_ip.S_un.S_un_b.s_b2 = tests[i].ip_strict[1]; -- expected_ip.S_un.S_un_b.s_b3 = tests[i].ip_strict[2]; -- expected_ip.S_un.S_un_b.s_b4 = tests[i].ip_strict[3]; -- } -+ ipv4_tests[i].address, terminator, ipv4_tests[i].address + ipv4_tests[i].terminator_offset_strict); -+ -+ init_ip4(&expected_ip, ipv4_tests[i].ip_strict); - ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, - "[%s] ip = %08x, expected %08x\n", -- tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); -+ ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); - } - } - -+static void test_RtlIpv4StringToAddressEx(void) -+{ -+ NTSTATUS res; -+ IN_ADDR ip, expected_ip; -+ USHORT port; -+ static const struct -+ { -+ PCSTR address; -+ NTSTATUS res; -+ int ip[4]; -+ USHORT port; -+ } ipv4_ex_tests[] = -+ { -+ { "", STATUS_INVALID_PARAMETER, { -1 }, 0xdead }, -+ { " ", STATUS_INVALID_PARAMETER, { -1 }, 0xdead }, -+ { "1.1.1.1:", STATUS_INVALID_PARAMETER, { 1, 1, 1, 1 }, 0xdead }, -+ { "1.1.1.1+", STATUS_INVALID_PARAMETER, { 1, 1, 1, 1 }, 0xdead }, -+ { "1.1.1.1:1", STATUS_SUCCESS, { 1, 1, 1, 1 }, 0x100 }, -+ { "256.1.1.1:1", STATUS_INVALID_PARAMETER, { -1 }, 0xdead }, -+ { "-1.1.1.1:1", STATUS_INVALID_PARAMETER, { -1 }, 0xdead }, -+ { "0.0.0.0:0", STATUS_INVALID_PARAMETER, { 0, 0, 0, 0 }, 0xdead }, -+ { "0.0.0.0:1", STATUS_SUCCESS, { 0, 0, 0, 0 }, 0x100 }, -+ { "1.2.3.4:65535", STATUS_SUCCESS, { 1, 2, 3, 4 }, 65535 }, -+ { "1.2.3.4:65536", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead }, -+ { "1.2.3.4:0xffff", STATUS_SUCCESS, { 1, 2, 3, 4 }, 65535 }, -+ { "1.2.3.4:0XfFfF", STATUS_SUCCESS, { 1, 2, 3, 4 }, 65535 }, -+ { "1.2.3.4:011064", STATUS_SUCCESS, { 1, 2, 3, 4 }, 0x3412 }, -+ { "1.2.3.4:1234a", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead }, -+ { "1.2.3.4:1234+", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead }, -+ { "1.2.3.4: 1234", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead }, -+ { "1.2.3.4:\t1234", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead }, -+ }; -+ const unsigned int ipv4_ex_testcount = sizeof(ipv4_ex_tests) / sizeof(ipv4_ex_tests[0]); -+ unsigned int i; -+ BOOLEAN strict; -+ -+ if (!pRtlIpv4StringToAddressExA) -+ { -+ skip("RtlIpv4StringToAddressEx not available\n"); -+ return; -+ } -+ -+ /* do not crash, and do not touch the ip / port. */ -+ ip.S_un.S_addr = 0xabababab; -+ port = 0xdead; -+ res = pRtlIpv4StringToAddressExA(NULL, FALSE, &ip, &port); -+ ok(res == STATUS_INVALID_PARAMETER, "[null address] res = 0x%08x, expected 0x%08x\n", -+ res, STATUS_INVALID_PARAMETER); -+ ok(ip.S_un.S_addr == 0xabababab, "RtlIpv4StringToAddressExA should not touch the ip!, ip == %x\n", ip.S_un.S_addr); -+ ok(port == 0xdead, "RtlIpv4StringToAddressExA should not touch the port!, port == %x\n", port); -+ -+ port = 0xdead; -+ res = pRtlIpv4StringToAddressExA("1.1.1.1", FALSE, NULL, &port); -+ ok(res == STATUS_INVALID_PARAMETER, "[null ip] res = 0x%08x, expected 0x%08x\n", -+ res, STATUS_INVALID_PARAMETER); -+ ok(port == 0xdead, "RtlIpv4StringToAddressExA should not touch the port!, port == %x\n", port); -+ -+ ip.S_un.S_addr = 0xabababab; -+ port = 0xdead; -+ res = pRtlIpv4StringToAddressExA("1.1.1.1", FALSE, &ip, NULL); -+ ok(res == STATUS_INVALID_PARAMETER, "[null port] res = 0x%08x, expected 0x%08x\n", -+ res, STATUS_INVALID_PARAMETER); -+ ok(ip.S_un.S_addr == 0xabababab, "RtlIpv4StringToAddressExA should not touch the ip!, ip == %x\n", ip.S_un.S_addr); -+ ok(port == 0xdead, "RtlIpv4StringToAddressExA should not touch the port!, port == %x\n", port); -+ -+ /* first we run the non-ex testcases on the ex function */ -+ for (i = 0; i < ipv4_testcount; i++) -+ { -+ NTSTATUS expect_res = (ipv4_tests[i].flags & ex_fail_4) ? STATUS_INVALID_PARAMETER : ipv4_tests[i].res; -+ -+ /* non-strict */ -+ port = 0xdead; -+ ip.S_un.S_addr = 0xabababab; -+ res = pRtlIpv4StringToAddressExA(ipv4_tests[i].address, FALSE, &ip, &port); -+ ok(res == expect_res, "[%s] res = 0x%08x, expected 0x%08x\n", -+ ipv4_tests[i].address, res, expect_res); -+ -+ init_ip4(&expected_ip, ipv4_tests[i].ip); -+ ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, "[%s] ip = %08x, expected %08x\n", -+ ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); -+ -+ if (!(ipv4_tests[i].flags & strict_diff_4)) -+ { -+ ipv4_tests[i].res_strict = ipv4_tests[i].res; -+ ipv4_tests[i].terminator_offset_strict = ipv4_tests[i].terminator_offset; -+ ipv4_tests[i].ip_strict[0] = ipv4_tests[i].ip[0]; -+ ipv4_tests[i].ip_strict[1] = ipv4_tests[i].ip[1]; -+ ipv4_tests[i].ip_strict[2] = ipv4_tests[i].ip[2]; -+ ipv4_tests[i].ip_strict[3] = ipv4_tests[i].ip[3]; -+ } -+ /* strict */ -+ expect_res = (ipv4_tests[i].flags & ex_fail_4) ? STATUS_INVALID_PARAMETER : ipv4_tests[i].res_strict; -+ port = 0xdead; -+ ip.S_un.S_addr = 0xabababab; -+ res = pRtlIpv4StringToAddressExA(ipv4_tests[i].address, TRUE, &ip, &port); -+ ok(res == expect_res, "[%s] res = 0x%08x, expected 0x%08x\n", -+ ipv4_tests[i].address, res, expect_res); -+ -+ init_ip4(&expected_ip, ipv4_tests[i].ip_strict); -+ ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, "[%s] ip = %08x, expected %08x\n", -+ ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); -+ } -+ -+ -+ for (i = 0; i < ipv4_ex_testcount; i++) -+ { -+ /* Strict is only relevant for the ip address, so make sure that it does not influence the port */ -+ for (strict = 0; strict < 2; strict++) -+ { -+ ip.S_un.S_addr = 0xabababab; -+ port = 0xdead; -+ res = pRtlIpv4StringToAddressExA(ipv4_ex_tests[i].address, strict, &ip, &port); -+ ok(res == ipv4_ex_tests[i].res, "[%s] res = 0x%08x, expected 0x%08x\n", -+ ipv4_ex_tests[i].address, res, ipv4_ex_tests[i].res); -+ -+ init_ip4(&expected_ip, ipv4_ex_tests[i].ip); -+ ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, "[%s] ip = %08x, expected %08x\n", -+ ipv4_ex_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); -+ ok(port == ipv4_ex_tests[i].port, "[%s] port = %u, expected %u\n", -+ ipv4_ex_tests[i].address, port, ipv4_ex_tests[i].port); -+ } -+ } -+} - - /* ipv6 addresses based on the set from https://github.com/beaugunderson/javascript-ipv6/tree/master/test/data */ - static const struct -@@ -2318,6 +2440,7 @@ START_TEST(rtl) - test_RtlIpv4AddressToString(); - test_RtlIpv4AddressToStringEx(); - test_RtlIpv4StringToAddress(); -+ test_RtlIpv4StringToAddressEx(); - test_RtlIpv6StringToAddress(); - test_RtlIpv6StringToAddressEx(); - test_LdrAddRefDll(); --- -2.3.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0004-ntdll-tests-Add-tests-for-RtlIpv6AddressToString-and.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0004-ntdll-tests-Add-tests-for-RtlIpv6AddressToString-and.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0004-ntdll-tests-Add-tests-for-RtlIpv6AddressToString-and.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/0004-ntdll-tests-Add-tests-for-RtlIpv6AddressToString-and.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,291 +0,0 @@ -From 569439573a4b64588331359269f90a32f0d93b9c Mon Sep 17 00:00:00 2001 -From: Mark Jansen -Date: Mon, 6 Apr 2015 00:48:33 +0200 -Subject: ntdll/tests: Add tests for RtlIpv6AddressToString and - RtlIpv6AddressToStringEx. - ---- - dlls/ntdll/tests/rtl.c | 246 +++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 246 insertions(+) - -diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c -index 6d41589..37f74b5 100644 ---- a/dlls/ntdll/tests/rtl.c -+++ b/dlls/ntdll/tests/rtl.c -@@ -91,6 +91,8 @@ static CHAR * (WINAPI *pRtlIpv4AddressToStringA)(const IN_ADDR *, LPSTR); - static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG); - static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *); - static NTSTATUS (WINAPI *pRtlIpv4StringToAddressExA)(PCSTR, BOOLEAN, IN_ADDR *, PUSHORT); -+static CHAR * (WINAPI *pRtlIpv6AddressToStringA)(struct in6_addr *, PSTR); -+static NTSTATUS (WINAPI *pRtlIpv6AddressToStringExA)(struct in6_addr *, ULONG, USHORT, PCHAR, PULONG); - static NTSTATUS (WINAPI *pRtlIpv6StringToAddressA)(PCSTR, PCSTR *, struct in6_addr *); - static NTSTATUS (WINAPI *pRtlIpv6StringToAddressW)(PCWSTR, PCWSTR *, struct in6_addr *); - static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExA)(PCSTR, struct in6_addr *, PULONG, PUSHORT); -@@ -148,6 +150,8 @@ static void InitFunctionPtrs(void) - pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA"); - pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA"); - pRtlIpv4StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressExA"); -+ pRtlIpv6AddressToStringA = (void *)GetProcAddress(hntdll, "RtlIpv6AddressToStringA"); -+ pRtlIpv6AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv6AddressToStringExA"); - pRtlIpv6StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressA"); - pRtlIpv6StringToAddressW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressW"); - pRtlIpv6StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExA"); -@@ -1924,6 +1928,246 @@ static void init_ip6(IN6_ADDR* addr, const int src[8]) - } - } - -+static void test_RtlIpv6AddressToString(void) -+{ -+ CHAR buffer[50]; -+ LPCSTR result; -+ IN6_ADDR ip; -+ DWORD_PTR len; -+ struct -+ { -+ PCSTR address; -+ int ip[8]; -+ } tests[] = -+ { -+ /* ipv4 addresses & ISATAP addresses */ -+ { "::13.1.68.3", { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, -+ { "::ffff:13.1.68.3", { 0, 0, 0, 0, 0, 0xffff, 0x10d, 0x344 } }, -+ { "::feff:d01:4403", { 0, 0, 0, 0, 0, 0xfffe, 0x10d, 0x344 } }, -+ { "::fffe:d01:4403", { 0, 0, 0, 0, 0, 0xfeff, 0x10d, 0x344 } }, -+ { "::100:d01:4403", { 0, 0, 0, 0, 0, 1, 0x10d, 0x344 } }, -+ { "::1:d01:4403", { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, -+ { "::ffff:0:4403", { 0, 0, 0, 0, 0, 0xffff, 0, 0x344 } }, -+ { "::ffff:13.1.0.0", { 0, 0, 0, 0, 0, 0xffff, 0x10d, 0 } }, -+ { "::ffff:0:0", { 0, 0, 0, 0, 0, 0xffff, 0, 0 } }, -+ { "::ffff:0:13.1.68.3", { 0, 0, 0, 0, 0xffff, 0, 0x10d, 0x344 } }, -+ { "::ffff:ffff:d01:4403", { 0, 0, 0, 0, 0xffff, 0xffff, 0x10d, 0x344 } }, -+ { "::ffff:0:0:d01:4403", { 0, 0, 0, 0xffff, 0, 0, 0x10d, 0x344 } }, -+ { "::ffff:255.255.255.255", { 0, 0, 0, 0, 0, 0xffff, 0xffff, 0xffff } }, -+ { "::ffff:129.144.52.38", { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, -+ { "::5efe:129.144.52.38", { 0, 0, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, -+ { "1111:2222:3333:4444:0:5efe:129.144.52.38", { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, -+ { "1111:2222:3333::5efe:129.144.52.38", { 0x1111, 0x2222, 0x3333, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, -+ { "1111:2222::5efe:129.144.52.38", { 0x1111, 0x2222, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, -+ { "1111::5efe:129.144.52.38", { 0x1111, 0, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, -+ { "::200:5efe:129.144.52.38", { 0, 0, 0, 0, 2, 0xfe5e, 0x9081, 0x2634 } }, -+ { "::100:5efe:8190:3426", { 0, 0, 0, 0, 1, 0xfe5e, 0x9081, 0x2634 } }, -+ /* 'normal' addresses */ -+ { "::1", { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "0:1:2:3:4:5:6:7", { 0, 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700 } }, -+ { "1080::8:800:200c:417a", { 0x8010, 0, 0, 0, 0x800, 0x8, 0x0c20, 0x7a41 } }, -+ { "1111:2222:3333:4444:5555:6666:7b7b:7b7b", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111:2222:3333:4444:5555:6666:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, -+ { "1111:2222:3333:4444:5555:6666::", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0 } }, -+ { "1111:2222:3333:4444:5555:6666:0:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0x8888 } }, -+ { "1111:2222:3333:4444:5555::", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0 } }, -+ { "1111:2222:3333:4444:5555:0:7b7b:7b7b", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7b7b, 0x7b7b } }, -+ { "1111:2222:3333:4444:5555:0:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7777, 0x8888 } }, -+ { "1111:2222:3333:4444:5555::8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8888 } }, -+ { "1111::", { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "1111::7b7b:7b7b", { 0x1111, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } }, -+ { "1111:0:3333:4444:5555:6666:7b7b:7b7b", { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111:0:3333:4444:5555:6666:7777:8888", { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, -+ { "1111::4444:5555:6666:7b7b:7b7b", { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111::4444:5555:6666:7777:8888", { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, -+ { "1111::5555:6666:7b7b:7b7b", { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111::5555:6666:7777:8888", { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7777, 0x8888 } }, -+ { "1111::6666:7b7b:7b7b", { 0x1111, 0, 0, 0, 0, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111::6666:7777:8888", { 0x1111, 0, 0, 0, 0, 0x6666, 0x7777, 0x8888 } }, -+ { "1111::7777:8888", { 0x1111, 0, 0, 0, 0, 0, 0x7777, 0x8888 } }, -+ { "1111::8888", { 0x1111, 0, 0, 0, 0, 0, 0, 0x8888 } }, -+ { "1:2:3:4:5:6:102:304", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x201, 0x403 } }, -+ { "1:2:3:4:5:6:7:8", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800 } }, -+ { "1:2:3:4:5:6::", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0 } }, -+ { "1:2:3:4:5:6:0:8", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0x800 } }, -+ { "2001:0:1234::c1c0:abcd:876", { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 } }, -+ { "2001:0:4136:e378:8000:63bf:3fff:fdd2", { 0x120, 0, 0x3641, 0x78e3, 0x80, 0xbf63, 0xff3f, 0xd2fd } }, -+ { "2001:db8::1428:57ab", { 0x120, 0xb80d, 0, 0, 0, 0, 0x2814, 0xab57 } }, -+ { "2001:db8:1234:ffff:ffff:ffff:ffff:ffff", { 0x120, 0xb80d, 0x3412, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } }, -+ { "2001:0:ce49:7601:2cad:dfff:7c94:fffe", { 0x120, 0, 0x49ce, 0x176, 0xad2c, 0xffdf, 0x947c, 0xfeff } }, -+ { "2001:db8:85a3::8a2e:370:7334", { 0x120, 0xb80d, 0xa385, 0, 0, 0x2e8a, 0x7003, 0x3473 } }, -+ { "3ffe:b00::1:0:0:a", { 0xfe3f, 0xb, 0, 0, 0x100, 0, 0, 0xa00 } }, -+ { "::a:b:c:d:e", { 0, 0, 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00 } }, -+ { "::123.123.123.123", { 0, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } }, -+ { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } }, -+ { "1111:2222:3333:4444:5555:6666:7777:1", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x100 } }, -+ { "1111:2222:3333:4444:5555:6666:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, -+ { "1111:2222::", { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 } }, -+ { "1111::3333:4444:5555:6666:7777", { 0x1111, 0, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777 } }, -+ { "1111:2222::", { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 } }, -+ { "1111::3333", { 0x1111, 0, 0, 0, 0, 0, 0, 0x3333 } }, -+ { "2001:0:1234::c1c0:abcd:876", { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 } }, -+ { "2001::ffd3", { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, -+ }; -+ const size_t testcount = sizeof(tests) / sizeof(tests[0]); -+ unsigned int i; -+ -+ if (!pRtlIpv6AddressToStringA) -+ { -+ skip("RtlIpv6AddressToStringA not available\n"); -+ return; -+ } -+ -+ memset(buffer, '#', sizeof(buffer)); -+ buffer[sizeof(buffer)-1] = 0; -+ memset(&ip, 0, sizeof(ip)); -+ result = pRtlIpv6AddressToStringA(&ip, buffer); -+ -+ len = strlen(buffer); -+ ok(result == (buffer + len) && !strcmp(buffer, "::"), -+ "got %p with '%s' (expected %p with '::')\n", result, buffer, buffer + len); -+ -+ result = pRtlIpv6AddressToStringA(&ip, NULL); -+ ok(result == (LPCSTR)~0 || broken(result == (LPCSTR)len) /* WinXP / Win2k3 */, -+ "got %p, expected %p\n", result, (LPCSTR)~0); -+ -+ for (i = 0; i < testcount; i++) -+ { -+ init_ip6(&ip, tests[i].ip); -+ memset(buffer, '#', sizeof(buffer)); -+ buffer[sizeof(buffer)-1] = 0; -+ -+ result = pRtlIpv6AddressToStringA(&ip, buffer); -+ len = strlen(buffer); -+ ok(result == (buffer + len) && !strcmp(buffer, tests[i].address), -+ "got %p with '%s' (expected %p with '%s')\n", result, buffer, buffer + len, tests[i].address); -+ -+ ok(buffer[45] == 0 || broken(buffer[45] != 0) /* WinXP / Win2k3 */, -+ "expected data at buffer[45] to always be NULL\n"); -+ ok(buffer[46] == '#', "expected data at buffer[46] not to change\n"); -+ } -+} -+ -+static void test_RtlIpv6AddressToStringEx(void) -+{ -+ CHAR buffer[70]; -+ NTSTATUS res; -+ IN6_ADDR ip; -+ ULONG len; -+ struct -+ { -+ PCSTR address; -+ ULONG scopeid; -+ USHORT port; -+ int ip[8]; -+ } tests[] = -+ { -+ /* ipv4 addresses & ISATAP addresses */ -+ { "::13.1.68.3", 0, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, -+ { "::13.1.68.3%1", 1, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, -+ { "::13.1.68.3%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, -+ { "[::13.1.68.3%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, -+ { "[::13.1.68.3%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, -+ { "[::13.1.68.3]:256", 0, 1, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, -+ -+ { "::1:d01:4403", 0, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, -+ { "::1:d01:4403%1", 1, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, -+ { "::1:d01:4403%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, -+ { "[::1:d01:4403%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, -+ { "[::1:d01:4403%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, -+ { "[::1:d01:4403]:256", 0, 1, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, -+ -+ { "1111:2222:3333:4444:0:5efe:129.144.52.38", 0, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, -+ { "1111:2222:3333:4444:0:5efe:129.144.52.38%1", 1, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, -+ { "1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819", 0xffffbbbb, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, -+ { "[1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819]:65518",0xffffbbbb, 0xeeff, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, -+ { "[1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, -+ { "[1111:2222:3333:4444:0:5efe:129.144.52.38]:256", 0, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, -+ -+ { "::1", 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "::1%1", 1, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "::1%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "[::1%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "[::1%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ { "[::1]:256", 0, 1, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, -+ -+ { "1111:2222:3333:4444:5555:6666:7b7b:7b7b", 0, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111:2222:3333:4444:5555:6666:7b7b:7b7b%1", 1, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "1111:2222:3333:4444:5555:6666:7b7b:7b7b%4294949819", 0xffffbbbb, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "[1111:2222:3333:4444:5555:6666:7b7b:7b7b%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "[1111:2222:3333:4444:5555:6666:7b7b:7b7b%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ { "[1111:2222:3333:4444:5555:6666:7b7b:7b7b]:256", 0, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, -+ -+ { "1111::", 0, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "1111::%1", 1, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "1111::%4294949819", 0xffffbbbb, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "[1111::%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "[1111::%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, -+ { "[1111::]:256", 0, 1, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, -+ -+ { "2001::ffd3", 0, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, -+ { "2001::ffd3%1", 1, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, -+ { "2001::ffd3%4294949819", 0xffffbbbb, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, -+ { "[2001::ffd3%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, -+ { "[2001::ffd3%4294949819]:256", 0xffffbbbb, 1, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, -+ { "[2001::ffd3]:256", 0, 1, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, -+ }; -+ const size_t testcount = sizeof(tests) / sizeof(tests[0]); -+ unsigned int i; -+ -+ if (!pRtlIpv6AddressToStringExA) -+ { -+ skip("RtlIpv6AddressToStringExA not available\n"); -+ return; -+ } -+ -+ memset(buffer, '#', sizeof(buffer)); -+ buffer[sizeof(buffer)-1] = 0; -+ memset(&ip, 0, sizeof(ip)); -+ len = sizeof(buffer); -+ res = pRtlIpv6AddressToStringExA(&ip, 0, 0, buffer, &len); -+ -+ ok(res == STATUS_SUCCESS, "[validate] res = 0x%08x, expected STATUS_SUCCESS\n", res); -+ ok(len == 3 && !strcmp(buffer, "::"), -+ "got len %d with '%s' (expected 3 with '::')\n", len, buffer); -+ -+ memset(buffer, '#', sizeof(buffer)); -+ buffer[sizeof(buffer)-1] = 0; -+ -+ len = sizeof(buffer); -+ res = pRtlIpv6AddressToStringExA(NULL, 0, 0, buffer, &len); -+ ok(res == STATUS_INVALID_PARAMETER, "[null ip] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); -+ -+ len = sizeof(buffer); -+ res = pRtlIpv6AddressToStringExA(&ip, 0, 0, NULL, &len); -+ ok(res == STATUS_INVALID_PARAMETER, "[null buffer] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); -+ -+ res = pRtlIpv6AddressToStringExA(&ip, 0, 0, buffer, NULL); -+ ok(res == STATUS_INVALID_PARAMETER, "[null length] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); -+ -+ len = 2; -+ memset(buffer, '#', sizeof(buffer)); -+ buffer[sizeof(buffer)-1] = 0; -+ res = pRtlIpv6AddressToStringExA(&ip, 0, 0, buffer, &len); -+ ok(res == STATUS_INVALID_PARAMETER, "[null length] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); -+ ok(buffer[0] == '#', "got first char %c (expected '#')\n", buffer[0]); -+ ok(len == 3, "got len %d (expected len 3)\n", len); -+ -+ for (i = 0; i < testcount; i++) -+ { -+ init_ip6(&ip, tests[i].ip); -+ len = sizeof(buffer); -+ memset(buffer, '#', sizeof(buffer)); -+ buffer[sizeof(buffer)-1] = 0; -+ -+ res = pRtlIpv6AddressToStringExA(&ip, tests[i].scopeid, tests[i].port, buffer, &len); -+ -+ ok(res == STATUS_SUCCESS, "[validate] res = 0x%08x, expected STATUS_SUCCESS\n", res); -+ ok(len == (strlen(tests[i].address) + 1) && !strcmp(buffer, tests[i].address), -+ "got len %d with '%s' (expected %d with '%s')\n", len, buffer, strlen(tests[i].address), tests[i].address); -+ } -+} -+ - static void compare_RtlIpv6StringToAddressW(PCSTR name_a, int terminator_offset_a, - const struct in6_addr *addr_a, NTSTATUS res_a) - { -@@ -3173,6 +3417,8 @@ START_TEST(rtl) - test_RtlIpv4AddressToStringEx(); - test_RtlIpv4StringToAddress(); - test_RtlIpv4StringToAddressEx(); -+ test_RtlIpv6AddressToString(); -+ test_RtlIpv6AddressToStringEx(); - test_RtlIpv6StringToAddress(); - test_RtlIpv6StringToAddressEx(); - test_LdrAddRefDll(); --- -2.3.5 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Category: stable diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/0001-ntdll-Fix-parameters-for-RtlIpv4StringToAddressExW-s.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/0001-ntdll-Fix-parameters-for-RtlIpv4StringToAddressExW-s.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/0001-ntdll-Fix-parameters-for-RtlIpv4StringToAddressExW-s.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/0001-ntdll-Fix-parameters-for-RtlIpv4StringToAddressExW-s.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,57 @@ +From 7f439e90221b6ef02371935f2f49528a0537af8c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 21 Jan 2016 00:33:12 +0100 +Subject: ntdll: Fix parameters for RtlIpv4StringToAddressExW stub. + +--- + dlls/ntdll/ntdll.spec | 2 +- + dlls/ntdll/rtl.c | 5 ++--- + dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- + 3 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec +index 4e49709..9712b3a 100644 +--- a/dlls/ntdll/ntdll.spec ++++ b/dlls/ntdll/ntdll.spec +@@ -714,7 +714,7 @@ + @ stdcall RtlIpv4AddressToStringW(ptr ptr) + # @ stub RtlIpv4StringToAddressA + # @ stub RtlIpv4StringToAddressExA +-@ stdcall RtlIpv4StringToAddressExW(ptr ptr wstr ptr) ++@ stdcall RtlIpv4StringToAddressExW(wstr long ptr ptr) + # @ stub RtlIpv4StringToAddressW + # @ stub RtlIpv6AddressToStringA + # @ stub RtlIpv6AddressToStringExA +diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c +index f699cff..ec5c999b 100644 +--- a/dlls/ntdll/rtl.c ++++ b/dlls/ntdll/rtl.c +@@ -882,10 +882,9 @@ void WINAPI RtlCopyLuidAndAttributesArray( + for (i = 0; i < Count; i++) Dest[i] = Src[i]; + } + +-NTSTATUS WINAPI RtlIpv4StringToAddressExW(PULONG IP, PULONG Port, +- LPCWSTR Buffer, PULONG MaxSize) ++NTSTATUS WINAPI RtlIpv4StringToAddressExW(LPCWSTR str, BOOLEAN strict, IN_ADDR *address, PUSHORT port) + { +- FIXME("(%p,%p,%p,%p): stub\n", IP, Port, Buffer, MaxSize); ++ FIXME("(%s, %u, %p, %p): stub\n", debugstr_w(str), strict, address, port); + + return STATUS_SUCCESS; + } +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +index 1319ada..7ec49f1 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec ++++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +@@ -1075,7 +1075,7 @@ + @ stdcall RtlIpv4AddressToStringW(ptr ptr) ntdll.RtlIpv4AddressToStringW + @ stub RtlIpv4StringToAddressA + @ stub RtlIpv4StringToAddressExA +-@ stdcall RtlIpv4StringToAddressExW(ptr ptr wstr ptr) ntdll.RtlIpv4StringToAddressExW ++@ stdcall RtlIpv4StringToAddressExW(wstr long ptr ptr) ntdll.RtlIpv4StringToAddressExW + @ stub RtlIpv4StringToAddressW + @ stub RtlIpv6AddressToStringA + @ stub RtlIpv6AddressToStringExA +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/0002-ntdll-Add-stub-for-RtlIpv6StringToAddressExW.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/0002-ntdll-Add-stub-for-RtlIpv6StringToAddressExW.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/0002-ntdll-Add-stub-for-RtlIpv6StringToAddressExW.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/0002-ntdll-Add-stub-for-RtlIpv6StringToAddressExW.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,79 @@ +From 6f149e702d91a7aeb1e541bb13bdde9993ce69d4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 21 Jan 2016 00:34:27 +0100 +Subject: ntdll: Add stub for RtlIpv6StringToAddressExW. + +--- + dlls/ntdll/ntdll.spec | 2 +- + dlls/ntdll/rtl.c | 14 ++++++++++++++ + dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- + 3 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec +index 9712b3a..24057ad 100644 +--- a/dlls/ntdll/ntdll.spec ++++ b/dlls/ntdll/ntdll.spec +@@ -722,7 +722,7 @@ + # @ stub RtlIpv6AddressToStringW + # @ stub RtlIpv6StringToAddressA + # @ stub RtlIpv6StringToAddressExA +-# @ stub RtlIpv6StringToAddressExW ++@ stdcall RtlIpv6StringToAddressExW(wstr ptr ptr ptr) + # @ stub RtlIpv6StringToAddressW + @ stdcall RtlIsActivationContextActive(ptr) + @ stdcall RtlIsCriticalSectionLocked(ptr) +diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c +index ec5c999b..262cc86 100644 +--- a/dlls/ntdll/rtl.c ++++ b/dlls/ntdll/rtl.c +@@ -45,6 +45,7 @@ + #include "wine/unicode.h" + #include "ntdll_misc.h" + #include "inaddr.h" ++#include "in6addr.h" + #include "ddk/ntddk.h" + + WINE_DEFAULT_DEBUG_CHANNEL(ntdll); +@@ -882,6 +883,9 @@ void WINAPI RtlCopyLuidAndAttributesArray( + for (i = 0; i < Count; i++) Dest[i] = Src[i]; + } + ++/*********************************************************************** ++ * RtlIpv4StringToAddressExW [NTDLL.@] ++ */ + NTSTATUS WINAPI RtlIpv4StringToAddressExW(LPCWSTR str, BOOLEAN strict, IN_ADDR *address, PUSHORT port) + { + FIXME("(%s, %u, %p, %p): stub\n", debugstr_w(str), strict, address, port); +@@ -890,6 +894,16 @@ NTSTATUS WINAPI RtlIpv4StringToAddressExW(LPCWSTR str, BOOLEAN strict, IN_ADDR * + } + + /*********************************************************************** ++ * RtlIpv6StringToAddressExW [NTDLL.@] ++ */ ++NTSTATUS NTAPI RtlIpv6StringToAddressExW(LPCWSTR str, IN6_ADDR *address, PULONG scope, PUSHORT port) ++{ ++ FIXME("(%s, %p, %p, %p): stub\n", debugstr_w(str), address, scope, port); ++ ++ return STATUS_INVALID_PARAMETER; ++} ++ ++/*********************************************************************** + * RtlIpv4AddressToStringExW [NTDLL.@] + * + * Convert the given ipv4 address and optional the port to a string +diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +index 7ec49f1..526c707 100644 +--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec ++++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +@@ -1083,7 +1083,7 @@ + @ stub RtlIpv6AddressToStringW + @ stub RtlIpv6StringToAddressA + @ stub RtlIpv6StringToAddressExA +-@ stub RtlIpv6StringToAddressExW ++@ stdcall RtlIpv6StringToAddressExW(wstr ptr ptr ptr) ntdll.RtlIpv6StringToAddressExW + @ stub RtlIpv6StringToAddressW + @ stub RtlIsGenericTableEmpty + @ stub RtlIsGenericTableEmptyAvl +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Stubs/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,2 @@ +Fixes: Fix prototype of RtlIpv4StringToAddressExW +Fixes: Add stub for RtlIpv6StringToAddressExW diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,501 @@ +From 34d880216777154f9fef645795783a6deaddf2f8 Mon Sep 17 00:00:00 2001 +From: Mark Jansen +Date: Sun, 8 Mar 2015 18:24:45 +0100 +Subject: ntdll/tests: Tests for RtlIpv6StringToAddress (try 6) + +Changes from try5: +-Reformat ipv6 table to be less wide +-Remove _s6_un from memcmp calls + +Changes from try4: +-Use RtlMultiByteToUnicodeN for A->W conversion as suggested by stefand on + +Changes from try3: +-Also test the W version against the A version +-Expand the test with more corner cases +-replace the 'broken' int with an enum as suggested by stefand +-add comments to the flags, explaining their purpose. +-initialize ipv6 from int array in a small function to avoid code +duplication +--- + dlls/ntdll/tests/rtl.c | 430 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 430 insertions(+) + +diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c +index ac463c6..657c1ae 100644 +--- a/dlls/ntdll/tests/rtl.c ++++ b/dlls/ntdll/tests/rtl.c +@@ -25,6 +25,7 @@ + + #include "ntdll_test.h" + #include "inaddr.h" ++#include "in6addr.h" + #include "initguid.h" + #define COBJMACROS + #include "shobjidl.h" +@@ -92,9 +93,12 @@ static IMAGE_BASE_RELOCATION *(WINAPI *pLdrProcessRelocationBlock)(void*,UINT,US + static CHAR * (WINAPI *pRtlIpv4AddressToStringA)(const IN_ADDR *, LPSTR); + static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG); + static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *); ++static NTSTATUS (WINAPI *pRtlIpv6StringToAddressA)(PCSTR, PCSTR *, struct in6_addr *); ++static NTSTATUS (WINAPI *pRtlIpv6StringToAddressW)(PCWSTR, PCWSTR *, struct in6_addr *); + static NTSTATUS (WINAPI *pLdrAddRefDll)(ULONG, HMODULE); + static NTSTATUS (WINAPI *pLdrLockLoaderLock)(ULONG, ULONG*, ULONG_PTR*); + static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG_PTR); ++static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD); + static NTSTATUS (WINAPI *pRtlGetCompressionWorkSpaceSize)(USHORT, PULONG, PULONG); + static NTSTATUS (WINAPI *pRtlDecompressBuffer)(USHORT, PUCHAR, ULONG, const UCHAR*, ULONG, PULONG); + static NTSTATUS (WINAPI *pRtlDecompressFragment)(USHORT, PUCHAR, ULONG, const UCHAR*, ULONG, ULONG, PULONG, PVOID); +@@ -146,9 +150,12 @@ static void InitFunctionPtrs(void) + pRtlIpv4AddressToStringA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringA"); + pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA"); + pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA"); ++ pRtlIpv6StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressA"); ++ pRtlIpv6StringToAddressW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressW"); + pLdrAddRefDll = (void *)GetProcAddress(hntdll, "LdrAddRefDll"); + pLdrLockLoaderLock = (void *)GetProcAddress(hntdll, "LdrLockLoaderLock"); + pLdrUnlockLoaderLock = (void *)GetProcAddress(hntdll, "LdrUnlockLoaderLock"); ++ pRtlMultiByteToUnicodeN = (void *)GetProcAddress(hntdll, "RtlMultiByteToUnicodeN"); + pRtlGetCompressionWorkSpaceSize = (void *)GetProcAddress(hntdll, "RtlGetCompressionWorkSpaceSize"); + pRtlDecompressBuffer = (void *)GetProcAddress(hntdll, "RtlDecompressBuffer"); + pRtlDecompressFragment = (void *)GetProcAddress(hntdll, "RtlDecompressFragment"); +@@ -1303,6 +1310,428 @@ static void test_RtlIpv4StringToAddress(void) + } + } + ++ ++/* ipv6 addresses based on the set from https://github.com/beaugunderson/javascript-ipv6/tree/master/test/data */ ++static const struct ++{ ++ PCSTR address; ++ NTSTATUS res; ++ int terminator_offset; ++ int ip[8]; ++ /* win_broken: older versions of windows do not handle this correct ++ ex_fail: Ex function does need the string to be terminated, non-Ex does not. ++ ex_skip: test doesnt make sense for Ex (f.e. it's invalid for non-Ex but valid for Ex) */ ++ enum { normal_6, win_broken_6 = 1, ex_fail_6 = 2, ex_skip_6 = 4 } flags; ++} ipv6_tests[] = ++{ ++ { "0000:0000:0000:0000:0000:0000:0000:0000", STATUS_SUCCESS, 39, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "0000:0000:0000:0000:0000:0000:0000:0001", STATUS_SUCCESS, 39, ++ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "0:0:0:0:0:0:0:0", STATUS_SUCCESS, 15, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "0:0:0:0:0:0:0:1", STATUS_SUCCESS, 15, ++ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "0:0:0:0:0:0:0::", STATUS_SUCCESS, 13, ++ { 0, 0, 0, 0, 0, 0, 0, 0 }, win_broken_6 }, ++ { "0:0:0:0:0:0:13.1.68.3", STATUS_SUCCESS, 21, ++ { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, ++ { "0:0:0:0:0:0::", STATUS_SUCCESS, 13, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "0:0:0:0:0::", STATUS_SUCCESS, 11, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "0:0:0:0:0:FFFF:129.144.52.38", STATUS_SUCCESS, 28, ++ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, ++ { "0::", STATUS_SUCCESS, 3, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "0:1:2:3:4:5:6:7", STATUS_SUCCESS, 15, ++ { 0, 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700 } }, ++ { "1080:0:0:0:8:800:200c:417a", STATUS_SUCCESS, 26, ++ { 0x8010, 0, 0, 0, 0x800, 0x8, 0x0c20, 0x7a41 } }, ++ { "0:a:b:c:d:e:f::", STATUS_SUCCESS, 13, ++ { 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00, 0xf00, 0 }, win_broken_6 }, ++ { "1111:2222:3333:4444:5555:6666:123.123.123.123", STATUS_SUCCESS, 45, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111:2222:3333:4444:5555:6666:7777:8888", STATUS_SUCCESS, 39, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, ++ { "1111:2222:3333:4444:0x5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 21, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:3333:4444:x555:6666:7777:8888", STATUS_INVALID_PARAMETER, 20, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:3333:4444:0r5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 21, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:3333:4444:r5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 20, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:3333:4444:5555:6666:7777::", STATUS_SUCCESS, 34, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0 }, win_broken_6 }, ++ { "1111:2222:3333:4444:5555:6666::", STATUS_SUCCESS, 31, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0 } }, ++ { "1111:2222:3333:4444:5555:6666::8888", STATUS_SUCCESS, 35, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0x8888 } }, ++ { "1111:2222:3333:4444:5555::", STATUS_SUCCESS, 26, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0 } }, ++ { "1111:2222:3333:4444:5555::123.123.123.123", STATUS_SUCCESS, 41, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7b7b, 0x7b7b } }, ++ { "1111:2222:3333:4444:5555::0x1.123.123.123", STATUS_SUCCESS, 27, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x100 }, ex_fail_6 }, ++ { "1111:2222:3333:4444:5555::0x88", STATUS_SUCCESS, 27, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8800 }, ex_fail_6 }, ++ { "1111:2222:3333:4444:5555::0X88", STATUS_SUCCESS, 27, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8800 }, ex_fail_6 }, ++ { "1111:2222:3333:4444:5555::0X", STATUS_SUCCESS, 27, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0 }, ex_fail_6 }, ++ { "1111:2222:3333:4444:5555::0X88:7777", STATUS_SUCCESS, 27, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8800 }, ex_fail_6 }, ++ { "1111:2222:3333:4444:5555::0x8888", STATUS_SUCCESS, 27, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8888 }, ex_fail_6 }, ++ { "1111:2222:3333:4444:5555::08888", STATUS_INVALID_PARAMETER, 31, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:3333:4444:5555::fffff", STATUS_INVALID_PARAMETER, 31, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:3333:4444::fffff", STATUS_INVALID_PARAMETER, 26, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:3333::fffff", STATUS_INVALID_PARAMETER, 21, ++ { 0x1111, 0x2222, 0x3333, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:3333:4444:5555::7777:8888", STATUS_SUCCESS, 35, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7777, 0x8888 } }, ++ { "1111:2222:3333:4444:5555::8888", STATUS_SUCCESS, 30, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8888 } }, ++ { "1111::", STATUS_SUCCESS, 6, ++ { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "1111::123.123.123.123", STATUS_SUCCESS, 21, ++ { 0x1111, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } }, ++ { "1111::3333:4444:5555:6666:123.123.123.123", STATUS_SUCCESS, 41, ++ { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111::3333:4444:5555:6666:7777:8888", STATUS_SUCCESS, 35, ++ { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, ++ { "1111::4444:5555:6666:123.123.123.123", STATUS_SUCCESS, 36, ++ { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111::4444:5555:6666:7777:8888", STATUS_SUCCESS, 30, ++ { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, ++ { "1111::5555:6666:123.123.123.123", STATUS_SUCCESS, 31, ++ { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111::5555:6666:7777:8888", STATUS_SUCCESS, 25, ++ { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7777, 0x8888 } }, ++ { "1111::6666:123.123.123.123", STATUS_SUCCESS, 26, ++ { 0x1111, 0, 0, 0, 0, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111::6666:7777:8888", STATUS_SUCCESS, 20, ++ { 0x1111, 0, 0, 0, 0, 0x6666, 0x7777, 0x8888 } }, ++ { "1111::7777:8888", STATUS_SUCCESS, 15, ++ { 0x1111, 0, 0, 0, 0, 0, 0x7777, 0x8888 } }, ++ { "1111::8888", STATUS_SUCCESS, 10, ++ { 0x1111, 0, 0, 0, 0, 0, 0, 0x8888 } }, ++ { "1:2:3:4:5:6:1.2.3.4", STATUS_SUCCESS, 19, ++ { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x201, 0x403 } }, ++ { "1:2:3:4:5:6:7:8", STATUS_SUCCESS, 15, ++ { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800 } }, ++ { "1:2:3:4:5:6::", STATUS_SUCCESS, 13, ++ { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0 } }, ++ { "1:2:3:4:5:6::8", STATUS_SUCCESS, 14, ++ { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0x800 } }, ++ { "2001:0000:1234:0000:0000:C1C0:ABCD:0876", STATUS_SUCCESS, 39, ++ { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 } }, ++ { "2001:0000:4136:e378:8000:63bf:3fff:fdd2", STATUS_SUCCESS, 39, ++ { 0x120, 0, 0x3641, 0x78e3, 0x80, 0xbf63, 0xff3f, 0xd2fd } }, ++ { "2001:0db8:0:0:0:0:1428:57ab", STATUS_SUCCESS, 27, ++ { 0x120, 0xb80d, 0, 0, 0, 0, 0x2814, 0xab57 } }, ++ { "2001:0db8:1234:ffff:ffff:ffff:ffff:ffff", STATUS_SUCCESS, 39, ++ { 0x120, 0xb80d, 0x3412, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } }, ++ { "2001::CE49:7601:2CAD:DFFF:7C94:FFFE", STATUS_SUCCESS, 35, ++ { 0x120, 0, 0x49ce, 0x176, 0xad2c, 0xffdf, 0x947c, 0xfeff } }, ++ { "2001:db8:85a3::8a2e:370:7334", STATUS_SUCCESS, 28, ++ { 0x120, 0xb80d, 0xa385, 0, 0, 0x2e8a, 0x7003, 0x3473 } }, ++ { "3ffe:0b00:0000:0000:0001:0000:0000:000a", STATUS_SUCCESS, 39, ++ { 0xfe3f, 0xb, 0, 0, 0x100, 0, 0, 0xa00 } }, ++ { "::", STATUS_SUCCESS, 2, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "::%16", STATUS_SUCCESS, 2, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "::/16", STATUS_SUCCESS, 2, ++ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, ++ { "::0", STATUS_SUCCESS, 3, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "::0:0", STATUS_SUCCESS, 5, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "::0:0:0", STATUS_SUCCESS, 7, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "::0:0:0:0", STATUS_SUCCESS, 9, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "::0:0:0:0:0", STATUS_SUCCESS, 11, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "::0:0:0:0:0:0", STATUS_SUCCESS, 13, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ /* this one and the next one are incorrectly parsed by windows, ++ it adds one zero too many in front, cutting off the last digit. */ ++ { "::0:0:0:0:0:0:0", STATUS_SUCCESS, 13, ++ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, ++ { "::0:a:b:c:d:e:f", STATUS_SUCCESS, 13, ++ { 0, 0, 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00 }, ex_fail_6 }, ++ { "::123.123.123.123", STATUS_SUCCESS, 17, ++ { 0, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } }, ++ { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", STATUS_SUCCESS, 39, ++ { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } }, ++ ++ { "':10.0.0.1", STATUS_INVALID_PARAMETER, 0, ++ { -1 } }, ++ { "-1", STATUS_INVALID_PARAMETER, 0, ++ { -1 } }, ++ { "02001:0000:1234:0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, -1, ++ { -1 } }, ++ { "2001:00000:1234:0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, -1, ++ { 0x120, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "2001:0000:01234:0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, -1, ++ { 0x120, 0, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1.2.3.4", STATUS_INVALID_PARAMETER, 7, ++ { 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1.2.3.4:1111::5555", STATUS_INVALID_PARAMETER, 7, ++ { 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1.2.3.4::5555", STATUS_INVALID_PARAMETER, 7, ++ { 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "11112222:3333:4444:5555:6666:1.2.3.4", STATUS_INVALID_PARAMETER, -1, ++ { -1 } }, ++ { "11112222:3333:4444:5555:6666:7777:8888", STATUS_INVALID_PARAMETER, -1, ++ { -1 } }, ++ { "1111", STATUS_INVALID_PARAMETER, 4, ++ { -1 } }, ++ { "1111:22223333:4444:5555:6666:1.2.3.4", STATUS_INVALID_PARAMETER, -1, ++ { 0x1111, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111:22223333:4444:5555:6666:7777:8888", STATUS_INVALID_PARAMETER, -1, ++ { 0x1111, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:", STATUS_INVALID_PARAMETER, 10, ++ { 0x1111, 0x2222, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:1.2.3.4", STATUS_INVALID_PARAMETER, 17, ++ { 0x1111, 0x2222, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:3333", STATUS_INVALID_PARAMETER, 14, ++ { 0x1111, 0x2222, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111:2222:3333:4444:5555:6666:7777:1.2.3.4", STATUS_SUCCESS, 36, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x100 }, ex_fail_6 }, ++ { "1111:2222:3333:4444:5555:6666:7777:8888:", STATUS_SUCCESS, 39, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, ex_fail_6 }, ++ { "1111:2222:3333:4444:5555:6666:7777:8888:1.2.3.4",STATUS_SUCCESS, 39, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, ex_fail_6 }, ++ { "1111:2222:3333:4444:5555:6666:7777:8888:9999", STATUS_SUCCESS, 39, ++ { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, ex_fail_6 }, ++ { "1111:2222:::", STATUS_SUCCESS, 11, ++ { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, ++ { "1111::5555:", STATUS_INVALID_PARAMETER, 11, ++ { 0x1111, 0x5555, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1111::3333:4444:5555:6666:7777::", STATUS_SUCCESS, 30, ++ { 0x1111, 0, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777 }, ex_fail_6 }, ++ { "1111:2222:::4444:5555:6666:1.2.3.4", STATUS_SUCCESS, 11, ++ { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, ++ { "1111::3333::5555:6666:1.2.3.4", STATUS_SUCCESS, 10, ++ { 0x1111, 0, 0, 0, 0, 0, 0, 0x3333 }, ex_fail_6 }, ++ { "12345::6:7:8", STATUS_INVALID_PARAMETER, -1, ++ { -1 } }, ++ { "1::1.2.256.4", STATUS_INVALID_PARAMETER, -1, ++ { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::1.2.3.256", STATUS_INVALID_PARAMETER, 12, ++ { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::1.2.3.300", STATUS_INVALID_PARAMETER, 12, ++ { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::1.2::1", STATUS_INVALID_PARAMETER, 6, ++ { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::1.2.3.4::1", STATUS_SUCCESS, 10, ++ { 0x100, 0, 0, 0, 0, 0, 0x201, 0x403 }, ex_fail_6 }, ++ { "1::1.", STATUS_INVALID_PARAMETER, 5, ++ { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::1.2", STATUS_INVALID_PARAMETER, 6, ++ { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::1.2.", STATUS_INVALID_PARAMETER, 7, ++ { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::1.2.3", STATUS_INVALID_PARAMETER, 8, ++ { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::1.2.3.", STATUS_INVALID_PARAMETER, 9, ++ { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::1.2.3.4", STATUS_SUCCESS, 10, ++ { 0x100, 0, 0, 0, 0, 0, 0x201, 0x403 } }, ++ { "1::1.2.3.900", STATUS_INVALID_PARAMETER, 12, ++ { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::1.2.300.4", STATUS_INVALID_PARAMETER, -1, ++ { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::1.256.3.4", STATUS_INVALID_PARAMETER, -1, ++ { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::256.2.3.4", STATUS_INVALID_PARAMETER, -1, ++ { 0x100, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "1::2::3", STATUS_SUCCESS, 4, ++ { 0x100, 0, 0, 0, 0, 0, 0, 0x200 }, ex_fail_6 }, ++ { "2001:0000:1234: 0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, 15, ++ { 0x120, 0, 0x3412, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } }, ++ { "2001:0000:1234:0000:0000:C1C0:ABCD:0876 0", STATUS_SUCCESS, 39, ++ { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 }, ex_fail_6 }, ++ { "2001:1:1:1:1:1:255Z255X255Y255", STATUS_INVALID_PARAMETER, 18, ++ { 0x120, 0x100, 0x100, 0x100, 0x100, 0x100, 0xabab, 0xabab } }, ++ { "2001::FFD3::57ab", STATUS_SUCCESS, 10, ++ { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff }, ex_fail_6 }, ++ { ":", STATUS_INVALID_PARAMETER, 0, ++ { -1 } }, ++ { ":1111:2222:3333:4444:5555:6666:1.2.3.4", STATUS_INVALID_PARAMETER, 0, ++ { -1 } }, ++ { ":1111:2222:3333:4444:5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 0, ++ { -1 } }, ++ { ":1111::", STATUS_INVALID_PARAMETER, 0, ++ { -1 } }, ++ { "::-1", STATUS_SUCCESS, 2, ++ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, ++ { "::.", STATUS_SUCCESS, 2, ++ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, ++ { "::..", STATUS_SUCCESS, 2, ++ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, ++ { "::...", STATUS_SUCCESS, 2, ++ { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 }, ++ { "XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:1.2.3.4", STATUS_INVALID_PARAMETER, 0, ++ { -1 } }, ++ { "[::]", STATUS_INVALID_PARAMETER, 0, ++ { -1 }, ex_skip_6 }, ++}; ++const unsigned int ipv6_testcount = sizeof(ipv6_tests) / sizeof(ipv6_tests[0]); ++ ++ ++static void init_ip6(IN6_ADDR* addr, const int src[8]) ++{ ++ unsigned int j; ++ if (!src || src[0] == -1) ++ { ++ for (j = 0; j < 8; ++j) ++ addr->s6_words[j] = 0xabab; ++ } ++ else ++ { ++ for (j = 0; j < 8; ++j) ++ addr->s6_words[j] = src[j]; ++ } ++} ++ ++static void compare_RtlIpv6StringToAddressW(PCSTR name_a, int terminator_offset_a, ++ const struct in6_addr *addr_a, NTSTATUS res_a) ++{ ++ WCHAR name[512]; ++ NTSTATUS res; ++ IN6_ADDR ip; ++ PCWSTR terminator; ++ ++ if (!pRtlIpv6StringToAddressW) ++ return; ++ ++ pRtlMultiByteToUnicodeN(name, sizeof(name), NULL, name_a, strlen(name_a) + 1); ++ ++ init_ip6(&ip, NULL); ++ terminator = (void *)0xdeadbeef; ++ res = pRtlIpv6StringToAddressW(name, &terminator, &ip); ++ ok(res == res_a, "[W:%s] res = 0x%08x, expected 0x%08x\n", name_a, res, res_a); ++ ++ if (terminator_offset_a < 0) ++ { ++ ok(terminator == (void *)0xdeadbeef, ++ "[W:%s] terminator = %p, expected it not to change\n", ++ name_a, terminator); ++ } ++ else ++ { ++ ok(terminator == name + terminator_offset_a, ++ "[W:%s] terminator = %p, expected %p\n", ++ name_a, terminator, name + terminator_offset_a); ++ } ++ ++ ok(!memcmp(&ip, addr_a, sizeof(ip)), ++ "[W:%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n", ++ name_a, ++ ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3], ++ ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7], ++ addr_a->s6_words[0], addr_a->s6_words[1], addr_a->s6_words[2], addr_a->s6_words[3], ++ addr_a->s6_words[4], addr_a->s6_words[5], addr_a->s6_words[6], addr_a->s6_words[7]); ++} ++ ++static void test_RtlIpv6StringToAddress(void) ++{ ++ NTSTATUS res; ++ IN6_ADDR ip, expected_ip; ++ PCSTR terminator; ++ unsigned int i; ++ ++ if (!pRtlIpv6StringToAddressW) ++ { ++ skip("RtlIpv6StringToAddressW not available\n"); ++ /* we can continue, just not test W */ ++ } ++ ++ if (!pRtlIpv6StringToAddressA) ++ { ++ skip("RtlIpv6StringToAddressA not available\n"); ++ return; /* all tests are centered around A, we cannot continue */ ++ } ++ ++ res = pRtlIpv6StringToAddressA("::", &terminator, &ip); ++ ok(res == STATUS_SUCCESS, "[validate] res = 0x%08x, expected STATUS_SUCCESS\n", res); ++ if (0) ++ { ++ /* any of these crash */ ++ res = pRtlIpv6StringToAddressA(NULL, &terminator, &ip); ++ ok(res == STATUS_INVALID_PARAMETER, "[null string] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ++ res = pRtlIpv6StringToAddressA("::", NULL, &ip); ++ ok(res == STATUS_INVALID_PARAMETER, "[null terminator] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ++ res = pRtlIpv6StringToAddressA("::", &terminator, NULL); ++ ok(res == STATUS_INVALID_PARAMETER, "[null result] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ++ } ++ ++ /* sanity check */ ++ ok(sizeof(ip) == sizeof(USHORT)* 8, "sizeof(ip)\n"); ++ ++ for (i = 0; i < ipv6_testcount; i++) ++ { ++ init_ip6(&ip, NULL); ++ terminator = (void *)0xdeadbeef; ++ res = pRtlIpv6StringToAddressA(ipv6_tests[i].address, &terminator, &ip); ++ compare_RtlIpv6StringToAddressW(ipv6_tests[i].address, (terminator != (void *)0xdeadbeef) ? ++ (terminator - ipv6_tests[i].address) : -1, &ip, res); ++ ++ if (ipv6_tests[i].flags & win_broken_6) ++ { ++ ok(res == ipv6_tests[i].res || broken(res == STATUS_INVALID_PARAMETER), ++ "[%s] res = 0x%08x, expected 0x%08x\n", ++ ipv6_tests[i].address, res, ipv6_tests[i].res); ++ ++ if (res == STATUS_INVALID_PARAMETER) ++ continue; ++ } ++ else ++ { ++ ok(res == ipv6_tests[i].res, ++ "[%s] res = 0x%08x, expected 0x%08x\n", ++ ipv6_tests[i].address, res, ipv6_tests[i].res); ++ } ++ ++ if (ipv6_tests[i].terminator_offset < 0) ++ { ++ ok(terminator == (void *)0xdeadbeef, ++ "[%s] terminator = %p, expected it not to change\n", ++ ipv6_tests[i].address, terminator); ++ } ++ else if (ipv6_tests[i].flags & win_broken_6) ++ { ++ PCSTR expected = ipv6_tests[i].address + ipv6_tests[i].terminator_offset; ++ ok(terminator == expected || broken(terminator == expected + 2), ++ "[%s] terminator = %p, expected %p\n", ++ ipv6_tests[i].address, terminator, expected); ++ } ++ else ++ { ++ ok(terminator == ipv6_tests[i].address + ipv6_tests[i].terminator_offset, ++ "[%s] terminator = %p, expected %p\n", ++ ipv6_tests[i].address, terminator, ipv6_tests[i].address + ipv6_tests[i].terminator_offset); ++ } ++ ++ init_ip6(&expected_ip, ipv6_tests[i].ip); ++ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), ++ "[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n", ++ ipv6_tests[i].address, ++ ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3], ++ ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7], ++ expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3], ++ expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]); ++ } ++} ++ + static void test_LdrAddRefDll(void) + { + HMODULE mod, mod2; +@@ -2155,6 +2584,7 @@ START_TEST(rtl) + test_RtlIpv4AddressToString(); + test_RtlIpv4AddressToStringEx(); + test_RtlIpv4StringToAddress(); ++ test_RtlIpv6StringToAddress(); + test_LdrAddRefDll(); + test_LdrLockLoaderLock(); + test_RtlCompressBuffer(); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,333 @@ +From 7b6d523f37901554bfdb17e301dd25e50a899e22 Mon Sep 17 00:00:00 2001 +From: Mark Jansen +Date: Sun, 8 Mar 2015 18:24:50 +0100 +Subject: ntdll/tests: Tests for RtlIpv6StringToAddressEx (try 6) + +Changes from try5: +-Reformat ipv6 table to be less wide +-Remove _s6_un from memcmp calls + +Changes from try4 (all suggestions from stefand in #winehackers): +-Use RtlMultiByteToUnicodeN for A->W conversion +-Fix warning +-Clarify comment / move init_ip6 inside if branch + +Changes from try3: +-Also test the W version against the A version +-Test the ip against the non-ex version as suggested by stefand +-Add more testcases +--- + dlls/ntdll/tests/rtl.c | 269 ++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 268 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c +index 47acfe9..f5bbbb3 100644 +--- a/dlls/ntdll/tests/rtl.c ++++ b/dlls/ntdll/tests/rtl.c +@@ -92,6 +92,8 @@ static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, L + static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *); + static NTSTATUS (WINAPI *pRtlIpv6StringToAddressA)(PCSTR, PCSTR *, struct in6_addr *); + static NTSTATUS (WINAPI *pRtlIpv6StringToAddressW)(PCWSTR, PCWSTR *, struct in6_addr *); ++static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExA)(PCSTR, struct in6_addr *, PULONG, PUSHORT); ++static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExW)(PCWSTR, struct in6_addr *, PULONG, PUSHORT); + static NTSTATUS (WINAPI *pLdrAddRefDll)(ULONG, HMODULE); + static NTSTATUS (WINAPI *pLdrLockLoaderLock)(ULONG, ULONG*, ULONG_PTR*); + static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG_PTR); +@@ -146,6 +148,8 @@ static void InitFunctionPtrs(void) + pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA"); + pRtlIpv6StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressA"); + pRtlIpv6StringToAddressW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressW"); ++ pRtlIpv6StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExA"); ++ pRtlIpv6StringToAddressExW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExW"); + pLdrAddRefDll = (void *)GetProcAddress(hntdll, "LdrAddRefDll"); + pLdrLockLoaderLock = (void *)GetProcAddress(hntdll, "LdrLockLoaderLock"); + pLdrUnlockLoaderLock = (void *)GetProcAddress(hntdll, "LdrUnlockLoaderLock"); +@@ -1783,7 +1787,6 @@ static const struct + }; + const unsigned int ipv6_testcount = sizeof(ipv6_tests) / sizeof(ipv6_tests[0]); + +- + static void init_ip6(IN6_ADDR* addr, const int src[8]) + { + unsigned int j; +@@ -1929,6 +1932,269 @@ static void test_RtlIpv6StringToAddress(void) + } + } + ++static void compare_RtlIpv6StringToAddressExW(PCSTR name_a, const struct in6_addr *addr_a, HRESULT res_a, ULONG scope_a, USHORT port_a) ++{ ++ WCHAR name[512]; ++ NTSTATUS res; ++ IN6_ADDR ip; ++ ULONG scope = 0xbadf00d; ++ USHORT port = 0xbeef; ++ ++ if (!pRtlIpv6StringToAddressExW) ++ return; ++ ++ pRtlMultiByteToUnicodeN(name, sizeof(name), NULL, name_a, strlen(name_a) + 1); ++ ++ init_ip6(&ip, NULL); ++ res = pRtlIpv6StringToAddressExW(name, &ip, &scope, &port); ++ ++ ok(res == res_a, "[W:%s] res = 0x%08x, expected 0x%08x\n", name_a, res, res_a); ++ ok(scope == scope_a, "[W:%s] scope = 0x%08x, expected 0x%08x\n", name_a, scope, scope_a); ++ ok(port == port_a, "[W:%s] port = 0x%08x, expected 0x%08x\n", name_a, port, port_a); ++ ++ ok(!memcmp(&ip, addr_a, sizeof(ip)), ++ "[W:%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n", ++ name_a, ++ ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3], ++ ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7], ++ addr_a->s6_words[0], addr_a->s6_words[1], addr_a->s6_words[2], addr_a->s6_words[3], ++ addr_a->s6_words[4], addr_a->s6_words[5], addr_a->s6_words[6], addr_a->s6_words[7]); ++} ++ ++static void test_RtlIpv6StringToAddressEx(void) ++{ ++ NTSTATUS res; ++ IN6_ADDR ip, expected_ip; ++ ULONG scope; ++ USHORT port; ++ static const struct ++ { ++ PCSTR address; ++ NTSTATUS res; ++ ULONG scope; ++ USHORT port; ++ int ip[8]; ++ } ipv6_ex_tests[] = ++ { ++ { "[::]", STATUS_SUCCESS, 0, 0, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "[::1]:8080", STATUS_SUCCESS, 0, 0x901f, ++ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "[::1]:0x80", STATUS_SUCCESS, 0, 0x8000, ++ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "[::1]:0X80", STATUS_SUCCESS, 0, 0x8000, ++ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "[::1]:080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "[::1]:800000000080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80", STATUS_SUCCESS, 0, 0x5000, ++ { 0xdcfe, 0x98ba, 0x5476, 0x1032, 0xdcfe, 0x98ba, 0x5476, 0x1032 } }, ++ { "[1080:0:0:0:8:800:200C:417A]:1234", STATUS_SUCCESS, 0, 0xd204, ++ { 0x8010, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[3ffe:2a00:100:7031::1]:8080", STATUS_SUCCESS, 0, 0x901f, ++ { 0xfe3f, 0x2a, 1, 0x3170, 0, 0, 0, 0x100 } }, ++ { "[ 3ffe:2a00:100:7031::1]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { -1 } }, ++ { "[3ffe:2a00:100:7031::1 ]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0xfe3f, 0x2a, 1, 0x3170, 0, 0, 0, 0x100 } }, ++ { "[3ffe:2a00:100:7031::1].8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0xfe3f, 0x2a, 1, 0x3170, 0, 0, 0, 0x100 } }, ++ { "[1080::8:800:200C:417A]:8080", STATUS_SUCCESS, 0, 0x901f, ++ { 0x8010, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[1080::8:800:200C:417A]!8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0x8010, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[::FFFF:129.144.52.38]:80", STATUS_SUCCESS, 0, 0x5000, ++ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, ++ { "[::FFFF:129.144.52.38]:-80", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, ++ { "[::FFFF:129.144.52.38]:999999999999", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, ++ { "[::FFFF:129.144.52.38%-8]:80", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, ++ { "[::FFFF:129.144.52.38]:80", STATUS_SUCCESS, 0, 0x5000, ++ { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, ++ { "[12345::6:7:8]:80", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { -1 } }, ++ { "[ff01::8:800:200C:417A%16]:8080", STATUS_SUCCESS, 16, 0x901f, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[ff01::8:800:200C:417A%100]:8080", STATUS_SUCCESS, 100, 0x901f, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[ff01::8:800:200C:417A%1000]:8080", STATUS_SUCCESS, 1000, 0x901f, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[ff01::8:800:200C:417A%10000]:8080", STATUS_SUCCESS, 10000, 0x901f, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[ff01::8:800:200C:417A%1000000]:8080", STATUS_SUCCESS, 1000000, 0x901f, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[ff01::8:800:200C:417A%4294967295]:8080", STATUS_SUCCESS, 0xffffffff, 0x901f, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[ff01::8:800:200C:417A%4294967296]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[ff01::8:800:200C:417A%-1]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[ff01::8:800:200C:417A%0]:8080", STATUS_SUCCESS, 0, 0x901f, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[ff01::8:800:200C:417A%1", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[ff01::8:800:200C:417A%0x1000]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ { "[ff01::8:800:200C:417A/16]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef, ++ { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } }, ++ }; ++ const unsigned int ipv6_ex_testcount = sizeof(ipv6_ex_tests) / sizeof(ipv6_ex_tests[0]); ++ const char *simple_ip = "::"; ++ unsigned int i; ++ ++ if (!pRtlIpv6StringToAddressExW) ++ { ++ skip("RtlIpv6StringToAddressExW not available\n"); ++ /* we can continue, just not test W */ ++ } ++ ++ if (!pRtlIpv6StringToAddressExA) ++ { ++ skip("RtlIpv6StringToAddressExA not available\n"); ++ return; ++ } ++ ++ res = pRtlIpv6StringToAddressExA(simple_ip, &ip, &scope, &port); ++ ok(res == STATUS_SUCCESS, "[validate] res = 0x%08x, expected STATUS_SUCCESS\n", res); ++ ++ init_ip6(&ip, NULL); ++ init_ip6(&expected_ip, NULL); ++ scope = 0xbadf00d; ++ port = 0xbeef; ++ res = pRtlIpv6StringToAddressExA(NULL, &ip, &scope, &port); ++ ok(res == STATUS_INVALID_PARAMETER, ++ "[null string] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ++ ok(scope == 0xbadf00d, "[null string] scope = 0x%08x, expected 0xbadf00d\n", scope); ++ ok(port == 0xbeef, "[null string] port = 0x%08x, expected 0xbeef\n", port); ++ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), ++ "[null string] ip is changed, expected it not to change\n"); ++ ++ ++ init_ip6(&ip, NULL); ++ scope = 0xbadf00d; ++ port = 0xbeef; ++ res = pRtlIpv6StringToAddressExA(simple_ip, NULL, &scope, &port); ++ ok(res == STATUS_INVALID_PARAMETER, ++ "[null result] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ++ ok(scope == 0xbadf00d, "[null result] scope = 0x%08x, expected 0xbadf00d\n", scope); ++ ok(port == 0xbeef, "[null result] port = 0x%08x, expected 0xbeef\n", port); ++ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), ++ "[null result] ip is changed, expected it not to change\n"); ++ ++ init_ip6(&ip, NULL); ++ scope = 0xbadf00d; ++ port = 0xbeef; ++ res = pRtlIpv6StringToAddressExA(simple_ip, &ip, NULL, &port); ++ ok(res == STATUS_INVALID_PARAMETER, ++ "[null scope] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ++ ok(scope == 0xbadf00d, "[null scope] scope = 0x%08x, expected 0xbadf00d\n", scope); ++ ok(port == 0xbeef, "[null scope] port = 0x%08x, expected 0xbeef\n", port); ++ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), ++ "[null scope] ip is changed, expected it not to change\n"); ++ ++ init_ip6(&ip, NULL); ++ scope = 0xbadf00d; ++ port = 0xbeef; ++ res = pRtlIpv6StringToAddressExA(simple_ip, &ip, &scope, NULL); ++ ok(res == STATUS_INVALID_PARAMETER, ++ "[null port] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ++ ok(scope == 0xbadf00d, "[null port] scope = 0x%08x, expected 0xbadf00d\n", scope); ++ ok(port == 0xbeef, "[null port] port = 0x%08x, expected 0xbeef\n", port); ++ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), ++ "[null port] ip is changed, expected it not to change\n"); ++ ++ /* sanity check */ ++ ok(sizeof(ip) == sizeof(USHORT)* 8, "sizeof(ip)\n"); ++ ++ /* first we run all ip related tests, to make sure someone didnt accidentally reimplement instead of re-use. */ ++ for (i = 0; i < ipv6_testcount; i++) ++ { ++ ULONG scope = 0xbadf00d; ++ USHORT port = 0xbeef; ++ NTSTATUS expect_ret = (ipv6_tests[i].flags & ex_fail_6) ? STATUS_INVALID_PARAMETER : ipv6_tests[i].res; ++ ++ if (ipv6_tests[i].flags & ex_skip_6) ++ continue; ++ ++ init_ip6(&ip, NULL); ++ res = pRtlIpv6StringToAddressExA(ipv6_tests[i].address, &ip, &scope, &port); ++ compare_RtlIpv6StringToAddressExW(ipv6_tests[i].address, &ip, res, scope, port); ++ ++ /* make sure nothing was changed if this function fails. */ ++ if (res == STATUS_INVALID_PARAMETER) ++ { ++ ok(scope == 0xbadf00d, "[%s] scope = 0x%08x, expected 0xbadf00d\n", ++ ipv6_tests[i].address, scope); ++ ok(port == 0xbeef, "[%s] port = 0x%08x, expected 0xbeef\n", ++ ipv6_tests[i].address, port); ++ } ++ else ++ { ++ ok(scope != 0xbadf00d, "[%s] scope = 0x%08x, not expected 0xbadf00d\n", ++ ipv6_tests[i].address, scope); ++ ok(port != 0xbeef, "[%s] port = 0x%08x, not expected 0xbeef\n", ++ ipv6_tests[i].address, port); ++ } ++ ++ if (ipv6_tests[i].flags & win_broken_6) ++ { ++ ok(res == expect_ret || broken(res == STATUS_INVALID_PARAMETER), ++ "[%s] res = 0x%08x, expected 0x%08x\n", ipv6_tests[i].address, res, expect_ret); ++ ++ if (res == STATUS_INVALID_PARAMETER) ++ continue; ++ } ++ else ++ { ++ ok(res == expect_ret, "[%s] res = 0x%08x, expected 0x%08x\n", ++ ipv6_tests[i].address, res, expect_ret); ++ } ++ ++ /* If ex fails but non-ex does not we cannot check if the part that is converted ++ before it failed was correct, since there is no data for it in the table. */ ++ if (res == expect_ret) ++ { ++ init_ip6(&expected_ip, ipv6_tests[i].ip); ++ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), ++ "[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n", ++ ipv6_tests[i].address, ++ ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3], ++ ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7], ++ expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3], ++ expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]); ++ } ++ } ++ ++ /* now we run scope / port related tests */ ++ for (i = 0; i < ipv6_ex_testcount; i++) ++ { ++ scope = 0xbadf00d; ++ port = 0xbeef; ++ init_ip6(&ip, NULL); ++ res = pRtlIpv6StringToAddressExA(ipv6_ex_tests[i].address, &ip, &scope, &port); ++ compare_RtlIpv6StringToAddressExW(ipv6_ex_tests[i].address, &ip, res, scope, port); ++ ++ ok(res == ipv6_ex_tests[i].res, "[%s] res = 0x%08x, expected 0x%08x\n", ++ ipv6_ex_tests[i].address, res, ipv6_ex_tests[i].res); ++ ok(scope == ipv6_ex_tests[i].scope, "[%s] scope = 0x%08x, expected 0x%08x\n", ++ ipv6_ex_tests[i].address, scope, ipv6_ex_tests[i].scope); ++ ok(port == ipv6_ex_tests[i].port, "[%s] port = 0x%08x, expected 0x%08x\n", ++ ipv6_ex_tests[i].address, port, ipv6_ex_tests[i].port); ++ ++ init_ip6(&expected_ip, ipv6_ex_tests[i].ip); ++ ok(!memcmp(&ip, &expected_ip, sizeof(ip)), ++ "[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n", ++ ipv6_ex_tests[i].address, ++ ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3], ++ ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7], ++ expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3], ++ expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]); ++ } ++} ++ + static void test_LdrAddRefDll(void) + { + HMODULE mod, mod2; +@@ -2616,6 +2882,7 @@ START_TEST(rtl) + test_RtlIpv4AddressToStringEx(); + test_RtlIpv4StringToAddress(); + test_RtlIpv6StringToAddress(); ++ test_RtlIpv6StringToAddressEx(); + test_LdrAddRefDll(); + test_LdrLockLoaderLock(); + test_RtlCompressBuffer(); +-- +2.4.5 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0003-ntdll-tests-Tests-for-RtlIpv4StringToAddressEx-try-5.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0003-ntdll-tests-Tests-for-RtlIpv4StringToAddressEx-try-5.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0003-ntdll-tests-Tests-for-RtlIpv4StringToAddressEx-try-5.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0003-ntdll-tests-Tests-for-RtlIpv4StringToAddressEx-try-5.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,456 @@ +From a2f2703bd49023e395090c6ed8b7b6d2e7722680 Mon Sep 17 00:00:00 2001 +From: Mark Jansen +Date: Sun, 8 Mar 2015 18:24:48 +0100 +Subject: ntdll/tests: Tests for RtlIpv4StringToAddressEx (try 5, resend) + +Changes from try4: +-Remove leftover comments + +Changes from try3: +-Test the ip against the non-ex version as suggested by stefand +-Change strict_is_different to a flag +-Add ipv4 init function to avoid code duplication +--- + dlls/ntdll/tests/rtl.c | 371 ++++++++++++++++++++++++++++++++----------------- + 1 file changed, 247 insertions(+), 124 deletions(-) + +diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c +index 5d789d1..79c4974 100644 +--- a/dlls/ntdll/tests/rtl.c ++++ b/dlls/ntdll/tests/rtl.c +@@ -90,6 +90,7 @@ static IMAGE_BASE_RELOCATION *(WINAPI *pLdrProcessRelocationBlock)(void*,UINT,US + static CHAR * (WINAPI *pRtlIpv4AddressToStringA)(const IN_ADDR *, LPSTR); + static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG); + static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *); ++static NTSTATUS (WINAPI *pRtlIpv4StringToAddressExA)(PCSTR, BOOLEAN, IN_ADDR *, PUSHORT); + static NTSTATUS (WINAPI *pRtlIpv6StringToAddressA)(PCSTR, PCSTR *, struct in6_addr *); + static NTSTATUS (WINAPI *pRtlIpv6StringToAddressW)(PCWSTR, PCWSTR *, struct in6_addr *); + static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExA)(PCSTR, struct in6_addr *, PULONG, PUSHORT); +@@ -142,6 +143,7 @@ static void InitFunctionPtrs(void) + pRtlIpv4AddressToStringA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringA"); + pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA"); + pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA"); ++ pRtlIpv4StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressExA"); + pRtlIpv6StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressA"); + pRtlIpv6StringToAddressW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressW"); + pRtlIpv6StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExA"); +@@ -1331,98 +1333,109 @@ static void test_RtlIpv4AddressToStringEx(void) + res, size, buffer); + } + ++static struct ++{ ++ PCSTR address; ++ NTSTATUS res; ++ int terminator_offset; ++ int ip[4]; ++ enum { normal_4, strict_diff_4 = 1, ex_fail_4 = 2 } flags; ++ NTSTATUS res_strict; ++ int terminator_offset_strict; ++ int ip_strict[4]; ++} ipv4_tests[] = ++{ ++ { "", STATUS_INVALID_PARAMETER, 0, { -1 } }, ++ { " ", STATUS_INVALID_PARAMETER, 0, { -1 } }, ++ { "1.1.1.1", STATUS_SUCCESS, 7, { 1, 1, 1, 1 } }, ++ { "0.0.0.0", STATUS_SUCCESS, 7, { 0, 0, 0, 0 } }, ++ { "255.255.255.255", STATUS_SUCCESS, 15, { 255, 255, 255, 255 } }, ++ { "255.255.255.255:123", STATUS_SUCCESS, 15, { 255, 255, 255, 255 } }, ++ { "255.255.255.256", STATUS_INVALID_PARAMETER, 15, { -1 } }, ++ { "255.255.255.4294967295", STATUS_INVALID_PARAMETER, 22, { -1 } }, ++ { "255.255.255.4294967296", STATUS_INVALID_PARAMETER, 21, { -1 } }, ++ { "255.255.255.4294967297", STATUS_INVALID_PARAMETER, 21, { -1 } }, ++ { "a", STATUS_INVALID_PARAMETER, 0, { -1 } }, ++ { "1.1.1.0xaA", STATUS_SUCCESS, 10, { 1, 1, 1, 170 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 8, { -1 } }, ++ { "1.1.1.0XaA", STATUS_SUCCESS, 10, { 1, 1, 1, 170 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 8, { -1 } }, ++ { "1.1.1.0x", STATUS_INVALID_PARAMETER, 8, { -1 } }, ++ { "1.1.1.0xff", STATUS_SUCCESS, 10, { 1, 1, 1, 255 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 8, { -1 } }, ++ { "1.1.1.0x100", STATUS_INVALID_PARAMETER, 11, { -1 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 8, { -1 } }, ++ { "1.1.1.0xffffffff", STATUS_INVALID_PARAMETER, 16, { -1 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 8, { -1 } }, ++ { "1.1.1.0x100000000", STATUS_INVALID_PARAMETER, 16, { -1, 0, 0, 0 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 8, { -1 } }, ++ { "1.1.1.010", STATUS_SUCCESS, 9, { 1, 1, 1, 8 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 7, { -1 } }, ++ { "1.1.1.00", STATUS_SUCCESS, 8, { 1, 1, 1, 0 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 7, { -1 } }, ++ { "1.1.1.007", STATUS_SUCCESS, 9, { 1, 1, 1, 7 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 7, { -1 } }, ++ { "1.1.1.08", STATUS_INVALID_PARAMETER, 7, { -1 } }, ++ { "1.1.1.008", STATUS_SUCCESS, 8, { 1, 1, 1, 0 }, strict_diff_4 | ex_fail_4, ++ STATUS_INVALID_PARAMETER, 7, { -1 } }, ++ { "1.1.1.0a", STATUS_SUCCESS, 7, { 1, 1, 1, 0 }, ex_fail_4 }, ++ { "1.1.1.0o10", STATUS_SUCCESS, 7, { 1, 1, 1, 0 }, ex_fail_4 }, ++ { "1.1.1.0b10", STATUS_SUCCESS, 7, { 1, 1, 1, 0 }, ex_fail_4 }, ++ { "1.1.1.-2", STATUS_INVALID_PARAMETER, 6, { -1 } }, ++ { "1", STATUS_SUCCESS, 1, { 0, 0, 0, 1 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 1, { -1 } }, ++ { "-1", STATUS_INVALID_PARAMETER, 0, { -1 } }, ++ { "203569230", STATUS_SUCCESS, 9, { 12, 34, 56, 78 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 9, { -1 } }, ++ { "1.223756", STATUS_SUCCESS, 8, { 1, 3, 106, 12 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 8, { -1 } }, ++ { "3.4.756", STATUS_SUCCESS, 7, { 3, 4, 2, 244 }, strict_diff_4, ++ STATUS_INVALID_PARAMETER, 7, { -1 } }, ++ { "3.4.756.1", STATUS_INVALID_PARAMETER, 9, { -1 } }, ++ { "3.4.65536", STATUS_INVALID_PARAMETER, 9, { -1 } }, ++ { "3.4.5.6.7", STATUS_INVALID_PARAMETER, 7, { -1 } }, ++ { "3.4.5.+6", STATUS_INVALID_PARAMETER, 6, { -1 } }, ++ { " 3.4.5.6", STATUS_INVALID_PARAMETER, 0, { -1 } }, ++ { "\t3.4.5.6", STATUS_INVALID_PARAMETER, 0, { -1 } }, ++ { "3.4.5.6 ", STATUS_SUCCESS, 7, { 3, 4, 5, 6 }, ex_fail_4 }, ++ { "3. 4.5.6", STATUS_INVALID_PARAMETER, 2, { -1 } }, ++ { ".", STATUS_INVALID_PARAMETER, 1, { -1 } }, ++ { "..", STATUS_INVALID_PARAMETER, 1, { -1 } }, ++ { "1.", STATUS_INVALID_PARAMETER, 2, { -1 } }, ++ { "1..", STATUS_INVALID_PARAMETER, 3, { -1 } }, ++ { ".1", STATUS_INVALID_PARAMETER, 1, { -1 } }, ++ { ".1.", STATUS_INVALID_PARAMETER, 1, { -1 } }, ++ { ".1.2.3", STATUS_INVALID_PARAMETER, 1, { -1 } }, ++ { "0.1.2.3", STATUS_SUCCESS, 7, { 0, 1, 2, 3 } }, ++ { "0.1.2.3.", STATUS_INVALID_PARAMETER, 7, { -1 } }, ++ { "[0.1.2.3]", STATUS_INVALID_PARAMETER, 0, { -1 } }, ++ { "::1", STATUS_INVALID_PARAMETER, 0, { -1 } }, ++ { ":1", STATUS_INVALID_PARAMETER, 0, { -1 } }, ++}; ++const unsigned int ipv4_testcount = sizeof(ipv4_tests) / sizeof(ipv4_tests[0]); ++ ++static void init_ip4(IN_ADDR* addr, const int src[4]) ++{ ++ if (!src || src[0] == -1) ++ { ++ addr->S_un.S_addr = 0xabababab; ++ } ++ else ++ { ++ addr->S_un.S_un_b.s_b1 = src[0]; ++ addr->S_un.S_un_b.s_b2 = src[1]; ++ addr->S_un.S_un_b.s_b3 = src[2]; ++ addr->S_un.S_un_b.s_b4 = src[3]; ++ } ++} ++ + static void test_RtlIpv4StringToAddress(void) + { + NTSTATUS res; + IN_ADDR ip, expected_ip; + PCSTR terminator; + CHAR dummy; +- struct +- { +- PCSTR address; +- NTSTATUS res; +- int terminator_offset; +- int ip[4]; +- BOOL strict_is_different; +- NTSTATUS res_strict; +- int terminator_offset_strict; +- int ip_strict[4]; +- } tests[] = +- { +- { "", STATUS_INVALID_PARAMETER, 0, { -1 } }, +- { " ", STATUS_INVALID_PARAMETER, 0, { -1 } }, +- { "1.1.1.1", STATUS_SUCCESS, 7, { 1, 1, 1, 1 } }, +- { "0.0.0.0", STATUS_SUCCESS, 7, { 0, 0, 0, 0 } }, +- { "255.255.255.255", STATUS_SUCCESS, 15, { 255, 255, 255, 255 } }, +- { "255.255.255.255:123", +- STATUS_SUCCESS, 15, { 255, 255, 255, 255 } }, +- { "255.255.255.256", STATUS_INVALID_PARAMETER, 15, { -1 } }, +- { "255.255.255.4294967295", +- STATUS_INVALID_PARAMETER, 22, { -1 } }, +- { "255.255.255.4294967296", +- STATUS_INVALID_PARAMETER, 21, { -1 } }, +- { "255.255.255.4294967297", +- STATUS_INVALID_PARAMETER, 21, { -1 } }, +- { "a", STATUS_INVALID_PARAMETER, 0, { -1 } }, +- { "1.1.1.0xaA", STATUS_SUCCESS, 10, { 1, 1, 1, 170 }, +- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, +- { "1.1.1.0XaA", STATUS_SUCCESS, 10, { 1, 1, 1, 170 }, +- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, +- { "1.1.1.0x", STATUS_INVALID_PARAMETER, 8, { -1 } }, +- { "1.1.1.0xff", STATUS_SUCCESS, 10, { 1, 1, 1, 255 }, +- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, +- { "1.1.1.0x100", STATUS_INVALID_PARAMETER, 11, { -1 }, +- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, +- { "1.1.1.0xffffffff",STATUS_INVALID_PARAMETER, 16, { -1 }, +- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, +- { "1.1.1.0x100000000", +- STATUS_INVALID_PARAMETER, 16, { -1, 0, 0, 0 }, +- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, +- { "1.1.1.010", STATUS_SUCCESS, 9, { 1, 1, 1, 8 }, +- TRUE, STATUS_INVALID_PARAMETER, 7, { -1 } }, +- { "1.1.1.00", STATUS_SUCCESS, 8, { 1, 1, 1, 0 }, +- TRUE, STATUS_INVALID_PARAMETER, 7, { -1 } }, +- { "1.1.1.007", STATUS_SUCCESS, 9, { 1, 1, 1, 7 }, +- TRUE, STATUS_INVALID_PARAMETER, 7, { -1 } }, +- { "1.1.1.08", STATUS_INVALID_PARAMETER, 7, { -1 } }, +- { "1.1.1.008", STATUS_SUCCESS, 8, { 1, 1, 1, 0 }, +- TRUE, STATUS_INVALID_PARAMETER, 7, { -1 } }, +- { "1.1.1.0a", STATUS_SUCCESS, 7, { 1, 1, 1, 0 } }, +- { "1.1.1.0o10", STATUS_SUCCESS, 7, { 1, 1, 1, 0 } }, +- { "1.1.1.0b10", STATUS_SUCCESS, 7, { 1, 1, 1, 0 } }, +- { "1.1.1.-2", STATUS_INVALID_PARAMETER, 6, { -1 } }, +- { "1", STATUS_SUCCESS, 1, { 0, 0, 0, 1 }, +- TRUE, STATUS_INVALID_PARAMETER, 1, { -1 } }, +- { "-1", STATUS_INVALID_PARAMETER, 0, { -1 } }, +- { "203569230", STATUS_SUCCESS, 9, { 12, 34, 56, 78 }, +- TRUE, STATUS_INVALID_PARAMETER, 9, { -1 } }, +- { "1.223756", STATUS_SUCCESS, 8, { 1, 3, 106, 12 }, +- TRUE, STATUS_INVALID_PARAMETER, 8, { -1 } }, +- { "3.4.756", STATUS_SUCCESS, 7, { 3, 4, 2, 244 }, +- TRUE, STATUS_INVALID_PARAMETER, 7, { -1 } }, +- { "3.4.756.1", STATUS_INVALID_PARAMETER, 9, { -1 } }, +- { "3.4.65536", STATUS_INVALID_PARAMETER, 9, { -1 } }, +- { "3.4.5.6.7", STATUS_INVALID_PARAMETER, 7, { -1 } }, +- { "3.4.5.+6", STATUS_INVALID_PARAMETER, 6, { -1 } }, +- { " 3.4.5.6", STATUS_INVALID_PARAMETER, 0, { -1 } }, +- { "\t3.4.5.6", STATUS_INVALID_PARAMETER, 0, { -1 } }, +- { "3.4.5.6 ", STATUS_SUCCESS, 7, { 3, 4, 5, 6 } }, +- { "3. 4.5.6", STATUS_INVALID_PARAMETER, 2, { -1 } }, +- { ".", STATUS_INVALID_PARAMETER, 1, { -1 } }, +- { "..", STATUS_INVALID_PARAMETER, 1, { -1 } }, +- { "1.", STATUS_INVALID_PARAMETER, 2, { -1 } }, +- { "1..", STATUS_INVALID_PARAMETER, 3, { -1 } }, +- { ".1", STATUS_INVALID_PARAMETER, 1, { -1 } }, +- { ".1.", STATUS_INVALID_PARAMETER, 1, { -1 } }, +- { ".1.2.3", STATUS_INVALID_PARAMETER, 1, { -1 } }, +- { "0.1.2.3", STATUS_SUCCESS, 7, { 0, 1, 2, 3 } }, +- { "0.1.2.3.", STATUS_INVALID_PARAMETER, 7, { -1 } }, +- { "[0.1.2.3]", STATUS_INVALID_PARAMETER, 0, { -1 } }, +- { "::1", STATUS_INVALID_PARAMETER, 0, { -1 } }, +- { ":1", STATUS_INVALID_PARAMETER, 0, { -1 } }, +- }; +- const int testcount = sizeof(tests) / sizeof(tests[0]); +- int i; ++ unsigned int i; + + if (!pRtlIpv4StringToAddressA) + { +@@ -1444,65 +1457,174 @@ static void test_RtlIpv4StringToAddress(void) + */ + } + +- for (i = 0; i < testcount; i++) ++ for (i = 0; i < ipv4_testcount; i++) + { + /* non-strict */ + terminator = &dummy; + ip.S_un.S_addr = 0xabababab; +- res = pRtlIpv4StringToAddressA(tests[i].address, FALSE, &terminator, &ip); +- ok(res == tests[i].res, ++ res = pRtlIpv4StringToAddressA(ipv4_tests[i].address, FALSE, &terminator, &ip); ++ ok(res == ipv4_tests[i].res, + "[%s] res = 0x%08x, expected 0x%08x\n", +- tests[i].address, res, tests[i].res); +- ok(terminator == tests[i].address + tests[i].terminator_offset, ++ ipv4_tests[i].address, res, ipv4_tests[i].res); ++ ok(terminator == ipv4_tests[i].address + ipv4_tests[i].terminator_offset, + "[%s] terminator = %p, expected %p\n", +- tests[i].address, terminator, tests[i].address + tests[i].terminator_offset); +- if (tests[i].ip[0] == -1) +- expected_ip.S_un.S_addr = 0xabababab; +- else +- { +- expected_ip.S_un.S_un_b.s_b1 = tests[i].ip[0]; +- expected_ip.S_un.S_un_b.s_b2 = tests[i].ip[1]; +- expected_ip.S_un.S_un_b.s_b3 = tests[i].ip[2]; +- expected_ip.S_un.S_un_b.s_b4 = tests[i].ip[3]; +- } ++ ipv4_tests[i].address, terminator, ipv4_tests[i].address + ipv4_tests[i].terminator_offset); ++ ++ init_ip4(&expected_ip, ipv4_tests[i].ip); + ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, + "[%s] ip = %08x, expected %08x\n", +- tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); ++ ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); + +- if (!tests[i].strict_is_different) ++ if (!(ipv4_tests[i].flags & strict_diff_4)) + { +- tests[i].res_strict = tests[i].res; +- tests[i].terminator_offset_strict = tests[i].terminator_offset; +- tests[i].ip_strict[0] = tests[i].ip[0]; +- tests[i].ip_strict[1] = tests[i].ip[1]; +- tests[i].ip_strict[2] = tests[i].ip[2]; +- tests[i].ip_strict[3] = tests[i].ip[3]; ++ ipv4_tests[i].res_strict = ipv4_tests[i].res; ++ ipv4_tests[i].terminator_offset_strict = ipv4_tests[i].terminator_offset; ++ ipv4_tests[i].ip_strict[0] = ipv4_tests[i].ip[0]; ++ ipv4_tests[i].ip_strict[1] = ipv4_tests[i].ip[1]; ++ ipv4_tests[i].ip_strict[2] = ipv4_tests[i].ip[2]; ++ ipv4_tests[i].ip_strict[3] = ipv4_tests[i].ip[3]; + } + /* strict */ + terminator = &dummy; + ip.S_un.S_addr = 0xabababab; +- res = pRtlIpv4StringToAddressA(tests[i].address, TRUE, &terminator, &ip); +- ok(res == tests[i].res_strict, ++ res = pRtlIpv4StringToAddressA(ipv4_tests[i].address, TRUE, &terminator, &ip); ++ ok(res == ipv4_tests[i].res_strict, + "[%s] res = 0x%08x, expected 0x%08x\n", +- tests[i].address, res, tests[i].res_strict); +- ok(terminator == tests[i].address + tests[i].terminator_offset_strict, ++ ipv4_tests[i].address, res, ipv4_tests[i].res_strict); ++ ok(terminator == ipv4_tests[i].address + ipv4_tests[i].terminator_offset_strict, + "[%s] terminator = %p, expected %p\n", +- tests[i].address, terminator, tests[i].address + tests[i].terminator_offset_strict); +- if (tests[i].ip_strict[0] == -1) +- expected_ip.S_un.S_addr = 0xabababab; +- else +- { +- expected_ip.S_un.S_un_b.s_b1 = tests[i].ip_strict[0]; +- expected_ip.S_un.S_un_b.s_b2 = tests[i].ip_strict[1]; +- expected_ip.S_un.S_un_b.s_b3 = tests[i].ip_strict[2]; +- expected_ip.S_un.S_un_b.s_b4 = tests[i].ip_strict[3]; +- } ++ ipv4_tests[i].address, terminator, ipv4_tests[i].address + ipv4_tests[i].terminator_offset_strict); ++ ++ init_ip4(&expected_ip, ipv4_tests[i].ip_strict); + ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, + "[%s] ip = %08x, expected %08x\n", +- tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); ++ ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); + } + } + ++static void test_RtlIpv4StringToAddressEx(void) ++{ ++ NTSTATUS res; ++ IN_ADDR ip, expected_ip; ++ USHORT port; ++ static const struct ++ { ++ PCSTR address; ++ NTSTATUS res; ++ int ip[4]; ++ USHORT port; ++ } ipv4_ex_tests[] = ++ { ++ { "", STATUS_INVALID_PARAMETER, { -1 }, 0xdead }, ++ { " ", STATUS_INVALID_PARAMETER, { -1 }, 0xdead }, ++ { "1.1.1.1:", STATUS_INVALID_PARAMETER, { 1, 1, 1, 1 }, 0xdead }, ++ { "1.1.1.1+", STATUS_INVALID_PARAMETER, { 1, 1, 1, 1 }, 0xdead }, ++ { "1.1.1.1:1", STATUS_SUCCESS, { 1, 1, 1, 1 }, 0x100 }, ++ { "256.1.1.1:1", STATUS_INVALID_PARAMETER, { -1 }, 0xdead }, ++ { "-1.1.1.1:1", STATUS_INVALID_PARAMETER, { -1 }, 0xdead }, ++ { "0.0.0.0:0", STATUS_INVALID_PARAMETER, { 0, 0, 0, 0 }, 0xdead }, ++ { "0.0.0.0:1", STATUS_SUCCESS, { 0, 0, 0, 0 }, 0x100 }, ++ { "1.2.3.4:65535", STATUS_SUCCESS, { 1, 2, 3, 4 }, 65535 }, ++ { "1.2.3.4:65536", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead }, ++ { "1.2.3.4:0xffff", STATUS_SUCCESS, { 1, 2, 3, 4 }, 65535 }, ++ { "1.2.3.4:0XfFfF", STATUS_SUCCESS, { 1, 2, 3, 4 }, 65535 }, ++ { "1.2.3.4:011064", STATUS_SUCCESS, { 1, 2, 3, 4 }, 0x3412 }, ++ { "1.2.3.4:1234a", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead }, ++ { "1.2.3.4:1234+", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead }, ++ { "1.2.3.4: 1234", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead }, ++ { "1.2.3.4:\t1234", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead }, ++ }; ++ const unsigned int ipv4_ex_testcount = sizeof(ipv4_ex_tests) / sizeof(ipv4_ex_tests[0]); ++ unsigned int i; ++ BOOLEAN strict; ++ ++ if (!pRtlIpv4StringToAddressExA) ++ { ++ skip("RtlIpv4StringToAddressEx not available\n"); ++ return; ++ } ++ ++ /* do not crash, and do not touch the ip / port. */ ++ ip.S_un.S_addr = 0xabababab; ++ port = 0xdead; ++ res = pRtlIpv4StringToAddressExA(NULL, FALSE, &ip, &port); ++ ok(res == STATUS_INVALID_PARAMETER, "[null address] res = 0x%08x, expected 0x%08x\n", ++ res, STATUS_INVALID_PARAMETER); ++ ok(ip.S_un.S_addr == 0xabababab, "RtlIpv4StringToAddressExA should not touch the ip!, ip == %x\n", ip.S_un.S_addr); ++ ok(port == 0xdead, "RtlIpv4StringToAddressExA should not touch the port!, port == %x\n", port); ++ ++ port = 0xdead; ++ res = pRtlIpv4StringToAddressExA("1.1.1.1", FALSE, NULL, &port); ++ ok(res == STATUS_INVALID_PARAMETER, "[null ip] res = 0x%08x, expected 0x%08x\n", ++ res, STATUS_INVALID_PARAMETER); ++ ok(port == 0xdead, "RtlIpv4StringToAddressExA should not touch the port!, port == %x\n", port); ++ ++ ip.S_un.S_addr = 0xabababab; ++ port = 0xdead; ++ res = pRtlIpv4StringToAddressExA("1.1.1.1", FALSE, &ip, NULL); ++ ok(res == STATUS_INVALID_PARAMETER, "[null port] res = 0x%08x, expected 0x%08x\n", ++ res, STATUS_INVALID_PARAMETER); ++ ok(ip.S_un.S_addr == 0xabababab, "RtlIpv4StringToAddressExA should not touch the ip!, ip == %x\n", ip.S_un.S_addr); ++ ok(port == 0xdead, "RtlIpv4StringToAddressExA should not touch the port!, port == %x\n", port); ++ ++ /* first we run the non-ex testcases on the ex function */ ++ for (i = 0; i < ipv4_testcount; i++) ++ { ++ NTSTATUS expect_res = (ipv4_tests[i].flags & ex_fail_4) ? STATUS_INVALID_PARAMETER : ipv4_tests[i].res; ++ ++ /* non-strict */ ++ port = 0xdead; ++ ip.S_un.S_addr = 0xabababab; ++ res = pRtlIpv4StringToAddressExA(ipv4_tests[i].address, FALSE, &ip, &port); ++ ok(res == expect_res, "[%s] res = 0x%08x, expected 0x%08x\n", ++ ipv4_tests[i].address, res, expect_res); ++ ++ init_ip4(&expected_ip, ipv4_tests[i].ip); ++ ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, "[%s] ip = %08x, expected %08x\n", ++ ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); ++ ++ if (!(ipv4_tests[i].flags & strict_diff_4)) ++ { ++ ipv4_tests[i].res_strict = ipv4_tests[i].res; ++ ipv4_tests[i].terminator_offset_strict = ipv4_tests[i].terminator_offset; ++ ipv4_tests[i].ip_strict[0] = ipv4_tests[i].ip[0]; ++ ipv4_tests[i].ip_strict[1] = ipv4_tests[i].ip[1]; ++ ipv4_tests[i].ip_strict[2] = ipv4_tests[i].ip[2]; ++ ipv4_tests[i].ip_strict[3] = ipv4_tests[i].ip[3]; ++ } ++ /* strict */ ++ expect_res = (ipv4_tests[i].flags & ex_fail_4) ? STATUS_INVALID_PARAMETER : ipv4_tests[i].res_strict; ++ port = 0xdead; ++ ip.S_un.S_addr = 0xabababab; ++ res = pRtlIpv4StringToAddressExA(ipv4_tests[i].address, TRUE, &ip, &port); ++ ok(res == expect_res, "[%s] res = 0x%08x, expected 0x%08x\n", ++ ipv4_tests[i].address, res, expect_res); ++ ++ init_ip4(&expected_ip, ipv4_tests[i].ip_strict); ++ ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, "[%s] ip = %08x, expected %08x\n", ++ ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); ++ } ++ ++ ++ for (i = 0; i < ipv4_ex_testcount; i++) ++ { ++ /* Strict is only relevant for the ip address, so make sure that it does not influence the port */ ++ for (strict = 0; strict < 2; strict++) ++ { ++ ip.S_un.S_addr = 0xabababab; ++ port = 0xdead; ++ res = pRtlIpv4StringToAddressExA(ipv4_ex_tests[i].address, strict, &ip, &port); ++ ok(res == ipv4_ex_tests[i].res, "[%s] res = 0x%08x, expected 0x%08x\n", ++ ipv4_ex_tests[i].address, res, ipv4_ex_tests[i].res); ++ ++ init_ip4(&expected_ip, ipv4_ex_tests[i].ip); ++ ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, "[%s] ip = %08x, expected %08x\n", ++ ipv4_ex_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr); ++ ok(port == ipv4_ex_tests[i].port, "[%s] port = %u, expected %u\n", ++ ipv4_ex_tests[i].address, port, ipv4_ex_tests[i].port); ++ } ++ } ++} + + /* ipv6 addresses based on the set from https://github.com/beaugunderson/javascript-ipv6/tree/master/test/data */ + static const struct +@@ -2318,6 +2440,7 @@ START_TEST(rtl) + test_RtlIpv4AddressToString(); + test_RtlIpv4AddressToStringEx(); + test_RtlIpv4StringToAddress(); ++ test_RtlIpv4StringToAddressEx(); + test_RtlIpv6StringToAddress(); + test_RtlIpv6StringToAddressEx(); + test_LdrAddRefDll(); +-- +2.3.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0004-ntdll-tests-Add-tests-for-RtlIpv6AddressToString-and.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0004-ntdll-tests-Add-tests-for-RtlIpv6AddressToString-and.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0004-ntdll-tests-Add-tests-for-RtlIpv6AddressToString-and.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/0004-ntdll-tests-Add-tests-for-RtlIpv6AddressToString-and.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,291 @@ +From 569439573a4b64588331359269f90a32f0d93b9c Mon Sep 17 00:00:00 2001 +From: Mark Jansen +Date: Mon, 6 Apr 2015 00:48:33 +0200 +Subject: ntdll/tests: Add tests for RtlIpv6AddressToString and + RtlIpv6AddressToStringEx. + +--- + dlls/ntdll/tests/rtl.c | 246 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 246 insertions(+) + +diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c +index 6d41589..37f74b5 100644 +--- a/dlls/ntdll/tests/rtl.c ++++ b/dlls/ntdll/tests/rtl.c +@@ -91,6 +91,8 @@ static CHAR * (WINAPI *pRtlIpv4AddressToStringA)(const IN_ADDR *, LPSTR); + static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG); + static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *); + static NTSTATUS (WINAPI *pRtlIpv4StringToAddressExA)(PCSTR, BOOLEAN, IN_ADDR *, PUSHORT); ++static CHAR * (WINAPI *pRtlIpv6AddressToStringA)(struct in6_addr *, PSTR); ++static NTSTATUS (WINAPI *pRtlIpv6AddressToStringExA)(struct in6_addr *, ULONG, USHORT, PCHAR, PULONG); + static NTSTATUS (WINAPI *pRtlIpv6StringToAddressA)(PCSTR, PCSTR *, struct in6_addr *); + static NTSTATUS (WINAPI *pRtlIpv6StringToAddressW)(PCWSTR, PCWSTR *, struct in6_addr *); + static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExA)(PCSTR, struct in6_addr *, PULONG, PUSHORT); +@@ -148,6 +150,8 @@ static void InitFunctionPtrs(void) + pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA"); + pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA"); + pRtlIpv4StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressExA"); ++ pRtlIpv6AddressToStringA = (void *)GetProcAddress(hntdll, "RtlIpv6AddressToStringA"); ++ pRtlIpv6AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv6AddressToStringExA"); + pRtlIpv6StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressA"); + pRtlIpv6StringToAddressW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressW"); + pRtlIpv6StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExA"); +@@ -1924,6 +1928,246 @@ static void init_ip6(IN6_ADDR* addr, const int src[8]) + } + } + ++static void test_RtlIpv6AddressToString(void) ++{ ++ CHAR buffer[50]; ++ LPCSTR result; ++ IN6_ADDR ip; ++ DWORD_PTR len; ++ struct ++ { ++ PCSTR address; ++ int ip[8]; ++ } tests[] = ++ { ++ /* ipv4 addresses & ISATAP addresses */ ++ { "::13.1.68.3", { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, ++ { "::ffff:13.1.68.3", { 0, 0, 0, 0, 0, 0xffff, 0x10d, 0x344 } }, ++ { "::feff:d01:4403", { 0, 0, 0, 0, 0, 0xfffe, 0x10d, 0x344 } }, ++ { "::fffe:d01:4403", { 0, 0, 0, 0, 0, 0xfeff, 0x10d, 0x344 } }, ++ { "::100:d01:4403", { 0, 0, 0, 0, 0, 1, 0x10d, 0x344 } }, ++ { "::1:d01:4403", { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, ++ { "::ffff:0:4403", { 0, 0, 0, 0, 0, 0xffff, 0, 0x344 } }, ++ { "::ffff:13.1.0.0", { 0, 0, 0, 0, 0, 0xffff, 0x10d, 0 } }, ++ { "::ffff:0:0", { 0, 0, 0, 0, 0, 0xffff, 0, 0 } }, ++ { "::ffff:0:13.1.68.3", { 0, 0, 0, 0, 0xffff, 0, 0x10d, 0x344 } }, ++ { "::ffff:ffff:d01:4403", { 0, 0, 0, 0, 0xffff, 0xffff, 0x10d, 0x344 } }, ++ { "::ffff:0:0:d01:4403", { 0, 0, 0, 0xffff, 0, 0, 0x10d, 0x344 } }, ++ { "::ffff:255.255.255.255", { 0, 0, 0, 0, 0, 0xffff, 0xffff, 0xffff } }, ++ { "::ffff:129.144.52.38", { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, ++ { "::5efe:129.144.52.38", { 0, 0, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, ++ { "1111:2222:3333:4444:0:5efe:129.144.52.38", { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, ++ { "1111:2222:3333::5efe:129.144.52.38", { 0x1111, 0x2222, 0x3333, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, ++ { "1111:2222::5efe:129.144.52.38", { 0x1111, 0x2222, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, ++ { "1111::5efe:129.144.52.38", { 0x1111, 0, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, ++ { "::200:5efe:129.144.52.38", { 0, 0, 0, 0, 2, 0xfe5e, 0x9081, 0x2634 } }, ++ { "::100:5efe:8190:3426", { 0, 0, 0, 0, 1, 0xfe5e, 0x9081, 0x2634 } }, ++ /* 'normal' addresses */ ++ { "::1", { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "0:1:2:3:4:5:6:7", { 0, 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700 } }, ++ { "1080::8:800:200c:417a", { 0x8010, 0, 0, 0, 0x800, 0x8, 0x0c20, 0x7a41 } }, ++ { "1111:2222:3333:4444:5555:6666:7b7b:7b7b", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111:2222:3333:4444:5555:6666:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, ++ { "1111:2222:3333:4444:5555:6666::", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0 } }, ++ { "1111:2222:3333:4444:5555:6666:0:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0x8888 } }, ++ { "1111:2222:3333:4444:5555::", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0 } }, ++ { "1111:2222:3333:4444:5555:0:7b7b:7b7b", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7b7b, 0x7b7b } }, ++ { "1111:2222:3333:4444:5555:0:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7777, 0x8888 } }, ++ { "1111:2222:3333:4444:5555::8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8888 } }, ++ { "1111::", { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "1111::7b7b:7b7b", { 0x1111, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } }, ++ { "1111:0:3333:4444:5555:6666:7b7b:7b7b", { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111:0:3333:4444:5555:6666:7777:8888", { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, ++ { "1111::4444:5555:6666:7b7b:7b7b", { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111::4444:5555:6666:7777:8888", { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, ++ { "1111::5555:6666:7b7b:7b7b", { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111::5555:6666:7777:8888", { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7777, 0x8888 } }, ++ { "1111::6666:7b7b:7b7b", { 0x1111, 0, 0, 0, 0, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111::6666:7777:8888", { 0x1111, 0, 0, 0, 0, 0x6666, 0x7777, 0x8888 } }, ++ { "1111::7777:8888", { 0x1111, 0, 0, 0, 0, 0, 0x7777, 0x8888 } }, ++ { "1111::8888", { 0x1111, 0, 0, 0, 0, 0, 0, 0x8888 } }, ++ { "1:2:3:4:5:6:102:304", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x201, 0x403 } }, ++ { "1:2:3:4:5:6:7:8", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800 } }, ++ { "1:2:3:4:5:6::", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0 } }, ++ { "1:2:3:4:5:6:0:8", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0x800 } }, ++ { "2001:0:1234::c1c0:abcd:876", { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 } }, ++ { "2001:0:4136:e378:8000:63bf:3fff:fdd2", { 0x120, 0, 0x3641, 0x78e3, 0x80, 0xbf63, 0xff3f, 0xd2fd } }, ++ { "2001:db8::1428:57ab", { 0x120, 0xb80d, 0, 0, 0, 0, 0x2814, 0xab57 } }, ++ { "2001:db8:1234:ffff:ffff:ffff:ffff:ffff", { 0x120, 0xb80d, 0x3412, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } }, ++ { "2001:0:ce49:7601:2cad:dfff:7c94:fffe", { 0x120, 0, 0x49ce, 0x176, 0xad2c, 0xffdf, 0x947c, 0xfeff } }, ++ { "2001:db8:85a3::8a2e:370:7334", { 0x120, 0xb80d, 0xa385, 0, 0, 0x2e8a, 0x7003, 0x3473 } }, ++ { "3ffe:b00::1:0:0:a", { 0xfe3f, 0xb, 0, 0, 0x100, 0, 0, 0xa00 } }, ++ { "::a:b:c:d:e", { 0, 0, 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00 } }, ++ { "::123.123.123.123", { 0, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } }, ++ { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } }, ++ { "1111:2222:3333:4444:5555:6666:7777:1", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x100 } }, ++ { "1111:2222:3333:4444:5555:6666:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, ++ { "1111:2222::", { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 } }, ++ { "1111::3333:4444:5555:6666:7777", { 0x1111, 0, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777 } }, ++ { "1111:2222::", { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 } }, ++ { "1111::3333", { 0x1111, 0, 0, 0, 0, 0, 0, 0x3333 } }, ++ { "2001:0:1234::c1c0:abcd:876", { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 } }, ++ { "2001::ffd3", { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, ++ }; ++ const size_t testcount = sizeof(tests) / sizeof(tests[0]); ++ unsigned int i; ++ ++ if (!pRtlIpv6AddressToStringA) ++ { ++ skip("RtlIpv6AddressToStringA not available\n"); ++ return; ++ } ++ ++ memset(buffer, '#', sizeof(buffer)); ++ buffer[sizeof(buffer)-1] = 0; ++ memset(&ip, 0, sizeof(ip)); ++ result = pRtlIpv6AddressToStringA(&ip, buffer); ++ ++ len = strlen(buffer); ++ ok(result == (buffer + len) && !strcmp(buffer, "::"), ++ "got %p with '%s' (expected %p with '::')\n", result, buffer, buffer + len); ++ ++ result = pRtlIpv6AddressToStringA(&ip, NULL); ++ ok(result == (LPCSTR)~0 || broken(result == (LPCSTR)len) /* WinXP / Win2k3 */, ++ "got %p, expected %p\n", result, (LPCSTR)~0); ++ ++ for (i = 0; i < testcount; i++) ++ { ++ init_ip6(&ip, tests[i].ip); ++ memset(buffer, '#', sizeof(buffer)); ++ buffer[sizeof(buffer)-1] = 0; ++ ++ result = pRtlIpv6AddressToStringA(&ip, buffer); ++ len = strlen(buffer); ++ ok(result == (buffer + len) && !strcmp(buffer, tests[i].address), ++ "got %p with '%s' (expected %p with '%s')\n", result, buffer, buffer + len, tests[i].address); ++ ++ ok(buffer[45] == 0 || broken(buffer[45] != 0) /* WinXP / Win2k3 */, ++ "expected data at buffer[45] to always be NULL\n"); ++ ok(buffer[46] == '#', "expected data at buffer[46] not to change\n"); ++ } ++} ++ ++static void test_RtlIpv6AddressToStringEx(void) ++{ ++ CHAR buffer[70]; ++ NTSTATUS res; ++ IN6_ADDR ip; ++ ULONG len; ++ struct ++ { ++ PCSTR address; ++ ULONG scopeid; ++ USHORT port; ++ int ip[8]; ++ } tests[] = ++ { ++ /* ipv4 addresses & ISATAP addresses */ ++ { "::13.1.68.3", 0, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, ++ { "::13.1.68.3%1", 1, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, ++ { "::13.1.68.3%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, ++ { "[::13.1.68.3%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, ++ { "[::13.1.68.3%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, ++ { "[::13.1.68.3]:256", 0, 1, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, ++ ++ { "::1:d01:4403", 0, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, ++ { "::1:d01:4403%1", 1, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, ++ { "::1:d01:4403%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, ++ { "[::1:d01:4403%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, ++ { "[::1:d01:4403%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, ++ { "[::1:d01:4403]:256", 0, 1, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, ++ ++ { "1111:2222:3333:4444:0:5efe:129.144.52.38", 0, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, ++ { "1111:2222:3333:4444:0:5efe:129.144.52.38%1", 1, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, ++ { "1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819", 0xffffbbbb, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, ++ { "[1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819]:65518",0xffffbbbb, 0xeeff, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, ++ { "[1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, ++ { "[1111:2222:3333:4444:0:5efe:129.144.52.38]:256", 0, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, ++ ++ { "::1", 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "::1%1", 1, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "::1%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "[::1%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "[::1%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ { "[::1]:256", 0, 1, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, ++ ++ { "1111:2222:3333:4444:5555:6666:7b7b:7b7b", 0, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111:2222:3333:4444:5555:6666:7b7b:7b7b%1", 1, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "1111:2222:3333:4444:5555:6666:7b7b:7b7b%4294949819", 0xffffbbbb, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "[1111:2222:3333:4444:5555:6666:7b7b:7b7b%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "[1111:2222:3333:4444:5555:6666:7b7b:7b7b%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ { "[1111:2222:3333:4444:5555:6666:7b7b:7b7b]:256", 0, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, ++ ++ { "1111::", 0, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "1111::%1", 1, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "1111::%4294949819", 0xffffbbbb, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "[1111::%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "[1111::%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, ++ { "[1111::]:256", 0, 1, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, ++ ++ { "2001::ffd3", 0, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, ++ { "2001::ffd3%1", 1, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, ++ { "2001::ffd3%4294949819", 0xffffbbbb, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, ++ { "[2001::ffd3%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, ++ { "[2001::ffd3%4294949819]:256", 0xffffbbbb, 1, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, ++ { "[2001::ffd3]:256", 0, 1, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, ++ }; ++ const size_t testcount = sizeof(tests) / sizeof(tests[0]); ++ unsigned int i; ++ ++ if (!pRtlIpv6AddressToStringExA) ++ { ++ skip("RtlIpv6AddressToStringExA not available\n"); ++ return; ++ } ++ ++ memset(buffer, '#', sizeof(buffer)); ++ buffer[sizeof(buffer)-1] = 0; ++ memset(&ip, 0, sizeof(ip)); ++ len = sizeof(buffer); ++ res = pRtlIpv6AddressToStringExA(&ip, 0, 0, buffer, &len); ++ ++ ok(res == STATUS_SUCCESS, "[validate] res = 0x%08x, expected STATUS_SUCCESS\n", res); ++ ok(len == 3 && !strcmp(buffer, "::"), ++ "got len %d with '%s' (expected 3 with '::')\n", len, buffer); ++ ++ memset(buffer, '#', sizeof(buffer)); ++ buffer[sizeof(buffer)-1] = 0; ++ ++ len = sizeof(buffer); ++ res = pRtlIpv6AddressToStringExA(NULL, 0, 0, buffer, &len); ++ ok(res == STATUS_INVALID_PARAMETER, "[null ip] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ++ ++ len = sizeof(buffer); ++ res = pRtlIpv6AddressToStringExA(&ip, 0, 0, NULL, &len); ++ ok(res == STATUS_INVALID_PARAMETER, "[null buffer] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ++ ++ res = pRtlIpv6AddressToStringExA(&ip, 0, 0, buffer, NULL); ++ ok(res == STATUS_INVALID_PARAMETER, "[null length] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ++ ++ len = 2; ++ memset(buffer, '#', sizeof(buffer)); ++ buffer[sizeof(buffer)-1] = 0; ++ res = pRtlIpv6AddressToStringExA(&ip, 0, 0, buffer, &len); ++ ok(res == STATUS_INVALID_PARAMETER, "[null length] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ++ ok(buffer[0] == '#', "got first char %c (expected '#')\n", buffer[0]); ++ ok(len == 3, "got len %d (expected len 3)\n", len); ++ ++ for (i = 0; i < testcount; i++) ++ { ++ init_ip6(&ip, tests[i].ip); ++ len = sizeof(buffer); ++ memset(buffer, '#', sizeof(buffer)); ++ buffer[sizeof(buffer)-1] = 0; ++ ++ res = pRtlIpv6AddressToStringExA(&ip, tests[i].scopeid, tests[i].port, buffer, &len); ++ ++ ok(res == STATUS_SUCCESS, "[validate] res = 0x%08x, expected STATUS_SUCCESS\n", res); ++ ok(len == (strlen(tests[i].address) + 1) && !strcmp(buffer, tests[i].address), ++ "got len %d with '%s' (expected %d with '%s')\n", len, buffer, strlen(tests[i].address), tests[i].address); ++ } ++} ++ + static void compare_RtlIpv6StringToAddressW(PCSTR name_a, int terminator_offset_a, + const struct in6_addr *addr_a, NTSTATUS res_a) + { +@@ -3173,6 +3417,8 @@ START_TEST(rtl) + test_RtlIpv4AddressToStringEx(); + test_RtlIpv4StringToAddress(); + test_RtlIpv4StringToAddressEx(); ++ test_RtlIpv6AddressToString(); ++ test_RtlIpv6AddressToStringEx(); + test_RtlIpv6StringToAddress(); + test_RtlIpv6StringToAddressEx(); + test_LdrAddRefDll(); +-- +2.3.5 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlIpStringToAddress_Tests/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,2 @@ +Category: stable +Depends: ntdll-RtlQueryPackageIdentity diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0001-ntdll-Add-stub-for-RtlQueryPackageIdentity.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0001-ntdll-Add-stub-for-RtlQueryPackageIdentity.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0001-ntdll-Add-stub-for-RtlQueryPackageIdentity.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0001-ntdll-Add-stub-for-RtlQueryPackageIdentity.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,43 @@ +From 3fad7f8640f1600a00896f82056423303e4cc3e0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 00:48:11 +0100 +Subject: ntdll: Add stub for RtlQueryPackageIdentity. + +--- + dlls/ntdll/ntdll.spec | 1 + + dlls/ntdll/rtl.c | 10 ++++++++++ + 2 files changed, 11 insertions(+) + +diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec +index 4e49709..fee2e11 100644 +--- a/dlls/ntdll/ntdll.spec ++++ b/dlls/ntdll/ntdll.spec +@@ -799,6 +799,7 @@ + @ stdcall RtlQueryInformationActivationContext(long long ptr long ptr long ptr) + @ stub RtlQueryInformationActiveActivationContext + @ stub RtlQueryInterfaceMemoryStream ++@ stdcall RtlQueryPackageIdentity(long ptr ptr ptr ptr ptr) + @ stub RtlQueryProcessBackTraceInformation + @ stdcall RtlQueryProcessDebugInformation(long long ptr) + @ stub RtlQueryProcessHeapInformation +diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c +index f699cff..37dce23 100644 +--- a/dlls/ntdll/rtl.c ++++ b/dlls/ntdll/rtl.c +@@ -1626,3 +1626,13 @@ NTSTATUS WINAPI RtlCreateUserProcess(UNICODE_STRING *path, ULONG attributes, RTL + parent, inherit, debug, exception, info); + return STATUS_NOT_IMPLEMENTED; + } ++ ++/********************************************************************* ++ * RtlQueryPackageIdentity [NTDLL.@] ++ */ ++NTSTATUS WINAPI RtlQueryPackageIdentity(HANDLE token, WCHAR *fullname, SIZE_T *fullname_size, ++ WCHAR *appid, SIZE_T *appid_size, BOOLEAN *packaged) ++{ ++ FIXME("(%p, %p, %p, %p, %p, %p): stub\n", token, fullname, fullname_size, appid, appid_size, packaged); ++ return STATUS_NOT_FOUND; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0002-include-Add-IApplicationActivationManager-interface-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0002-include-Add-IApplicationActivationManager-interface-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0002-include-Add-IApplicationActivationManager-interface-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0002-include-Add-IApplicationActivationManager-interface-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,64 @@ +From 730defc94816ecb8e67f79f4bbee7cf31bedfec1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 00:46:34 +0100 +Subject: include: Add IApplicationActivationManager interface declaration. + +--- + include/shobjidl.idl | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/include/shobjidl.idl b/include/shobjidl.idl +index 1cc6132..cf9b8b3 100644 +--- a/include/shobjidl.idl ++++ b/include/shobjidl.idl +@@ -3639,6 +3639,34 @@ typedef enum ASSOC_FILTER + } ASSOC_FILTER; + cpp_quote("HRESULT WINAPI SHAssocEnumHandlers(PCWSTR extra, ASSOC_FILTER filter, IEnumAssocHandlers **handlersenum);") + ++typedef [v1_enum] enum ACTIVATEOPTIONS ++{ ++ AO_NONE = 0x00000000, ++ AO_DESIGNMODE = 0x00000001, ++ AO_NOERRORUI = 0x00000002, ++ AO_NOSPLASHSCREEN = 0x00000004 ++} ACTIVATEOPTIONS; ++ ++[ ++ uuid(2e941141-7f97-4756-ba1d-9decde894a3d), ++ object, ++ pointer_default(unique) ++] ++interface IApplicationActivationManager : IUnknown ++{ ++ HRESULT ActivateApplication([in] LPCWSTR appusermodelid, ++ [in, unique] LPCWSTR arguments, ++ [in] ACTIVATEOPTIONS options, ++ [out] DWORD *processid); ++ HRESULT ActivateForFile([in] LPCWSTR appusermodelid, ++ [in] IShellItemArray *itemarray, ++ [in, unique] LPCWSTR verb, ++ [out] DWORD *processid); ++ HRESULT ActivateForProtocol([in] LPCWSTR appusermodelid, ++ [in] IShellItemArray *itemarray, ++ [out] DWORD *processid); ++} ++ + /***************************************************************************** + * ShellObjects typelibrary + */ +@@ -3735,4 +3763,12 @@ library ShellObjects + { + interface IQueryCancelAutoPlay; + } ++ ++ [ ++ uuid(45ba127d-10a8-46ea-8ab7-56ea9078943c) ++ ] ++ coclass ApplicationActivationManager ++ { ++ interface IApplicationActivationManager; ++ } + } +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0003-ntdll-tests-Add-basic-tests-for-RtlQueryPackageIdent.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0003-ntdll-tests-Add-basic-tests-for-RtlQueryPackageIdent.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0003-ntdll-tests-Add-basic-tests-for-RtlQueryPackageIdent.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/0003-ntdll-tests-Add-basic-tests-for-RtlQueryPackageIdent.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,137 @@ +From 12db1d30697314446ae03aaed86a1a57efa786da Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 00:50:50 +0100 +Subject: ntdll/tests: Add basic tests for RtlQueryPackageIdentity. + +--- + dlls/ntdll/tests/Makefile.in | 2 +- + dlls/ntdll/tests/rtl.c | 76 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 77 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntdll/tests/Makefile.in b/dlls/ntdll/tests/Makefile.in +index fc352dd..0de4fe8 100644 +--- a/dlls/ntdll/tests/Makefile.in ++++ b/dlls/ntdll/tests/Makefile.in +@@ -1,5 +1,5 @@ + TESTDLL = ntdll.dll +-IMPORTS = user32 ++IMPORTS = user32 ole32 advapi32 + + C_SRCS = \ + atom.c \ +diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c +index 94a22ac..ac463c6 100644 +--- a/dlls/ntdll/tests/rtl.c ++++ b/dlls/ntdll/tests/rtl.c +@@ -25,6 +25,9 @@ + + #include "ntdll_test.h" + #include "inaddr.h" ++#include "initguid.h" ++#define COBJMACROS ++#include "shobjidl.h" + + #ifndef __WINE_WINTERNL_H + +@@ -98,6 +101,7 @@ static NTSTATUS (WINAPI *pRtlDecompressFragment)(USHORT, PUCHAR, ULONG, const U + static NTSTATUS (WINAPI *pRtlCompressBuffer)(USHORT, const UCHAR*, ULONG, PUCHAR, ULONG, ULONG, PULONG, PVOID); + static BOOL (WINAPI *pRtlIsCriticalSectionLocked)(CRITICAL_SECTION *); + static BOOL (WINAPI *pRtlIsCriticalSectionLockedByThread)(CRITICAL_SECTION *); ++static NTSTATUS (WINAPI *pRtlQueryPackageIdentity)(HANDLE, WCHAR*, SIZE_T*, WCHAR*, SIZE_T*, BOOLEAN*); + + static HMODULE hkernel32 = 0; + static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); +@@ -151,6 +155,7 @@ static void InitFunctionPtrs(void) + pRtlCompressBuffer = (void *)GetProcAddress(hntdll, "RtlCompressBuffer"); + pRtlIsCriticalSectionLocked = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLocked"); + pRtlIsCriticalSectionLockedByThread = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLockedByThread"); ++ pRtlQueryPackageIdentity = (void *)GetProcAddress(hntdll, "RtlQueryPackageIdentity"); + } + hkernel32 = LoadLibraryA("kernel32.dll"); + ok(hkernel32 != 0, "LoadLibrary failed\n"); +@@ -2056,6 +2061,76 @@ static void test_RtlIsCriticalSectionLocked(void) + DeleteCriticalSection(&info.crit); + } + ++static void test_RtlQueryPackageIdentity(void) ++{ ++ const WCHAR programW[] = {'M','i','c','r','o','s','o','f','t','.','W','i','n','d','o','w','s','.', ++ 'P','h','o','t','o','s','_','8','w','e','k','y','b','3','d','8','b','b','w','e','!','A','p','p',0}; ++ const WCHAR fullnameW[] = {'M','i','c','r','o','s','o','f','t','.','W','i','n','d','o','w','s','.', ++ 'P','h','o','t','o','s', 0}; ++ const WCHAR appidW[] = {'A','p','p',0}; ++ IApplicationActivationManager *manager; ++ WCHAR buf1[MAX_PATH], buf2[MAX_PATH]; ++ HANDLE process, token; ++ SIZE_T size1, size2; ++ NTSTATUS status; ++ DWORD processid; ++ HRESULT hr; ++ BOOL ret; ++ ++ if (!pRtlQueryPackageIdentity) ++ { ++ win_skip("RtlQueryPackageIdentity not available\n"); ++ return; ++ } ++ ++ size1 = size2 = MAX_PATH * sizeof(WCHAR); ++ status = pRtlQueryPackageIdentity((HANDLE)~(ULONG_PTR)3, buf1, &size1, buf2, &size2, NULL); ++ ok(status == STATUS_NOT_FOUND, "expected STATUS_NOT_FOUND, got %08x\n", status); ++ ++ CoInitializeEx(0, COINIT_APARTMENTTHREADED); ++ hr = CoCreateInstance(&CLSID_ApplicationActivationManager, NULL, CLSCTX_LOCAL_SERVER, ++ &IID_IApplicationActivationManager, (void **)&manager); ++ if (FAILED(hr)) ++ { ++ todo_wine win_skip("Failed to create ApplicationActivationManager (%x)\n", hr); ++ goto done; ++ } ++ ++ hr = IApplicationActivationManager_ActivateApplication(manager, programW, NULL, ++ AO_NOERRORUI, &processid); ++ if (FAILED(hr)) ++ { ++ todo_wine win_skip("Failed to start program (%x)\n", hr); ++ IApplicationActivationManager_Release(manager); ++ goto done; ++ } ++ ++ process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE, FALSE, processid); ++ ok(process != NULL, "OpenProcess failed with %u\n", GetLastError()); ++ ret = OpenProcessToken(process, TOKEN_QUERY, &token); ++ ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); ++ ++ size1 = size2 = MAX_PATH * sizeof(WCHAR); ++ status = pRtlQueryPackageIdentity(token, buf1, &size1, buf2, &size2, NULL); ++ ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ++ ++ ok(!memcmp(buf1, fullnameW, sizeof(fullnameW) - sizeof(WCHAR)), ++ "Expected buf1 to begin with %s, got %s\n", wine_dbgstr_w(fullnameW), wine_dbgstr_w(buf1)); ++ ok(size1 >= sizeof(WCHAR) && !(size1 % sizeof(WCHAR)), "Unexpected size1 = %lu\n", size1); ++ ok(buf1[size1 / sizeof(WCHAR) - 1] == 0, "Expected buf1[%lu] == 0\n", size1 / sizeof(WCHAR) - 1); ++ ++ ok(!lstrcmpW(buf2, appidW), "Expected buf2 to be %s, got %s\n", wine_dbgstr_w(appidW), wine_dbgstr_w(buf2)); ++ ok(size2 >= sizeof(WCHAR) && !(size2 % sizeof(WCHAR)), "Unexpected size2 = %lu\n", size2); ++ ok(buf2[size2 / sizeof(WCHAR) - 1] == 0, "Expected buf2[%lu] == 0\n", size2 / sizeof(WCHAR) - 1); ++ ++ CloseHandle(token); ++ TerminateProcess(process, 0); ++ CloseHandle(process); ++ ++done: ++ CoUninitialize(); ++} ++ + START_TEST(rtl) + { + InitFunctionPtrs(); +@@ -2086,4 +2161,5 @@ START_TEST(rtl) + test_RtlGetCompressionWorkSpaceSize(); + test_RtlDecompressBuffer(); + test_RtlIsCriticalSectionLocked(); ++ test_RtlQueryPackageIdentity(); + } +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-RtlQueryPackageIdentity/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Add stub for ntdll.RtlQueryPackageIdentity diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Serial_Port_Detection/0001-ntdll-Do-a-device-check-before-returning-a-default-s.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Serial_Port_Detection/0001-ntdll-Do-a-device-check-before-returning-a-default-s.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Serial_Port_Detection/0001-ntdll-Do-a-device-check-before-returning-a-default-s.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Serial_Port_Detection/0001-ntdll-Do-a-device-check-before-returning-a-default-s.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,66 @@ +From 9e643b1eb9f0050b72e17665fcc803756184637d Mon Sep 17 00:00:00 2001 +From: Alex Henrie +Date: Tue, 29 Dec 2015 00:48:02 -0700 +Subject: ntdll: Do a device check before returning a default serial port name. + +Fixes https://bugs.winehq.org/show_bug.cgi?id=39793 + +Signed-off-by: Alex Henrie +--- + dlls/ntdll/directory.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c +index f3c6aa2..046f1b9 100644 +--- a/dlls/ntdll/directory.c ++++ b/dlls/ntdll/directory.c +@@ -83,6 +83,9 @@ + #ifdef HAVE_SYS_STATFS_H + #include + #endif ++#ifdef HAVE_TERMIOS_H ++# include ++#endif + #include + #ifdef HAVE_UNISTD_H + # include +@@ -321,6 +324,24 @@ static void flush_dir_queue(void) + } + } + ++#ifdef linux ++/* Serial port device files almost always exist on Linux even if the corresponding serial ++ * ports don't exist. Do a basic functionality check before advertising a serial port. */ ++static BOOL is_serial_device( const char *unix_name ) ++{ ++ struct termios tios; ++ BOOL ret = FALSE; ++ int fd; ++ ++ if ((fd = open( unix_name, O_RDONLY )) != -1) ++ { ++ ret = tcgetattr( fd, &tios ) != -1; ++ close( fd ); ++ } ++ ++ return ret; ++} ++#endif + + /*********************************************************************** + * get_default_com_device +@@ -336,6 +357,11 @@ static char *get_default_com_device( int num ) + ret = RtlAllocateHeap( GetProcessHeap(), 0, sizeof("/dev/ttyS256") ); + if (!ret) return NULL; + sprintf( ret, "/dev/ttyS%d", num - 1 ); ++ if (!is_serial_device( ret )) ++ { ++ RtlFreeHeap( GetProcessHeap(), 0, ret ); ++ ret = NULL; ++ } + #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + ret = RtlAllocateHeap( GetProcessHeap(), 0, sizeof("/dev/cuau256") ); + if (!ret) return NULL; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Serial_Port_Detection/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Serial_Port_Detection/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Serial_Port_Detection/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Serial_Port_Detection/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [39793] Do a device check before returning a default serial port name diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Syscall_Wrappers/0002-ntdll-Use-wrapper-functions-for-syscalls.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Syscall_Wrappers/0002-ntdll-Use-wrapper-functions-for-syscalls.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Syscall_Wrappers/0002-ntdll-Use-wrapper-functions-for-syscalls.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Syscall_Wrappers/0002-ntdll-Use-wrapper-functions-for-syscalls.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 1a0efd8b70bcf35e4e12326ba77bfd93b4bf0367 Mon Sep 17 00:00:00 2001 +From 2ea2d12561993dba7a8b042bdac894c9967d0c85 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 16 Oct 2015 02:32:58 +0200 Subject: ntdll: Use wrapper functions for syscalls. @@ -81,10 +81,10 @@ { NTSTATUS status; diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c -index 4faafe9..770cd3f 100644 +index 04c8e26..e4b7069 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c -@@ -2236,7 +2236,8 @@ done: +@@ -2210,7 +2210,8 @@ done: * NtQueryDirectoryFile [NTDLL.@] * ZwQueryDirectoryFile [NTDLL.@] */ @@ -141,10 +141,10 @@ HARDERROR_RESPONSE_OPTION ResponseOption, PHARDERROR_RESPONSE Response ) { diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 1027b54..1cde19c 100644 +index 43b74b2..2e24079 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c -@@ -298,7 +298,8 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT +@@ -296,7 +296,8 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT * Success: 0. FileHandle and IoStatusBlock are updated. * Failure: An NTSTATUS error code describing the error. */ @@ -154,7 +154,7 @@ POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK io, ULONG sharing, ULONG options ) { -@@ -330,7 +331,8 @@ NTSTATUS WINAPI NtOpenFile( PHANDLE handle, ACCESS_MASK access, +@@ -328,7 +329,8 @@ NTSTATUS WINAPI NtOpenFile( PHANDLE handle, ACCESS_MASK access, * Success: 0. handle and io are updated. * Failure: An NTSTATUS error code describing the error. */ @@ -164,7 +164,7 @@ PIO_STATUS_BLOCK io, PLARGE_INTEGER alloc_size, ULONG attributes, ULONG sharing, ULONG disposition, ULONG options, PVOID ea_buffer, ULONG ea_length ) -@@ -800,7 +802,8 @@ static NTSTATUS get_io_avail_mode( HANDLE handle, enum server_fd_type type, BOOL +@@ -792,7 +794,8 @@ static NTSTATUS get_io_avail_mode( HANDLE handle, enum server_fd_type type, BOOL * The number of bytes read. * Failure: An NTSTATUS error code describing the error. */ @@ -174,7 +174,7 @@ PIO_APC_ROUTINE apc, void* apc_user, PIO_STATUS_BLOCK io_status, void* buffer, ULONG length, PLARGE_INTEGER offset, PULONG key) -@@ -1011,7 +1014,8 @@ err: +@@ -1003,7 +1006,8 @@ err: * NtReadFileScatter [NTDLL.@] * ZwReadFileScatter [NTDLL.@] */ @@ -184,7 +184,7 @@ PIO_STATUS_BLOCK io_status, FILE_SEGMENT_ELEMENT *segments, ULONG length, PLARGE_INTEGER offset, PULONG key ) { -@@ -1183,7 +1187,8 @@ static NTSTATUS set_pending_write( HANDLE device ) +@@ -1175,7 +1179,8 @@ static NTSTATUS set_pending_write( HANDLE device ) * The number of bytes written. * Failure: An NTSTATUS error code describing the error. */ @@ -194,7 +194,7 @@ PIO_APC_ROUTINE apc, void* apc_user, PIO_STATUS_BLOCK io_status, const void* buffer, ULONG length, -@@ -1417,7 +1422,8 @@ err: +@@ -1409,7 +1414,8 @@ err: * NtWriteFileGather [NTDLL.@] * ZwWriteFileGather [NTDLL.@] */ @@ -204,7 +204,7 @@ PIO_STATUS_BLOCK io_status, FILE_SEGMENT_ELEMENT *segments, ULONG length, PLARGE_INTEGER offset, PULONG key ) { -@@ -1606,7 +1612,8 @@ static void ignore_server_ioctl_struct_holes (ULONG code, const void *in_buffer, +@@ -1598,7 +1604,8 @@ static void ignore_server_ioctl_struct_holes (ULONG code, const void *in_buffer, * Success: 0. IoStatusBlock is updated. * Failure: An NTSTATUS error code describing the error. */ @@ -214,7 +214,7 @@ PIO_APC_ROUTINE apc, PVOID apc_context, PIO_STATUS_BLOCK io, ULONG code, PVOID in_buffer, ULONG in_size, -@@ -1670,7 +1677,8 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE handle, HANDLE event, +@@ -1662,7 +1669,8 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE handle, HANDLE event, * Success: 0. IoStatusBlock is updated. * Failure: An NTSTATUS error code describing the error. */ @@ -224,7 +224,7 @@ PVOID apc_context, PIO_STATUS_BLOCK io, ULONG code, PVOID in_buffer, ULONG in_size, PVOID out_buffer, ULONG out_size) { -@@ -1913,7 +1921,8 @@ static NTSTATUS read_changes_apc( void *user, IO_STATUS_BLOCK *iosb, +@@ -1905,7 +1913,8 @@ static NTSTATUS read_changes_apc( void *user, IO_STATUS_BLOCK *iosb, /****************************************************************************** * NtNotifyChangeDirectoryFile [NTDLL.@] */ @@ -234,7 +234,7 @@ void *apc_context, PIO_STATUS_BLOCK iosb, void *buffer, ULONG buffer_size, ULONG filter, BOOLEAN subtree ) { -@@ -1972,7 +1981,8 @@ NTSTATUS WINAPI NtNotifyChangeDirectoryFile( HANDLE handle, HANDLE event, PIO_AP +@@ -1964,7 +1973,8 @@ NTSTATUS WINAPI NtNotifyChangeDirectoryFile( HANDLE handle, HANDLE event, PIO_AP * Success: 0. IoStatusBlock is updated. * Failure: An NTSTATUS error code describing the error. */ @@ -244,7 +244,7 @@ IN HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, -@@ -2277,7 +2287,8 @@ static NTSTATUS fill_name_info( const ANSI_STRING *unix_name, FILE_NAME_INFORMAT +@@ -2269,7 +2279,8 @@ static NTSTATUS fill_name_info( const ANSI_STRING *unix_name, FILE_NAME_INFORMAT * Success: 0. IoStatusBlock and FileInformation are updated. * Failure: An NTSTATUS error code describing the error. */ @@ -254,7 +254,7 @@ PVOID ptr, LONG len, FILE_INFORMATION_CLASS class ) { static const size_t info_sizes[] = -@@ -2603,7 +2614,8 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, +@@ -2595,7 +2606,8 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, * Success: 0. io is updated. * Failure: An NTSTATUS error code describing the error. */ @@ -264,7 +264,7 @@ PVOID ptr, ULONG len, FILE_INFORMATION_CLASS class) { int fd, needs_close; -@@ -2900,7 +2912,8 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, +@@ -2892,7 +2904,8 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, /****************************************************************************** * NtQueryFullAttributesFile (NTDLL.@) */ @@ -274,7 +274,7 @@ FILE_NETWORK_OPEN_INFORMATION *info ) { ANSI_STRING unix_name; -@@ -2944,7 +2957,8 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr, +@@ -2936,7 +2949,8 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr, * NtQueryAttributesFile (NTDLL.@) * ZwQueryAttributesFile (NTDLL.@) */ @@ -284,7 +284,7 @@ { ANSI_STRING unix_name; NTSTATUS status; -@@ -3165,7 +3179,8 @@ static NTSTATUS get_device_info( int fd, FILE_FS_DEVICE_INFORMATION *info ) +@@ -3157,7 +3171,8 @@ static NTSTATUS get_device_info( int fd, FILE_FS_DEVICE_INFORMATION *info ) * Success: 0. io and buffer are updated. * Failure: An NTSTATUS error code describing the error. */ @@ -294,7 +294,7 @@ PVOID buffer, ULONG length, FS_INFORMATION_CLASS info_class ) { -@@ -3313,7 +3328,8 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io +@@ -3305,7 +3320,8 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io * Success: 0. Atrributes read into buffer * Failure: An NTSTATUS error code describing the error. */ @@ -304,7 +304,7 @@ BOOLEAN single_entry, PVOID ea_list, ULONG ea_list_len, PULONG ea_index, BOOLEAN restart ) { -@@ -3339,7 +3355,8 @@ NTSTATUS WINAPI NtQueryEaFile( HANDLE hFile, PIO_STATUS_BLOCK iosb, PVOID buffer +@@ -3331,7 +3347,8 @@ NTSTATUS WINAPI NtQueryEaFile( HANDLE hFile, PIO_STATUS_BLOCK iosb, PVOID buffer * Success: 0. Attributes are updated * Failure: An NTSTATUS error code describing the error. */ @@ -314,7 +314,7 @@ { FIXME("(%p,%p,%p,%d) stub\n", hFile, iosb, buffer, length); return STATUS_ACCESS_DENIED; -@@ -3359,7 +3376,8 @@ NTSTATUS WINAPI NtSetEaFile( HANDLE hFile, PIO_STATUS_BLOCK iosb, PVOID buffer, +@@ -3351,7 +3368,8 @@ NTSTATUS WINAPI NtSetEaFile( HANDLE hFile, PIO_STATUS_BLOCK iosb, PVOID buffer, * Success: 0. IoStatusBlock is updated. * Failure: An NTSTATUS error code describing the error. */ @@ -324,7 +324,7 @@ { NTSTATUS ret; HANDLE hEvent = NULL; -@@ -3401,7 +3419,8 @@ NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK* IoStatusBlock +@@ -3393,7 +3411,8 @@ NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK* IoStatusBlock * * */ @@ -334,7 +334,7 @@ PIO_APC_ROUTINE apc, void* apc_user, PIO_STATUS_BLOCK io_status, PLARGE_INTEGER offset, PLARGE_INTEGER count, ULONG* key, BOOLEAN dont_wait, -@@ -3473,7 +3492,8 @@ NTSTATUS WINAPI NtLockFile( HANDLE hFile, HANDLE lock_granted_event, +@@ -3465,7 +3484,8 @@ NTSTATUS WINAPI NtLockFile( HANDLE hFile, HANDLE lock_granted_event, * * */ @@ -344,7 +344,7 @@ PLARGE_INTEGER offset, PLARGE_INTEGER count, PULONG key ) { -@@ -3504,7 +3524,8 @@ NTSTATUS WINAPI NtUnlockFile( HANDLE hFile, PIO_STATUS_BLOCK io_status, +@@ -3496,7 +3516,8 @@ NTSTATUS WINAPI NtUnlockFile( HANDLE hFile, PIO_STATUS_BLOCK io_status, * * */ @@ -354,7 +354,7 @@ POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK iosb, ULONG sharing, ULONG dispo, ULONG options, ULONG pipe_type, ULONG read_mode, -@@ -3563,7 +3584,8 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, +@@ -3547,7 +3568,8 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, * * */ @@ -364,7 +364,7 @@ { NTSTATUS status; HANDLE hFile; -@@ -3583,7 +3605,8 @@ NTSTATUS WINAPI NtDeleteFile( POBJECT_ATTRIBUTES ObjectAttributes ) +@@ -3567,7 +3589,8 @@ NTSTATUS WINAPI NtDeleteFile( POBJECT_ATTRIBUTES ObjectAttributes ) * * */ @@ -374,7 +374,7 @@ { TRACE("%p %p %p\n", hFile, iosb, io_status ); -@@ -3604,7 +3627,8 @@ NTSTATUS WINAPI NtCancelIoFileEx( HANDLE hFile, PIO_STATUS_BLOCK iosb, PIO_STATU +@@ -3588,7 +3611,8 @@ NTSTATUS WINAPI NtCancelIoFileEx( HANDLE hFile, PIO_STATUS_BLOCK iosb, PIO_STATU * * */ @@ -384,7 +384,7 @@ { TRACE("%p %p\n", hFile, io_status ); -@@ -3637,7 +3661,8 @@ NTSTATUS WINAPI NtCancelIoFile( HANDLE hFile, PIO_STATUS_BLOCK io_status ) +@@ -3621,7 +3645,8 @@ NTSTATUS WINAPI NtCancelIoFile( HANDLE hFile, PIO_STATUS_BLOCK io_status ) * RETURNS * An NT status code */ @@ -395,7 +395,7 @@ ULONG CreateOptions, ULONG MailslotQuota, ULONG MaxMessageSize, PLARGE_INTEGER TimeOut) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c -index 74feb97..e5ea736 100644 +index 5bcc03e..b08feeb 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3200,7 +3200,8 @@ PVOID WINAPI RtlPcToFileHeader( PVOID pc, PVOID *address ) @@ -419,7 +419,7 @@ FIXME("(%p), stub!\n",DriverServiceName); return STATUS_NOT_IMPLEMENTED; diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c -index 8ea1ddd..19d5b6e 100644 +index 9b750e4..9b54be6 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -74,7 +74,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll); @@ -632,7 +632,7 @@ ULONG Interval, KPROFILE_SOURCE Source) { -@@ -1676,7 +1697,8 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION ** +@@ -1838,7 +1859,8 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION ** * Length size of the structure * ResultLength Data written */ @@ -642,7 +642,7 @@ IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG Length, -@@ -2142,7 +2164,8 @@ NTSTATUS WINAPI NtQuerySystemInformation( +@@ -2405,7 +2427,8 @@ NTSTATUS WINAPI NtQuerySystemInformationEx(SYSTEM_INFORMATION_CLASS SystemInform * NtSetSystemInformation [NTDLL.@] * ZwSetSystemInformation [NTDLL.@] */ @@ -652,7 +652,7 @@ { FIXME("(0x%08x,%p,0x%08x) stub\n",SystemInformationClass,SystemInformation,Length); return STATUS_SUCCESS; -@@ -2152,7 +2175,8 @@ NTSTATUS WINAPI NtSetSystemInformation(SYSTEM_INFORMATION_CLASS SystemInformatio +@@ -2415,7 +2438,8 @@ NTSTATUS WINAPI NtSetSystemInformation(SYSTEM_INFORMATION_CLASS SystemInformatio * NtCreatePagingFile [NTDLL.@] * ZwCreatePagingFile [NTDLL.@] */ @@ -662,7 +662,7 @@ PUNICODE_STRING PageFileName, PLARGE_INTEGER MinimumSize, PLARGE_INTEGER MaximumSize, -@@ -2167,7 +2191,8 @@ NTSTATUS WINAPI NtCreatePagingFile( +@@ -2430,7 +2454,8 @@ NTSTATUS WINAPI NtCreatePagingFile( * * writes a string to the nt-textmode screen eg. during startup */ @@ -672,7 +672,7 @@ { STRING stringA; NTSTATUS ret; -@@ -2184,7 +2209,8 @@ NTSTATUS WINAPI NtDisplayString ( PUNICODE_STRING string ) +@@ -2447,7 +2472,8 @@ NTSTATUS WINAPI NtDisplayString ( PUNICODE_STRING string ) * NtInitiatePowerAction [NTDLL.@] * */ @@ -682,7 +682,7 @@ IN POWER_ACTION SystemAction, IN SYSTEM_POWER_STATE MinSystemState, IN ULONG Flags, -@@ -2228,7 +2254,8 @@ static ULONG mhz_from_cpuinfo(void) +@@ -2491,7 +2517,8 @@ static ULONG mhz_from_cpuinfo(void) * NtPowerInformation [NTDLL.@] * */ @@ -692,7 +692,7 @@ IN POWER_INFORMATION_LEVEL InformationLevel, IN PVOID lpInputBuffer, IN ULONG nInputBufferSize, -@@ -2418,7 +2445,8 @@ NTSTATUS WINAPI NtPowerInformation( +@@ -2681,7 +2708,8 @@ NTSTATUS WINAPI NtPowerInformation( * NtShutdownSystem [NTDLL.@] * */ @@ -702,7 +702,7 @@ { FIXME("%d\n",Action); return STATUS_SUCCESS; -@@ -2427,7 +2455,8 @@ NTSTATUS WINAPI NtShutdownSystem(SHUTDOWN_ACTION Action) +@@ -2690,7 +2718,8 @@ NTSTATUS WINAPI NtShutdownSystem(SHUTDOWN_ACTION Action) /****************************************************************************** * NtAllocateLocallyUniqueId (NTDLL.@) */ @@ -712,7 +712,7 @@ { NTSTATUS status; -@@ -2485,7 +2514,8 @@ ULONGLONG WINAPI VerSetConditionMask( ULONGLONG dwlConditionMask, DWORD dwTypeBi +@@ -2748,7 +2777,8 @@ ULONGLONG WINAPI VerSetConditionMask( ULONGLONG dwlConditionMask, DWORD dwTypeBi * NtAccessCheckAndAuditAlarm (NTDLL.@) * ZwAccessCheckAndAuditAlarm (NTDLL.@) */ @@ -722,7 +722,7 @@ PUNICODE_STRING ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, ACCESS_MASK DesiredAccess, PGENERIC_MAPPING GenericMapping, BOOLEAN ObjectCreation, PACCESS_MASK GrantedAccess, PBOOLEAN AccessStatus, PBOOLEAN GenerateOnClose) -@@ -2501,7 +2531,8 @@ NTSTATUS WINAPI NtAccessCheckAndAuditAlarm(PUNICODE_STRING SubsystemName, HANDLE +@@ -2764,7 +2794,8 @@ NTSTATUS WINAPI NtAccessCheckAndAuditAlarm(PUNICODE_STRING SubsystemName, HANDLE * NtSystemDebugControl (NTDLL.@) * ZwSystemDebugControl (NTDLL.@) */ @@ -733,10 +733,10 @@ { FIXME("(%d, %p, %d, %p, %d, %p), stub\n", command, inbuffer, inbuflength, outbuffer, outbuflength, retlength); diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h -index cbd19db..e3f902f 100644 +index 5e4c39e..d0ed679 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h -@@ -262,6 +262,23 @@ extern HANDLE keyed_event DECLSPEC_HIDDEN; +@@ -260,6 +260,23 @@ extern HANDLE keyed_event DECLSPEC_HIDDEN; "ret $(4*" #args ")" ) /* fake ret to make copy protections happy */ #endif @@ -761,7 +761,7 @@ #define HASH_STRING_ALGORITHM_X65599 1 #define HASH_STRING_ALGORITHM_INVALID 0xffffffff diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c -index 3fadba7..4fd0656 100644 +index 7aa2fea..5d28684 100644 --- a/dlls/ntdll/om.c +++ b/dlls/ntdll/om.c @@ -50,7 +50,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll); @@ -819,23 +819,23 @@ * Success: ERROR_SUCCESS. * Failure: An NTSTATUS error code. */ --NTSTATUS WINAPI NtOpenDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess, +-NTSTATUS WINAPI NtOpenDirectoryObject( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr) +DEFINE_SYSCALL_ENTRYPOINT( NtOpenDirectoryObject, 3 ); -+NTSTATUS WINAPI SYSCALL(NtOpenDirectoryObject)(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes) ++NTSTATUS WINAPI SYSCALL(NtOpenDirectoryObject)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr) { NTSTATUS ret; -@@ -477,7 +483,8 @@ NTSTATUS WINAPI NtOpenDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK Desir + +@@ -467,7 +473,8 @@ NTSTATUS WINAPI NtOpenDirectoryObject( HANDLE *handle, ACCESS_MASK access, const * Success: ERROR_SUCCESS. * Failure: An NTSTATUS error code. */ -NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess, +DEFINE_SYSCALL_ENTRYPOINT( NtCreateDirectoryObject, 3 ); +NTSTATUS WINAPI SYSCALL(NtCreateDirectoryObject)(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes) + OBJECT_ATTRIBUTES *attr ) { NTSTATUS ret; -@@ -519,7 +526,8 @@ NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK Des +@@ -511,7 +518,8 @@ NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK Des * Success: ERROR_SUCCESS. * Failure: An NTSTATUS error code. */ @@ -845,27 +845,27 @@ ULONG size, BOOLEAN single_entry, BOOLEAN restart, PULONG context, PULONG ret_size) { -@@ -584,7 +592,8 @@ NTSTATUS WINAPI NtQueryDirectoryObject(HANDLE handle, PDIRECTORY_BASIC_INFORMATI +@@ -576,7 +584,8 @@ NTSTATUS WINAPI NtQueryDirectoryObject(HANDLE handle, PDIRECTORY_BASIC_INFORMATI * Success: ERROR_SUCCESS. * Failure: An NTSTATUS error code. */ --NTSTATUS WINAPI NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, IN ACCESS_MASK DesiredAccess, +-NTSTATUS WINAPI NtOpenSymbolicLinkObject( HANDLE *handle, ACCESS_MASK access, +DEFINE_SYSCALL_ENTRYPOINT( NtOpenSymbolicLinkObject, 3 ); -+NTSTATUS WINAPI SYSCALL(NtOpenSymbolicLinkObject)(OUT PHANDLE LinkHandle, IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes) ++NTSTATUS WINAPI SYSCALL(NtOpenSymbolicLinkObject)( HANDLE *handle, ACCESS_MASK access, + const OBJECT_ATTRIBUTES *attr) { NTSTATUS ret; -@@ -633,7 +642,8 @@ NTSTATUS WINAPI NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, IN ACCESS_MASK +@@ -616,7 +625,8 @@ NTSTATUS WINAPI NtOpenSymbolicLinkObject( HANDLE *handle, ACCESS_MASK access, * Success: ERROR_SUCCESS. * Failure: An NTSTATUS error code. */ -NTSTATUS WINAPI NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle,IN ACCESS_MASK DesiredAccess, +DEFINE_SYSCALL_ENTRYPOINT( NtCreateSymbolicLinkObject, 4 ); +NTSTATUS WINAPI SYSCALL(NtCreateSymbolicLinkObject)(OUT PHANDLE SymbolicLinkHandle,IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN PUNICODE_STRING TargetName) + POBJECT_ATTRIBUTES attr, PUNICODE_STRING TargetName) { -@@ -681,7 +691,8 @@ NTSTATUS WINAPI NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle,IN ACC + NTSTATUS ret; +@@ -660,7 +670,8 @@ NTSTATUS WINAPI NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle,IN ACC * Success: ERROR_SUCCESS. * Failure: An NTSTATUS error code. */ @@ -875,7 +875,7 @@ { NTSTATUS ret; -@@ -709,7 +720,8 @@ NTSTATUS WINAPI NtQuerySymbolicLinkObject( HANDLE handle, PUNICODE_STRING target +@@ -688,7 +699,8 @@ NTSTATUS WINAPI NtQuerySymbolicLinkObject( HANDLE handle, PUNICODE_STRING target /****************************************************************************** * NtAllocateUuids [NTDLL.@] */ @@ -885,7 +885,7 @@ PULARGE_INTEGER Time, PULONG Range, PULONG Sequence) -@@ -731,7 +743,8 @@ NTSTATUS WINAPI NtAllocateUuids( +@@ -710,7 +722,8 @@ NTSTATUS WINAPI NtAllocateUuids( * Success: STATUS_SUCCESS. * Failure: An NTSTATUS error code. */ @@ -896,7 +896,7 @@ FIXME("(%p), stub.\n", Handle); return STATUS_SUCCESS; diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c -index ca9462a..37c08f1 100644 +index 5a5c3ef..c7a0a8a 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -53,7 +53,8 @@ static ULONG execute_flags = MEM_EXECUTE_OPTION_DISABLE; @@ -950,10 +950,10 @@ { NTSTATUS status; diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c -index 0701426..b74c464 100644 +index bf786f4..2d17af6 100644 --- a/dlls/ntdll/reg.c +++ b/dlls/ntdll/reg.c -@@ -51,7 +51,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(reg); +@@ -49,7 +49,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(reg); * NtCreateKey [NTDLL.@] * ZwCreateKey [NTDLL.@] */ @@ -992,8 +992,8 @@ +NTSTATUS WINAPI SYSCALL(NtOpenKeyEx)( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, ULONG options ) { NTSTATUS ret; - DWORD len; -@@ -161,19 +165,22 @@ NTSTATUS WINAPI NtOpenKeyEx( PHANDLE retkey, ACCESS_MASK access, const OBJECT_AT + +@@ -159,19 +163,22 @@ NTSTATUS WINAPI NtOpenKeyEx( PHANDLE retkey, ACCESS_MASK access, const OBJECT_AT * IN ACCESS_MASK access * IN POBJECT_ATTRIBUTES attr */ @@ -1019,7 +1019,7 @@ HANDLE transaction ) { return NtOpenKeyTransactedEx( retkey, access, attr, 0, transaction ); -@@ -195,7 +202,8 @@ NTSTATUS WINAPI RtlpNtOpenKey( PHANDLE retkey, ACCESS_MASK access, OBJECT_ATTRIB +@@ -193,7 +200,8 @@ NTSTATUS WINAPI RtlpNtOpenKey( PHANDLE retkey, ACCESS_MASK access, OBJECT_ATTRIB * NtDeleteKey [NTDLL.@] * ZwDeleteKey [NTDLL.@] */ @@ -1029,7 +1029,7 @@ { NTSTATUS ret; -@@ -224,7 +232,8 @@ NTSTATUS WINAPI RtlpNtMakeTemporaryKey( HANDLE hkey ) +@@ -222,7 +230,8 @@ NTSTATUS WINAPI RtlpNtMakeTemporaryKey( HANDLE hkey ) * NtDeleteValueKey [NTDLL.@] * ZwDeleteValueKey [NTDLL.@] */ @@ -1039,7 +1039,7 @@ { NTSTATUS ret; -@@ -350,7 +359,8 @@ static NTSTATUS enumerate_key( HANDLE handle, int index, KEY_INFORMATION_CLASS i +@@ -366,7 +375,8 @@ static NTSTATUS enumerate_key( HANDLE handle, int index, KEY_INFORMATION_CLASS i * NOTES * the name copied into the buffer is NOT 0-terminated */ @@ -1049,7 +1049,7 @@ void *info, DWORD length, DWORD *result_len ) { /* -1 means query key, so avoid it here */ -@@ -409,7 +419,8 @@ NTSTATUS WINAPI RtlpNtEnumerateSubKey( HANDLE handle, UNICODE_STRING *out, ULONG +@@ -425,7 +435,8 @@ NTSTATUS WINAPI RtlpNtEnumerateSubKey( HANDLE handle, UNICODE_STRING *out, ULONG * NtQueryKey [NTDLL.@] * ZwQueryKey [NTDLL.@] */ @@ -1059,7 +1059,7 @@ void *info, DWORD length, DWORD *result_len ) { return enumerate_key( handle, -1, info_class, info, length, result_len ); -@@ -464,7 +475,8 @@ static void copy_key_value_info( KEY_VALUE_INFORMATION_CLASS info_class, void *i +@@ -480,7 +491,8 @@ static void copy_key_value_info( KEY_VALUE_INFORMATION_CLASS info_class, void *i * NtEnumerateValueKey [NTDLL.@] * ZwEnumerateValueKey [NTDLL.@] */ @@ -1069,7 +1069,7 @@ KEY_VALUE_INFORMATION_CLASS info_class, void *info, DWORD length, DWORD *result_len ) { -@@ -512,7 +524,8 @@ NTSTATUS WINAPI NtEnumerateValueKey( HANDLE handle, ULONG index, +@@ -528,7 +540,8 @@ NTSTATUS WINAPI NtEnumerateValueKey( HANDLE handle, ULONG index, * NOTES * the name in the KeyValueInformation is never set */ @@ -1079,7 +1079,7 @@ KEY_VALUE_INFORMATION_CLASS info_class, void *info, DWORD length, DWORD *result_len ) { -@@ -614,7 +627,8 @@ NTSTATUS WINAPI RtlpNtQueryValueKey( HANDLE handle, ULONG *result_type, PBYTE de +@@ -630,7 +643,8 @@ NTSTATUS WINAPI RtlpNtQueryValueKey( HANDLE handle, ULONG *result_type, PBYTE de * NtFlushKey [NTDLL.@] * ZwFlushKey [NTDLL.@] */ @@ -1089,7 +1089,7 @@ { NTSTATUS ret; -@@ -634,7 +648,8 @@ NTSTATUS WINAPI NtFlushKey(HANDLE key) +@@ -650,7 +664,8 @@ NTSTATUS WINAPI NtFlushKey(HANDLE key) * NtLoadKey [NTDLL.@] * ZwLoadKey [NTDLL.@] */ @@ -1099,7 +1099,7 @@ { NTSTATUS ret; HANDLE hive; -@@ -664,7 +679,8 @@ NTSTATUS WINAPI NtLoadKey( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *fil +@@ -683,7 +698,8 @@ NTSTATUS WINAPI NtLoadKey( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *fil * NtNotifyChangeMultipleKeys [NTDLL.@] * ZwNotifyChangeMultipleKeys [NTDLL.@] */ @@ -1109,7 +1109,7 @@ HANDLE KeyHandle, ULONG Count, OBJECT_ATTRIBUTES *SubordinateObjects, -@@ -720,7 +736,8 @@ NTSTATUS WINAPI NtNotifyChangeMultipleKeys( +@@ -739,7 +755,8 @@ NTSTATUS WINAPI NtNotifyChangeMultipleKeys( * NtNotifyChangeKey [NTDLL.@] * ZwNotifyChangeKey [NTDLL.@] */ @@ -1119,7 +1119,7 @@ IN HANDLE KeyHandle, IN HANDLE Event, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, -@@ -742,7 +759,8 @@ NTSTATUS WINAPI NtNotifyChangeKey( +@@ -761,7 +778,8 @@ NTSTATUS WINAPI NtNotifyChangeKey( * ZwQueryMultipleValueKey */ @@ -1129,7 +1129,7 @@ HANDLE KeyHandle, PKEY_MULTIPLE_VALUE_INFORMATION ListOfValuesToQuery, ULONG NumberOfItems, -@@ -760,7 +778,8 @@ NTSTATUS WINAPI NtQueryMultipleValueKey( +@@ -779,7 +797,8 @@ NTSTATUS WINAPI NtQueryMultipleValueKey( * NtReplaceKey [NTDLL.@] * ZwReplaceKey [NTDLL.@] */ @@ -1139,7 +1139,7 @@ IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE Key, IN POBJECT_ATTRIBUTES ReplacedObjectAttributes) -@@ -773,7 +792,8 @@ NTSTATUS WINAPI NtReplaceKey( +@@ -792,7 +811,8 @@ NTSTATUS WINAPI NtReplaceKey( * NtRestoreKey [NTDLL.@] * ZwRestoreKey [NTDLL.@] */ @@ -1149,7 +1149,7 @@ HANDLE KeyHandle, HANDLE FileHandle, ULONG RestoreFlags) -@@ -786,7 +806,8 @@ NTSTATUS WINAPI NtRestoreKey( +@@ -805,7 +825,8 @@ NTSTATUS WINAPI NtRestoreKey( * NtSaveKey [NTDLL.@] * ZwSaveKey [NTDLL.@] */ @@ -1159,7 +1159,7 @@ { NTSTATUS ret; -@@ -806,7 +827,8 @@ NTSTATUS WINAPI NtSaveKey(IN HANDLE KeyHandle, IN HANDLE FileHandle) +@@ -825,7 +846,8 @@ NTSTATUS WINAPI NtSaveKey(IN HANDLE KeyHandle, IN HANDLE FileHandle) * NtSetInformationKey [NTDLL.@] * ZwSetInformationKey [NTDLL.@] */ @@ -1169,7 +1169,7 @@ IN HANDLE KeyHandle, IN const int KeyInformationClass, IN PVOID KeyInformation, -@@ -826,7 +848,8 @@ NTSTATUS WINAPI NtSetInformationKey( +@@ -845,7 +867,8 @@ NTSTATUS WINAPI NtSetInformationKey( * win95 does not care about count for REG_SZ and finds out the len by itself (js) * NT does definitely care (aj) */ @@ -1179,7 +1179,7 @@ ULONG type, const void *data, ULONG count ) { NTSTATUS ret; -@@ -865,7 +888,8 @@ NTSTATUS WINAPI RtlpNtSetValueKey( HANDLE hkey, ULONG type, const void *data, +@@ -884,7 +907,8 @@ NTSTATUS WINAPI RtlpNtSetValueKey( HANDLE hkey, ULONG type, const void *data, * NtUnloadKey [NTDLL.@] * ZwUnloadKey [NTDLL.@] */ @@ -1189,7 +1189,7 @@ { NTSTATUS ret; -@@ -1472,7 +1496,8 @@ NTSTATUS WINAPI RtlWriteRegistryValue( ULONG RelativeTo, PCWSTR path, PCWSTR nam +@@ -1491,7 +1515,8 @@ NTSTATUS WINAPI RtlWriteRegistryValue( ULONG RelativeTo, PCWSTR path, PCWSTR nam * unless there is some app which explicitly depends on that, there is * no good reason to reproduce that. */ @@ -1326,10 +1326,10 @@ NTSTATUS status = raise_exception( rec, context, first_chance ); if (status == STATUS_SUCCESS) NtSetContextThread( GetCurrentThread(), context ); diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c -index 5c3aa819..fdb48371 100644 +index a3abbff..839f793 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c -@@ -2617,7 +2617,8 @@ DEFINE_REGS_ENTRYPOINT( RtlUnwind, 4 ) +@@ -2598,7 +2598,8 @@ DEFINE_REGS_ENTRYPOINT( RtlUnwind, 4 ) /******************************************************************* * NtRaiseException (NTDLL.@) */ @@ -1339,7 +1339,7 @@ { NTSTATUS status = raise_exception( rec, context, first_chance ); if (status == STATUS_SUCCESS) -@@ -2856,4 +2857,12 @@ __ASM_GLOBAL_FUNC(call_exception_handler, +@@ -2837,4 +2838,12 @@ __ASM_GLOBAL_FUNC(call_exception_handler, __ASM_CFI(".cfi_same_value %ebp\n\t") "ret $20" ) /* (*4) */ @@ -1367,10 +1367,10 @@ NTSTATUS status = raise_exception( rec, context, first_chance ); if (status == STATUS_SUCCESS) NtSetContextThread( GetCurrentThread(), context ); diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c -index 524de68..574b086 100644 +index 0c64541..ad00eb6 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c -@@ -3617,7 +3617,8 @@ EXCEPTION_DISPOSITION WINAPI __C_specific_handler( EXCEPTION_RECORD *rec, +@@ -3637,7 +3637,8 @@ EXCEPTION_DISPOSITION WINAPI __C_specific_handler( EXCEPTION_RECORD *rec, /******************************************************************* * NtRaiseException (NTDLL.@) */ @@ -1381,10 +1381,10 @@ NTSTATUS status = raise_exception( rec, context, first_chance ); if (status == STATUS_SUCCESS) NtSetContextThread( GetCurrentThread(), context ); diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c -index 6892732..341a71a 100644 +index aa58442..45bac3e 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c -@@ -149,7 +149,8 @@ void NTDLL_free_struct_sd(struct security_descriptor *server_sd) +@@ -171,7 +171,8 @@ NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr ) /****************************************************************************** * NtCreateSemaphore (NTDLL.@) */ @@ -1394,17 +1394,17 @@ IN ACCESS_MASK access, IN const OBJECT_ATTRIBUTES *attr OPTIONAL, IN LONG InitialCount, -@@ -195,7 +196,8 @@ NTSTATUS WINAPI NtCreateSemaphore( OUT PHANDLE SemaphoreHandle, +@@ -204,7 +205,8 @@ NTSTATUS WINAPI NtCreateSemaphore( OUT PHANDLE SemaphoreHandle, /****************************************************************************** * NtOpenSemaphore (NTDLL.@) */ --NTSTATUS WINAPI NtOpenSemaphore( OUT PHANDLE SemaphoreHandle, +-NTSTATUS WINAPI NtOpenSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) +DEFINE_SYSCALL_ENTRYPOINT( NtOpenSemaphore, 3 ); -+NTSTATUS WINAPI SYSCALL(NtOpenSemaphore)( OUT PHANDLE SemaphoreHandle, - IN ACCESS_MASK access, - IN const OBJECT_ATTRIBUTES *attr ) ++NTSTATUS WINAPI SYSCALL(NtOpenSemaphore)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { -@@ -220,7 +222,8 @@ NTSTATUS WINAPI NtOpenSemaphore( OUT PHANDLE SemaphoreHandle, + NTSTATUS ret; + +@@ -227,7 +229,8 @@ NTSTATUS WINAPI NtOpenSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJEC /****************************************************************************** * NtQuerySemaphore (NTDLL.@) */ @@ -1414,7 +1414,7 @@ void *info, ULONG len, ULONG *ret_len ) { NTSTATUS ret; -@@ -252,7 +255,8 @@ NTSTATUS WINAPI NtQuerySemaphore( HANDLE handle, SEMAPHORE_INFORMATION_CLASS cla +@@ -259,7 +262,8 @@ NTSTATUS WINAPI NtQuerySemaphore( HANDLE handle, SEMAPHORE_INFORMATION_CLASS cla /****************************************************************************** * NtReleaseSemaphore (NTDLL.@) */ @@ -1424,7 +1424,7 @@ { NTSTATUS ret; SERVER_START_REQ( release_semaphore ) -@@ -276,7 +280,8 @@ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous +@@ -283,7 +287,8 @@ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous * NtCreateEvent (NTDLL.@) * ZwCreateEvent (NTDLL.@) */ @@ -1433,18 +1433,18 @@ +NTSTATUS WINAPI SYSCALL(NtCreateEvent)( PHANDLE EventHandle, ACCESS_MASK DesiredAccess, const OBJECT_ATTRIBUTES *attr, EVENT_TYPE type, BOOLEAN InitialState) { - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; -@@ -318,7 +323,8 @@ NTSTATUS WINAPI NtCreateEvent( PHANDLE EventHandle, ACCESS_MASK DesiredAccess, + NTSTATUS ret; +@@ -311,7 +316,8 @@ NTSTATUS WINAPI NtCreateEvent( PHANDLE EventHandle, ACCESS_MASK DesiredAccess, * NtOpenEvent (NTDLL.@) * ZwOpenEvent (NTDLL.@) */ --NTSTATUS WINAPI NtOpenEvent( +-NTSTATUS WINAPI NtOpenEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) +DEFINE_SYSCALL_ENTRYPOINT( NtOpenEvent, 3 ); -+NTSTATUS WINAPI SYSCALL(NtOpenEvent)( - OUT PHANDLE EventHandle, - IN ACCESS_MASK DesiredAccess, - IN const OBJECT_ATTRIBUTES *attr ) -@@ -346,7 +352,8 @@ NTSTATUS WINAPI NtOpenEvent( ++NTSTATUS WINAPI SYSCALL(NtOpenEvent)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) + { + NTSTATUS ret; + +@@ -336,7 +342,8 @@ NTSTATUS WINAPI NtOpenEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_AT * NtSetEvent (NTDLL.@) * ZwSetEvent (NTDLL.@) */ @@ -1454,7 +1454,7 @@ { NTSTATUS ret; -@@ -365,7 +372,8 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, PULONG NumberOfThreadsReleased ) +@@ -355,7 +362,8 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, PULONG NumberOfThreadsReleased ) /****************************************************************************** * NtResetEvent (NTDLL.@) */ @@ -1464,7 +1464,7 @@ { NTSTATUS ret; -@@ -388,7 +396,8 @@ NTSTATUS WINAPI NtResetEvent( HANDLE handle, PULONG NumberOfThreadsReleased ) +@@ -378,7 +386,8 @@ NTSTATUS WINAPI NtResetEvent( HANDLE handle, PULONG NumberOfThreadsReleased ) * FIXME * same as NtResetEvent ??? */ @@ -1474,7 +1474,7 @@ { return NtResetEvent( handle, NULL ); } -@@ -399,7 +408,8 @@ NTSTATUS WINAPI NtClearEvent ( HANDLE handle ) +@@ -389,7 +398,8 @@ NTSTATUS WINAPI NtClearEvent ( HANDLE handle ) * FIXME * PulseCount */ @@ -1484,7 +1484,7 @@ { NTSTATUS ret; -@@ -419,7 +429,8 @@ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, PULONG PulseCount ) +@@ -409,7 +419,8 @@ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, PULONG PulseCount ) /****************************************************************************** * NtQueryEvent (NTDLL.@) */ @@ -1494,7 +1494,7 @@ void *info, ULONG len, ULONG *ret_len ) { NTSTATUS ret; -@@ -457,7 +468,8 @@ NTSTATUS WINAPI NtQueryEvent( HANDLE handle, EVENT_INFORMATION_CLASS class, +@@ -447,7 +458,8 @@ NTSTATUS WINAPI NtQueryEvent( HANDLE handle, EVENT_INFORMATION_CLASS class, * NtCreateMutant [NTDLL.@] * ZwCreateMutant [NTDLL.@] */ @@ -1504,17 +1504,17 @@ IN ACCESS_MASK access, IN const OBJECT_ATTRIBUTES* attr OPTIONAL, IN BOOLEAN InitialOwner) -@@ -500,7 +512,8 @@ NTSTATUS WINAPI NtCreateMutant(OUT HANDLE* MutantHandle, +@@ -476,7 +488,8 @@ NTSTATUS WINAPI NtCreateMutant(OUT HANDLE* MutantHandle, * NtOpenMutant [NTDLL.@] * ZwOpenMutant [NTDLL.@] */ --NTSTATUS WINAPI NtOpenMutant(OUT HANDLE* MutantHandle, +-NTSTATUS WINAPI NtOpenMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) +DEFINE_SYSCALL_ENTRYPOINT( NtOpenMutant, 3 ); -+NTSTATUS WINAPI SYSCALL(NtOpenMutant)(OUT HANDLE* MutantHandle, - IN ACCESS_MASK access, - IN const OBJECT_ATTRIBUTES* attr ) ++NTSTATUS WINAPI SYSCALL(NtOpenMutant)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { -@@ -526,7 +539,8 @@ NTSTATUS WINAPI NtOpenMutant(OUT HANDLE* MutantHandle, + NTSTATUS status; + +@@ -500,7 +513,8 @@ NTSTATUS WINAPI NtOpenMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT_A * NtReleaseMutant [NTDLL.@] * ZwReleaseMutant [NTDLL.@] */ @@ -1524,7 +1524,7 @@ { NTSTATUS status; -@@ -544,7 +558,8 @@ NTSTATUS WINAPI NtReleaseMutant( IN HANDLE handle, OUT PLONG prev_count OPTIONAL +@@ -518,7 +532,8 @@ NTSTATUS WINAPI NtReleaseMutant( IN HANDLE handle, OUT PLONG prev_count OPTIONAL * NtQueryMutant [NTDLL.@] * ZwQueryMutant [NTDLL.@] */ @@ -1534,7 +1534,7 @@ IN MUTANT_INFORMATION_CLASS MutantInformationClass, OUT PVOID MutantInformation, IN ULONG MutantInformationLength, -@@ -563,7 +578,8 @@ NTSTATUS WINAPI NtQueryMutant(IN HANDLE handle, +@@ -537,7 +552,8 @@ NTSTATUS WINAPI NtQueryMutant(IN HANDLE handle, * NtCreateJobObject [NTDLL.@] * ZwCreateJobObject [NTDLL.@] */ @@ -1542,19 +1542,19 @@ +DEFINE_SYSCALL_ENTRYPOINT( NtCreateJobObject, 3 ); +NTSTATUS WINAPI SYSCALL(NtCreateJobObject)( PHANDLE handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; -@@ -601,7 +617,8 @@ NTSTATUS WINAPI NtCreateJobObject( PHANDLE handle, ACCESS_MASK access, const OBJ + data_size_t len; +@@ -562,7 +578,8 @@ NTSTATUS WINAPI NtCreateJobObject( PHANDLE handle, ACCESS_MASK access, const OBJ * NtOpenJobObject [NTDLL.@] * ZwOpenJobObject [NTDLL.@] */ --NTSTATUS WINAPI NtOpenJobObject( PHANDLE handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) +-NTSTATUS WINAPI NtOpenJobObject( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) +DEFINE_SYSCALL_ENTRYPOINT( NtOpenJobObject, 3 ); -+NTSTATUS WINAPI SYSCALL(NtOpenJobObject)( PHANDLE handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) ++NTSTATUS WINAPI SYSCALL(NtOpenJobObject)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { - FIXME( "stub: %p %x %s\n", handle, access, attr ? debugstr_us(attr->ObjectName) : "" ); - return STATUS_NOT_IMPLEMENTED; -@@ -611,7 +628,8 @@ NTSTATUS WINAPI NtOpenJobObject( PHANDLE handle, ACCESS_MASK access, const OBJEC + NTSTATUS ret; + +@@ -586,7 +603,8 @@ NTSTATUS WINAPI NtOpenJobObject( HANDLE *handle, ACCESS_MASK access, const OBJEC * NtTerminateJobObject [NTDLL.@] * ZwTerminateJobObject [NTDLL.@] */ @@ -1564,7 +1564,7 @@ { NTSTATUS ret; -@@ -632,7 +650,8 @@ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status ) +@@ -607,7 +625,8 @@ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status ) * NtQueryInformationJobObject [NTDLL.@] * ZwQueryInformationJobObject [NTDLL.@] */ @@ -1574,7 +1574,7 @@ ULONG len, PULONG ret_len ) { FIXME( "stub: %p %u %p %u %p\n", handle, class, info, len, ret_len ); -@@ -675,7 +694,8 @@ NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS c +@@ -650,7 +669,8 @@ NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS c * NtSetInformationJobObject [NTDLL.@] * ZwSetInformationJobObject [NTDLL.@] */ @@ -1584,7 +1584,7 @@ { NTSTATUS status = STATUS_NOT_IMPLEMENTED; JOBOBJECT_BASIC_LIMIT_INFORMATION *basic_limit; -@@ -740,7 +760,8 @@ NTSTATUS WINAPI NtSetInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS cla +@@ -715,7 +735,8 @@ NTSTATUS WINAPI NtSetInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS cla * NtIsProcessInJob [NTDLL.@] * ZwIsProcessInJob [NTDLL.@] */ @@ -1594,7 +1594,7 @@ { NTSTATUS status; -@@ -761,7 +782,8 @@ NTSTATUS WINAPI NtIsProcessInJob( HANDLE process, HANDLE job ) +@@ -736,7 +757,8 @@ NTSTATUS WINAPI NtIsProcessInJob( HANDLE process, HANDLE job ) * NtAssignProcessToJobObject [NTDLL.@] * ZwAssignProcessToJobObject [NTDLL.@] */ @@ -1604,7 +1604,7 @@ { NTSTATUS status; -@@ -786,7 +808,8 @@ NTSTATUS WINAPI NtAssignProcessToJobObject( HANDLE job, HANDLE process ) +@@ -761,7 +783,8 @@ NTSTATUS WINAPI NtAssignProcessToJobObject( HANDLE job, HANDLE process ) * NtCreateTimer [NTDLL.@] * ZwCreateTimer [NTDLL.@] */ @@ -1614,17 +1614,17 @@ IN ACCESS_MASK access, IN const OBJECT_ATTRIBUTES *attr OPTIONAL, IN TIMER_TYPE timer_type) -@@ -818,7 +841,8 @@ NTSTATUS WINAPI NtCreateTimer(OUT HANDLE *handle, +@@ -794,7 +817,8 @@ NTSTATUS WINAPI NtCreateTimer(OUT HANDLE *handle, * NtOpenTimer [NTDLL.@] * ZwOpenTimer [NTDLL.@] */ --NTSTATUS WINAPI NtOpenTimer(OUT PHANDLE handle, +-NTSTATUS WINAPI NtOpenTimer( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) +DEFINE_SYSCALL_ENTRYPOINT( NtOpenTimer, 3 ); -+NTSTATUS WINAPI SYSCALL(NtOpenTimer)(OUT PHANDLE handle, - IN ACCESS_MASK access, - IN const OBJECT_ATTRIBUTES* attr ) ++NTSTATUS WINAPI SYSCALL(NtOpenTimer)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { -@@ -844,7 +868,8 @@ NTSTATUS WINAPI NtOpenTimer(OUT PHANDLE handle, + NTSTATUS status; + +@@ -818,7 +842,8 @@ NTSTATUS WINAPI NtOpenTimer( HANDLE *handle, ACCESS_MASK access, const OBJECT_AT * NtSetTimer [NTDLL.@] * ZwSetTimer [NTDLL.@] */ @@ -1634,7 +1634,7 @@ IN const LARGE_INTEGER* when, IN PTIMER_APC_ROUTINE callback, IN PVOID callback_arg, -@@ -878,7 +903,8 @@ NTSTATUS WINAPI NtSetTimer(IN HANDLE handle, +@@ -852,7 +877,8 @@ NTSTATUS WINAPI NtSetTimer(IN HANDLE handle, * NtCancelTimer [NTDLL.@] * ZwCancelTimer [NTDLL.@] */ @@ -1644,7 +1644,7 @@ { NTSTATUS status; -@@ -912,7 +938,8 @@ NTSTATUS WINAPI NtCancelTimer(IN HANDLE handle, OUT BOOLEAN* state) +@@ -886,7 +912,8 @@ NTSTATUS WINAPI NtCancelTimer(IN HANDLE handle, OUT BOOLEAN* state) * STATUS_ACCESS_DENIED, if TimerHandle does not have TIMER_QUERY_STATE access * to the timer. */ @@ -1654,7 +1654,7 @@ HANDLE TimerHandle, TIMER_INFORMATION_CLASS TimerInformationClass, PVOID TimerInformation, -@@ -963,7 +990,8 @@ NTSTATUS WINAPI NtQueryTimer( +@@ -937,7 +964,8 @@ NTSTATUS WINAPI NtQueryTimer( /****************************************************************************** * NtQueryTimerResolution [NTDLL.@] */ @@ -1664,7 +1664,7 @@ OUT ULONG* max_resolution, OUT ULONG* current_resolution) { -@@ -976,7 +1004,8 @@ NTSTATUS WINAPI NtQueryTimerResolution(OUT ULONG* min_resolution, +@@ -950,7 +978,8 @@ NTSTATUS WINAPI NtQueryTimerResolution(OUT ULONG* min_resolution, /****************************************************************************** * NtSetTimerResolution [NTDLL.@] */ @@ -1674,7 +1674,7 @@ IN BOOLEAN set_resolution, OUT ULONG* current_resolution ) { -@@ -1009,7 +1038,8 @@ static NTSTATUS wait_objects( DWORD count, const HANDLE *handles, +@@ -983,7 +1012,8 @@ static NTSTATUS wait_objects( DWORD count, const HANDLE *handles, /****************************************************************** * NtWaitForMultipleObjects (NTDLL.@) */ @@ -1684,7 +1684,7 @@ BOOLEAN wait_any, BOOLEAN alertable, const LARGE_INTEGER *timeout ) { -@@ -1020,7 +1050,8 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, +@@ -994,7 +1024,8 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, /****************************************************************** * NtWaitForSingleObject (NTDLL.@) */ @@ -1694,7 +1694,7 @@ { return wait_objects( 1, &handle, FALSE, alertable, timeout ); } -@@ -1029,7 +1060,8 @@ NTSTATUS WINAPI NtWaitForSingleObject(HANDLE handle, BOOLEAN alertable, const LA +@@ -1003,7 +1034,8 @@ NTSTATUS WINAPI NtWaitForSingleObject(HANDLE handle, BOOLEAN alertable, const LA /****************************************************************** * NtSignalAndWaitForSingleObject (NTDLL.@) */ @@ -1704,7 +1704,7 @@ BOOLEAN alertable, const LARGE_INTEGER *timeout ) { select_op_t select_op; -@@ -1048,7 +1080,8 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE hSignalObject, HANDLE hWa +@@ -1022,7 +1054,8 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE hSignalObject, HANDLE hWa /****************************************************************** * NtYieldExecution (NTDLL.@) */ @@ -1714,7 +1714,7 @@ { #ifdef HAVE_SCHED_YIELD sched_yield(); -@@ -1062,7 +1095,8 @@ NTSTATUS WINAPI NtYieldExecution(void) +@@ -1036,7 +1069,8 @@ NTSTATUS WINAPI NtYieldExecution(void) /****************************************************************** * NtDelayExecution (NTDLL.@) */ @@ -1724,7 +1724,7 @@ { /* if alertable, we need to query the server */ if (alertable) -@@ -1105,7 +1139,8 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou +@@ -1079,7 +1113,8 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou /****************************************************************************** * NtCreateKeyedEvent (NTDLL.@) */ @@ -1733,8 +1733,8 @@ +NTSTATUS WINAPI SYSCALL(NtCreateKeyedEvent)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, ULONG flags ) { - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; -@@ -1143,7 +1178,8 @@ NTSTATUS WINAPI NtCreateKeyedEvent( HANDLE *handle, ACCESS_MASK access, + NTSTATUS ret; +@@ -1104,7 +1139,8 @@ NTSTATUS WINAPI NtCreateKeyedEvent( HANDLE *handle, ACCESS_MASK access, /****************************************************************************** * NtOpenKeyedEvent (NTDLL.@) */ @@ -1742,9 +1742,9 @@ +DEFINE_SYSCALL_ENTRYPOINT( NtOpenKeyedEvent, 3 ); +NTSTATUS WINAPI SYSCALL(NtOpenKeyedEvent)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { - DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; -@@ -1166,7 +1202,8 @@ NTSTATUS WINAPI NtOpenKeyedEvent( HANDLE *handle, ACCESS_MASK access, const OBJE + +@@ -1127,7 +1163,8 @@ NTSTATUS WINAPI NtOpenKeyedEvent( HANDLE *handle, ACCESS_MASK access, const OBJE /****************************************************************************** * NtWaitForKeyedEvent (NTDLL.@) */ @@ -1754,7 +1754,7 @@ BOOLEAN alertable, const LARGE_INTEGER *timeout ) { select_op_t select_op; -@@ -1183,7 +1220,8 @@ NTSTATUS WINAPI NtWaitForKeyedEvent( HANDLE handle, const void *key, +@@ -1144,7 +1181,8 @@ NTSTATUS WINAPI NtWaitForKeyedEvent( HANDLE handle, const void *key, /****************************************************************************** * NtReleaseKeyedEvent (NTDLL.@) */ @@ -1764,17 +1764,17 @@ BOOLEAN alertable, const LARGE_INTEGER *timeout ) { select_op_t select_op; -@@ -1210,7 +1248,8 @@ NTSTATUS WINAPI NtReleaseKeyedEvent( HANDLE handle, const void *key, +@@ -1171,7 +1209,8 @@ NTSTATUS WINAPI NtReleaseKeyedEvent( HANDLE handle, const void *key, * NumberOfConcurrentThreads [I] desired number of concurrent active worker threads * */ -NTSTATUS WINAPI NtCreateIoCompletion( PHANDLE CompletionPort, ACCESS_MASK DesiredAccess, +DEFINE_SYSCALL_ENTRYPOINT( NtCreateIoCompletion, 4 ); +NTSTATUS WINAPI SYSCALL(NtCreateIoCompletion)( PHANDLE CompletionPort, ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, ULONG NumberOfConcurrentThreads ) + POBJECT_ATTRIBUTES attr, ULONG NumberOfConcurrentThreads ) { NTSTATUS status; -@@ -1250,7 +1289,8 @@ NTSTATUS WINAPI NtCreateIoCompletion( PHANDLE CompletionPort, ACCESS_MASK Desire +@@ -1212,7 +1251,8 @@ NTSTATUS WINAPI NtCreateIoCompletion( PHANDLE CompletionPort, ACCESS_MASK Desire * Status [I] operation status * NumberOfBytesTransferred [I] number of bytes transferred */ @@ -1784,7 +1784,7 @@ ULONG_PTR CompletionValue, NTSTATUS Status, SIZE_T NumberOfBytesTransferred ) { -@@ -1286,7 +1326,8 @@ NTSTATUS WINAPI NtSetIoCompletion( HANDLE CompletionPort, ULONG_PTR CompletionKe +@@ -1248,7 +1288,8 @@ NTSTATUS WINAPI NtSetIoCompletion( HANDLE CompletionPort, ULONG_PTR CompletionKe * WaitTime [I] optional wait time in NTDLL format * */ @@ -1794,17 +1794,17 @@ PULONG_PTR CompletionValue, PIO_STATUS_BLOCK iosb, PLARGE_INTEGER WaitTime ) { -@@ -1329,7 +1370,8 @@ NTSTATUS WINAPI NtRemoveIoCompletion( HANDLE CompletionPort, PULONG_PTR Completi +@@ -1291,7 +1332,8 @@ NTSTATUS WINAPI NtRemoveIoCompletion( HANDLE CompletionPort, PULONG_PTR Completi * ObjectAttributes [I] completion object name * */ --NTSTATUS WINAPI NtOpenIoCompletion( PHANDLE CompletionPort, ACCESS_MASK DesiredAccess, +-NTSTATUS WINAPI NtOpenIoCompletion( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) +DEFINE_SYSCALL_ENTRYPOINT( NtOpenIoCompletion, 3 ); -+NTSTATUS WINAPI SYSCALL(NtOpenIoCompletion)( PHANDLE CompletionPort, ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes ) ++NTSTATUS WINAPI SYSCALL(NtOpenIoCompletion)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { NTSTATUS status; -@@ -1366,7 +1408,8 @@ NTSTATUS WINAPI NtOpenIoCompletion( PHANDLE CompletionPort, ACCESS_MASK DesiredA + +@@ -1326,7 +1368,8 @@ NTSTATUS WINAPI NtOpenIoCompletion( HANDLE *handle, ACCESS_MASK access, const OB * RequiredLength [O] required buffer length * */ @@ -1815,7 +1815,7 @@ { NTSTATUS status; diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c -index aaf7a71..41f93be 100644 +index 0b68185..7d9d2d7 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -599,7 +599,8 @@ ULONG WINAPI RtlGetNtGlobalFlags(void) @@ -1898,7 +1898,7 @@ { NTSTATUS ret; DWORD dummy, i; -@@ -823,7 +831,8 @@ static inline unsigned int get_server_context_flags( DWORD flags ) +@@ -825,7 +833,8 @@ static inline unsigned int get_server_context_flags( DWORD flags ) * NtGetContextThread (NTDLL.@) * ZwGetContextThread (NTDLL.@) */ @@ -1908,7 +1908,7 @@ { NTSTATUS ret; DWORD dummy, i; -@@ -910,7 +919,8 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) +@@ -914,7 +923,8 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) * NtQueryInformationThread (NTDLL.@) * ZwQueryInformationThread (NTDLL.@) */ @@ -1918,7 +1918,7 @@ void *data, ULONG length, ULONG *ret_len ) { NTSTATUS status; -@@ -1154,7 +1164,8 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, +@@ -1158,7 +1168,8 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, * NtSetInformationThread (NTDLL.@) * ZwSetInformationThread (NTDLL.@) */ @@ -1928,7 +1928,7 @@ LPCVOID data, ULONG length ) { NTSTATUS status; -@@ -1313,7 +1324,8 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, +@@ -1317,7 +1328,8 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, * Return the processor, on which the thread is running * */ @@ -1983,7 +1983,7 @@ struct timeval tv; time_t tm_t; diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c -index 4d4bc3b..f30d94a 100644 +index c57524a..a65d206 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -1857,7 +1857,8 @@ void virtual_set_large_address_space(void) @@ -2056,7 +2056,7 @@ const LARGE_INTEGER *size, ULONG protect, ULONG sec_flags, HANDLE file ) { -@@ -2510,7 +2517,8 @@ NTSTATUS WINAPI NtCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJEC +@@ -2495,7 +2502,8 @@ NTSTATUS WINAPI NtCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJEC * NtOpenSection (NTDLL.@) * ZwOpenSection (NTDLL.@) */ @@ -2065,8 +2065,8 @@ +NTSTATUS WINAPI SYSCALL(NtOpenSection)( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr ) { NTSTATUS ret; - DWORD len = attr->ObjectName->Length; -@@ -2534,7 +2542,8 @@ NTSTATUS WINAPI NtOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ + +@@ -2520,7 +2528,8 @@ NTSTATUS WINAPI NtOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ * NtMapViewOfSection (NTDLL.@) * ZwMapViewOfSection (NTDLL.@) */ @@ -2076,7 +2076,7 @@ SIZE_T commit_size, const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr, SECTION_INHERIT inherit, ULONG alloc_type, ULONG protect ) { -@@ -2732,7 +2741,8 @@ done: +@@ -2718,7 +2727,8 @@ done: * NtUnmapViewOfSection (NTDLL.@) * ZwUnmapViewOfSection (NTDLL.@) */ @@ -2086,7 +2086,7 @@ { struct file_view *view; NTSTATUS status = STATUS_NOT_MAPPED_VIEW; -@@ -2768,7 +2778,8 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr ) +@@ -2754,7 +2764,8 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr ) * NtFlushVirtualMemory (NTDLL.@) * ZwFlushVirtualMemory (NTDLL.@) */ @@ -2096,7 +2096,7 @@ SIZE_T *size_ptr, ULONG unknown ) { struct file_view *view; -@@ -2816,7 +2827,8 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr, +@@ -2802,7 +2813,8 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr, * NtGetWriteWatch (NTDLL.@) * ZwGetWriteWatch (NTDLL.@) */ @@ -2106,7 +2106,7 @@ ULONG_PTR *count, ULONG *granularity ) { struct file_view *view; -@@ -2864,7 +2876,8 @@ NTSTATUS WINAPI NtGetWriteWatch( HANDLE process, ULONG flags, PVOID base, SIZE_T +@@ -2850,7 +2862,8 @@ NTSTATUS WINAPI NtGetWriteWatch( HANDLE process, ULONG flags, PVOID base, SIZE_T * NtResetWriteWatch (NTDLL.@) * ZwResetWriteWatch (NTDLL.@) */ @@ -2116,7 +2116,7 @@ { struct file_view *view; NTSTATUS status = STATUS_SUCCESS; -@@ -2893,7 +2906,8 @@ NTSTATUS WINAPI NtResetWriteWatch( HANDLE process, PVOID base, SIZE_T size ) +@@ -2879,7 +2892,8 @@ NTSTATUS WINAPI NtResetWriteWatch( HANDLE process, PVOID base, SIZE_T size ) * NtReadVirtualMemory (NTDLL.@) * ZwReadVirtualMemory (NTDLL.@) */ @@ -2126,7 +2126,7 @@ SIZE_T size, SIZE_T *bytes_read ) { NTSTATUS status; -@@ -2923,7 +2937,8 @@ NTSTATUS WINAPI NtReadVirtualMemory( HANDLE process, const void *addr, void *buf +@@ -2909,7 +2923,8 @@ NTSTATUS WINAPI NtReadVirtualMemory( HANDLE process, const void *addr, void *buf * NtWriteVirtualMemory (NTDLL.@) * ZwWriteVirtualMemory (NTDLL.@) */ @@ -2136,7 +2136,7 @@ SIZE_T size, SIZE_T *bytes_written ) { NTSTATUS status; -@@ -2953,7 +2968,8 @@ NTSTATUS WINAPI NtWriteVirtualMemory( HANDLE process, void *addr, const void *bu +@@ -2939,7 +2954,8 @@ NTSTATUS WINAPI NtWriteVirtualMemory( HANDLE process, void *addr, const void *bu * NtAreMappedFilesTheSame (NTDLL.@) * ZwAreMappedFilesTheSame (NTDLL.@) */ @@ -2147,5 +2147,5 @@ struct file_view *view1, *view2; struct stat st1, st2; -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemHandleInformation/0001-server-Implement-wineserver-call-for-SystemHandleInf.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemHandleInformation/0001-server-Implement-wineserver-call-for-SystemHandleInf.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemHandleInformation/0001-server-Implement-wineserver-call-for-SystemHandleInf.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemHandleInformation/0001-server-Implement-wineserver-call-for-SystemHandleInf.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,231 +0,0 @@ -From 1703d568d9756fbf3d6a11889386ff9355f33755 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Thu, 24 Dec 2015 13:08:50 +0100 -Subject: server: Implement wineserver call for SystemHandleInformation. (v2) - -Signed-off-by: Sebastian Lackner ---- - dlls/ntdll/nt.c | 49 ++++++++++++++++++++++++++++++++++++------- - dlls/ntdll/tests/info.c | 10 ++++----- - server/handle.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ - server/protocol.def | 16 ++++++++++++++ - server/trace.c | 17 +++++++++++++++ - 5 files changed, 135 insertions(+), 13 deletions(-) - -diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c -index 8ea1ddd..55255a8 100644 ---- a/dlls/ntdll/nt.c -+++ b/dlls/ntdll/nt.c -@@ -2004,18 +2004,51 @@ NTSTATUS WINAPI NtQuerySystemInformation( - break; - case SystemHandleInformation: - { -- SYSTEM_HANDLE_INFORMATION shi; -+ struct handle_info *info; -+ DWORD i, num_handles; - -- memset(&shi, 0, sizeof(shi)); -- len = sizeof(shi); -+ if (Length < sizeof(SYSTEM_HANDLE_INFORMATION)) -+ { -+ ret = STATUS_INFO_LENGTH_MISMATCH; -+ break; -+ } - -- if ( Length >= len) -+ if (!SystemInformation) - { -- if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION; -- else memcpy( SystemInformation, &shi, len); -+ ret = STATUS_ACCESS_VIOLATION; -+ break; - } -- else ret = STATUS_INFO_LENGTH_MISMATCH; -- FIXME("info_class SYSTEM_HANDLE_INFORMATION\n"); -+ -+ num_handles = (Length - FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION, Handle )) / sizeof(SYSTEM_HANDLE_ENTRY); -+ if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*info) * num_handles ))) -+ return STATUS_NO_MEMORY; -+ -+ SERVER_START_REQ( get_system_handles ) -+ { -+ wine_server_set_reply( req, info, sizeof(*info) * num_handles ); -+ if (!(ret = wine_server_call( req ))) -+ { -+ SYSTEM_HANDLE_INFORMATION *shi = SystemInformation; -+ shi->Count = wine_server_reply_size( req ) / sizeof(*info); -+ len = FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION, Handle[shi->Count] ); -+ for (i = 0; i < shi->Count; i++) -+ { -+ memset( &shi->Handle[i], 0, sizeof(shi->Handle[i]) ); -+ shi->Handle[i].OwnerPid = info[i].owner; -+ shi->Handle[i].HandleValue = info[i].handle; -+ shi->Handle[i].AccessMask = info[i].access; -+ /* FIXME: Fill out ObjectType, HandleFlags, ObjectPointer */ -+ } -+ } -+ else if (ret == STATUS_BUFFER_TOO_SMALL) -+ { -+ len = FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION, Handle[reply->count] ); -+ ret = STATUS_INFO_LENGTH_MISMATCH; -+ } -+ } -+ SERVER_END_REQ; -+ -+ RtlFreeHeap( GetProcessHeap(), 0, info ); - } - break; - case SystemCacheInformation: -diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c -index 3219dbb..da509aa 100644 ---- a/dlls/ntdll/tests/info.c -+++ b/dlls/ntdll/tests/info.c -@@ -487,7 +487,7 @@ static void test_query_handle(void) - /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */ - ReturnLength = 0xdeadbeef; - status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength); -- todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); -+ ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); - ok( ReturnLength != 0xdeadbeef, "Expected valid ReturnLength\n" ); - - SystemInformationLength = ReturnLength; -@@ -503,13 +503,13 @@ static void test_query_handle(void) - } - ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status ); - ExpectedLength = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION, Handle[shi->Count]); -- todo_wine ok( ReturnLength == ExpectedLength || broken(ReturnLength == ExpectedLength - sizeof(DWORD)), /* Vista / 2008 */ -- "Expected length %u, got %u\n", ExpectedLength, ReturnLength ); -- todo_wine ok( shi->Count > 1, "Expected more than 1 handle, got %u\n", shi->Count ); -+ ok( ReturnLength == ExpectedLength || broken(ReturnLength == ExpectedLength - sizeof(DWORD)), /* Vista / 2008 */ -+ "Expected length %u, got %u\n", ExpectedLength, ReturnLength ); -+ ok( shi->Count > 1, "Expected more than 1 handle, got %u\n", shi->Count ); - for (i = 0, found = FALSE; i < shi->Count && !found; i++) - found = (shi->Handle[i].OwnerPid == GetCurrentProcessId()) && - ((HANDLE)(ULONG_PTR)shi->Handle[i].HandleValue == EventHandle); -- todo_wine ok( found, "Expected to find event handle in handle list\n" ); -+ ok( found, "Expected to find event handle in handle list\n" ); - - CloseHandle(EventHandle); - -diff --git a/server/handle.c b/server/handle.c -index 5043ff7..05d71ba 100644 ---- a/server/handle.c -+++ b/server/handle.c -@@ -745,3 +745,59 @@ DECL_HANDLER(get_security_object) - - release_object( obj ); - } -+ -+struct enum_handle_info -+{ -+ unsigned int count; -+ struct handle_info *handle; -+}; -+ -+static int enum_handles( struct process *process, void *user ) -+{ -+ struct enum_handle_info *info = user; -+ struct handle_table *table = process->handles; -+ struct handle_entry *entry; -+ struct handle_info *handle; -+ unsigned int i; -+ -+ if (!table) -+ return 0; -+ -+ for (i = 0, entry = table->entries; i <= table->last; i++, entry++) -+ { -+ if (!entry->ptr) continue; -+ if (!info->handle) -+ { -+ info->count++; -+ continue; -+ } -+ assert( info->count ); -+ handle = info->handle++; -+ handle->owner = process->id; -+ handle->handle = index_to_handle(i); -+ handle->access = entry->access & ~RESERVED_ALL; -+ info->count--; -+ } -+ -+ return 0; -+} -+ -+DECL_HANDLER(get_system_handles) -+{ -+ struct enum_handle_info info; -+ struct handle_info *handle; -+ data_size_t max_handles = get_reply_max_size() / sizeof(*handle); -+ -+ info.handle = NULL; -+ info.count = 0; -+ enum_processes( enum_handles, &info ); -+ reply->count = info.count; -+ -+ if (max_handles < info.count) -+ set_error( STATUS_BUFFER_TOO_SMALL ); -+ else if ((handle = set_reply_data_size( info.count * sizeof(*handle) ))) -+ { -+ info.handle = handle; -+ enum_processes( enum_handles, &info ); -+ } -+} -diff --git a/server/protocol.def b/server/protocol.def -index bfb9089..ea5bd61 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -3266,6 +3266,22 @@ enum coords_relative - VARARG(sd,security_descriptor); /* retrieved security descriptor */ - @END - -+ -+struct handle_info -+{ -+ process_id_t owner; -+ obj_handle_t handle; -+ unsigned int access; -+}; -+ -+/* Return a list of all opened handles */ -+@REQ(get_system_handles) -+@REPLY -+ unsigned int count; /* number of handles */ -+ VARARG(data,handle_infos); /* array of handle_infos */ -+@END -+ -+ - /* Create a mailslot */ - @REQ(create_mailslot) - unsigned int access; /* wanted access rights */ -diff --git a/server/trace.c b/server/trace.c -index 405a1c9..8a26fdb 100644 ---- a/server/trace.c -+++ b/server/trace.c -@@ -1142,6 +1142,23 @@ static void dump_varargs_rawinput_devices(const char *prefix, data_size_t size ) - fputc( '}', stderr ); - } - -+static void dump_varargs_handle_infos( const char *prefix, data_size_t size ) -+{ -+ const struct handle_info *handle; -+ -+ fprintf( stderr, "%s{", prefix ); -+ while (size >= sizeof(*handle)) -+ { -+ handle = cur_data; -+ fprintf( stderr, "{owner=%04x,handle=%04x,access=%08x}", -+ handle->owner, handle->handle, handle->access ); -+ size -= sizeof(*handle); -+ remove_data( sizeof(*handle) ); -+ if (size) fputc( ',', stderr ); -+ } -+ fputc( '}', stderr ); -+} -+ - typedef void (*dump_func)( const void *req ); - - /* Everything below this line is generated automatically by tools/make_requests */ --- -2.6.4 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemHandleInformation/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemHandleInformation/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemHandleInformation/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemHandleInformation/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Fixes: Implement SystemHandleInformation info class diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemInterruptInformation/0001-ntdll-Return-buffer-filled-with-random-values-from-S.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemInterruptInformation/0001-ntdll-Return-buffer-filled-with-random-values-from-S.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemInterruptInformation/0001-ntdll-Return-buffer-filled-with-random-values-from-S.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemInterruptInformation/0001-ntdll-Return-buffer-filled-with-random-values-from-S.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,39 @@ +From e42cdb8305dcebca77afba4a56e59391f2cb4a38 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 7 Jan 2016 06:01:01 +0100 +Subject: ntdll: Return buffer filled with random values from + SystemInterruptInformation. + +--- + dlls/ntdll/nt.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c +index 9ee1923..fe3e8e8 100644 +--- a/dlls/ntdll/nt.c ++++ b/dlls/ntdll/nt.c +@@ -2070,10 +2070,21 @@ NTSTATUS WINAPI NtQuerySystemInformation( + case SystemInterruptInformation: + { + SYSTEM_INTERRUPT_INFORMATION sii; ++ int dev_random; + + memset(&sii, 0, sizeof(sii)); + len = sizeof(sii); + ++ /* Some applications use the returned buffer for random number ++ * generation. Its unlikely that an app depends on the exact ++ * layout, so just fill with values from /dev/urandom. */ ++ dev_random = open( "/dev/urandom", O_RDONLY ); ++ if (dev_random != -1) ++ { ++ read( dev_random, &sii, sizeof(sii) ); ++ close( dev_random ); ++ } ++ + if ( Length >= len) + { + if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemInterruptInformation/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemInterruptInformation/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemInterruptInformation/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemInterruptInformation/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [39123] Return buffer filled with random values from SystemInterruptInformation diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/0001-include-Add-more-constants-to-SYSTEM_INFORMATION_CLA.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/0001-include-Add-more-constants-to-SYSTEM_INFORMATION_CLA.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/0001-include-Add-more-constants-to-SYSTEM_INFORMATION_CLA.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/0001-include-Add-more-constants-to-SYSTEM_INFORMATION_CLA.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,70 @@ +From 8ffb502a5289e9bd56ae02d292f19c67b94e2b19 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 21 Jan 2016 00:28:15 +0100 +Subject: include: Add more constants to SYSTEM_INFORMATION_CLASS. + +--- + include/winternl.h | 46 +++++++++++++++++++++++++++------------------- + 1 file changed, 27 insertions(+), 19 deletions(-) + +diff --git a/include/winternl.h b/include/winternl.h +index 3494c00..e665a47 100644 +--- a/include/winternl.h ++++ b/include/winternl.h +@@ -822,26 +822,34 @@ typedef enum _SYSTEM_INFORMATION_CLASS { + SystemVerifierInformation = 51, + SystemAddVerifier = 52, + SystemSessionProcessesInformation = 53, +- Unknown54, +- Unknown55, +- Unknown56, +- Unknown57, +- Unknown58, +- Unknown59, +- Unknown60, +- Unknown61, +- Unknown62, +- Unknown63, +- Unknown64, +- Unknown65, +- Unknown66, +- Unknown67, +- Unknown68, +- Unknown69, +- Unknown70, +- Unknown71, +- Unknown72, ++ SystemLoadGdiDriverInSystemSpace = 54, ++ SystemNumaProcessorMap = 55, ++ SystemPrefetcherInformation = 56, ++ SystemExtendedProcessInformation = 57, ++ SystemRecommendedSharedDataAlignment = 58, ++ SystemComPlusPackage = 59, ++ SystemNumaAvailableMemory = 60, ++ SystemProcessorPowerInformation = 61, ++ SystemEmulationBasicInformation = 62, ++ SystemEmulationProcessorInformation = 63, ++ SystemExtendedHandleInformation = 64, ++ SystemLostDelayedWriteInformation = 65, ++ SystemBigPoolInformation = 66, ++ SystemSessionPoolTagInformation = 67, ++ SystemSessionMappedViewInformation = 68, ++ SystemHotpatchInformation = 69, ++ SystemObjectSecurityMode = 70, ++ SystemWatchdogTimerHandler = 71, ++ SystemWatchdogTimerInformation = 72, + SystemLogicalProcessorInformation = 73, ++ SystemWow64SharedInformation = 74, ++ SystemRegisterFirmwareTableInformationHandler = 75, ++ SystemFirmwareTableInformation = 76, ++ SystemModuleInformationEx = 77, ++ SystemVerifierTriageInformation = 78, ++ SystemSuperfetchInformation = 79, ++ SystemMemoryListInformation = 80, ++ SystemFileCacheInformationEx = 81, + SystemLogicalProcessorInformationEx = 107, + SystemInformationClassMax + } SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/0002-ntdll-Implement-SystemRecommendedSharedDataAlignment.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/0002-ntdll-Implement-SystemRecommendedSharedDataAlignment.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/0002-ntdll-Implement-SystemRecommendedSharedDataAlignment.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/0002-ntdll-Implement-SystemRecommendedSharedDataAlignment.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,70 @@ +From f5437d47185217d5c82ae09301ad92a6d22e55c9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 21 Jan 2016 00:30:31 +0100 +Subject: ntdll: Implement SystemRecommendedSharedDataAlignment class in + NtQuerySystemInformation. + +--- + dlls/ntdll/nt.c | 11 +++++++++++ + dlls/ntdll/tests/info.c | 16 ++++++++++++++++ + 2 files changed, 27 insertions(+) + +diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c +index 9ee1923..e28b21f 100644 +--- a/dlls/ntdll/nt.c ++++ b/dlls/ntdll/nt.c +@@ -2155,6 +2155,17 @@ NTSTATUS WINAPI NtQuerySystemInformation( + RtlFreeHeap(GetProcessHeap(), 0, buf); + } + break; ++ case SystemRecommendedSharedDataAlignment: ++ { ++ len = sizeof(DWORD); ++ if (Length >= len) ++ { ++ if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION; ++ else *((DWORD *)SystemInformation) = 64; ++ } ++ else ret = STATUS_INFO_LENGTH_MISMATCH; ++ } ++ break; + default: + FIXME("(0x%08x,%p,0x%08x,%p) stub\n", + SystemInformationClass,SystemInformation,Length,ResultLength); +diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c +index 252736e..e8ad0bf 100644 +--- a/dlls/ntdll/tests/info.c ++++ b/dlls/ntdll/tests/info.c +@@ -1929,6 +1929,19 @@ static void test_thread_start_address(void) + CloseHandle(thread); + } + ++static void test_query_data_alignment(void) ++{ ++ ULONG ReturnLength; ++ NTSTATUS status; ++ DWORD value; ++ ++ value = 0xdeadbeef; ++ status = pNtQuerySystemInformation(SystemRecommendedSharedDataAlignment, &value, sizeof(value), &ReturnLength); ++ ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ++ ok(sizeof(value) == ReturnLength, "Inconsistent length %u\n", ReturnLength); ++ ok(value == 64, "Expected 64, got %u\n", value); ++} ++ + START_TEST(info) + { + char **argv; +@@ -1995,6 +2008,9 @@ START_TEST(info) + test_query_logicalproc(); + test_query_logicalprocex(); + ++ trace("Starting test_query_data_alignment()\n"); ++ test_query_data_alignment(); ++ + /* NtPowerInformation */ + + /* 0xb ProcessorInformation */ +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemRecommendedSharedDataAlignment/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Implement SystemRecommendedSharedDataAlignment class in NtQuerySystemInformation diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemRoot_Symlink/0001-ntdll-Add-special-handling-for-SystemRoot-to-satisfy.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemRoot_Symlink/0001-ntdll-Add-special-handling-for-SystemRoot-to-satisfy.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-SystemRoot_Symlink/0001-ntdll-Add-special-handling-for-SystemRoot-to-satisfy.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-SystemRoot_Symlink/0001-ntdll-Add-special-handling-for-SystemRoot-to-satisfy.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,15 +1,15 @@ -From fc9e2809d5ace76166250a4af312f167c7d40af7 Mon Sep 17 00:00:00 2001 +From c3a457db84cd6c95bbce802329840befdbe9057f Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 17 Aug 2015 06:17:33 +0200 Subject: ntdll: Add special handling for \SystemRoot to satisfy MSYS2 case-insensitive system check. --- - dlls/ntdll/om.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) + dlls/ntdll/om.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c -index c28a82a..ef17b1d 100644 +index a45de9c..0c3f69e 100644 --- a/dlls/ntdll/om.c +++ b/dlls/ntdll/om.c @@ -39,6 +39,7 @@ @@ -20,24 +20,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll); -@@ -623,7 +624,9 @@ DEFINE_SYSCALL_ENTRYPOINT( NtOpenSymbolicLinkObject, 3 ); - NTSTATUS WINAPI SYSCALL(NtOpenSymbolicLinkObject)(OUT PHANDLE LinkHandle, IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes) +@@ -615,6 +616,7 @@ DEFINE_SYSCALL_ENTRYPOINT( NtOpenSymbolicLinkObject, 3 ); + NTSTATUS WINAPI SYSCALL(NtOpenSymbolicLinkObject)( HANDLE *handle, ACCESS_MASK access, + const OBJECT_ATTRIBUTES *attr) { + static const WCHAR SystemRootW[] = {'\\','S','y','s','t','e','m','R','o','o','t'}; NTSTATUS ret; -+ - TRACE("(%p,0x%08x,%s)\n",LinkHandle, DesiredAccess, debugstr_ObjectAttributes(ObjectAttributes)); - if (!LinkHandle) return STATUS_ACCESS_VIOLATION; -@@ -638,6 +641,16 @@ NTSTATUS WINAPI SYSCALL(NtOpenSymbolicLinkObject)(OUT PHANDLE LinkHandle, IN ACC - return STATUS_OBJECT_PATH_SYNTAX_BAD; - } + TRACE("(%p,0x%08x,%s)\n", handle, access, debugstr_ObjectAttributes(attr)); +@@ -622,6 +624,16 @@ NTSTATUS WINAPI SYSCALL(NtOpenSymbolicLinkObject)( HANDLE *handle, ACCESS_MASK a + if (!handle) return STATUS_ACCESS_VIOLATION; + if ((ret = validate_open_object_attributes( attr ))) return ret; + /* MSYS2 tries to open \\SYSTEMROOT to check for case-insensitive systems */ -+ if (!DesiredAccess && !ObjectAttributes->RootDirectory && -+ ObjectAttributes->ObjectName->Length == sizeof(SystemRootW) && -+ !memicmpW( ObjectAttributes->ObjectName->Buffer, SystemRootW, ++ if (!access && !attr->RootDirectory && ++ attr->ObjectName->Length == sizeof(SystemRootW) && ++ !memicmpW( attr->ObjectName->Buffer, SystemRootW, + sizeof(SystemRootW)/sizeof(WCHAR) )) + { + TRACE( "returning STATUS_ACCESS_DENIED\n" ); @@ -46,7 +44,7 @@ + SERVER_START_REQ(open_symlink) { - req->access = DesiredAccess; + req->access = access; -- -2.6.1 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Unused_Import_Descr/0001-ntdll-Skip-unused-import-descriptors-when-loading-li.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Unused_Import_Descr/0001-ntdll-Skip-unused-import-descriptors-when-loading-li.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Unused_Import_Descr/0001-ntdll-Skip-unused-import-descriptors-when-loading-li.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Unused_Import_Descr/0001-ntdll-Skip-unused-import-descriptors-when-loading-li.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,36 @@ +From 62e17ad9aac4093654a2347aca9fd62f9e0499a8 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 7 Jan 2016 04:07:25 +0100 +Subject: ntdll: Skip unused import descriptors when loading libraries. + +--- + dlls/ntdll/loader.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c +index 74feb97..d552a32 100644 +--- a/dlls/ntdll/loader.c ++++ b/dlls/ntdll/loader.c +@@ -901,7 +901,18 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path ) + status = STATUS_SUCCESS; + for (i = 0; i < nb_imports; i++) + { +- if (!(wm->deps[i] = import_dll( wm->ldr.BaseAddress, &imports[i], load_path ))) ++ const IMAGE_IMPORT_DESCRIPTOR *descr = &imports[i]; ++ const IMAGE_THUNK_DATA *import_list = get_rva( wm->ldr.BaseAddress, descr->u.OriginalFirstThunk ? ++ (DWORD)descr->u.OriginalFirstThunk : (DWORD)descr->FirstThunk ); ++ if (!import_list->u1.Ordinal) ++ { ++ const char *name = get_rva( wm->ldr.BaseAddress, descr->Name ); ++ WARN( "Skipping unused import %s\n", debugstr_a(name) ); ++ wm->deps[i] = NULL; ++ continue; ++ } ++ ++ if (!(wm->deps[i] = import_dll( wm->ldr.BaseAddress, descr, load_path ))) + status = STATUS_DLL_NOT_FOUND; + } + current_modref = prev; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Unused_Import_Descr/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Unused_Import_Descr/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-Unused_Import_Descr/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-Unused_Import_Descr/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [39792] Ignore import descriptors with empty thunk list diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-WinSqm/0001-ntdll-Add-stubs-for-WinSqmStartSession-WinSqmEndSess.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-WinSqm/0001-ntdll-Add-stubs-for-WinSqmStartSession-WinSqmEndSess.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-WinSqm/0001-ntdll-Add-stubs-for-WinSqmStartSession-WinSqmEndSess.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-WinSqm/0001-ntdll-Add-stubs-for-WinSqmStartSession-WinSqmEndSess.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From ff1be4d15b2114de6b785c164ddc27fd6993c6f8 Mon Sep 17 00:00:00 2001 +From d02606aaa6cbdbb1939cfe99b6d5f013af5c48a6 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 25 Dec 2014 12:36:28 -0700 Subject: ntdll: Add stubs for WinSqmStartSession / WinSqmEndSession. @@ -11,7 +11,7 @@ 3 files changed, 76 insertions(+) diff --git a/dlls/ntdll/misc.c b/dlls/ntdll/misc.c -index 2cfa900..7832d37 100644 +index 5469116..4517aec 100644 --- a/dlls/ntdll/misc.c +++ b/dlls/ntdll/misc.c @@ -27,6 +27,8 @@ @@ -20,10 +20,10 @@ +#include "ntstatus.h" +#define WIN32_NO_STATUS - #include "wine/library.h" - #include "wine/debug.h" - #include "ntdll_misc.h" -@@ -328,6 +330,15 @@ void * __cdecl _lfind( const void *key, const void *base, unsigned int *nmemb, + #include "windows.h" + #include "wmistr.h" + #include "evntrace.h" +@@ -332,6 +334,15 @@ void * __cdecl _lfind( const void *key, const void *base, unsigned int *nmemb, } /********************************************************************* @@ -39,12 +39,10 @@ * WinSqmIsOptedIn (NTDLL.@) */ BOOL WINAPI WinSqmIsOptedIn(void) -@@ -335,3 +346,12 @@ BOOL WINAPI WinSqmIsOptedIn(void) - FIXME("() stub\n"); - return FALSE; +@@ -341,6 +352,15 @@ BOOL WINAPI WinSqmIsOptedIn(void) } -+ -+/********************************************************************* + + /********************************************************************* + * WinSqmStartSession (NTDLL.@) + */ +PVOID WINAPI WinSqmStartSession(PVOID unknown1, DWORD unknown2, DWORD unknown3) @@ -52,18 +50,27 @@ + FIXME("(%p, 0x%x, 0x%x) stub!\n", unknown1, unknown2, unknown3); + return NULL; +} ++ ++/********************************************************************* + * EtwEventRegister (NTDLL.@) + */ + ULONG WINAPI EtwEventRegister( LPCGUID provider, PENABLECALLBACK callback, PVOID context, PREGHANDLE handle ) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 28165ef..9225898 100644 +index d6ded19..0c23514 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec -@@ -971,3 +971,5 @@ +@@ -1011,7 +1011,9 @@ + @ stdcall TpWaitForWait(ptr long) + @ stdcall TpWaitForWork(ptr long) @ stdcall -ret64 VerSetConditionMask(int64 long long) +@ stdcall WinSqmEndSession(ptr) @ stdcall WinSqmIsOptedIn() +@ stdcall WinSqmStartSession(ptr long long) @ stdcall ZwAcceptConnectPort(ptr long ptr long long ptr) NtAcceptConnectPort + @ stdcall ZwAccessCheck(ptr long long ptr ptr ptr ptr ptr) NtAccessCheck + @ stdcall ZwAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr) NtAccessCheckAndAuditAlarm diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c -index e8eb04a..7b5f07d 100644 +index 94a22ac..d382691 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -62,6 +62,9 @@ static inline USHORT __my_ushort_swap(USHORT s) @@ -76,7 +83,7 @@ static SIZE_T (WINAPI *pRtlCompareMemory)(LPCVOID,LPCVOID,SIZE_T); static SIZE_T (WINAPI *pRtlCompareMemoryUlong)(PULONG, SIZE_T, ULONG); static NTSTATUS (WINAPI *pRtlDeleteTimer)(HANDLE, HANDLE, HANDLE); -@@ -109,6 +112,9 @@ static void InitFunctionPtrs(void) +@@ -115,6 +118,9 @@ static void InitFunctionPtrs(void) hntdll = LoadLibraryA("ntdll.dll"); ok(hntdll != 0, "LoadLibrary failed\n"); if (hntdll) { @@ -86,7 +93,7 @@ pRtlCompareMemory = (void *)GetProcAddress(hntdll, "RtlCompareMemory"); pRtlCompareMemoryUlong = (void *)GetProcAddress(hntdll, "RtlCompareMemoryUlong"); pRtlDeleteTimer = (void *)GetProcAddress(hntdll, "RtlDeleteTimer"); -@@ -149,6 +155,48 @@ static void InitFunctionPtrs(void) +@@ -161,6 +167,48 @@ static void InitFunctionPtrs(void) ok(strlen(src) == 15, "Source must be 16 bytes long!\n"); } @@ -135,7 +142,7 @@ #define COMP(str1,str2,cmplen,len) size = pRtlCompareMemory(str1, str2, cmplen); \ ok(size == len, "Expected %ld, got %ld\n", size, (SIZE_T)len) -@@ -1603,6 +1651,12 @@ START_TEST(rtl) +@@ -2060,6 +2108,12 @@ START_TEST(rtl) { InitFunctionPtrs(); @@ -149,5 +156,5 @@ test_RtlCompareMemoryUlong(); test_RtlMoveMemory(); -- -2.3.5 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-WinSqm/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-WinSqm/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-WinSqm/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-WinSqm/definition 2016-02-08 20:07:32.000000000 +0000 @@ -1 +1,2 @@ Fixes: [31971] ntdll is missing WinSqm[Start|End]Session implementation +Depends: ntdll-EtwRegisterTraceGuids diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0001-ntdll-Allow-to-set-debug-registers-separately-in-NtS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0001-ntdll-Allow-to-set-debug-registers-separately-in-NtS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0001-ntdll-Allow-to-set-debug-registers-separately-in-NtS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0001-ntdll-Allow-to-set-debug-registers-separately-in-NtS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -From abaac4383f22f06b4d6e703d243f30de4bf90229 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sun, 29 Nov 2015 00:34:04 +0100 -Subject: ntdll: Allow to set debug registers separately in NtSetContextThread. - ---- - dlls/ntdll/signal_x86_64.c | 24 ++++++++++++++++++++++-- - 1 file changed, 22 insertions(+), 2 deletions(-) - -diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c -index 524de68..02710a4 100644 ---- a/dlls/ntdll/signal_x86_64.c -+++ b/dlls/ntdll/signal_x86_64.c -@@ -1800,11 +1800,12 @@ __ASM_GLOBAL_FUNC( RtlCaptureContext, - "ret" ); - - /*********************************************************************** -- * set_cpu_context -+ * __wine_restore_regs - * - * Set the new CPU context. - */ --__ASM_GLOBAL_FUNC( set_cpu_context, -+extern void __wine_restore_regs( const CONTEXT *context ); -+__ASM_GLOBAL_FUNC( __wine_restore_regs, - "subq $40,%rsp\n\t" - __ASM_CFI(".cfi_adjust_cfa_offset 40\n\t") - "ldmxcsr 0x34(%rdi)\n\t" /* context->MxCsr */ -@@ -1852,6 +1853,25 @@ __ASM_GLOBAL_FUNC( set_cpu_context, - "movq 0xb0(%rdi),%rdi\n\t" /* context->Rdi */ - "iretq" ); - -+ -+/*********************************************************************** -+ * set_cpu_context -+ * -+ * Set the new CPU context. Used by NtSetContextThread. -+ */ -+void set_cpu_context( const CONTEXT *context ) -+{ -+ DWORD flags = context->ContextFlags & ~CONTEXT_AMD64; -+ if (flags & CONTEXT_FULL) -+ { -+ if (!(flags & CONTEXT_CONTROL)) -+ FIXME( "setting partial context (%x) not supported\n", flags ); -+ else -+ __wine_restore_regs( context ); -+ } -+} -+ -+ - /*********************************************************************** - * copy_context - * --- -2.6.4 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0002-ntdll-Receive-debug-registers-from-server-on-x86_64.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0002-ntdll-Receive-debug-registers-from-server-on-x86_64.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0002-ntdll-Receive-debug-registers-from-server-on-x86_64.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0002-ntdll-Receive-debug-registers-from-server-on-x86_64.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -From 71095e2e64ba74798bc037ad25ec9a14d59dbd4b Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 28 Dec 2015 01:59:47 +0100 -Subject: ntdll: Receive debug registers from server on x86_64. - ---- - dlls/ntdll/thread.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c -index aaf7a71..1455eb1 100644 ---- a/dlls/ntdll/thread.c -+++ b/dlls/ntdll/thread.c -@@ -830,9 +830,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) - DWORD needed_flags = context->ContextFlags; - BOOL self = (handle == GetCurrentThread()); - -+ /* on i386/amd64 debug registers always require a server call */ - #ifdef __i386__ -- /* on i386 debug registers always require a server call */ - if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386)) self = FALSE; -+#elif defined(__x86_64__) -+ if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_AMD64)) self = FALSE; - #endif - - if (!self) --- -2.6.4 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0003-ntdll-tests-Add-tests-for-setting-debug-registers-wi.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0003-ntdll-tests-Add-tests-for-setting-debug-registers-wi.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0003-ntdll-tests-Add-tests-for-setting-debug-registers-wi.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/0003-ntdll-tests-Add-tests-for-setting-debug-registers-wi.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -From 2db0a83315fbe9f84369f0123ad1b5f27a4b202e Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 28 Dec 2015 03:00:56 +0100 -Subject: ntdll/tests: Add tests for setting debug registers with - NtSetContextThread. - ---- - dlls/ntdll/tests/exception.c | 79 ++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 79 insertions(+) - -diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c -index a368997..f355513 100644 ---- a/dlls/ntdll/tests/exception.c -+++ b/dlls/ntdll/tests/exception.c -@@ -1723,6 +1723,83 @@ static void test_dynamic_unwind(void) - #endif /* __x86_64__ */ - - #if defined(__i386__) || defined(__x86_64__) -+ -+static void test_debug_registers(void) -+{ -+ NTSTATUS status; -+ CONTEXT ctx, ctx2; -+ -+ memset(&ctx, 0, sizeof(ctx)); -+ ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; -+ ctx2.ContextFlags = CONTEXT_DEBUG_REGISTERS; -+ -+ ctx.Dr0 = 0x42424240; -+ ctx.Dr2 = 0x126bb070; -+ ctx.Dr3 = 0x0badbad0; -+ ctx.Dr7 = 0xffff0115; -+ status = pNtSetContextThread(GetCurrentThread(), &ctx); -+ ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %08x\n", status); -+ status = pNtGetContextThread(GetCurrentThread(), &ctx2); -+ ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %x\n", status); -+ ctx2.Dr6 &= 0xf00f; ctx2.Dr7 &= ~0xdc00; -+ ok(ctx2.Dr0 == ctx.Dr0, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr0, (DWORD_PTR)ctx2.Dr0); -+ ok(ctx2.Dr1 == ctx.Dr1, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr1, (DWORD_PTR)ctx2.Dr1); -+ ok(ctx2.Dr2 == ctx.Dr2, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr2, (DWORD_PTR)ctx2.Dr2); -+ ok(ctx2.Dr3 == ctx.Dr3, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr3, (DWORD_PTR)ctx2.Dr3); -+ ok(ctx2.Dr6 == ctx.Dr6, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr6, (DWORD_PTR)ctx2.Dr6); -+ ok(ctx2.Dr7 == ctx.Dr7, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr7, (DWORD_PTR)ctx2.Dr7); -+ -+ ctx.Dr0 = 0x42424242; -+ ctx.Dr2 = 0x100f0fe7; -+ ctx.Dr3 = 0x0abebabe; -+ ctx.Dr7 = 0x115; -+ status = pNtSetContextThread(GetCurrentThread(), &ctx); -+ ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %08x\n", status); -+ status = pNtGetContextThread(GetCurrentThread(), &ctx2); -+ ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %x\n", status); -+ ctx2.Dr6 &= 0xf00f; ctx2.Dr7 &= ~0xdc00; -+ ok(ctx2.Dr0 == ctx.Dr0, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr0, (DWORD_PTR)ctx2.Dr0); -+ ok(ctx2.Dr1 == ctx.Dr1, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr1, (DWORD_PTR)ctx2.Dr1); -+ ok(ctx2.Dr2 == ctx.Dr2, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr2, (DWORD_PTR)ctx2.Dr2); -+ ok(ctx2.Dr3 == ctx.Dr3, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr3, (DWORD_PTR)ctx2.Dr3); -+ ok(ctx2.Dr6 == ctx.Dr6, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr6, (DWORD_PTR)ctx2.Dr6); -+ ok(ctx2.Dr7 == ctx.Dr7, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr7, (DWORD_PTR)ctx2.Dr7); -+ -+ /* setting Gx flags is not allowed */ -+ ctx.Dr7 |= 0xaa; -+ status = pNtSetContextThread(GetCurrentThread(), &ctx); -+ ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %08x\n", status); -+ status = pNtGetContextThread(GetCurrentThread(), &ctx2); -+ ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %x\n", status); -+ ctx.Dr7 &= ~0xaa; ctx2.Dr7 &= ~0xdc00; -+todo_wine -+ ok(ctx2.Dr7 == ctx.Dr7, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr7, (DWORD_PTR)ctx2.Dr7); -+ -+ /* setting GE flag is not allowed on 32-bit, but on 64-bit */ -+ ctx.Dr7 |= 0x200; -+ status = pNtSetContextThread(GetCurrentThread(), &ctx); -+ ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %08x\n", status); -+ status = pNtGetContextThread(GetCurrentThread(), &ctx2); -+ ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %x\n", status); -+#ifdef __i386__ -+ ctx.Dr7 &= ~0x200; ctx2.Dr7 &= ~0xdc00; -+todo_wine -+ ok(ctx2.Dr7 == ctx.Dr7, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr7, (DWORD_PTR)ctx2.Dr7); -+#else -+ ctx2.Dr7 &= ~0xdc00; -+ ok(ctx2.Dr7 == ctx.Dr7, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr7, (DWORD_PTR)ctx2.Dr7); -+#endif -+ -+ /* clearing LE flag is allowed */ -+ ctx.Dr7 &= ~0x100; -+ status = pNtSetContextThread(GetCurrentThread(), &ctx); -+ ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %08x\n", status); -+ status = pNtGetContextThread(GetCurrentThread(), &ctx2); -+ ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %x\n", status); -+ ctx2.Dr7 &= ~0xdc00; -+ ok(ctx2.Dr7 == ctx.Dr7, "expected %lx, got %lx\n", (DWORD_PTR)ctx.Dr7, (DWORD_PTR)ctx2.Dr7); -+} -+ - static DWORD outputdebugstring_exceptions; - - static LONG CALLBACK outputdebugstring_vectored_handler(EXCEPTION_POINTERS *ExceptionInfo) -@@ -1946,6 +2023,7 @@ START_TEST(exception) - test_unwind(); - test_exceptions(); - test_rtlraiseexception(); -+ test_debug_registers(); - test_outputdebugstring(1, FALSE); - test_ripevent(1); - test_vectored_continue_handler(); -@@ -1965,6 +2043,7 @@ START_TEST(exception) - pRtlLookupFunctionEntry = (void *)GetProcAddress( hntdll, - "RtlLookupFunctionEntry" ); - -+ test_debug_registers(); - test_outputdebugstring(1, FALSE); - test_ripevent(1); - test_vectored_continue_handler(); --- -2.6.4 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ntdll-x86_64_set_cpu_context/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Fixes: [39454] Allow to set debug registers separately in NtSetContextThread diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-CoGetApartmentType/0001-ole32-Implement-CoGetApartmentType.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-CoGetApartmentType/0001-ole32-Implement-CoGetApartmentType.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-CoGetApartmentType/0001-ole32-Implement-CoGetApartmentType.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-CoGetApartmentType/0001-ole32-Implement-CoGetApartmentType.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,209 @@ +From 66fe4e28e5cf72bbad572c102579ec3259e4c73c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Fri, 15 Jan 2016 12:16:32 +0100 +Subject: ole32: Implement CoGetApartmentType. + +--- + .../api-ms-win-core-com-l1-1-0.spec | 2 +- + .../api-ms-win-downlevel-ole32-l1-1-0.spec | 2 +- + dlls/combase/combase.spec | 2 +- + dlls/ole32/compobj.c | 29 +++++++++++++ + dlls/ole32/ole32.spec | 1 + + dlls/ole32/tests/compobj.c | 50 ++++++++++++++++++++++ + include/objidl.idl | 9 ++++ + 7 files changed, 92 insertions(+), 3 deletions(-) + +diff --git a/dlls/api-ms-win-core-com-l1-1-0/api-ms-win-core-com-l1-1-0.spec b/dlls/api-ms-win-core-com-l1-1-0/api-ms-win-core-com-l1-1-0.spec +index f8026db..f645c9d 100644 +--- a/dlls/api-ms-win-core-com-l1-1-0/api-ms-win-core-com-l1-1-0.spec ++++ b/dlls/api-ms-win-core-com-l1-1-0/api-ms-win-core-com-l1-1-0.spec +@@ -17,7 +17,7 @@ + @ stub CoEnableCallCancellation + @ stdcall CoFreeUnusedLibraries() ole32.CoFreeUnusedLibraries + @ stdcall CoFreeUnusedLibrariesEx(long long) ole32.CoFreeUnusedLibrariesEx +-@ stub CoGetApartmentType ++@ stdcall CoGetApartmentType(ptr ptr) ole32.CoGetApartmentType + @ stdcall CoGetCallContext(ptr ptr) ole32.CoGetCallContext + @ stdcall CoGetCallerTID(ptr) ole32.CoGetCallerTID + @ stub CoGetCancelObject +diff --git a/dlls/api-ms-win-downlevel-ole32-l1-1-0/api-ms-win-downlevel-ole32-l1-1-0.spec b/dlls/api-ms-win-downlevel-ole32-l1-1-0/api-ms-win-downlevel-ole32-l1-1-0.spec +index a0eabe9..82ff0f1 100644 +--- a/dlls/api-ms-win-downlevel-ole32-l1-1-0/api-ms-win-downlevel-ole32-l1-1-0.spec ++++ b/dlls/api-ms-win-downlevel-ole32-l1-1-0/api-ms-win-downlevel-ole32-l1-1-0.spec +@@ -8,7 +8,7 @@ + @ stdcall CoDisconnectObject(ptr long) ole32.CoDisconnectObject + @ stdcall CoFreeUnusedLibraries() ole32.CoFreeUnusedLibraries + @ stdcall CoFreeUnusedLibrariesEx(long long) ole32.CoFreeUnusedLibrariesEx +-@ stub CoGetApartmentType ++@ stdcall CoGetApartmentType(ptr ptr) ole32.CoGetApartmentType + @ stdcall CoGetClassObject(ptr long ptr ptr ptr) ole32.CoGetClassObject + @ stdcall CoGetCurrentLogicalThreadId(ptr) ole32.CoGetCurrentLogicalThreadId + @ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr) ole32.CoGetInterfaceAndReleaseStream +diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec +index 5082f39..075d904 100644 +--- a/dlls/combase/combase.spec ++++ b/dlls/combase/combase.spec +@@ -90,7 +90,7 @@ + @ stdcall CoFreeUnusedLibrariesEx(long long) ole32.CoFreeUnusedLibrariesEx + @ stdcall CoGetActivationState(int128 long ptr) ole32.CoGetActivationState + @ stub CoGetApartmentID +-@ stub CoGetApartmentType ++@ stdcall CoGetApartmentType(ptr ptr) ole32.CoGetApartmentType + @ stdcall CoGetCallContext(ptr ptr) ole32.CoGetCallContext + @ stdcall CoGetCallState(long ptr) ole32.CoGetCallState + @ stdcall CoGetCallerTID(ptr) ole32.CoGetCallerTID +diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c +index 90b049a..d8d618e 100644 +--- a/dlls/ole32/compobj.c ++++ b/dlls/ole32/compobj.c +@@ -5027,6 +5027,35 @@ HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) + } + + /*********************************************************************** ++ * CoGetApartmentType [OLE32.@] ++ */ ++HRESULT WINAPI CoGetApartmentType(APTTYPE *type, APTTYPEQUALIFIER *qualifier) ++{ ++ struct oletls *info = COM_CurrentInfo(); ++ ++ FIXME("(%p %p): semi-stub\n", type, qualifier); ++ ++ if (!type || !qualifier) ++ return E_INVALIDARG; ++ ++ if (!info) ++ return E_OUTOFMEMORY; ++ ++ if (!info->apt) ++ *type = APTTYPE_CURRENT; ++ else if (info->apt->multi_threaded) ++ *type = APTTYPE_MTA; ++ else if (info->apt->main) ++ *type = APTTYPE_MAINSTA; ++ else ++ *type = APTTYPE_STA; ++ ++ *qualifier = APTTYPEQUALIFIER_NONE; ++ ++ return info->apt ? ERROR_SUCCESS : CO_E_NOTINITIALIZED; ++} ++ ++/*********************************************************************** + * DllMain (OLE32.@) + */ + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved) +diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec +index 04c9f1e..c836176 100644 +--- a/dlls/ole32/ole32.spec ++++ b/dlls/ole32/ole32.spec +@@ -23,6 +23,7 @@ + @ stdcall CoFreeUnusedLibraries() + @ stdcall CoFreeUnusedLibrariesEx(long long) + @ stdcall CoGetActivationState(int128 long ptr) ++@ stdcall CoGetApartmentType(ptr ptr) + @ stdcall CoGetCallContext(ptr ptr) + @ stdcall CoGetCallState(long ptr) + @ stdcall CoGetCallerTID(ptr) +diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c +index 5fe9876..2ca5a45 100644 +--- a/dlls/ole32/tests/compobj.c ++++ b/dlls/ole32/tests/compobj.c +@@ -70,6 +70,7 @@ static HRESULT (WINAPI * pCoSwitchCallContext)(IUnknown *pObject, IUnknown **ppO + static HRESULT (WINAPI * pCoGetTreatAsClass)(REFCLSID clsidOld, LPCLSID pClsidNew); + static HRESULT (WINAPI * pCoTreatAsClass)(REFCLSID clsidOld, REFCLSID pClsidNew); + static HRESULT (WINAPI * pCoGetContextToken)(ULONG_PTR *token); ++static HRESULT (WINAPI * pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier); + static LONG (WINAPI * pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD); + static LONG (WINAPI * pRegOverridePredefKey)(HKEY key, HKEY override); + +@@ -2812,6 +2813,53 @@ if (0) /* crashes on native */ + IMalloc_Release(imalloc); + } + ++static void test_CoGetApartmentType(void) ++{ ++ APTTYPEQUALIFIER qualifier; ++ APTTYPE type; ++ HRESULT hr; ++ ++ if (!pCoGetApartmentType) ++ { ++ win_skip("CoGetApartmentType not present\n"); ++ return; ++ } ++ ++ hr = pCoGetApartmentType(NULL, NULL); ++ ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); ++ ++ hr = pCoGetApartmentType(&type, NULL); ++ ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); ++ ++ hr = pCoGetApartmentType(NULL, &qualifier); ++ ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); ++ ++ hr = pCoGetApartmentType(&type, &qualifier); ++ ok(hr == CO_E_NOTINITIALIZED, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); ++ ok(type == APTTYPE_CURRENT, "Expected APTTYPE_CURRENT, got %u\n", type); ++ ok(qualifier == APTTYPEQUALIFIER_NONE, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier); ++ ++ hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); ++ ok(!hr, "CoInitializeEx failed, error: 0x%08x\n", hr); ++ ++ hr = pCoGetApartmentType(&type, &qualifier); ++ ok(!hr, "CoGetApartmentType failed, error: 0x%08x\n", hr); ++ ok(type == APTTYPE_MAINSTA, "Expected APTTYPE_MAINSTA, got %u\n", type); ++ ok(qualifier == APTTYPEQUALIFIER_NONE, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier); ++ ++ CoUninitialize(); ++ ++ hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED); ++ ok(!hr, "CoInitializeEx failed, error: 0x%08x\n", hr); ++ ++ hr = pCoGetApartmentType(&type, &qualifier); ++ ok(!hr, "CoGetApartmentType failed, error: 0x%08x\n", hr); ++ ok(type == APTTYPE_MTA, "Expected APTTYPE_MTA, got %u\n", type); ++ ok(qualifier == APTTYPEQUALIFIER_NONE, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier); ++ ++ CoUninitialize(); ++} ++ + static void init_funcs(void) + { + HMODULE hOle32 = GetModuleHandleA("ole32"); +@@ -2823,6 +2871,7 @@ static void init_funcs(void) + pCoGetTreatAsClass = (void*)GetProcAddress(hOle32,"CoGetTreatAsClass"); + pCoTreatAsClass = (void*)GetProcAddress(hOle32,"CoTreatAsClass"); + pCoGetContextToken = (void*)GetProcAddress(hOle32, "CoGetContextToken"); ++ pCoGetApartmentType = (void*)GetProcAddress(hOle32, "CoGetApartmentType"); + pRegDeleteKeyExA = (void*)GetProcAddress(hAdvapi32, "RegDeleteKeyExA"); + pRegOverridePredefKey = (void*)GetProcAddress(hAdvapi32, "RegOverridePredefKey"); + pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx"); +@@ -2876,4 +2925,5 @@ START_TEST(compobj) + test_CoWaitForMultipleHandles(); + test_CoGetMalloc(); + test_OleRegGetUserType(); ++ test_CoGetApartmentType(); + } +diff --git a/include/objidl.idl b/include/objidl.idl +index c18442f..859620a 100644 +--- a/include/objidl.idl ++++ b/include/objidl.idl +@@ -2327,6 +2327,15 @@ typedef enum _APTTYPE { + APTTYPE_MAINSTA = 3 + } APTTYPE; + ++typedef enum _APTTYPEQUALIFIER { ++ APTTYPEQUALIFIER_NONE = 0, ++ APTTYPEQUALIFIER_IMPLICIT_MTA = 1, ++ APTTYPEQUALIFIER_NA_ON_MTA = 2, ++ APTTYPEQUALIFIER_NA_ON_STA = 3, ++ APTTYPEQUALIFIER_NA_ON_IMPLICIT_MTA = 4, ++ APTTYPEQUALIFIER_NA_ON_MAINSTA = 5 ++} APTTYPEQUALIFIER; ++ + typedef enum _THDTYPE { + THDTYPE_BLOCKMESSAGES = 0, + THDTYPE_PROCESSMESSAGES = 1 +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-CoGetApartmentType/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-CoGetApartmentType/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-CoGetApartmentType/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-CoGetApartmentType/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Add implementation for ole32.CoGetApartmentType diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0001-ole32-tests-Add-a-bunch-of-tests-for-HGLOBAL-based-I.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0001-ole32-tests-Add-a-bunch-of-tests-for-HGLOBAL-based-I.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0001-ole32-tests-Add-a-bunch-of-tests-for-HGLOBAL-based-I.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0001-ole32-tests-Add-a-bunch-of-tests-for-HGLOBAL-based-I.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,279 @@ +From 267315dd040ccfa527f8ba48038a268236ca1d29 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 2 Feb 2016 12:49:16 +0800 +Subject: ole32/tests: Add a bunch of tests for HGLOBAL based IStream::Clone. + +--- + dlls/ole32/tests/hglobalstream.c | 244 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 244 insertions(+) + +diff --git a/dlls/ole32/tests/hglobalstream.c b/dlls/ole32/tests/hglobalstream.c +index e20d81b..0dc3c52 100644 +--- a/dlls/ole32/tests/hglobalstream.c ++++ b/dlls/ole32/tests/hglobalstream.c +@@ -2,6 +2,7 @@ + * Stream on HGLOBAL Tests + * + * Copyright 2006 Robert Shearman (for CodeWeavers) ++ * Copyright 2016 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -508,11 +509,254 @@ static void test_freed_hglobal(void) + IStream_Release(pStream); + } + ++static void stream_info(IStream *stream, HGLOBAL *hmem, int *size, int *pos) ++{ ++ HRESULT hr; ++ STATSTG stat; ++ LARGE_INTEGER offset; ++ ULARGE_INTEGER newpos; ++ ++ *hmem = 0; ++ *size = *pos = -1; ++ ++ hr = GetHGlobalFromStream(stream, hmem); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ memset(&stat, 0x55, sizeof(stat)); ++ hr = IStream_Stat(stream, &stat, STATFLAG_DEFAULT); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ok(stat.type == STGTY_STREAM, "unexpected %#x\n", stat.type); ++ ok(!stat.pwcsName, "unexpected %p\n", stat.pwcsName); ++ ok(IsEqualIID(&stat.clsid, &GUID_NULL), "unexpected %s\n", wine_dbgstr_guid(&stat.clsid)); ++ ok(!stat.cbSize.HighPart, "unexpected %#x\n", stat.cbSize.HighPart); ++ *size = stat.cbSize.LowPart; ++ ++ offset.QuadPart = 0; ++ hr = IStream_Seek(stream, offset, STREAM_SEEK_CUR, &newpos); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ok(!newpos.HighPart, "unexpected %#x\n", newpos.HighPart); ++ *pos = newpos.LowPart; ++} ++ ++static void test_IStream_Clone(void) ++{ ++ static const char hello[] = "Hello World!"; ++ char buf[32]; ++ HRESULT hr; ++ IStream *stream, *clone; ++ HGLOBAL orig_hmem, hmem, hmem_clone; ++ ULARGE_INTEGER newsize; ++ LARGE_INTEGER offset; ++ int size, pos, ret; ++ ++ /* test simple case for Clone */ ++ orig_hmem = GlobalAlloc(GMEM_MOVEABLE, 0); ++ ok(orig_hmem != 0, "unexpected %p\n", orig_hmem); ++ hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &stream); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ stream_info(stream, &hmem, &size, &pos); ++ ok(hmem == orig_hmem, "handles should match\n"); ++ ok(size == 0, "unexpected %d\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ hr = IStream_Clone(stream, &clone); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ hr = IStream_Write(stream, hello, sizeof(hello), NULL); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ stream_info(stream, &hmem, &size, &pos); ++ ok(hmem != 0, "unexpected %p\n", hmem); ++ ok(size == 13, "unexpected %d\n", size); ++ ok(pos == 13, "unexpected %d\n", pos); ++ ++ stream_info(clone, &hmem_clone, &size, &pos); ++ ok(hmem_clone == hmem, "handles should match\n"); ++todo_wine ++ ok(size == 13, "unexpected %d\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ buf[0] = 0; ++ hr = IStream_Read(clone, buf, sizeof(buf), NULL); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++todo_wine ++ ok(!strcmp(buf, hello), "wrong stream contents\n"); ++ ++ newsize.QuadPart = 0x8000; ++ hr = IStream_SetSize(stream, newsize); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ stream_info(stream, &hmem, &size, &pos); ++ ok(hmem != 0, "unexpected %p\n", hmem); ++ ok(hmem == orig_hmem, "unexpected %p\n", hmem); ++ ok(size == 0x8000, "unexpected %#x\n", size); ++ ok(pos == 13, "unexpected %d\n", pos); ++ ++ stream_info(clone, &hmem_clone, &size, &pos); ++ ok(hmem_clone == hmem, "handles should match\n"); ++todo_wine ++ ok(size == 0x8000, "unexpected %#x\n", size); ++todo_wine ++ ok(pos == 13, "unexpected %d\n", pos); ++ ++ IStream_Release(clone); ++ IStream_Release(stream); ++ ++ /* exploit GMEM_FIXED forced move for the same base streams */ ++ orig_hmem = GlobalAlloc(GMEM_FIXED, 1); ++ ok(orig_hmem != 0, "unexpected %p\n", orig_hmem); ++ hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &stream); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ hr = IStream_Clone(stream, &clone); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ stream_info(stream, &hmem, &size, &pos); ++ ok(hmem != 0, "unexpected %p\n", hmem); ++ ok(size == 1, "unexpected %d\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ stream_info(clone, &hmem_clone, &size, &pos); ++ ok(hmem_clone == hmem, "handles should match\n"); ++ ok(size == 1, "unexpected %d\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ newsize.QuadPart = 0x8000; ++ hr = IStream_SetSize(stream, newsize); ++todo_wine ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ stream_info(stream, &hmem, &size, &pos); ++ ok(hmem != 0, "unexpected %p\n", hmem); ++todo_wine ++ ok(hmem != orig_hmem, "unexpected %p\n", hmem); ++todo_wine ++ ok(size == 0x8000, "unexpected %#x\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ stream_info(clone, &hmem_clone, &size, &pos); ++ ok(hmem_clone == hmem, "handles should match\n"); ++todo_wine ++ ok(size == 0x8000, "unexpected %#x\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ IStream_Release(stream); ++ IStream_Release(clone); ++ ++ /* exploit GMEM_FIXED forced move for different base streams */ ++ orig_hmem = GlobalAlloc(GMEM_FIXED, 1); ++ ok(orig_hmem != 0, "unexpected %p\n", orig_hmem); ++ hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &stream); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &clone); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ stream_info(stream, &hmem, &size, &pos); ++ ok(hmem != 0, "unexpected %p\n", hmem); ++ ok(size == 1, "unexpected %d\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ stream_info(clone, &hmem_clone, &size, &pos); ++ ok(hmem_clone == hmem, "handles should match\n"); ++ ok(size == 1, "unexpected %d\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ newsize.QuadPart = 0x8000; ++ hr = IStream_SetSize(stream, newsize); ++todo_wine ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ stream_info(stream, &hmem, &size, &pos); ++ ok(hmem != 0, "unexpected %p\n", hmem); ++todo_wine ++ ok(hmem != orig_hmem, "unexpected %p\n", hmem); ++todo_wine ++ ok(size == 0x8000, "unexpected %#x\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ stream_info(clone, &hmem_clone, &size, &pos); ++todo_wine ++ ok(hmem_clone != hmem, "handles should not match\n"); ++ ok(size == 1, "unexpected %#x\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ IStream_Release(stream); ++ /* releasing clone leads to test termination under windows ++ IStream_Release(clone); ++ */ ++ ++ /* test Release for a being cloned stream */ ++ hr = CreateStreamOnHGlobal(0, TRUE, &stream); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ hr = IStream_Clone(stream, &clone); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ stream_info(stream, &hmem, &size, &pos); ++ ok(hmem != 0, "unexpected %p\n", hmem); ++ ok(size == 0, "unexpected %d\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ stream_info(clone, &hmem_clone, &size, &pos); ++ ok(hmem_clone == hmem, "handles should match\n"); ++ ok(size == 0, "unexpected %#x\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ ret = IStream_Release(stream); ++ ok(ret == 0, "unexpected %d\n", ret); ++ ++ newsize.QuadPart = 0x8000; ++ hr = IStream_SetSize(clone, newsize); ++todo_wine ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ stream_info(clone, &hmem_clone, &size, &pos); ++ ok(hmem_clone == hmem, "handles should match\n"); ++todo_wine ++ ok(size == 0x8000, "unexpected %#x\n", size); ++ ok(pos == 0, "unexpected %d\n", pos); ++ ++ hr = IStream_Write(clone, hello, sizeof(hello), NULL); ++todo_wine ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ stream_info(clone, &hmem_clone, &size, &pos); ++ ok(hmem_clone == hmem, "handles should match\n"); ++todo_wine ++ ok(size == 0x8000, "unexpected %#x\n", size); ++todo_wine ++ ok(pos == 13, "unexpected %d\n", pos); ++ ++ offset.QuadPart = 0; ++ hr = IStream_Seek(clone, offset, STREAM_SEEK_SET, NULL); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++ ++ buf[0] = 0; ++ hr = IStream_Read(clone, buf, sizeof(buf), NULL); ++ ok(hr == S_OK, "unexpected %#x\n", hr); ++todo_wine ++ ok(!strcmp(buf, hello), "wrong stream contents\n"); ++ ++ stream_info(clone, &hmem_clone, &size, &pos); ++ ok(hmem_clone == hmem, "handles should match\n"); ++todo_wine ++ ok(size == 0x8000, "unexpected %#x\n", size); ++todo_wine ++ ok(pos == 32, "unexpected %d\n", pos); ++ ++ ret = IStream_Release(clone); ++ ok(ret == 0, "unexpected %d\n", ret); ++} ++ + START_TEST(hglobalstream) + { + HRESULT hr; + IStream *pStream; + ++ test_IStream_Clone(); ++ + hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream); + ok_ole_success(hr, "CreateStreamOnHGlobal"); + +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0002-ole32-Add-a-check-for-hglobal-pointer-to-GetHGlobalF.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0002-ole32-Add-a-check-for-hglobal-pointer-to-GetHGlobalF.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0002-ole32-Add-a-check-for-hglobal-pointer-to-GetHGlobalF.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0002-ole32-Add-a-check-for-hglobal-pointer-to-GetHGlobalF.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,47 @@ +From a26bfabac3940176f412896241ffab5c7f92baaa Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 2 Feb 2016 12:53:47 +0800 +Subject: ole32: Add a check for hglobal pointer to GetHGlobalFromStream. + +--- + dlls/ole32/hglobalstream.c | 4 ++-- + dlls/ole32/tests/hglobalstream.c | 6 ++++++ + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/dlls/ole32/hglobalstream.c b/dlls/ole32/hglobalstream.c +index 655e380..b86de56 100644 +--- a/dlls/ole32/hglobalstream.c ++++ b/dlls/ole32/hglobalstream.c +@@ -621,10 +621,10 @@ HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal) + { + HGLOBALStreamImpl* pStream; + +- if (pstm == NULL) ++ if (!pstm || !phglobal) + return E_INVALIDARG; + +- pStream = (HGLOBALStreamImpl*) pstm; ++ pStream = impl_from_IStream(pstm); + + /* + * Verify that the stream object was created with CreateStreamOnHGlobal. +diff --git a/dlls/ole32/tests/hglobalstream.c b/dlls/ole32/tests/hglobalstream.c +index 0dc3c52..0453e54 100644 +--- a/dlls/ole32/tests/hglobalstream.c ++++ b/dlls/ole32/tests/hglobalstream.c +@@ -555,6 +555,12 @@ static void test_IStream_Clone(void) + hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &stream); + ok(hr == S_OK, "unexpected %#x\n", hr); + ++ hr = GetHGlobalFromStream(stream, NULL); ++ ok(hr == E_INVALIDARG, "unexpected %#x\n", hr); ++ ++ hr = GetHGlobalFromStream(NULL, &hmem); ++ ok(hr == E_INVALIDARG, "unexpected %#x\n", hr); ++ + stream_info(stream, &hmem, &size, &pos); + ok(hmem == orig_hmem, "handles should match\n"); + ok(size == 0, "unexpected %d\n", size); +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0003-ole32-Add-a-wrapper-for-memory-block-managed-by-HGLO.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0003-ole32-Add-a-wrapper-for-memory-block-managed-by-HGLO.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0003-ole32-Add-a-wrapper-for-memory-block-managed-by-HGLO.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0003-ole32-Add-a-wrapper-for-memory-block-managed-by-HGLO.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,422 @@ +From 3c9954c3838d7504fad0213ade7363747e7a6805 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 2 Feb 2016 13:03:58 +0800 +Subject: ole32: Add a wrapper for memory block managed by HGLOBAL based + IStream. + +Based on a suggestion of Sebastian Lackner . +--- + dlls/ole32/hglobalstream.c | 202 +++++++++++++++++++++++++++------------ + dlls/ole32/tests/hglobalstream.c | 12 --- + 2 files changed, 140 insertions(+), 74 deletions(-) + +diff --git a/dlls/ole32/hglobalstream.c b/dlls/ole32/hglobalstream.c +index b86de56..5eb6320 100644 +--- a/dlls/ole32/hglobalstream.c ++++ b/dlls/ole32/hglobalstream.c +@@ -5,6 +5,7 @@ + * for streams contained supported by an HGLOBAL pointer. + * + * Copyright 1999 Francis Beaudet ++ * Copyright 2016 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -42,7 +43,96 @@ + + #include "wine/debug.h" + +-WINE_DEFAULT_DEBUG_CHANNEL(storage); ++WINE_DEFAULT_DEBUG_CHANNEL(hglobalstream); ++ ++struct handle_wrapper ++{ ++ LONG ref; ++ HGLOBAL hglobal; ++ ULONG size; ++ BOOL delete_on_release; ++ CRITICAL_SECTION lock; ++}; ++ ++static void handle_addref(struct handle_wrapper *handle) ++{ ++ InterlockedIncrement(&handle->ref); ++} ++ ++static void handle_release(struct handle_wrapper *handle) ++{ ++ ULONG ref = InterlockedDecrement(&handle->ref); ++ ++ if (!ref) ++ { ++ if (handle->delete_on_release) ++ { ++ GlobalFree(handle->hglobal); ++ handle->hglobal = NULL; ++ } ++ ++ DeleteCriticalSection(&handle->lock); ++ HeapFree(GetProcessHeap(), 0, handle); ++ } ++} ++ ++static void *handle_lock(struct handle_wrapper *handle) ++{ ++ return GlobalLock(handle->hglobal); ++} ++ ++static void handle_unlock(struct handle_wrapper *handle) ++{ ++ GlobalUnlock(handle->hglobal); ++} ++ ++static HGLOBAL handle_gethglobal(struct handle_wrapper *handle) ++{ ++ return handle->hglobal; ++} ++ ++static HRESULT handle_setsize(struct handle_wrapper *handle, ULONG size) ++{ ++ HRESULT hr = S_OK; ++ ++ EnterCriticalSection(&handle->lock); ++ ++ if (handle->size != size) ++ { ++ HGLOBAL hglobal = GlobalReAlloc(handle->hglobal, size, 0); ++ if (hglobal) ++ { ++ handle->hglobal = hglobal; ++ handle->size = size; ++ } ++ else ++ hr = E_OUTOFMEMORY; ++ } ++ ++ LeaveCriticalSection(&handle->lock); ++ return hr; ++} ++ ++static ULONG handle_getsize(struct handle_wrapper *handle) ++{ ++ return handle->size; ++} ++ ++static struct handle_wrapper *handle_create(HGLOBAL hglobal, BOOL delete_on_release) ++{ ++ struct handle_wrapper *handle; ++ ++ handle = HeapAlloc(GetProcessHeap(), 0, sizeof(*handle)); ++ if (handle) ++ { ++ handle->ref = 1; ++ handle->hglobal = hglobal; ++ handle->size = GlobalSize(hglobal); ++ handle->delete_on_release = delete_on_release; ++ InitializeCriticalSection(&handle->lock); ++ } ++ return handle; ++} + + /**************************************************************************** + * HGLOBALStreamImpl definition. +@@ -55,14 +145,7 @@ typedef struct + IStream IStream_iface; + LONG ref; + +- /* support for the stream */ +- HGLOBAL supportHandle; +- +- /* if TRUE the HGLOBAL is destroyed when the stream is finally released */ +- BOOL deleteOnRelease; +- +- /* size of the stream */ +- ULARGE_INTEGER streamSize; ++ struct handle_wrapper *handle; + + /* current position of the cursor */ + ULARGE_INTEGER currentPosition; +@@ -114,12 +197,7 @@ static ULONG WINAPI HGLOBALStreamImpl_Release( + + if (!ref) + { +- if (This->deleteOnRelease) +- { +- GlobalFree(This->supportHandle); +- This->supportHandle = NULL; +- } +- ++ handle_release(This->handle); + HeapFree(GetProcessHeap(), 0, This); + } + +@@ -161,15 +239,15 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read( + * Using the known size of the stream, calculate the number of bytes + * to read from the block chain + */ +- bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb); ++ bytesToReadFromBuffer = min( handle_getsize(This->handle) - This->currentPosition.u.LowPart, cb); + + /* + * Lock the buffer in position and copy the data. + */ +- supportBuffer = GlobalLock(This->supportHandle); ++ supportBuffer = handle_lock(This->handle); + if (!supportBuffer) + { +- WARN("read from invalid hglobal %p\n", This->supportHandle); ++ WARN("read from invalid hglobal %p\n", handle_gethglobal(This->handle)); + *pcbRead = 0; + return S_OK; + } +@@ -189,7 +267,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read( + /* + * Cleanup + */ +- GlobalUnlock(This->supportHandle); ++ handle_unlock(This->handle); + + /* + * Always returns S_OK even if the end of the stream is reached before the +@@ -241,7 +319,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write( + /* + * Verify if we need to grow the stream + */ +- if (newSize.u.LowPart > This->streamSize.u.LowPart) ++ if (newSize.u.LowPart > handle_getsize(This->handle)) + { + /* grow stream */ + HRESULT hr = IStream_SetSize(iface, newSize); +@@ -255,10 +333,10 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write( + /* + * Lock the buffer in position and copy the data. + */ +- supportBuffer = GlobalLock(This->supportHandle); ++ supportBuffer = handle_lock(This->handle); + if (!supportBuffer) + { +- WARN("write to invalid hglobal %p\n", This->supportHandle); ++ WARN("write to invalid hglobal %p\n", handle_gethglobal(This->handle)); + return S_OK; + } + +@@ -272,7 +350,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write( + /* + * Cleanup + */ +- GlobalUnlock(This->supportHandle); ++ handle_unlock(This->handle); + + out: + /* +@@ -318,7 +396,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek( + case STREAM_SEEK_CUR: + break; + case STREAM_SEEK_END: +- newPosition = This->streamSize; ++ newPosition.QuadPart = handle_getsize(This->handle); + break; + default: + hr = STG_E_SEEKERROR; +@@ -363,29 +441,13 @@ static HRESULT WINAPI HGLOBALStreamImpl_SetSize( + ULARGE_INTEGER libNewSize) /* [in] */ + { + HGLOBALStreamImpl* This = impl_from_IStream(iface); +- HGLOBAL supportHandle; + + TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart); + + /* + * HighPart is ignored as shown in tests + */ +- +- if (This->streamSize.u.LowPart == libNewSize.u.LowPart) +- return S_OK; +- +- /* +- * Re allocate the HGlobal to fit the new size of the stream. +- */ +- supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0); +- +- if (supportHandle == 0) +- return E_OUTOFMEMORY; +- +- This->supportHandle = supportHandle; +- This->streamSize.u.LowPart = libNewSize.u.LowPart; +- +- return S_OK; ++ return handle_setsize(This->handle, libNewSize.u.LowPart); + } + + /*** +@@ -533,24 +595,49 @@ static HRESULT WINAPI HGLOBALStreamImpl_Stat( + + pstatstg->pwcsName = NULL; + pstatstg->type = STGTY_STREAM; +- pstatstg->cbSize = This->streamSize; ++ pstatstg->cbSize.QuadPart = handle_getsize(This->handle); + + return S_OK; + } + ++static const IStreamVtbl HGLOBALStreamImplVtbl; ++ ++static HGLOBALStreamImpl *HGLOBALStreamImpl_Create(void) ++{ ++ HGLOBALStreamImpl *This; ++ ++ This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); ++ if (This) ++ { ++ This->IStream_iface.lpVtbl = &HGLOBALStreamImplVtbl; ++ This->ref = 1; ++ } ++ return This; ++} ++ + static HRESULT WINAPI HGLOBALStreamImpl_Clone( + IStream* iface, + IStream** ppstm) /* [out] */ + { + HGLOBALStreamImpl* This = impl_from_IStream(iface); ++ HGLOBALStreamImpl* clone; + ULARGE_INTEGER dummy; + LARGE_INTEGER offset; +- HRESULT hr; + +- TRACE(" Cloning %p (deleteOnRelease=%d seek position=%ld)\n",iface,This->deleteOnRelease,(long)This->currentPosition.QuadPart); +- hr = CreateStreamOnHGlobal(This->supportHandle, FALSE, ppstm); +- if(FAILED(hr)) +- return hr; ++ if (!ppstm) return E_INVALIDARG; ++ ++ *ppstm = NULL; ++ ++ TRACE(" Cloning %p (seek position=%d)\n", iface, This->currentPosition.u.LowPart); ++ ++ clone = HGLOBALStreamImpl_Create(); ++ if (!clone) return E_OUTOFMEMORY; ++ ++ *ppstm = &clone->IStream_iface; ++ ++ handle_addref(This->handle); ++ clone->handle = This->handle; ++ + offset.QuadPart = (LONGLONG)This->currentPosition.QuadPart; + IStream_Seek(*ppstm, offset, STREAM_SEEK_SET, &dummy); + return S_OK; +@@ -587,28 +674,19 @@ HRESULT WINAPI CreateStreamOnHGlobal( + if (!ppstm) + return E_INVALIDARG; + +- This = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl)); ++ This = HGLOBALStreamImpl_Create(); + if (!This) return E_OUTOFMEMORY; + +- This->IStream_iface.lpVtbl = &HGLOBALStreamImplVtbl; +- This->ref = 1; +- +- /* initialize the support */ +- This->supportHandle = hGlobal; +- This->deleteOnRelease = fDeleteOnRelease; +- + /* allocate a handle if one is not supplied */ +- if (!This->supportHandle) +- This->supportHandle = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE, 0); ++ if (!hGlobal) ++ hGlobal = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE, 0); ++ ++ This->handle = handle_create(hGlobal, fDeleteOnRelease); + + /* start at the beginning */ + This->currentPosition.u.HighPart = 0; + This->currentPosition.u.LowPart = 0; + +- /* initialize the size of the stream to the size of the handle */ +- This->streamSize.u.HighPart = 0; +- This->streamSize.u.LowPart = GlobalSize(This->supportHandle); +- + *ppstm = &This->IStream_iface; + + return S_OK; +@@ -630,7 +708,7 @@ HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal) + * Verify that the stream object was created with CreateStreamOnHGlobal. + */ + if (pStream->IStream_iface.lpVtbl == &HGLOBALStreamImplVtbl) +- *phglobal = pStream->supportHandle; ++ *phglobal = handle_gethglobal(pStream->handle); + else + { + *phglobal = 0; +diff --git a/dlls/ole32/tests/hglobalstream.c b/dlls/ole32/tests/hglobalstream.c +index 0453e54..afda4e6 100644 +--- a/dlls/ole32/tests/hglobalstream.c ++++ b/dlls/ole32/tests/hglobalstream.c +@@ -579,14 +579,12 @@ static void test_IStream_Clone(void) + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); +-todo_wine + ok(size == 13, "unexpected %d\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + buf[0] = 0; + hr = IStream_Read(clone, buf, sizeof(buf), NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); +-todo_wine + ok(!strcmp(buf, hello), "wrong stream contents\n"); + + newsize.QuadPart = 0x8000; +@@ -601,9 +599,7 @@ todo_wine + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); +-todo_wine + ok(size == 0x8000, "unexpected %#x\n", size); +-todo_wine + ok(pos == 13, "unexpected %d\n", pos); + + IStream_Release(clone); +@@ -715,24 +711,19 @@ todo_wine + + newsize.QuadPart = 0x8000; + hr = IStream_SetSize(clone, newsize); +-todo_wine + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); +-todo_wine + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + hr = IStream_Write(clone, hello, sizeof(hello), NULL); +-todo_wine + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); +-todo_wine + ok(size == 0x8000, "unexpected %#x\n", size); +-todo_wine + ok(pos == 13, "unexpected %d\n", pos); + + offset.QuadPart = 0; +@@ -742,14 +733,11 @@ todo_wine + buf[0] = 0; + hr = IStream_Read(clone, buf, sizeof(buf), NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); +-todo_wine + ok(!strcmp(buf, hello), "wrong stream contents\n"); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); +-todo_wine + ok(size == 0x8000, "unexpected %#x\n", size); +-todo_wine + ok(pos == 32, "unexpected %d\n", pos); + + ret = IStream_Release(clone); +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0004-ole32-Set-DebugInfo-Spare-0-for-handle_wrapper-lock.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0004-ole32-Set-DebugInfo-Spare-0-for-handle_wrapper-lock.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0004-ole32-Set-DebugInfo-Spare-0-for-handle_wrapper-lock.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0004-ole32-Set-DebugInfo-Spare-0-for-handle_wrapper-lock.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,32 @@ +From e6b772e0000dac0c50a8070b46413352e9c86174 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 6 Feb 2016 03:26:10 +0100 +Subject: ole32: Set DebugInfo->Spare[0] for handle_wrapper lock. + +--- + dlls/ole32/hglobalstream.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/dlls/ole32/hglobalstream.c b/dlls/ole32/hglobalstream.c +index 5eb6320..8b7e960 100644 +--- a/dlls/ole32/hglobalstream.c ++++ b/dlls/ole32/hglobalstream.c +@@ -71,6 +71,7 @@ static void handle_release(struct handle_wrapper *handle) + handle->hglobal = NULL; + } + ++ handle->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&handle->lock); + HeapFree(GetProcessHeap(), 0, handle); + } +@@ -130,6 +131,7 @@ static struct handle_wrapper *handle_create(HGLOBAL hglobal, BOOL delete_on_rele + handle->size = GlobalSize(hglobal); + handle->delete_on_release = delete_on_release; + InitializeCriticalSection(&handle->lock); ++ handle->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": handle_wrapper.lock"); + } + return handle; + } +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0005-ole32-Allow-moving-a-being-reallocated-block-of-memo.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0005-ole32-Allow-moving-a-being-reallocated-block-of-memo.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0005-ole32-Allow-moving-a-being-reallocated-block-of-memo.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0005-ole32-Allow-moving-a-being-reallocated-block-of-memo.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,72 @@ +From b7849b3a81d2e55ccfc3d61a8a14bbacf878438b Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 2 Feb 2016 15:35:59 +0800 +Subject: ole32: Allow moving a being reallocated block of memory managed by + HGLOBAL based IStream. + +--- + dlls/ole32/hglobalstream.c | 2 +- + dlls/ole32/tests/hglobalstream.c | 8 -------- + 2 files changed, 1 insertion(+), 9 deletions(-) + +diff --git a/dlls/ole32/hglobalstream.c b/dlls/ole32/hglobalstream.c +index 8b7e960..3e7f67b 100644 +--- a/dlls/ole32/hglobalstream.c ++++ b/dlls/ole32/hglobalstream.c +@@ -100,7 +100,7 @@ static HRESULT handle_setsize(struct handle_wrapper *handle, ULONG size) + + if (handle->size != size) + { +- HGLOBAL hglobal = GlobalReAlloc(handle->hglobal, size, 0); ++ HGLOBAL hglobal = GlobalReAlloc(handle->hglobal, size, GMEM_MOVEABLE); + if (hglobal) + { + handle->hglobal = hglobal; +diff --git a/dlls/ole32/tests/hglobalstream.c b/dlls/ole32/tests/hglobalstream.c +index afda4e6..9aa3b6c 100644 +--- a/dlls/ole32/tests/hglobalstream.c ++++ b/dlls/ole32/tests/hglobalstream.c +@@ -626,20 +626,16 @@ static void test_IStream_Clone(void) + + newsize.QuadPart = 0x8000; + hr = IStream_SetSize(stream, newsize); +-todo_wine + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(stream, &hmem, &size, &pos); + ok(hmem != 0, "unexpected %p\n", hmem); +-todo_wine + ok(hmem != orig_hmem, "unexpected %p\n", hmem); +-todo_wine + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); +-todo_wine + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 0, "unexpected %d\n", pos); + +@@ -667,19 +663,15 @@ todo_wine + + newsize.QuadPart = 0x8000; + hr = IStream_SetSize(stream, newsize); +-todo_wine + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(stream, &hmem, &size, &pos); + ok(hmem != 0, "unexpected %p\n", hmem); +-todo_wine + ok(hmem != orig_hmem, "unexpected %p\n", hmem); +-todo_wine + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + stream_info(clone, &hmem_clone, &size, &pos); +-todo_wine + ok(hmem_clone != hmem, "handles should not match\n"); + ok(size == 1, "unexpected %#x\n", size); + ok(pos == 0, "unexpected %d\n", pos); +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0006-ole32-Improve-thread-safety-of-HGLOBALStreamImpl_Rea.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0006-ole32-Improve-thread-safety-of-HGLOBALStreamImpl_Rea.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0006-ole32-Improve-thread-safety-of-HGLOBALStreamImpl_Rea.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0006-ole32-Improve-thread-safety-of-HGLOBALStreamImpl_Rea.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,115 @@ +From f5c31437019892510e36f603cbde72d9204a4155 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 6 Feb 2016 03:50:55 +0100 +Subject: ole32: Improve thread-safety of HGLOBALStreamImpl_Read. + +--- + dlls/ole32/hglobalstream.c | 83 ++++++++++++++++++---------------------------- + 1 file changed, 32 insertions(+), 51 deletions(-) + +diff --git a/dlls/ole32/hglobalstream.c b/dlls/ole32/hglobalstream.c +index 3e7f67b..27ac706 100644 +--- a/dlls/ole32/hglobalstream.c ++++ b/dlls/ole32/hglobalstream.c +@@ -87,6 +87,34 @@ static void handle_unlock(struct handle_wrapper *handle) + GlobalUnlock(handle->hglobal); + } + ++static ULONG handle_read(struct handle_wrapper *handle, ULONG *pos, void *dest, ULONG len) ++{ ++ void *source; ++ ++ EnterCriticalSection(&handle->lock); ++ ++ if (*pos < handle->size) ++ len = min(handle->size - *pos, len); ++ else ++ len = 0; ++ ++ source = GlobalLock(handle->hglobal); ++ if (source) ++ { ++ memcpy(dest, (char *)source + *pos, len); ++ *pos += len; ++ GlobalUnlock(handle->hglobal); ++ } ++ else ++ { ++ WARN("read from invalid hglobal %p\n", handle->hglobal); ++ len = 0; ++ } ++ ++ LeaveCriticalSection(&handle->lock); ++ return len; ++} ++ + static HGLOBAL handle_gethglobal(struct handle_wrapper *handle) + { + return handle->hglobal; +@@ -222,59 +250,12 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read( + ULONG* pcbRead) /* [out] */ + { + HGLOBALStreamImpl* This = impl_from_IStream(iface); ++ ULONG num_bytes; + +- void* supportBuffer; +- ULONG bytesReadBuffer; +- ULONG bytesToReadFromBuffer; +- +- TRACE("(%p, %p, %d, %p)\n", iface, +- pv, cb, pcbRead); +- +- /* +- * If the caller is not interested in the number of bytes read, +- * we use another buffer to avoid "if" statements in the code. +- */ +- if (pcbRead==0) +- pcbRead = &bytesReadBuffer; +- +- /* +- * Using the known size of the stream, calculate the number of bytes +- * to read from the block chain +- */ +- bytesToReadFromBuffer = min( handle_getsize(This->handle) - This->currentPosition.u.LowPart, cb); +- +- /* +- * Lock the buffer in position and copy the data. +- */ +- supportBuffer = handle_lock(This->handle); +- if (!supportBuffer) +- { +- WARN("read from invalid hglobal %p\n", handle_gethglobal(This->handle)); +- *pcbRead = 0; +- return S_OK; +- } +- +- memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer); +- +- /* +- * Move the current position to the new position +- */ +- This->currentPosition.u.LowPart+=bytesToReadFromBuffer; +- +- /* +- * Return the number of bytes read. +- */ +- *pcbRead = bytesToReadFromBuffer; +- +- /* +- * Cleanup +- */ +- handle_unlock(This->handle); ++ TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbRead); + +- /* +- * Always returns S_OK even if the end of the stream is reached before the +- * buffer is filled +- */ ++ num_bytes = handle_read(This->handle, &This->currentPosition.u.LowPart, pv, cb); ++ if (pcbRead) *pcbRead = num_bytes; + + return S_OK; + } +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0007-ole32-Improve-thread-safety-of-HGLOBALStreamImpl_Wri.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0007-ole32-Improve-thread-safety-of-HGLOBALStreamImpl_Wri.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/0007-ole32-Improve-thread-safety-of-HGLOBALStreamImpl_Wri.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/0007-ole32-Improve-thread-safety-of-HGLOBALStreamImpl_Wri.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,158 @@ +From 8656639654762bd3151593fe00a0c47080a085d8 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 6 Feb 2016 04:09:45 +0100 +Subject: ole32: Improve thread-safety of HGLOBALStreamImpl_Write. + +--- + dlls/ole32/hglobalstream.c | 117 ++++++++++++++++++--------------------------- + 1 file changed, 46 insertions(+), 71 deletions(-) + +diff --git a/dlls/ole32/hglobalstream.c b/dlls/ole32/hglobalstream.c +index 27ac706..2c08710 100644 +--- a/dlls/ole32/hglobalstream.c ++++ b/dlls/ole32/hglobalstream.c +@@ -77,16 +77,6 @@ static void handle_release(struct handle_wrapper *handle) + } + } + +-static void *handle_lock(struct handle_wrapper *handle) +-{ +- return GlobalLock(handle->hglobal); +-} +- +-static void handle_unlock(struct handle_wrapper *handle) +-{ +- GlobalUnlock(handle->hglobal); +-} +- + static ULONG handle_read(struct handle_wrapper *handle, ULONG *pos, void *dest, ULONG len) + { + void *source; +@@ -115,6 +105,48 @@ static ULONG handle_read(struct handle_wrapper *handle, ULONG *pos, void *dest, + return len; + } + ++static ULONG handle_write(struct handle_wrapper *handle, ULONG *pos, const void *source, ULONG len) ++{ ++ void *dest; ++ ++ if (!len) ++ return 0; ++ ++ EnterCriticalSection(&handle->lock); ++ ++ if (*pos + len > handle->size) ++ { ++ HGLOBAL hglobal = GlobalReAlloc(handle->hglobal, *pos + len, GMEM_MOVEABLE); ++ if (hglobal) ++ { ++ handle->hglobal = hglobal; ++ handle->size = *pos + len; ++ } ++ else ++ { ++ len = 0; ++ goto done; ++ } ++ } ++ ++ dest = GlobalLock(handle->hglobal); ++ if (dest) ++ { ++ memcpy((char *)dest + *pos, source, len); ++ *pos += len; ++ GlobalUnlock(handle->hglobal); ++ } ++ else ++ { ++ WARN("write to invalid hglobal %p\n", handle->hglobal); ++ /* len = 0; */ ++ } ++ ++done: ++ LeaveCriticalSection(&handle->lock); ++ return len; ++} ++ + static HGLOBAL handle_gethglobal(struct handle_wrapper *handle) + { + return handle->hglobal; +@@ -277,71 +309,14 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write( + ULONG* pcbWritten) /* [out] */ + { + HGLOBALStreamImpl* This = impl_from_IStream(iface); +- +- void* supportBuffer; +- ULARGE_INTEGER newSize; +- ULONG bytesWritten = 0; ++ ULONG num_bytes; + + TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbWritten); + +- /* +- * If the caller is not interested in the number of bytes written, +- * we use another buffer to avoid "if" statements in the code. +- */ +- if (pcbWritten == 0) +- pcbWritten = &bytesWritten; +- +- if (cb == 0) +- goto out; +- +- *pcbWritten = 0; +- +- newSize.u.HighPart = 0; +- newSize.u.LowPart = This->currentPosition.u.LowPart + cb; +- +- /* +- * Verify if we need to grow the stream +- */ +- if (newSize.u.LowPart > handle_getsize(This->handle)) +- { +- /* grow stream */ +- HRESULT hr = IStream_SetSize(iface, newSize); +- if (FAILED(hr)) +- { +- ERR("IStream_SetSize failed with error 0x%08x\n", hr); +- return hr; +- } +- } +- +- /* +- * Lock the buffer in position and copy the data. +- */ +- supportBuffer = handle_lock(This->handle); +- if (!supportBuffer) +- { +- WARN("write to invalid hglobal %p\n", handle_gethglobal(This->handle)); +- return S_OK; +- } +- +- memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb); +- +- /* +- * Move the current position to the new position +- */ +- This->currentPosition.u.LowPart+=cb; +- +- /* +- * Cleanup +- */ +- handle_unlock(This->handle); +- +-out: +- /* +- * Return the number of bytes read. +- */ +- *pcbWritten = cb; ++ num_bytes = handle_write(This->handle, &This->currentPosition.u.LowPart, pv, cb); ++ if (pcbWritten) *pcbWritten = num_bytes; + +- return S_OK; ++ return (num_bytes < cb) ? E_OUTOFMEMORY : S_OK; + } + + /*** +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ole32-HGLOBALStream/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ole32-HGLOBALStream/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Implement proper refcounting and locking for HGLOBAL based IStream diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-CreateTypeLib/0001-oleaut32-Implement-semi-stub-for-CreateTypeLib.patch wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-CreateTypeLib/0001-oleaut32-Implement-semi-stub-for-CreateTypeLib.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-CreateTypeLib/0001-oleaut32-Implement-semi-stub-for-CreateTypeLib.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-CreateTypeLib/0001-oleaut32-Implement-semi-stub-for-CreateTypeLib.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,43 @@ +From c82a7265f3a5fa9114c7881fba3047aae960340a Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Wed, 2 Sep 2015 13:09:34 +1000 +Subject: oleaut32: Implement semi-stub for CreateTypeLib. + +--- + dlls/oleaut32/typelib.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c +index 2a24b79..4066d03 100644 +--- a/dlls/oleaut32/typelib.c ++++ b/dlls/oleaut32/typelib.c +@@ -424,11 +424,21 @@ HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID l + * Success: S_OK + * Failure: Status + */ +-HRESULT WINAPI CreateTypeLib( +- SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib +-) { +- FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib); +- return E_FAIL; ++HRESULT WINAPI CreateTypeLib(SYSKIND syskind, LPCOLESTR file, ICreateTypeLib **ctlib) ++{ ++ ICreateTypeLib2 *typelib2; ++ HRESULT hres; ++ ++ FIXME("(%d, %s, %p): forwarding to CreateTypeLib2\n", syskind, debugstr_w(file), ctlib); ++ ++ hres = CreateTypeLib2(syskind, file, &typelib2); ++ if(SUCCEEDED(hres)) ++ { ++ hres = ICreateTypeLib2_QueryInterface(typelib2, &IID_ICreateTypeLib, (void **)&ctlib); ++ ICreateTypeLib2_Release(typelib2); ++ } ++ ++ return hres; + } + + /****************************************************************************** +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-CreateTypeLib/definition wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-CreateTypeLib/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-CreateTypeLib/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-CreateTypeLib/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [!8780] Forward CreateTypeLib to CreateTypeLib2 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0001-oleaut32-Pass-size-without-terminating-null-to-get_c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0001-oleaut32-Pass-size-without-terminating-null-to-get_c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0001-oleaut32-Pass-size-without-terminating-null-to-get_c.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0001-oleaut32-Pass-size-without-terminating-null-to-get_c.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -From 58ca159c89e1eb626f287a37320369df5f8ba98e Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Fri, 25 Dec 2015 06:37:44 +0100 -Subject: oleaut32: Pass size without terminating null to get_cache_entry. - -Signed-off-by: Sebastian Lackner ---- - dlls/oleaut32/oleaut.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/dlls/oleaut32/oleaut.c b/dlls/oleaut32/oleaut.c -index 0352215..75f9cb4 100644 ---- a/dlls/oleaut32/oleaut.c -+++ b/dlls/oleaut32/oleaut.c -@@ -119,7 +119,7 @@ static inline bstr_t *bstr_from_str(BSTR str) - - static inline bstr_cache_entry_t *get_cache_entry(size_t size) - { -- unsigned cache_idx = FIELD_OFFSET(bstr_t, u.ptr[size-1])/BUCKET_SIZE; -+ unsigned cache_idx = FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)-1])/BUCKET_SIZE; - return bstr_cache_enabled && cache_idx < sizeof(bstr_cache)/sizeof(*bstr_cache) - ? bstr_cache + cache_idx - : NULL; -@@ -127,14 +127,14 @@ static inline bstr_cache_entry_t *get_cache_entry(size_t size) - - static bstr_t *alloc_bstr(size_t size) - { -- bstr_cache_entry_t *cache_entry = get_cache_entry(size+sizeof(WCHAR)); -+ bstr_cache_entry_t *cache_entry = get_cache_entry(size); - bstr_t *ret; - - if(cache_entry) { - EnterCriticalSection(&cs_bstr_cache); - - if(!cache_entry->cnt) { -- cache_entry = get_cache_entry(size+sizeof(WCHAR)+BUCKET_SIZE); -+ cache_entry = get_cache_entry(size+BUCKET_SIZE); - if(cache_entry && !cache_entry->cnt) - cache_entry = NULL; - } -@@ -258,7 +258,7 @@ void WINAPI SysFreeString(BSTR str) - return; - - bstr = bstr_from_str(str); -- cache_entry = get_cache_entry(bstr->size+sizeof(WCHAR)); -+ cache_entry = get_cache_entry(bstr->size); - if(cache_entry) { - unsigned i; - --- -2.6.4 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0002-oleaut32-Align-terminating-null-character-in-SysAllo.patch wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0002-oleaut32-Align-terminating-null-character-in-SysAllo.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0002-oleaut32-Align-terminating-null-character-in-SysAllo.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0002-oleaut32-Align-terminating-null-character-in-SysAllo.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -From cd1a0baf46ef8d3394fbd7ba220d850a372c172a Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Fri, 25 Dec 2015 06:38:10 +0100 -Subject: oleaut32: Align terminating null character in SysAllocStringByteLen. - -Signed-off-by: Sebastian Lackner ---- - dlls/oleaut32/oleaut.c | 14 ++++++-------- - dlls/oleaut32/tests/vartype.c | 29 +++++++++++++++++++++++++++++ - 2 files changed, 35 insertions(+), 8 deletions(-) - -diff --git a/dlls/oleaut32/oleaut.c b/dlls/oleaut32/oleaut.c -index 75f9cb4..78cb083 100644 ---- a/dlls/oleaut32/oleaut.c -+++ b/dlls/oleaut32/oleaut.c -@@ -149,12 +149,9 @@ static bstr_t *alloc_bstr(size_t size) - - if(cache_entry) { - if(WARN_ON(heap)) { -- size_t tail; -- -- memset(ret, ARENA_INUSE_FILLER, FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)])); -- tail = bstr_alloc_size(size) - FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)]); -- if(tail) -- memset(ret->u.ptr+size+sizeof(WCHAR), ARENA_TAIL_FILLER, tail); -+ size_t fill_size = (FIELD_OFFSET(bstr_t, u.ptr[size])+2*sizeof(WCHAR)-1) & ~(sizeof(WCHAR)-1); -+ memset(ret, ARENA_INUSE_FILLER, fill_size); -+ memset((char *)ret+fill_size, ARENA_TAIL_FILLER, bstr_alloc_size(size)-fill_size); - } - ret->size = size; - return ret; -@@ -418,10 +415,11 @@ BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len) - - if(str) { - memcpy(bstr->u.ptr, str, len); -- bstr->u.ptr[len] = bstr->u.ptr[len+1] = 0; -+ bstr->u.ptr[len] = 0; - }else { -- memset(bstr->u.ptr, 0, len+sizeof(WCHAR)); -+ memset(bstr->u.ptr, 0, len+1); - } -+ bstr->u.str[(len+sizeof(WCHAR)-1)/sizeof(WCHAR)] = 0; - - return bstr->u.str; - } -diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c -index 7cbb059..d905d37 100644 ---- a/dlls/oleaut32/tests/vartype.c -+++ b/dlls/oleaut32/tests/vartype.c -@@ -5444,7 +5444,9 @@ static void test_SysAllocStringByteLen(void) - { - const OLECHAR szTest[10] = { 'T','e','s','t','\0' }; - const CHAR szTestA[6] = { 'T','e','s','t','\0','?' }; -+ char *buf; - BSTR str; -+ int i; - - if (sizeof(void *) == 4) /* not limited to 0x80000000 on Win64 */ - { -@@ -5487,6 +5489,7 @@ static void test_SysAllocStringByteLen(void) - - ok (bstr->dwLen == 3, "Expected 3, got %d\n", bstr->dwLen); - ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n"); -+ ok (!bstr->szString[2], "String not terminated\n"); - SysFreeString(str); - } - -@@ -5500,6 +5503,32 @@ static void test_SysAllocStringByteLen(void) - ok (!lstrcmpW(bstr->szString, szTest), "String different\n"); - SysFreeString(str); - } -+ -+ /* Make sure terminating null is aligned properly */ -+ buf = HeapAlloc(GetProcessHeap(), 0, 1025); -+ ok (buf != NULL, "Expected non-NULL\n"); -+ for (i = 0; i < 1024; i++) -+ { -+ LPINTERNAL_BSTR bstr; -+ -+ str = SysAllocStringByteLen(NULL, i); -+ ok (str != NULL, "Expected non-NULL\n"); -+ bstr = Get(str); -+ ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen); -+ ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n"); -+ SysFreeString(str); -+ -+ memset(buf, 0xaa, 1025); -+ str = SysAllocStringByteLen(buf, i); -+ ok (str != NULL, "Expected non-NULL\n"); -+ bstr = Get(str); -+ ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen); -+ buf[i] = 0; -+ ok (!lstrcmpA((LPCSTR)bstr->szString, buf), "String different\n"); -+ ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n"); -+ SysFreeString(str); -+ } -+ HeapFree(GetProcessHeap(), 0, buf); - } - - static void test_SysReAllocString(void) --- -2.6.4 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0003-oleaut32-tests-Test-SysStringLen-on-string-allocated.patch wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0003-oleaut32-tests-Test-SysStringLen-on-string-allocated.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0003-oleaut32-tests-Test-SysStringLen-on-string-allocated.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/0003-oleaut32-tests-Test-SysStringLen-on-string-allocated.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -From ab8673852c2b53cf96fca841687cdf482b729510 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sun, 27 Dec 2015 18:16:42 +0100 -Subject: oleaut32/tests: Test SysStringLen() on string allocated with - SysAllocStringByteLen. - ---- - dlls/oleaut32/tests/vartype.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c -index d905d37..975922f 100644 ---- a/dlls/oleaut32/tests/vartype.c -+++ b/dlls/oleaut32/tests/vartype.c -@@ -5515,6 +5515,7 @@ static void test_SysAllocStringByteLen(void) - ok (str != NULL, "Expected non-NULL\n"); - bstr = Get(str); - ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen); -+ ok (SysStringLen(str) == i/sizeof(WCHAR), "Expected %d, got %d\n", i/sizeof(WCHAR), SysStringLen(str)); - ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n"); - SysFreeString(str); - -@@ -5525,6 +5526,7 @@ static void test_SysAllocStringByteLen(void) - ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen); - buf[i] = 0; - ok (!lstrcmpA((LPCSTR)bstr->szString, buf), "String different\n"); -+ ok (SysStringLen(str) == i/sizeof(WCHAR), "Expected %d, got %d\n", i/sizeof(WCHAR), SysStringLen(str)); - ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n"); - SysFreeString(str); - } --- -2.6.4 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/definition wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/oleaut32-SysAllocStringByteLen/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Fixes: SysAllocStringByteLen should align terminating null WCHAR diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/patchinstall.sh wine-staging-1.9.3~ubuntu12.04.1/patches/patchinstall.sh --- wine-staging-1.9.0~ubuntu12.04.1/patches/patchinstall.sh 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/patchinstall.sh 2016-02-08 20:07:32.000000000 +0000 @@ -2,7 +2,7 @@ # # Script to automatically install all Wine Staging patches # -# Copyright (C) 2015 Sebastian Lackner +# Copyright (C) 2015-2016 Sebastian Lackner # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -26,16 +26,15 @@ echo "Usage: ./patchinstall.sh [DESTDIR=path] [--all] [-W patchset] [patchset ...]" echo "" echo "Autogenerated script to apply all Wine Staging patches on your Wine" - echo "source tree. This script replaces and enhances the old method of" - echo "using a Makefile." + echo "source tree." echo "" echo "Configuration:" echo " DESTDIR=path Specify the path to the wine source tree" echo " --all Select all patches" echo " --force-autoconf Run autoreconf and tools/make_requests after each patch" echo " --help Display this help and exit" - echo " --no-patchlist Do not apply patchlist (needed for 'wine --patches')" echo " --no-autoconf Do not run autoreconf and tools/make_requests" + echo " --no-patchlist Do not apply patchlist (needed for 'wine --patches')" echo " --upstream-commit Print the upstream Wine commit SHA1 and exit" echo " --version Show version information and exit" echo " -W patchset Exclude a specific patchset" @@ -52,14 +51,14 @@ # Get the upstream commit sha upstream_commit() { - echo "93d7356290bfe5bfd2104f98592790841e33420e" + echo "c266d373deb417abef4883f59daa5d517b77e76c" } # Show version information version() { - echo "Wine Staging 1.9.0" - echo "Copyright (C) 2014-2015 the Wine Staging project authors." + echo "Wine Staging 1.9.3" + echo "Copyright (C) 2014-2016 the Wine Staging project authors." echo "" echo "Patchset to be applied on upstream Wine:" echo " commit $(upstream_commit)" @@ -90,11 +89,17 @@ enable_advapi32_LsaLookupSids="$1" enable_advapi32_SetSecurityInfo="$1" enable_amstream_GetMultiMediaStream="$1" - enable_api_ms_win_crt_Stub_DLLs="$1" + enable_api_ms_win_Stub_DLLs="$1" enable_authz_Stub_Functions="$1" + enable_avifil32_AVIFile_Proxies="$1" + enable_avifil32_IGetFrame_fnSetFormat="$1" + enable_avifile_dll16_AVIStreamGetFrame="$1" enable_browseui_Progress_Dialog="$1" + enable_combase_RoApi="$1" + enable_combase_WindowsString="$1" enable_comctl32_Button_Theming="$1" enable_comctl32_PROPSHEET_InsertPage="$1" + enable_comctl32_TTM_ADDTOOLW="$1" enable_configure_Absolute_RPATH="$1" enable_crypt32_CMS_Certificates="$1" enable_crypt32_CryptUnprotectMemory="$1" @@ -105,7 +110,6 @@ enable_d3dx9_25_ID3DXEffect="$1" enable_d3dx9_26_ID3DXEffect="$1" enable_d3dx9_33_Share_Source="$1" - enable_d3dx9_36_AnimationController="$1" enable_d3dx9_36_CloneEffect="$1" enable_d3dx9_36_D3DXCreateTeapot="$1" enable_d3dx9_36_D3DXStubs="$1" @@ -120,9 +124,11 @@ enable_d3dx9_36_Texture_Align="$1" enable_d3dx9_36_UpdateSkinnedMesh="$1" enable_dbghelp_Debug_Symbols="$1" + enable_ddraw_Device_Caps="$1" enable_ddraw_EnumSurfaces="$1" enable_ddraw_IDirect3DTexture2_Load="$1" enable_ddraw_Rendering_Targets="$1" + enable_ddraw_Revert_Surface_Init="$1" enable_ddraw_Write_Vtable="$1" enable_ddraw_ZBufferBitDepths="$1" enable_ddraw_d3d_execute_buffer="$1" @@ -131,10 +137,12 @@ enable_dsound_EAX="$1" enable_dsound_Fast_Mixer="$1" enable_dsound_Revert_Cleanup="$1" + enable_dxdiagn_Display_Information="$1" enable_dxdiagn_Enumerate_DirectSound="$1" enable_dxdiagn_GetChildContainer_Leaf_Nodes="$1" enable_dxgi_MakeWindowAssociation="$1" enable_dxva2_Video_Decoder="$1" + enable_explorer_Video_Registry_Key="$1" enable_fonts_Missing_Fonts="$1" enable_gdi32_Lazy_Font_Initialization="$1" enable_gdi32_MultiMonitor="$1" @@ -147,47 +155,56 @@ enable_imagehlp_BindImageEx="$1" enable_imagehlp_Cleanup="$1" enable_imagehlp_ImageLoad="$1" + enable_imm32_IMMDisableLegacyIME="$1" enable_inetcpl_Default_Home="$1" enable_iphlpapi_System_Ping="$1" enable_iphlpapi_TCP_Table="$1" enable_kernel32_COMSPEC="$1" - enable_kernel32_Codepage_Conversion="$1" enable_kernel32_CompareString_Length="$1" enable_kernel32_CopyFileEx="$1" enable_kernel32_Cwd_Startup_Info="$1" + enable_kernel32_FindFirstFile="$1" enable_kernel32_FreeUserPhysicalPages="$1" + enable_kernel32_GetCurrentPackageFamilyName="$1" enable_kernel32_GetFinalPathNameByHandle="$1" - enable_kernel32_GetLargestConsoleWindowSize="$1" - enable_kernel32_GetLogicalProcessorInformationEx="$1" + enable_kernel32_InterlockedPushListSList="$1" enable_kernel32_LocaleNameToLCID="$1" enable_kernel32_Named_Pipe="$1" enable_kernel32_NeedCurrentDirectoryForExePath="$1" enable_kernel32_Profile="$1" + enable_kernel32_QT_Environment_Variables="$1" enable_kernel32_SetFileCompletionNotificationModes="$1" enable_kernel32_SetFileInformationByHandle="$1" enable_kernel32_TimezoneInformation_Registry="$1" enable_kernel32_VerifyVersionInfo="$1" + enable_kernel32_VirtualProtect="$1" enable_libs_Debug_Channel="$1" enable_libs_Unicode_Collation="$1" enable_makedep_PARENTSPEC="$1" enable_mfplat_MFTRegister="$1" enable_mmdevapi_AEV_Stubs="$1" + enable_mmsystem_dll16_Fix_Argument_Order="$1" enable_mountmgr_DosDevices="$1" enable_mpr_WNetGetUniversalNameW="$1" enable_mscoree_CorValidateImage="$1" enable_mshtml_HTMLLocation_put_hash="$1" enable_msidb_Implementation="$1" + enable_msvcr120__SetWinRTOutOfMemoryExceptionCallback="$1" + enable_msvcr120_strof="$1" enable_msvcrt_Math_Precision="$1" enable_msvcrt_StdHandle_RefCount="$1" + enable_msvideo_MCIWNDM_SETTIMEFORMATA="$1" enable_ntdll_APC_Performance="$1" enable_ntdll_APC_Start_Process="$1" enable_ntdll_Activation_Context="$1" + enable_ntdll_ApiSetQueryApiSetPresence="$1" enable_ntdll_CLI_Images="$1" enable_ntdll_DOS_Attributes="$1" enable_ntdll_Dealloc_Thread_Stack="$1" enable_ntdll_DeviceType_Systemroot="$1" enable_ntdll_DllOverrides_WOW64="$1" enable_ntdll_DllRedirects="$1" + enable_ntdll_EtwRegisterTraceGuids="$1" enable_ntdll_Exception="$1" enable_ntdll_FileDispositionInformation="$1" enable_ntdll_FileFsFullSizeInformation="$1" @@ -206,41 +223,50 @@ enable_ntdll_Pipe_SpecialCharacters="$1" enable_ntdll_ProcessQuotaLimits="$1" enable_ntdll_Purist_Mode="$1" - enable_ntdll_RtlIpStringToAddress="$1" + enable_ntdll_RtlIpStringToAddress_Stubs="$1" + enable_ntdll_RtlIpStringToAddress_Tests="$1" + enable_ntdll_RtlQueryPackageIdentity="$1" + enable_ntdll_Serial_Port_Detection="$1" enable_ntdll_Status_Mapping="$1" enable_ntdll_Syscall_Wrappers="$1" - enable_ntdll_SystemHandleInformation="$1" + enable_ntdll_SystemInterruptInformation="$1" + enable_ntdll_SystemRecommendedSharedDataAlignment="$1" enable_ntdll_SystemRoot_Symlink="$1" enable_ntdll_ThreadTime="$1" enable_ntdll_Threading="$1" + enable_ntdll_Unused_Import_Descr="$1" enable_ntdll_User_Shared_Data="$1" enable_ntdll_WRITECOPY="$1" enable_ntdll_Wait_User_APC="$1" enable_ntdll_WinSqm="$1" enable_ntdll_WriteWatches="$1" enable_ntdll_Zero_mod_name="$1" - enable_ntdll_x86_64_set_cpu_context="$1" enable_ntoskrnl_DriverTest="$1" enable_ntoskrnl_Stubs="$1" enable_nvapi_Stub_DLL="$1" enable_nvcuda_CUDA_Support="$1" enable_nvcuvid_CUDA_Video_Support="$1" enable_nvencodeapi_Video_Encoder="$1" - enable_oleaut32_SysAllocStringByteLen="$1" + enable_ole32_CoGetApartmentType="$1" + enable_ole32_HGLOBALStream="$1" + enable_oleaut32_CreateTypeLib="$1" enable_oleaut32_TKIND_COCLASS="$1" enable_oleaut32_x86_64_Marshaller="$1" enable_openal32_EFX_Extension="$1" enable_opengl32_Revert_Disable_Ext="$1" + enable_quartz_AsyncReader="$1" enable_quartz_MediaSeeking_Positions="$1" enable_rasapi32_RasEnumDevicesA="$1" enable_riched20_IText_Interface="$1" enable_rpcrt4_Pipe_Transport="$1" + enable_rpcrt4_RpcBindingServerFromClient="$1" enable_secur32_ANSI_NTLM_Credentials="$1" enable_server_ClipCursor="$1" enable_server_CreateProcess_ACLs="$1" enable_server_Desktop_Refcount="$1" enable_server_FileEndOfFileInformation="$1" enable_server_File_Permissions="$1" + enable_server_Fix_Leak="$1" enable_server_Inherited_ACLs="$1" enable_server_Key_State="$1" enable_server_Map_EXDEV_Error="$1" @@ -254,6 +280,7 @@ enable_server_Signal_Thread="$1" enable_server_Stored_ACLs="$1" enable_server_Timestamp_Compat="$1" + enable_server_Win8_Pseudo_Handles="$1" enable_services_SERVICE_FILE_SYSTEM_DRIVER="$1" enable_setupapi_HSPFILEQ_Check_Type="$1" enable_setupapi_SetupDiSetDeviceInstallParamsW="$1" @@ -280,24 +307,29 @@ enable_shlwapi_AssocGetPerceivedType="$1" enable_shlwapi_SHMapHandle="$1" enable_shlwapi_UrlCombine="$1" + enable_stdole32_idl_Typelib="$1" + enable_stdole32_tlb_SLTG_Typelib="$1" + enable_taskmgr_Memory_Usage="$1" + enable_ucrtbase_Functions="$1" enable_user32_DeferWindowPos="$1" enable_user32_Dialog_Paint_Event="$1" enable_user32_DrawTextExW="$1" enable_user32_GetSystemMetrics="$1" enable_user32_Invalidate_Key_State="$1" enable_user32_ListBox_Size="$1" - enable_user32_MOUSEHOOKSTRUCTEX="$1" enable_user32_Mouse_Message_Hwnd="$1" enable_user32_Refresh_MDI_Menus="$1" enable_user32_ScrollWindowEx="$1" - enable_user32_SetCaretPos="$1" enable_user32_SetCoalescableTimer="$1" - enable_user32_WM_CAPTURECHANGE="$1" enable_user32_WM_MDICALCCHILDSCROLL="$1" enable_user32_WndProc="$1" + enable_uxtheme_CloseThemeData="$1" enable_uxtheme_GTK_Theming="$1" + enable_vcomp_Atomic_I8="$1" enable_version_VerQueryValue="$1" + enable_vmm_vxd_PageReserve="$1" enable_wbemdisp_ISWbemSecurity="$1" + enable_widl_SLTG_Typelib_Support="$1" enable_wine_inf_Performance="$1" enable_wine_inf_ProfileList_UserSID="$1" enable_wineboot_DriveSerial="$1" @@ -312,10 +344,10 @@ enable_wined3d_DXTn="$1" enable_wined3d_Geforce_425M="$1" enable_wined3d_MESA_GPU_Info="$1" - enable_wined3d_Multisampling="$1" enable_wined3d_Revert_PixelFormat="$1" enable_wined3d_UnhandledBlendFactor="$1" enable_wined3d_resource_check_usage="$1" + enable_wined3d_resource_map="$1" enable_wined3d_surface_cpu_blt="$1" enable_wined3d_wined3d_swapchain_present="$1" enable_winedevice_Fix_Relocation="$1" @@ -337,6 +369,7 @@ enable_winspool_drv_SetPrinterW="$1" enable_winsta_WinStationEnumerateW="$1" enable_wpcap_Dynamic_Linking="$1" + enable_wpcap_Several_Fixes="$1" enable_ws2_32_APC_Performance="$1" enable_ws2_32_Connect_Time="$1" enable_ws2_32_Sort_default_route="$1" @@ -344,6 +377,7 @@ enable_ws2_32_WSACleanup="$1" enable_ws2_32_WriteWatches="$1" enable_ws2_32_getaddrinfo="$1" + enable_ws2_32_getsockopt="$1" enable_wtsapi32_EnumerateProcesses="$1" enable_wusa_MSU_Package_Installer="$1" } @@ -382,24 +416,42 @@ amstream-GetMultiMediaStream) enable_amstream_GetMultiMediaStream="$2" ;; - api-ms-win-crt-Stub_DLLs) - enable_api_ms_win_crt_Stub_DLLs="$2" + api-ms-win-Stub_DLLs) + enable_api_ms_win_Stub_DLLs="$2" ;; authz-Stub_Functions) enable_authz_Stub_Functions="$2" ;; + avifil32-AVIFile_Proxies) + enable_avifil32_AVIFile_Proxies="$2" + ;; + avifil32-IGetFrame_fnSetFormat) + enable_avifil32_IGetFrame_fnSetFormat="$2" + ;; + avifile.dll16-AVIStreamGetFrame) + enable_avifile_dll16_AVIStreamGetFrame="$2" + ;; browseui-Progress_Dialog) enable_browseui_Progress_Dialog="$2" ;; category-stable) enable_category_stable="$2" ;; + combase-RoApi) + enable_combase_RoApi="$2" + ;; + combase-WindowsString) + enable_combase_WindowsString="$2" + ;; comctl32-Button_Theming) enable_comctl32_Button_Theming="$2" ;; comctl32-PROPSHEET_InsertPage) enable_comctl32_PROPSHEET_InsertPage="$2" ;; + comctl32-TTM_ADDTOOLW) + enable_comctl32_TTM_ADDTOOLW="$2" + ;; configure-Absolute_RPATH) enable_configure_Absolute_RPATH="$2" ;; @@ -430,9 +482,6 @@ d3dx9_33-Share_Source) enable_d3dx9_33_Share_Source="$2" ;; - d3dx9_36-AnimationController) - enable_d3dx9_36_AnimationController="$2" - ;; d3dx9_36-CloneEffect) enable_d3dx9_36_CloneEffect="$2" ;; @@ -475,6 +524,9 @@ dbghelp-Debug_Symbols) enable_dbghelp_Debug_Symbols="$2" ;; + ddraw-Device_Caps) + enable_ddraw_Device_Caps="$2" + ;; ddraw-EnumSurfaces) enable_ddraw_EnumSurfaces="$2" ;; @@ -484,6 +536,9 @@ ddraw-Rendering_Targets) enable_ddraw_Rendering_Targets="$2" ;; + ddraw-Revert_Surface_Init) + enable_ddraw_Revert_Surface_Init="$2" + ;; ddraw-Write_Vtable) enable_ddraw_Write_Vtable="$2" ;; @@ -508,6 +563,9 @@ dsound-Revert_Cleanup) enable_dsound_Revert_Cleanup="$2" ;; + dxdiagn-Display_Information) + enable_dxdiagn_Display_Information="$2" + ;; dxdiagn-Enumerate_DirectSound) enable_dxdiagn_Enumerate_DirectSound="$2" ;; @@ -520,6 +578,9 @@ dxva2-Video_Decoder) enable_dxva2_Video_Decoder="$2" ;; + explorer-Video_Registry_Key) + enable_explorer_Video_Registry_Key="$2" + ;; fonts-Missing_Fonts) enable_fonts_Missing_Fonts="$2" ;; @@ -556,6 +617,9 @@ imagehlp-ImageLoad) enable_imagehlp_ImageLoad="$2" ;; + imm32-IMMDisableLegacyIME) + enable_imm32_IMMDisableLegacyIME="$2" + ;; inetcpl-Default_Home) enable_inetcpl_Default_Home="$2" ;; @@ -568,9 +632,6 @@ kernel32-COMSPEC) enable_kernel32_COMSPEC="$2" ;; - kernel32-Codepage_Conversion) - enable_kernel32_Codepage_Conversion="$2" - ;; kernel32-CompareString_Length) enable_kernel32_CompareString_Length="$2" ;; @@ -580,17 +641,20 @@ kernel32-Cwd_Startup_Info) enable_kernel32_Cwd_Startup_Info="$2" ;; + kernel32-FindFirstFile) + enable_kernel32_FindFirstFile="$2" + ;; kernel32-FreeUserPhysicalPages) enable_kernel32_FreeUserPhysicalPages="$2" ;; + kernel32-GetCurrentPackageFamilyName) + enable_kernel32_GetCurrentPackageFamilyName="$2" + ;; kernel32-GetFinalPathNameByHandle) enable_kernel32_GetFinalPathNameByHandle="$2" ;; - kernel32-GetLargestConsoleWindowSize) - enable_kernel32_GetLargestConsoleWindowSize="$2" - ;; - kernel32-GetLogicalProcessorInformationEx) - enable_kernel32_GetLogicalProcessorInformationEx="$2" + kernel32-InterlockedPushListSList) + enable_kernel32_InterlockedPushListSList="$2" ;; kernel32-LocaleNameToLCID) enable_kernel32_LocaleNameToLCID="$2" @@ -604,6 +668,9 @@ kernel32-Profile) enable_kernel32_Profile="$2" ;; + kernel32-QT_Environment_Variables) + enable_kernel32_QT_Environment_Variables="$2" + ;; kernel32-SetFileCompletionNotificationModes) enable_kernel32_SetFileCompletionNotificationModes="$2" ;; @@ -616,6 +683,9 @@ kernel32-VerifyVersionInfo) enable_kernel32_VerifyVersionInfo="$2" ;; + kernel32-VirtualProtect) + enable_kernel32_VirtualProtect="$2" + ;; libs-Debug_Channel) enable_libs_Debug_Channel="$2" ;; @@ -631,6 +701,9 @@ mmdevapi-AEV_Stubs) enable_mmdevapi_AEV_Stubs="$2" ;; + mmsystem.dll16-Fix_Argument_Order) + enable_mmsystem_dll16_Fix_Argument_Order="$2" + ;; mountmgr-DosDevices) enable_mountmgr_DosDevices="$2" ;; @@ -646,12 +719,21 @@ msidb-Implementation) enable_msidb_Implementation="$2" ;; + msvcr120-_SetWinRTOutOfMemoryExceptionCallback) + enable_msvcr120__SetWinRTOutOfMemoryExceptionCallback="$2" + ;; + msvcr120-strof) + enable_msvcr120_strof="$2" + ;; msvcrt-Math_Precision) enable_msvcrt_Math_Precision="$2" ;; msvcrt-StdHandle_RefCount) enable_msvcrt_StdHandle_RefCount="$2" ;; + msvideo-MCIWNDM_SETTIMEFORMATA) + enable_msvideo_MCIWNDM_SETTIMEFORMATA="$2" + ;; ntdll-APC_Performance) enable_ntdll_APC_Performance="$2" ;; @@ -661,6 +743,9 @@ ntdll-Activation_Context) enable_ntdll_Activation_Context="$2" ;; + ntdll-ApiSetQueryApiSetPresence) + enable_ntdll_ApiSetQueryApiSetPresence="$2" + ;; ntdll-CLI_Images) enable_ntdll_CLI_Images="$2" ;; @@ -679,6 +764,9 @@ ntdll-DllRedirects) enable_ntdll_DllRedirects="$2" ;; + ntdll-EtwRegisterTraceGuids) + enable_ntdll_EtwRegisterTraceGuids="$2" + ;; ntdll-Exception) enable_ntdll_Exception="$2" ;; @@ -733,8 +821,17 @@ ntdll-Purist_Mode) enable_ntdll_Purist_Mode="$2" ;; - ntdll-RtlIpStringToAddress) - enable_ntdll_RtlIpStringToAddress="$2" + ntdll-RtlIpStringToAddress_Stubs) + enable_ntdll_RtlIpStringToAddress_Stubs="$2" + ;; + ntdll-RtlIpStringToAddress_Tests) + enable_ntdll_RtlIpStringToAddress_Tests="$2" + ;; + ntdll-RtlQueryPackageIdentity) + enable_ntdll_RtlQueryPackageIdentity="$2" + ;; + ntdll-Serial_Port_Detection) + enable_ntdll_Serial_Port_Detection="$2" ;; ntdll-Status_Mapping) enable_ntdll_Status_Mapping="$2" @@ -742,8 +839,11 @@ ntdll-Syscall_Wrappers) enable_ntdll_Syscall_Wrappers="$2" ;; - ntdll-SystemHandleInformation) - enable_ntdll_SystemHandleInformation="$2" + ntdll-SystemInterruptInformation) + enable_ntdll_SystemInterruptInformation="$2" + ;; + ntdll-SystemRecommendedSharedDataAlignment) + enable_ntdll_SystemRecommendedSharedDataAlignment="$2" ;; ntdll-SystemRoot_Symlink) enable_ntdll_SystemRoot_Symlink="$2" @@ -754,6 +854,9 @@ ntdll-Threading) enable_ntdll_Threading="$2" ;; + ntdll-Unused_Import_Descr) + enable_ntdll_Unused_Import_Descr="$2" + ;; ntdll-User_Shared_Data) enable_ntdll_User_Shared_Data="$2" ;; @@ -772,9 +875,6 @@ ntdll-Zero_mod_name) enable_ntdll_Zero_mod_name="$2" ;; - ntdll-x86_64_set_cpu_context) - enable_ntdll_x86_64_set_cpu_context="$2" - ;; ntoskrnl-DriverTest) enable_ntoskrnl_DriverTest="$2" ;; @@ -793,8 +893,14 @@ nvencodeapi-Video_Encoder) enable_nvencodeapi_Video_Encoder="$2" ;; - oleaut32-SysAllocStringByteLen) - enable_oleaut32_SysAllocStringByteLen="$2" + ole32-CoGetApartmentType) + enable_ole32_CoGetApartmentType="$2" + ;; + ole32-HGLOBALStream) + enable_ole32_HGLOBALStream="$2" + ;; + oleaut32-CreateTypeLib) + enable_oleaut32_CreateTypeLib="$2" ;; oleaut32-TKIND_COCLASS) enable_oleaut32_TKIND_COCLASS="$2" @@ -808,6 +914,9 @@ opengl32-Revert_Disable_Ext) enable_opengl32_Revert_Disable_Ext="$2" ;; + quartz-AsyncReader) + enable_quartz_AsyncReader="$2" + ;; quartz-MediaSeeking_Positions) enable_quartz_MediaSeeking_Positions="$2" ;; @@ -820,6 +929,9 @@ rpcrt4-Pipe_Transport) enable_rpcrt4_Pipe_Transport="$2" ;; + rpcrt4-RpcBindingServerFromClient) + enable_rpcrt4_RpcBindingServerFromClient="$2" + ;; secur32-ANSI_NTLM_Credentials) enable_secur32_ANSI_NTLM_Credentials="$2" ;; @@ -838,6 +950,9 @@ server-File_Permissions) enable_server_File_Permissions="$2" ;; + server-Fix_Leak) + enable_server_Fix_Leak="$2" + ;; server-Inherited_ACLs) enable_server_Inherited_ACLs="$2" ;; @@ -877,6 +992,9 @@ server-Timestamp_Compat) enable_server_Timestamp_Compat="$2" ;; + server-Win8_Pseudo_Handles) + enable_server_Win8_Pseudo_Handles="$2" + ;; services-SERVICE_FILE_SYSTEM_DRIVER) enable_services_SERVICE_FILE_SYSTEM_DRIVER="$2" ;; @@ -955,6 +1073,18 @@ shlwapi-UrlCombine) enable_shlwapi_UrlCombine="$2" ;; + stdole32.idl-Typelib) + enable_stdole32_idl_Typelib="$2" + ;; + stdole32.tlb-SLTG_Typelib) + enable_stdole32_tlb_SLTG_Typelib="$2" + ;; + taskmgr-Memory_Usage) + enable_taskmgr_Memory_Usage="$2" + ;; + ucrtbase-Functions) + enable_ucrtbase_Functions="$2" + ;; user32-DeferWindowPos) enable_user32_DeferWindowPos="$2" ;; @@ -973,9 +1103,6 @@ user32-ListBox_Size) enable_user32_ListBox_Size="$2" ;; - user32-MOUSEHOOKSTRUCTEX) - enable_user32_MOUSEHOOKSTRUCTEX="$2" - ;; user32-Mouse_Message_Hwnd) enable_user32_Mouse_Message_Hwnd="$2" ;; @@ -985,30 +1112,36 @@ user32-ScrollWindowEx) enable_user32_ScrollWindowEx="$2" ;; - user32-SetCaretPos) - enable_user32_SetCaretPos="$2" - ;; user32-SetCoalescableTimer) enable_user32_SetCoalescableTimer="$2" ;; - user32-WM_CAPTURECHANGE) - enable_user32_WM_CAPTURECHANGE="$2" - ;; user32-WM_MDICALCCHILDSCROLL) enable_user32_WM_MDICALCCHILDSCROLL="$2" ;; user32-WndProc) enable_user32_WndProc="$2" ;; + uxtheme-CloseThemeData) + enable_uxtheme_CloseThemeData="$2" + ;; uxtheme-GTK_Theming) enable_uxtheme_GTK_Theming="$2" ;; + vcomp-Atomic_I8) + enable_vcomp_Atomic_I8="$2" + ;; version-VerQueryValue) enable_version_VerQueryValue="$2" ;; + vmm.vxd-PageReserve) + enable_vmm_vxd_PageReserve="$2" + ;; wbemdisp-ISWbemSecurity) enable_wbemdisp_ISWbemSecurity="$2" ;; + widl-SLTG_Typelib_Support) + enable_widl_SLTG_Typelib_Support="$2" + ;; wine.inf-Performance) enable_wine_inf_Performance="$2" ;; @@ -1051,9 +1184,6 @@ wined3d-MESA_GPU_Info) enable_wined3d_MESA_GPU_Info="$2" ;; - wined3d-Multisampling) - enable_wined3d_Multisampling="$2" - ;; wined3d-Revert_PixelFormat) enable_wined3d_Revert_PixelFormat="$2" ;; @@ -1063,6 +1193,9 @@ wined3d-resource_check_usage) enable_wined3d_resource_check_usage="$2" ;; + wined3d-resource_map) + enable_wined3d_resource_map="$2" + ;; wined3d-surface_cpu_blt) enable_wined3d_surface_cpu_blt="$2" ;; @@ -1126,6 +1259,9 @@ wpcap-Dynamic_Linking) enable_wpcap_Dynamic_Linking="$2" ;; + wpcap-Several_Fixes) + enable_wpcap_Several_Fixes="$2" + ;; ws2_32-APC_Performance) enable_ws2_32_APC_Performance="$2" ;; @@ -1147,6 +1283,9 @@ ws2_32-getaddrinfo) enable_ws2_32_getaddrinfo="$2" ;; + ws2_32-getsockopt) + enable_ws2_32_getsockopt="$2" + ;; wtsapi32-EnumerateProcesses) enable_wtsapi32_EnumerateProcesses="$2" ;; @@ -1533,9 +1672,6 @@ if test "$enable_d3dx9_26_ID3DXEffect" -gt 1; then abort "Patchset d3dx9_26-ID3DXEffect disabled, but category-stable depends on that." fi - if test "$enable_d3dx9_36_AnimationController" -gt 1; then - abort "Patchset d3dx9_36-AnimationController disabled, but category-stable depends on that." - fi if test "$enable_d3dx9_36_D3DXStubs" -gt 1; then abort "Patchset d3dx9_36-D3DXStubs disabled, but category-stable depends on that." fi @@ -1611,8 +1747,8 @@ if test "$enable_ntdll_Pipe_SpecialCharacters" -gt 1; then abort "Patchset ntdll-Pipe_SpecialCharacters disabled, but category-stable depends on that." fi - if test "$enable_ntdll_RtlIpStringToAddress" -gt 1; then - abort "Patchset ntdll-RtlIpStringToAddress disabled, but category-stable depends on that." + if test "$enable_ntdll_RtlIpStringToAddress_Tests" -gt 1; then + abort "Patchset ntdll-RtlIpStringToAddress_Tests disabled, but category-stable depends on that." fi if test "$enable_ntdll_Threading" -gt 1; then abort "Patchset ntdll-Threading disabled, but category-stable depends on that." @@ -1659,9 +1795,6 @@ if test "$enable_winecfg_Libraries" -gt 1; then abort "Patchset winecfg-Libraries disabled, but category-stable depends on that." fi - if test "$enable_wined3d_Multisampling" -gt 1; then - abort "Patchset wined3d-Multisampling disabled, but category-stable depends on that." - fi if test "$enable_wined3d_Revert_PixelFormat" -gt 1; then abort "Patchset wined3d-Revert_PixelFormat disabled, but category-stable depends on that." fi @@ -1695,9 +1828,6 @@ if test "$enable_winmm_Delay_Import_Depends" -gt 1; then abort "Patchset winmm-Delay_Import_Depends disabled, but category-stable depends on that." fi - if test "$enable_wpcap_Dynamic_Linking" -gt 1; then - abort "Patchset wpcap-Dynamic_Linking disabled, but category-stable depends on that." - fi if test "$enable_ws2_32_Connect_Time" -gt 1; then abort "Patchset ws2_32-Connect_Time disabled, but category-stable depends on that." fi @@ -1712,7 +1842,6 @@ enable_d3dx9_24_ID3DXEffect=1 enable_d3dx9_25_ID3DXEffect=1 enable_d3dx9_26_ID3DXEffect=1 - enable_d3dx9_36_AnimationController=1 enable_d3dx9_36_D3DXStubs=1 enable_d3dx9_36_FindNextValidTechnique=1 enable_d3dx9_36_Optimize_Inplace=1 @@ -1738,7 +1867,7 @@ enable_ntdll_Heap_FreeLists=1 enable_ntdll_NtSetLdtEntries=1 enable_ntdll_Pipe_SpecialCharacters=1 - enable_ntdll_RtlIpStringToAddress=1 + enable_ntdll_RtlIpStringToAddress_Tests=1 enable_ntdll_Threading=1 enable_ntdll_User_Shared_Data=1 enable_ntdll_WriteWatches=1 @@ -1754,7 +1883,6 @@ enable_wine_inf_ProfileList_UserSID=1 enable_wineboot_HKEY_DYN_DATA=1 enable_winecfg_Libraries=1 - enable_wined3d_Multisampling=1 enable_wined3d_Revert_PixelFormat=1 enable_wined3d_UnhandledBlendFactor=1 enable_wined3d_resource_check_usage=1 @@ -1766,7 +1894,6 @@ enable_winex11_wglShareLists=1 enable_wininet_ParseX509EncodedCertificateForListBoxEntry=1 enable_winmm_Delay_Import_Depends=1 - enable_wpcap_Dynamic_Linking=1 enable_ws2_32_Connect_Time=1 enable_ws2_32_WriteWatches=1 fi @@ -1785,6 +1912,13 @@ enable_server_Desktop_Refcount=1 fi +if test "$enable_wpcap_Dynamic_Linking" -eq 1; then + if test "$enable_wpcap_Several_Fixes" -gt 1; then + abort "Patchset wpcap-Several_Fixes disabled, but wpcap-Dynamic_Linking depends on that." + fi + enable_wpcap_Several_Fixes=1 +fi + if test "$enable_wined3d_CSMT_Main" -eq 1; then if test "$enable_wined3d_CSMT_Helper" -gt 1; then abort "Patchset wined3d-CSMT_Helper disabled, but wined3d-CSMT_Main depends on that." @@ -1809,9 +1943,13 @@ if test "$enable_wined3d_DXTn" -gt 1; then abort "Patchset wined3d-DXTn disabled, but wined3d-CSMT_Helper depends on that." fi + if test "$enable_wined3d_resource_map" -gt 1; then + abort "Patchset wined3d-resource_map disabled, but wined3d-CSMT_Helper depends on that." + fi enable_makedep_PARENTSPEC=1 enable_ntdll_DllRedirects=1 enable_wined3d_DXTn=1 + enable_wined3d_resource_map=1 fi if test "$enable_uxtheme_GTK_Theming" -eq 1; then @@ -1821,6 +1959,13 @@ enable_ntdll_DllRedirects=1 fi +if test "$enable_stdole32_tlb_SLTG_Typelib" -eq 1; then + if test "$enable_widl_SLTG_Typelib_Support" -gt 1; then + abort "Patchset widl-SLTG_Typelib_Support disabled, but stdole32.tlb-SLTG_Typelib depends on that." + fi + enable_widl_SLTG_Typelib_Support=1 +fi + if test "$enable_shell32_SHFileOperation_Win9x" -eq 1; then if test "$enable_shell32_Progress_Dialog" -gt 1; then abort "Patchset shell32-Progress_Dialog disabled, but shell32-SHFileOperation_Win9x depends on that." @@ -1919,6 +2064,13 @@ enable_ws2_32_WriteWatches=1 fi +if test "$enable_ntdll_WinSqm" -eq 1; then + if test "$enable_ntdll_EtwRegisterTraceGuids" -gt 1; then + abort "Patchset ntdll-EtwRegisterTraceGuids disabled, but ntdll-WinSqm depends on that." + fi + enable_ntdll_EtwRegisterTraceGuids=1 +fi + if test "$enable_ntdll_SystemRoot_Symlink" -eq 1; then if test "$enable_ntdll_Exception" -gt 1; then abort "Patchset ntdll-Exception disabled, but ntdll-SystemRoot_Symlink depends on that." @@ -1930,6 +2082,13 @@ enable_ntdll_Syscall_Wrappers=1 fi +if test "$enable_ntdll_RtlIpStringToAddress_Tests" -eq 1; then + if test "$enable_ntdll_RtlQueryPackageIdentity" -gt 1; then + abort "Patchset ntdll-RtlQueryPackageIdentity disabled, but ntdll-RtlIpStringToAddress_Tests depends on that." + fi + enable_ntdll_RtlQueryPackageIdentity=1 +fi + if test "$enable_ntdll_Purist_Mode" -eq 1; then if test "$enable_ntdll_DllRedirects" -gt 1; then abort "Patchset ntdll-DllRedirects disabled, but ntdll-Purist_Mode depends on that." @@ -1962,13 +2121,6 @@ enable_ntdll_Syscall_Wrappers=1 fi -if test "$enable_ntdll_Exception" -eq 1; then - if test "$enable_ntdll_x86_64_set_cpu_context" -gt 1; then - abort "Patchset ntdll-x86_64_set_cpu_context disabled, but ntdll-Exception depends on that." - fi - enable_ntdll_x86_64_set_cpu_context=1 -fi - if test "$enable_ntdll_DllRedirects" -eq 1; then if test "$enable_ntdll_DllOverrides_WOW64" -gt 1; then abort "Patchset ntdll-DllOverrides_WOW64 disabled, but ntdll-DllRedirects depends on that." @@ -1994,6 +2146,13 @@ enable_mscoree_CorValidateImage=1 fi +if test "$enable_ntdll_ApiSetQueryApiSetPresence" -eq 1; then + if test "$enable_ntdll_EtwRegisterTraceGuids" -gt 1; then + abort "Patchset ntdll-EtwRegisterTraceGuids disabled, but ntdll-ApiSetQueryApiSetPresence depends on that." + fi + enable_ntdll_EtwRegisterTraceGuids=1 +fi + if test "$enable_kernel32_Named_Pipe" -eq 1; then if test "$enable_rpcrt4_Pipe_Transport" -gt 1; then abort "Patchset rpcrt4-Pipe_Transport disabled, but kernel32-Named_Pipe depends on that." @@ -2048,11 +2207,11 @@ enable_dsound_Revert_Cleanup=1 fi -if test "$enable_d3dx9_36_AnimationController" -eq 1; then - if test "$enable_d3dx9_36_DXTn" -gt 1; then - abort "Patchset d3dx9_36-DXTn disabled, but d3dx9_36-AnimationController depends on that." +if test "$enable_ddraw_IDirect3DTexture2_Load" -eq 1; then + if test "$enable_wined3d_resource_map" -gt 1; then + abort "Patchset wined3d-resource_map disabled, but ddraw-IDirect3DTexture2_Load depends on that." fi - enable_d3dx9_36_DXTn=1 + enable_wined3d_resource_map=1 fi if test "$enable_d3dx9_33_Share_Source" -eq 1; then @@ -2080,6 +2239,33 @@ enable_d3dx9_25_ID3DXEffect=1 fi +if test "$enable_api_ms_win_Stub_DLLs" -eq 1; then + if test "$enable_combase_RoApi" -gt 1; then + abort "Patchset combase-RoApi disabled, but api-ms-win-Stub_DLLs depends on that." + fi + if test "$enable_kernel32_FreeUserPhysicalPages" -gt 1; then + abort "Patchset kernel32-FreeUserPhysicalPages disabled, but api-ms-win-Stub_DLLs depends on that." + fi + if test "$enable_kernel32_GetCurrentPackageFamilyName" -gt 1; then + abort "Patchset kernel32-GetCurrentPackageFamilyName disabled, but api-ms-win-Stub_DLLs depends on that." + fi + if test "$enable_kernel32_GetFinalPathNameByHandle" -gt 1; then + abort "Patchset kernel32-GetFinalPathNameByHandle disabled, but api-ms-win-Stub_DLLs depends on that." + fi + if test "$enable_kernel32_InterlockedPushListSList" -gt 1; then + abort "Patchset kernel32-InterlockedPushListSList disabled, but api-ms-win-Stub_DLLs depends on that." + fi + if test "$enable_ole32_CoGetApartmentType" -gt 1; then + abort "Patchset ole32-CoGetApartmentType disabled, but api-ms-win-Stub_DLLs depends on that." + fi + enable_combase_RoApi=1 + enable_kernel32_FreeUserPhysicalPages=1 + enable_kernel32_GetCurrentPackageFamilyName=1 + enable_kernel32_GetFinalPathNameByHandle=1 + enable_kernel32_InterlockedPushListSList=1 + enable_ole32_CoGetApartmentType=1 +fi + if test "$enable_advapi32_LsaLookupSids" -eq 1; then if test "$enable_server_CreateProcess_ACLs" -gt 1; then abort "Patchset server-CreateProcess_ACLs disabled, but advapi32-LsaLookupSids depends on that." @@ -2345,15 +2531,220 @@ ) >> "$patchlist" fi -# Patchset api-ms-win-crt-Stub_DLLs +# Patchset combase-RoApi +# | +# | Modified files: +# | * dlls/api-ms-win-core-winrt-l1-1-0/api-ms-win-core-winrt-l1-1-0.spec, dlls/combase/Makefile.in, +# | dlls/combase/combase.spec, dlls/combase/roapi.c, include/Makefile.in, include/activation.idl, include/objidl.idl, +# | include/roapi.h +# | +if test "$enable_combase_RoApi" -eq 1; then + patch_apply combase-RoApi/0001-include-Add-activation.idl-with-IActivationFactory-i.patch + patch_apply combase-RoApi/0002-include-roapi.h-Add-further-typedefs.patch + patch_apply combase-RoApi/0003-combase-Implement-RoGetActivationFactory.patch + patch_apply combase-RoApi/0004-combase-Implement-RoActivateInstance.patch + patch_apply combase-RoApi/0005-combase-Add-stub-for-RoGetApartmentIdentifier.patch + patch_apply combase-RoApi/0006-include-objidl.idl-Add-IApartmentShutdown-interface.patch + patch_apply combase-RoApi/0007-combase-Add-stub-for-RoRegisterForApartmentShutdown.patch + patch_apply combase-RoApi/0008-combase-Add-stub-for-RoGetServerActivatableClasses.patch + patch_apply combase-RoApi/0009-combase-Add-stub-for-RoRegisterActivationFactories.patch + patch_apply combase-RoApi/0010-combase-Add-stub-for-CleanupTlsOleState.patch + ( + echo '+ { "Michael Müller", "include: Add activation.idl with IActivationFactory interface.", 1 },'; + echo '+ { "Michael Müller", "include/roapi.h: Add further typedefs.", 1 },'; + echo '+ { "Michael Müller", "combase: Implement RoGetActivationFactory.", 1 },'; + echo '+ { "Michael Müller", "combase: Implement RoActivateInstance.", 1 },'; + echo '+ { "Michael Müller", "combase: Add stub for RoGetApartmentIdentifier.", 1 },'; + echo '+ { "Michael Müller", "include/objidl.idl: Add IApartmentShutdown interface.", 1 },'; + echo '+ { "Michael Müller", "combase: Add stub for RoRegisterForApartmentShutdown.", 1 },'; + echo '+ { "Michael Müller", "combase: Add stub for RoGetServerActivatableClasses.", 1 },'; + echo '+ { "Michael Müller", "combase: Add stub for RoRegisterActivationFactories.", 1 },'; + echo '+ { "Michael Müller", "combase: Add stub for CleanupTlsOleState.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset kernel32-FreeUserPhysicalPages +# | +# | This patchset fixes the following Wine bugs: +# | * [#39543] Add stub kernel32.FreeUserPhysicalPages # | # | Modified files: -# | * dlls/ucrtbase/ucrtbase.spec +# | * dlls/kernel32/heap.c, dlls/kernel32/kernel32.spec # | -if test "$enable_api_ms_win_crt_Stub_DLLs" -eq 1; then - patch_apply api-ms-win-crt-Stub_DLLs/0001-ucrtbase-Hook-up-some-functions-with-new-names-to-ex.patch +if test "$enable_kernel32_FreeUserPhysicalPages" -eq 1; then + patch_apply kernel32-FreeUserPhysicalPages/0001-kernel32-add-FreeUserPhysicalPages-stub-try-2.patch ( - echo '+ { "Martin Storsjo", "ucrtbase: Hook up some functions with new names to existing implementations.", 1 },'; + echo '+ { "Austin English", "kernel32: Add FreeUserPhysicalPages stub.", 2 },'; + ) >> "$patchlist" +fi + +# Patchset kernel32-GetCurrentPackageFamilyName +# | +# | Modified files: +# | * dlls/kernel32/kernel32.spec, dlls/kernel32/version.c +# | +if test "$enable_kernel32_GetCurrentPackageFamilyName" -eq 1; then + patch_apply kernel32-GetCurrentPackageFamilyName/0001-kernel32-Add-stub-for-GetCurrentPackageFamilyName-an.patch + ( + echo '+ { "Michael Müller", "kernel32: Add stub for GetCurrentPackageFamilyName and add related functions to spec file.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset kernel32-GetFinalPathNameByHandle +# | +# | This patchset fixes the following Wine bugs: +# | * [#34851] Support for GetFinalPathNameByHandle +# | +# | Modified files: +# | * dlls/api-ms-win-core-file-l1-1-0/api-ms-win-core-file-l1-1-0.spec, dlls/api-ms-win-core-file-l1-2-0/api-ms-win-core- +# | file-l1-2-0.spec, dlls/kernel32/file.c, dlls/kernel32/kernel32.spec +# | +if test "$enable_kernel32_GetFinalPathNameByHandle" -eq 1; then + patch_apply kernel32-GetFinalPathNameByHandle/0001-kernel32-Implement-GetFinalPathNameByHandle.patch + ( + echo '+ { "Michael Müller", "kernel32: Implement GetFinalPathNameByHandle.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset kernel32-InterlockedPushListSList +# | +# | Modified files: +# | * dlls/api-ms-win-core-interlocked-l1-1-0/api-ms-win-core-interlocked-l1-1-0.spec, dlls/kernel32/kernel32.spec +# | +if test "$enable_kernel32_InterlockedPushListSList" -eq 1; then + patch_apply kernel32-InterlockedPushListSList/0001-kernel32-Forward-InterlockedPushListSList-to-ntdll.patch + ( + echo '+ { "Sebastian Lackner", "kernel32: Forward InterlockedPushListSList to ntdll.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset ole32-CoGetApartmentType +# | +# | Modified files: +# | * dlls/api-ms-win-core-com-l1-1-0/api-ms-win-core-com-l1-1-0.spec, dlls/api-ms-win-downlevel-ole32-l1-1-0/api-ms-win- +# | downlevel-ole32-l1-1-0.spec, dlls/combase/combase.spec, dlls/ole32/compobj.c, dlls/ole32/ole32.spec, +# | dlls/ole32/tests/compobj.c, include/objidl.idl +# | +if test "$enable_ole32_CoGetApartmentType" -eq 1; then + patch_apply ole32-CoGetApartmentType/0001-ole32-Implement-CoGetApartmentType.patch + ( + echo '+ { "Michael Müller", "ole32: Implement CoGetApartmentType.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset api-ms-win-Stub_DLLs +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * combase-RoApi, kernel32-FreeUserPhysicalPages, kernel32-GetCurrentPackageFamilyName, kernel32-GetFinalPathNameByHandle, +# | kernel32-InterlockedPushListSList, ole32-CoGetApartmentType +# | +# | Modified files: +# | * configure.ac, dlls/api-ms-win-appmodel-runtime-l1-1-1/Makefile.in, dlls/api-ms-win-appmodel-runtime-l1-1-1/api-ms-win- +# | appmodel-runtime-l1-1-1.spec, dlls/api-ms-win-core-apiquery-l1-1-0/Makefile.in, dlls/api-ms-win-core-apiquery-l1-1-0 +# | /api-ms-win-core-apiquery-l1-1-0.spec, dlls/api-ms-win-core-com-l1-1-1/Makefile.in, dlls/api-ms-win-core-com-l1-1-1/api- +# | ms-win-core-com-l1-1-1.spec, dlls/api-ms-win-core-delayload-l1-1-1/Makefile.in, dlls/api-ms-win-core-delayload-l1-1-1 +# | /api-ms-win-core-delayload-l1-1-1.spec, dlls/api-ms-win-core-heap-l2-1-0/Makefile.in, dlls/api-ms-win-core-heap-l2-1-0 +# | /api-ms-win-core-heap-l2-1-0.spec, dlls/api-ms-win-core-kernel32-legacy-l1-1-1/Makefile.in, dlls/api-ms-win-core- +# | kernel32-legacy-l1-1-1/api-ms-win-core-kernel32-legacy-l1-1-1.spec, dlls/api-ms-win-core- +# | libraryloader-l1-2-0/Makefile.in, dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec, +# | dlls/api-ms-win-core-memory-l1-1-2/Makefile.in, dlls/api-ms-win-core-memory-l1-1-2/api-ms-win-core-memory-l1-1-2.spec, +# | dlls/api-ms-win-core-quirks-l1-1-0/Makefile.in, dlls/api-ms-win-core-quirks-l1-1-0/api-ms-win-core-quirks-l1-1-0.spec, +# | dlls/api-ms-win-core-shlwapi-obsolete-l1-2-0/Makefile.in, dlls/api-ms-win-core-shlwapi-obsolete-l1-2-0/api-ms-win-core- +# | shlwapi-obsolete-l1-2-0.spec, dlls/api-ms-win-core-threadpool-l1-2-0/Makefile.in, dlls/api-ms-win-core-threadpool-l1-2-0 +# | /api-ms-win-core-threadpool-l1-2-0.spec, dlls/api-ms-win-core-winrt-registration-l1-1-0/Makefile.in, dlls/api-ms-win- +# | core-winrt-registration-l1-1-0/api-ms-win-core-winrt-registration-l1-1-0.spec, dlls/api-ms-win-core- +# | wow64-l1-1-0/Makefile.in, dlls/api-ms-win-core-wow64-l1-1-0/api-ms-win-core-wow64-l1-1-0.spec, dlls/api-ms-win-eventing- +# | classicprovider-l1-1-0/Makefile.in, dlls/api-ms-win-eventing-classicprovider-l1-1-0/api-ms-win-eventing- +# | classicprovider-l1-1-0.spec, dlls/api-ms-win-rtcore-ntuser-draw-l1-1-0/Makefile.in, dlls/api-ms-win-rtcore-ntuser- +# | draw-l1-1-0/api-ms-win-rtcore-ntuser-draw-l1-1-0.spec, dlls/api-ms-win-rtcore-ntuser-window-l1-1-0/Makefile.in, dlls +# | /api-ms-win-rtcore-ntuser-window-l1-1-0/api-ms-win-rtcore-ntuser-window-l1-1-0.spec, dlls/api-ms-win-shcore- +# | obsolete-l1-1-0/Makefile.in, dlls/api-ms-win-shcore-obsolete-l1-1-0/api-ms-win-shcore-obsolete-l1-1-0.spec, dlls/api-ms- +# | win-shcore-stream-l1-1-0/Makefile.in, dlls/api-ms-win-shcore-stream-l1-1-0/api-ms-win-shcore-stream-l1-1-0.spec, dlls +# | /api-ms-win-shcore-thread-l1-1-0/Makefile.in, dlls/api-ms-win-shcore-thread-l1-1-0/api-ms-win-shcore-thread-l1-1-0.spec, +# | dlls/ext-ms-win-appmodel-usercontext-l1-1-0/Makefile.in, dlls/ext-ms-win-appmodel-usercontext-l1-1-0/ext-ms-win- +# | appmodel-usercontext-l1-1-0.spec, dlls/ext-ms-win-appmodel-usercontext-l1-1-0/main.c, dlls/ext-ms-win-kernel32-package- +# | current-l1-1-0/Makefile.in, dlls/ext-ms-win-kernel32-package-current-l1-1-0/ext-ms-win-kernel32-package- +# | current-l1-1-0.spec, dlls/ext-ms-win-ntuser-mouse-l1-1-0/Makefile.in, dlls/ext-ms-win-ntuser-mouse-l1-1-0/ext-ms-win- +# | ntuser-mouse-l1-1-0.spec, dlls/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0/Makefile.in, dlls/ext-ms-win-rtcore-ntuser- +# | syscolors-l1-1-0/ext-ms-win-rtcore-ntuser-syscolors-l1-1-0.spec, dlls/ext-ms-win-rtcore-ntuser- +# | sysparams-l1-1-0/Makefile.in, dlls/ext-ms-win-rtcore-ntuser-sysparams-l1-1-0/ext-ms-win-rtcore-ntuser- +# | sysparams-l1-1-0.spec, dlls/ext-ms-win-uxtheme-themes-l1-1-0/Makefile.in, dlls/ext-ms-win-uxtheme-themes-l1-1-0/ext-ms- +# | win-uxtheme-themes-l1-1-0.spec, dlls/ext-ms-win-xaml-pal-l1-1-0/Makefile.in, dlls/ext-ms-win-xaml-pal-l1-1-0/ext-ms-win- +# | xaml-pal-l1-1-0.spec, dlls/ext-ms-win-xaml-pal-l1-1-0/main.c, dlls/iertutil/Makefile.in, dlls/iertutil/iertutil.spec, +# | dlls/iertutil/main.c, dlls/kernelbase/Makefile.in, dlls/kernelbase/kernelbase.spec, dlls/kernelbase/misc.c, +# | dlls/shcore/Makefile.in, dlls/shcore/main.c, dlls/shcore/shcore.spec, dlls/shlwapi/shlwapi.spec, include/Makefile.in, +# | include/shellscalingapi.h, tools/make_specfiles +# | +if test "$enable_api_ms_win_Stub_DLLs" -eq 1; then + patch_apply api-ms-win-Stub_DLLs/0001-api-ms-win-core-com-l1-1-1-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0002-kernelbase-Add-dll-and-add-stub-for-QuirkIsEnabled.patch + patch_apply api-ms-win-Stub_DLLs/0003-api-ms-win-core-quirks-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0004-api-ms-win-core-delayload-l1-1-1-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0005-api-ms-win-appmodel-runtime-l1-1-1-Add-new-dll.patch + patch_apply api-ms-win-Stub_DLLs/0006-api-ms-win-core-apiquery-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0007-api-ms-win-core-libraryloader-l1-2-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0008-api-ms-win-core-kernel32-legacy-l1-1-1-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0009-api-ms-win-core-heap-l2-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0010-api-ms-win-eventing-classicprovider-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0011-iertutil-Add-dll-and-add-stub-for-ordinal-811.patch + patch_apply api-ms-win-Stub_DLLs/0012-api-ms-win-core-winrt-registration-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0013-shcore-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0014-api-ms-win-shcore-obsolete-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0015-ext-ms-win-xaml-pal-l1-1-0-Add-dll-and-add-stub-for-.patch + patch_apply api-ms-win-Stub_DLLs/0016-ext-ms-win-appmodel-usercontext-l1-1-0-Add-dll-and-a.patch + patch_apply api-ms-win-Stub_DLLs/0017-api-ms-win-shcore-thread-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0018-ext-ms-win-xaml-pal-l1-1-0-Add-stub-for-GetThemeServ.patch + patch_apply api-ms-win-Stub_DLLs/0019-api-ms-win-core-memory-l1-1-2-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0020-api-ms-win-core-wow64-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0021-api-ms-win-core-shlwapi-obsolete-l1-2-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0022-api-ms-win-core-threadpool-l1-2-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0023-api-ms-win-shcore-stream-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0024-ext-ms-win-ntuser-mouse-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0025-ext-ms-win-uxtheme-themes-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0026-api-ms-win-rtcore-ntuser-window-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0027-ext-ms-win-rtcore-ntuser-syscolors-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0028-api-ms-win-rtcore-ntuser-draw-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0029-ext-ms-win-rtcore-ntuser-sysparams-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0030-ext-ms-win-kernel32-package-current-l1-1-0-Add-dll.patch + patch_apply api-ms-win-Stub_DLLs/0031-shcore-Add-SetProcessDpiAwareness-stub.patch + patch_apply api-ms-win-Stub_DLLs/0032-shcore-Implement-stub-for-GetDpiForMonitor.patch + patch_apply api-ms-win-Stub_DLLs/0033-kernelbase-Add-stub-for-QuirkIsEnabled3.patch + patch_apply api-ms-win-Stub_DLLs/0034-shcore-Add-stub-for-GetProcessDpiAwareness.patch + ( + echo '+ { "Michael Müller", "api-ms-win-core-com-l1-1-1: Add dll.", 1 },'; + echo '+ { "Michael Müller", "kernelbase: Add dll and add stub for QuirkIsEnabled.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-core-quirks-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-core-delayload-l1-1-1: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-appmodel-runtime-l1-1-1: Add new dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-core-apiquery-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-core-libraryloader-l1-2-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-core-kernel32-legacy-l1-1-1: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-core-heap-l2-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-eventing-classicprovider-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "iertutil: Add dll and add stub for ordinal 811.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-core-winrt-registration-l1-1-0: Add dll.", 1 },'; + echo '+ { "Sebastian Lackner", "shcore: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-shcore-obsolete-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "ext-ms-win-xaml-pal-l1-1-0: Add dll and add stub for XamlBehaviorEnabled.", 1 },'; + echo '+ { "Michael Müller", "ext-ms-win-appmodel-usercontext-l1-1-0: Add dll and add stub for UserContextExtInitialize.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-shcore-thread-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "ext-ms-win-xaml-pal-l1-1-0: Add stub for GetThemeServices.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-core-memory-l1-1-2: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-core-wow64-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-core-shlwapi-obsolete-l1-2-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-core-threadpool-l1-2-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-shcore-stream-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "ext-ms-win-ntuser-mouse-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "ext-ms-win-uxtheme-themes-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-rtcore-ntuser-window-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "ext-ms-win-rtcore-ntuser-syscolors-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "api-ms-win-rtcore-ntuser-draw-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "ext-ms-win-rtcore-ntuser-sysparams-l1-1-0: Add dll.", 1 },'; + echo '+ { "Michael Müller", "ext-ms-win-kernel32-package-current-l1-1-0: Add dll.", 1 },'; + echo '+ { "Sebastian Lackner", "shcore: Add SetProcessDpiAwareness stub.", 1 },'; + echo '+ { "Sebastian Lackner", "shcore: Implement stub for GetDpiForMonitor.", 1 },'; + echo '+ { "Michael Müller", "kernelbase: Add stub for QuirkIsEnabled3.", 1 },'; + echo '+ { "Sebastian Lackner", "shcore: Add stub for GetProcessDpiAwareness.", 1 },'; ) >> "$patchlist" fi @@ -2369,6 +2760,48 @@ ) >> "$patchlist" fi +# Patchset avifil32-AVIFile_Proxies +# | +# | This patchset fixes the following Wine bugs: +# | * [#38564] Add support for AVIFile interface proxies +# | +# | Modified files: +# | * dlls/avifil32/Makefile.in, dlls/avifil32/avifil32.idl, dlls/avifil32/avifile_ifaces.idl, +# | dlls/avifil32/avifile_private.h, dlls/avifil32/factory.c +# | +if test "$enable_avifil32_AVIFile_Proxies" -eq 1; then + patch_apply avifil32-AVIFile_Proxies/0001-avifil32-Add-support-for-AVIFile-interface-proxies.-.patch + ( + echo '+ { "Dmitry Timoshkov", "avifil32: Add support for AVIFile interface proxies.", 2 },'; + ) >> "$patchlist" +fi + +# Patchset avifil32-IGetFrame_fnSetFormat +# | +# | Modified files: +# | * dlls/avifil32/getframe.c +# | +if test "$enable_avifil32_IGetFrame_fnSetFormat" -eq 1; then + patch_apply avifil32-IGetFrame_fnSetFormat/0001-avifil32-Correctly-handle-compressed-frames-when-des.patch + ( + echo '+ { "Michael Müller", "avifil32: Correctly handle compressed frames when desired format is specified.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset avifile.dll16-AVIStreamGetFrame +# | +# | Modified files: +# | * dlls/avifile.dll16/Makefile.in, dlls/avifile.dll16/avifile.dll16.spec, dlls/avifile.dll16/main.c +# | +if test "$enable_avifile_dll16_AVIStreamGetFrame" -eq 1; then + patch_apply avifile.dll16-AVIStreamGetFrame/0001-avifile-Correctly-convert-result-of-AVIStreamGetFram.patch + patch_apply avifile.dll16-AVIStreamGetFrame/0002-avifile-Convert-between-AVISTREAMINFO-16-bit-and-AVI.patch + ( + echo '+ { "Michael Müller", "avifile.dll16: Correctly convert result of AVIStreamGetFrame to a segptr.", 1 },'; + echo '+ { "Michael Müller", "avifile.dll16: Convert between AVISTREAMINFO (16 bit) and AVISTREAMINFOA.", 1 },'; + ) >> "$patchlist" +fi + # Patchset browseui-Progress_Dialog # | # | Modified files: @@ -2383,6 +2816,27 @@ ) >> "$patchlist" fi +# Patchset combase-WindowsString +# | +# | Modified files: +# | * dlls/api-ms-win-core-winrt-string-l1-1-0/api-ms-win-core-winrt-string-l1-1-0.spec, dlls/combase/combase.spec, +# | dlls/combase/string.c, dlls/combase/tests/string.c, include/winnls.h +# | +if test "$enable_combase_WindowsString" -eq 1; then + patch_apply combase-WindowsString/0001-combase-Implement-WindowsCompareStringOrdinal.patch + patch_apply combase-WindowsString/0002-combase-tests-Add-tests-for-WindowsCompareStringOrdi.patch + patch_apply combase-WindowsString/0003-combase-Implement-WindowsTrimStringStart.patch + patch_apply combase-WindowsString/0004-combase-Implement-WindowsTrimStringEnd.patch + patch_apply combase-WindowsString/0005-combase-tests-Add-tests-for-WindowsTrimString-Start-.patch + ( + echo '+ { "Sebastian Lackner", "combase: Implement WindowsCompareStringOrdinal.", 2 },'; + echo '+ { "Sebastian Lackner", "combase/tests: Add tests for WindowsCompareStringOrdinal.", 1 },'; + echo '+ { "Sebastian Lackner", "combase: Implement WindowsTrimStringStart.", 1 },'; + echo '+ { "Sebastian Lackner", "combase: Implement WindowsTrimStringEnd.", 1 },'; + echo '+ { "Sebastian Lackner", "combase/tests: Add tests for WindowsTrimString{Start,End}.", 1 },'; + ) >> "$patchlist" +fi + # Patchset comctl32-Button_Theming # | # | This patchset fixes the following Wine bugs: @@ -2415,6 +2869,21 @@ ) >> "$patchlist" fi +# Patchset comctl32-TTM_ADDTOOLW +# | +# | This patchset fixes the following Wine bugs: +# | * [#10347] Protect TTM_ADDTOOLW from invalid text pointers +# | +# | Modified files: +# | * dlls/comctl32/tests/tooltips.c, dlls/comctl32/tooltips.c +# | +if test "$enable_comctl32_TTM_ADDTOOLW" -eq 1; then + patch_apply comctl32-TTM_ADDTOOLW/0001-comctl32-tooltip-Protect-TTM_ADDTOOLW-from-invalid-t.patch + ( + echo '+ { "Alistair Leslie-Hughes", "comctl32/tooltip: Protect TTM_ADDTOOLW from invalid text pointers.", 1 },'; + ) >> "$patchlist" +fi + # Patchset configure-Absolute_RPATH # | # | This patchset fixes the following Wine bugs: @@ -2502,7 +2971,7 @@ # | * [#25138] Fix wrong version of ID3DXEffect interface for d3dx9_25 # | # | Modified files: -# | * dlls/d3dx9_25/Makefile.in, dlls/d3dx9_25/d3dx9_25.spec, dlls/d3dx9_25/effect.c, include/d3dx9effect.h +# | * dlls/d3dx9_25/Makefile.in, dlls/d3dx9_25/d3dx9_25.spec, dlls/d3dx9_25/effect.c # | if test "$enable_d3dx9_25_ID3DXEffect" -eq 1; then patch_apply d3dx9_25-ID3DXEffect/0001-d3dx9_25-Add-an-interface-wrapper-for-different-vers.patch @@ -2616,7 +3085,7 @@ # | * [#21817] Share source of d3dx9_36 with d3dx9_33 to avoid Wine DLL forwards # | # | Modified files: -# | * dlls/d3dx9_33/Makefile.in, dlls/d3dx9_33/d3dx9_33.spec, dlls/d3dx9_33/d3dx9_33_main.c +# | * dlls/d3dx9_33/Makefile.in, dlls/d3dx9_33/d3dx9_33.spec, dlls/d3dx9_33/d3dx9_33_main.c, tools/make_specfiles # | if test "$enable_d3dx9_33_Share_Source" -eq 1; then patch_apply d3dx9_33-Share_Source/0001-d3dx9_33-Share-the-source-with-d3dx9_36.patch @@ -2625,26 +3094,6 @@ ) >> "$patchlist" fi -# Patchset d3dx9_36-AnimationController -# | -# | This patchset has the following (direct or indirect) dependencies: -# | * wined3d-DXTn, d3dx9_36-DXTn -# | -# | Modified files: -# | * dlls/d3dx9_36/Makefile.in, dlls/d3dx9_36/animation.c, dlls/d3dx9_36/d3dx9_36.spec, dlls/d3dx9_36/tests/mesh.c, -# | include/d3dx9anim.h -# | -if test "$enable_d3dx9_36_AnimationController" -eq 1; then - patch_apply d3dx9_36-AnimationController/0001-d3dx9_36-Implement-D3DXCreateAnimationController-wit.patch - patch_apply d3dx9_36-AnimationController/0002-d3dx9_36-Store-all-values-passed-to-the-create-and-r.patch - patch_apply d3dx9_36-AnimationController/0003-d3dx9_36-Add-D3DXCreateAnimationController-tests.patch - ( - echo '+ { "Christian Costa", "d3dx9_36: Implement D3DXCreateAnimationController with a stubbed ID3DXAnimationController interface.", 1 },'; - echo '+ { "Alistair Leslie-Hughes", "d3dx9_36: Store all values passed to the create and return them in the correct functions.", 1 },'; - echo '+ { "Alistair Leslie-Hughes", "d3dx9_36: Add D3DXCreateAnimationController tests.", 1 },'; - ) >> "$patchlist" -fi - # Patchset d3dx9_36-CloneEffect # | # | Modified files: @@ -2678,16 +3127,12 @@ # | * [#26898] Support for DDS file format in D3DXSaveTextureToFileInMemory # | # | Modified files: -# | * dlls/d3dx9_36/d3dx9_36_private.h, dlls/d3dx9_36/surface.c, dlls/d3dx9_36/tests/surface.c, dlls/d3dx9_36/texture.c +# | * dlls/d3dx9_36/d3dx9_36_private.h, dlls/d3dx9_36/surface.c, dlls/d3dx9_36/texture.c # | if test "$enable_d3dx9_36_DDS" -eq 1; then - patch_apply d3dx9_36-DDS/0001-d3dx9_36-tests-Add-D3DXSaveSurfaceToFileInMemory-D3D.patch - patch_apply d3dx9_36-DDS/0002-d3dx9_36-Fix-several-issues-in-save_dds_surface_to_m.patch - patch_apply d3dx9_36-DDS/0003-d3dx9_36-Add-support-for-FOURCC-surface-to-save_dds_.patch - patch_apply d3dx9_36-DDS/0004-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch + patch_apply d3dx9_36-DDS/0001-d3dx9_36-Add-support-for-FOURCC-surface-to-save_dds_.patch + patch_apply d3dx9_36-DDS/0002-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch ( - echo '+ { "Alistair Leslie-Hughes", "d3dx9_36/tests: Add D3DXSaveSurfaceToFileInMemory D3DXIFF_DDS tests.", 1 },'; - echo '+ { "Christian Costa", "d3dx9_36: Fix several issues in save_dds_surface_to_memory.", 1 },'; echo '+ { "Christian Costa", "d3dx9_36: Add support for FOURCC surface to save_dds_surface_to_memory.", 1 },'; echo '+ { "Christian Costa", "d3dx9_36: Improve D3DXSaveTextureToFile to save simple texture to dds file.", 1 },'; ) >> "$patchlist" @@ -2829,6 +3274,18 @@ ) >> "$patchlist" fi +# Patchset ddraw-Device_Caps +# | +# | Modified files: +# | * dlls/ddraw/ddraw.c, dlls/ddraw/tests/ddraw7.c +# | +if test "$enable_ddraw_Device_Caps" -eq 1; then + patch_apply ddraw-Device_Caps/0001-ddraw-Don-t-set-HWTRANSFORMANDLIGHT-flag-on-d3d7-RGB.patch + ( + echo '+ { "Michael Müller", "ddraw: Don'\''t set HWTRANSFORMANDLIGHT flag on d3d7 RGB device.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ddraw-EnumSurfaces # | # | This patchset fixes the following Wine bugs: @@ -2848,8 +3305,24 @@ ) >> "$patchlist" fi +# Patchset wined3d-resource_map +# | +# | Modified files: +# | * dlls/d3d11/device.c, dlls/d3d11/texture.c, dlls/d3d8/surface.c, dlls/d3d8/volume.c, dlls/d3d9/surface.c, +# | dlls/d3d9/volume.c, dlls/ddraw/surface.c, dlls/wined3d/resource.c, dlls/wined3d/wined3d.spec, include/wine/wined3d.h +# | +if test "$enable_wined3d_resource_map" -eq 1; then + patch_apply wined3d-resource_map/0001-wined3d-Rename-wined3d_resource_-un-map-to-wined3d_r.patch + ( + echo '+ { "Sebastian Lackner", "wined3d: Rename wined3d_resource_(un)map to wined3d_resource_sub_resource_(un)map.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ddraw-IDirect3DTexture2_Load # | +# | This patchset has the following (direct or indirect) dependencies: +# | * wined3d-resource_map +# | # | Modified files: # | * dlls/ddraw/surface.c, dlls/ddraw/tests/d3d.c, dlls/ddraw/tests/ddraw2.c # | @@ -2877,6 +3350,23 @@ ) >> "$patchlist" fi +# Patchset ddraw-Revert_Surface_Init +# | +# | This patchset fixes the following Wine bugs: +# | * [#40094] Revert patches to move mip-level dimensions fixup (causes regressions in multiple games) +# | +# | Modified files: +# | * dlls/ddraw/surface.c, dlls/wined3d/surface.c, dlls/wined3d/wined3d.spec, include/wine/wined3d.h +# | +if test "$enable_ddraw_Revert_Surface_Init" -eq 1; then + patch_apply ddraw-Revert_Surface_Init/0001-Revert-ddraw-Use-wined3d_texture_get_sub_resource-in.patch + patch_apply ddraw-Revert_Surface_Init/0002-Revert-ddraw-Move-the-mip-level-dimensions-fix-up-fr.patch + ( + echo '+ { "Sebastian Lackner", "Revert \"ddraw: Use wined3d_texture_get_sub_resource() in ddraw_surface7_Flip().\".", 1 },'; + echo '+ { "Sebastian Lackner", "Revert \"ddraw: Move the mip-level dimensions fix-up from ddraw_surface_init() to ddraw_surface_create().\".", 1 },'; + ) >> "$patchlist" +fi + # Patchset ddraw-Write_Vtable # | # | This patchset fixes the following Wine bugs: @@ -3034,6 +3524,21 @@ ) >> "$patchlist" fi +# Patchset dxdiagn-Display_Information +# | +# | This patchset fixes the following Wine bugs: +# | * [#34686] Return additional properties for display devices in dxdiagn +# | +# | Modified files: +# | * dlls/dxdiagn/provider.c, dlls/dxdiagn/tests/container.c +# | +if test "$enable_dxdiagn_Display_Information" -eq 1; then + patch_apply dxdiagn-Display_Information/0001-dxdiagn-Add-several-more-fields-for-DisplayDevices.patch + ( + echo '+ { "Michael Müller", "dxdiagn: Add several more fields for DisplayDevices.", 1 },'; + ) >> "$patchlist" +fi + # Patchset dxdiagn-Enumerate_DirectSound # | # | This patchset fixes the following Wine bugs: @@ -3138,6 +3643,18 @@ ) >> "$patchlist" fi +# Patchset explorer-Video_Registry_Key +# | +# | Modified files: +# | * dlls/advapi32/tests/registry.c, programs/explorer/desktop.c +# | +if test "$enable_explorer_Video_Registry_Key" -eq 1; then + patch_apply explorer-Video_Registry_Key/0001-explorer-Create-CurrentControlSet-Control-Video-regi.patch + ( + echo '+ { "Michael Müller", "explorer: Create CurrentControlSet\\\\Control\\\\Video registry key as non-volatile.", 1 },'; + ) >> "$patchlist" +fi + # Patchset fonts-Missing_Fonts # | # | This patchset fixes the following Wine bugs: @@ -3332,6 +3849,18 @@ ) >> "$patchlist" fi +# Patchset imm32-IMMDisableLegacyIME +# | +# | Modified files: +# | * dlls/imm32/imm.c, dlls/imm32/imm32.spec +# | +if test "$enable_imm32_IMMDisableLegacyIME" -eq 1; then + patch_apply imm32-IMMDisableLegacyIME/0001-imm32-Add-stub-for-ImmDisableLegacyIME.patch + ( + echo '+ { "Michael Müller", "imm32: Add stub for ImmDisableLegacyIME.", 1 },'; + ) >> "$patchlist" +fi + # Patchset inetcpl-Default_Home # | # | Modified files: @@ -3386,18 +3915,6 @@ ) >> "$patchlist" fi -# Patchset kernel32-Codepage_Conversion -# | -# | Modified files: -# | * dlls/kernel32/locale.c, dlls/kernel32/tests/codepage.c -# | -if test "$enable_kernel32_Codepage_Conversion" -eq 1; then - patch_apply kernel32-Codepage_Conversion/0001-kernel32-Set-error-if-dstlen-0-in-codepage-conversio.patch - ( - echo '+ { "Alex Henrie", "kernel32: Set error if dstlen < 0 in codepage conversion functions.", 1 },'; - ) >> "$patchlist" -fi - # Patchset kernel32-CompareString_Length # | # | This patchset fixes the following Wine bugs: @@ -3409,9 +3926,11 @@ if test "$enable_kernel32_CompareString_Length" -eq 1; then patch_apply kernel32-CompareString_Length/0001-kernel32-CompareStringW-should-abort-on-the-first-no.patch patch_apply kernel32-CompareString_Length/0002-kernel32-tests-Add-some-more-tests-for-NORM_IGNORESY.patch + patch_apply kernel32-CompareString_Length/0003-kenrel32-tests-Add-further-tests-for-comparing-strin.patch ( - echo '+ { "Dmitry Timoshkov", "kernel32: CompareStringW should abort on the first nonmatching character to avoid invalid memory access.", 1 },'; + echo '+ { "Dmitry Timoshkov", "kernel32: CompareStringW should abort on the first nonmatching character to avoid invalid memory access.", 2 },'; echo '+ { "Sebastian Lackner", "kernel32/tests: Add some more tests for NORM_IGNORESYMBOLS.", 1 },'; + echo '+ { "Sebastian Lackner", "kenrel32/tests: Add further tests for comparing strings ending with multiple \\\\0 characters.", 1 },'; ) >> "$patchlist" fi @@ -3499,79 +4018,27 @@ ) >> "$patchlist" fi -# Patchset kernel32-FreeUserPhysicalPages +# Patchset kernel32-FindFirstFile # | # | This patchset fixes the following Wine bugs: -# | * [#39543] Add stub kernel32.FreeUserPhysicalPages +# | * [#22635] Strip invalid characters from mask in FindFirstFileExW # | # | Modified files: -# | * dlls/kernel32/heap.c, dlls/kernel32/kernel32.spec +# | * dlls/kernel32/file.c, dlls/kernel32/tests/file.c # | -if test "$enable_kernel32_FreeUserPhysicalPages" -eq 1; then - patch_apply kernel32-FreeUserPhysicalPages/0001-kernel32-add-FreeUserPhysicalPages-stub-try-2.patch +if test "$enable_kernel32_FindFirstFile" -eq 1; then + patch_apply kernel32-FindFirstFile/0001-kernel32-Strip-invalid-characters-from-mask-in-FindF.patch + patch_apply kernel32-FindFirstFile/0002-kernel32-tests-Add-tests-for-FindFirstFileA-with-inv.patch ( - echo '+ { "Austin English", "kernel32: Add FreeUserPhysicalPages stub.", 2 },'; + echo '+ { "Michael Müller", "kernel32: Strip invalid characters from mask in FindFirstFileExW.", 1 },'; + echo '+ { "Michael Müller", "kernel32/tests: Add tests for FindFirstFileA with invalid characters.", 1 },'; ) >> "$patchlist" fi -# Patchset kernel32-GetFinalPathNameByHandle +# Patchset kernel32-LocaleNameToLCID # | # | This patchset fixes the following Wine bugs: -# | * [#34851] Support for GetFinalPathNameByHandle -# | -# | Modified files: -# | * dlls/api-ms-win-core-file-l1-1-0/api-ms-win-core-file-l1-1-0.spec, dlls/api-ms-win-core-file-l1-2-0/api-ms-win-core- -# | file-l1-2-0.spec, dlls/kernel32/file.c, dlls/kernel32/kernel32.spec -# | -if test "$enable_kernel32_GetFinalPathNameByHandle" -eq 1; then - patch_apply kernel32-GetFinalPathNameByHandle/0001-kernel32-Implement-GetFinalPathNameByHandle.patch - ( - echo '+ { "Michael Müller", "kernel32: Implement GetFinalPathNameByHandle.", 1 },'; - ) >> "$patchlist" -fi - -# Patchset kernel32-GetLargestConsoleWindowSize -# | -# | This patchset fixes the following Wine bugs: -# | * [#10919] Properly implement GetLargestConsoleWindowSize -# | -# | Modified files: -# | * dlls/kernel32/console.c, dlls/kernel32/kernel32.spec, dlls/kernel32/tests/console.c, programs/wineconsole/wineconsole.c, -# | server/console.c -# | -if test "$enable_kernel32_GetLargestConsoleWindowSize" -eq 1; then - patch_apply kernel32-GetLargestConsoleWindowSize/0001-wineconsole-Send-the-largest-console-window-size-inf.patch - patch_apply kernel32-GetLargestConsoleWindowSize/0002-kernel32-Implement-GetLargestConsoleWindowSize.patch - patch_apply kernel32-GetLargestConsoleWindowSize/0003-kernel32-Add-a-stub-for-SetConsoleFont.patch - patch_apply kernel32-GetLargestConsoleWindowSize/0004-kernel32-tests-Refresh-the-console-to-clear-the-cons.patch - patch_apply kernel32-GetLargestConsoleWindowSize/0005-kernel32-tests-Add-tests-for-GetLargestConsoleWindow.patch - patch_apply kernel32-GetLargestConsoleWindowSize/0006-kernel32-Clamp-maximum-window-size-to-screen-buffer-.patch - ( - echo '+ { "Hugh McMaster", "wineconsole: Send the largest console window size information to the server.", 1 },'; - echo '+ { "Hugh McMaster", "kernel32: Implement GetLargestConsoleWindowSize.", 1 },'; - echo '+ { "Hugh McMaster", "kernel32: Add a stub for SetConsoleFont.", 1 },'; - echo '+ { "Hugh McMaster", "kernel32/tests: Refresh the console to clear the console font table.", 1 },'; - echo '+ { "Hugh McMaster", "kernel32/tests: Add tests for GetLargestConsoleWindowSize.", 1 },'; - echo '+ { "Sebastian Lackner", "kernel32: Clamp maximum window size to screen buffer size.", 1 },'; - ) >> "$patchlist" -fi - -# Patchset kernel32-GetLogicalProcessorInformationEx -# | -# | Modified files: -# | * dlls/kernel32/process.c -# | -if test "$enable_kernel32_GetLogicalProcessorInformationEx" -eq 1; then - patch_apply kernel32-GetLogicalProcessorInformationEx/0001-kernel32-Make-GetLogicalProcessorInformationEx-a-stu.patch - ( - echo '+ { "Sebastian Lackner", "kernel32: Make GetLogicalProcessorInformationEx a stub which returns TRUE.", 1 },'; - ) >> "$patchlist" -fi - -# Patchset kernel32-LocaleNameToLCID -# | -# | This patchset fixes the following Wine bugs: -# | * [#30076] Silence repeated LocaleNameToLCID/LCIDToLocaleName unsupported flags FIXMEs +# | * [#30076] Silence repeated LocaleNameToLCID/LCIDToLocaleName unsupported flags FIXMEs # | # | Modified files: # | * dlls/kernel32/locale.c @@ -3709,6 +4176,18 @@ ) >> "$patchlist" fi +# Patchset kernel32-QT_Environment_Variables +# | +# | Modified files: +# | * dlls/kernel32/process.c +# | +if test "$enable_kernel32_QT_Environment_Variables" -eq 1; then + patch_apply kernel32-QT_Environment_Variables/0001-kernel32-Do-not-inherit-QT_-environment-variables-to.patch + ( + echo '+ { "Sebastian Lackner", "kernel32: Do not inherit QT_* environment variables to Windows environment.", 1 },'; + ) >> "$patchlist" +fi + # Patchset kernel32-SetFileCompletionNotificationModes # | # | This patchset fixes the following Wine bugs: @@ -3753,6 +4232,18 @@ ) >> "$patchlist" fi +# Patchset kernel32-VirtualProtect +# | +# | Modified files: +# | * dlls/kernel32/virtual.c +# | +if test "$enable_kernel32_VirtualProtect" -eq 1; then + patch_apply kernel32-VirtualProtect/0001-kernel32-Allow-to-pass-NULL-as-old-protection-in-Vir.patch + ( + echo '+ { "Michael Müller", "kernel32: Allow to pass NULL as old protection in VirtualProtect for Win9X.", 1 },'; + ) >> "$patchlist" +fi + # Patchset libs-Debug_Channel # | # | Modified files: @@ -3835,6 +4326,18 @@ ) >> "$patchlist" fi +# Patchset mmsystem.dll16-Fix_Argument_Order +# | +# | Modified files: +# | * dlls/mmsystem.dll16/mmsystem.c +# | +if test "$enable_mmsystem_dll16_Fix_Argument_Order" -eq 1; then + patch_apply mmsystem.dll16-Fix_Argument_Order/0001-mmsystem.dll16-Fix-argument-order-in-GlobalAlloc16-c.patch + ( + echo '+ { "Sebastian Lackner", "mmsystem.dll16: Fix argument order in GlobalAlloc16 call.", 1 },'; + ) >> "$patchlist" +fi + # Patchset mountmgr-DosDevices # | # | This patchset fixes the following Wine bugs: @@ -3932,6 +4435,33 @@ ) >> "$patchlist" fi +# Patchset msvcr120-_SetWinRTOutOfMemoryExceptionCallback +# | +# | Modified files: +# | * dlls/msvcr120/msvcr120.spec, dlls/msvcr120_app/msvcr120_app.spec, dlls/msvcrt/misc.c +# | +if test "$enable_msvcr120__SetWinRTOutOfMemoryExceptionCallback" -eq 1; then + patch_apply msvcr120-_SetWinRTOutOfMemoryExceptionCallback/0001-msvcr120-Add-stub-for-_SetWinRTOutOfMemoryExceptionC.patch + ( + echo '+ { "Michael Müller", "msvcr120: Add stub for _SetWinRTOutOfMemoryExceptionCallback.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset msvcr120-strof +# | +# | This patchset fixes the following Wine bugs: +# | * [#39908] Implement msvcr120.strtof and _strtof_l +# | +# | Modified files: +# | * dlls/msvcr120/msvcr120.spec, dlls/msvcr120/tests/msvcr120.c, dlls/msvcr120_app/msvcr120_app.spec, dlls/msvcrt/string.c +# | +if test "$enable_msvcr120_strof" -eq 1; then + patch_apply msvcr120-strof/0001-msvcr120-Implement-strtof-and-_strtof_l-try-3.patch + ( + echo '+ { "Bernhard Übelacker", "msvcr120: Implement strtof and _strtof_l.", 3 },'; + ) >> "$patchlist" +fi + # Patchset msvcrt-Math_Precision # | # | This patchset fixes the following Wine bugs: @@ -3963,6 +4493,18 @@ ) >> "$patchlist" fi +# Patchset msvideo-MCIWNDM_SETTIMEFORMATA +# | +# | Modified files: +# | * dlls/msvideo.dll16/msvideo16.c +# | +if test "$enable_msvideo_MCIWNDM_SETTIMEFORMATA" -eq 1; then + patch_apply msvideo-MCIWNDM_SETTIMEFORMATA/0001-msvideo.dll-Translate-16-bit-address-in-MCIWNDM_SETT.patch + ( + echo '+ { "Michael Müller", "msvideo.dll16: Translate 16 bit address in MCIWNDM_SETTIMEFORMATA command.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-APC_Performance # | # | Modified files: @@ -3999,6 +4541,40 @@ ) >> "$patchlist" fi +# Patchset ntdll-EtwRegisterTraceGuids +# | +# | This patchset fixes the following Wine bugs: +# | * [#34318] Move implementation of EtwRegisterTraceGuidsW to ntdll +# | +# | Modified files: +# | * dlls/advapi32/advapi32.spec, dlls/advapi32/eventlog.c, dlls/ntdll/misc.c, dlls/ntdll/ntdll.spec +# | +if test "$enable_ntdll_EtwRegisterTraceGuids" -eq 1; then + patch_apply ntdll-EtwRegisterTraceGuids/0001-ntdll-Move-RegisterTraceGuids-from-advapi32-to-ntdll.patch + patch_apply ntdll-EtwRegisterTraceGuids/0002-ntdll-Move-EventRegister-from-advapi32-to-ntdll.patch + patch_apply ntdll-EtwRegisterTraceGuids/0003-ntdll-Move-EventSetInformation-from-advapi32-to-ntdl.patch + ( + echo '+ { "Michael Müller", "ntdll: Move RegisterTraceGuids from advapi32 to ntdll.", 1 },'; + echo '+ { "Michael Müller", "ntdll: Move EventRegister from advapi32 to ntdll.", 1 },'; + echo '+ { "Michael Müller", "ntdll: Move EventSetInformation from advapi32 to ntdll.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset ntdll-ApiSetQueryApiSetPresence +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * ntdll-EtwRegisterTraceGuids +# | +# | Modified files: +# | * dlls/ntdll/misc.c, dlls/ntdll/ntdll.spec +# | +if test "$enable_ntdll_ApiSetQueryApiSetPresence" -eq 1; then + patch_apply ntdll-ApiSetQueryApiSetPresence/0001-ntdll-Add-stub-for-ApiSetQueryApiSetPresence.patch + ( + echo '+ { "Michael Müller", "ntdll: Add stub for ApiSetQueryApiSetPresence.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-CLI_Images # | # | This patchset has the following (direct or indirect) dependencies: @@ -4066,6 +4642,7 @@ patch_apply ntdll-DOS_Attributes/0005-libport-Add-support-for-Mac-OS-X-style-extended-attr.patch patch_apply ntdll-DOS_Attributes/0006-libport-Add-support-for-FreeBSD-style-extended-attri.patch patch_apply ntdll-DOS_Attributes/0007-ntdll-Perform-the-Unix-style-hidden-file-check-withi.patch + patch_apply ntdll-DOS_Attributes/0008-ntdll-Always-store-SAMBA_XATTR_DOS_ATTRIB-when-path-.patch ( echo '+ { "Erich E. Hoover", "ntdll: Implement retrieving DOS attributes in NtQueryInformationFile.", 1 },'; echo '+ { "Erich E. Hoover", "ntdll: Implement retrieving DOS attributes in NtQuery[Full]AttributesFile and NtQueryDirectoryFile.", 1 },'; @@ -4074,6 +4651,7 @@ echo '+ { "Erich E. Hoover", "libport: Add support for Mac OS X style extended attributes.", 1 },'; echo '+ { "Erich E. Hoover", "libport: Add support for FreeBSD style extended attributes.", 1 },'; echo '+ { "Erich E. Hoover", "ntdll: Perform the Unix-style hidden file check within the unified file info grabbing routine.", 1 },'; + echo '+ { "Sebastian Lackner", "ntdll: Always store SAMBA_XATTR_DOS_ATTRIB when path could be interpreted as hidden.", 1 },'; ) >> "$patchlist" fi @@ -4155,30 +4733,8 @@ ) >> "$patchlist" fi -# Patchset ntdll-x86_64_set_cpu_context -# | -# | This patchset fixes the following Wine bugs: -# | * [#39454] Allow to set debug registers separately in NtSetContextThread -# | -# | Modified files: -# | * dlls/ntdll/signal_x86_64.c, dlls/ntdll/tests/exception.c, dlls/ntdll/thread.c -# | -if test "$enable_ntdll_x86_64_set_cpu_context" -eq 1; then - patch_apply ntdll-x86_64_set_cpu_context/0001-ntdll-Allow-to-set-debug-registers-separately-in-NtS.patch - patch_apply ntdll-x86_64_set_cpu_context/0002-ntdll-Receive-debug-registers-from-server-on-x86_64.patch - patch_apply ntdll-x86_64_set_cpu_context/0003-ntdll-tests-Add-tests-for-setting-debug-registers-wi.patch - ( - echo '+ { "Sebastian Lackner", "ntdll: Allow to set debug registers separately in NtSetContextThread.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll: Receive debug registers from server on x86_64.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll/tests: Add tests for setting debug registers with NtSetContextThread.", 1 },'; - ) >> "$patchlist" -fi - # Patchset ntdll-Exception # | -# | This patchset has the following (direct or indirect) dependencies: -# | * ntdll-x86_64_set_cpu_context -# | # | Modified files: # | * dlls/kernel32/debugger.c, dlls/ntdll/om.c, dlls/ntdll/tests/exception.c # | @@ -4423,16 +4979,49 @@ ) >> "$patchlist" fi -# Patchset ntdll-RtlIpStringToAddress +# Patchset ntdll-RtlIpStringToAddress_Stubs +# | +# | Modified files: +# | * dlls/ntdll/ntdll.spec, dlls/ntdll/rtl.c, dlls/ntoskrnl.exe/ntoskrnl.exe.spec +# | +if test "$enable_ntdll_RtlIpStringToAddress_Stubs" -eq 1; then + patch_apply ntdll-RtlIpStringToAddress_Stubs/0001-ntdll-Fix-parameters-for-RtlIpv4StringToAddressExW-s.patch + patch_apply ntdll-RtlIpStringToAddress_Stubs/0002-ntdll-Add-stub-for-RtlIpv6StringToAddressExW.patch + ( + echo '+ { "Michael Müller", "ntdll: Fix parameters for RtlIpv4StringToAddressExW stub.", 1 },'; + echo '+ { "Michael Müller", "ntdll: Add stub for RtlIpv6StringToAddressExW.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset ntdll-RtlQueryPackageIdentity +# | +# | Modified files: +# | * dlls/ntdll/ntdll.spec, dlls/ntdll/rtl.c, dlls/ntdll/tests/Makefile.in, dlls/ntdll/tests/rtl.c, include/shobjidl.idl +# | +if test "$enable_ntdll_RtlQueryPackageIdentity" -eq 1; then + patch_apply ntdll-RtlQueryPackageIdentity/0001-ntdll-Add-stub-for-RtlQueryPackageIdentity.patch + patch_apply ntdll-RtlQueryPackageIdentity/0002-include-Add-IApplicationActivationManager-interface-.patch + patch_apply ntdll-RtlQueryPackageIdentity/0003-ntdll-tests-Add-basic-tests-for-RtlQueryPackageIdent.patch + ( + echo '+ { "Michael Müller", "ntdll: Add stub for RtlQueryPackageIdentity.", 1 },'; + echo '+ { "Michael Müller", "include: Add IApplicationActivationManager interface declaration.", 1 },'; + echo '+ { "Michael Müller", "ntdll/tests: Add basic tests for RtlQueryPackageIdentity.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset ntdll-RtlIpStringToAddress_Tests +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * ntdll-RtlQueryPackageIdentity # | # | Modified files: # | * dlls/ntdll/tests/rtl.c # | -if test "$enable_ntdll_RtlIpStringToAddress" -eq 1; then - patch_apply ntdll-RtlIpStringToAddress/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch - patch_apply ntdll-RtlIpStringToAddress/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch - patch_apply ntdll-RtlIpStringToAddress/0003-ntdll-tests-Tests-for-RtlIpv4StringToAddressEx-try-5.patch - patch_apply ntdll-RtlIpStringToAddress/0004-ntdll-tests-Add-tests-for-RtlIpv6AddressToString-and.patch +if test "$enable_ntdll_RtlIpStringToAddress_Tests" -eq 1; then + patch_apply ntdll-RtlIpStringToAddress_Tests/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch + patch_apply ntdll-RtlIpStringToAddress_Tests/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch + patch_apply ntdll-RtlIpStringToAddress_Tests/0003-ntdll-tests-Tests-for-RtlIpv4StringToAddressEx-try-5.patch + patch_apply ntdll-RtlIpStringToAddress_Tests/0004-ntdll-tests-Add-tests-for-RtlIpv6AddressToString-and.patch ( echo '+ { "Mark Jansen", "ntdll/tests: Tests for RtlIpv6StringToAddress.", 6 },'; echo '+ { "Mark Jansen", "ntdll/tests: Tests for RtlIpv6StringToAddressEx.", 6 },'; @@ -4441,6 +5030,21 @@ ) >> "$patchlist" fi +# Patchset ntdll-Serial_Port_Detection +# | +# | This patchset fixes the following Wine bugs: +# | * [#39793] Do a device check before returning a default serial port name +# | +# | Modified files: +# | * dlls/ntdll/directory.c +# | +if test "$enable_ntdll_Serial_Port_Detection" -eq 1; then + patch_apply ntdll-Serial_Port_Detection/0001-ntdll-Do-a-device-check-before-returning-a-default-s.patch + ( + echo '+ { "Alex Henrie", "ntdll: Do a device check before returning a default serial port name.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-Status_Mapping # | # | Modified files: @@ -4453,22 +5057,39 @@ ) >> "$patchlist" fi -# Patchset ntdll-SystemHandleInformation +# Patchset ntdll-SystemInterruptInformation +# | +# | This patchset fixes the following Wine bugs: +# | * [#39123] Return buffer filled with random values from SystemInterruptInformation +# | +# | Modified files: +# | * dlls/ntdll/nt.c +# | +if test "$enable_ntdll_SystemInterruptInformation" -eq 1; then + patch_apply ntdll-SystemInterruptInformation/0001-ntdll-Return-buffer-filled-with-random-values-from-S.patch + ( + echo '+ { "Sebastian Lackner", "ntdll: Return buffer filled with random values from SystemInterruptInformation.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset ntdll-SystemRecommendedSharedDataAlignment # | # | Modified files: -# | * dlls/ntdll/nt.c, dlls/ntdll/tests/info.c, server/handle.c, server/protocol.def, server/trace.c +# | * dlls/ntdll/nt.c, dlls/ntdll/tests/info.c, include/winternl.h # | -if test "$enable_ntdll_SystemHandleInformation" -eq 1; then - patch_apply ntdll-SystemHandleInformation/0001-server-Implement-wineserver-call-for-SystemHandleInf.patch +if test "$enable_ntdll_SystemRecommendedSharedDataAlignment" -eq 1; then + patch_apply ntdll-SystemRecommendedSharedDataAlignment/0001-include-Add-more-constants-to-SYSTEM_INFORMATION_CLA.patch + patch_apply ntdll-SystemRecommendedSharedDataAlignment/0002-ntdll-Implement-SystemRecommendedSharedDataAlignment.patch ( - echo '+ { "Sebastian Lackner", "server: Implement wineserver call for SystemHandleInformation.", 2 },'; + echo '+ { "Michael Müller", "include: Add more constants to SYSTEM_INFORMATION_CLASS.", 1 },'; + echo '+ { "Michael Müller", "ntdll: Implement SystemRecommendedSharedDataAlignment class in NtQuerySystemInformation.", 1 },'; ) >> "$patchlist" fi # Patchset ntdll-SystemRoot_Symlink # | # | This patchset has the following (direct or indirect) dependencies: -# | * ntdll-x86_64_set_cpu_context, ntdll-Exception, ntdll-Syscall_Wrappers +# | * ntdll-Exception, ntdll-Syscall_Wrappers # | # | Modified files: # | * dlls/ntdll/om.c @@ -4507,6 +5128,21 @@ ) >> "$patchlist" fi +# Patchset ntdll-Unused_Import_Descr +# | +# | This patchset fixes the following Wine bugs: +# | * [#39792] Ignore import descriptors with empty thunk list +# | +# | Modified files: +# | * dlls/ntdll/loader.c +# | +if test "$enable_ntdll_Unused_Import_Descr" -eq 1; then + patch_apply ntdll-Unused_Import_Descr/0001-ntdll-Skip-unused-import-descriptors-when-loading-li.patch + ( + echo '+ { "Sebastian Lackner", "ntdll: Skip unused import descriptors when loading libraries.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-User_Shared_Data # | # | Modified files: @@ -4538,6 +5174,9 @@ # Patchset ntdll-WinSqm # | +# | This patchset has the following (direct or indirect) dependencies: +# | * ntdll-EtwRegisterTraceGuids +# | # | This patchset fixes the following Wine bugs: # | * [#31971] ntdll is missing WinSqm[Start|End]Session implementation # | @@ -4754,19 +5393,42 @@ ) >> "$patchlist" fi -# Patchset oleaut32-SysAllocStringByteLen +# Patchset ole32-HGLOBALStream # | # | Modified files: -# | * dlls/oleaut32/oleaut.c, dlls/oleaut32/tests/vartype.c +# | * dlls/ole32/hglobalstream.c, dlls/ole32/tests/hglobalstream.c # | -if test "$enable_oleaut32_SysAllocStringByteLen" -eq 1; then - patch_apply oleaut32-SysAllocStringByteLen/0001-oleaut32-Pass-size-without-terminating-null-to-get_c.patch - patch_apply oleaut32-SysAllocStringByteLen/0002-oleaut32-Align-terminating-null-character-in-SysAllo.patch - patch_apply oleaut32-SysAllocStringByteLen/0003-oleaut32-tests-Test-SysStringLen-on-string-allocated.patch +if test "$enable_ole32_HGLOBALStream" -eq 1; then + patch_apply ole32-HGLOBALStream/0001-ole32-tests-Add-a-bunch-of-tests-for-HGLOBAL-based-I.patch + patch_apply ole32-HGLOBALStream/0002-ole32-Add-a-check-for-hglobal-pointer-to-GetHGlobalF.patch + patch_apply ole32-HGLOBALStream/0003-ole32-Add-a-wrapper-for-memory-block-managed-by-HGLO.patch + patch_apply ole32-HGLOBALStream/0004-ole32-Set-DebugInfo-Spare-0-for-handle_wrapper-lock.patch + patch_apply ole32-HGLOBALStream/0005-ole32-Allow-moving-a-being-reallocated-block-of-memo.patch + patch_apply ole32-HGLOBALStream/0006-ole32-Improve-thread-safety-of-HGLOBALStreamImpl_Rea.patch + patch_apply ole32-HGLOBALStream/0007-ole32-Improve-thread-safety-of-HGLOBALStreamImpl_Wri.patch ( - echo '+ { "Sebastian Lackner", "oleaut32: Pass size without terminating null to get_cache_entry.", 1 },'; - echo '+ { "Sebastian Lackner", "oleaut32: Align terminating null character in SysAllocStringByteLen.", 1 },'; - echo '+ { "Sebastian Lackner", "oleaut32/tests: Test SysStringLen() on string allocated with SysAllocStringByteLen.", 1 },'; + echo '+ { "Dmitry Timoshkov", "ole32/tests: Add a bunch of tests for HGLOBAL based IStream::Clone.", 1 },'; + echo '+ { "Dmitry Timoshkov", "ole32: Add a check for hglobal pointer to GetHGlobalFromStream.", 1 },'; + echo '+ { "Dmitry Timoshkov", "ole32: Add a wrapper for memory block managed by HGLOBAL based IStream.", 1 },'; + echo '+ { "Sebastian Lackner", "ole32: Set DebugInfo->Spare[0] for handle_wrapper lock.", 1 },'; + echo '+ { "Dmitry Timoshkov", "ole32: Allow moving a being reallocated block of memory managed by HGLOBAL based IStream.", 1 },'; + echo '+ { "Sebastian Lackner", "ole32: Improve thread-safety of HGLOBALStreamImpl_Read.", 1 },'; + echo '+ { "Sebastian Lackner", "ole32: Improve thread-safety of HGLOBALStreamImpl_Write.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset oleaut32-CreateTypeLib +# | +# | This patchset fixes the following Wine bugs: +# | * [#8780] Forward CreateTypeLib to CreateTypeLib2 +# | +# | Modified files: +# | * dlls/oleaut32/typelib.c +# | +if test "$enable_oleaut32_CreateTypeLib" -eq 1; then + patch_apply oleaut32-CreateTypeLib/0001-oleaut32-Implement-semi-stub-for-CreateTypeLib.patch + ( + echo '+ { "Alistair Leslie-Hughes", "oleaut32: Implement semi-stub for CreateTypeLib.", 1 },'; ) >> "$patchlist" fi @@ -4837,6 +5499,20 @@ ) >> "$patchlist" fi +# Patchset quartz-AsyncReader +# | +# | Modified files: +# | * dlls/quartz/filesource.c, dlls/quartz/regsvr.c +# | +if test "$enable_quartz_AsyncReader" -eq 1; then + patch_apply quartz-AsyncReader/0001-quartz-AsyncReader-should-return-NULL-as-media-subty.patch + patch_apply quartz-AsyncReader/0002-quartz-Recognize-mpeg2-program-streams.patch + ( + echo '+ { "Michael Müller", "quartz: AsyncReader should return NULL as media subtype for unknown formats instead of failing.", 1 },'; + echo '+ { "Michael Müller", "quartz: Recognize mpeg2 program streams.", 1 },'; + ) >> "$patchlist" +fi + # Patchset quartz-MediaSeeking_Positions # | # | Modified files: @@ -4902,6 +5578,18 @@ ) >> "$patchlist" fi +# Patchset rpcrt4-RpcBindingServerFromClient +# | +# | Modified files: +# | * dlls/rpcrt4/rpc_binding.c +# | +if test "$enable_rpcrt4_RpcBindingServerFromClient" -eq 1; then + patch_apply rpcrt4-RpcBindingServerFromClient/0001-rpcrt4-Fix-prototype-of-RpcBindingServerFromClient.patch + ( + echo '+ { "Sebastian Lackner", "rpcrt4: Fix prototype of RpcBindingServerFromClient.", 1 },'; + ) >> "$patchlist" +fi + # Patchset secur32-ANSI_NTLM_Credentials # | # | This patchset fixes the following Wine bugs: @@ -4946,6 +5634,18 @@ ) >> "$patchlist" fi +# Patchset server-Fix_Leak +# | +# | Modified files: +# | * server/object.c +# | +if test "$enable_server_Fix_Leak" -eq 1; then + patch_apply server-Fix_Leak/0001-server-Fix-newly-introduced-memory-leak-of-object-na.patch + ( + echo '+ { "Sebastian Lackner", "server: Fix newly introduced memory leak of object name structure.", 1 },'; + ) >> "$patchlist" +fi + # Patchset server-Stored_ACLs # | # | This patchset has the following (direct or indirect) dependencies: @@ -5060,16 +5760,12 @@ # | * rpcrt4-Pipe_Transport, server-Desktop_Refcount, kernel32-Named_Pipe # | # | Modified files: -# | * server/named_pipe.c, server/object.c, server/object.h +# | * dlls/ntdll/tests/om.c, server/named_pipe.c, server/object.c # | if test "$enable_server_Pipe_ObjectName" -eq 1; then - patch_apply server-Pipe_ObjectName/0001-server-Move-parent-reference-from-object_name-to-obj.patch - patch_apply server-Pipe_ObjectName/0002-server-Link-named-pipes-to-their-device.patch - patch_apply server-Pipe_ObjectName/0003-server-Store-a-reference-to-the-parent-object-for-pi.patch - ( - echo '+ { "Sebastian Lackner", "server: Move parent reference from object_name to object.", 1 },'; - echo '+ { "Sebastian Lackner", "server: Link named pipes to their device.", 1 },'; - echo '+ { "Sebastian Lackner", "server: Store a reference to the parent object for pipe servers.", 1 },'; + patch_apply server-Pipe_ObjectName/0001-server-Store-a-reference-to-the-parent-object-for-pi.patch + ( + echo '+ { "Sebastian Lackner", "server: Store a reference to the parent object for pipe servers.", 2 },'; ) >> "$patchlist" fi @@ -5157,6 +5853,18 @@ ) >> "$patchlist" fi +# Patchset server-Win8_Pseudo_Handles +# | +# | Modified files: +# | * dlls/advapi32/tests/security.c, include/winbase.h, server/handle.c +# | +if test "$enable_server_Win8_Pseudo_Handles" -eq 1; then + patch_apply server-Win8_Pseudo_Handles/0001-server-Implement-support-for-pseudo-tokens-CurrentPr.patch + ( + echo '+ { "Michael Müller", "server: Implement support for pseudo tokens CurrentProcessToken, CurrentThreadToken, CurrentThreadEffectiveToken.", 1 },'; + ) >> "$patchlist" +fi + # Patchset services-SERVICE_FILE_SYSTEM_DRIVER # | # | This patchset fixes the following Wine bugs: @@ -5447,7 +6155,7 @@ # | * [#35630] Support for SHCreateSessionKey # | # | Modified files: -# | * dlls/shell32/shell32.spec, dlls/shell32/shellreg.c +# | * dlls/shell32/shell32.spec, dlls/shell32/shellreg.c, dlls/shell32/tests/shellole.c # | if test "$enable_shell32_SHCreateSessionKey" -eq 1; then patch_apply shell32-SHCreateSessionKey/0001-shell32-Implement-SHCreateSessionKey.patch @@ -5541,6 +6249,130 @@ ) >> "$patchlist" fi +# Patchset stdole32.idl-Typelib +# | +# | Modified files: +# | * dlls/stdole32.tlb/std_ole_v1.idl, include/Makefile.in, include/stdole32.idl +# | +if test "$enable_stdole32_idl_Typelib" -eq 1; then + patch_apply stdole32.idl-Typelib/0001-include-Make-stdole32.idl-a-public-component.patch + ( + echo '+ { "Dmitry Timoshkov", "include: Make stdole32.idl a public component.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset widl-SLTG_Typelib_Support +# | +# | Modified files: +# | * dlls/oleaut32/typelib.c, dlls/oleaut32/typelib.h, tools/widl/Makefile.in, tools/widl/typelib.c, tools/widl/typelib.h, +# | tools/widl/widl.c, tools/widl/widl.h, tools/widl/write_sltg.c +# | +if test "$enable_widl_SLTG_Typelib_Support" -eq 1; then + patch_apply widl-SLTG_Typelib_Support/0001-widl-Add-initial-implementation-of-SLTG-typelib-gene.patch + patch_apply widl-SLTG_Typelib_Support/0002-widl-Add-support-for-structures.patch + patch_apply widl-SLTG_Typelib_Support/0003-widl-Properly-align-name-table-entries.patch + patch_apply widl-SLTG_Typelib_Support/0004-widl-More-accurately-report-variable-descriptions-da.patch + patch_apply widl-SLTG_Typelib_Support/0005-widl-Calculate-size-of-instance-for-structures.patch + patch_apply widl-SLTG_Typelib_Support/0006-widl-Write-correct-typekind-to-the-SLTG-typeinfo-blo.patch + patch_apply widl-SLTG_Typelib_Support/0007-widl-Write-SLTG-blocks-according-to-the-index-order.patch + patch_apply widl-SLTG_Typelib_Support/0008-widl-Write-correct-syskind-by-SLTG-typelib-generator.patch + patch_apply widl-SLTG_Typelib_Support/0009-widl-Add-support-for-VT_VOID-and-VT_VARIANT-to-SLTG-.patch + patch_apply widl-SLTG_Typelib_Support/0010-widl-Add-support-for-VT_USERDEFINED-to-SLTG-typelib-.patch + patch_apply widl-SLTG_Typelib_Support/0011-widl-Factor-out-SLTG-tail-initialization.patch + patch_apply widl-SLTG_Typelib_Support/0012-widl-Add-support-for-recursive-type-references-to-SL.patch + patch_apply widl-SLTG_Typelib_Support/0013-widl-Add-support-for-interfaces-to-SLTG-typelib-gene.patch + patch_apply widl-SLTG_Typelib_Support/0014-widl-Add-support-for-inherited-interfaces-to-SLTG-ty.patch + patch_apply widl-SLTG_Typelib_Support/0015-widl-Make-automatic-dispid-generation-scheme-better-.patch + patch_apply widl-SLTG_Typelib_Support/0016-widl-Create-library-block-index-right-after-the-Comp.patch + patch_apply widl-SLTG_Typelib_Support/0017-widl-Fix-generation-of-resources-containing-an-old-t.patch + patch_apply widl-SLTG_Typelib_Support/0018-widl-Add-oldtlb-switch-in-usage-message.patch + patch_apply widl-SLTG_Typelib_Support/0019-widl-Avoid-relying-on-side-effects-when-marking-func.patch + patch_apply widl-SLTG_Typelib_Support/0020-widl-Set-the-lowest-bit-in-the-param-name-to-indicat.patch + patch_apply widl-SLTG_Typelib_Support/0021-oleaut32-Fix-logic-for-deciding-whether-type-descrip.patch + patch_apply widl-SLTG_Typelib_Support/0022-widl-Add-support-for-function-parameter-flags-to-SLT.patch + patch_apply widl-SLTG_Typelib_Support/0023-oleaut32-Implement-decoding-of-SLTG-help-strings.patch + patch_apply widl-SLTG_Typelib_Support/0024-oleaut32-Add-support-for-decoding-SLTG-function-help.patch + patch_apply widl-SLTG_Typelib_Support/0025-oleaut32-Add-support-for-decoding-SLTG-variable-help.patch + patch_apply widl-SLTG_Typelib_Support/0026-widl-Minor-cosmetic-clean-up.patch + ( + echo '+ { "Dmitry Timoshkov", "widl: Add initial implementation of SLTG typelib generator.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Add support for structures.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Properly align name table entries.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: More accurately report variable descriptions data size.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Calculate size of instance for structures.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Write correct typekind to the SLTG typeinfo block.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Write SLTG blocks according to the index order.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Write correct syskind by SLTG typelib generator.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Add support for VT_VOID and VT_VARIANT to SLTG typelib generator.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Add support for VT_USERDEFINED to SLTG typelib generator.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Factor out SLTG tail initialization.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Add support for recursive type references to SLTG typelib generator.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Add support for interfaces to SLTG typelib generator.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Add support for inherited interfaces to SLTG typelib generator.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Make automatic dispid generation scheme better match what midl does.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Create library block index right after the CompObj one.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Fix generation of resources containing an old typelib.", 1 },'; + echo '+ { "Sebastian Lackner", "widl: Add --oldtlb switch in usage message.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Avoid relying on side effects when marking function index as the last one.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Set the lowest bit in the param name to indicate whether type description follows the name.", 1 },'; + echo '+ { "Dmitry Timoshkov", "oleaut32: Fix logic for deciding whether type description follows the name.", 2 },'; + echo '+ { "Dmitry Timoshkov", "widl: Add support for function parameter flags to SLTG typelib generator.", 1 },'; + echo '+ { "Dmitry Timoshkov", "oleaut32: Implement decoding of SLTG help strings.", 1 },'; + echo '+ { "Dmitry Timoshkov", "oleaut32: Add support for decoding SLTG function help strings.", 1 },'; + echo '+ { "Dmitry Timoshkov", "oleaut32: Add support for decoding SLTG variable help strings.", 1 },'; + echo '+ { "Dmitry Timoshkov", "widl: Minor/cosmetic clean up.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset stdole32.tlb-SLTG_Typelib +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * widl-SLTG_Typelib_Support +# | +# | This patchset fixes the following Wine bugs: +# | * [#3689] Compile stdole32.tlb in SLTG typelib format +# | +# | Modified files: +# | * dlls/stdole32.tlb/Makefile.in +# | +if test "$enable_stdole32_tlb_SLTG_Typelib" -eq 1; then + patch_apply stdole32.tlb-SLTG_Typelib/0020-stdole32.tlb-Compile-typelib-with-oldtlb.patch + ( + echo '+ { "Sebastian Lackner", "stdole32.tlb: Compile typelib with --oldtlb.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset taskmgr-Memory_Usage +# | +# | Modified files: +# | * configure.ac, dlls/ntdll/nt.c, dlls/ntdll/virtual.c, programs/taskmgr/font.bmp, programs/taskmgr/graph.c, +# | programs/taskmgr/resource.h, programs/taskmgr/taskmgr.c, programs/taskmgr/taskmgr.rc +# | +if test "$enable_taskmgr_Memory_Usage" -eq 1; then + patch_apply taskmgr-Memory_Usage/0001-ntdll-Use-sysinfo-to-report-correct-number-of-physic.patch + patch_apply taskmgr-Memory_Usage/0002-ntdll-Report-system-information-SystemPerformanceInf.patch + patch_apply taskmgr-Memory_Usage/0003-taskmgr-Use-system-font-instead-of-special-bitmap-fo.patch + patch_apply taskmgr-Memory_Usage/0004-taskmgr-Use-different-units-depending-on-memory-usag.patch + ( + echo '+ { "Michael Müller", "ntdll: Use sysinfo to report correct number of physical pages.", 1 },'; + echo '+ { "Michael Müller", "ntdll: Report system information SystemPerformanceInformation info class.", 1 },'; + echo '+ { "Michael Müller", "taskmgr: Use system font instead of special bitmap font.", 1 },'; + echo '+ { "Michael Müller", "taskmgr: Use different units depending on memory usage.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset ucrtbase-Functions +# | +# | Modified files: +# | * dlls/api-ms-win-crt-heap-l1-1-0/api-ms-win-crt-heap-l1-1-0.spec, dlls/ucrtbase/ucrtbase.spec +# | +if test "$enable_ucrtbase_Functions" -eq 1; then + patch_apply ucrtbase-Functions/0001-ucrtbase-Hook-up-some-functions-with-new-names-to-ex.patch + ( + echo '+ { "Martin Storsjo", "ucrtbase: Hook up some functions with new names to existing implementations.", 1 },'; + ) >> "$patchlist" +fi + # Patchset user32-DeferWindowPos # | # | This patchset fixes the following Wine bugs: @@ -5631,25 +6463,11 @@ ) >> "$patchlist" fi -# Patchset user32-MOUSEHOOKSTRUCTEX -# | -# | This patchset fixes the following Wine bugs: -# | * [#38314] Pass MOUSEHOOKSTRUCTEX struct to mouse hook callback -# | -# | Modified files: -# | * dlls/user32/message.c -# | -if test "$enable_user32_MOUSEHOOKSTRUCTEX" -eq 1; then - patch_apply user32-MOUSEHOOKSTRUCTEX/0001-user32-Add-MOUSEHOOKSTRUCTEX-to-fix-mouse-wheel-supp.patch - ( - echo '+ { "Kira Backes", "user32: Add MOUSEHOOKSTRUCTEX to fix mouse wheel support for JA2 1.13 and other apps which use it.", 1 },'; - ) >> "$patchlist" -fi - # Patchset user32-Mouse_Message_Hwnd # | # | This patchset fixes the following Wine bugs: # | * [#12007] Fix issues with dragging layers between images in Adobe Photoshop 7.0 +# | * [#9512] Make sure popups don't block access to objects underneath in DVDPro # | # | Modified files: # | * dlls/user32/message.c, dlls/user32/tests/input.c @@ -5691,18 +6509,6 @@ ) >> "$patchlist" fi -# Patchset user32-SetCaretPos -# | -# | Modified files: -# | * dlls/user32/caret.c, server/protocol.def, server/queue.c -# | -if test "$enable_user32_SetCaretPos" -eq 1; then - patch_apply user32-SetCaretPos/0001-user32-Set-correct-caret-state-in-the-server-in-SetC.patch - ( - echo '+ { "Anton Baskanov", "user32: Set correct caret state in the server in SetCaretPos.", 4 },'; - ) >> "$patchlist" -fi - # Patchset user32-SetCoalescableTimer # | # | This patchset fixes the following Wine bugs: @@ -5718,21 +6524,6 @@ ) >> "$patchlist" fi -# Patchset user32-WM_CAPTURECHANGE -# | -# | This patchset fixes the following Wine bugs: -# | * [#13683] Also send WM_CAPTURECHANGE when capture has not changed -# | -# | Modified files: -# | * dlls/comctl32/toolbar.c, dlls/comctl32/trackbar.c, dlls/user32/button.c, dlls/user32/input.c, dlls/user32/tests/msg.c -# | -if test "$enable_user32_WM_CAPTURECHANGE" -eq 1; then - patch_apply user32-WM_CAPTURECHANGE/0001-user32-Also-send-WM_CAPTURECHANGE-when-capture-has-n.patch - ( - echo '+ { "Christopher Thielen", "user32: Also send WM_CAPTURECHANGE when capture has not changed.", 1 },'; - ) >> "$patchlist" -fi - # Patchset user32-WM_MDICALCCHILDSCROLL # | # | Modified files: @@ -5760,6 +6551,21 @@ ) >> "$patchlist" fi +# Patchset uxtheme-CloseThemeData +# | +# | This patchset fixes the following Wine bugs: +# | * [#29862] Do not crash when INVALID_HANDLE_VALUE is passed to CloseThemeData +# | +# | Modified files: +# | * dlls/uxtheme/system.c, dlls/uxtheme/tests/system.c +# | +if test "$enable_uxtheme_CloseThemeData" -eq 1; then + patch_apply uxtheme-CloseThemeData/0001-uxtheme-Do-not-crash-when-INVALID_HANDLE_VALUE-is-pa.patch + ( + echo '+ { "Louis Lenders", "uxtheme: Do not crash when INVALID_HANDLE_VALUE is passed to CloseThemeData.", 1 },'; + ) >> "$patchlist" +fi + # Patchset uxtheme-GTK_Theming # | # | This patchset has the following (direct or indirect) dependencies: @@ -5779,6 +6585,9 @@ patch_apply uxtheme-GTK_Theming/0004-uxthemegtk-Correctly-render-buttons-with-GTK-3.14.0.patch patch_apply uxtheme-GTK_Theming/0005-uxthemegtk-Print-class-name-before-calling-vtable-fu.patch patch_apply uxtheme-GTK_Theming/0006-uxthemegtk-Reset-FPU-flags-before-calling-GTK3-funct.patch + patch_apply uxtheme-GTK_Theming/0007-uxthemegtk-Add-export-for-OpenThemeDataEx.patch + patch_apply uxtheme-GTK_Theming/0008-uxthemegtk-Fix-some-incorrect-error-codes.patch + patch_apply uxtheme-GTK_Theming/0009-uxthemegtk-Validate-theme-handles-before-accessing-p.patch ( echo '+ { "Michael Müller", "uxthemegtk: Add configure check and stub dll.", 1 },'; echo '+ { "Ivan Akulinchev", "uxthemegtk: Initial implementation.", 1 },'; @@ -5786,6 +6595,26 @@ echo '+ { "Sebastian Lackner", "uxthemegtk: Correctly render buttons with GTK >= 3.14.0.", 1 },'; echo '+ { "Michael Müller", "uxthemegtk: Print class name before calling vtable functions.", 1 },'; echo '+ { "Michael Müller", "uxthemegtk: Reset FPU flags before calling GTK3 functions.", 1 },'; + echo '+ { "Sebastian Lackner", "uxthemegtk: Add export for OpenThemeDataEx.", 1 },'; + echo '+ { "Sebastian Lackner", "uxthemegtk: Fix some incorrect error codes.", 1 },'; + echo '+ { "Sebastian Lackner", "uxthemegtk: Validate theme handles before accessing private data.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset vcomp-Atomic_I8 +# | +# | Modified files: +# | * dlls/vcomp/main.c, dlls/vcomp/tests/vcomp.c, dlls/vcomp/vcomp.spec, dlls/vcomp100/vcomp100.spec, +# | dlls/vcomp110/vcomp110.spec, dlls/vcomp120/vcomp120.spec, dlls/vcomp90/vcomp90.spec +# | +if test "$enable_vcomp_Atomic_I8" -eq 1; then + patch_apply vcomp-Atomic_I8/0001-vcomp-tests-Reenable-architecture-dependent-tests.patch + patch_apply vcomp-Atomic_I8/0002-vcomp-Implement-64-bit-atomic-instructions.patch + patch_apply vcomp-Atomic_I8/0003-vcomp-tests-Add-tests-for-64-bit-atomic-instructions.patch + ( + echo '+ { "Sebastian Lackner", "vcomp/tests: Reenable architecture dependent tests.", 1 },'; + echo '+ { "Sebastian Lackner", "vcomp: Implement 64-bit atomic instructions.", 1 },'; + echo '+ { "Sebastian Lackner", "vcomp/tests: Add tests for 64-bit atomic instructions.", 1 },'; ) >> "$patchlist" fi @@ -5801,6 +6630,21 @@ ) >> "$patchlist" fi +# Patchset vmm.vxd-PageReserve +# | +# | This patchset fixes the following Wine bugs: +# | * [#36013] Fix protection flags passed to VirtualAlloc call in PageReserve VxDCall +# | +# | Modified files: +# | * dlls/vmm.vxd/vmm.c +# | +if test "$enable_vmm_vxd_PageReserve" -eq 1; then + patch_apply vmm.vxd-PageReserve/0001-vmm.vxd-Fix-protection-flags-passed-to-VirtualAlloc.patch + ( + echo '+ { "Sebastian Lackner", "vmm.vxd: Fix protection flags passed to VirtualAlloc.", 1 },'; + ) >> "$patchlist" +fi + # Patchset wbemdisp-ISWbemSecurity # | # | Modified files: @@ -5927,18 +6771,15 @@ # Patchset wined3d-CSMT_Helper # | # | This patchset has the following (direct or indirect) dependencies: -# | * makedep-PARENTSPEC, ntdll-DllOverrides_WOW64, ntdll-Loader_Machine_Type, ntdll-DllRedirects, wined3d-DXTn +# | * makedep-PARENTSPEC, ntdll-DllOverrides_WOW64, ntdll-Loader_Machine_Type, ntdll-DllRedirects, wined3d-DXTn, wined3d- +# | resource_map # | # | Modified files: -# | * configure.ac, dlls/d3d11/device.c, dlls/d3d11/texture.c, dlls/d3d8/surface.c, dlls/d3d8/volume.c, dlls/d3d9/surface.c, -# | dlls/d3d9/volume.c, dlls/wined3d-csmt/Makefile.in, dlls/wined3d-csmt/version.rc, dlls/wined3d/resource.c, -# | dlls/wined3d/wined3d.spec, include/wine/wined3d.h +# | * configure.ac, dlls/wined3d-csmt/Makefile.in, dlls/wined3d-csmt/version.rc # | if test "$enable_wined3d_CSMT_Helper" -eq 1; then - patch_apply wined3d-CSMT_Helper/0001-wined3d-Rename-wined3d_resource_-un-map-to-wined3d_r.patch patch_apply wined3d-CSMT_Helper/0002-wined3d-Add-second-dll-with-STAGING_CSMT-definition-.patch ( - echo '+ { "Sebastian Lackner", "wined3d: Rename wined3d_resource_(un)map to wined3d_resource_sub_resource_(un)map.", 1 },'; echo '+ { "Sebastian Lackner", "wined3d: Add second dll with STAGING_CSMT definition set.", 1 },'; ) >> "$patchlist" fi @@ -5973,21 +6814,6 @@ ) >> "$patchlist" fi -# Patchset wined3d-Multisampling -# | -# | This patchset fixes the following Wine bugs: -# | * [#12652] Allow to override number of quality levels for D3DMULTISAMPLE_NONMASKABLE. -# | -# | Modified files: -# | * dlls/wined3d/directx.c, dlls/wined3d/wined3d_main.c, dlls/wined3d/wined3d_private.h -# | -if test "$enable_wined3d_Multisampling" -eq 1; then - patch_apply wined3d-Multisampling/0001-wined3d-Allow-to-specify-multisampling-AA-quality-le.patch - ( - echo '+ { "Austin English", "wined3d: Allow to specify multisampling AA quality levels via registry.", 1 },'; - ) >> "$patchlist" -fi - # Patchset wined3d-Revert_PixelFormat # | # | Modified files: @@ -6069,7 +6895,7 @@ # | # | This patchset has the following (direct or indirect) dependencies: # | * makedep-PARENTSPEC, ntdll-DllOverrides_WOW64, ntdll-Loader_Machine_Type, ntdll-DllRedirects, wined3d-DXTn, wined3d- -# | CSMT_Helper +# | resource_map, wined3d-CSMT_Helper # | # | This patchset fixes the following Wine bugs: # | * [#11674] Support for CSMT (command stream) to increase graphic performance @@ -6108,153 +6934,150 @@ patch_apply wined3d-CSMT_Main/0022-wined3d-Discard-implicit-surfaces-on-unload.patch patch_apply wined3d-CSMT_Main/0023-wined3d-Don-t-try-to-flip-sysmem-copies-in-swapchain.patch patch_apply wined3d-CSMT_Main/0024-wined3d-Discard-the-backbuffer-in-discard-presents.patch - patch_apply wined3d-CSMT_Main/0025-wined3d-Allocate-sysmem-for-client-storage-if-it-doe.patch - patch_apply wined3d-CSMT_Main/0026-wined3d-Introduce-a-function-to-retrieve-resource-me.patch - patch_apply wined3d-CSMT_Main/0027-wined3d-Make-surface_ops-unmap-specific-for-front-bu.patch - patch_apply wined3d-CSMT_Main/0028-wined3d-Move-check_block_align-to-resource.c.patch - patch_apply wined3d-CSMT_Main/0029-wined3d-Replace-surface-alloc-functions-with-resourc.patch - patch_apply wined3d-CSMT_Main/0030-wined3d-Don-t-delete-the-buffer-in-surface_cleanup.patch - patch_apply wined3d-CSMT_Main/0031-wined3d-Use-resource-facilities-to-destroy-PBOs.patch - patch_apply wined3d-CSMT_Main/0032-wined3d-Move-simple-location-copying-to-the-resource.patch - patch_apply wined3d-CSMT_Main/0033-wined3d-Move-most-of-volume_map-to-resource.c.patch - patch_apply wined3d-CSMT_Main/0034-wined3d-Use-resource_map-for-surface_map.patch - patch_apply wined3d-CSMT_Main/0035-wined3d-Use-client-storage-with-DIB-sections.patch - patch_apply wined3d-CSMT_Main/0036-wined3d-Don-t-call-the-public-map-function-in-surfac.patch - patch_apply wined3d-CSMT_Main/0037-wined3d-Don-t-call-the-public-map-function-in-surfac.patch - patch_apply wined3d-CSMT_Main/0038-wined3d-Move-the-framebuffer-into-wined3d_state.patch - patch_apply wined3d-CSMT_Main/0039-wined3d-Get-rid-of-state-access-in-shader_generate_g.patch - patch_apply wined3d-CSMT_Main/0040-wined3d-Preload-buffers-if-streamsrc-is-not-dirty.patch - patch_apply wined3d-CSMT_Main/0041-wined3d-Hackily-introduce-a-multithreaded-command-st.patch - patch_apply wined3d-CSMT_Main/0042-wined3d-Wait-for-resource-updates-to-finish-when-usi.patch - patch_apply wined3d-CSMT_Main/0043-wined3d-Don-t-store-pointers-in-struct-wined3d_cs_pr.patch - patch_apply wined3d-CSMT_Main/0044-wined3d-Don-t-put-rectangle-pointers-into-wined3d_cs.patch - patch_apply wined3d-CSMT_Main/0045-wined3d-Store-the-color-in-clear-ops-instead-of-a-po.patch - patch_apply wined3d-CSMT_Main/0046-wined3d-Pass-the-state-to-draw_primitive.patch - patch_apply wined3d-CSMT_Main/0047-wined3d-Wait-for-the-cs-before-destroying-objects.patch - patch_apply wined3d-CSMT_Main/0048-wined3d-Give-the-cs-its-own-state.patch - patch_apply wined3d-CSMT_Main/0049-wined3d-Send-float-constant-updates-through-the-comm.patch - patch_apply wined3d-CSMT_Main/0050-wined3d-Request-a-glFinish-before-modifying-resource.patch - patch_apply wined3d-CSMT_Main/0051-wined3d-Finish-the-cs-before-changing-the-texture-lo.patch - patch_apply wined3d-CSMT_Main/0052-wined3d-Don-t-call-glFinish-after-clears.patch - patch_apply wined3d-CSMT_Main/0053-wined3d-Don-t-call-glFinish-after-draws.patch - patch_apply wined3d-CSMT_Main/0054-wined3d-Shadow-device-offscreenBuffer-in-the-context.patch - patch_apply wined3d-CSMT_Main/0055-wined3d-Don-t-access-the-stateblock-in-find_draw_buf.patch - patch_apply wined3d-CSMT_Main/0056-wined3d-Pass-the-depth-stencil-to-swapchain-present.patch - patch_apply wined3d-CSMT_Main/0057-wined3d-Don-t-store-viewport-pointers-in-the-command.patch - patch_apply wined3d-CSMT_Main/0058-wined3d-Keep-track-of-the-onscreen-depth-stencil-in-.patch - patch_apply wined3d-CSMT_Main/0059-wined3d-Send-base-vertex-index-updates-through-the-c.patch - patch_apply wined3d-CSMT_Main/0060-wined3d-Send-primitive-type-updates-through-the-comm.patch - patch_apply wined3d-CSMT_Main/0061-wined3d-Send-bool-constant-updates-through-the-comma.patch - patch_apply wined3d-CSMT_Main/0062-wined3d-Send-int-constant-updates-through-the-comman.patch - patch_apply wined3d-CSMT_Main/0063-wined3d-Send-light-updates-through-the-command-strea.patch - patch_apply wined3d-CSMT_Main/0064-wined3d-Prevent-the-command-stream-from-running-ahea.patch - patch_apply wined3d-CSMT_Main/0065-wined3d-Wait-for-the-cs-to-finish-before-destroying-.patch - patch_apply wined3d-CSMT_Main/0066-wined3d-Run-the-cs-asynchronously.patch - patch_apply wined3d-CSMT_Main/0067-wined3d-Send-blits-through-the-command-stream.patch - patch_apply wined3d-CSMT_Main/0068-wined3d-Put-update_surface-checks-back-in-place.patch - patch_apply wined3d-CSMT_Main/0069-wined3d-Get-rid-of-WINED3D_BUFFER_FLUSH.patch - patch_apply wined3d-CSMT_Main/0070-wined3d-Don-t-force-strict-draw-ordering-for-multith.patch - patch_apply wined3d-CSMT_Main/0071-wined3d-Send-render-target-view-clears-through-the-c.patch - patch_apply wined3d-CSMT_Main/0072-wined3d-Wait-for-the-CS-in-GetDC.patch - patch_apply wined3d-CSMT_Main/0073-wined3d-send-resource-maps-through-the-command-strea.patch - patch_apply wined3d-CSMT_Main/0074-wined3d-Get-rid-of-the-end_scene-flush-and-finish.patch - patch_apply wined3d-CSMT_Main/0075-wined3d-Replace-the-linked-lists-with-a-ringbuffer.patch - patch_apply wined3d-CSMT_Main/0076-wined3d-Don-t-preload-buffers-on-unmap.patch - patch_apply wined3d-CSMT_Main/0077-wined3d-Don-t-call-glFinish-before-swapping.patch - patch_apply wined3d-CSMT_Main/0078-wined3d-wined3d_-_query_issue-never-fails.patch - patch_apply wined3d-CSMT_Main/0079-wined3d-Add-query-support-to-the-command-stream.patch - patch_apply wined3d-CSMT_Main/0080-wined3d-Check-our-CS-state-to-find-out-if-a-query-is.patch - patch_apply wined3d-CSMT_Main/0081-wined3d-Poll-queries-automatically-in-the-CS.patch - patch_apply wined3d-CSMT_Main/0082-wined3d-Introduce-a-separate-queue-for-priority-comm.patch - patch_apply wined3d-CSMT_Main/0083-wined3d-Destroy-queries-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0084-wined3d-Separate-main-and-worker-thread-query-state.patch - patch_apply wined3d-CSMT_Main/0085-wined3d-Don-t-poll-queries-that-failed-to-start.patch - patch_apply wined3d-CSMT_Main/0086-wined3d-Remove-restated-queries-from-the-poll-list.patch - patch_apply wined3d-CSMT_Main/0087-wined3d-Don-t-reset-the-query-state-if-it-doesn-t-ha.patch - patch_apply wined3d-CSMT_Main/0088-wined3d-Put-this-into-the-query-poll-patch.patch - patch_apply wined3d-CSMT_Main/0089-wined3d-Send-update_surface-commands-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0090-wined3d-Send-texture-preloads-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0091-wined3d-Send-surface-preloads-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0092-wined3d-Send-update_texture-calls-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0093-wined3d-Get-rid-of-the-surface_upload_data-glFinish.patch - patch_apply wined3d-CSMT_Main/0094-wined3d-Don-t-lock-the-src-volume-in-device_update_v.patch - patch_apply wined3d-CSMT_Main/0095-wined3d-Handle-evit_managed_resources-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0096-wined3d-Introduce-resource-fencing.patch - patch_apply wined3d-CSMT_Main/0097-wined3d-Fence-update_texture-and-update_surface-call.patch - patch_apply wined3d-CSMT_Main/0098-wined3d-Dirtify-resources-on-unmap.patch - patch_apply wined3d-CSMT_Main/0099-wined3d-Fence-texture-reads-in-draws.patch - patch_apply wined3d-CSMT_Main/0100-wined3d-Fence-render-targets-and-depth-stencils.patch - patch_apply wined3d-CSMT_Main/0101-wined3d-Fence-blit-operations.patch - patch_apply wined3d-CSMT_Main/0102-wined3d-Fence-color_fill-operations.patch - patch_apply wined3d-CSMT_Main/0103-wined3d-Fence-clear-calls.patch - patch_apply wined3d-CSMT_Main/0104-wined3d-Fence-present-calls.patch - patch_apply wined3d-CSMT_Main/0105-wined3d-Make-resource-maps-and-unmaps-a-priority-com.patch - patch_apply wined3d-CSMT_Main/0106-wined3d-Dirtify-changed-textures-through-the-command.patch - patch_apply wined3d-CSMT_Main/0107-wined3d-Wrap-GL-BOs-in-a-structure.patch - patch_apply wined3d-CSMT_Main/0108-wined3d-Separate-resource-map-and-draw-buffers.patch - patch_apply wined3d-CSMT_Main/0109-wined3d-Implement-DISCARD-resource-maps-with-buffers.patch - patch_apply wined3d-CSMT_Main/0110-wined3d-Implement-DISCARD-resource-maps-with-heap-me.patch - patch_apply wined3d-CSMT_Main/0111-wined3d-Unset-some-objects-in-state_init_default.patch - patch_apply wined3d-CSMT_Main/0112-wined3d-Don-t-request-the-frontbuffer-to-create-dumm.patch - patch_apply wined3d-CSMT_Main/0113-wined3d-Use-double-buffered-buffers-for-multithreade.patch - patch_apply wined3d-CSMT_Main/0114-wined3d-Don-t-synchronize-NOOVERWRITE-buffer-maps.patch - patch_apply wined3d-CSMT_Main/0115-wined3d-Separate-buffer-map-write-and-draw-read-memo.patch - patch_apply wined3d-CSMT_Main/0116-wined3d-Accelerate-DISCARD-buffer-maps.patch - patch_apply wined3d-CSMT_Main/0117-wined3d-Accelerate-READONLY-buffer-maps.patch - patch_apply wined3d-CSMT_Main/0118-wined3d-Access-the-buffer-dirty-areas-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0119-wined3d-Ignore-buffer-resource.map_count-in-the-CS.patch - patch_apply wined3d-CSMT_Main/0120-wined3d-Send-buffer-preloads-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0121-wined3d-Use-glBufferSubData-instead-of-glMapBufferRa.patch - patch_apply wined3d-CSMT_Main/0122-wined3d-Separate-GL-buffer-discard-control-from-igno.patch - patch_apply wined3d-CSMT_Main/0123-wined3d-Create-buffers-before-mapping-them.patch - patch_apply wined3d-CSMT_Main/0124-wined3d-Destroy-views-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0125-wined3d-Remove-another-glFinish.patch - patch_apply wined3d-CSMT_Main/0126-wined3d-Destroy-vertex-declarations-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0127-wined3d-Destroy-shaders-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0128-wined3d-Create-VBOs-through-the-command-stream.patch - patch_apply wined3d-CSMT_Main/0129-wined3d-Clean-up-resource-data-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0130-wined3d-Clean-up-buffer-resource-data-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0131-wined3d-Clean-up-volume-resource-data-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0132-wined3d-Clean-up-surfaces-through-the-cs.patch - patch_apply wined3d-CSMT_Main/0133-wined3d-Clean-up-texture-resources-through-the-cs.patch - patch_apply wined3d-CSMT_Main/0134-wined3d-Unload-resources-through-the-CS-in-uninit_3d.patch - patch_apply wined3d-CSMT_Main/0135-wined3d-Unload-resources-through-the-CS-in-device_re.patch - patch_apply wined3d-CSMT_Main/0136-wined3d-Don-t-glFinish-after-a-depth-buffer-blit.patch - patch_apply wined3d-CSMT_Main/0137-wined3d-Remove-software-cursor-support.patch - patch_apply wined3d-CSMT_Main/0138-wined3d-Create-dummy-textures-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0139-wined3d-Create-the-initial-context-through-the-CS.patch - patch_apply wined3d-CSMT_Main/0140-wined3d-Recreate-ctx-and-dummy-textures-through-the-.patch - patch_apply wined3d-CSMT_Main/0141-wined3d-Ignore-WINED3D_MAP_NO_DIRTY_UPDATE-in-resour.patch - patch_apply wined3d-CSMT_Main/0142-wined3d-Delete-GL-contexts-through-the-CS-in-reset.patch - patch_apply wined3d-CSMT_Main/0143-wined3d-Delete-GL-contexts-through-the-CS-in-uninit_.patch - patch_apply wined3d-CSMT_Main/0144-wined3d-Invoke-surface_unload-through-the-CS-in-wine.patch - patch_apply wined3d-CSMT_Main/0145-wined3d-Use-an-event-to-block-the-worker-thread-when.patch - patch_apply wined3d-CSMT_Main/0146-wined3d-Fence-preload-operations.patch - patch_apply wined3d-CSMT_Main/0147-d3d8-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch - patch_apply wined3d-CSMT_Main/0148-d3d9-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch - patch_apply wined3d-CSMT_Main/0149-wined3d-Completely-reset-the-state-on-reset.patch - patch_apply wined3d-CSMT_Main/0150-wined3d-Send-getdc-and-releasedc-through-the-command.patch - patch_apply wined3d-CSMT_Main/0151-wined3d-Set-map_heap_memory-NULL-when-allocating-a-P.patch - patch_apply wined3d-CSMT_Main/0152-wined3d-Wait-only-for-the-buffer-to-be-idle.patch - patch_apply wined3d-CSMT_Main/0153-wined3d-Add-a-comment-about-worker-thread-lag.patch - patch_apply wined3d-CSMT_Main/0154-wined3d-Remove-the-texture-destroy-glFinish.patch - patch_apply wined3d-CSMT_Main/0155-wined3d-Move-FBO-destruction-into-the-worker-thread.patch - patch_apply wined3d-CSMT_Main/0156-wined3d-Don-t-incref-decref-textures-in-color-depth-.patch - patch_apply wined3d-CSMT_Main/0157-Winex11-complain-about-glfinish.patch - patch_apply wined3d-CSMT_Main/0158-wined3d-Make-sure-the-new-window-is-set-up-before-se.patch - patch_apply wined3d-CSMT_Main/0159-wined3d-Remove-the-device_reset-CS-sync-fixme.patch - patch_apply wined3d-CSMT_Main/0160-wined3d-Put-GL_APPLE_flush_buffer_range-syncing-back.patch - patch_apply wined3d-CSMT_Main/0161-wined3d-Wait-for-the-resource-to-be-idle-when-destro.patch - patch_apply wined3d-CSMT_Main/0162-wined3d-Don-t-sync-on-redundant-discard-calls.patch - patch_apply wined3d-CSMT_Main/0163-wined3d-Don-t-discard-new-buffers.patch - patch_apply wined3d-CSMT_Main/0164-wined3d-Don-t-try-to-sync-VBOs-manually-on-OSX-with-.patch - patch_apply wined3d-CSMT_Main/0165-wined3d-Render-target-lock-hack.patch - patch_apply wined3d-CSMT_Main/0166-wined3d-Avoid-calling-wined3d_surface_blt-from-surfa.patch - patch_apply wined3d-CSMT_Main/0167-wined3d-Only-discard-buffers-that-are-in-use.patch - patch_apply wined3d-CSMT_Main/0168-wined3d-Destroy-samplers-through-the-command-stream.patch - patch_apply wined3d-CSMT_Main/0169-wined3d-Hack-to-reject-unsupported-color-fills.patch - patch_apply wined3d-CSMT_Main/0170-wined3d-Alloc-the-buffer-map-array-before-mapping-th.patch - patch_apply wined3d-CSMT_Main/0171-wined3d-Send-update_sub_resource-calls-through-the-c.patch + patch_apply wined3d-CSMT_Main/0025-wined3d-Introduce-a-function-to-retrieve-resource-me.patch + patch_apply wined3d-CSMT_Main/0026-wined3d-Make-surface_ops-unmap-specific-for-front-bu.patch + patch_apply wined3d-CSMT_Main/0027-wined3d-Move-check_block_align-to-resource.c.patch + patch_apply wined3d-CSMT_Main/0028-wined3d-Replace-surface-alloc-functions-with-resourc.patch + patch_apply wined3d-CSMT_Main/0029-wined3d-Don-t-delete-the-buffer-in-surface_cleanup.patch + patch_apply wined3d-CSMT_Main/0030-wined3d-Use-resource-facilities-to-destroy-PBOs.patch + patch_apply wined3d-CSMT_Main/0031-wined3d-Move-simple-location-copying-to-the-resource.patch + patch_apply wined3d-CSMT_Main/0032-wined3d-Move-most-of-volume_map-to-resource.c.patch + patch_apply wined3d-CSMT_Main/0033-wined3d-Use-resource_map-for-surface_map.patch + patch_apply wined3d-CSMT_Main/0034-wined3d-Don-t-call-the-public-map-function-in-surfac.patch + patch_apply wined3d-CSMT_Main/0035-wined3d-Don-t-call-the-public-map-function-in-surfac.patch + patch_apply wined3d-CSMT_Main/0036-wined3d-Move-the-framebuffer-into-wined3d_state.patch + patch_apply wined3d-CSMT_Main/0037-wined3d-Get-rid-of-state-access-in-shader_generate_g.patch + patch_apply wined3d-CSMT_Main/0038-wined3d-Preload-buffers-if-streamsrc-is-not-dirty.patch + patch_apply wined3d-CSMT_Main/0039-wined3d-Hackily-introduce-a-multithreaded-command-st.patch + patch_apply wined3d-CSMT_Main/0040-wined3d-Wait-for-resource-updates-to-finish-when-usi.patch + patch_apply wined3d-CSMT_Main/0041-wined3d-Don-t-store-pointers-in-struct-wined3d_cs_pr.patch + patch_apply wined3d-CSMT_Main/0042-wined3d-Don-t-put-rectangle-pointers-into-wined3d_cs.patch + patch_apply wined3d-CSMT_Main/0043-wined3d-Store-the-color-in-clear-ops-instead-of-a-po.patch + patch_apply wined3d-CSMT_Main/0044-wined3d-Pass-the-state-to-draw_primitive.patch + patch_apply wined3d-CSMT_Main/0045-wined3d-Wait-for-the-cs-before-destroying-objects.patch + patch_apply wined3d-CSMT_Main/0046-wined3d-Give-the-cs-its-own-state.patch + patch_apply wined3d-CSMT_Main/0047-wined3d-Send-float-constant-updates-through-the-comm.patch + patch_apply wined3d-CSMT_Main/0048-wined3d-Request-a-glFinish-before-modifying-resource.patch + patch_apply wined3d-CSMT_Main/0049-wined3d-Finish-the-cs-before-changing-the-texture-lo.patch + patch_apply wined3d-CSMT_Main/0050-wined3d-Don-t-call-glFinish-after-clears.patch + patch_apply wined3d-CSMT_Main/0051-wined3d-Don-t-call-glFinish-after-draws.patch + patch_apply wined3d-CSMT_Main/0052-wined3d-Shadow-device-offscreenBuffer-in-the-context.patch + patch_apply wined3d-CSMT_Main/0053-wined3d-Don-t-access-the-stateblock-in-find_draw_buf.patch + patch_apply wined3d-CSMT_Main/0054-wined3d-Pass-the-depth-stencil-to-swapchain-present.patch + patch_apply wined3d-CSMT_Main/0055-wined3d-Don-t-store-viewport-pointers-in-the-command.patch + patch_apply wined3d-CSMT_Main/0056-wined3d-Keep-track-of-the-onscreen-depth-stencil-in-.patch + patch_apply wined3d-CSMT_Main/0057-wined3d-Send-base-vertex-index-updates-through-the-c.patch + patch_apply wined3d-CSMT_Main/0058-wined3d-Send-primitive-type-updates-through-the-comm.patch + patch_apply wined3d-CSMT_Main/0059-wined3d-Send-bool-constant-updates-through-the-comma.patch + patch_apply wined3d-CSMT_Main/0060-wined3d-Send-int-constant-updates-through-the-comman.patch + patch_apply wined3d-CSMT_Main/0061-wined3d-Send-light-updates-through-the-command-strea.patch + patch_apply wined3d-CSMT_Main/0062-wined3d-Prevent-the-command-stream-from-running-ahea.patch + patch_apply wined3d-CSMT_Main/0063-wined3d-Wait-for-the-cs-to-finish-before-destroying-.patch + patch_apply wined3d-CSMT_Main/0064-wined3d-Run-the-cs-asynchronously.patch + patch_apply wined3d-CSMT_Main/0065-wined3d-Send-blits-through-the-command-stream.patch + patch_apply wined3d-CSMT_Main/0066-wined3d-Put-update_surface-checks-back-in-place.patch + patch_apply wined3d-CSMT_Main/0067-wined3d-Get-rid-of-WINED3D_BUFFER_FLUSH.patch + patch_apply wined3d-CSMT_Main/0068-wined3d-Don-t-force-strict-draw-ordering-for-multith.patch + patch_apply wined3d-CSMT_Main/0069-wined3d-Send-render-target-view-clears-through-the-c.patch + patch_apply wined3d-CSMT_Main/0070-wined3d-Wait-for-the-CS-in-GetDC.patch + patch_apply wined3d-CSMT_Main/0071-wined3d-send-resource-maps-through-the-command-strea.patch + patch_apply wined3d-CSMT_Main/0072-wined3d-Get-rid-of-the-end_scene-flush-and-finish.patch + patch_apply wined3d-CSMT_Main/0073-wined3d-Replace-the-linked-lists-with-a-ringbuffer.patch + patch_apply wined3d-CSMT_Main/0074-wined3d-Don-t-preload-buffers-on-unmap.patch + patch_apply wined3d-CSMT_Main/0075-wined3d-Don-t-call-glFinish-before-swapping.patch + patch_apply wined3d-CSMT_Main/0076-wined3d-wined3d_-_query_issue-never-fails.patch + patch_apply wined3d-CSMT_Main/0077-wined3d-Add-query-support-to-the-command-stream.patch + patch_apply wined3d-CSMT_Main/0078-wined3d-Check-our-CS-state-to-find-out-if-a-query-is.patch + patch_apply wined3d-CSMT_Main/0079-wined3d-Poll-queries-automatically-in-the-CS.patch + patch_apply wined3d-CSMT_Main/0080-wined3d-Introduce-a-separate-queue-for-priority-comm.patch + patch_apply wined3d-CSMT_Main/0081-wined3d-Destroy-queries-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0082-wined3d-Separate-main-and-worker-thread-query-state.patch + patch_apply wined3d-CSMT_Main/0083-wined3d-Don-t-poll-queries-that-failed-to-start.patch + patch_apply wined3d-CSMT_Main/0084-wined3d-Remove-restated-queries-from-the-poll-list.patch + patch_apply wined3d-CSMT_Main/0085-wined3d-Don-t-reset-the-query-state-if-it-doesn-t-ha.patch + patch_apply wined3d-CSMT_Main/0086-wined3d-Put-this-into-the-query-poll-patch.patch + patch_apply wined3d-CSMT_Main/0087-wined3d-Send-update_surface-commands-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0088-wined3d-Send-texture-preloads-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0089-wined3d-Send-update_texture-calls-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0090-wined3d-Get-rid-of-the-surface_upload_data-glFinish.patch + patch_apply wined3d-CSMT_Main/0091-wined3d-Don-t-lock-the-src-volume-in-device_update_v.patch + patch_apply wined3d-CSMT_Main/0092-wined3d-Handle-evit_managed_resources-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0093-wined3d-Introduce-resource-fencing.patch + patch_apply wined3d-CSMT_Main/0094-wined3d-Fence-update_texture-and-update_surface-call.patch + patch_apply wined3d-CSMT_Main/0095-wined3d-Dirtify-resources-on-unmap.patch + patch_apply wined3d-CSMT_Main/0096-wined3d-Fence-texture-reads-in-draws.patch + patch_apply wined3d-CSMT_Main/0097-wined3d-Fence-render-targets-and-depth-stencils.patch + patch_apply wined3d-CSMT_Main/0098-wined3d-Fence-blit-operations.patch + patch_apply wined3d-CSMT_Main/0099-wined3d-Fence-color_fill-operations.patch + patch_apply wined3d-CSMT_Main/0100-wined3d-Fence-clear-calls.patch + patch_apply wined3d-CSMT_Main/0101-wined3d-Fence-present-calls.patch + patch_apply wined3d-CSMT_Main/0102-wined3d-Make-resource-maps-and-unmaps-a-priority-com.patch + patch_apply wined3d-CSMT_Main/0103-wined3d-Dirtify-changed-textures-through-the-command.patch + patch_apply wined3d-CSMT_Main/0104-wined3d-Wrap-GL-BOs-in-a-structure.patch + patch_apply wined3d-CSMT_Main/0105-wined3d-Separate-resource-map-and-draw-buffers.patch + patch_apply wined3d-CSMT_Main/0106-wined3d-Implement-DISCARD-resource-maps-with-buffers.patch + patch_apply wined3d-CSMT_Main/0107-wined3d-Implement-DISCARD-resource-maps-with-heap-me.patch + patch_apply wined3d-CSMT_Main/0108-wined3d-Unset-some-objects-in-state_init_default.patch + patch_apply wined3d-CSMT_Main/0109-wined3d-Don-t-request-the-frontbuffer-to-create-dumm.patch + patch_apply wined3d-CSMT_Main/0110-wined3d-Use-double-buffered-buffers-for-multithreade.patch + patch_apply wined3d-CSMT_Main/0111-wined3d-Don-t-synchronize-NOOVERWRITE-buffer-maps.patch + patch_apply wined3d-CSMT_Main/0112-wined3d-Separate-buffer-map-write-and-draw-read-memo.patch + patch_apply wined3d-CSMT_Main/0113-wined3d-Accelerate-DISCARD-buffer-maps.patch + patch_apply wined3d-CSMT_Main/0114-wined3d-Accelerate-READONLY-buffer-maps.patch + patch_apply wined3d-CSMT_Main/0115-wined3d-Access-the-buffer-dirty-areas-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0116-wined3d-Ignore-buffer-resource.map_count-in-the-CS.patch + patch_apply wined3d-CSMT_Main/0117-wined3d-Send-buffer-preloads-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0118-wined3d-Use-glBufferSubData-instead-of-glMapBufferRa.patch + patch_apply wined3d-CSMT_Main/0119-wined3d-Separate-GL-buffer-discard-control-from-igno.patch + patch_apply wined3d-CSMT_Main/0120-wined3d-Create-buffers-before-mapping-them.patch + patch_apply wined3d-CSMT_Main/0121-wined3d-Destroy-views-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0122-wined3d-Remove-another-glFinish.patch + patch_apply wined3d-CSMT_Main/0123-wined3d-Destroy-vertex-declarations-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0124-wined3d-Destroy-shaders-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0125-wined3d-Create-VBOs-through-the-command-stream.patch + patch_apply wined3d-CSMT_Main/0126-wined3d-Clean-up-resource-data-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0127-wined3d-Clean-up-buffer-resource-data-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0128-wined3d-Clean-up-volume-resource-data-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0129-wined3d-Clean-up-surfaces-through-the-cs.patch + patch_apply wined3d-CSMT_Main/0130-wined3d-Clean-up-texture-resources-through-the-cs.patch + patch_apply wined3d-CSMT_Main/0131-wined3d-Unload-resources-through-the-CS-in-uninit_3d.patch + patch_apply wined3d-CSMT_Main/0132-wined3d-Unload-resources-through-the-CS-in-device_re.patch + patch_apply wined3d-CSMT_Main/0133-wined3d-Don-t-glFinish-after-a-depth-buffer-blit.patch + patch_apply wined3d-CSMT_Main/0134-wined3d-Remove-software-cursor-support.patch + patch_apply wined3d-CSMT_Main/0135-wined3d-Create-dummy-textures-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0136-wined3d-Create-the-initial-context-through-the-CS.patch + patch_apply wined3d-CSMT_Main/0137-wined3d-Recreate-ctx-and-dummy-textures-through-the-.patch + patch_apply wined3d-CSMT_Main/0138-wined3d-Ignore-WINED3D_MAP_NO_DIRTY_UPDATE-in-resour.patch + patch_apply wined3d-CSMT_Main/0139-wined3d-Delete-GL-contexts-through-the-CS-in-reset.patch + patch_apply wined3d-CSMT_Main/0140-wined3d-Delete-GL-contexts-through-the-CS-in-uninit_.patch + patch_apply wined3d-CSMT_Main/0141-wined3d-Invoke-surface_unload-through-the-CS-in-wine.patch + patch_apply wined3d-CSMT_Main/0142-wined3d-Use-an-event-to-block-the-worker-thread-when.patch + patch_apply wined3d-CSMT_Main/0143-wined3d-Fence-preload-operations.patch + patch_apply wined3d-CSMT_Main/0144-d3d8-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch + patch_apply wined3d-CSMT_Main/0145-d3d9-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch + patch_apply wined3d-CSMT_Main/0146-wined3d-Completely-reset-the-state-on-reset.patch + patch_apply wined3d-CSMT_Main/0147-wined3d-Send-getdc-and-releasedc-through-the-command.patch + patch_apply wined3d-CSMT_Main/0148-wined3d-Set-map_heap_memory-NULL-when-allocating-a-P.patch + patch_apply wined3d-CSMT_Main/0149-wined3d-Wait-only-for-the-buffer-to-be-idle.patch + patch_apply wined3d-CSMT_Main/0150-wined3d-Add-a-comment-about-worker-thread-lag.patch + patch_apply wined3d-CSMT_Main/0151-wined3d-Remove-the-texture-destroy-glFinish.patch + patch_apply wined3d-CSMT_Main/0152-wined3d-Move-FBO-destruction-into-the-worker-thread.patch + patch_apply wined3d-CSMT_Main/0153-wined3d-Don-t-incref-decref-textures-in-color-depth-.patch + patch_apply wined3d-CSMT_Main/0154-Winex11-complain-about-glfinish.patch + patch_apply wined3d-CSMT_Main/0155-wined3d-Make-sure-the-new-window-is-set-up-before-se.patch + patch_apply wined3d-CSMT_Main/0156-wined3d-Remove-the-device_reset-CS-sync-fixme.patch + patch_apply wined3d-CSMT_Main/0157-wined3d-Put-GL_APPLE_flush_buffer_range-syncing-back.patch + patch_apply wined3d-CSMT_Main/0158-wined3d-Wait-for-the-resource-to-be-idle-when-destro.patch + patch_apply wined3d-CSMT_Main/0159-wined3d-Don-t-sync-on-redundant-discard-calls.patch + patch_apply wined3d-CSMT_Main/0160-wined3d-Don-t-discard-new-buffers.patch + patch_apply wined3d-CSMT_Main/0161-wined3d-Don-t-try-to-sync-VBOs-manually-on-OSX-with-.patch + patch_apply wined3d-CSMT_Main/0162-wined3d-Render-target-lock-hack.patch + patch_apply wined3d-CSMT_Main/0163-wined3d-Avoid-calling-wined3d_surface_blt-from-surfa.patch + patch_apply wined3d-CSMT_Main/0164-wined3d-Only-discard-buffers-that-are-in-use.patch + patch_apply wined3d-CSMT_Main/0165-wined3d-Destroy-samplers-through-the-command-stream.patch + patch_apply wined3d-CSMT_Main/0166-wined3d-Hack-to-reject-unsupported-color-fills.patch + patch_apply wined3d-CSMT_Main/0167-wined3d-Alloc-the-buffer-map-array-before-mapping-th.patch + patch_apply wined3d-CSMT_Main/0168-wined3d-Send-update_sub_resource-calls-through-the-c.patch patch_apply wined3d-CSMT_Main/9998-wined3d-Enable-CSMT-by-default-print-a-winediag-mess.patch patch_apply wined3d-CSMT_Main/9999-IfDefined.patch ( @@ -6282,7 +7105,6 @@ echo '+ { "Stefan Dösinger", "wined3d: Discard implicit surfaces on unload.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Don'\''t try to flip sysmem copies in swapchain_present.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Discard the backbuffer in discard presents.", 1 },'; - echo '+ { "Stefan Dösinger", "wined3d: Allocate sysmem for client storage if it doesn'\''t exist already.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Introduce a function to retrieve resource memory.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Make surface_ops->unmap specific for front buffers.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Move check_block_align to resource.c.", 1 },'; @@ -6292,7 +7114,6 @@ echo '+ { "Stefan Dösinger", "wined3d: Move simple location copying to the resource.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Move most of volume_map to resource.c.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Use resource_map for surface_map.", 1 },'; - echo '+ { "Stefan Dösinger", "wined3d: Use client storage with DIB sections.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Don'\''t call the public map function in surface_convert_format.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Don'\''t call the public map function in surface_cpu_blt.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Move the framebuffer into wined3d_state.", 1 },'; @@ -6348,7 +7169,6 @@ echo '+ { "Stefan Dösinger", "wined3d: Put this into the query poll patch.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Send update_surface commands through the CS.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Send texture preloads through the CS.", 1 },'; - echo '+ { "Stefan Dösinger", "wined3d: Send surface preloads through the CS.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Send update_texture calls through the CS.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Get rid of the surface_upload_data glFinish.", 1 },'; echo '+ { "Stefan Dösinger", "wined3d: Don'\''t lock the src volume in device_update_volume.", 1 },'; @@ -6714,8 +7534,25 @@ ) >> "$patchlist" fi +# Patchset wpcap-Several_Fixes +# | +# | Modified files: +# | * dlls/wpcap/wpcap.c, dlls/wpcap/wpcap.spec +# | +if test "$enable_wpcap_Several_Fixes" -eq 1; then + patch_apply wpcap-Several_Fixes/0001-wpcap-Implement-pcap_dump_open-and-pcap_dump.patch + patch_apply wpcap-Several_Fixes/0002-wpcap-Fix-crash-on-pcap_loop.patch + ( + echo '+ { "Jianqiu Zhang", "wpcap: Implement pcap_dump_open and pcap_dump.", 1 },'; + echo '+ { "Jianqiu Zhang", "wpcap: Fix crash on pcap_loop.", 1 },'; + ) >> "$patchlist" +fi + # Patchset wpcap-Dynamic_Linking # | +# | This patchset has the following (direct or indirect) dependencies: +# | * wpcap-Several_Fixes +# | # | Modified files: # | * configure.ac, dlls/wpcap/Makefile.in, dlls/wpcap/wpcap.c # | @@ -6816,6 +7653,21 @@ ) >> "$patchlist" fi +# Patchset ws2_32-getsockopt +# | +# | This patchset fixes the following Wine bugs: +# | * [#8606] Divide values returned by SO_RCVBUF and SO_SNDBUF getsockopt options by two +# | +# | Modified files: +# | * dlls/ws2_32/socket.c, dlls/ws2_32/tests/sock.c +# | +if test "$enable_ws2_32_getsockopt" -eq 1; then + patch_apply ws2_32-getsockopt/0001-ws2_32-Divide-values-returned-by-SO_RCVBUF-and-SO_SN.patch + ( + echo '+ { "Sebastian Lackner", "ws2_32: Divide values returned by SO_RCVBUF and SO_SNDBUF getsockopt options by two.", 1 },'; + ) >> "$patchlist" +fi + # Patchset wtsapi32-EnumerateProcesses # | # | This patchset fixes the following Wine bugs: diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/Pipelight/0003-wined3d-allow-changing-strict-drawing-through-an-exp.patch wine-staging-1.9.3~ubuntu12.04.1/patches/Pipelight/0003-wined3d-allow-changing-strict-drawing-through-an-exp.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/Pipelight/0003-wined3d-allow-changing-strict-drawing-through-an-exp.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/Pipelight/0003-wined3d-allow-changing-strict-drawing-through-an-exp.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 8794d625750d35293adecbedc32cc02257817b05 Mon Sep 17 00:00:00 2001 +From 8e79e9494a7d4c9173066772b09afa26e643ef33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sun, 20 Jul 2014 22:22:14 +0200 Subject: wined3d: allow changing strict drawing through an exported function @@ -9,23 +9,23 @@ 2 files changed, 7 insertions(+) diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec -index 7a77003..5519a48 100644 +index 49041bb..8c253cd 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec -@@ -219,6 +219,8 @@ +@@ -222,6 +222,8 @@ @ cdecl wined3d_stateblock_decref(ptr) @ cdecl wined3d_stateblock_incref(ptr) +@ cdecl wined3d_strictdrawing_set(long) + - @ cdecl wined3d_surface_blt(ptr ptr ptr ptr long ptr long) - @ cdecl wined3d_surface_decref(ptr) - @ cdecl wined3d_surface_from_resource(ptr) + @ cdecl wined3d_surface_get_overlay_position(ptr ptr ptr) + @ cdecl wined3d_surface_get_parent(ptr) + @ cdecl wined3d_surface_get_pitch(ptr) diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c -index 758ba43..7ccd3a1 100644 +index 0543d97..78cc3a2 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c -@@ -505,6 +505,11 @@ void wined3d_unregister_window(HWND window) +@@ -515,6 +515,11 @@ void wined3d_unregister_window(HWND window) wined3d_wndproc_mutex_unlock(); } @@ -38,5 +38,5 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { -- -2.1.3 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/quartz-AsyncReader/0001-quartz-AsyncReader-should-return-NULL-as-media-subty.patch wine-staging-1.9.3~ubuntu12.04.1/patches/quartz-AsyncReader/0001-quartz-AsyncReader-should-return-NULL-as-media-subty.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/quartz-AsyncReader/0001-quartz-AsyncReader-should-return-NULL-as-media-subty.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/quartz-AsyncReader/0001-quartz-AsyncReader-should-return-NULL-as-media-subty.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,29 @@ +From db3178f4292558456596cc31766480638d8a0f3a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 7 Feb 2016 01:30:22 +0100 +Subject: quartz: AsyncReader should return NULL as media subtype for unknown + formats instead of failing. + +--- + dlls/quartz/filesource.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c +index 33ac442..a62db2c 100644 +--- a/dlls/quartz/filesource.c ++++ b/dlls/quartz/filesource.c +@@ -652,8 +652,9 @@ static HRESULT WINAPI FileSource_Load(IFileSourceFilter * iface, LPCOLESTR pszFi + hr = GetClassMediaFile(pReader, pszFileName, &This->pmt->majortype, &This->pmt->subtype, NULL); + if (FAILED(hr)) + { +- CoTaskMemFree(This->pmt); +- This->pmt = NULL; ++ memcpy(&This->pmt->majortype, &MEDIATYPE_Stream, sizeof(GUID)); ++ memcpy(&This->pmt->subtype, &MEDIASUBTYPE_NULL, sizeof(GUID)); ++ hr = S_OK; + } + } + else +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/quartz-AsyncReader/0002-quartz-Recognize-mpeg2-program-streams.patch wine-staging-1.9.3~ubuntu12.04.1/patches/quartz-AsyncReader/0002-quartz-Recognize-mpeg2-program-streams.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/quartz-AsyncReader/0002-quartz-Recognize-mpeg2-program-streams.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/quartz-AsyncReader/0002-quartz-Recognize-mpeg2-program-streams.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,28 @@ +From 6db27add885e521e7b42829ade2f7de74abdd619 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 7 Feb 2016 01:32:04 +0100 +Subject: quartz: Recognize mpeg2 program streams. + +--- + dlls/quartz/regsvr.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/dlls/quartz/regsvr.c b/dlls/quartz/regsvr.c +index b0f1e9a..196e064 100644 +--- a/dlls/quartz/regsvr.c ++++ b/dlls/quartz/regsvr.c +@@ -818,6 +818,11 @@ static struct regsvr_mediatype_parsing const mediatype_parsing_list[] = { + "0, 10, FFFFFF00000080808080, 494433000000000000", + NULL } + }, ++ { &MEDIATYPE_Stream, ++ &MEDIASUBTYPE_MPEG2_PROGRAM, ++ { "0, 5, FFFFFFFFC0, 000001BA40", ++ NULL } ++ }, + { &MEDIATYPE_Stream, + &MEDIASUBTYPE_QTMovie, + { "4, 4, , 6d646174", +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/quartz-AsyncReader/definition wine-staging-1.9.3~ubuntu12.04.1/patches/quartz-AsyncReader/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/quartz-AsyncReader/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/quartz-AsyncReader/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Improve detection of MPEG2 streams diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/rpcrt4-RpcBindingServerFromClient/0001-rpcrt4-Fix-prototype-of-RpcBindingServerFromClient.patch wine-staging-1.9.3~ubuntu12.04.1/patches/rpcrt4-RpcBindingServerFromClient/0001-rpcrt4-Fix-prototype-of-RpcBindingServerFromClient.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/rpcrt4-RpcBindingServerFromClient/0001-rpcrt4-Fix-prototype-of-RpcBindingServerFromClient.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/rpcrt4-RpcBindingServerFromClient/0001-rpcrt4-Fix-prototype-of-RpcBindingServerFromClient.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,27 @@ +From e96dbcea16b0f61eeb3547688613774e2c8b778e Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 14 Jan 2016 19:08:08 +0100 +Subject: rpcrt4: Fix prototype of RpcBindingServerFromClient. + +--- + dlls/rpcrt4/rpc_binding.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/rpcrt4/rpc_binding.c b/dlls/rpcrt4/rpc_binding.c +index 7212a18..2503d31 100644 +--- a/dlls/rpcrt4/rpc_binding.c ++++ b/dlls/rpcrt4/rpc_binding.c +@@ -1636,8 +1636,8 @@ RpcBindingInqAuthClientExW( RPC_BINDING_HANDLE ClientBinding, RPC_AUTHZ_HANDLE * + /*********************************************************************** + * RpcBindingServerFromClient (RPCRT4.@) + */ +- +-RPC_STATUS RPC_ENTRY RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding, RPC_BINDING_HANDLE *ServerBinding) ++RPCRTAPI RPC_STATUS RPC_ENTRY ++RpcBindingServerFromClient( RPC_BINDING_HANDLE ClientBinding, RPC_BINDING_HANDLE *ServerBinding ) + { + FIXME("%p %p: stub\n", ClientBinding, ServerBinding); + return RPC_S_INVALID_BINDING; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Desktop_Refcount/0001-server-Introduce-a-new-alloc_handle-object-callback..patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Desktop_Refcount/0001-server-Introduce-a-new-alloc_handle-object-callback..patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Desktop_Refcount/0001-server-Introduce-a-new-alloc_handle-object-callback..patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Desktop_Refcount/0001-server-Introduce-a-new-alloc_handle-object-callback..patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From a04ff4bba9832fd787972911fb391558f129870c Mon Sep 17 00:00:00 2001 +From bb902548f15deec4dc9d9eaaf6e78b4cbdb01f87 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 4 Dec 2015 10:36:47 +0100 Subject: server: Introduce a new alloc_handle object callback. (v2) @@ -42,258 +42,258 @@ 34 files changed, 73 insertions(+), 3 deletions(-) diff --git a/server/async.c b/server/async.c -index d2da976..b00d2cc 100644 +index 64aa27a..bc74173 100644 --- a/server/async.c +++ b/server/async.c -@@ -66,6 +66,7 @@ static const struct object_ops async_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -68,6 +68,7 @@ static const struct object_ops async_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ async_destroy /* destroy */ }; -@@ -99,6 +100,7 @@ static const struct object_ops async_queue_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -103,6 +104,7 @@ static const struct object_ops async_queue_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ async_queue_destroy /* destroy */ }; diff --git a/server/atom.c b/server/atom.c -index 0ed4ed5..1f694bc 100644 +index 3ff7540..7bebf13 100644 --- a/server/atom.c +++ b/server/atom.c -@@ -88,6 +88,7 @@ static const struct object_ops atom_table_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -90,6 +90,7 @@ static const struct object_ops atom_table_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ atom_table_destroy /* destroy */ }; diff --git a/server/change.c b/server/change.c -index 59d1819..4f36179 100644 +index 36a1997..6da2f63 100644 --- a/server/change.c +++ b/server/change.c -@@ -167,6 +167,7 @@ static const struct object_ops dir_ops = - dir_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -169,6 +169,7 @@ static const struct object_ops dir_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ fd_close_handle, /* close_handle */ dir_destroy /* destroy */ }; diff --git a/server/clipboard.c b/server/clipboard.c -index 2f56c72..1f988bc 100644 +index 7b92706..fa3aa51 100644 --- a/server/clipboard.c +++ b/server/clipboard.c -@@ -66,6 +66,7 @@ static const struct object_ops clipboard_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -68,6 +68,7 @@ static const struct object_ops clipboard_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ no_destroy /* destroy */ }; diff --git a/server/completion.c b/server/completion.c -index 77c72cc..97d2102 100644 +index 759c6e2..bca0963 100644 --- a/server/completion.c +++ b/server/completion.c -@@ -73,6 +73,7 @@ static const struct object_ops completion_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -75,6 +75,7 @@ static const struct object_ops completion_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ completion_destroy /* destroy */ }; diff --git a/server/console.c b/server/console.c -index a57b2fe..264b45f 100644 +index 0d98b78..37e413c 100644 --- a/server/console.c +++ b/server/console.c -@@ -85,6 +85,7 @@ static const struct object_ops console_input_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -87,6 +87,7 @@ static const struct object_ops console_input_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ console_input_destroy /* destroy */ }; -@@ -117,6 +118,7 @@ static const struct object_ops console_input_events_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -121,6 +122,7 @@ static const struct object_ops console_input_events_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ console_input_events_destroy /* destroy */ }; -@@ -169,6 +171,7 @@ static const struct object_ops screen_buffer_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -175,6 +177,7 @@ static const struct object_ops screen_buffer_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ screen_buffer_destroy /* destroy */ }; diff --git a/server/debugger.c b/server/debugger.c -index 374f2ad..5e9e6bf 100644 +index 2eb794a..a2c07ba 100644 --- a/server/debugger.c +++ b/server/debugger.c -@@ -82,6 +82,7 @@ static const struct object_ops debug_event_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -84,6 +84,7 @@ static const struct object_ops debug_event_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ debug_event_destroy /* destroy */ }; -@@ -106,6 +107,7 @@ static const struct object_ops debug_ctx_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -110,6 +111,7 @@ static const struct object_ops debug_ctx_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ debug_ctx_destroy /* destroy */ }; diff --git a/server/device.c b/server/device.c -index fb91c02..e207ba8 100644 +index a8f6f5d..4fdf7ad 100644 --- a/server/device.c +++ b/server/device.c -@@ -79,6 +79,7 @@ static const struct object_ops irp_call_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -81,6 +81,7 @@ static const struct object_ops irp_call_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ irp_call_destroy /* destroy */ }; -@@ -113,6 +114,7 @@ static const struct object_ops device_manager_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -117,6 +118,7 @@ static const struct object_ops device_manager_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ device_manager_destroy /* destroy */ }; -@@ -152,6 +154,7 @@ static const struct object_ops device_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -158,6 +160,7 @@ static const struct object_ops device_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ device_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ device_destroy /* destroy */ }; -@@ -198,6 +201,7 @@ static const struct object_ops device_file_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -206,6 +209,7 @@ static const struct object_ops device_file_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ device_file_close_handle, /* close_handle */ device_file_destroy /* destroy */ }; diff --git a/server/directory.c b/server/directory.c -index e0cf75e..da98fb0 100644 +index 45683b9..445c35c 100644 --- a/server/directory.c +++ b/server/directory.c -@@ -65,6 +65,7 @@ static const struct object_ops object_type_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -67,6 +67,7 @@ static const struct object_ops object_type_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ no_destroy /* destroy */ }; -@@ -98,6 +99,7 @@ static const struct object_ops directory_ops = - default_set_sd, /* set_sd */ - directory_lookup_name, /* lookup_name */ +@@ -102,6 +103,7 @@ static const struct object_ops directory_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ directory_destroy /* destroy */ }; diff --git a/server/event.c b/server/event.c -index 4d3c562..9c09694 100644 +index c9a0ebb..36ea8fd 100644 --- a/server/event.c +++ b/server/event.c -@@ -66,6 +66,7 @@ static const struct object_ops event_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -68,6 +68,7 @@ static const struct object_ops event_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ no_destroy /* destroy */ }; -@@ -97,6 +98,7 @@ static const struct object_ops keyed_event_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -101,6 +102,7 @@ static const struct object_ops keyed_event_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ no_destroy /* destroy */ }; diff --git a/server/fd.c b/server/fd.c -index e3fe292..3e6373a 100644 +index 28f5346..c64132c 100644 --- a/server/fd.c +++ b/server/fd.c -@@ -210,6 +210,7 @@ static const struct object_ops fd_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -212,6 +212,7 @@ static const struct object_ops fd_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ fd_destroy /* destroy */ }; -@@ -247,6 +248,7 @@ static const struct object_ops device_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -251,6 +252,7 @@ static const struct object_ops device_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ device_destroy /* destroy */ }; -@@ -283,6 +285,7 @@ static const struct object_ops inode_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -289,6 +291,7 @@ static const struct object_ops inode_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ inode_destroy /* destroy */ }; -@@ -321,6 +324,7 @@ static const struct object_ops file_lock_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -329,6 +332,7 @@ static const struct object_ops file_lock_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ no_destroy /* destroy */ }; diff --git a/server/file.c b/server/file.c -index a07ca16..c9c47a4 100644 +index 15fd411..e6f3fc2 100644 --- a/server/file.c +++ b/server/file.c -@@ -92,6 +92,7 @@ static const struct object_ops file_ops = - file_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -94,6 +94,7 @@ static const struct object_ops file_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ file_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ fd_close_handle, /* close_handle */ file_destroy /* destroy */ }; diff --git a/server/handle.c b/server/handle.c -index 5043ff7..64db8fc 100644 +index f440f9f..eb83a3b 100644 --- a/server/handle.c +++ b/server/handle.c -@@ -131,6 +131,7 @@ static const struct object_ops handle_table_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -133,6 +133,7 @@ static const struct object_ops handle_table_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ handle_table_destroy /* destroy */ }; -@@ -229,7 +230,7 @@ static int grow_handle_table( struct handle_table *table ) +@@ -232,7 +233,7 @@ static int grow_handle_table( struct handle_table *table ) } /* allocate the first free entry in the handle table */ @@ -302,7 +302,7 @@ { struct handle_entry *entry = table->entries + table->free; int i; -@@ -245,6 +246,10 @@ static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned +@@ -248,6 +249,10 @@ static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned table->free = i + 1; entry->ptr = grab_object_for_handle( obj ); entry->access = access; @@ -313,7 +313,7 @@ return index_to_handle(i); } -@@ -369,7 +374,11 @@ struct handle_table *copy_handle_table( struct process *process, struct process +@@ -372,7 +377,11 @@ struct handle_table *copy_handle_table( struct process *process, struct process for (i = 0; i <= table->last; i++, ptr++) { if (!ptr->ptr) continue; @@ -327,110 +327,110 @@ } } diff --git a/server/hook.c b/server/hook.c -index a8e6ab9..c005cae 100644 +index 3a0e4b4..dc653b8 100644 --- a/server/hook.c +++ b/server/hook.c -@@ -89,6 +89,7 @@ static const struct object_ops hook_table_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -91,6 +91,7 @@ static const struct object_ops hook_table_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ hook_table_destroy /* destroy */ }; diff --git a/server/mailslot.c b/server/mailslot.c -index 97ea3f6..5075a1a 100644 +index a0fa6e2..bff0208 100644 --- a/server/mailslot.c +++ b/server/mailslot.c -@@ -86,6 +86,7 @@ static const struct object_ops mailslot_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -89,6 +89,7 @@ static const struct object_ops mailslot_ops = + mailslot_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ mailslot_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ fd_close_handle, /* close_handle */ mailslot_destroy /* destroy */ }; -@@ -139,6 +140,7 @@ static const struct object_ops mail_writer_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -144,6 +145,7 @@ static const struct object_ops mail_writer_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ fd_close_handle, /* close_handle */ mail_writer_destroy /* destroy */ }; -@@ -193,6 +195,7 @@ static const struct object_ops mailslot_device_ops = - default_set_sd, /* set_sd */ - mailslot_device_lookup_name, /* lookup_name */ +@@ -200,6 +202,7 @@ static const struct object_ops mailslot_device_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ mailslot_device_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ fd_close_handle, /* close_handle */ mailslot_device_destroy /* destroy */ }; diff --git a/server/mapping.c b/server/mapping.c -index 16e7c1c..fd31df2 100644 +index 4384cec..fc6404f 100644 --- a/server/mapping.c +++ b/server/mapping.c -@@ -92,6 +92,7 @@ static const struct object_ops mapping_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -94,6 +94,7 @@ static const struct object_ops mapping_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ fd_close_handle, /* close_handle */ mapping_destroy /* destroy */ }; diff --git a/server/mutex.c b/server/mutex.c -index 910fbca..6e23770 100644 +index ca0da59..3598ac9 100644 --- a/server/mutex.c +++ b/server/mutex.c -@@ -69,6 +69,7 @@ static const struct object_ops mutex_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -71,6 +71,7 @@ static const struct object_ops mutex_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ mutex_destroy /* destroy */ }; diff --git a/server/named_pipe.c b/server/named_pipe.c -index 8d5753a..f48ead9 100644 +index 1e4169d..ade9165 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c -@@ -132,6 +132,7 @@ static const struct object_ops named_pipe_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -135,6 +135,7 @@ static const struct object_ops named_pipe_ops = + named_pipe_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ named_pipe_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ named_pipe_destroy /* destroy */ }; -@@ -161,6 +162,7 @@ static const struct object_ops pipe_server_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -166,6 +167,7 @@ static const struct object_ops pipe_server_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ fd_close_handle, /* close_handle */ pipe_server_destroy /* destroy */ }; -@@ -203,6 +205,7 @@ static const struct object_ops pipe_client_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -210,6 +212,7 @@ static const struct object_ops pipe_client_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ fd_close_handle, /* close_handle */ pipe_client_destroy /* destroy */ }; -@@ -249,6 +252,7 @@ static const struct object_ops named_pipe_device_ops = - default_set_sd, /* set_sd */ - named_pipe_device_lookup_name, /* lookup_name */ +@@ -258,6 +261,7 @@ static const struct object_ops named_pipe_device_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ named_pipe_device_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ fd_close_handle, /* close_handle */ named_pipe_device_destroy /* destroy */ }; diff --git a/server/object.c b/server/object.c -index 31883bd..3ccaa4c 100644 +index b8be122..8310067 100644 --- a/server/object.c +++ b/server/object.c -@@ -548,6 +548,10 @@ struct object *no_open_file( struct object *obj, unsigned int access, unsigned i +@@ -563,6 +563,10 @@ struct object *no_open_file( struct object *obj, unsigned int access, unsigned i return NULL; } @@ -442,10 +442,10 @@ { return 1; /* ok to close */ diff --git a/server/object.h b/server/object.h -index b59811f..06ee321 100644 +index c4bc40b..16bf089 100644 --- a/server/object.h +++ b/server/object.h -@@ -86,8 +86,10 @@ struct object_ops +@@ -90,8 +90,10 @@ struct object_ops /* open a file object to access this object */ struct object *(*open_file)(struct object *, unsigned int access, unsigned int sharing, unsigned int options); @@ -457,8 +457,8 @@ /* destroy on refcount == 0 */ void (*destroy)(struct object *); }; -@@ -145,6 +147,7 @@ extern int set_sd_defaults_from_token( struct object *obj, const struct security - extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes ); +@@ -161,6 +163,7 @@ extern int no_link_name( struct object *obj, struct object_name *name, struct ob + extern void default_unlink_name( struct object *obj, struct object_name *name ); extern struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); +extern void no_alloc_handle( struct object *obj, struct process *process, obj_handle_t handle ); @@ -466,221 +466,221 @@ extern void no_destroy( struct object *obj ); #ifdef DEBUG_OBJECTS diff --git a/server/process.c b/server/process.c -index e00b429..bc86c24 100644 +index c9bcabb..cc9c01c 100644 --- a/server/process.c +++ b/server/process.c -@@ -82,6 +82,7 @@ static const struct object_ops process_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -84,6 +84,7 @@ static const struct object_ops process_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ process_destroy /* destroy */ }; -@@ -130,6 +131,7 @@ static const struct object_ops startup_info_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -134,6 +135,7 @@ static const struct object_ops startup_info_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ startup_info_destroy /* destroy */ }; -@@ -171,6 +173,7 @@ static const struct object_ops job_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -177,6 +179,7 @@ static const struct object_ops job_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ job_close_handle, /* close_handle */ job_destroy /* destroy */ }; diff --git a/server/queue.c b/server/queue.c -index 3099e12..bdc740d 100644 +index f82060f..e097f5b 100644 --- a/server/queue.c +++ b/server/queue.c -@@ -179,6 +179,7 @@ static const struct object_ops msg_queue_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -181,6 +181,7 @@ static const struct object_ops msg_queue_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ msg_queue_destroy /* destroy */ }; -@@ -212,6 +213,7 @@ static const struct object_ops thread_input_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -216,6 +217,7 @@ static const struct object_ops thread_input_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ thread_input_destroy /* destroy */ }; diff --git a/server/registry.c b/server/registry.c -index a3c1390..2db56c3 100644 +index 5ca2a52..e38d6bb 100644 --- a/server/registry.c +++ b/server/registry.c -@@ -167,6 +167,7 @@ static const struct object_ops key_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -169,6 +169,7 @@ static const struct object_ops key_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ key_close_handle, /* close_handle */ key_destroy /* destroy */ }; diff --git a/server/request.c b/server/request.c -index f78026a..bd01179 100644 +index dfa4485..122de96 100644 --- a/server/request.c +++ b/server/request.c -@@ -103,6 +103,7 @@ static const struct object_ops master_socket_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -107,6 +107,7 @@ static const struct object_ops master_socket_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ master_socket_destroy /* destroy */ }; diff --git a/server/semaphore.c b/server/semaphore.c -index d87325c..aaf2d65 100644 +index c77bd58..9c06ce4 100644 --- a/server/semaphore.c +++ b/server/semaphore.c -@@ -66,6 +66,7 @@ static const struct object_ops semaphore_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -68,6 +68,7 @@ static const struct object_ops semaphore_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ no_destroy /* destroy */ }; diff --git a/server/serial.c b/server/serial.c -index 164a4b1..cc9c3bc 100644 +index 03d726a..46949a3 100644 --- a/server/serial.c +++ b/server/serial.c -@@ -101,6 +101,7 @@ static const struct object_ops serial_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -106,6 +106,7 @@ static const struct object_ops serial_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ fd_close_handle, /* close_handle */ serial_destroy /* destroy */ }; diff --git a/server/signal.c b/server/signal.c -index 5e4fe33..308f494 100644 +index c20e154..8c05c5f 100644 --- a/server/signal.c +++ b/server/signal.c -@@ -75,6 +75,7 @@ static const struct object_ops handler_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -77,6 +77,7 @@ static const struct object_ops handler_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ handler_destroy /* destroy */ }; diff --git a/server/snapshot.c b/server/snapshot.c -index dd00bd1..b827c6f 100644 +index 3566b89..a0cf32e 100644 --- a/server/snapshot.c +++ b/server/snapshot.c -@@ -69,6 +69,7 @@ static const struct object_ops snapshot_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -71,6 +71,7 @@ static const struct object_ops snapshot_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ snapshot_destroy /* destroy */ }; diff --git a/server/sock.c b/server/sock.c -index 1767dea..57d3d93 100644 +index dc10d2a..a11964f 100644 --- a/server/sock.c +++ b/server/sock.c -@@ -154,6 +154,7 @@ static const struct object_ops sock_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -156,6 +156,7 @@ static const struct object_ops sock_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ fd_close_handle, /* close_handle */ sock_destroy /* destroy */ }; -@@ -996,6 +997,7 @@ static const struct object_ops ifchange_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -1000,6 +1001,7 @@ static const struct object_ops ifchange_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ ifchange_destroy /* destroy */ }; diff --git a/server/symlink.c b/server/symlink.c -index 2330fde..1107639 100644 +index bd09d34..6607e47 100644 --- a/server/symlink.c +++ b/server/symlink.c -@@ -68,6 +68,7 @@ static const struct object_ops symlink_ops = - default_set_sd, /* set_sd */ - symlink_lookup_name, /* lookup_name */ +@@ -70,6 +70,7 @@ static const struct object_ops symlink_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ symlink_destroy /* destroy */ }; diff --git a/server/thread.c b/server/thread.c -index bad2231..9407938 100644 +index ca02a8a..71b4d7b 100644 --- a/server/thread.c +++ b/server/thread.c -@@ -118,6 +118,7 @@ static const struct object_ops thread_apc_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -120,6 +120,7 @@ static const struct object_ops thread_apc_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ thread_apc_destroy /* destroy */ }; -@@ -147,6 +148,7 @@ static const struct object_ops thread_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -151,6 +152,7 @@ static const struct object_ops thread_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ destroy_thread /* destroy */ }; diff --git a/server/timer.c b/server/timer.c -index 9c293f2..9957ee3 100644 +index 0d81d90..966d65d 100644 --- a/server/timer.c +++ b/server/timer.c -@@ -73,6 +73,7 @@ static const struct object_ops timer_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -75,6 +75,7 @@ static const struct object_ops timer_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ timer_destroy /* destroy */ }; diff --git a/server/token.c b/server/token.c -index 42cfb3d..893d58f 100644 +index ca12813..e13d03a 100644 --- a/server/token.c +++ b/server/token.c -@@ -159,6 +159,7 @@ static const struct object_ops token_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -161,6 +161,7 @@ static const struct object_ops token_ops = + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ no_close_handle, /* close_handle */ token_destroy /* destroy */ }; diff --git a/server/winstation.c b/server/winstation.c -index 5016184..c4e55e3 100644 +index 9dc348d..17c312a 100644 --- a/server/winstation.c +++ b/server/winstation.c -@@ -71,6 +71,7 @@ static const struct object_ops winstation_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -73,6 +73,7 @@ static const struct object_ops winstation_ops = + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ winstation_close_handle, /* close_handle */ winstation_destroy /* destroy */ }; -@@ -92,6 +93,7 @@ static const struct object_ops desktop_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -96,6 +97,7 @@ static const struct object_ops desktop_ops = + desktop_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ desktop_close_handle, /* close_handle */ desktop_destroy /* destroy */ }; -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Desktop_Refcount/0002-server-Track-desktop-handle-count-more-correctly.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Desktop_Refcount/0002-server-Track-desktop-handle-count-more-correctly.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Desktop_Refcount/0002-server-Track-desktop-handle-count-more-correctly.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Desktop_Refcount/0002-server-Track-desktop-handle-count-more-correctly.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From dd59d5fa25b8a20842e565d656c2b0f7833dae6c Mon Sep 17 00:00:00 2001 +From 02981c79c3ad972000fd3f397371f284ce9fade6 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 4 Dec 2015 01:22:29 +0100 Subject: server: Track desktop handle count more correctly. @@ -54,10 +54,10 @@ } diff --git a/server/handle.c b/server/handle.c -index 64db8fc..63dbf4e 100644 +index eb83a3b..38f38d5 100644 --- a/server/handle.c +++ b/server/handle.c -@@ -487,7 +487,7 @@ obj_handle_t find_inherited_handle( struct process *process, const struct object +@@ -490,7 +490,7 @@ obj_handle_t find_inherited_handle( struct process *process, const struct object /* enumerate handles of a given type */ /* this is needed for window stations and desktops */ obj_handle_t enumerate_handles( struct process *process, const struct object_ops *ops, @@ -66,7 +66,7 @@ { struct handle_table *table = process->handles; unsigned int i; -@@ -500,6 +500,7 @@ obj_handle_t enumerate_handles( struct process *process, const struct object_ops +@@ -503,6 +503,7 @@ obj_handle_t enumerate_handles( struct process *process, const struct object_ops if (!entry->ptr) continue; if (entry->ptr->ops != ops) continue; *index = i + 1; @@ -75,11 +75,11 @@ } return 0; diff --git a/server/handle.h b/server/handle.h -index 821c4ef..583a25a 100644 +index f1deb79..1347836 100644 --- a/server/handle.h +++ b/server/handle.h -@@ -48,7 +48,7 @@ extern obj_handle_t open_object( const struct namespace *namespace, const struct - const struct object_ops *ops, unsigned int access, unsigned int attr ); +@@ -49,7 +49,7 @@ extern obj_handle_t open_object( struct process *process, obj_handle_t parent, u + unsigned int attr ); extern obj_handle_t find_inherited_handle( struct process *process, const struct object_ops *ops ); extern obj_handle_t enumerate_handles( struct process *process, const struct object_ops *ops, - unsigned int *index ); @@ -88,10 +88,10 @@ extern struct handle_table *alloc_handle_table( struct process *process, int count ); extern struct handle_table *copy_handle_table( struct process *process, struct process *parent ); diff --git a/server/process.c b/server/process.c -index bc86c24..77771e5 100644 +index cc9c01c..b43e1f8 100644 --- a/server/process.c +++ b/server/process.c -@@ -832,7 +832,6 @@ static void process_killed( struct process *process ) +@@ -838,7 +838,6 @@ static void process_killed( struct process *process ) assert( list_empty( &process->thread_list )); process->end_time = current_time; @@ -100,28 +100,28 @@ process->desktop = 0; close_process_handles( process ); diff --git a/server/winstation.c b/server/winstation.c -index c4e55e3..78bd24c 100644 +index 17c312a..46ade3b 100644 --- a/server/winstation.c +++ b/server/winstation.c -@@ -51,6 +51,7 @@ static void winstation_destroy( struct object *obj ); - static unsigned int winstation_map_access( struct object *obj, unsigned int access ); +@@ -51,6 +51,7 @@ static unsigned int winstation_map_access( struct object *obj, unsigned int acce static void desktop_dump( struct object *obj, int verbose ); static struct object_type *desktop_get_type( struct object *obj ); + static int desktop_link_name( struct object *obj, struct object_name *name, struct object *parent ); +static void desktop_alloc_handle( struct object *obj, struct process *process, obj_handle_t handle ); static int desktop_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); static void desktop_destroy( struct object *obj ); static unsigned int desktop_map_access( struct object *obj, unsigned int access ); -@@ -93,7 +94,7 @@ static const struct object_ops desktop_ops = - default_set_sd, /* set_sd */ - no_lookup_name, /* lookup_name */ +@@ -97,7 +98,7 @@ static const struct object_ops desktop_ops = + desktop_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ - no_alloc_handle, /* alloc_handle */ + desktop_alloc_handle, /* alloc_handle */ desktop_close_handle, /* close_handle */ desktop_destroy /* destroy */ }; -@@ -261,14 +262,54 @@ static struct object_type *desktop_get_type( struct object *obj ) - return get_object_type( &str ); +@@ -253,14 +254,54 @@ static int desktop_link_name( struct object *obj, struct object_name *name, stru + return 1; } +static void close_desktop_timeout( void *private ) @@ -175,7 +175,7 @@ return 1; } -@@ -276,6 +317,7 @@ static void desktop_destroy( struct object *obj ) +@@ -268,6 +309,7 @@ static void desktop_destroy( struct object *obj ) { struct desktop *desktop = (struct desktop *)obj; @@ -183,7 +183,7 @@ free_hotkeys( desktop, 0 ); if (desktop->top_window) destroy_window( desktop->top_window ); if (desktop->msg_window) destroy_window( desktop->msg_window ); -@@ -302,40 +344,6 @@ struct desktop *get_thread_desktop( struct thread *thread, unsigned int access ) +@@ -294,40 +336,6 @@ struct desktop *get_thread_desktop( struct thread *thread, unsigned int access ) return get_desktop_obj( thread->process, thread->desktop, access ); } @@ -224,7 +224,7 @@ /* set the process default desktop handle */ void set_process_default_desktop( struct process *process, struct desktop *desktop, obj_handle_t handle ) -@@ -352,12 +360,6 @@ void set_process_default_desktop( struct process *process, struct desktop *deskt +@@ -344,12 +352,6 @@ void set_process_default_desktop( struct process *process, struct desktop *deskt LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry ) if (!thread->desktop) thread->desktop = handle; @@ -237,7 +237,7 @@ if (old_desktop) release_object( old_desktop ); } -@@ -407,8 +409,8 @@ done: +@@ -399,8 +401,8 @@ done: void close_process_desktop( struct process *process ) { struct desktop *desktop; @@ -249,5 +249,5 @@ remove_desktop_user( desktop ); release_object( desktop ); -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Fix_Leak/0001-server-Fix-newly-introduced-memory-leak-of-object-na.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Fix_Leak/0001-server-Fix-newly-introduced-memory-leak-of-object-na.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Fix_Leak/0001-server-Fix-newly-introduced-memory-leak-of-object-na.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Fix_Leak/0001-server-Fix-newly-introduced-memory-leak-of-object-na.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,24 @@ +From 3d1d0332cc94bdac774643e1adfe987c534e088b Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Fri, 5 Feb 2016 19:07:42 +0100 +Subject: server: Fix newly introduced memory leak of object name structure. + +--- + server/object.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/server/object.c b/server/object.c +index c8098ca..b8be122 100644 +--- a/server/object.c ++++ b/server/object.c +@@ -222,6 +222,7 @@ void *create_object( struct object *parent, const struct object_ops *ops, const + if (!obj->ops->link_name( obj, name_ptr, parent )) + { + free_object( obj ); ++ free( name_ptr ); + return NULL; + } + name_ptr->obj = obj; +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Misc_ACL/0001-server-Add-default-security-descriptor-ownership-for.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Misc_ACL/0001-server-Add-default-security-descriptor-ownership-for.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Misc_ACL/0001-server-Add-default-security-descriptor-ownership-for.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Misc_ACL/0001-server-Add-default-security-descriptor-ownership-for.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From f06a13e553d543e7b49c805b9292611ab1c68371 Mon Sep 17 00:00:00 2001 +From 2380d7451dc978cdab3ebcbeb75272c9147d0f68 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Wed, 25 Jun 2014 11:49:12 -0600 Subject: server: Add default security descriptor ownership for processes. @@ -11,10 +11,10 @@ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index 466100d..ca4a8ad 100644 +index 498d19a..c09b097 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c -@@ -4253,11 +4253,15 @@ static void test_acls(void) +@@ -4303,11 +4303,15 @@ static void test_acls(void) static void test_GetSecurityInfo(void) { @@ -30,7 +30,7 @@ ACL_SIZE_INFORMATION acl_size; PSECURITY_DESCRIPTOR pSD; ACCESS_ALLOWED_ACE *ace; -@@ -4382,6 +4386,37 @@ static void test_GetSecurityInfo(void) +@@ -4434,6 +4438,37 @@ static void test_GetSecurityInfo(void) } LocalFree(pSD); CloseHandle(obj); @@ -69,7 +69,7 @@ static void test_GetSidSubAuthority(void) diff --git a/server/process.c b/server/process.c -index 26f8924..1047c25 100644 +index d51c884..14e36b0 100644 --- a/server/process.c +++ b/server/process.c @@ -62,6 +62,7 @@ static int shutdown_stage; /* current stage in the shutdown process */ @@ -88,8 +88,8 @@ + process_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ - no_open_file, /* open_file */ -@@ -642,6 +643,29 @@ static unsigned int process_map_access( struct object *obj, unsigned int access + no_link_name, /* link_name */ +@@ -664,6 +665,29 @@ static unsigned int process_map_access( struct object *obj, unsigned int access return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); } @@ -120,7 +120,7 @@ { struct process *process = get_fd_user( fd ); diff --git a/server/security.h b/server/security.h -index 855f2e7..01bf637 100644 +index 925a85b..bdb7d42 100644 --- a/server/security.h +++ b/server/security.h @@ -47,6 +47,7 @@ extern const PSID security_local_user_sid; @@ -132,7 +132,7 @@ /* token functions */ diff --git a/server/token.c b/server/token.c -index cb81eec..914dfba 100644 +index ca12813..d66c39a 100644 --- a/server/token.c +++ b/server/token.c @@ -91,6 +91,13 @@ static const struct /* same fields as struct SID */ @@ -158,5 +158,5 @@ static luid_t prev_luid_value = { 1000, 0 }; -- -2.3.5 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Pipe_ObjectName/0001-server-Move-parent-reference-from-object_name-to-obj.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Pipe_ObjectName/0001-server-Move-parent-reference-from-object_name-to-obj.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Pipe_ObjectName/0001-server-Move-parent-reference-from-object_name-to-obj.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Pipe_ObjectName/0001-server-Move-parent-reference-from-object_name-to-obj.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,114 +0,0 @@ -From e266c05975d524f09886decb854ec78942e9b2fb Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 17 Aug 2015 00:13:27 +0200 -Subject: server: Move parent reference from object_name to object. - ---- - server/object.c | 20 ++++++++++---------- - server/object.h | 1 + - 2 files changed, 11 insertions(+), 10 deletions(-) - -diff --git a/server/object.c b/server/object.c -index d04fdb9..bfb4689 100644 ---- a/server/object.c -+++ b/server/object.c -@@ -44,7 +44,6 @@ struct object_name - { - struct list entry; /* entry in the hash list */ - struct object *obj; /* object owning this name */ -- struct object *parent; /* parent object */ - data_size_t len; /* name length in bytes */ - WCHAR name[1]; - }; -@@ -136,18 +135,15 @@ static struct object_name *alloc_name( const struct unicode_str *name ) - if ((ptr = mem_alloc( sizeof(*ptr) + name->len - sizeof(ptr->name) ))) - { - ptr->len = name->len; -- ptr->parent = NULL; - memcpy( ptr->name, name->str, name->len ); - } - return ptr; - } - - /* free the name of an object */ --static void free_name( struct object *obj ) -+static void free_name( struct object_name *ptr ) - { -- struct object_name *ptr = obj->name; - list_remove( &ptr->entry ); -- if (ptr->parent) release_object( ptr->parent ); - free( ptr ); - } - -@@ -183,7 +179,7 @@ WCHAR *get_object_full_name( struct object *obj, data_size_t *ret_len ) - { - struct object_name *name = ptr->name; - len += name->len + sizeof(WCHAR); -- ptr = name->parent; -+ ptr = ptr->parent; - } - if (!len) return NULL; - if (!(ret = malloc( len ))) return NULL; -@@ -195,7 +191,7 @@ WCHAR *get_object_full_name( struct object *obj, data_size_t *ret_len ) - memcpy( ret + len - name->len, name->name, name->len ); - len -= name->len + sizeof(WCHAR); - memcpy( ret + len, &backslash, sizeof(WCHAR) ); -- obj = name->parent; -+ obj = obj->parent; - } - return (WCHAR *)ret; - } -@@ -208,6 +204,7 @@ void *alloc_object( const struct object_ops *ops ) - { - obj->refcount = 1; - obj->handle_count = 0; -+ obj->parent = NULL; - obj->ops = ops; - obj->name = NULL; - obj->sd = NULL; -@@ -230,7 +227,7 @@ void *create_object( struct namespace *namespace, const struct object_ops *ops, - if ((obj = alloc_object( ops ))) - { - set_object_name( namespace, obj, name_ptr ); -- if (parent) name_ptr->parent = grab_object( parent ); -+ if (parent) obj->parent = grab_object( parent ); - } - else - free( name_ptr ); -@@ -278,8 +275,10 @@ void dump_object_name( struct object *obj ) - /* unlink a named object from its namespace, without freeing the object itself */ - void unlink_named_object( struct object *obj ) - { -- if (obj->name) free_name( obj ); -+ if (obj->name) free_name( obj->name ); -+ if (obj->parent) release_object( obj->parent ); - obj->name = NULL; -+ obj->parent = NULL; - } - - /* mark an object as being stored statically, i.e. only released at shutdown */ -@@ -311,7 +310,8 @@ void release_object( void *ptr ) - /* if the refcount is 0, nobody can be in the wait queue */ - assert( list_empty( &obj->wait_queue )); - obj->ops->destroy( obj ); -- if (obj->name) free_name( obj ); -+ if (obj->name) free_name( obj->name ); -+ if (obj->parent) release_object( obj->parent ); - free( obj->sd ); - #ifdef DEBUG_OBJECTS - list_remove( &obj->obj_list ); -diff --git a/server/object.h b/server/object.h -index 0974d87..9d14c9c 100644 ---- a/server/object.h -+++ b/server/object.h -@@ -96,6 +96,7 @@ struct object - { - unsigned int refcount; /* reference count */ - unsigned int handle_count;/* handle count */ -+ struct object *parent; /* parent object */ - const struct object_ops *ops; - struct list wait_queue; - struct object_name *name; --- -2.5.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Pipe_ObjectName/0001-server-Store-a-reference-to-the-parent-object-for-pi.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Pipe_ObjectName/0001-server-Store-a-reference-to-the-parent-object-for-pi.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Pipe_ObjectName/0001-server-Store-a-reference-to-the-parent-object-for-pi.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Pipe_ObjectName/0001-server-Store-a-reference-to-the-parent-object-for-pi.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,193 @@ +From dea19bf17349a7c1c2398a44e15587dae8fbce44 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Mon, 17 Aug 2015 01:11:47 +0200 +Subject: server: Store a reference to the parent object for pipe servers. (v2) + +--- + dlls/ntdll/tests/om.c | 3 --- + server/named_pipe.c | 45 +++++++++++++++++++++++++++++++++++++-------- + server/object.c | 18 ++++++++++++------ + 3 files changed, 49 insertions(+), 17 deletions(-) + +diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c +index 3d0487c..84507de 100644 +--- a/dlls/ntdll/tests/om.c ++++ b/dlls/ntdll/tests/om.c +@@ -1401,14 +1401,11 @@ static void test_query_object(void) + status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); + ok( status == STATUS_SUCCESS , "NtQueryObject returned %x\n", status ); + str = (UNICODE_STRING *)buffer; +- todo_wine + ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len ); + str = (UNICODE_STRING *)buffer; + expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR); +- todo_wine + ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */ + "unexpected len %u\n", len ); +- todo_wine + ok( len > sizeof(UNICODE_STRING) + sizeof("\\test_pipe") * sizeof(WCHAR), + "name too short %s\n", wine_dbgstr_w(str->Buffer) ); + trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len ); +diff --git a/server/named_pipe.c b/server/named_pipe.c +index ffa9e32..c92a117 100644 +--- a/server/named_pipe.c ++++ b/server/named_pipe.c +@@ -148,6 +148,8 @@ static const struct object_ops named_pipe_ops = + /* server end functions */ + static void pipe_server_dump( struct object *obj, int verbose ); + static struct fd *pipe_server_get_fd( struct object *obj ); ++static int pipe_server_link_name( struct object *obj, struct object_name *name, struct object *parent ); ++static void pipe_server_unlink_name( struct object *obj, struct object_name *name ); + static int pipe_server_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); + static void pipe_server_destroy( struct object *obj); + static obj_handle_t pipe_server_flush( struct fd *fd, const async_data_t *async, int blocking ); +@@ -170,8 +172,8 @@ static const struct object_ops pipe_server_ops = + default_get_sd, /* get_sd */ + default_set_sd, /* set_sd */ + no_lookup_name, /* lookup_name */ +- no_link_name, /* link_name */ +- NULL, /* unlink_name */ ++ pipe_server_link_name, /* link_name */ ++ pipe_server_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ + pipe_server_close_handle, /* close_handle */ +@@ -196,6 +198,8 @@ static const struct fd_ops pipe_server_fd_ops = + static void pipe_client_dump( struct object *obj, int verbose ); + static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *entry ); + static struct fd *pipe_client_get_fd( struct object *obj ); ++static int pipe_client_link_name( struct object *obj, struct object_name *name, struct object *parent ); ++static void pipe_client_unlink_name( struct object *obj, struct object_name *name ); + static int pipe_client_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); + static void pipe_client_destroy( struct object *obj ); + static obj_handle_t pipe_client_flush( struct fd *fd, const async_data_t *async, int blocking ); +@@ -216,8 +220,8 @@ static const struct object_ops pipe_client_ops = + default_get_sd, /* get_sd */ + default_set_sd, /* set_sd */ + no_lookup_name, /* lookup_name */ +- no_link_name, /* link_name */ +- NULL, /* unlink_name */ ++ pipe_client_link_name, /* link_name */ ++ pipe_client_unlink_name, /* unlink_name */ + no_open_file, /* open_file */ + no_alloc_handle, /* alloc_handle */ + pipe_client_close_handle, /* close_handle */ +@@ -399,6 +403,17 @@ static void do_disconnect( struct pipe_server *server ) + server->fd = NULL; + } + ++static int pipe_server_link_name( struct object *obj, struct object_name *name, struct object *parent ) ++{ ++ assert( parent->ops == &named_pipe_ops ); ++ name->parent = grab_object( parent ); ++ return 1; ++} ++ ++static void pipe_server_unlink_name( struct object *obj, struct object_name *name ) ++{ ++} ++ + static int pipe_server_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) + { + #ifdef __linux__ +@@ -442,6 +457,17 @@ static void pipe_server_destroy( struct object *obj) + release_object( server->pipe ); + } + ++static int pipe_client_link_name( struct object *obj, struct object_name *name, struct object *parent ) ++{ ++ assert( parent->ops == &named_pipe_ops ); ++ name->parent = grab_object( parent ); ++ return 1; ++} ++ ++static void pipe_client_unlink_name( struct object *obj, struct object_name *name ) ++{ ++} ++ + static int pipe_client_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) + { + #ifdef __linux__ +@@ -768,9 +794,10 @@ static struct pipe_server *get_pipe_server_obj( struct process *process, + static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned int options, + unsigned int pipe_flags ) + { ++ static const struct unicode_str str = { NULL, 0 }; + struct pipe_server *server; + +- server = alloc_object( &pipe_server_ops ); ++ server = create_object( &pipe->obj, &pipe_server_ops, &str ); + if (!server) + return NULL; + +@@ -792,11 +819,13 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned + return server; + } + +-static struct pipe_client *create_pipe_client( unsigned int flags, unsigned int pipe_flags ) ++static struct pipe_client *create_pipe_client( struct named_pipe *pipe, unsigned int flags, ++ unsigned int pipe_flags ) + { ++ static const struct unicode_str str = { NULL, 0 }; + struct pipe_client *client; + +- client = alloc_object( &pipe_client_ops ); ++ client = create_object( &pipe->obj, &pipe_client_ops, &str ); + if (!client) + return NULL; + +@@ -896,7 +925,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc + return NULL; + } + +- if ((client = create_pipe_client( options, pipe->flags ))) ++ if ((client = create_pipe_client( pipe, options, pipe->flags ))) + { + type = ((pipe->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) && is_messagemode_supported()) ? + SOCK_SEQPACKET : SOCK_STREAM; +diff --git a/server/object.c b/server/object.c +index d4217c0..ef99334 100644 +--- a/server/object.c ++++ b/server/object.c +@@ -162,7 +162,7 @@ WCHAR *get_object_full_name( struct object *obj, data_size_t *ret_len ) + while (ptr && ptr->name) + { + struct object_name *name = ptr->name; +- len += name->len + sizeof(WCHAR); ++ if (name->len) len += name->len + sizeof(WCHAR); + ptr = name->parent; + } + if (!len) return NULL; +@@ -172,9 +172,12 @@ WCHAR *get_object_full_name( struct object *obj, data_size_t *ret_len ) + while (obj && obj->name) + { + struct object_name *name = obj->name; +- memcpy( ret + len - name->len, name->name, name->len ); +- len -= name->len + sizeof(WCHAR); +- memcpy( ret + len, &backslash, sizeof(WCHAR) ); ++ if (name->len) ++ { ++ memcpy( ret + len - name->len, name->name, name->len ); ++ len -= name->len + sizeof(WCHAR); ++ memcpy( ret + len, &backslash, sizeof(WCHAR) ); ++ } + obj = name->parent; + } + return (WCHAR *)ret; +@@ -269,8 +272,11 @@ static void dump_name( struct object *obj ) + + if (!name) return; + if (name->parent) dump_name( name->parent ); +- fputs( "\\\\", stderr ); +- dump_strW( name->name, name->len / sizeof(WCHAR), stderr, "[]" ); ++ if (name->len) ++ { ++ fputs( "\\\\", stderr ); ++ dump_strW( name->name, name->len / sizeof(WCHAR), stderr, "[]" ); ++ } + } + + /* dump the name of an object to stderr */ +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Pipe_ObjectName/0002-server-Link-named-pipes-to-their-device.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Pipe_ObjectName/0002-server-Link-named-pipes-to-their-device.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Pipe_ObjectName/0002-server-Link-named-pipes-to-their-device.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Pipe_ObjectName/0002-server-Link-named-pipes-to-their-device.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -From 8ff87be88de81b45327a9fc0eeacbc357544be20 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 17 Aug 2015 01:10:10 +0200 -Subject: server: Link named pipes to their device. - ---- - server/named_pipe.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/server/named_pipe.c b/server/named_pipe.c -index 53bec02..0ce3e59 100644 ---- a/server/named_pipe.c -+++ b/server/named_pipe.c -@@ -743,7 +743,7 @@ static struct named_pipe *create_named_pipe( struct directory *root, const struc - else - { - struct named_pipe_device *dev = (struct named_pipe_device *)obj; -- if ((pipe = create_object( dev->pipes, &named_pipe_ops, &new_name, NULL ))) -+ if ((pipe = create_object( dev->pipes, &named_pipe_ops, &new_name, &dev->obj ))) - clear_error(); - } - --- -2.5.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Pipe_ObjectName/0003-server-Store-a-reference-to-the-parent-object-for-pi.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Pipe_ObjectName/0003-server-Store-a-reference-to-the-parent-object-for-pi.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Pipe_ObjectName/0003-server-Store-a-reference-to-the-parent-object-for-pi.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Pipe_ObjectName/0003-server-Store-a-reference-to-the-parent-object-for-pi.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -From 84d1dc87366a3f72365b29f490da5bed67998386 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Mon, 17 Aug 2015 01:11:47 +0200 -Subject: server: Store a reference to the parent object for pipe servers. - ---- - server/named_pipe.c | 9 +++++---- - server/object.c | 21 ++++++++++++--------- - 2 files changed, 17 insertions(+), 13 deletions(-) - -diff --git a/server/named_pipe.c b/server/named_pipe.c -index 0ce3e59..283eb2c 100644 ---- a/server/named_pipe.c -+++ b/server/named_pipe.c -@@ -764,7 +764,7 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned - { - struct pipe_server *server; - -- server = alloc_object( &pipe_server_ops ); -+ server = create_object( NULL, &pipe_server_ops, NULL, &pipe->obj ); - if (!server) - return NULL; - -@@ -786,11 +786,12 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned - return server; - } - --static struct pipe_client *create_pipe_client( unsigned int flags, unsigned int pipe_flags ) -+static struct pipe_client *create_pipe_client( struct named_pipe *pipe, unsigned int flags, -+ unsigned int pipe_flags ) - { - struct pipe_client *client; - -- client = alloc_object( &pipe_client_ops ); -+ client = create_object( NULL, &pipe_client_ops, NULL, &pipe->obj ); - if (!client) - return NULL; - -@@ -876,7 +877,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc - return NULL; - } - -- if ((client = create_pipe_client( options, pipe->flags ))) -+ if ((client = create_pipe_client( pipe, options, pipe->flags ))) - { - type = ((pipe->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) && is_messagemode_supported()) ? - SOCK_SEQPACKET : SOCK_STREAM; -diff --git a/server/object.c b/server/object.c -index bfb4689..5f16046 100644 ---- a/server/object.c -+++ b/server/object.c -@@ -175,22 +175,25 @@ WCHAR *get_object_full_name( struct object *obj, data_size_t *ret_len ) - data_size_t len = 0; - char *ret; - -- while (ptr && ptr->name) -+ while (ptr) - { - struct object_name *name = ptr->name; -- len += name->len + sizeof(WCHAR); -+ if (name) len += name->len + sizeof(WCHAR); - ptr = ptr->parent; - } - if (!len) return NULL; - if (!(ret = malloc( len ))) return NULL; - - *ret_len = len; -- while (obj && obj->name) -+ while (obj) - { - struct object_name *name = obj->name; -- memcpy( ret + len - name->len, name->name, name->len ); -- len -= name->len + sizeof(WCHAR); -- memcpy( ret + len, &backslash, sizeof(WCHAR) ); -+ if (name) -+ { -+ memcpy( ret + len - name->len, name->name, name->len ); -+ len -= name->len + sizeof(WCHAR); -+ memcpy( ret + len, &backslash, sizeof(WCHAR) ); -+ } - obj = obj->parent; - } - return (WCHAR *)ret; -@@ -220,13 +223,13 @@ void *alloc_object( const struct object_ops *ops ) - void *create_object( struct namespace *namespace, const struct object_ops *ops, - const struct unicode_str *name, struct object *parent ) - { -+ struct object_name *name_ptr = NULL; - struct object *obj; -- struct object_name *name_ptr; - -- if (!(name_ptr = alloc_name( name ))) return NULL; -+ if (namespace && !(name_ptr = alloc_name( name ))) return NULL; - if ((obj = alloc_object( ops ))) - { -- set_object_name( namespace, obj, name_ptr ); -+ if (namespace) set_object_name( namespace, obj, name_ptr ); - if (parent) obj->parent = grab_object( parent ); - } - else --- -2.5.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Shared_Memory/0002-server-Implement-support-for-global-and-local-shared.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Shared_Memory/0002-server-Implement-support-for-global-and-local-shared.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Shared_Memory/0002-server-Implement-support-for-global-and-local-shared.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Shared_Memory/0002-server-Implement-support-for-global-and-local-shared.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 0514f064febfdfdd9321c03793e996b6989fb3d0 Mon Sep 17 00:00:00 2001 +From 0d5c923e97bebd777846bfb736319646f248e01a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Thu, 19 Mar 2015 01:22:34 +0100 Subject: server: Implement support for global and local shared memory blocks @@ -20,19 +20,19 @@ 12 files changed, 215 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h -index 7eded42..79cc2c1 100644 +index 6e24ac3..7fe8189 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h -@@ -97,6 +97,7 @@ extern int server_remove_fd_from_cache( HANDLE handle ) DECLSPEC_HIDDEN; - extern int server_get_unix_fd( HANDLE handle, unsigned int access, int *unix_fd, - int *needs_close, enum server_fd_type *type, unsigned int *options ) DECLSPEC_HIDDEN; - extern int server_pipe( int fd[2] ) DECLSPEC_HIDDEN; +@@ -100,6 +100,7 @@ extern int server_pipe( int fd[2] ) DECLSPEC_HIDDEN; + extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret, + data_size_t *ret_len ) DECLSPEC_HIDDEN; + extern NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN; +extern void *server_get_shared_memory( HANDLE thread ) DECLSPEC_HIDDEN; - /* security descriptors */ - NTSTATUS NTDLL_create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_descriptor **server_sd, + /* module handling */ + extern LIST_ENTRY tls_links DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c -index 95111ad..955c392 100644 +index 356d631..a91e478 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -972,6 +972,66 @@ done: @@ -114,7 +114,7 @@ ntdll_get_thread_data()->wow64_redir = is_wow64; diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c -index 7633232..c56ee1d 100644 +index 08275dd..ce19a34 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -376,6 +376,7 @@ void terminate_thread( int status ) @@ -158,7 +158,7 @@ /* macros for server requests */ diff --git a/include/winternl.h b/include/winternl.h -index 5420391..624da00 100644 +index 51320f2..5d0aa54 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -366,7 +366,7 @@ typedef struct _TEB @@ -171,10 +171,10 @@ ULONG ImpersonationLocale; /* f98/1788 */ ULONG IsImpersonating; /* f9c/178c */ diff --git a/server/fd.c b/server/fd.c -index fe778f1..f6f9b42 100644 +index 559a737..603cef4 100644 --- a/server/fd.c +++ b/server/fd.c -@@ -2472,6 +2472,33 @@ DECL_HANDLER(write) +@@ -2481,6 +2481,33 @@ DECL_HANDLER(write) } } @@ -240,7 +240,7 @@ return 0; } diff --git a/server/mapping.c b/server/mapping.c -index 16e7c1c..c180ae5 100644 +index f66f326..75fda15 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -29,8 +29,32 @@ @@ -341,7 +341,7 @@ static int create_temp_file( file_pos_t size ) { diff --git a/server/protocol.def b/server/protocol.def -index c313006..b8c5abf 100644 +index a5a45eb..7c61b76 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -69,6 +69,15 @@ struct request_max_size @@ -360,7 +360,7 @@ /* debug event data */ typedef union -@@ -1203,6 +1212,12 @@ enum server_fd_type +@@ -1200,6 +1209,12 @@ enum server_fd_type }; @@ -374,7 +374,7 @@ @REQ(flush) int blocking; /* whether it's a blocking flush */ diff --git a/server/thread.c b/server/thread.c -index ba84bee..4bb5149 100644 +index 251be1c..198c371 100644 --- a/server/thread.c +++ b/server/thread.c @@ -196,6 +196,8 @@ static inline void init_thread_structure( struct thread *thread ) @@ -419,5 +419,5 @@ struct thread_snapshot -- -2.6.1 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Stored_ACLs/0004-server-Temporarily-store-the-full-security-descripto.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Stored_ACLs/0004-server-Temporarily-store-the-full-security-descripto.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Stored_ACLs/0004-server-Temporarily-store-the-full-security-descripto.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Stored_ACLs/0004-server-Temporarily-store-the-full-security-descripto.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,21 +1,21 @@ -From 2884ad4a99443701819564254dc21289d6f13aec Mon Sep 17 00:00:00 2001 +From 04bdbb48453d5575e42d6dc5b9caa89a141167c1 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 30 Mar 2015 12:50:21 +0200 Subject: server: Temporarily store the full security descriptor for file objects. --- - dlls/advapi32/tests/security.c | 15 +++---- + dlls/advapi32/tests/security.c | 16 +++----- server/change.c | 8 +++- server/file.c | 88 ++++++++++++++++++++++++++++-------------- server/file.h | 3 +- - 4 files changed, 74 insertions(+), 40 deletions(-) + 4 files changed, 74 insertions(+), 41 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index 40cf23c..57adc4e 100644 +index f34831d..b149ea4 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c -@@ -3311,7 +3311,6 @@ static void test_CreateDirectoryA(void) +@@ -3350,7 +3350,6 @@ static void test_CreateDirectoryA(void) ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok(bret, "GetAclInformation failed\n"); @@ -23,7 +23,7 @@ ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", acl_size.AceCount); LocalFree(pSD); -@@ -3387,7 +3386,6 @@ static void test_CreateDirectoryA(void) +@@ -3426,7 +3425,6 @@ static void test_CreateDirectoryA(void) ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok(bret, "GetAclInformation failed\n"); @@ -31,7 +31,7 @@ ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", acl_size.AceCount); LocalFree(pSD); -@@ -3533,7 +3531,6 @@ static void test_CreateDirectoryA(void) +@@ -3572,7 +3570,6 @@ static void test_CreateDirectoryA(void) ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok(bret, "GetAclInformation failed\n"); @@ -39,12 +39,13 @@ ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", acl_size.AceCount); LocalFree(pSD); -@@ -4508,22 +4505,22 @@ static void test_GetSecurityInfo(void) +@@ -4552,23 +4549,22 @@ static void test_GetSecurityInfo(void) bret = pGetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get Current User ACE.\n"); bret = EqualSid(&ace->SidStart, user_sid); -- todo_wine ok(bret, "Current User ACE != Current User SID.\n"); -+ ok(bret, "Current User ACE != Current User SID.\n"); +- todo_wine ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", +- debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); ++ ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); - ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", @@ -57,8 +58,8 @@ bret = pGetAce(pDacl, 1, (VOID **)&ace); ok(bret, "Failed to get Administators Group ACE.\n"); bret = EqualSid(&ace->SidStart, admin_sid); -- todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n"); -+ ok(bret, "Administators Group ACE != Administators Group SID.\n"); +- todo_wine ok(bret, "Administators Group ACE (%s) != Administators Group SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); ++ ok(bret, "Administators Group ACE (%s) != Administators Group SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); - ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", @@ -69,10 +70,10 @@ LocalFree(pSD); CloseHandle(obj); diff --git a/server/change.c b/server/change.c -index b334fd1..2e98f5c 100644 +index b3ee681..a631925 100644 --- a/server/change.c +++ b/server/change.c -@@ -1022,7 +1022,8 @@ static int dir_add_to_existing_notify( struct dir *dir ) +@@ -1030,7 +1030,8 @@ static int dir_add_to_existing_notify( struct dir *dir ) #endif /* USE_INOTIFY */ @@ -82,7 +83,7 @@ { struct dir *dir; -@@ -1041,6 +1042,11 @@ struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode ) +@@ -1049,6 +1050,11 @@ struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode ) dir->uid = ~(uid_t)0; set_fd_user( fd, &dir_fd_ops, &dir->obj ); @@ -95,10 +96,10 @@ return &dir->obj; diff --git a/server/file.c b/server/file.c -index 011c29f..175fbce 100644 +index a684a77..fb78559 100644 --- a/server/file.c +++ b/server/file.c -@@ -172,7 +172,8 @@ struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigne +@@ -173,7 +173,8 @@ struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigne return file; } @@ -108,7 +109,7 @@ { struct file *file = alloc_object( &file_ops ); -@@ -183,6 +184,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_ +@@ -184,6 +185,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_ file->fd = fd; grab_object( fd ); set_fd_user( fd, &file_fd_ops, &file->obj ); @@ -121,7 +122,7 @@ return &file->obj; } -@@ -249,11 +256,11 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si +@@ -250,11 +257,11 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si if (!fd) goto done; if (S_ISDIR(mode)) @@ -135,7 +136,7 @@ release_object( fd ); -@@ -562,46 +569,66 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) +@@ -570,46 +577,66 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid, const struct security_descriptor *sd, unsigned int set_info ) { @@ -227,15 +228,15 @@ } static struct object *file_open_file( struct object *obj, unsigned int access, -@@ -733,7 +760,10 @@ DECL_HANDLER(create_file) +@@ -737,7 +764,10 @@ DECL_HANDLER(create_file) if ((file = create_file( root_fd, name, name_len, req->access, req->sharing, req->create, req->options, req->attrs, sd ))) { -- reply->handle = alloc_handle( current->process, file, req->access, req->attributes ); +- reply->handle = alloc_handle( current->process, file, req->access, objattr->attributes ); + if (get_error() == STATUS_OBJECT_NAME_EXISTS) -+ reply->handle = alloc_handle( current->process, file, req->access, req->attributes ); ++ reply->handle = alloc_handle( current->process, file, req->access, objattr->attributes ); + else -+ reply->handle = alloc_handle_no_access_check( current->process, file, req->access, req->attributes ); ++ reply->handle = alloc_handle_no_access_check( current->process, file, req->access, objattr->attributes ); release_object( file ); } if (root_fd) release_object( root_fd ); @@ -254,5 +255,5 @@ /* completion */ -- -2.4.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 5c19cb0685dd47e7eb36dce9729200b79da61b11 Mon Sep 17 00:00:00 2001 +From 93fd1bb452f2d64ee0827b3d53221040cdb4b6b5 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Fri, 18 Apr 2014 14:05:32 -0600 Subject: server: Convert return of file security masks with generic access @@ -10,11 +10,11 @@ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index f7ae089..0013c3c 100644 +index b149ea4..f4238c7 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c -@@ -4501,8 +4501,8 @@ static void test_GetSecurityInfo(void) - ok(bret, "Current User ACE != Current User SID.\n"); +@@ -4552,8 +4552,8 @@ static void test_GetSecurityInfo(void) + ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); - todo_wine ok(ace->Mask == 0x1f01ff, @@ -24,8 +24,8 @@ } if (acl_size.AceCount > 1) { -@@ -4512,7 +4512,7 @@ static void test_GetSecurityInfo(void) - ok(bret, "Administators Group ACE != Administators Group SID.\n"); +@@ -4563,7 +4563,7 @@ static void test_GetSecurityInfo(void) + ok(bret, "Administators Group ACE (%s) != Administators Group SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); - todo_wine ok(ace->Mask == 0x1f01ff, @@ -34,10 +34,10 @@ } LocalFree(pSD); diff --git a/server/file.c b/server/file.c -index ed7ddfc..6663927 100644 +index 55551bc..703479f 100644 --- a/server/file.c +++ b/server/file.c -@@ -466,6 +466,26 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID +@@ -479,6 +479,26 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID return sd; } @@ -64,7 +64,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid ) { -@@ -608,6 +628,9 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid, +@@ -621,6 +641,9 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid, new_sd = set_sd_from_token_internal( sd, obj->sd, set_info, current->process->token ); if (new_sd) { @@ -75,5 +75,5 @@ { owner = sd_get_owner( new_sd ); -- -2.3.5 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Stored_ACLs/0007-server-Retrieve-file-security-attributes-with-extend.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Stored_ACLs/0007-server-Retrieve-file-security-attributes-with-extend.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Stored_ACLs/0007-server-Retrieve-file-security-attributes-with-extend.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Stored_ACLs/0007-server-Retrieve-file-security-attributes-with-extend.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,19 +1,19 @@ -From ea6969acf3f5e79a39bb461f78b4f0785a2b8843 Mon Sep 17 00:00:00 2001 +From 212dc266153f4c782ad4855720cc5b377f35c0ad Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Fri, 18 Apr 2014 14:01:35 -0600 Subject: server: Retrieve file security attributes with extended file attributes. (try 7) --- - dlls/advapi32/tests/security.c | 15 +++++++-------- + dlls/advapi32/tests/security.c | 19 +++++++++---------- server/file.c | 30 +++++++++++++++++++++++++++--- - 2 files changed, 34 insertions(+), 11 deletions(-) + 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index 0013c3c..945542e 100644 +index f4238c7..79a9df4 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c -@@ -3264,7 +3264,7 @@ static void test_CreateDirectoryA(void) +@@ -3303,7 +3303,7 @@ static void test_CreateDirectoryA(void) } ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, @@ -22,12 +22,14 @@ LocalFree(pSD); /* Test inheritance of ACLs in CreateFile without security descriptor */ -@@ -3719,19 +3719,18 @@ static void test_GetNamedSecurityInfoA(void) +@@ -3758,21 +3758,20 @@ static void test_GetNamedSecurityInfoA(void) bret = pGetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get Current User ACE.\n"); bret = EqualSid(&ace->SidStart, user_sid); -- todo_wine ok(bret, "Current User ACE != Current User SID.\n"); -+ ok(bret, "Current User ACE != Current User SID.\n"); +- todo_wine ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", +- debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); ++ ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", ++ debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); - ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", @@ -41,12 +43,14 @@ ok(bret, "Failed to get Administators Group ACE.\n"); bret = EqualSid(&ace->SidStart, admin_sid); - todo_wine ok(bret || broken(!bret) /* win2k */, -- "Administators Group ACE != Administators Group SID.\n"); -+ ok(bret || broken(!bret) /* win2k */, "Administators Group ACE != Administators Group SID.\n"); +- "Administators Group ACE (%s) != Administators Group SID (%s).\n", +- debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); ++ ok(bret || broken(!bret) /* win2k */, "Administators Group ACE (%s) != Administators Group SID (%s).\n", ++ debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */, -@@ -3758,8 +3757,8 @@ static void test_GetNamedSecurityInfoA(void) +@@ -3799,8 +3798,8 @@ static void test_GetNamedSecurityInfoA(void) { bret = pGetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get ACE.\n"); @@ -58,10 +62,10 @@ LocalFree(pSD); diff --git a/server/file.c b/server/file.c -index 6663927..8bcf6ee 100644 +index 703479f..78eef58 100644 --- a/server/file.c +++ b/server/file.c -@@ -486,6 +486,29 @@ static void convert_generic_sd( struct security_descriptor *sd ) +@@ -499,6 +499,29 @@ static void convert_generic_sd( struct security_descriptor *sd ) } } @@ -91,7 +95,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid ) { -@@ -501,9 +524,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode +@@ -514,9 +537,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode (st.st_uid == *uid)) return obj->sd; @@ -106,5 +110,5 @@ *mode = st.st_mode; -- -2.3.5 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Win8_Pseudo_Handles/0001-server-Implement-support-for-pseudo-tokens-CurrentPr.patch wine-staging-1.9.3~ubuntu12.04.1/patches/server-Win8_Pseudo_Handles/0001-server-Implement-support-for-pseudo-tokens-CurrentPr.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Win8_Pseudo_Handles/0001-server-Implement-support-for-pseudo-tokens-CurrentPr.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Win8_Pseudo_Handles/0001-server-Implement-support-for-pseudo-tokens-CurrentPr.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,126 @@ +From e68fdb7c4406d7b01a653480e28153c0e2c87bbf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 17 Jan 2016 20:32:28 +0100 +Subject: server: Implement support for pseudo tokens CurrentProcessToken, + CurrentThreadToken, CurrentThreadEffectiveToken. + +--- + dlls/advapi32/tests/security.c | 52 ++++++++++++++++++++++++++++++++++++++++++ + include/winbase.h | 15 ++++++++++++ + server/handle.c | 6 +++++ + 3 files changed, 73 insertions(+) + +diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c +index c71e6fe..a3d194c 100644 +--- a/dlls/advapi32/tests/security.c ++++ b/dlls/advapi32/tests/security.c +@@ -6070,6 +6070,57 @@ static void test_GetSidIdentifierAuthority(void) + ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", GetLastError()); + } + ++static void test_pseudo_tokens(void) ++{ ++ TOKEN_STATISTICS statistics1, statistics2; ++ HANDLE token; ++ DWORD retlen; ++ BOOL ret; ++ ++ ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); ++ ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); ++ memset(&statistics1, 0x11, sizeof(statistics1)); ++ ret = GetTokenInformation(token, TokenStatistics, &statistics1, sizeof(statistics1), &retlen); ++ ok(ret, "GetTokenInformation failed with %u\n", GetLastError()); ++ CloseHandle(token); ++ ++ /* test GetCurrentProcessToken() */ ++ SetLastError(0xdeadbeef); ++ memset(&statistics2, 0x22, sizeof(statistics2)); ++ ret = GetTokenInformation(GetCurrentProcessToken(), TokenStatistics, ++ &statistics2, sizeof(statistics2), &retlen); ++ ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE), ++ "GetTokenInformation failed with %u\n", GetLastError()); ++ if (ret) ++ ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics are not equal\n"); ++ else ++ win_skip("Failed to get information about pseudo process token, skipping comparison\n"); ++ ++ /* test GetCurrentThreadEffectiveToken() */ ++ SetLastError(0xdeadbeef); ++ memset(&statistics2, 0x22, sizeof(statistics2)); ++ ret = GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenStatistics, ++ &statistics2, sizeof(statistics2), &retlen); ++ ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE), ++ "GetTokenInformation failed with %u\n", GetLastError()); ++ if (ret) ++ ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics are not equal\n"); ++ else ++ win_skip("Failed to get information about pseudo effective thread token, skipping comparison\n"); ++ ++ SetLastError(0xdeadbeef); ++ ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token); ++ ok(!ret, "OpenThreadToken should have failed\n"); ++ ok(GetLastError() == ERROR_NO_TOKEN, "Expected ERROR_NO_TOKEN, got %u\n", GetLastError()); ++ ++ /* test GetCurrentThreadToken() */ ++ SetLastError(0xdeadbeef); ++ ret = GetTokenInformation(GetCurrentThreadToken(), TokenStatistics, ++ &statistics2, sizeof(statistics2), &retlen); ++ todo_wine ok(GetLastError() == ERROR_NO_TOKEN || broken(GetLastError() == ERROR_INVALID_HANDLE), ++ "Expected ERROR_NO_TOKEN, got %u\n", GetLastError()); ++} ++ + START_TEST(security) + { + init(); +@@ -6115,4 +6166,5 @@ START_TEST(security) + test_AddAce(); + test_system_security_access(); + test_GetSidIdentifierAuthority(); ++ test_pseudo_tokens(); + } +diff --git a/include/winbase.h b/include/winbase.h +index f35391d..f5c2557 100644 +--- a/include/winbase.h ++++ b/include/winbase.h +@@ -2973,6 +2973,21 @@ WINBASEAPI VOID WINAPI SetLastError(DWORD); + #define GetCurrentThread() ((HANDLE)~(ULONG_PTR)1) + #endif + ++static FORCEINLINE HANDLE GetCurrentProcessToken(void) ++{ ++ return (HANDLE)~(LONG_PTR)3; ++} ++ ++static FORCEINLINE HANDLE GetCurrentThreadToken(void) ++{ ++ return (HANDLE)~(LONG_PTR)4; ++} ++ ++static FORCEINLINE HANDLE GetCurrentThreadEffectiveToken(void) ++{ ++ return (HANDLE)~(LONG_PTR)5; ++} ++ + /* WinMain(entry point) must be declared in winbase.h. */ + /* If this is not declared, we cannot compile many sources written with C++. */ + int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int); +diff --git a/server/handle.c b/server/handle.c +index 05d71ba..76e1cca 100644 +--- a/server/handle.c ++++ b/server/handle.c +@@ -402,6 +402,12 @@ static inline struct object *get_magic_handle( obj_handle_t handle ) + { + switch(handle) + { ++ case 0xfffffffa: /* current thread impersonation token pseudo-handle */ ++ return (struct object *)thread_get_impersonation_token( current ); ++ case 0xfffffffb: /* current thread token pseudo-handle */ ++ return (struct object *)current->token; ++ case 0xfffffffc: /* current process token pseudo-handle */ ++ return (struct object *)current->process->token; + case 0xfffffffe: /* current thread pseudo-handle */ + return ¤t->obj; + case 0x7fffffff: /* current process pseudo-handle */ +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/server-Win8_Pseudo_Handles/definition wine-staging-1.9.3~ubuntu12.04.1/patches/server-Win8_Pseudo_Handles/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/server-Win8_Pseudo_Handles/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/server-Win8_Pseudo_Handles/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Implement support for Win8+ process/thread token pseudo handles diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/shell32-SFGAO_HASSUBFOLDER/0001-shell32-Set-SFGAO_HASSUBFOLDER-correctly-for-unixfs.patch wine-staging-1.9.3~ubuntu12.04.1/patches/shell32-SFGAO_HASSUBFOLDER/0001-shell32-Set-SFGAO_HASSUBFOLDER-correctly-for-unixfs.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/shell32-SFGAO_HASSUBFOLDER/0001-shell32-Set-SFGAO_HASSUBFOLDER-correctly-for-unixfs.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/shell32-SFGAO_HASSUBFOLDER/0001-shell32-Set-SFGAO_HASSUBFOLDER-correctly-for-unixfs.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,18 +1,18 @@ -From d9a2ea5065ced402ffe4551d7d863450310c1978 Mon Sep 17 00:00:00 2001 +From e86e14d9db9067fa0312470ac1c8363171e57837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sat, 15 Aug 2015 21:09:22 +0200 Subject: shell32: Set SFGAO_HASSUBFOLDER correctly for unixfs. --- - dlls/shell32/shfldr_unixfs.c | 26 ++++++++++++++++++++++---- - 1 file changed, 22 insertions(+), 4 deletions(-) + dlls/shell32/shfldr_unixfs.c | 25 +++++++++++++++++++++---- + 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c -index b3b0214..dbc71f2 100644 +index be1ba81..481ee06 100644 --- a/dlls/shell32/shfldr_unixfs.c +++ b/dlls/shell32/shfldr_unixfs.c @@ -1143,8 +1143,10 @@ static HRESULT WINAPI ShellFolder2_GetAttributesOf(IShellFolder2* iface, UINT ci - SFGAO_HASPROPSHEET|SFGAO_DROPTARGET|SFGAO_FILESYSTEM; + SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | SFGAO_FILESYSTEM; lstrcpyA(szAbsolutePath, This->m_pszPath); pszRelativePath = szAbsolutePath + lstrlenA(szAbsolutePath); - for (i=0; i Date: Mon, 17 Feb 2014 11:52:46 +0900 Subject: shell32: Implement SHCreateSessionKey. @@ -6,12 +6,13 @@ This implementation is based on the Geoff Chappell description, and it seems to be enough for the application I have here. --- - dlls/shell32/shell32.spec | 1 + - dlls/shell32/shellreg.c | 41 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 42 insertions(+) + dlls/shell32/shell32.spec | 1 + + dlls/shell32/shellreg.c | 41 +++++++++++++++++++++++++++++++++++++++++ + dlls/shell32/tests/shellole.c | 4 ++-- + 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec -index d73dcbb..ff1b522 100644 +index 93fd449..abbe6d2 100644 --- a/dlls/shell32/shell32.spec +++ b/dlls/shell32/shell32.spec @@ -261,6 +261,7 @@ @@ -71,6 +72,21 @@ + TRACE("using session key %s\n", debugstr_w(session_reg_str)); + return RegOpenKeyExW(HKEY_CURRENT_USER, session_reg_str, 0, access, hkey); +} +diff --git a/dlls/shell32/tests/shellole.c b/dlls/shell32/tests/shellole.c +index e8cf744..91125c0 100644 +--- a/dlls/shell32/tests/shellole.c ++++ b/dlls/shell32/tests/shellole.c +@@ -876,8 +876,8 @@ if (0) /* crashes on native */ + + hkey = (HKEY)0xdeadbeef; + hr = pSHCreateSessionKey(0, &hkey); +- ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr); +- ok(hkey == NULL, "got %p\n", hkey); ++ todo_wine ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr); ++ todo_wine ok(hkey == NULL, "got %p\n", hkey); + + hr = pSHCreateSessionKey(KEY_READ, &hkey); + ok(hr == S_OK, "got 0x%08x\n", hr); -- -1.7.9.5 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/stdole32.idl-Typelib/0001-include-Make-stdole32.idl-a-public-component.patch wine-staging-1.9.3~ubuntu12.04.1/patches/stdole32.idl-Typelib/0001-include-Make-stdole32.idl-a-public-component.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/stdole32.idl-Typelib/0001-include-Make-stdole32.idl-a-public-component.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/stdole32.idl-Typelib/0001-include-Make-stdole32.idl-a-public-component.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,304 @@ +From 2db7b6af860b34134a0a1177fd5628f8cc6506cc Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 22 Jan 2016 17:40:43 +0800 +Subject: include: Make stdole32.idl a public component. + +This makes it possible to import stdole32.tlb from other .idl files. +--- + dlls/stdole32.tlb/std_ole_v1.idl | 119 +------------------------------- + include/Makefile.in | 1 + + include/stdole32.idl | 143 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 145 insertions(+), 118 deletions(-) + create mode 100644 include/stdole32.idl + +diff --git a/dlls/stdole32.tlb/std_ole_v1.idl b/dlls/stdole32.tlb/std_ole_v1.idl +index 359a810..de053e9 100644 +--- a/dlls/stdole32.tlb/std_ole_v1.idl ++++ b/dlls/stdole32.tlb/std_ole_v1.idl +@@ -20,121 +20,4 @@ + + #pragma makedep regtypelib + +-[ +- uuid(00020430-0000-0000-C000-000000000046), +- restricted, +- version(1.0), +- helpstring("OLE Automation") +-] +-library stdole +-{ +- /* typedefs aren't stored in the type library. +- These type names are known by the type compiler so it +- doesn't really matter what we define them as. */ +- +- typedef void *VARIANT; +- typedef wchar_t *BSTR; +- typedef unsigned long SCODE; +- typedef unsigned long HRESULT; +- +- typedef struct GUID { +- unsigned long Data1; +- unsigned short Data2; +- unsigned short Data3; +- unsigned char Data4[ 8 ]; +- } GUID; +- +- typedef struct DISPPARAMS { +- VARIANT *rgvarg; +- long *rgdispidNamedArgs; +- unsigned int cArgs; +- unsigned int cNamedArgs; +- } DISPPARAMS; +- +- typedef struct EXCEPINFO { +- unsigned short wCode; +- unsigned short wReserved; +- BSTR bstrSource; +- BSTR bstrDescription; +- BSTR bstrHelpFile; +- unsigned long dwHelpContext; +- void *pvReserved; +- void *pfnDeferredFillIn; +- SCODE scode; +- } EXCEPINFO; +- +- [ +- odl, +- uuid(00000000-0000-0000-C000-000000000046) +- ] +- interface IUnknown +- { +- [restricted] +- HRESULT QueryInterface( +- [in] GUID *riid, +- [out] void **ppvObj); +- +- [restricted] +- unsigned long AddRef(); +- +- [restricted] +- unsigned long Release(); +- } +- +- [ +- odl, +- uuid(00020400-0000-0000-C000-000000000046) +- ] +- interface IDispatch : IUnknown +- { +- [restricted] +- HRESULT GetTypeInfoCount( +- [out] unsigned int *pctinfo); +- +- [restricted] +- HRESULT GetTypeInfo( +- [in] unsigned int itinfo, +- [in] unsigned long lcid, +- [out] void **pptinfo); +- +- [restricted] +- HRESULT GetIDsOfNames( +- [in] GUID *riid, +- [in] char **rgszNames, +- [in] unsigned int cNames, +- [in] unsigned long lcid, +- [out] long *rgdispid); +- +- [restricted] +- HRESULT Invoke( +- [in] long dispidMember, +- [in] GUID *riid, +- [in] unsigned long lcid, +- [in] unsigned short wFlags, +- [in] DISPPARAMS *pdispparams, +- [out] VARIANT *pvarResult, +- [out] EXCEPINFO *pexcepinfo, +- [out] unsigned int *puArgErr); +- +- } +- +- [ +- odl, +- uuid(00020404-0000-0000-C000-000000000046) +- ] +- interface IEnumVARIANT : IUnknown +- { +- HRESULT Next( +- [in] unsigned long celt, +- [in] VARIANT *rgvar, +- [out] unsigned long *pceltFetched); +- +- HRESULT Skip( +- [in] unsigned long celt); +- +- HRESULT Reset(); +- +- HRESULT Clone( +- [out] IEnumVARIANT **ppenum); +- } +-}; ++#include "stdole32.idl" +diff --git a/include/Makefile.in b/include/Makefile.in +index 129ff6d..c15544a 100644 +--- a/include/Makefile.in ++++ b/include/Makefile.in +@@ -140,6 +140,7 @@ IDL_SRCS = \ + shtypes.idl \ + srcrst.idl \ + stdole2.idl \ ++ stdole32.idl \ + strmif.idl \ + structuredquerycondition.idl \ + taskschd.idl \ +diff --git a/include/stdole32.idl b/include/stdole32.idl +new file mode 100644 +index 0000000..107cee8 +--- /dev/null ++++ b/include/stdole32.idl +@@ -0,0 +1,143 @@ ++/* ++ * Copyright (C) 2003 Robert Shearman ++ * 2005 Huw Davies ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ * ++ */ ++ ++#if 0 ++#pragma makedep install ++#pragma makedep typelib ++#endif ++ ++[ ++ uuid(00020430-0000-0000-C000-000000000046), ++ restricted, ++ version(1.0), ++ helpstring("OLE Automation") ++] ++library stdole ++{ ++ /* typedefs aren't stored in the type library. ++ These type names are known by the type compiler so it ++ doesn't really matter what we define them as. */ ++ ++ typedef void *VARIANT; ++ typedef wchar_t *BSTR; ++ typedef unsigned long SCODE; ++ typedef unsigned long HRESULT; ++ ++ typedef struct GUID { ++ unsigned long Data1; ++ unsigned short Data2; ++ unsigned short Data3; ++ unsigned char Data4[ 8 ]; ++ } GUID; ++ ++ typedef struct DISPPARAMS { ++ VARIANT *rgvarg; ++ long *rgdispidNamedArgs; ++ unsigned int cArgs; ++ unsigned int cNamedArgs; ++ } DISPPARAMS; ++ ++ typedef struct EXCEPINFO { ++ unsigned short wCode; ++ unsigned short wReserved; ++ BSTR bstrSource; ++ BSTR bstrDescription; ++ BSTR bstrHelpFile; ++ unsigned long dwHelpContext; ++ void *pvReserved; ++ void *pfnDeferredFillIn; ++ SCODE scode; ++ } EXCEPINFO; ++ ++ [ ++ odl, ++ uuid(00000000-0000-0000-C000-000000000046) ++ ] ++ interface IUnknown ++ { ++ [restricted] ++ HRESULT QueryInterface( ++ [in] GUID *riid, ++ [out] void **ppvObj); ++ ++ [restricted] ++ unsigned long AddRef(); ++ ++ [restricted] ++ unsigned long Release(); ++ } ++ ++ [ ++ odl, ++ uuid(00020400-0000-0000-C000-000000000046) ++ ] ++ interface IDispatch : IUnknown ++ { ++ [restricted] ++ HRESULT GetTypeInfoCount( ++ [out] unsigned int *pctinfo); ++ ++ [restricted] ++ HRESULT GetTypeInfo( ++ [in] unsigned int itinfo, ++ [in] unsigned long lcid, ++ [out] void **pptinfo); ++ ++ [restricted] ++ HRESULT GetIDsOfNames( ++ [in] GUID *riid, ++ [in] char **rgszNames, ++ [in] unsigned int cNames, ++ [in] unsigned long lcid, ++ [out] long *rgdispid); ++ ++ [restricted] ++ HRESULT Invoke( ++ [in] long dispidMember, ++ [in] GUID *riid, ++ [in] unsigned long lcid, ++ [in] unsigned short wFlags, ++ [in] DISPPARAMS *pdispparams, ++ [out] VARIANT *pvarResult, ++ [out] EXCEPINFO *pexcepinfo, ++ [out] unsigned int *puArgErr); ++ ++ } ++ ++ [ ++ odl, ++ uuid(00020404-0000-0000-C000-000000000046) ++ ] ++ interface IEnumVARIANT : IUnknown ++ { ++ HRESULT Next( ++ [in] unsigned long celt, ++ [in] VARIANT *rgvar, ++ [out] unsigned long *pceltFetched); ++ ++ HRESULT Skip( ++ [in] unsigned long celt); ++ ++ HRESULT Reset(); ++ ++ HRESULT Clone( ++ [out] IEnumVARIANT **ppenum); ++ } ++}; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/stdole32.tlb-SLTG_Typelib/0020-stdole32.tlb-Compile-typelib-with-oldtlb.patch wine-staging-1.9.3~ubuntu12.04.1/patches/stdole32.tlb-SLTG_Typelib/0020-stdole32.tlb-Compile-typelib-with-oldtlb.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/stdole32.tlb-SLTG_Typelib/0020-stdole32.tlb-Compile-typelib-with-oldtlb.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/stdole32.tlb-SLTG_Typelib/0020-stdole32.tlb-Compile-typelib-with-oldtlb.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,22 @@ +From a004652281da81bace202bed4fe451f1d60f83f0 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 21 Jan 2016 02:53:22 +0100 +Subject: stdole32.tlb: Compile typelib with --oldtlb. + +--- + dlls/stdole32.tlb/Makefile.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/stdole32.tlb/Makefile.in b/dlls/stdole32.tlb/Makefile.in +index 6422325..226235a 100644 +--- a/dlls/stdole32.tlb/Makefile.in ++++ b/dlls/stdole32.tlb/Makefile.in +@@ -1,4 +1,5 @@ + MODULE = stdole32.tlb ++EXTRAIDLFLAGS = --oldtlb + + RC_SRCS = rsrc.rc + IDL_SRCS = std_ole_v1.idl +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/stdole32.tlb-SLTG_Typelib/definition wine-staging-1.9.3~ubuntu12.04.1/patches/stdole32.tlb-SLTG_Typelib/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/stdole32.tlb-SLTG_Typelib/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/stdole32.tlb-SLTG_Typelib/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,2 @@ +Fixes: [3689] Compile stdole32.tlb in SLTG typelib format +Depends: widl-SLTG_Typelib_Support diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0001-ntdll-Use-sysinfo-to-report-correct-number-of-physic.patch wine-staging-1.9.3~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0001-ntdll-Use-sysinfo-to-report-correct-number-of-physic.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0001-ntdll-Use-sysinfo-to-report-correct-number-of-physic.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0001-ntdll-Use-sysinfo-to-report-correct-number-of-physic.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,62 @@ +From cfc7a0a240df174882997f8b69d37848543e12dd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Wed, 27 Jan 2016 04:54:15 +0100 +Subject: ntdll: Use sysinfo to report correct number of physical pages. + +--- + configure.ac | 1 + + dlls/ntdll/virtual.c | 14 ++++++++++++++ + 2 files changed, 15 insertions(+) + +diff --git a/configure.ac b/configure.ac +index 59fc4fa..3909cd5 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -502,6 +502,7 @@ AC_CHECK_HEADERS(\ + sys/statvfs.h \ + sys/strtio.h \ + sys/syscall.h \ ++ sys/sysinfo.h \ + sys/tihdr.h \ + sys/time.h \ + sys/timeout.h \ +diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c +index f4ca487..b9a59fc 100644 +--- a/dlls/ntdll/virtual.c ++++ b/dlls/ntdll/virtual.c +@@ -38,6 +38,9 @@ + #ifdef HAVE_SYS_MMAN_H + # include + #endif ++#ifdef HAVE_SYS_SYSINFO_H ++# include ++#endif + #ifdef HAVE_VALGRIND_VALGRIND_H + # include + #endif +@@ -1356,11 +1359,22 @@ void virtual_init_threading(void) + */ + void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) + { ++#ifdef HAVE_SYS_SYSINFO_H ++ struct sysinfo sinfo; ++#endif ++ + info->unknown = 0; + info->KeMaximumIncrement = 0; /* FIXME */ + info->PageSize = page_size; + info->MmLowestPhysicalPage = 1; + info->MmHighestPhysicalPage = 0x7fffffff / page_size; ++#ifdef HAVE_SYS_SYSINFO_H ++ if (!sysinfo(&sinfo)) ++ { ++ ULONG64 total = (ULONG64)sinfo.totalram * sinfo.mem_unit; ++ info->MmHighestPhysicalPage = max(1, total / page_size); ++ } ++#endif + info->MmNumberOfPhysicalPages = info->MmHighestPhysicalPage - info->MmLowestPhysicalPage; + info->AllocationGranularity = get_mask(0) + 1; + info->LowestUserAddress = (void *)0x10000; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0002-ntdll-Report-system-information-SystemPerformanceInf.patch wine-staging-1.9.3~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0002-ntdll-Report-system-information-SystemPerformanceInf.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0002-ntdll-Report-system-information-SystemPerformanceInf.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0002-ntdll-Report-system-information-SystemPerformanceInf.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,58 @@ +From 67f11502fdf5bdabbc786efe99ce4e681683ba31 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 28 Jan 2016 06:43:00 +0100 +Subject: ntdll: Report system information SystemPerformanceInformation info + class. + +--- + dlls/ntdll/nt.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c +index 9ee1923..947b410 100644 +--- a/dlls/ntdll/nt.c ++++ b/dlls/ntdll/nt.c +@@ -30,6 +30,9 @@ + #ifdef HAVE_SYS_SYSCTL_H + # include + #endif ++#ifdef HAVE_SYS_SYSINFO_H ++# include ++#endif + #ifdef HAVE_MACHINE_CPU_H + # include + #endif +@@ -1718,6 +1721,9 @@ NTSTATUS WINAPI NtQuerySystemInformation( + SYSTEM_PERFORMANCE_INFORMATION spi; + static BOOL fixme_written = FALSE; + FILE *fp; ++ #ifdef HAVE_SYS_SYSINFO_H ++ struct sysinfo sinfo; ++ #endif + + memset(&spi, 0 , sizeof(spi)); + len = sizeof(spi); +@@ -1739,6 +1745,20 @@ NTSTATUS WINAPI NtQuerySystemInformation( + spi.IdleTime.QuadPart = ++idle; + } + ++ #ifdef HAVE_SYS_SYSINFO_H ++ if (!sysinfo(&sinfo)) ++ { ++ ULONG64 freemem = (ULONG64)sinfo.freeram * sinfo.mem_unit; ++ ULONG64 totalram = (ULONG64)sinfo.totalram * sinfo.mem_unit; ++ ULONG64 totalswap = (ULONG64)sinfo.totalswap * sinfo.mem_unit; ++ ULONG64 freeswap = (ULONG64)sinfo.freeswap * sinfo.mem_unit; ++ ++ spi.AvailablePages = freemem / page_size; ++ spi.TotalCommittedPages = (totalram + totalswap - freemem - freeswap) / page_size; ++ spi.TotalCommitLimit = (totalram + totalswap) / page_size; ++ } ++ #endif ++ + if (Length >= len) + { + if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0003-taskmgr-Use-system-font-instead-of-special-bitmap-fo.patch wine-staging-1.9.3~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0003-taskmgr-Use-system-font-instead-of-special-bitmap-fo.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0003-taskmgr-Use-system-font-instead-of-special-bitmap-fo.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0003-taskmgr-Use-system-font-instead-of-special-bitmap-fo.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,139 @@ +From 54f6838211778a8f2527640d3c5a411f56d5cd98 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Wed, 27 Jan 2016 04:55:09 +0100 +Subject: taskmgr: Use system font instead of special bitmap font. + +--- + programs/taskmgr/font.bmp | Bin 646 -> 0 bytes + programs/taskmgr/graph.c | 14 ++++++++++++-- + programs/taskmgr/resource.h | 1 - + programs/taskmgr/taskmgr.c | 29 ----------------------------- + programs/taskmgr/taskmgr.rc | 3 --- + 5 files changed, 12 insertions(+), 35 deletions(-) + delete mode 100644 programs/taskmgr/font.bmp + +diff --git a/programs/taskmgr/font.bmp b/programs/taskmgr/font.bmp +deleted file mode 100644 +index c1f8410c93273f4bc7013014561c35ef84faa182..0000000000000000000000000000000000000000 +GIT binary patch +literal 0 +HcmV?d00001 + +literal 646 +zcma)(!4U#62u0EH6fcfdSci9eun5QVo~(m&sz_(+`>@G4J060-haZBlxj#Nf3wh&j +z*b_Tr2Rq@-E}XxvX+aFPn4z{T33x(lt${jNLv39ZVf;klYOQWo0y8!j?qiD3aA3(K +zIq{C$VS%n9(V2QTr);{O_DntBpT=8p%%lCvw&%ZnE9Lyb=%2T9J{pLZxOXEEt2{0S +rj&qR`_imbB3(wY5`TKp;OQ!n~kRUw=3;lV4-TOj~_w9QN#T)VkBip4W + +diff --git a/programs/taskmgr/graph.c b/programs/taskmgr/graph.c +index 4098675..df4f922 100644 +--- a/programs/taskmgr/graph.c ++++ b/programs/taskmgr/graph.c +@@ -44,6 +44,7 @@ static void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd) + RECT rcClient; + RECT rcBarLeft; + RECT rcBarRight; ++ RECT rcText; + WCHAR Text[256]; + ULONG CpuUsage; + ULONG CpuKernelUsage; +@@ -97,7 +98,11 @@ static void Graph_DrawCpuUsageGraph(HDC hDC, HWND hWnd) + * Draw the font text onto the graph + * The bottom 20 pixels are reserved for the text + */ +- Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - 32) / 2, rcClient.bottom - 11 - 5); ++ CopyRect(&rcText, &rcClient); ++ rcText.top = rcText.bottom - 19; ++ ++ SetTextColor(hDC, BRIGHT_GREEN); ++ DrawTextW(hDC, Text, -1, &rcText, DT_CENTER); + + /* + * Now we have to draw the graph +@@ -224,6 +229,7 @@ static void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd) + RECT rcClient; + RECT rcBarLeft; + RECT rcBarRight; ++ RECT rcText; + WCHAR Text[256]; + ULONGLONG CommitChargeTotal; + ULONGLONG CommitChargeLimit; +@@ -258,7 +264,11 @@ static void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd) + * Draw the font text onto the graph + * The bottom 20 pixels are reserved for the text + */ +- Font_DrawText(hDC, Text, ((rcClient.right - rcClient.left) - (strlenW(Text) * 8)) / 2, rcClient.bottom - 11 - 5); ++ CopyRect(&rcText, &rcClient); ++ rcText.top = rcText.bottom - 19; ++ ++ SetTextColor(hDC, BRIGHT_GREEN); ++ DrawTextW(hDC, Text, -1, &rcText, DT_CENTER); + + /* + * Now we have to draw the graph +diff --git a/programs/taskmgr/resource.h b/programs/taskmgr/resource.h +index add873d..cbd2448 100644 +--- a/programs/taskmgr/resource.h ++++ b/programs/taskmgr/resource.h +@@ -35,7 +35,6 @@ + #define IDR_PROCESS_PAGE_CONTEXT 144 + #define IDB_TRAYMASK 150 + #define IDB_TRAYICON 153 +-#define IDB_FONT 154 + #define IDD_DEBUG_CHANNELS_DIALOG 155 + #define IDC_DEBUG_CHANNELS_LIST 156 + +diff --git a/programs/taskmgr/taskmgr.c b/programs/taskmgr/taskmgr.c +index 80dc81c..b0f2e78 100644 +--- a/programs/taskmgr/taskmgr.c ++++ b/programs/taskmgr/taskmgr.c +@@ -80,35 +80,6 @@ static void Draw3dRect(HDC hDC, int x, int y, int cx, int cy, COLORREF clrTopLef + FillSolidRect2(hDC, x, y + cy, cx, -1, clrBottomRight); + } + +-void Font_DrawText(HDC hDC, LPWSTR lpwszText, int x, int y) +-{ +- HDC hFontDC; +- HBITMAP hFontBitmap; +- HBITMAP hOldBitmap; +- int i; +- +- hFontDC = CreateCompatibleDC(hDC); +- hFontBitmap = LoadBitmapW(hInst, MAKEINTRESOURCEW(IDB_FONT)); +- hOldBitmap = SelectObject(hFontDC, hFontBitmap); +- +- for (i = 0; lpwszText[i]; i++) { +- if ((lpwszText[i] >= '0') && (lpwszText[i] <= '9')) { +- BitBlt(hDC, x + (i * 8), y, 8, 11, hFontDC, (lpwszText[i] - '0') * 8, 0, SRCCOPY); +- } +- else if (lpwszText[i] == 'K') +- { +- BitBlt(hDC, x + (i * 8), y, 8, 11, hFontDC, 80, 0, SRCCOPY); +- } +- else if (lpwszText[i] == '%') +- { +- BitBlt(hDC, x + (i * 8), y, 8, 11, hFontDC, 88, 0, SRCCOPY); +- } +- } +- SelectObject(hFontDC, hOldBitmap); +- DeleteObject(hFontBitmap); +- DeleteDC(hFontDC); +-} +- + static BOOL OnCreate(HWND hWnd) + { + HMENU hMenu; +diff --git a/programs/taskmgr/taskmgr.rc b/programs/taskmgr/taskmgr.rc +index e6742a7..ffd0699 100644 +--- a/programs/taskmgr/taskmgr.rc ++++ b/programs/taskmgr/taskmgr.rc +@@ -609,6 +609,3 @@ IDB_TRAYMASK BITMAP traymask.bmp + + /* @makedep: trayicon.bmp */ + IDB_TRAYICON BITMAP trayicon.bmp +- +-/* @makedep: font.bmp */ +-IDB_FONT BITMAP font.bmp +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0004-taskmgr-Use-different-units-depending-on-memory-usag.patch wine-staging-1.9.3~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0004-taskmgr-Use-different-units-depending-on-memory-usag.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0004-taskmgr-Use-different-units-depending-on-memory-usag.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/taskmgr-Memory_Usage/0004-taskmgr-Use-different-units-depending-on-memory-usag.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,45 @@ +From 6b3fbb9c89a49f1ae936cc7db666f9ee09069463 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Wed, 27 Jan 2016 05:03:26 +0100 +Subject: taskmgr: Use different units depending on memory usage. + +--- + programs/taskmgr/graph.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/programs/taskmgr/graph.c b/programs/taskmgr/graph.c +index df4f922..7f1d09c 100644 +--- a/programs/taskmgr/graph.c ++++ b/programs/taskmgr/graph.c +@@ -240,8 +240,10 @@ static void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd) + /* Top bars that are "unused", i.e. are dark green, representing free memory */ + int i; + +- static const WCHAR wszFormat[] = {'%','d','K',0}; +- ++ static const WCHAR wszFormatKB[] = {'%','u',' ','K','B',0}; ++ static const WCHAR wszFormatMB[] = {'%','u',' ','M','B',0}; ++ static const WCHAR wszFormatGB[] = {'%','.','1','f',' ','G','B',0}; ++ + /* + * Get the client area rectangle + */ +@@ -258,8 +260,13 @@ static void Graph_DrawMemUsageGraph(HDC hDC, HWND hWnd) + CommitChargeTotal = (ULONGLONG)PerfDataGetCommitChargeTotalK(); + CommitChargeLimit = (ULONGLONG)PerfDataGetCommitChargeLimitK(); + +- sprintfW(Text, wszFormat, (int)CommitChargeTotal); +- ++ if (CommitChargeTotal > 1048576) ++ sprintfW(Text, wszFormatGB, (float)CommitChargeTotal / 1048576); ++ else if (CommitChargeTotal > 1024) ++ sprintfW(Text, wszFormatMB, (DWORD)CommitChargeTotal / 1024); ++ else ++ sprintfW(Text, wszFormatKB, (DWORD)CommitChargeTotal); ++ + /* + * Draw the font text onto the graph + * The bottom 20 pixels are reserved for the text +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ucrtbase-Functions/0001-ucrtbase-Hook-up-some-functions-with-new-names-to-ex.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ucrtbase-Functions/0001-ucrtbase-Hook-up-some-functions-with-new-names-to-ex.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ucrtbase-Functions/0001-ucrtbase-Hook-up-some-functions-with-new-names-to-ex.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ucrtbase-Functions/0001-ucrtbase-Hook-up-some-functions-with-new-names-to-ex.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,69 @@ +From 97853bae25a321b30e2ee38044c85af75fb61174 Mon Sep 17 00:00:00 2001 +From: Martin Storsjo +Date: Mon, 3 Aug 2015 22:26:01 +0300 +Subject: ucrtbase: Hook up some functions with new names to existing + implementations + +These are some functions that on a first glance seem to have a +matching signature even though the name has changed. +--- + dlls/api-ms-win-crt-heap-l1-1-0/api-ms-win-crt-heap-l1-1-0.spec | 6 +++--- + dlls/ucrtbase/ucrtbase.spec | 6 +++--- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/dlls/api-ms-win-crt-heap-l1-1-0/api-ms-win-crt-heap-l1-1-0.spec b/dlls/api-ms-win-crt-heap-l1-1-0/api-ms-win-crt-heap-l1-1-0.spec +index 18ca9d4..418926e 100644 +--- a/dlls/api-ms-win-crt-heap-l1-1-0/api-ms-win-crt-heap-l1-1-0.spec ++++ b/dlls/api-ms-win-crt-heap-l1-1-0/api-ms-win-crt-heap-l1-1-0.spec +@@ -7,14 +7,14 @@ + @ cdecl _aligned_realloc(ptr long long) ucrtbase._aligned_realloc + @ stub _aligned_recalloc + @ cdecl _callnewh(long) ucrtbase._callnewh +-@ stub _calloc_base ++@ cdecl _calloc_base(long long) ucrtbase._calloc_base + @ cdecl _expand(ptr long) ucrtbase._expand +-@ stub _free_base ++@ cdecl _free_base(ptr) ucrtbase._free_base + @ cdecl _get_heap_handle() ucrtbase._get_heap_handle + @ cdecl _heapchk() ucrtbase._heapchk + @ cdecl _heapmin() ucrtbase._heapmin + @ cdecl _heapwalk(ptr) ucrtbase._heapwalk +-@ stub _malloc_base ++@ cdecl _malloc_base(long) ucrtbase._malloc_base + @ cdecl _msize(ptr) ucrtbase._msize + @ stub _query_new_handler + @ stub _query_new_mode +diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec +index 3478342..53ca8fb 100644 +--- a/dlls/ucrtbase/ucrtbase.spec ++++ b/dlls/ucrtbase/ucrtbase.spec +@@ -211,7 +211,7 @@ + @ cdecl _c_exit() MSVCRT__c_exit + @ cdecl _cabs(long) MSVCRT__cabs + @ cdecl _callnewh(long) +-@ stub _calloc_base ++@ cdecl _calloc_base(long long) MSVCRT_calloc + @ cdecl _cexit() MSVCRT__cexit + @ cdecl _cgets(ptr) + @ stub _cgets_s +@@ -333,7 +333,7 @@ + @ cdecl _fputwchar(long) MSVCRT__fputwchar + @ cdecl _fread_nolock(ptr long long ptr) MSVCRT__fread_nolock + @ cdecl _fread_nolock_s(ptr long long long ptr) MSVCRT__fread_nolock_s +-@ stub _free_base ++@ cdecl _free_base(ptr) MSVCRT_free + @ cdecl _free_locale(ptr) MSVCRT__free_locale + @ cdecl _fseek_nolock(ptr long long) MSVCRT__fseek_nolock + @ cdecl _fseeki64(ptr int64 long) MSVCRT__fseeki64 +@@ -580,7 +580,7 @@ + @ cdecl _ltow_s(long ptr long long) MSVCRT__ltow_s + @ cdecl _makepath(ptr str str str str) MSVCRT__makepath + @ cdecl _makepath_s(ptr long str str str str) MSVCRT__makepath_s +-@ stub _malloc_base ++@ cdecl _malloc_base(long) MSVCRT_malloc + @ cdecl _mbbtombc(long) + @ stub _mbbtombc_l + @ cdecl _mbbtype(long long) +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ucrtbase-Functions/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ucrtbase-Functions/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ucrtbase-Functions/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ucrtbase-Functions/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Forward _{calloc,malloc,free}_base to {calloc,malloc,free} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/user32-MOUSEHOOKSTRUCTEX/0001-user32-Add-MOUSEHOOKSTRUCTEX-to-fix-mouse-wheel-supp.patch wine-staging-1.9.3~ubuntu12.04.1/patches/user32-MOUSEHOOKSTRUCTEX/0001-user32-Add-MOUSEHOOKSTRUCTEX-to-fix-mouse-wheel-supp.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/user32-MOUSEHOOKSTRUCTEX/0001-user32-Add-MOUSEHOOKSTRUCTEX-to-fix-mouse-wheel-supp.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/user32-MOUSEHOOKSTRUCTEX/0001-user32-Add-MOUSEHOOKSTRUCTEX-to-fix-mouse-wheel-supp.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -From f3a55ca22853088d82f30711f9616b22b20bd228 Mon Sep 17 00:00:00 2001 -From: Kira Backes -Date: Tue, 22 Dec 2015 16:34:41 +0100 -Subject: user32: Add MOUSEHOOKSTRUCTEX to fix mouse wheel support for JA2 1.13 - and other apps which use it - -- Fixes out-of-bounds access for programs which cast to MOUSEHOOKSTRUCTEX (instead of just MOUSEHOOKSTRUCT) on mouse hooks -- Enables mouse wheel support for those programs -- Fixes Bug 38314 (and maybe others?) - -Signed-off-by: Kira Backes -Signed-off-by: Sebastian Lackner ---- - dlls/user32/message.c | 26 +++++++++++++++++--------- - 1 file changed, 17 insertions(+), 9 deletions(-) - -diff --git a/dlls/user32/message.c b/dlls/user32/message.c -index 96e7f2e..b96418f 100644 ---- a/dlls/user32/message.c -+++ b/dlls/user32/message.c -@@ -2488,8 +2488,12 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H - INT hittest; - EVENTMSG event; - GUITHREADINFO info; -- MOUSEHOOKSTRUCT hook; - BOOL eatMsg; -+ struct /* MOUSEHOOKSTRUCTEX */ -+ { -+ MOUSEHOOKSTRUCT hook; -+ DWORD mouseData; -+ } hook; - - /* find the window to dispatch this mouse message to */ - -@@ -2584,17 +2588,21 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H - - /* message is accepted now (but may still get dropped) */ - -- hook.pt = msg->pt; -- hook.hwnd = msg->hwnd; -- hook.wHitTestCode = hittest; -- hook.dwExtraInfo = extra_info; -+ hook.hook.pt = msg->pt; -+ hook.hook.hwnd = msg->hwnd; -+ hook.hook.wHitTestCode = hittest; -+ hook.hook.dwExtraInfo = extra_info; -+ /* the correct mouseData for the events WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, -+ * WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, and WM_NCXBUTTONDBLCLK is not yet implemented */ -+ hook.mouseData = (msg->message == WM_MOUSEWHEEL ? msg->wParam : 0); - if (HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE, - message, (LPARAM)&hook, TRUE )) - { -- hook.pt = msg->pt; -- hook.hwnd = msg->hwnd; -- hook.wHitTestCode = hittest; -- hook.dwExtraInfo = extra_info; -+ hook.hook.pt = msg->pt; -+ hook.hook.hwnd = msg->hwnd; -+ hook.hook.wHitTestCode = hittest; -+ hook.hook.dwExtraInfo = extra_info; -+ hook.mouseData = (msg->message == WM_MOUSEWHEEL ? msg->wParam : 0); - HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook, TRUE ); - accept_hardware_message( hw_id, TRUE ); - return FALSE; --- -2.6.4 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/user32-MOUSEHOOKSTRUCTEX/definition wine-staging-1.9.3~ubuntu12.04.1/patches/user32-MOUSEHOOKSTRUCTEX/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/user32-MOUSEHOOKSTRUCTEX/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/user32-MOUSEHOOKSTRUCTEX/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Fixes: [38314] Pass MOUSEHOOKSTRUCTEX struct to mouse hook callback diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/user32-Mouse_Message_Hwnd/definition wine-staging-1.9.3~ubuntu12.04.1/patches/user32-Mouse_Message_Hwnd/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/user32-Mouse_Message_Hwnd/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/user32-Mouse_Message_Hwnd/definition 2016-02-08 20:07:32.000000000 +0000 @@ -1 +1,2 @@ Fixes: [12007] Fix issues with dragging layers between images in Adobe Photoshop 7.0 +Fixes: [9512] Make sure popups don't block access to objects underneath in DVDPro diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/user32-SetCaretPos/0001-user32-Set-correct-caret-state-in-the-server-in-SetC.patch wine-staging-1.9.3~ubuntu12.04.1/patches/user32-SetCaretPos/0001-user32-Set-correct-caret-state-in-the-server-in-SetC.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/user32-SetCaretPos/0001-user32-Set-correct-caret-state-in-the-server-in-SetC.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/user32-SetCaretPos/0001-user32-Set-correct-caret-state-in-the-server-in-SetC.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -From 00f9c189e83c7e470ab03e779b6829467fe6e39b Mon Sep 17 00:00:00 2001 -From: Anton Baskanov -Date: Fri, 25 Dec 2015 21:06:07 +0600 -Subject: user32: Set correct caret state in the server in SetCaretPos (try 4) - -Signed-off-by: Anton Baskanov - -The code in SetCaretPos doesn't change the caret state if it's position is unchanged. -Reflect this at the server side to avoid caret corruption. - -try2: - - fixed incorrect if statement in the server -try3: - - fixed multiline comment -try4: - - replaced magic numbers with named constants ---- - dlls/user32/caret.c | 8 ++++---- - server/protocol.def | 6 +++++- - server/queue.c | 9 +++++++-- - 3 files changed, 16 insertions(+), 7 deletions(-) - -diff --git a/dlls/user32/caret.c b/dlls/user32/caret.c -index 53bb5b4..734377a 100644 ---- a/dlls/user32/caret.c -+++ b/dlls/user32/caret.c -@@ -86,7 +86,7 @@ static void CALLBACK CARET_Callback( HWND hwnd, UINT msg, UINT_PTR id, DWORD cti - req->x = 0; - req->y = 0; - req->hide = 0; -- req->state = -1; /* toggle current state */ -+ req->state = CARET_STATE_TOGGLE; - if ((ret = !wine_server_call( req ))) - { - hwnd = wine_server_ptr_handle( reply->full_handle ); -@@ -256,7 +256,7 @@ BOOL WINAPI SetCaretPos( INT x, INT y ) - req->x = x; - req->y = y; - req->hide = 0; -- req->state = 1; -+ req->state = CARET_STATE_ON_IF_POS_CHANGED; - if ((ret = !wine_server_call_err( req ))) - { - hwnd = wine_server_ptr_handle( reply->full_handle ); -@@ -300,7 +300,7 @@ BOOL WINAPI HideCaret( HWND hwnd ) - req->x = 0; - req->y = 0; - req->hide = 1; -- req->state = 0; -+ req->state = CARET_STATE_OFF; - if ((ret = !wine_server_call_err( req ))) - { - hwnd = wine_server_ptr_handle( reply->full_handle ); -@@ -339,7 +339,7 @@ BOOL WINAPI ShowCaret( HWND hwnd ) - req->x = 0; - req->y = 0; - req->hide = -1; -- req->state = 1; -+ req->state = CARET_STATE_ON; - if ((ret = !wine_server_call_err( req ))) - { - hwnd = wine_server_ptr_handle( reply->full_handle ); -diff --git a/server/protocol.def b/server/protocol.def -index bfb9089..7a7c7e1 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -2978,7 +2978,7 @@ enum coords_relative - int x; /* caret x position */ - int y; /* caret y position */ - int hide; /* increment for hide count (can be negative to show it) */ -- int state; /* caret state (1=on, 0=off, -1=toggle current state) */ -+ int state; /* caret state (see below) */ - @REPLY - user_handle_t full_handle; /* handle to the current caret window */ - rectangle_t old_rect; /* previous caret rectangle */ -@@ -2988,6 +2988,10 @@ enum coords_relative - #define SET_CARET_POS 0x01 /* set the caret position from x,y */ - #define SET_CARET_HIDE 0x02 /* increment the caret hide count */ - #define SET_CARET_STATE 0x04 /* set the caret on/off state */ -+#define CARET_STATE_OFF 0 /* off */ -+#define CARET_STATE_ON 1 /* on */ -+#define CARET_STATE_TOGGLE -1 /* toggle current state */ -+#define CARET_STATE_ON_IF_POS_CHANGED -2 /* on if the position differs, unchanged otherwise */ - - - /* Set a window hook */ -diff --git a/server/queue.c b/server/queue.c -index 3099e12..c04d73a 100644 ---- a/server/queue.c -+++ b/server/queue.c -@@ -3039,8 +3039,13 @@ DECL_HANDLER(set_caret_info) - } - if (req->flags & SET_CARET_STATE) - { -- if (req->state == -1) input->caret_state = !input->caret_state; -- else input->caret_state = !!req->state; -+ if (req->state == CARET_STATE_TOGGLE) input->caret_state = !input->caret_state; -+ else if (req->state == CARET_STATE_ON_IF_POS_CHANGED) -+ { -+ if (req->x != reply->old_rect.left || req->y != reply->old_rect.top) -+ input->caret_state = 1; -+ } -+ else input->caret_state = (req->state == CARET_STATE_ON); - } - } - --- -2.6.4 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/user32-SetCaretPos/definition wine-staging-1.9.3~ubuntu12.04.1/patches/user32-SetCaretPos/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/user32-SetCaretPos/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/user32-SetCaretPos/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Fixes: Avoid corruption of caret when SetCaretPos() is called diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/user32-WM_CAPTURECHANGE/0001-user32-Also-send-WM_CAPTURECHANGE-when-capture-has-n.patch wine-staging-1.9.3~ubuntu12.04.1/patches/user32-WM_CAPTURECHANGE/0001-user32-Also-send-WM_CAPTURECHANGE-when-capture-has-n.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/user32-WM_CAPTURECHANGE/0001-user32-Also-send-WM_CAPTURECHANGE-when-capture-has-n.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/user32-WM_CAPTURECHANGE/0001-user32-Also-send-WM_CAPTURECHANGE-when-capture-has-n.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -From 5bfd73ad3ec48deae92927e8116fce81ac31cf66 Mon Sep 17 00:00:00 2001 -From: Christopher Thielen -Date: Mon, 23 Nov 2015 21:48:26 -0800 -Subject: user32: Also send WM_CAPTURECHANGE when capture has not changed. - -Fixes https://bugs.winehq.org/show_bug.cgi?id=13683 - -A window may be notified with WM_CAPTURECHANGED about itself -gaining mouse capture if it calls SetCapture() twice. - -Signed-off-by: Christopher Thielen -Signed-off-by: Sebastian Lackner ---- - dlls/comctl32/toolbar.c | 1 + - dlls/comctl32/trackbar.c | 1 + - dlls/user32/button.c | 1 + - dlls/user32/input.c | 2 +- - dlls/user32/tests/msg.c | 27 +++++++++++++++++++++++++++ - 5 files changed, 31 insertions(+), 1 deletion(-) - -diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c -index 890c18e..3251682 100644 ---- a/dlls/comctl32/toolbar.c -+++ b/dlls/comctl32/toolbar.c -@@ -6807,6 +6807,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - return TOOLBAR_MouseLeave (infoPtr); - - case WM_CAPTURECHANGED: -+ if (lParam == (LPARAM)hwnd) return 0; - return TOOLBAR_CaptureChanged(infoPtr); - - case WM_NCACTIVATE: -diff --git a/dlls/comctl32/trackbar.c b/dlls/comctl32/trackbar.c -index 6d092a3..4d19a70 100644 ---- a/dlls/comctl32/trackbar.c -+++ b/dlls/comctl32/trackbar.c -@@ -1976,6 +1976,7 @@ TRACKBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - - - case WM_CAPTURECHANGED: -+ if (lParam == (LPARAM)hwnd) return 0; - return TRACKBAR_CaptureChanged (infoPtr); - - case WM_CREATE: -diff --git a/dlls/user32/button.c b/dlls/user32/button.c -index 890d154..2fee3c8 100644 ---- a/dlls/user32/button.c -+++ b/dlls/user32/button.c -@@ -364,6 +364,7 @@ LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, - - case WM_CAPTURECHANGED: - TRACE("WM_CAPTURECHANGED %p\n", hWnd); -+ if (lParam == (LPARAM)hWnd) break; - state = get_button_state( hWnd ); - if (state & BUTTON_BTNPRESSED) - { -diff --git a/dlls/user32/input.c b/dlls/user32/input.c -index 40e35a9..63fae67 100644 ---- a/dlls/user32/input.c -+++ b/dlls/user32/input.c -@@ -108,7 +108,7 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) - { - USER_Driver->pSetCapture( hwnd, gui_flags ); - -- if (previous && previous != hwnd) -+ if (previous) - SendMessageW( previous, WM_CAPTURECHANGED, 0, (LPARAM)hwnd ); - - if (prev_ret) *prev_ret = previous; -diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c -index b90f8d0..151b77a 100644 ---- a/dlls/user32/tests/msg.c -+++ b/dlls/user32/tests/msg.c -@@ -14906,6 +14906,32 @@ else - flush_sequence(); - } - -+static const struct message DoubleSetCaptureSeq[] = -+{ -+ { WM_CAPTURECHANGED, sent }, -+ { 0 } -+}; -+ -+static void test_DoubleSetCapture(void) -+{ -+ HWND hwnd; -+ -+ hwnd = CreateWindowExA(0, "TestWindowClass", "Test DoubleSetCapture", -+ WS_OVERLAPPEDWINDOW | WS_VISIBLE, -+ 100, 100, 200, 200, 0, 0, 0, NULL); -+ ok(hwnd != 0, "Failed to create overlapped window\n"); -+ -+ ShowWindow( hwnd, SW_SHOW ); -+ flush_sequence(); -+ -+ SetCapture(hwnd); -+ ok_sequence(WmEmptySeq, "SetCapture(hwnd) empty sequence", FALSE); -+ SetCapture(hwnd); -+ ok_sequence(DoubleSetCaptureSeq, "SetCapture(hwnd) twice", FALSE); -+ -+ DestroyWindow(hwnd); -+} -+ - static void init_funcs(void) - { - HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); -@@ -15045,6 +15071,7 @@ START_TEST(msg) - test_layered_window(); - test_TrackPopupMenu(); - test_TrackPopupMenuEmpty(); -+ test_DoubleSetCapture(); - /* keep it the last test, under Windows it tends to break the tests - * which rely on active/foreground windows being correct. - */ --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/user32-WM_CAPTURECHANGE/definition wine-staging-1.9.3~ubuntu12.04.1/patches/user32-WM_CAPTURECHANGE/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/user32-WM_CAPTURECHANGE/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/user32-WM_CAPTURECHANGE/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -Fixes: [13683] Also send WM_CAPTURECHANGE when capture has not changed diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/uxtheme-CloseThemeData/0001-uxtheme-Do-not-crash-when-INVALID_HANDLE_VALUE-is-pa.patch wine-staging-1.9.3~ubuntu12.04.1/patches/uxtheme-CloseThemeData/0001-uxtheme-Do-not-crash-when-INVALID_HANDLE_VALUE-is-pa.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/uxtheme-CloseThemeData/0001-uxtheme-Do-not-crash-when-INVALID_HANDLE_VALUE-is-pa.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/uxtheme-CloseThemeData/0001-uxtheme-Do-not-crash-when-INVALID_HANDLE_VALUE-is-pa.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,40 @@ +From ab3d3417ca146b9a72b395b082b4aae628c39d7c Mon Sep 17 00:00:00 2001 +From: Louis Lenders +Date: Wed, 27 Jan 2016 07:29:50 +0100 +Subject: uxtheme: Do not crash when INVALID_HANDLE_VALUE is passed to + CloseThemeData. + +--- + dlls/uxtheme/system.c | 2 +- + dlls/uxtheme/tests/system.c | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c +index 8947587..7d07680 100644 +--- a/dlls/uxtheme/system.c ++++ b/dlls/uxtheme/system.c +@@ -746,7 +746,7 @@ void WINAPI SetThemeAppProperties(DWORD dwFlags) + HRESULT WINAPI CloseThemeData(HTHEME hTheme) + { + TRACE("(%p)\n", hTheme); +- if(!hTheme) ++ if(!hTheme || hTheme == INVALID_HANDLE_VALUE) + return E_HANDLE; + return MSSTYLES_CloseThemeClass(hTheme); + } +diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c +index 49eba64..4aeedbc 100644 +--- a/dlls/uxtheme/tests/system.c ++++ b/dlls/uxtheme/tests/system.c +@@ -541,6 +541,8 @@ static void test_CloseThemeData(void) + + hRes = pCloseThemeData(NULL); + ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes); ++ hRes = pCloseThemeData(INVALID_HANDLE_VALUE); ++ ok( hRes == E_HANDLE, "Expected E_HANDLE, got 0x%08x\n", hRes); + } + + START_TEST(system) +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/uxtheme-CloseThemeData/definition wine-staging-1.9.3~ubuntu12.04.1/patches/uxtheme-CloseThemeData/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/uxtheme-CloseThemeData/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/uxtheme-CloseThemeData/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [29862] Do not crash when INVALID_HANDLE_VALUE is passed to CloseThemeData diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0007-uxthemegtk-Add-export-for-OpenThemeDataEx.patch wine-staging-1.9.3~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0007-uxthemegtk-Add-export-for-OpenThemeDataEx.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0007-uxthemegtk-Add-export-for-OpenThemeDataEx.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0007-uxthemegtk-Add-export-for-OpenThemeDataEx.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,59 @@ +From e82e7adedc71f3a2cb3f8a4c7af5ffbfaad48885 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 27 Jan 2016 08:20:28 +0100 +Subject: uxthemegtk: Add export for OpenThemeDataEx. + +--- + dlls/uxtheme-gtk/uxtheme-gtk.spec | 2 +- + dlls/uxtheme-gtk/uxtheme.c | 9 +++++++-- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/dlls/uxtheme-gtk/uxtheme-gtk.spec b/dlls/uxtheme-gtk/uxtheme-gtk.spec +index 4acc0fa..c4a619a 100644 +--- a/dlls/uxtheme-gtk/uxtheme-gtk.spec ++++ b/dlls/uxtheme-gtk/uxtheme-gtk.spec +@@ -38,7 +38,7 @@ + 46 stub -noname ClassicAdjustWindowRectEx + 48 stub -noname GetThemeParseErrorInfo + 60 stub -noname CreateThemeDataFromObjects +-61 stub OpenThemeDataEx ++61 stdcall OpenThemeDataEx(ptr wstr long) + 62 stub -noname ServerClearStockObjects + 63 stub -noname MarkSelection + +diff --git a/dlls/uxtheme-gtk/uxtheme.c b/dlls/uxtheme-gtk/uxtheme.c +index b520f6f..15fc231 100644 +--- a/dlls/uxtheme-gtk/uxtheme.c ++++ b/dlls/uxtheme-gtk/uxtheme.c +@@ -501,14 +501,14 @@ BOOL WINAPI IsThemeDialogTextureEnabled(HWND hwnd) + return TRUE; /* Always enabled */ + } + +-HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist) ++HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR classlist, DWORD flags) + { + WCHAR *start, *tok, buf[CLASSLIST_MAXLEN]; + uxgtk_theme_t *theme; + WORD fpu_flags; + int i; + +- TRACE("(%p, %s)\n", hwnd, debugstr_w(classlist)); ++ TRACE("(%p, %s, %x)\n", hwnd, debugstr_w(classlist), flags); + + if (libgtk3 == NULL) + { +@@ -562,6 +562,11 @@ found: + return theme; + } + ++HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist) ++{ ++ return OpenThemeDataEx(hwnd, classlist, 0); ++} ++ + void WINAPI SetThemeAppProperties(DWORD flags) + { + TRACE("(%u)\n", flags); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0008-uxthemegtk-Fix-some-incorrect-error-codes.patch wine-staging-1.9.3~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0008-uxthemegtk-Fix-some-incorrect-error-codes.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0008-uxthemegtk-Fix-some-incorrect-error-codes.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0008-uxthemegtk-Fix-some-incorrect-error-codes.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,43 @@ +From 60dd76b04fa8aad2200f91660d0277a1c403dbab Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 27 Jan 2016 08:16:10 +0100 +Subject: uxthemegtk: Fix some incorrect error codes. + +--- + dlls/uxtheme-gtk/uxtheme.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/dlls/uxtheme-gtk/uxtheme.c b/dlls/uxtheme-gtk/uxtheme.c +index ab369f5..631c4da 100644 +--- a/dlls/uxtheme-gtk/uxtheme.c ++++ b/dlls/uxtheme-gtk/uxtheme.c +@@ -519,7 +519,7 @@ HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR classlist, DWORD flags) + /* comctl32.dll likes to send NULL */ + if (classlist == NULL) + { +- SetLastError(ERROR_INVALID_PARAMETER); ++ SetLastError(E_POINTER); + return NULL; + } + +@@ -578,7 +578,7 @@ HRESULT WINAPI SetWindowTheme(HWND hwnd, LPCWSTR sub_app_name, + FIXME("(%p, %s, %s)\n", hwnd, debugstr_w(sub_app_name), + debugstr_w(sub_id_list)); + +- return E_NOTIMPL; ++ return S_OK; + } + + HRESULT WINAPI GetThemeBool(HTHEME htheme, int part_id, int state_id, +@@ -1145,7 +1145,7 @@ BOOL WINAPI IsThemePartDefined(HTHEME htheme, int part_id, int state_id) + + if (theme == NULL || theme->vtable == NULL) + { +- SetLastError(ERROR_INVALID_HANDLE); ++ SetLastError(E_HANDLE); + return FALSE; + } + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0009-uxthemegtk-Validate-theme-handles-before-accessing-p.patch wine-staging-1.9.3~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0009-uxthemegtk-Validate-theme-handles-before-accessing-p.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0009-uxthemegtk-Validate-theme-handles-before-accessing-p.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/uxtheme-GTK_Theming/0009-uxthemegtk-Validate-theme-handles-before-accessing-p.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,192 @@ +From f5278dc9cd67771aace50ba14bce51626719ac7c Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 27 Jan 2016 08:53:14 +0100 +Subject: uxthemegtk: Validate theme handles before accessing private data. + +--- + dlls/uxtheme-gtk/uxtheme.c | 47 +++++++++++++++++++++++++++++++++---------- + dlls/uxtheme-gtk/uxthemegtk.h | 2 +- + 2 files changed, 37 insertions(+), 12 deletions(-) + +diff --git a/dlls/uxtheme-gtk/uxtheme.c b/dlls/uxtheme-gtk/uxtheme.c +index 631c4da..aeaeb06 100644 +--- a/dlls/uxtheme-gtk/uxtheme.c ++++ b/dlls/uxtheme-gtk/uxtheme.c +@@ -3,6 +3,7 @@ + * + * Copyright (C) 2015 Ivan Akulinchev + * Copyright (C) 2015 Michael Müller ++ * Copyright (C) 2016 Sebastian Lackner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -36,6 +37,7 @@ + #include "vfwmsgs.h" + #include "shlobj.h" + ++#include "wine/exception.h" + #include "wine/debug.h" + + #include "uxthemegtk.h" +@@ -129,6 +131,7 @@ MAKE_FUNCPTR(gtk_widget_style_get); + MAKE_FUNCPTR(gtk_window_new); + #undef MAKE_FUNCPTR + ++#define HTHEME_MAGIC 0x4b544758 + #define NUM_SYS_COLORS (COLOR_MENUBAR + 1) + #define MENU_HEIGHT 20 + #define CLASSLIST_MAXLEN 128 +@@ -265,6 +268,26 @@ error: + return FALSE; + } + ++static uxgtk_theme_t *impl_from_HTHEME(HTHEME htheme) ++{ ++ uxgtk_theme_t *theme = (uxgtk_theme_t *)htheme; ++ if (!htheme || htheme == INVALID_HANDLE_VALUE) return NULL; ++ __TRY ++ { ++ if (theme->magic != HTHEME_MAGIC) theme = NULL; ++ } ++ __EXCEPT_PAGE_FAULT ++ { ++ theme = NULL; ++ } ++ __ENDTRY ++ ++ if (!theme) ++ FIXME("Theme handle %p is invalid\n", htheme); ++ ++ return theme; ++} ++ + static void process_attach(void) + { + static const WCHAR themes_subdir[] = {'\\','T','h','e','m','e','s','\\', 'g','t','k','3',0}; +@@ -347,6 +370,7 @@ static BOOL is_fake_theme(const WCHAR *path) + + void uxgtk_theme_init(uxgtk_theme_t *theme, const uxgtk_theme_vtable_t *vtable) + { ++ theme->magic = HTHEME_MAGIC; + theme->vtable = vtable; + theme->window = pgtk_window_new(GTK_WINDOW_TOPLEVEL); + theme->layout = pgtk_fixed_new(); +@@ -404,7 +428,7 @@ static void paint_cairo_surface(cairo_surface_t *surface, HDC target_hdc, + + HRESULT WINAPI CloseThemeData(HTHEME htheme) + { +- uxgtk_theme_t *theme = (uxgtk_theme_t *)htheme; ++ uxgtk_theme_t *theme; + WORD fpu_flags; + + TRACE("(%p)\n", htheme); +@@ -412,7 +436,7 @@ HRESULT WINAPI CloseThemeData(HTHEME htheme) + if (libgtk3 == NULL) + return E_NOTIMPL; + +- if (theme == NULL) ++ if (!(theme = impl_from_HTHEME(htheme))) + return E_HANDLE; + + /* Destroy the toplevel widget */ +@@ -420,6 +444,7 @@ HRESULT WINAPI CloseThemeData(HTHEME htheme) + pgtk_widget_destroy(theme->window); + set_fpu_flags(fpu_flags); + ++ theme->magic = 0; + HeapFree(GetProcessHeap(), 0, theme); + return S_OK; + } +@@ -592,17 +617,17 @@ HRESULT WINAPI GetThemeBool(HTHEME htheme, int part_id, int state_id, + HRESULT WINAPI GetThemeColor(HTHEME htheme, int part_id, int state_id, + int prop_id, COLORREF *color) + { +- HRESULT hr; + GdkRGBA rgba = {0, 0, 0, 0}; +- uxgtk_theme_t *theme = (uxgtk_theme_t *)htheme; ++ uxgtk_theme_t *theme; + WORD fpu_flags; ++ HRESULT hr; + + TRACE("(%p, %d, %d, %d, %p)\n", htheme, part_id, state_id, prop_id, color); + + if (libgtk3 == NULL) + return E_NOTIMPL; + +- if (theme == NULL || theme->vtable == NULL) ++ if (!(theme = impl_from_HTHEME(htheme))) + return E_HANDLE; + + if (theme->vtable->get_color == NULL) +@@ -895,8 +920,8 @@ HRESULT WINAPI DrawThemeBackground(HTHEME htheme, HDC hdc, int part_id, int stat + HRESULT WINAPI DrawThemeBackgroundEx(HTHEME htheme, HDC hdc, int part_id, int state_id, + LPCRECT rect, const DTBGOPTS *options) + { +- uxgtk_theme_t *theme = (uxgtk_theme_t *)htheme; + cairo_surface_t *surface; ++ uxgtk_theme_t *theme; + int width, height; + WORD fpu_flags; + cairo_t *cr; +@@ -907,7 +932,7 @@ HRESULT WINAPI DrawThemeBackgroundEx(HTHEME htheme, HDC hdc, int part_id, int st + if (libgtk3 == NULL) + return E_NOTIMPL; + +- if (theme == NULL || theme->vtable == NULL) ++ if (!(theme = impl_from_HTHEME(htheme))) + return E_HANDLE; + + if (theme->vtable->draw_background == NULL) +@@ -1064,7 +1089,7 @@ HRESULT WINAPI GetThemeBackgroundRegion(HTHEME htheme, HDC hdc, int part_id, int + HRESULT WINAPI GetThemePartSize(HTHEME htheme, HDC hdc, int part_id, int state_id, + RECT *rect, THEMESIZE type, SIZE *size) + { +- uxgtk_theme_t *theme = (uxgtk_theme_t *)htheme; ++ uxgtk_theme_t *theme; + HRESULT result; + WORD fpu_flags; + +@@ -1073,7 +1098,7 @@ HRESULT WINAPI GetThemePartSize(HTHEME htheme, HDC hdc, int part_id, int state_i + if (libgtk3 == NULL) + return E_NOTIMPL; + +- if (theme == NULL || theme->vtable == NULL) ++ if (!(theme = impl_from_HTHEME(htheme))) + return E_HANDLE; + + if (theme->vtable->get_part_size == NULL) +@@ -1131,7 +1156,7 @@ BOOL WINAPI IsThemeBackgroundPartiallyTransparent(HTHEME htheme, int part_id, in + + BOOL WINAPI IsThemePartDefined(HTHEME htheme, int part_id, int state_id) + { +- uxgtk_theme_t *theme = (uxgtk_theme_t *)htheme; ++ uxgtk_theme_t *theme; + WORD fpu_flags; + BOOL result; + +@@ -1143,7 +1168,7 @@ BOOL WINAPI IsThemePartDefined(HTHEME htheme, int part_id, int state_id) + return FALSE; + } + +- if (theme == NULL || theme->vtable == NULL) ++ if (!(theme = impl_from_HTHEME(htheme))) + { + SetLastError(E_HANDLE); + return FALSE; +diff --git a/dlls/uxtheme-gtk/uxthemegtk.h b/dlls/uxtheme-gtk/uxthemegtk.h +index 79037fb..185366b 100644 +--- a/dlls/uxtheme-gtk/uxthemegtk.h ++++ b/dlls/uxtheme-gtk/uxthemegtk.h +@@ -44,8 +44,8 @@ struct _uxgtk_theme_vtable + + struct _uxgtk_theme + { ++ DWORD magic; + const uxgtk_theme_vtable_t *vtable; +- + GtkWidget *window; + GtkWidget *layout; + }; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/vcomp-Atomic_I8/0001-vcomp-tests-Reenable-architecture-dependent-tests.patch wine-staging-1.9.3~ubuntu12.04.1/patches/vcomp-Atomic_I8/0001-vcomp-tests-Reenable-architecture-dependent-tests.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/vcomp-Atomic_I8/0001-vcomp-tests-Reenable-architecture-dependent-tests.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/vcomp-Atomic_I8/0001-vcomp-tests-Reenable-architecture-dependent-tests.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,46 @@ +From 94973c7be88a18b4b4f79cea79f82f450cb659f0 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 14 Jan 2016 07:18:08 +0100 +Subject: vcomp/tests: Reenable architecture dependent tests. + +--- + dlls/vcomp/tests/vcomp.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c +index 4f030d3..5c177df 100644 +--- a/dlls/vcomp/tests/vcomp.c ++++ b/dlls/vcomp/tests/vcomp.c +@@ -1406,13 +1406,15 @@ static void test_atomic_integer32(void) + { p_vcomp_atomic_mul_i4, 0x11223344, -0x77665544, 0xecccdf0 }, + { p_vcomp_atomic_or_i4, 0x11223344, 0x77665544, 0x77667744 }, + { p_vcomp_atomic_shl_i4, 0x11223344, 3, -0x76ee65e0 }, +- /* { p_vcomp_atomic_shl_i4, 0x11223344, 35, -0x76ee65e0 }, */ /* depends on Architecture */ + { p_vcomp_atomic_shl_i4, -0x11223344, 3, 0x76ee65e0 }, + { p_vcomp_atomic_shr_i4, 0x11223344, 3, 0x2244668 }, +- /* { p_vcomp_atomic_shr_i4, 0x11223344, 35, 0x2244668 }, */ /* depends on Architecture */ + { p_vcomp_atomic_shr_i4, -0x11223344, 3, -0x2244669 }, + { p_vcomp_atomic_sub_i4, 0x11223344, 0x77665544, -0x66442200 }, + { p_vcomp_atomic_xor_i4, 0x11223344, 0x77665544, 0x66446600 }, ++ #if defined(__i386__) || defined(__x86_64__) ++ { p_vcomp_atomic_shl_i4, 0x11223344, 35, -0x76ee65e0 }, ++ { p_vcomp_atomic_shr_i4, 0x11223344, 35, 0x2244668 }, ++ #endif + }; + struct + { +@@ -1424,8 +1426,10 @@ static void test_atomic_integer32(void) + { p_vcomp_atomic_div_ui4, 0x77665544, 0x11223344, 6 }, + { p_vcomp_atomic_div_ui4, 0x77665544, 0xeeddccbc, 0 }, + { p_vcomp_atomic_shr_ui4, 0x11223344, 3, 0x2244668 }, +- /* { p_vcomp_atomic_shr_ui4, 0x11223344, 35, 0x2244668 }, */ /* depends on Architecture */ + { p_vcomp_atomic_shr_ui4, 0xeeddccbc, 3, 0x1ddbb997 }, ++ #if defined(__i386__) || defined(__x86_64__) ++ { p_vcomp_atomic_shr_ui4, 0x11223344, 35, 0x2244668 }, ++ #endif + }; + int i; + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/vcomp-Atomic_I8/0002-vcomp-Implement-64-bit-atomic-instructions.patch wine-staging-1.9.3~ubuntu12.04.1/patches/vcomp-Atomic_I8/0002-vcomp-Implement-64-bit-atomic-instructions.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/vcomp-Atomic_I8/0002-vcomp-Implement-64-bit-atomic-instructions.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/vcomp-Atomic_I8/0002-vcomp-Implement-64-bit-atomic-instructions.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,458 @@ +From bf16d653d692fdb4b3f5f595f1fa9cf58d9b2947 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 14 Jan 2016 07:20:03 +0100 +Subject: vcomp: Implement 64-bit atomic instructions. + +--- + dlls/vcomp/main.c | 68 ++++++++++++++++++++++++++++++++++++++++++++- + dlls/vcomp/vcomp.spec | 22 +++++++-------- + dlls/vcomp100/vcomp100.spec | 22 +++++++-------- + dlls/vcomp110/vcomp110.spec | 22 +++++++-------- + dlls/vcomp120/vcomp120.spec | 22 +++++++-------- + dlls/vcomp90/vcomp90.spec | 22 +++++++-------- + 6 files changed, 122 insertions(+), 56 deletions(-) + +diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c +index 12fd2a5..446b83d 100644 +--- a/dlls/vcomp/main.c ++++ b/dlls/vcomp/main.c +@@ -4,7 +4,7 @@ + * + * Copyright 2011 Austin English + * Copyright 2012 Dan Kegel +- * Copyright 2015 Sebastian Lackner ++ * Copyright 2015-2016 Sebastian Lackner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -356,6 +356,72 @@ void CDECL _vcomp_atomic_xor_i4(int *dest, int val) + do old = *dest; while (interlocked_cmpxchg(dest, old ^ val, old) != old); + } + ++void CDECL _vcomp_atomic_add_i8(LONG64 *dest, LONG64 val) ++{ ++ LONG64 old; ++ do old = *dest; while (interlocked_cmpxchg64(dest, old + val, old) != old); ++} ++ ++void CDECL _vcomp_atomic_and_i8(LONG64 *dest, LONG64 val) ++{ ++ LONG64 old; ++ do old = *dest; while (interlocked_cmpxchg64(dest, old & val, old) != old); ++} ++ ++void CDECL _vcomp_atomic_div_i8(LONG64 *dest, LONG64 val) ++{ ++ LONG64 old; ++ do old = *dest; while (interlocked_cmpxchg64(dest, old / val, old) != old); ++} ++ ++void CDECL _vcomp_atomic_div_ui8(ULONG64 *dest, ULONG64 val) ++{ ++ ULONG64 old; ++ do old = *dest; while (interlocked_cmpxchg64((LONG64 *)dest, old / val, old) != old); ++} ++ ++void CDECL _vcomp_atomic_mul_i8(LONG64 *dest, LONG64 val) ++{ ++ LONG64 old; ++ do old = *dest; while (interlocked_cmpxchg64(dest, old * val, old) != old); ++} ++ ++void CDECL _vcomp_atomic_or_i8(LONG64 *dest, LONG64 val) ++{ ++ LONG64 old; ++ do old = *dest; while (interlocked_cmpxchg64(dest, old | val, old) != old); ++} ++ ++void CDECL _vcomp_atomic_shl_i8(LONG64 *dest, unsigned int val) ++{ ++ LONG64 old; ++ do old = *dest; while (interlocked_cmpxchg64(dest, old << val, old) != old); ++} ++ ++void CDECL _vcomp_atomic_shr_i8(LONG64 *dest, unsigned int val) ++{ ++ LONG64 old; ++ do old = *dest; while (interlocked_cmpxchg64(dest, old >> val, old) != old); ++} ++ ++void CDECL _vcomp_atomic_shr_ui8(ULONG64 *dest, unsigned int val) ++{ ++ ULONG64 old; ++ do old = *dest; while (interlocked_cmpxchg64((LONG64 *)dest, old >> val, old) != old); ++} ++ ++void CDECL _vcomp_atomic_sub_i8(LONG64 *dest, LONG64 val) ++{ ++ LONG64 old; ++ do old = *dest; while (interlocked_cmpxchg64(dest, old - val, old) != old); ++} ++ ++void CDECL _vcomp_atomic_xor_i8(LONG64 *dest, LONG64 val) ++{ ++ LONG64 old; ++ do old = *dest; while (interlocked_cmpxchg64(dest, old ^ val, old) != old); ++} ++ + void CDECL _vcomp_atomic_add_r4(float *dest, float val) + { + int old, new; +diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec +index 7703e2e..eff411e 100644 +--- a/dlls/vcomp/vcomp.spec ++++ b/dlls/vcomp/vcomp.spec +@@ -1,55 +1,55 @@ + @ stub _vcomp_atomic_add_i1 + @ stub _vcomp_atomic_add_i2 + @ cdecl _vcomp_atomic_add_i4(ptr long) +-@ stub _vcomp_atomic_add_i8 ++@ cdecl _vcomp_atomic_add_i8(ptr int64) + @ cdecl _vcomp_atomic_add_r4(ptr float) + @ cdecl _vcomp_atomic_add_r8(ptr double) + @ stub _vcomp_atomic_and_i1 + @ stub _vcomp_atomic_and_i2 + @ cdecl _vcomp_atomic_and_i4(ptr long) +-@ stub _vcomp_atomic_and_i8 ++@ cdecl _vcomp_atomic_and_i8(ptr int64) + @ stub _vcomp_atomic_div_i1 + @ stub _vcomp_atomic_div_i2 + @ cdecl _vcomp_atomic_div_i4(ptr long) +-@ stub _vcomp_atomic_div_i8 ++@ cdecl _vcomp_atomic_div_i8(ptr int64) + @ cdecl _vcomp_atomic_div_r4(ptr float) + @ cdecl _vcomp_atomic_div_r8(ptr double) + @ stub _vcomp_atomic_div_ui1 + @ stub _vcomp_atomic_div_ui2 + @ cdecl _vcomp_atomic_div_ui4(ptr long) +-@ stub _vcomp_atomic_div_ui8 ++@ cdecl _vcomp_atomic_div_ui8(ptr int64) + @ stub _vcomp_atomic_mul_i1 + @ stub _vcomp_atomic_mul_i2 + @ cdecl _vcomp_atomic_mul_i4(ptr long) +-@ stub _vcomp_atomic_mul_i8 ++@ cdecl _vcomp_atomic_mul_i8(ptr int64) + @ cdecl _vcomp_atomic_mul_r4(ptr float) + @ cdecl _vcomp_atomic_mul_r8(ptr double) + @ stub _vcomp_atomic_or_i1 + @ stub _vcomp_atomic_or_i2 + @ cdecl _vcomp_atomic_or_i4(ptr long) +-@ stub _vcomp_atomic_or_i8 ++@ cdecl _vcomp_atomic_or_i8(ptr int64) + @ stub _vcomp_atomic_shl_i1 + @ stub _vcomp_atomic_shl_i2 + @ cdecl _vcomp_atomic_shl_i4(ptr long) +-@ stub _vcomp_atomic_shl_i8 ++@ cdecl _vcomp_atomic_shl_i8(ptr long) + @ stub _vcomp_atomic_shr_i1 + @ stub _vcomp_atomic_shr_i2 + @ cdecl _vcomp_atomic_shr_i4(ptr long) +-@ stub _vcomp_atomic_shr_i8 ++@ cdecl _vcomp_atomic_shr_i8(ptr long) + @ stub _vcomp_atomic_shr_ui1 + @ stub _vcomp_atomic_shr_ui2 + @ cdecl _vcomp_atomic_shr_ui4(ptr long) +-@ stub _vcomp_atomic_shr_ui8 ++@ cdecl _vcomp_atomic_shr_ui8(ptr long) + @ stub _vcomp_atomic_sub_i1 + @ stub _vcomp_atomic_sub_i2 + @ cdecl _vcomp_atomic_sub_i4(ptr long) +-@ stub _vcomp_atomic_sub_i8 ++@ cdecl _vcomp_atomic_sub_i8(ptr int64) + @ cdecl _vcomp_atomic_sub_r4(ptr float) + @ cdecl _vcomp_atomic_sub_r8(ptr double) + @ stub _vcomp_atomic_xor_i1 + @ stub _vcomp_atomic_xor_i2 + @ cdecl _vcomp_atomic_xor_i4(ptr long) +-@ stub _vcomp_atomic_xor_i8 ++@ cdecl _vcomp_atomic_xor_i8(ptr int64) + @ cdecl _vcomp_barrier() + @ stub _vcomp_copyprivate_broadcast + @ stub _vcomp_copyprivate_receive +diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec +index 849125f..ba1f414 100644 +--- a/dlls/vcomp100/vcomp100.spec ++++ b/dlls/vcomp100/vcomp100.spec +@@ -1,55 +1,55 @@ + @ stub _vcomp_atomic_add_i1 + @ stub _vcomp_atomic_add_i2 + @ cdecl _vcomp_atomic_add_i4(ptr long) vcomp._vcomp_atomic_add_i4 +-@ stub _vcomp_atomic_add_i8 ++@ cdecl _vcomp_atomic_add_i8(ptr int64) vcomp._vcomp_atomic_add_i8 + @ cdecl _vcomp_atomic_add_r4(ptr float) vcomp._vcomp_atomic_add_r4 + @ cdecl _vcomp_atomic_add_r8(ptr double) vcomp._vcomp_atomic_add_r8 + @ stub _vcomp_atomic_and_i1 + @ stub _vcomp_atomic_and_i2 + @ cdecl _vcomp_atomic_and_i4(ptr long) vcomp._vcomp_atomic_and_i4 +-@ stub _vcomp_atomic_and_i8 ++@ cdecl _vcomp_atomic_and_i8(ptr int64) vcomp._vcomp_atomic_and_i8 + @ stub _vcomp_atomic_div_i1 + @ stub _vcomp_atomic_div_i2 + @ cdecl _vcomp_atomic_div_i4(ptr long) vcomp._vcomp_atomic_div_i4 +-@ stub _vcomp_atomic_div_i8 ++@ cdecl _vcomp_atomic_div_i8(ptr int64) vcomp._vcomp_atomic_div_i8 + @ cdecl _vcomp_atomic_div_r4(ptr float) vcomp._vcomp_atomic_div_r4 + @ cdecl _vcomp_atomic_div_r8(ptr double) vcomp._vcomp_atomic_div_r8 + @ stub _vcomp_atomic_div_ui1 + @ stub _vcomp_atomic_div_ui2 + @ cdecl _vcomp_atomic_div_ui4(ptr long) vcomp._vcomp_atomic_div_ui4 +-@ stub _vcomp_atomic_div_ui8 ++@ cdecl _vcomp_atomic_div_ui8(ptr int64) vcomp._vcomp_atomic_div_ui8 + @ stub _vcomp_atomic_mul_i1 + @ stub _vcomp_atomic_mul_i2 + @ cdecl _vcomp_atomic_mul_i4(ptr long) vcomp._vcomp_atomic_mul_i4 +-@ stub _vcomp_atomic_mul_i8 ++@ cdecl _vcomp_atomic_mul_i8(ptr int64) vcomp._vcomp_atomic_mul_i8 + @ cdecl _vcomp_atomic_mul_r4(ptr float) vcomp._vcomp_atomic_mul_r4 + @ cdecl _vcomp_atomic_mul_r8(ptr double) vcomp._vcomp_atomic_mul_r8 + @ stub _vcomp_atomic_or_i1 + @ stub _vcomp_atomic_or_i2 + @ cdecl _vcomp_atomic_or_i4(ptr long) vcomp._vcomp_atomic_or_i4 +-@ stub _vcomp_atomic_or_i8 ++@ cdecl _vcomp_atomic_or_i8(ptr int64) vcomp._vcomp_atomic_or_i8 + @ stub _vcomp_atomic_shl_i1 + @ stub _vcomp_atomic_shl_i2 + @ cdecl _vcomp_atomic_shl_i4(ptr long) vcomp._vcomp_atomic_shl_i4 +-@ stub _vcomp_atomic_shl_i8 ++@ cdecl _vcomp_atomic_shl_i8(ptr long) vcomp._vcomp_atomic_shl_i8 + @ stub _vcomp_atomic_shr_i1 + @ stub _vcomp_atomic_shr_i2 + @ cdecl _vcomp_atomic_shr_i4(ptr long) vcomp._vcomp_atomic_shr_i4 +-@ stub _vcomp_atomic_shr_i8 ++@ cdecl _vcomp_atomic_shr_i8(ptr long) vcomp._vcomp_atomic_shr_i8 + @ stub _vcomp_atomic_shr_ui1 + @ stub _vcomp_atomic_shr_ui2 + @ cdecl _vcomp_atomic_shr_ui4(ptr long) vcomp._vcomp_atomic_shr_ui4 +-@ stub _vcomp_atomic_shr_ui8 ++@ cdecl _vcomp_atomic_shr_ui8(ptr long) vcomp._vcomp_atomic_shr_ui8 + @ stub _vcomp_atomic_sub_i1 + @ stub _vcomp_atomic_sub_i2 + @ cdecl _vcomp_atomic_sub_i4(ptr long) vcomp._vcomp_atomic_sub_i4 +-@ stub _vcomp_atomic_sub_i8 ++@ cdecl _vcomp_atomic_sub_i8(ptr int64) vcomp._vcomp_atomic_sub_i8 + @ cdecl _vcomp_atomic_sub_r4(ptr float) vcomp._vcomp_atomic_sub_r4 + @ cdecl _vcomp_atomic_sub_r8(ptr double) vcomp._vcomp_atomic_sub_r8 + @ stub _vcomp_atomic_xor_i1 + @ stub _vcomp_atomic_xor_i2 + @ cdecl _vcomp_atomic_xor_i4(ptr long) vcomp._vcomp_atomic_xor_i4 +-@ stub _vcomp_atomic_xor_i8 ++@ cdecl _vcomp_atomic_xor_i8(ptr int64) vcomp._vcomp_atomic_xor_i8 + @ cdecl _vcomp_barrier() vcomp._vcomp_barrier + @ stub _vcomp_copyprivate_broadcast + @ stub _vcomp_copyprivate_receive +diff --git a/dlls/vcomp110/vcomp110.spec b/dlls/vcomp110/vcomp110.spec +index 87a7205..8389d27 100644 +--- a/dlls/vcomp110/vcomp110.spec ++++ b/dlls/vcomp110/vcomp110.spec +@@ -2,55 +2,55 @@ + @ stub _vcomp_atomic_add_i1 + @ stub _vcomp_atomic_add_i2 + @ cdecl _vcomp_atomic_add_i4(ptr long) vcomp._vcomp_atomic_add_i4 +-@ stub _vcomp_atomic_add_i8 ++@ cdecl _vcomp_atomic_add_i8(ptr int64) vcomp._vcomp_atomic_add_i8 + @ cdecl _vcomp_atomic_add_r4(ptr float) vcomp._vcomp_atomic_add_r4 + @ cdecl _vcomp_atomic_add_r8(ptr double) vcomp._vcomp_atomic_add_r8 + @ stub _vcomp_atomic_and_i1 + @ stub _vcomp_atomic_and_i2 + @ cdecl _vcomp_atomic_and_i4(ptr long) vcomp._vcomp_atomic_and_i4 +-@ stub _vcomp_atomic_and_i8 ++@ cdecl _vcomp_atomic_and_i8(ptr int64) vcomp._vcomp_atomic_and_i8 + @ stub _vcomp_atomic_div_i1 + @ stub _vcomp_atomic_div_i2 + @ cdecl _vcomp_atomic_div_i4(ptr long) vcomp._vcomp_atomic_div_i4 +-@ stub _vcomp_atomic_div_i8 ++@ cdecl _vcomp_atomic_div_i8(ptr int64) vcomp._vcomp_atomic_div_i8 + @ cdecl _vcomp_atomic_div_r4(ptr float) vcomp._vcomp_atomic_div_r4 + @ cdecl _vcomp_atomic_div_r8(ptr double) vcomp._vcomp_atomic_div_r8 + @ stub _vcomp_atomic_div_ui1 + @ stub _vcomp_atomic_div_ui2 + @ cdecl _vcomp_atomic_div_ui4(ptr long) vcomp._vcomp_atomic_div_ui4 +-@ stub _vcomp_atomic_div_ui8 ++@ cdecl _vcomp_atomic_div_ui8(ptr int64) vcomp._vcomp_atomic_div_ui8 + @ stub _vcomp_atomic_mul_i1 + @ stub _vcomp_atomic_mul_i2 + @ cdecl _vcomp_atomic_mul_i4(ptr long) vcomp._vcomp_atomic_mul_i4 +-@ stub _vcomp_atomic_mul_i8 ++@ cdecl _vcomp_atomic_mul_i8(ptr int64) vcomp._vcomp_atomic_mul_i8 + @ cdecl _vcomp_atomic_mul_r4(ptr float) vcomp._vcomp_atomic_mul_r4 + @ cdecl _vcomp_atomic_mul_r8(ptr double) vcomp._vcomp_atomic_mul_r8 + @ stub _vcomp_atomic_or_i1 + @ stub _vcomp_atomic_or_i2 + @ cdecl _vcomp_atomic_or_i4(ptr long) vcomp._vcomp_atomic_or_i4 +-@ stub _vcomp_atomic_or_i8 ++@ cdecl _vcomp_atomic_or_i8(ptr int64) vcomp._vcomp_atomic_or_i8 + @ stub _vcomp_atomic_shl_i1 + @ stub _vcomp_atomic_shl_i2 + @ cdecl _vcomp_atomic_shl_i4(ptr long) vcomp._vcomp_atomic_shl_i4 +-@ stub _vcomp_atomic_shl_i8 ++@ cdecl _vcomp_atomic_shl_i8(ptr long) vcomp._vcomp_atomic_shl_i8 + @ stub _vcomp_atomic_shr_i1 + @ stub _vcomp_atomic_shr_i2 + @ cdecl _vcomp_atomic_shr_i4(ptr long) vcomp._vcomp_atomic_shr_i4 +-@ stub _vcomp_atomic_shr_i8 ++@ cdecl _vcomp_atomic_shr_i8(ptr long) vcomp._vcomp_atomic_shr_i8 + @ stub _vcomp_atomic_shr_ui1 + @ stub _vcomp_atomic_shr_ui2 + @ cdecl _vcomp_atomic_shr_ui4(ptr long) vcomp._vcomp_atomic_shr_ui4 +-@ stub _vcomp_atomic_shr_ui8 ++@ cdecl _vcomp_atomic_shr_ui8(ptr long) vcomp._vcomp_atomic_shr_ui8 + @ stub _vcomp_atomic_sub_i1 + @ stub _vcomp_atomic_sub_i2 + @ cdecl _vcomp_atomic_sub_i4(ptr long) vcomp._vcomp_atomic_sub_i4 +-@ stub _vcomp_atomic_sub_i8 ++@ cdecl _vcomp_atomic_sub_i8(ptr int64) vcomp._vcomp_atomic_sub_i8 + @ cdecl _vcomp_atomic_sub_r4(ptr float) vcomp._vcomp_atomic_sub_r4 + @ cdecl _vcomp_atomic_sub_r8(ptr double) vcomp._vcomp_atomic_sub_r8 + @ stub _vcomp_atomic_xor_i1 + @ stub _vcomp_atomic_xor_i2 + @ cdecl _vcomp_atomic_xor_i4(ptr long) vcomp._vcomp_atomic_xor_i4 +-@ stub _vcomp_atomic_xor_i8 ++@ cdecl _vcomp_atomic_xor_i8(ptr int64) vcomp._vcomp_atomic_xor_i8 + @ cdecl _vcomp_barrier() vcomp._vcomp_barrier + @ stub _vcomp_copyprivate_broadcast + @ stub _vcomp_copyprivate_receive +diff --git a/dlls/vcomp120/vcomp120.spec b/dlls/vcomp120/vcomp120.spec +index 87a7205..8389d27 100644 +--- a/dlls/vcomp120/vcomp120.spec ++++ b/dlls/vcomp120/vcomp120.spec +@@ -2,55 +2,55 @@ + @ stub _vcomp_atomic_add_i1 + @ stub _vcomp_atomic_add_i2 + @ cdecl _vcomp_atomic_add_i4(ptr long) vcomp._vcomp_atomic_add_i4 +-@ stub _vcomp_atomic_add_i8 ++@ cdecl _vcomp_atomic_add_i8(ptr int64) vcomp._vcomp_atomic_add_i8 + @ cdecl _vcomp_atomic_add_r4(ptr float) vcomp._vcomp_atomic_add_r4 + @ cdecl _vcomp_atomic_add_r8(ptr double) vcomp._vcomp_atomic_add_r8 + @ stub _vcomp_atomic_and_i1 + @ stub _vcomp_atomic_and_i2 + @ cdecl _vcomp_atomic_and_i4(ptr long) vcomp._vcomp_atomic_and_i4 +-@ stub _vcomp_atomic_and_i8 ++@ cdecl _vcomp_atomic_and_i8(ptr int64) vcomp._vcomp_atomic_and_i8 + @ stub _vcomp_atomic_div_i1 + @ stub _vcomp_atomic_div_i2 + @ cdecl _vcomp_atomic_div_i4(ptr long) vcomp._vcomp_atomic_div_i4 +-@ stub _vcomp_atomic_div_i8 ++@ cdecl _vcomp_atomic_div_i8(ptr int64) vcomp._vcomp_atomic_div_i8 + @ cdecl _vcomp_atomic_div_r4(ptr float) vcomp._vcomp_atomic_div_r4 + @ cdecl _vcomp_atomic_div_r8(ptr double) vcomp._vcomp_atomic_div_r8 + @ stub _vcomp_atomic_div_ui1 + @ stub _vcomp_atomic_div_ui2 + @ cdecl _vcomp_atomic_div_ui4(ptr long) vcomp._vcomp_atomic_div_ui4 +-@ stub _vcomp_atomic_div_ui8 ++@ cdecl _vcomp_atomic_div_ui8(ptr int64) vcomp._vcomp_atomic_div_ui8 + @ stub _vcomp_atomic_mul_i1 + @ stub _vcomp_atomic_mul_i2 + @ cdecl _vcomp_atomic_mul_i4(ptr long) vcomp._vcomp_atomic_mul_i4 +-@ stub _vcomp_atomic_mul_i8 ++@ cdecl _vcomp_atomic_mul_i8(ptr int64) vcomp._vcomp_atomic_mul_i8 + @ cdecl _vcomp_atomic_mul_r4(ptr float) vcomp._vcomp_atomic_mul_r4 + @ cdecl _vcomp_atomic_mul_r8(ptr double) vcomp._vcomp_atomic_mul_r8 + @ stub _vcomp_atomic_or_i1 + @ stub _vcomp_atomic_or_i2 + @ cdecl _vcomp_atomic_or_i4(ptr long) vcomp._vcomp_atomic_or_i4 +-@ stub _vcomp_atomic_or_i8 ++@ cdecl _vcomp_atomic_or_i8(ptr int64) vcomp._vcomp_atomic_or_i8 + @ stub _vcomp_atomic_shl_i1 + @ stub _vcomp_atomic_shl_i2 + @ cdecl _vcomp_atomic_shl_i4(ptr long) vcomp._vcomp_atomic_shl_i4 +-@ stub _vcomp_atomic_shl_i8 ++@ cdecl _vcomp_atomic_shl_i8(ptr long) vcomp._vcomp_atomic_shl_i8 + @ stub _vcomp_atomic_shr_i1 + @ stub _vcomp_atomic_shr_i2 + @ cdecl _vcomp_atomic_shr_i4(ptr long) vcomp._vcomp_atomic_shr_i4 +-@ stub _vcomp_atomic_shr_i8 ++@ cdecl _vcomp_atomic_shr_i8(ptr long) vcomp._vcomp_atomic_shr_i8 + @ stub _vcomp_atomic_shr_ui1 + @ stub _vcomp_atomic_shr_ui2 + @ cdecl _vcomp_atomic_shr_ui4(ptr long) vcomp._vcomp_atomic_shr_ui4 +-@ stub _vcomp_atomic_shr_ui8 ++@ cdecl _vcomp_atomic_shr_ui8(ptr long) vcomp._vcomp_atomic_shr_ui8 + @ stub _vcomp_atomic_sub_i1 + @ stub _vcomp_atomic_sub_i2 + @ cdecl _vcomp_atomic_sub_i4(ptr long) vcomp._vcomp_atomic_sub_i4 +-@ stub _vcomp_atomic_sub_i8 ++@ cdecl _vcomp_atomic_sub_i8(ptr int64) vcomp._vcomp_atomic_sub_i8 + @ cdecl _vcomp_atomic_sub_r4(ptr float) vcomp._vcomp_atomic_sub_r4 + @ cdecl _vcomp_atomic_sub_r8(ptr double) vcomp._vcomp_atomic_sub_r8 + @ stub _vcomp_atomic_xor_i1 + @ stub _vcomp_atomic_xor_i2 + @ cdecl _vcomp_atomic_xor_i4(ptr long) vcomp._vcomp_atomic_xor_i4 +-@ stub _vcomp_atomic_xor_i8 ++@ cdecl _vcomp_atomic_xor_i8(ptr int64) vcomp._vcomp_atomic_xor_i8 + @ cdecl _vcomp_barrier() vcomp._vcomp_barrier + @ stub _vcomp_copyprivate_broadcast + @ stub _vcomp_copyprivate_receive +diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec +index 849125f..ba1f414 100644 +--- a/dlls/vcomp90/vcomp90.spec ++++ b/dlls/vcomp90/vcomp90.spec +@@ -1,55 +1,55 @@ + @ stub _vcomp_atomic_add_i1 + @ stub _vcomp_atomic_add_i2 + @ cdecl _vcomp_atomic_add_i4(ptr long) vcomp._vcomp_atomic_add_i4 +-@ stub _vcomp_atomic_add_i8 ++@ cdecl _vcomp_atomic_add_i8(ptr int64) vcomp._vcomp_atomic_add_i8 + @ cdecl _vcomp_atomic_add_r4(ptr float) vcomp._vcomp_atomic_add_r4 + @ cdecl _vcomp_atomic_add_r8(ptr double) vcomp._vcomp_atomic_add_r8 + @ stub _vcomp_atomic_and_i1 + @ stub _vcomp_atomic_and_i2 + @ cdecl _vcomp_atomic_and_i4(ptr long) vcomp._vcomp_atomic_and_i4 +-@ stub _vcomp_atomic_and_i8 ++@ cdecl _vcomp_atomic_and_i8(ptr int64) vcomp._vcomp_atomic_and_i8 + @ stub _vcomp_atomic_div_i1 + @ stub _vcomp_atomic_div_i2 + @ cdecl _vcomp_atomic_div_i4(ptr long) vcomp._vcomp_atomic_div_i4 +-@ stub _vcomp_atomic_div_i8 ++@ cdecl _vcomp_atomic_div_i8(ptr int64) vcomp._vcomp_atomic_div_i8 + @ cdecl _vcomp_atomic_div_r4(ptr float) vcomp._vcomp_atomic_div_r4 + @ cdecl _vcomp_atomic_div_r8(ptr double) vcomp._vcomp_atomic_div_r8 + @ stub _vcomp_atomic_div_ui1 + @ stub _vcomp_atomic_div_ui2 + @ cdecl _vcomp_atomic_div_ui4(ptr long) vcomp._vcomp_atomic_div_ui4 +-@ stub _vcomp_atomic_div_ui8 ++@ cdecl _vcomp_atomic_div_ui8(ptr int64) vcomp._vcomp_atomic_div_ui8 + @ stub _vcomp_atomic_mul_i1 + @ stub _vcomp_atomic_mul_i2 + @ cdecl _vcomp_atomic_mul_i4(ptr long) vcomp._vcomp_atomic_mul_i4 +-@ stub _vcomp_atomic_mul_i8 ++@ cdecl _vcomp_atomic_mul_i8(ptr int64) vcomp._vcomp_atomic_mul_i8 + @ cdecl _vcomp_atomic_mul_r4(ptr float) vcomp._vcomp_atomic_mul_r4 + @ cdecl _vcomp_atomic_mul_r8(ptr double) vcomp._vcomp_atomic_mul_r8 + @ stub _vcomp_atomic_or_i1 + @ stub _vcomp_atomic_or_i2 + @ cdecl _vcomp_atomic_or_i4(ptr long) vcomp._vcomp_atomic_or_i4 +-@ stub _vcomp_atomic_or_i8 ++@ cdecl _vcomp_atomic_or_i8(ptr int64) vcomp._vcomp_atomic_or_i8 + @ stub _vcomp_atomic_shl_i1 + @ stub _vcomp_atomic_shl_i2 + @ cdecl _vcomp_atomic_shl_i4(ptr long) vcomp._vcomp_atomic_shl_i4 +-@ stub _vcomp_atomic_shl_i8 ++@ cdecl _vcomp_atomic_shl_i8(ptr long) vcomp._vcomp_atomic_shl_i8 + @ stub _vcomp_atomic_shr_i1 + @ stub _vcomp_atomic_shr_i2 + @ cdecl _vcomp_atomic_shr_i4(ptr long) vcomp._vcomp_atomic_shr_i4 +-@ stub _vcomp_atomic_shr_i8 ++@ cdecl _vcomp_atomic_shr_i8(ptr long) vcomp._vcomp_atomic_shr_i8 + @ stub _vcomp_atomic_shr_ui1 + @ stub _vcomp_atomic_shr_ui2 + @ cdecl _vcomp_atomic_shr_ui4(ptr long) vcomp._vcomp_atomic_shr_ui4 +-@ stub _vcomp_atomic_shr_ui8 ++@ cdecl _vcomp_atomic_shr_ui8(ptr long) vcomp._vcomp_atomic_shr_ui8 + @ stub _vcomp_atomic_sub_i1 + @ stub _vcomp_atomic_sub_i2 + @ cdecl _vcomp_atomic_sub_i4(ptr long) vcomp._vcomp_atomic_sub_i4 +-@ stub _vcomp_atomic_sub_i8 ++@ cdecl _vcomp_atomic_sub_i8(ptr int64) vcomp._vcomp_atomic_sub_i8 + @ cdecl _vcomp_atomic_sub_r4(ptr float) vcomp._vcomp_atomic_sub_r4 + @ cdecl _vcomp_atomic_sub_r8(ptr double) vcomp._vcomp_atomic_sub_r8 + @ stub _vcomp_atomic_xor_i1 + @ stub _vcomp_atomic_xor_i2 + @ cdecl _vcomp_atomic_xor_i4(ptr long) vcomp._vcomp_atomic_xor_i4 +-@ stub _vcomp_atomic_xor_i8 ++@ cdecl _vcomp_atomic_xor_i8(ptr int64) vcomp._vcomp_atomic_xor_i8 + @ cdecl _vcomp_barrier() vcomp._vcomp_barrier + @ stub _vcomp_copyprivate_broadcast + @ stub _vcomp_copyprivate_receive +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/vcomp-Atomic_I8/0003-vcomp-tests-Add-tests-for-64-bit-atomic-instructions.patch wine-staging-1.9.3~ubuntu12.04.1/patches/vcomp-Atomic_I8/0003-vcomp-tests-Add-tests-for-64-bit-atomic-instructions.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/vcomp-Atomic_I8/0003-vcomp-tests-Add-tests-for-64-bit-atomic-instructions.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/vcomp-Atomic_I8/0003-vcomp-tests-Add-tests-for-64-bit-atomic-instructions.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,249 @@ +From 351810ed0612e63620ec612eee12b15e962de6bc Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 14 Jan 2016 07:22:32 +0100 +Subject: vcomp/tests: Add tests for 64-bit atomic instructions. + +--- + dlls/vcomp/tests/vcomp.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 147 insertions(+), 1 deletion(-) + +diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c +index 5c177df..d1c242e 100644 +--- a/dlls/vcomp/tests/vcomp.c ++++ b/dlls/vcomp/tests/vcomp.c +@@ -2,7 +2,7 @@ + * Unit test suite for vcomp + * + * Copyright 2012 Dan Kegel +- * Copyright 2015 Sebastian Lackner ++ * Copyright 2015-2016 Sebastian Lackner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -19,6 +19,7 @@ + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + ++#include + #include "wine/test.h" + + static char vcomp_manifest_file[MAX_PATH]; +@@ -35,24 +36,35 @@ typedef CRITICAL_SECTION *omp_lock_t; + typedef CRITICAL_SECTION *omp_nest_lock_t; + + static void (CDECL *p_vcomp_atomic_add_i4)(int *dest, int val); ++static void (CDECL *p_vcomp_atomic_add_i8)(LONG64 *dest, LONG64 val); + static void (CDECL *p_vcomp_atomic_add_r4)(float *dest, float val); + static void (CDECL *p_vcomp_atomic_add_r8)(double *dest, double val); + static void (CDECL *p_vcomp_atomic_and_i4)(int *dest, int val); ++static void (CDECL *p_vcomp_atomic_and_i8)(LONG64 *dest, LONG64 val); + static void (CDECL *p_vcomp_atomic_div_i4)(int *dest, int val); ++static void (CDECL *p_vcomp_atomic_div_i8)(LONG64 *dest, LONG64 val); + static void (CDECL *p_vcomp_atomic_div_r4)(float *dest, float val); + static void (CDECL *p_vcomp_atomic_div_r8)(double *dest, double val); + static void (CDECL *p_vcomp_atomic_div_ui4)(unsigned int *dest, unsigned int val); ++static void (CDECL *p_vcomp_atomic_div_ui8)(ULONG64 *dest, ULONG64 val); + static void (CDECL *p_vcomp_atomic_mul_i4)(int *dest, int val); ++static void (CDECL *p_vcomp_atomic_mul_i8)(LONG64 *dest, LONG64 val); + static void (CDECL *p_vcomp_atomic_mul_r4)(float *dest, float val); + static void (CDECL *p_vcomp_atomic_mul_r8)(double *dest, double val); + static void (CDECL *p_vcomp_atomic_or_i4)(int *dest, int val); ++static void (CDECL *p_vcomp_atomic_or_i8)(LONG64 *dest, LONG64 val); + static void (CDECL *p_vcomp_atomic_shl_i4)(int *dest, int val); ++static void (CDECL *p_vcomp_atomic_shl_i8)(LONG64 *dest, unsigned int val); + static void (CDECL *p_vcomp_atomic_shr_i4)(int *dest, int val); ++static void (CDECL *p_vcomp_atomic_shr_i8)(LONG64 *dest, unsigned int val); + static void (CDECL *p_vcomp_atomic_shr_ui4)(unsigned int *dest, unsigned int val); ++static void (CDECL *p_vcomp_atomic_shr_ui8)(ULONG64 *dest, unsigned int val); + static void (CDECL *p_vcomp_atomic_sub_i4)(int *dest, int val); ++static void (CDECL *p_vcomp_atomic_sub_i8)(LONG64 *dest, LONG64 val); + static void (CDECL *p_vcomp_atomic_sub_r4)(float *dest, float val); + static void (CDECL *p_vcomp_atomic_sub_r8)(double *dest, double val); + static void (CDECL *p_vcomp_atomic_xor_i4)(int *dest, int val); ++static void (CDECL *p_vcomp_atomic_xor_i8)(LONG64 *dest, LONG64 val); + static void (CDECL *p_vcomp_barrier)(void); + static void (CDECL *p_vcomp_enter_critsect)(CRITICAL_SECTION **critsect); + static void (CDECL *p_vcomp_flush)(void); +@@ -134,6 +146,16 @@ static const char vcomp_manifest[] = + + #undef ARCH + ++static const char *debugstr_longlong(ULONGLONG ll) ++{ ++ static char str[17]; ++ if (sizeof(ll) > sizeof(unsigned long) && ll >> 32) ++ sprintf(str, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll); ++ else ++ sprintf(str, "%lx", (unsigned long)ll); ++ return str; ++} ++ + static void create_vcomp_manifest(void) + { + char temp_path[MAX_PATH]; +@@ -228,24 +250,35 @@ static BOOL init_vcomp(void) + } + + VCOMP_GET_PROC(_vcomp_atomic_add_i4); ++ VCOMP_GET_PROC(_vcomp_atomic_add_i8); + VCOMP_GET_PROC(_vcomp_atomic_add_r4); + VCOMP_GET_PROC(_vcomp_atomic_add_r8); + VCOMP_GET_PROC(_vcomp_atomic_and_i4); ++ VCOMP_GET_PROC(_vcomp_atomic_and_i8); + VCOMP_GET_PROC(_vcomp_atomic_div_i4); ++ VCOMP_GET_PROC(_vcomp_atomic_div_i8); + VCOMP_GET_PROC(_vcomp_atomic_div_r4); + VCOMP_GET_PROC(_vcomp_atomic_div_r8); + VCOMP_GET_PROC(_vcomp_atomic_div_ui4); ++ VCOMP_GET_PROC(_vcomp_atomic_div_ui8); + VCOMP_GET_PROC(_vcomp_atomic_mul_i4); ++ VCOMP_GET_PROC(_vcomp_atomic_mul_i8); + VCOMP_GET_PROC(_vcomp_atomic_mul_r4); + VCOMP_GET_PROC(_vcomp_atomic_mul_r8); + VCOMP_GET_PROC(_vcomp_atomic_or_i4); ++ VCOMP_GET_PROC(_vcomp_atomic_or_i8); + VCOMP_GET_PROC(_vcomp_atomic_shl_i4); ++ VCOMP_GET_PROC(_vcomp_atomic_shl_i8); + VCOMP_GET_PROC(_vcomp_atomic_shr_i4); ++ VCOMP_GET_PROC(_vcomp_atomic_shr_i8); + VCOMP_GET_PROC(_vcomp_atomic_shr_ui4); ++ VCOMP_GET_PROC(_vcomp_atomic_shr_ui8); + VCOMP_GET_PROC(_vcomp_atomic_sub_i4); ++ VCOMP_GET_PROC(_vcomp_atomic_sub_i8); + VCOMP_GET_PROC(_vcomp_atomic_sub_r4); + VCOMP_GET_PROC(_vcomp_atomic_sub_r8); + VCOMP_GET_PROC(_vcomp_atomic_xor_i4); ++ VCOMP_GET_PROC(_vcomp_atomic_xor_i8); + VCOMP_GET_PROC(_vcomp_barrier); + VCOMP_GET_PROC(_vcomp_enter_critsect); + VCOMP_GET_PROC(_vcomp_flush); +@@ -1447,6 +1480,118 @@ static void test_atomic_integer32(void) + } + } + ++static void test_atomic_integer64(void) ++{ ++ struct ++ { ++ void (CDECL *func)(LONG64 *, LONG64); ++ LONG64 v1, v2, expected; ++ } ++ tests1[] = ++ { ++ { p_vcomp_atomic_add_i8, 0x1122334455667788, 0x7766554433221100, -0x7777777777777778 }, ++ { p_vcomp_atomic_and_i8, 0x1122334455667788, 0x7766554433221100, 0x1122114411221100 }, ++ { p_vcomp_atomic_div_i8, 0x7766554433221100, 0x1122334455667788, 6 }, ++ { p_vcomp_atomic_div_i8, 0x7766554433221100, -0x1122334455667788, -6 }, ++ { p_vcomp_atomic_mul_i8, 0x1122334455667788, 0x7766554433221100, 0x3e963337c6000800 }, ++ { p_vcomp_atomic_mul_i8, 0x1122334455667788, -0x7766554433221100, 0xc169ccc839fff800 }, ++ { p_vcomp_atomic_or_i8, 0x1122334455667788, 0x7766554433221100, 0x7766774477667788 }, ++ { p_vcomp_atomic_sub_i8, 0x1122334455667788, 0x7766554433221100, -0x664421ffddbb9978 }, ++ { p_vcomp_atomic_xor_i8, 0x1122334455667788, 0x7766554433221100, 0x6644660066446688 }, ++ }; ++ struct ++ { ++ void (CDECL *func)(LONG64 *, unsigned int); ++ LONG64 v1; ++ unsigned int v2; ++ LONG64 expected; ++ BOOL todo; ++ } ++ tests2[] = ++ { ++ { p_vcomp_atomic_shl_i8, 0x1122334455667788, 3, -0x76ee65dd54cc43c0 }, ++ { p_vcomp_atomic_shl_i8, 0x1122334455667788, 60, 0x8000000000000000 }, ++ { p_vcomp_atomic_shl_i8, -0x1122334455667788, 3, 0x76ee65dd54cc43c0 }, ++ { p_vcomp_atomic_shr_i8, 0x1122334455667788, 3, 0x22446688aaccef1 }, ++ { p_vcomp_atomic_shr_i8, 0x1122334455667788, 60, 1 }, ++ { p_vcomp_atomic_shr_i8, -0x1122334455667788, 3, -0x22446688aaccef1 }, ++ #if defined(__i386__) ++ { p_vcomp_atomic_shl_i8, 0x1122334455667788, 64, 0, TRUE }, ++ { p_vcomp_atomic_shl_i8, 0x1122334455667788, 67, 0, TRUE }, ++ { p_vcomp_atomic_shr_i8, 0x1122334455667788, 64, 0, TRUE }, ++ { p_vcomp_atomic_shr_i8, 0x1122334455667788, 67, 0, TRUE }, ++ #elif defined(__x86_64__) ++ { p_vcomp_atomic_shl_i8, 0x1122334455667788, 64, 0x1122334455667788 }, ++ { p_vcomp_atomic_shl_i8, 0x1122334455667788, 67, -0x76ee65dd54cc43c0 }, ++ { p_vcomp_atomic_shr_i8, 0x1122334455667788, 64, 0x1122334455667788 }, ++ { p_vcomp_atomic_shr_i8, 0x1122334455667788, 67, 0x22446688aaccef1 }, ++ #endif ++ }; ++ struct ++ { ++ void (CDECL *func)(ULONG64 *, ULONG64); ++ ULONG64 v1, v2, expected; ++ } ++ tests3[] = ++ { ++ { p_vcomp_atomic_div_ui8, 0x7766554455667788, 0x1122334433221100, 6 }, ++ { p_vcomp_atomic_div_ui8, 0x7766554455667788, 0xeeddccbbaa998878, 0 }, ++ }; ++ struct ++ { ++ void (CDECL *func)(ULONG64 *, unsigned int); ++ ULONG64 v1; ++ unsigned int v2; ++ ULONG64 expected; ++ BOOL todo; ++ } ++ tests4[] = ++ { ++ { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 3, 0x22446688aaccef1 }, ++ { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 60, 1 }, ++ { p_vcomp_atomic_shr_ui8, 0xeeddccbbaa998878, 3, 0x1ddbb9977553310f }, ++ #if defined(__i386__) ++ { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 64, 0, TRUE }, ++ { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 67, 0, TRUE }, ++ #elif defined(__x86_64__) ++ { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 64, 0x1122334455667788 }, ++ { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 67, 0x22446688aaccef1 }, ++ #endif ++ }; ++ int i; ++ ++ for (i = 0; i < sizeof(tests1)/sizeof(tests1[0]); i++) ++ { ++ LONG64 val = tests1[i].v1; ++ tests1[i].func(&val, tests1[i].v2); ++ ok(val == tests1[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val)); ++ } ++ for (i = 0; i < sizeof(tests2)/sizeof(tests2[0]); i++) ++ { ++ LONG64 val = tests2[i].v1; ++ tests2[i].func(&val, tests2[i].v2); ++ if (!tests2[i].todo) ++ ok(val == tests2[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val)); ++ else todo_wine ++ ok(val == tests2[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val)); ++ } ++ for (i = 0; i < sizeof(tests3)/sizeof(tests3[0]); i++) ++ { ++ ULONG64 val = tests3[i].v1; ++ tests3[i].func(&val, tests3[i].v2); ++ ok(val == tests3[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val)); ++ } ++ for (i = 0; i < sizeof(tests4)/sizeof(tests4[0]); i++) ++ { ++ ULONG64 val = tests4[i].v1; ++ tests4[i].func(&val, tests4[i].v2); ++ if (!tests4[i].todo) ++ ok(val == tests4[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val)); ++ else todo_wine ++ ok(val == tests4[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val)); ++ } ++} ++ + static void test_atomic_float(void) + { + struct +@@ -1516,6 +1661,7 @@ START_TEST(vcomp) + test_omp_init_lock(); + test_omp_init_nest_lock(); + test_atomic_integer32(); ++ test_atomic_integer64(); + test_atomic_float(); + test_atomic_double(); + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/vcomp-Atomic_I8/definition wine-staging-1.9.3~ubuntu12.04.1/patches/vcomp-Atomic_I8/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/vcomp-Atomic_I8/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/vcomp-Atomic_I8/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Implement 64-bit atomic instructions in OpenMP diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/vmm.vxd-PageReserve/0001-vmm.vxd-Fix-protection-flags-passed-to-VirtualAlloc.patch wine-staging-1.9.3~ubuntu12.04.1/patches/vmm.vxd-PageReserve/0001-vmm.vxd-Fix-protection-flags-passed-to-VirtualAlloc.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/vmm.vxd-PageReserve/0001-vmm.vxd-Fix-protection-flags-passed-to-VirtualAlloc.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/vmm.vxd-PageReserve/0001-vmm.vxd-Fix-protection-flags-passed-to-VirtualAlloc.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,25 @@ +From d0c4bb573627e7e8ea1295bd781ee58c25a8c769 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 9 Jan 2016 21:20:28 +0100 +Subject: vmm.vxd: Fix protection flags passed to VirtualAlloc. + +--- + dlls/vmm.vxd/vmm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/vmm.vxd/vmm.c b/dlls/vmm.vxd/vmm.c +index 7327f78..833a8d1 100644 +--- a/dlls/vmm.vxd/vmm.c ++++ b/dlls/vmm.vxd/vmm.c +@@ -159,7 +159,7 @@ DWORD WINAPI VMM_VxDCall( DWORD service, CONTEXT *context ) + if ( page == PR_PRIVATE || page == PR_SHARED ) page = 0; + /* FIXME: Handle flags in some way */ + address = (LPVOID )(page * page_size); +- ret = VirtualAlloc ( address, npages * page_size, MEM_RESERVE, 0 ); ++ ret = VirtualAlloc ( address, npages * page_size, MEM_RESERVE, PAGE_EXECUTE_READWRITE ); + TRACE("PageReserve: returning: %p\n", ret ); + if ( ret == NULL ) + return -1; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/vmm.vxd-PageReserve/definition wine-staging-1.9.3~ubuntu12.04.1/patches/vmm.vxd-PageReserve/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/vmm.vxd-PageReserve/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/vmm.vxd-PageReserve/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [36013] Fix protection flags passed to VirtualAlloc call in PageReserve VxDCall diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0001-widl-Add-initial-implementation-of-SLTG-typelib-gene.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0001-widl-Add-initial-implementation-of-SLTG-typelib-gene.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0001-widl-Add-initial-implementation-of-SLTG-typelib-gene.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0001-widl-Add-initial-implementation-of-SLTG-typelib-gene.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,654 @@ +From 1db2c2426a44579d03fc166e19ee4d3b3fcb861b Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Wed, 23 Dec 2015 19:37:37 +0800 +Subject: widl: Add initial implementation of SLTG typelib generator. + +--- + tools/widl/Makefile.in | 3 +- + tools/widl/typelib.c | 5 +- + tools/widl/typelib.h | 1 + + tools/widl/widl.c | 8 +- + tools/widl/write_sltg.c | 558 ++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 572 insertions(+), 3 deletions(-) + create mode 100644 tools/widl/write_sltg.c + +diff --git a/tools/widl/Makefile.in b/tools/widl/Makefile.in +index f8111f3..c2f1638 100644 +--- a/tools/widl/Makefile.in ++++ b/tools/widl/Makefile.in +@@ -14,7 +14,8 @@ C_SRCS = \ + typetree.c \ + utils.c \ + widl.c \ +- write_msft.c ++ write_msft.c \ ++ write_sltg.c \ + + LEX_SRCS = parser.l + BISON_SRCS = parser.y +diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c +index 6ac748f..aa3305c 100644 +--- a/tools/widl/typelib.c ++++ b/tools/widl/typelib.c +@@ -249,7 +249,10 @@ void end_typelib(void) + { + if (!typelib) return; + +- create_msft_typelib(typelib); ++ if (do_typelib == 2) ++ create_sltg_typelib(typelib); ++ else ++ create_msft_typelib(typelib); + } + + static void tlb_read(int fd, void *buf, int count) +diff --git a/tools/widl/typelib.h b/tools/widl/typelib.h +index 18e6cdb..31f4a5a 100644 +--- a/tools/widl/typelib.h ++++ b/tools/widl/typelib.h +@@ -85,4 +85,5 @@ enum VARENUM { + extern unsigned short get_type_vt(type_t *t); + + extern int create_msft_typelib(typelib_t *typelib); ++extern int create_sltg_typelib(typelib_t *typelib); + #endif +diff --git a/tools/widl/widl.c b/tools/widl/widl.c +index a38f917..1180e65 100644 +--- a/tools/widl/widl.c ++++ b/tools/widl/widl.c +@@ -163,7 +163,8 @@ enum { + WIN64_OPTION, + WIN32_ALIGN_OPTION, + WIN64_ALIGN_OPTION, +- APP_CONFIG_OPTION ++ APP_CONFIG_OPTION, ++ OLD_TYPELIB_OPTION + }; + + static const char short_options[] = +@@ -185,6 +186,7 @@ static const struct option long_options[] = { + { "win32-align", 1, NULL, WIN32_ALIGN_OPTION }, + { "win64-align", 1, NULL, WIN64_ALIGN_OPTION }, + { "app_config", 0, NULL, APP_CONFIG_OPTION }, ++ { "oldtlb", 0, NULL, OLD_TYPELIB_OPTION }, + { NULL, 0, NULL, 0 } + }; + +@@ -679,6 +681,10 @@ int main(int argc,char *argv[]) + do_everything = 0; + do_typelib = 1; + break; ++ case OLD_TYPELIB_OPTION: ++ do_everything = 0; ++ do_typelib = 2; ++ break; + case 'T': + typelib_name = xstrdup(optarg); + break; +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +new file mode 100644 +index 0000000..45cac80 +--- /dev/null ++++ b/tools/widl/write_sltg.c +@@ -0,0 +1,558 @@ ++/* ++ * Typelib (SLTG) generation ++ * ++ * Copyright 2015 Dmitry Timoshkov ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define NONAMELESSUNION ++ ++#include "windef.h" ++#include "winbase.h" ++ ++#include "widl.h" ++#include "typelib.h" ++#include "typelib_struct.h" ++#include "utils.h" ++#include "header.h" ++#include "typetree.h" ++ ++static const GUID sltg_library_guid = { 0x204ff,0,0,{ 0xc0,0,0,0,0,0,0,0x46 } }; ++ ++struct sltg_index ++{ ++ int size, allocated; ++ char *names; ++}; ++ ++struct sltg_name_table ++{ ++ int size, allocated; ++ char *names; ++}; ++ ++struct sltg_library ++{ ++ short name; ++ char *helpstring; ++ char *helpfile; ++ int helpcontext; ++ int syskind; ++ LCID lcid; ++ int libflags; ++ int version; ++ GUID uuid; ++}; ++ ++struct sltg_block ++{ ++ int length; ++ int index_string; ++ void *data; ++ struct sltg_block *next; ++}; ++ ++struct sltg_typelib ++{ ++ typelib_t *typelib; ++ struct sltg_index index; ++ struct sltg_name_table name_table; ++ struct sltg_library library; ++ struct sltg_block *blocks; ++ int n_file_blocks; ++ int first_block; ++ int typeinfo_count; ++}; ++ ++static int add_index(struct sltg_index *index, const char *name) ++{ ++ int name_offset = index->size; ++ int new_size = index->size + strlen(name) + 1; ++ ++ if (new_size > index->allocated) ++ { ++ index->allocated = max(index->allocated * 2, new_size); ++ index->names = xrealloc(index->names, index->allocated); ++ } ++ ++ strcpy(index->names + index->size, name); ++ index->size = new_size; ++ ++ return name_offset; ++} ++ ++static void init_index(struct sltg_index *index) ++{ ++ static const char compobj[] = { 1,'C','o','m','p','O','b','j',0 }; ++ ++ index->size = 0; ++ index->allocated = 0x10; ++ index->names = xmalloc(0x10); ++ ++ add_index(index, compobj); ++} ++ ++static int add_name(struct sltg_name_table *name_table, const char *name) ++{ ++ int name_offset = name_table->size; ++ int new_size = name_table->size + strlen(name) + 1 + 8; ++ ++ new_size = (new_size + 1) & ~1; /* align */ ++ ++ if (new_size > name_table->allocated) ++ { ++ name_table->allocated = max(name_table->allocated * 2, new_size); ++ name_table->names = xrealloc(name_table->names, name_table->allocated); ++ } ++ ++ memset(name_table->names + name_table->size, 0xff, 8); ++ strcpy(name_table->names + name_table->size + 8, name); ++ name_table->size = new_size; ++ name_table->names[name_table->size - 1] = 0; /* clear alignment */ ++ ++ return name_offset; ++} ++ ++static void init_name_table(struct sltg_name_table *name_table) ++{ ++ name_table->size = 0; ++ name_table->allocated = 0x10; ++ name_table->names = xmalloc(0x10); ++} ++ ++static void init_library(struct sltg_typelib *sltg) ++{ ++ const attr_t *attr; ++ ++ sltg->library.name = add_name(&sltg->name_table, sltg->typelib->name); ++ sltg->library.helpstring = NULL; ++ sltg->library.helpcontext = 0; ++ sltg->library.syskind = SYS_WIN32; ++ sltg->library.lcid = 0x0409; ++ sltg->library.libflags = 0; ++ sltg->library.version = 0; ++ sltg->library.helpfile = NULL; ++ memset(&sltg->library.uuid, 0, sizeof(sltg->library.uuid)); ++ ++ if (!sltg->typelib->attrs) return; ++ ++ LIST_FOR_EACH_ENTRY(attr, sltg->typelib->attrs, const attr_t, entry) ++ { ++ const expr_t *expr; ++ ++ switch (attr->type) ++ { ++ case ATTR_VERSION: ++ sltg->library.version = attr->u.ival; ++ break; ++ case ATTR_HELPSTRING: ++ sltg->library.helpstring = attr->u.pval; ++ break; ++ case ATTR_HELPFILE: ++ sltg->library.helpfile = attr->u.pval; ++ break; ++ case ATTR_UUID: ++ sltg->library.uuid = *(GUID *)attr->u.pval; ++ break; ++ case ATTR_HELPCONTEXT: ++ expr = attr->u.pval; ++ sltg->library.helpcontext = expr->cval; ++ break; ++ case ATTR_LIBLCID: ++ expr = attr->u.pval; ++ sltg->library.lcid = expr->cval; ++ break; ++ case ATTR_CONTROL: ++ sltg->library.libflags |= 0x02; /* LIBFLAG_FCONTROL */ ++ break; ++ case ATTR_HIDDEN: ++ sltg->library.libflags |= 0x04; /* LIBFLAG_FHIDDEN */ ++ break; ++ case ATTR_RESTRICTED: ++ sltg->library.libflags |= 0x01; /* LIBFLAG_FRESTRICTED */ ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++static void add_block(struct sltg_typelib *sltg, void *data, int size, const char *name) ++{ ++ struct sltg_block *block = xmalloc(sizeof(*block)); ++ ++ block->length = size; ++ block->data = data; ++ block->index_string = add_index(&sltg->index, name); ++ block->next = sltg->blocks; ++ ++ sltg->blocks = block; ++ sltg->n_file_blocks++; ++} ++ ++static void add_library_block(struct sltg_typelib *typelib) ++{ ++ void *block; ++ short *p; ++ int size; ++ ++ size = sizeof(short) * 9 + sizeof(int) * 3 + sizeof(GUID); ++ if (typelib->library.helpstring) size += strlen(typelib->library.helpstring); ++ if (typelib->library.helpfile) size += strlen(typelib->library.helpfile); ++ ++ block = xmalloc(size); ++ p = block; ++ *p++ = 0x51cc; /* magic */ ++ *p++ = 3; /* res02 */ ++ *p++ = typelib->library.name; ++ *p++ = 0xffff; /* res06 */ ++ if (typelib->library.helpstring) ++ { ++ *p++ = strlen(typelib->library.helpstring); ++ strcpy((char *)p, typelib->library.helpstring); ++ p = (short *)((char *)p + strlen(typelib->library.helpstring)); ++ } ++ else ++ *p++ = 0xffff; ++ if (typelib->library.helpfile) ++ { ++ *p++ = strlen(typelib->library.helpfile); ++ strcpy((char *)p, typelib->library.helpfile); ++ p = (short *)((char *)p + strlen(typelib->library.helpfile)); ++ } ++ else ++ *p++ = 0xffff; ++ *(int *)p = typelib->library.helpcontext; ++ p += 2; ++ *p++ = typelib->library.syskind; ++ *p++ = typelib->library.lcid; ++ *(int *)p = 0; /* res12 */ ++ p += 2; ++ *p++ = typelib->library.libflags; ++ *(int *)p = typelib->library.version; ++ p += 2; ++ *(GUID *)p = typelib->library.uuid; ++ ++ add_block(typelib, block, size, "dir"); ++} ++ ++static void add_typedef_typeinfo(struct sltg_typelib *typelib, type_t *type) ++{ ++ error("add_typedef_typeinfo: %s not implemented\n", type->name); ++} ++ ++static void add_module_typeinfo(struct sltg_typelib *typelib, type_t *type) ++{ ++ error("add_module_typeinfo: %s not implemented\n", type->name); ++} ++ ++static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *type) ++{ ++ error("add_interface_typeinfo: %s not implemented\n", type->name); ++} ++ ++static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) ++{ ++ error("add_structure_typeinfo: %s not implemented\n", type->name); ++} ++ ++static void add_enum_typeinfo(struct sltg_typelib *typelib, type_t *type) ++{ ++ error("add_enum_typeinfo: %s not implemented\n", type->name); ++} ++ ++static void add_union_typeinfo(struct sltg_typelib *typelib, type_t *type) ++{ ++ error("add_union_typeinfo: %s not implemented\n", type->name); ++} ++ ++static void add_coclass_typeinfo(struct sltg_typelib *typelib, type_t *type) ++{ ++ error("add_coclass_typeinfo: %s not implemented\n", type->name); ++} ++ ++static void add_type_typeinfo(struct sltg_typelib *typelib, type_t *type) ++{ ++ chat("add_type_typeinfo: adding %s, type %d\n", type->name, type_get_type(type)); ++ ++ switch (type_get_type(type)) ++ { ++ case TYPE_INTERFACE: ++ add_interface_typeinfo(typelib, type); ++ break; ++ case TYPE_STRUCT: ++ add_structure_typeinfo(typelib, type); ++ break; ++ case TYPE_ENUM: ++ add_enum_typeinfo(typelib, type); ++ break; ++ case TYPE_UNION: ++ add_union_typeinfo(typelib, type); ++ break; ++ case TYPE_COCLASS: ++ add_coclass_typeinfo(typelib, type); ++ break; ++ case TYPE_BASIC: ++ case TYPE_POINTER: ++ break; ++ default: ++ error("add_type_typeinfo: unhandled type %d for %s\n", type_get_type(type), type->name); ++ break; ++ } ++} ++ ++static void add_statement(struct sltg_typelib *typelib, const statement_t *stmt) ++{ ++ switch(stmt->type) ++ { ++ case STMT_LIBRARY: ++ case STMT_IMPORT: ++ case STMT_PRAGMA: ++ case STMT_CPPQUOTE: ++ case STMT_DECLARATION: ++ /* not included in typelib */ ++ break; ++ case STMT_IMPORTLIB: ++ /* not processed here */ ++ break; ++ ++ case STMT_TYPEDEF: ++ { ++ const type_list_t *type_entry = stmt->u.type_list; ++ for (; type_entry; type_entry = type_entry->next) ++ { ++ /* if the type is public then add the typedef, otherwise attempt ++ * to add the aliased type */ ++ if (is_attr(type_entry->type->attrs, ATTR_PUBLIC)) ++ add_typedef_typeinfo(typelib, type_entry->type); ++ else ++ add_type_typeinfo(typelib, type_alias_get_aliasee(type_entry->type)); ++ } ++ break; ++ } ++ ++ case STMT_MODULE: ++ add_module_typeinfo(typelib, stmt->u.type); ++ break; ++ ++ case STMT_TYPE: ++ case STMT_TYPEREF: ++ { ++ type_t *type = stmt->u.type; ++ add_type_typeinfo(typelib, type); ++ break; ++ } ++ ++ default: ++ error("add_statement: unhandled statement type %d\n", stmt->type); ++ break; ++ } ++} ++ ++static void sltg_write_header(struct sltg_typelib *sltg, int *library_block_start) ++{ ++ char pad[0x40]; ++ struct sltg_header ++ { ++ int magic; ++ short n_file_blocks; ++ short res06; ++ short size_of_index; ++ short first_blk; ++ GUID uuid; ++ int res1c; ++ int res20; ++ } header; ++ struct sltg_block_entry ++ { ++ int length; ++ short index_string; ++ short next; ++ } entry; ++ struct sltg_block *block; ++ int i; ++ ++ header.magic = 0x47544c53; ++ header.n_file_blocks = sltg->n_file_blocks + 1; ++ header.res06 = 9; ++ header.size_of_index = sltg->index.size; ++ header.first_blk = 1; ++ header.uuid = sltg_library_guid; ++ header.res1c = 0x00000044; ++ header.res20 = 0xffff0000; ++ ++ put_data(&header, sizeof(header)); ++ ++ block = sltg->blocks; ++ for (i = 0; i < sltg->n_file_blocks - 1; i++) ++ { ++ assert(block->next != NULL); ++ ++ entry.length = block->length; ++ entry.index_string = block->index_string; ++ entry.next = header.first_blk + i; ++ put_data(&entry, sizeof(entry)); ++ ++ block = block->next; ++ } ++ ++ assert(block->next == NULL); ++ ++ /* library block length includes helpstrings and name table */ ++ entry.length = block->length + 0x40 + 2 + 4 + 6 + 12 + 0x200 + sltg->name_table.size + 12; ++ entry.index_string = block->index_string; ++ entry.next = 0; ++ put_data(&entry, sizeof(entry)); ++ ++ put_data(sltg->index.names, sltg->index.size); ++ memset(pad, 0, 9); ++ put_data(pad, 9); ++ ++ block = sltg->blocks; ++ for (i = 0; i < sltg->n_file_blocks - 1; i++) ++ { ++ chat("sltg_write_header: writing block %d: %d bytes\n", i, block->length); ++ ++ put_data(block->data, block->length); ++ block = block->next; ++ } ++ ++ assert(block->next == NULL); ++ ++ /* library block */ ++ *library_block_start = output_buffer_pos; ++ put_data(block->data, block->length); ++ ++ memset(pad, 0xff, 0x40); ++ put_data(pad, 0x40); ++} ++ ++static void sltg_write_typeinfo(struct sltg_typelib *typelib) ++{ ++ short count = typelib->typeinfo_count; ++ ++ put_data(&count, sizeof(count)); ++} ++ ++static void sltg_write_helpstrings(struct sltg_typelib *typelib) ++{ ++ static const char dummy[6]; ++ ++ put_data(dummy, sizeof(dummy)); ++} ++ ++static void sltg_write_nametable(struct sltg_typelib *typelib) ++{ ++ static const short dummy[6] = { 0xffff,1,2,0xff00,0xffff,0xffff }; ++ char pad[0x200]; ++ ++ put_data(dummy, sizeof(dummy)); ++ memset(pad, 0xff, 0x200); ++ put_data(pad, 0x200); ++ put_data(&typelib->name_table.size, sizeof(typelib->name_table.size)); ++ put_data(typelib->name_table.names, typelib->name_table.size); ++} ++ ++static void sltg_write_remainder(void) ++{ ++ static const short dummy1[] = { 1,0xfffe,0x0a03,0,0xffff,0xffff }; ++ static const short dummy2[] = { 0xffff,0xffff,0x0200,0,0,0 }; ++ static const char dummy3[] = { 0xf4,0x39,0xb2,0x71,0,0,0,0,0,0,0,0,0,0,0,0 }; ++ static const char TYPELIB[] = { 8,0,0,0,'T','Y','P','E','L','I','B',0 }; ++ int pad; ++ ++ pad = 0x01ffff01; ++ put_data(&pad, sizeof(pad)); ++ pad = 0; ++ put_data(&pad, sizeof(pad)); ++ ++ put_data(dummy1, sizeof(dummy1)); ++ ++ put_data(&sltg_library_guid, sizeof(sltg_library_guid)); ++ ++ put_data(TYPELIB, sizeof(TYPELIB)); ++ ++ put_data(dummy2, sizeof(dummy2)); ++ put_data(dummy3, sizeof(dummy3)); ++} ++ ++static void save_all_changes(struct sltg_typelib *typelib) ++{ ++ int library_block_start; ++ int *name_table_offset; ++ ++ sltg_write_header(typelib, &library_block_start); ++ sltg_write_typeinfo(typelib); ++ ++ name_table_offset = (int *)(output_buffer + output_buffer_pos); ++ put_data(&library_block_start, sizeof(library_block_start)); ++ ++ sltg_write_helpstrings(typelib); ++ ++ *name_table_offset = output_buffer_pos - library_block_start; ++ ++ sltg_write_nametable(typelib); ++ sltg_write_remainder(); ++ ++ if (strendswith(typelib_name, ".res")) /* create a binary resource file */ ++ { ++ char typelib_id[13] = "#1"; ++ ++ expr_t *expr = get_attrp(typelib->typelib->attrs, ATTR_ID); ++ if (expr) ++ sprintf(typelib_id, "#%d", expr->cval); ++ add_output_to_resources("TYPELIB", typelib_id); ++ output_typelib_regscript(typelib->typelib); ++ flush_output_resources(typelib_name); ++ } ++ else flush_output_buffer(typelib_name); ++} ++ ++int create_sltg_typelib(typelib_t *typelib) ++{ ++ struct sltg_typelib sltg; ++ const statement_t *stmt; ++ ++ sltg.typelib = typelib; ++ sltg.typeinfo_count = 0; ++ sltg.blocks = NULL; ++ sltg.n_file_blocks = 0; ++ sltg.first_block = 1; ++ ++ init_index(&sltg.index); ++ init_name_table(&sltg.name_table); ++ init_library(&sltg); ++ ++ add_library_block(&sltg); ++ ++ if (typelib->stmts) ++ LIST_FOR_EACH_ENTRY(stmt, typelib->stmts, const statement_t, entry) ++ add_statement(&sltg, stmt); ++ ++ save_all_changes(&sltg); ++ ++ return 1; ++} +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0002-widl-Add-support-for-structures.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0002-widl-Add-support-for-structures.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0002-widl-Add-support-for-structures.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0002-widl-Add-support-for-structures.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,767 @@ +From 813a2e94c759d826262892ad99fe284e4a57cb44 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Thu, 7 Jan 2016 17:38:17 +0800 +Subject: widl: Add support for structures. + +--- + tools/widl/write_sltg.c | 586 +++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 553 insertions(+), 33 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 45cac80..11b4d0c 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -1,7 +1,7 @@ + /* + * Typelib (SLTG) generation + * +- * Copyright 2015 Dmitry Timoshkov ++ * Copyright 2015,2016 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -42,16 +42,10 @@ + + static const GUID sltg_library_guid = { 0x204ff,0,0,{ 0xc0,0,0,0,0,0,0,0x46 } }; + +-struct sltg_index ++struct sltg_data + { + int size, allocated; +- char *names; +-}; +- +-struct sltg_name_table +-{ +- int size, allocated; +- char *names; ++ char *data; + }; + + struct sltg_library +@@ -78,69 +72,152 @@ struct sltg_block + struct sltg_typelib + { + typelib_t *typelib; +- struct sltg_index index; +- struct sltg_name_table name_table; ++ struct sltg_data index; ++ struct sltg_data name_table; + struct sltg_library library; + struct sltg_block *blocks; + int n_file_blocks; + int first_block; + int typeinfo_count; ++ int typeinfo_size; ++ struct sltg_block *typeinfo; + }; + +-static int add_index(struct sltg_index *index, const char *name) ++#include "pshpack1.h" ++struct sltg_typeinfo_header ++{ ++ short magic; ++ int href_offset; ++ int res06; ++ int member_offset; ++ int res0e; ++ int version; ++ int res16; ++ struct ++ { ++ unsigned unknown1 : 3; ++ unsigned flags : 13; ++ unsigned unknown2 : 8; ++ unsigned typekind : 8; ++ } misc; ++ int res1e; ++}; ++ ++struct sltg_member_header ++{ ++ short res00; ++ short res02; ++ char res04; ++ int extra; ++}; ++ ++struct sltg_variable ++{ ++ char magic; /* 0x0a */ ++ char flags; ++ short next; ++ short name; ++ short byte_offs; /* pos in struct, or offset to const type or const data (if flags & 0x08) */ ++ short type; /* if flags & 0x02 this is the type, else offset to type */ ++ int memid; ++ short helpcontext; ++ short helpstring; ++ short varflags; /* only present if magic & 0x02 */ ++}; ++ ++struct sltg_tail ++{ ++ short cFuncs; ++ short cVars; ++ short cImplTypes; ++ short res06; /* always 0000 */ ++ short funcs_off; /* offset to functions (starting from the member header) */ ++ short vars_off; /* offset to vars (starting from the member header) */ ++ short impls_off; /* offset to implemented types (starting from the member header) */ ++ short funcs_bytes; /* bytes used by function data */ ++ short vars_bytes; /* bytes used by var data */ ++ short impls_bytes; /* bytes used by implemented type data */ ++ short tdescalias_vt; /* for TKIND_ALIAS */ ++ short res16; /* always ffff */ ++ short res18; /* always 0000 */ ++ short res1a; /* always 0000 */ ++ short simple_alias; /* tdescalias_vt is a vt rather than an offset? */ ++ short res1e; /* always 0000 */ ++ short cbSizeInstance; ++ short cbAlignment; ++ short res24; /* always ffff */ ++ short res26; /* always ffff */ ++ short cbSizeVft; ++ short res2a; /* always ffff */ ++ short res2c; /* always ffff */ ++ short res2e; /* always ffff */ ++ short res30; /* always ffff */ ++ short res32; /* unknown */ ++ short type_bytes; /* bytes used by type descriptions */ ++}; ++#include "poppack.h" ++ ++static void init_sltg_data(struct sltg_data *data) ++{ ++ data->size = 0; ++ data->allocated = 0x10; ++ data->data = xmalloc(0x10); ++} ++ ++static int add_index(struct sltg_data *index, const char *name) + { + int name_offset = index->size; + int new_size = index->size + strlen(name) + 1; + ++ chat("add_index: name_offset %d, \"%s\"\n", name_offset, name); ++ + if (new_size > index->allocated) + { + index->allocated = max(index->allocated * 2, new_size); +- index->names = xrealloc(index->names, index->allocated); ++ index->data = xrealloc(index->data, index->allocated); + } + +- strcpy(index->names + index->size, name); ++ strcpy(index->data + index->size, name); + index->size = new_size; + + return name_offset; + } + +-static void init_index(struct sltg_index *index) ++static void init_index(struct sltg_data *index) + { + static const char compobj[] = { 1,'C','o','m','p','O','b','j',0 }; + +- index->size = 0; +- index->allocated = 0x10; +- index->names = xmalloc(0x10); ++ init_sltg_data(index); + + add_index(index, compobj); + } + +-static int add_name(struct sltg_name_table *name_table, const char *name) ++static int add_name(struct sltg_data *name_table, const char *name) + { + int name_offset = name_table->size; + int new_size = name_table->size + strlen(name) + 1 + 8; + ++ chat("add_name: %s\n", name); ++ + new_size = (new_size + 1) & ~1; /* align */ + + if (new_size > name_table->allocated) + { + name_table->allocated = max(name_table->allocated * 2, new_size); +- name_table->names = xrealloc(name_table->names, name_table->allocated); ++ name_table->data = xrealloc(name_table->data, name_table->allocated); + } + +- memset(name_table->names + name_table->size, 0xff, 8); +- strcpy(name_table->names + name_table->size + 8, name); ++ memset(name_table->data + name_table->size, 0xff, 8); ++ strcpy(name_table->data + name_table->size + 8, name); + name_table->size = new_size; +- name_table->names[name_table->size - 1] = 0; /* clear alignment */ ++ name_table->data[name_table->size - 1] = 0; /* clear alignment */ + + return name_offset; + } + +-static void init_name_table(struct sltg_name_table *name_table) ++static void init_name_table(struct sltg_data *name_table) + { +- name_table->size = 0; +- name_table->allocated = 0x10; +- name_table->names = xmalloc(0x10); ++ init_sltg_data(name_table); + } + + static void init_library(struct sltg_typelib *sltg) +@@ -204,6 +281,8 @@ static void add_block(struct sltg_typelib *sltg, void *data, int size, const cha + { + struct sltg_block *block = xmalloc(sizeof(*block)); + ++ chat("add_block: %p,%d,\"%s\"\n", data, size, name); ++ + block->length = size; + block->data = data; + block->index_string = add_index(&sltg->index, name); +@@ -259,6 +338,67 @@ static void add_library_block(struct sltg_typelib *typelib) + add_block(typelib, block, size, "dir"); + } + ++static const char *new_index_name(void) ++{ ++ static char name[11] = "0000000000"; ++ static int pos = 0; ++ char *new_name; ++ ++ if (name[pos] == 'Z') ++ { ++ pos++; ++ if (pos > 9) ++ error("too many index names\n"); ++ } ++ ++ name[pos]++; ++ ++ new_name = xmalloc(sizeof(name)); ++ strcpy(new_name, name); ++ return new_name; ++} ++ ++static void sltg_add_typeinfo(struct sltg_typelib *sltg, void *data, int size, const char *name) ++{ ++ struct sltg_block *block = xmalloc(sizeof(*block)); ++ ++ chat("sltg_add_typeinfo: %p,%d,%s\n", data, size, name); ++ ++ block->length = size; ++ block->data = data; ++ block->index_string = 0; ++ block->next = NULL; ++ ++ if (sltg->typeinfo) ++ { ++ struct sltg_block *typeinfo = sltg->typeinfo; ++ ++ while (typeinfo && typeinfo->next) ++ typeinfo = typeinfo->next; ++ ++ typeinfo->next = block; ++ } ++ else ++ sltg->typeinfo = block; ++ ++ sltg->typeinfo_count++; ++ sltg->typeinfo_size += size; ++} ++ ++static void append_data(struct sltg_data *block, const void *data, int size) ++{ ++ int new_size = block->size + size; ++ ++ if (new_size > block->allocated) ++ { ++ block->allocated = max(block->allocated * 2, new_size); ++ block->data = xrealloc(block->data, block->allocated); ++ } ++ ++ memcpy(block->data + block->size, data, size); ++ block->size = new_size; ++} ++ + static void add_typedef_typeinfo(struct sltg_typelib *typelib, type_t *type) + { + error("add_typedef_typeinfo: %s not implemented\n", type->name); +@@ -274,9 +414,359 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *type) + error("add_interface_typeinfo: %s not implemented\n", type->name); + } + +-static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) ++static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t *type) + { +- error("add_structure_typeinfo: %s not implemented\n", type->name); ++ const char *index_name, *other_name; ++ void *block; ++ short *p; ++ int size, helpcontext = 0; ++ GUID guid = { 0 }; ++ const expr_t *expr; ++ ++ index_name = new_index_name(); ++ other_name = new_index_name(); ++ ++ expr = get_attrp(type->attrs, ATTR_HELPCONTEXT); ++ if (expr) helpcontext = expr->cval; ++ ++ p = get_attrp(type->attrs, ATTR_UUID); ++ if (p) guid = *(GUID *)p; ++ ++ size = sizeof(short) * 8 + 10 /* index_name */ * 2 + sizeof(int) + sizeof(GUID); ++ ++ block = xmalloc(size); ++ p = block; ++ *p++ = strlen(index_name); ++ strcpy((char *)p, index_name); ++ p = (short *)((char *)p + strlen(index_name)); ++ *p++ = strlen(other_name); ++ strcpy((char *)p, other_name); ++ p = (short *)((char *)p + strlen(other_name)); ++ *p++ = -1; /* res1a */ ++ *p++ = add_name(&typelib->name_table, type->name); /* name offset */ ++ *p++ = 0; /* FIXME: helpstring */ ++ *p++ = -1; /* res20 */ ++ *(int *)p = helpcontext; ++ p += 2; ++ *p++ = -1; /* res26 */ ++ *(GUID *)p = guid; ++ p += sizeof(GUID)/2; ++ *p = type_get_type(type); ++ ++ sltg_add_typeinfo(typelib, block, size, index_name); ++ ++ return index_name; ++} ++ ++static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, int kind) ++{ ++ ti->magic = 0x0501; ++ ti->href_offset = -1; ++ ti->res06 = -1; ++ ti->member_offset = sizeof(*ti); ++ ti->res0e = -1; ++ ti->version = get_attrv(type->attrs, ATTR_VERSION); ++ ti->res16 = 0xfffe0000; ++ ti->misc.unknown1 = 0x02; ++ ti->misc.flags = 0; /* FIXME */ ++ ti->misc.unknown2 = 0x02; ++ ti->misc.typekind = kind; ++ ti->res1e = -1; ++} ++ ++static void dump_var_desc(const char *data, int size) ++{ ++ const unsigned char *p = (const unsigned char *)data; ++ int i; ++ ++ if (!(debuglevel & (DEBUGLEVEL_TRACE | DEBUGLEVEL_CHAT))) return; ++ ++ chat("dump_var_desc: size %d bytes\n", size); ++ ++ for (i = 0; i < size; i++) ++ fprintf(stderr, " %02x", *p++); ++ ++ fprintf(stderr, "\n"); ++} ++ ++static int get_element_size(type_t *type) ++{ ++ int vt = get_type_vt(type); ++ ++ switch (vt) ++ { ++ case VT_I1: ++ case VT_UI1: ++ return 1; ++ ++ case VT_INT: ++ case VT_UINT: ++ return typelib_kind == SYS_WIN16 ? 2 : 4; ++ ++ case VT_UI2: ++ case VT_I2: ++ case VT_BOOL: ++ return 2; ++ ++ case VT_I4: ++ case VT_UI4: ++ case VT_R4: ++ case VT_ERROR: ++ case VT_HRESULT: ++ return 4; ++ ++ case VT_R8: ++ case VT_I8: ++ case VT_UI8: ++ case VT_CY: ++ case VT_DATE: ++ return 8; ++ ++ case VT_DECIMAL: ++ return 16; ++ ++ case VT_PTR: ++ case VT_UNKNOWN: ++ case VT_DISPATCH: ++ case VT_BSTR: ++ case VT_LPSTR: ++ case VT_LPWSTR: ++ return pointer_size; ++ ++ default: ++ error("get_element_size: unrecognized vt %d\n", vt); ++ break; ++ } ++ ++ return 0; ++} ++ ++static short write_var_desc(struct sltg_data *data, type_t *type, short flags, short base_offset) ++{ ++ short vt, desc_offset; ++ ++ chat("write_var_desc: type %p, type->name %s\n", ++ type, type->name ? type->name : "NULL"); ++ ++ if (is_array(type) && !type_array_is_decl_as_ptr(type)) ++ { ++ int num_dims, elements, array_start, size; ++ type_t *atype; ++ struct ++ { ++ short cDims; ++ short fFeatures; ++ int cbElements; ++ int cLocks; ++ void *pvData; ++ int bound[2]; ++ } *array; ++ int *bound; ++ short vt_off[2]; ++ ++ elements = 1; ++ num_dims = 0; ++ ++ atype = type; ++ ++ while (is_array(atype) && !type_array_is_decl_as_ptr(atype)) ++ { ++ num_dims++; ++ elements *= type_array_get_dim(atype); ++ ++ atype = type_array_get_element(atype); ++ } ++ ++ chat("write_var_desc: VT_CARRAY: %d dimensions, %d elements\n", num_dims, elements); ++ ++ array_start = data->size; ++ ++ size = sizeof(*array) + (num_dims - 1) * 8 /* sizeof(SAFEARRAYBOUND) */; ++ array = xmalloc(size); ++ ++ array->cDims = num_dims; ++ array->fFeatures = 0x0004; /* FADF_EMBEDDED */ ++ array->cbElements = get_element_size(type_array_get_element(type)); ++ array->cLocks = 0; ++ array->pvData = NULL; ++ ++ bound = array->bound; ++ atype = type; ++ ++ while (is_array(atype) && !type_array_is_decl_as_ptr(atype)) ++ { ++ bound[0] = type_array_get_dim(atype); ++ bound[1] = 0; ++ bound += 2; ++ ++ atype = type_array_get_element(atype); ++ } ++ ++ append_data(data, array, size); ++ ++ desc_offset = data->size; ++ ++ vt_off[0] = VT_CARRAY; ++ vt_off[1] = array_start + base_offset; ++ append_data(data, vt_off, sizeof(vt_off)); ++ ++ /* fall through to write array element description */ ++ type = atype; ++ } ++ else ++ desc_offset = data->size; ++ ++ vt = get_type_vt(type); ++ ++ if (vt == VT_PTR) ++ { ++ type_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : type_array_get_element(type); ++ ++ if (is_ptr(ref)) ++ { ++ chat("write_var_desc: vt VT_PTR | 0x0400\n"); ++ vt = VT_PTR | 0x0400; ++ append_data(data, &vt, sizeof(vt)); ++ write_var_desc(data, ref, 0, base_offset); ++ } ++ else ++ write_var_desc(data, ref, 0x0e00, base_offset); ++ return desc_offset; ++ } ++ ++ chat("write_var_desc: vt %d, flags %04x\n", vt, flags); ++ ++ vt |= flags; ++ append_data(data, &vt, sizeof(vt)); ++ ++ return desc_offset; ++} ++ ++static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *type) ++{ ++ struct sltg_data data, *var_data = NULL; ++ const char *index_name; ++ struct sltg_typeinfo_header ti; ++ struct sltg_member_header member; ++ struct sltg_tail tail; ++ int member_offset, var_count = 0, var_data_size = 0; ++ short *type_desc_offset = NULL; ++ ++ chat("add_structure_typeinfo: %s\n", type->name); ++ ++ init_sltg_data(&data); ++ ++ index_name = add_typeinfo_block(typelib, type); ++ ++ init_typeinfo(&ti, type, TKIND_RECORD); ++ append_data(&data, &ti, sizeof(ti)); ++ ++ if (type_struct_get_fields(type)) ++ { ++ int i = 0; ++ var_t *var; ++ ++ var_count = list_count(type_struct_get_fields(type)); ++ ++ var_data = xmalloc(var_count * sizeof(*var_data)); ++ type_desc_offset = xmalloc(var_count * sizeof(*type_desc_offset)); ++ ++ LIST_FOR_EACH_ENTRY(var, type_struct_get_fields(type), var_t, entry) ++ { ++ chat("add_structure_typeinfo: var %p, name %s, type %p\n", ++ var, var->name, var->type); ++ ++ init_sltg_data(&var_data[i]); ++ ++ var_data_size += sizeof(struct sltg_variable); ++ ++ type_desc_offset[i] = write_var_desc(&var_data[i], var->type, 0, var_data_size); ++ dump_var_desc(var_data[i].data, var_data[i].size); ++ ++ if (var_data[i].size > sizeof(short)) ++ var_data_size += var_data[i].size; ++ i++; ++ } ++ } ++ ++ member_offset = data.size; ++ ++ member.res00 = 0x0001; ++ member.res02 = 0xffff; ++ member.res04 = 0x01; ++ member.extra = var_data_size; ++ append_data(&data, &member, sizeof(member)); ++ ++ if (type_struct_get_fields(type)) ++ { ++ int i = 0; ++ short next = member_offset; ++ var_t *var; ++ ++ LIST_FOR_EACH_ENTRY(var, type_struct_get_fields(type), var_t, entry) ++ { ++ struct sltg_variable variable; ++ ++ next += sizeof(variable); ++ ++ variable.magic = 0x2a; /* always write flags to simplify calculations */ ++ variable.name = add_name(&typelib->name_table, var->name); ++ variable.byte_offs = 0; ++ if (var_data[i].size > sizeof(short)) ++ { ++ variable.flags = 0; ++ variable.type = next - member_offset + type_desc_offset[i]; ++ next += var_data[i].size; ++ } ++ else ++ { ++ variable.flags = 0x02; ++ variable.type = *(short *)var_data[i].data; ++ } ++ variable.next = i < var_count - 1 ? next - member_offset : -1; ++ variable.memid = 0x40000000 + i; ++ variable.helpcontext = -2; /* 0xfffe */ ++ variable.helpstring = -1; ++ variable.varflags = 0; ++ ++ append_data(&data, &variable, sizeof(variable)); ++ if (var_data[i].size > sizeof(short)) ++ append_data(&data, var_data[i].data, var_data[i].size); ++ ++ i++; ++ } ++ } ++ ++ tail.cFuncs = 0; ++ tail.cVars = var_count; ++ tail.cImplTypes = 0; ++ tail.res06 = 0; ++ tail.funcs_off = -1; ++ tail.vars_off = 0; ++ tail.impls_off = -1; ++ tail.funcs_bytes = -1; ++ tail.vars_bytes = var_data_size; ++ tail.impls_bytes = -1; ++ tail.tdescalias_vt = -1; ++ tail.res16 = -1; ++ tail.res18 = 0; ++ tail.res1a = 0; ++ tail.simple_alias = 0; ++ tail.res1e = 0; ++ tail.cbSizeInstance = 0; ++ tail.cbAlignment = 4; ++ tail.res24 = 0; ++ tail.res26 = 0; ++ tail.cbSizeVft = 0; ++ tail.res2a = -1; ++ tail.res2c = -1; ++ tail.res2e = -1; ++ tail.res30 = -1; ++ tail.res32 = 0; ++ tail.type_bytes = data.size - member_offset; ++ append_data(&data, &tail, sizeof(tail)); ++ ++ add_block(typelib, data.data, data.size, index_name); + } + + static void add_enum_typeinfo(struct sltg_typelib *typelib, type_t *type) +@@ -413,7 +903,9 @@ static void sltg_write_header(struct sltg_typelib *sltg, int *library_block_star + + entry.length = block->length; + entry.index_string = block->index_string; +- entry.next = header.first_blk + i; ++ entry.next = header.first_blk + i + 1; ++ chat("sltg_write_header: writing block entry %d: length %#x, index_string %#x, next %#x\n", ++ i, entry.length, entry.index_string, entry.next); + put_data(&entry, sizeof(entry)); + + block = block->next; +@@ -422,12 +914,15 @@ static void sltg_write_header(struct sltg_typelib *sltg, int *library_block_star + assert(block->next == NULL); + + /* library block length includes helpstrings and name table */ +- entry.length = block->length + 0x40 + 2 + 4 + 6 + 12 + 0x200 + sltg->name_table.size + 12; ++ entry.length = block->length + 0x40 + 2 + sltg->typeinfo_size + 4 + 6 + 12 + 0x200 + sltg->name_table.size + 12; + entry.index_string = block->index_string; + entry.next = 0; ++ chat("sltg_write_header: writing library block entry %d: length %#x, index_string %#x, next %#x\n", ++ i, entry.length, entry.index_string, entry.next); + put_data(&entry, sizeof(entry)); + +- put_data(sltg->index.names, sltg->index.size); ++ chat("sltg_write_header: writing index: %d bytes\n", sltg->index.size); ++ put_data(sltg->index.data, sltg->index.size); + memset(pad, 0, 9); + put_data(pad, 9); + +@@ -443,24 +938,41 @@ static void sltg_write_header(struct sltg_typelib *sltg, int *library_block_star + assert(block->next == NULL); + + /* library block */ ++ chat("library_block_start = %#lx\n", (SIZE_T)output_buffer_pos); + *library_block_start = output_buffer_pos; ++ chat("sltg_write_header: writing library block %d: %d bytes\n", i, block->length); + put_data(block->data, block->length); + ++ chat("sltg_write_header: writing pad 0x40 bytes\n"); + memset(pad, 0xff, 0x40); + put_data(pad, 0x40); + } + + static void sltg_write_typeinfo(struct sltg_typelib *typelib) + { ++ int i; ++ struct sltg_block *block; + short count = typelib->typeinfo_count; + + put_data(&count, sizeof(count)); ++ ++ block = typelib->typeinfo; ++ for (i = 0; i < typelib->typeinfo_count; i++) ++ { ++ chat("sltg_write_typeinfo: writing block %d: %d bytes\n", i, block->length); ++ ++ put_data(block->data, block->length); ++ block = block->next; ++ } ++ assert(block == NULL); + } + + static void sltg_write_helpstrings(struct sltg_typelib *typelib) + { + static const char dummy[6]; + ++ chat("sltg_write_helpstrings: writing dummy 6 bytes\n"); ++ + put_data(dummy, sizeof(dummy)); + } + +@@ -469,11 +981,13 @@ static void sltg_write_nametable(struct sltg_typelib *typelib) + static const short dummy[6] = { 0xffff,1,2,0xff00,0xffff,0xffff }; + char pad[0x200]; + ++ chat("sltg_write_nametable: writing 12+0x200+%d bytes\n", typelib->name_table.size); ++ + put_data(dummy, sizeof(dummy)); + memset(pad, 0xff, 0x200); + put_data(pad, 0x200); + put_data(&typelib->name_table.size, sizeof(typelib->name_table.size)); +- put_data(typelib->name_table.names, typelib->name_table.size); ++ put_data(typelib->name_table.data, typelib->name_table.size); + } + + static void sltg_write_remainder(void) +@@ -508,11 +1022,13 @@ static void save_all_changes(struct sltg_typelib *typelib) + sltg_write_typeinfo(typelib); + + name_table_offset = (int *)(output_buffer + output_buffer_pos); ++ chat("name_table_offset = %#lx\n", (SIZE_T)output_buffer_pos); + put_data(&library_block_start, sizeof(library_block_start)); + + sltg_write_helpstrings(typelib); + + *name_table_offset = output_buffer_pos - library_block_start; ++ chat("*name_table_offset = %#x\n", *name_table_offset); + + sltg_write_nametable(typelib); + sltg_write_remainder(); +@@ -536,8 +1052,12 @@ int create_sltg_typelib(typelib_t *typelib) + struct sltg_typelib sltg; + const statement_t *stmt; + ++ pointer_size = (typelib_kind == SYS_WIN64) ? 8 : 4; ++ + sltg.typelib = typelib; + sltg.typeinfo_count = 0; ++ sltg.typeinfo_size = 0; ++ sltg.typeinfo = NULL; + sltg.blocks = NULL; + sltg.n_file_blocks = 0; + sltg.first_block = 1; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0003-widl-Properly-align-name-table-entries.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0003-widl-Properly-align-name-table-entries.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0003-widl-Properly-align-name-table-entries.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0003-widl-Properly-align-name-table-entries.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,102 @@ +From 5cbf5f43c6b827a9454b2c326a61ea709e32947b Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Thu, 7 Jan 2016 19:12:47 +0800 +Subject: widl: Properly align name table entries. + +--- + tools/widl/write_sltg.c | 39 ++++++++++++++++++++++----------------- + 1 file changed, 22 insertions(+), 17 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 11b4d0c..1ba921d 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -192,39 +192,44 @@ static void init_index(struct sltg_data *index) + add_index(index, compobj); + } + +-static int add_name(struct sltg_data *name_table, const char *name) ++static int add_name(struct sltg_typelib *sltg, const char *name) + { +- int name_offset = name_table->size; +- int new_size = name_table->size + strlen(name) + 1 + 8; ++ int name_offset = sltg->name_table.size; ++ int new_size = sltg->name_table.size + strlen(name) + 1 + 8; ++ int aligned_size; + + chat("add_name: %s\n", name); + +- new_size = (new_size + 1) & ~1; /* align */ ++ aligned_size = (new_size + 0x1f) & ~0x1f; ++ if (aligned_size - new_size < 4) ++ new_size = aligned_size; ++ else ++ new_size = (new_size + 1) & ~1; + +- if (new_size > name_table->allocated) ++ if (aligned_size > sltg->name_table.allocated) + { +- name_table->allocated = max(name_table->allocated * 2, new_size); +- name_table->data = xrealloc(name_table->data, name_table->allocated); ++ sltg->name_table.allocated = max(sltg->name_table.allocated * 2, aligned_size); ++ sltg->name_table.data = xrealloc(sltg->name_table.data, sltg->name_table.allocated); + } + +- memset(name_table->data + name_table->size, 0xff, 8); +- strcpy(name_table->data + name_table->size + 8, name); +- name_table->size = new_size; +- name_table->data[name_table->size - 1] = 0; /* clear alignment */ ++ memset(sltg->name_table.data + sltg->name_table.size, 0xff, 8); ++ strcpy(sltg->name_table.data + sltg->name_table.size + 8, name); ++ sltg->name_table.size = new_size; ++ sltg->name_table.data[sltg->name_table.size - 1] = 0; /* clear alignment */ + + return name_offset; + } + +-static void init_name_table(struct sltg_data *name_table) ++static void init_name_table(struct sltg_typelib *sltg) + { +- init_sltg_data(name_table); ++ init_sltg_data(&sltg->name_table); + } + + static void init_library(struct sltg_typelib *sltg) + { + const attr_t *attr; + +- sltg->library.name = add_name(&sltg->name_table, sltg->typelib->name); ++ sltg->library.name = add_name(sltg, sltg->typelib->name); + sltg->library.helpstring = NULL; + sltg->library.helpcontext = 0; + sltg->library.syskind = SYS_WIN32; +@@ -443,7 +448,7 @@ static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t + strcpy((char *)p, other_name); + p = (short *)((char *)p + strlen(other_name)); + *p++ = -1; /* res1a */ +- *p++ = add_name(&typelib->name_table, type->name); /* name offset */ ++ *p++ = add_name(typelib, type->name); /* name offset */ + *p++ = 0; /* FIXME: helpstring */ + *p++ = -1; /* res20 */ + *(int *)p = helpcontext; +@@ -710,7 +715,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + next += sizeof(variable); + + variable.magic = 0x2a; /* always write flags to simplify calculations */ +- variable.name = add_name(&typelib->name_table, var->name); ++ variable.name = add_name(typelib, var->name); + variable.byte_offs = 0; + if (var_data[i].size > sizeof(short)) + { +@@ -1063,7 +1068,7 @@ int create_sltg_typelib(typelib_t *typelib) + sltg.first_block = 1; + + init_index(&sltg.index); +- init_name_table(&sltg.name_table); ++ init_name_table(&sltg); + init_library(&sltg); + + add_library_block(&sltg); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0004-widl-More-accurately-report-variable-descriptions-da.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0004-widl-More-accurately-report-variable-descriptions-da.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0004-widl-More-accurately-report-variable-descriptions-da.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0004-widl-More-accurately-report-variable-descriptions-da.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,77 @@ +From 4156b4077001ff084ee825c592e1f0753218e357 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sat, 9 Jan 2016 15:49:46 +0800 +Subject: widl: More accurately report variable descriptions data size. + +--- + tools/widl/write_sltg.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 1ba921d..20dd05d 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -678,14 +678,15 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + + LIST_FOR_EACH_ENTRY(var, type_struct_get_fields(type), var_t, entry) + { ++ short base_offset; ++ + chat("add_structure_typeinfo: var %p, name %s, type %p\n", + var, var->name, var->type); + + init_sltg_data(&var_data[i]); + +- var_data_size += sizeof(struct sltg_variable); +- +- type_desc_offset[i] = write_var_desc(&var_data[i], var->type, 0, var_data_size); ++ base_offset = var_data_size + (i + 1) * sizeof(struct sltg_variable); ++ type_desc_offset[i] = write_var_desc(&var_data[i], var->type, 0, base_offset); + dump_var_desc(var_data[i].data, var_data[i].size); + + if (var_data[i].size > sizeof(short)) +@@ -699,9 +700,11 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + member.res00 = 0x0001; + member.res02 = 0xffff; + member.res04 = 0x01; +- member.extra = var_data_size; ++ member.extra = var_data_size + var_count * sizeof(struct sltg_variable); + append_data(&data, &member, sizeof(member)); + ++ var_data_size = 0; ++ + if (type_struct_get_fields(type)) + { + int i = 0; +@@ -720,7 +723,8 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + if (var_data[i].size > sizeof(short)) + { + variable.flags = 0; +- variable.type = next - member_offset + type_desc_offset[i]; ++ var_data_size = next - member_offset + type_desc_offset[i]; ++ variable.type = var_data_size; + next += var_data[i].size; + } + else +@@ -760,15 +764,15 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + tail.res1e = 0; + tail.cbSizeInstance = 0; + tail.cbAlignment = 4; +- tail.res24 = 0; +- tail.res26 = 0; ++ tail.res24 = -1; ++ tail.res26 = -1; + tail.cbSizeVft = 0; + tail.res2a = -1; + tail.res2c = -1; + tail.res2e = -1; + tail.res30 = -1; + tail.res32 = 0; +- tail.type_bytes = data.size - member_offset; ++ tail.type_bytes = data.size - member_offset - sizeof(member); + append_data(&data, &tail, sizeof(tail)); + + add_block(typelib, data.data, data.size, index_name); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0005-widl-Calculate-size-of-instance-for-structures.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0005-widl-Calculate-size-of-instance-for-structures.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0005-widl-Calculate-size-of-instance-for-structures.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0005-widl-Calculate-size-of-instance-for-structures.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,112 @@ +From d1aa5ddca997bc92aae53b9d009debdd38c833f2 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sat, 9 Jan 2016 16:22:15 +0800 +Subject: widl: Calculate size of instance for structures. + +--- + tools/widl/write_sltg.c | 25 +++++++++++++++++-------- + 1 file changed, 17 insertions(+), 8 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 20dd05d..05cda99 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -546,7 +546,7 @@ static int get_element_size(type_t *type) + return 0; + } + +-static short write_var_desc(struct sltg_data *data, type_t *type, short flags, short base_offset) ++static short write_var_desc(struct sltg_data *data, type_t *type, short flags, short base_offset, int *size_instance) + { + short vt, desc_offset; + +@@ -555,7 +555,7 @@ static short write_var_desc(struct sltg_data *data, type_t *type, short flags, s + + if (is_array(type) && !type_array_is_decl_as_ptr(type)) + { +- int num_dims, elements, array_start, size; ++ int num_dims, elements, array_start, size, array_size; + type_t *atype; + struct + { +@@ -591,22 +591,28 @@ static short write_var_desc(struct sltg_data *data, type_t *type, short flags, s + + array->cDims = num_dims; + array->fFeatures = 0x0004; /* FADF_EMBEDDED */ +- array->cbElements = get_element_size(type_array_get_element(type)); ++ array->cbElements = get_element_size(atype); + array->cLocks = 0; + array->pvData = NULL; + + bound = array->bound; ++ ++ array_size = array->cbElements; + atype = type; + + while (is_array(atype) && !type_array_is_decl_as_ptr(atype)) + { + bound[0] = type_array_get_dim(atype); ++ array_size *= bound[0]; + bound[1] = 0; + bound += 2; + + atype = type_array_get_element(atype); + } + ++ *size_instance += array_size; ++ size_instance = NULL; /* don't account for element size */ ++ + append_data(data, array, size); + + desc_offset = data->size; +@@ -632,15 +638,18 @@ static short write_var_desc(struct sltg_data *data, type_t *type, short flags, s + chat("write_var_desc: vt VT_PTR | 0x0400\n"); + vt = VT_PTR | 0x0400; + append_data(data, &vt, sizeof(vt)); +- write_var_desc(data, ref, 0, base_offset); ++ write_var_desc(data, ref, 0, base_offset, size_instance); + } + else +- write_var_desc(data, ref, 0x0e00, base_offset); ++ write_var_desc(data, ref, 0x0e00, base_offset, size_instance); + return desc_offset; + } + + chat("write_var_desc: vt %d, flags %04x\n", vt, flags); + ++ if (size_instance) ++ *size_instance += get_element_size(type); ++ + vt |= flags; + append_data(data, &vt, sizeof(vt)); + +@@ -654,7 +663,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + struct sltg_typeinfo_header ti; + struct sltg_member_header member; + struct sltg_tail tail; +- int member_offset, var_count = 0, var_data_size = 0; ++ int member_offset, var_count = 0, var_data_size = 0, size_instance = 0; + short *type_desc_offset = NULL; + + chat("add_structure_typeinfo: %s\n", type->name); +@@ -686,7 +695,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + init_sltg_data(&var_data[i]); + + base_offset = var_data_size + (i + 1) * sizeof(struct sltg_variable); +- type_desc_offset[i] = write_var_desc(&var_data[i], var->type, 0, base_offset); ++ type_desc_offset[i] = write_var_desc(&var_data[i], var->type, 0, base_offset, &size_instance); + dump_var_desc(var_data[i].data, var_data[i].size); + + if (var_data[i].size > sizeof(short)) +@@ -762,7 +771,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + tail.res1a = 0; + tail.simple_alias = 0; + tail.res1e = 0; +- tail.cbSizeInstance = 0; ++ tail.cbSizeInstance = size_instance; + tail.cbAlignment = 4; + tail.res24 = -1; + tail.res26 = -1; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0006-widl-Write-correct-typekind-to-the-SLTG-typeinfo-blo.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0006-widl-Write-correct-typekind-to-the-SLTG-typeinfo-blo.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0006-widl-Write-correct-typekind-to-the-SLTG-typeinfo-blo.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0006-widl-Write-correct-typekind-to-the-SLTG-typeinfo-blo.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,43 @@ +From 2f8a1768690fb0bb26411f561fe9d9d513c2de1f Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sun, 10 Jan 2016 15:58:15 +0800 +Subject: widl: Write correct typekind to the SLTG typeinfo block. + +--- + tools/widl/write_sltg.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 05cda99..04c6123 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -419,7 +419,7 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *type) + error("add_interface_typeinfo: %s not implemented\n", type->name); + } + +-static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t *type) ++static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t *type, int kind) + { + const char *index_name, *other_name; + void *block; +@@ -456,7 +456,7 @@ static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t + *p++ = -1; /* res26 */ + *(GUID *)p = guid; + p += sizeof(GUID)/2; +- *p = type_get_type(type); ++ *p = kind; + + sltg_add_typeinfo(typelib, block, size, index_name); + +@@ -670,7 +670,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + + init_sltg_data(&data); + +- index_name = add_typeinfo_block(typelib, type); ++ index_name = add_typeinfo_block(typelib, type, TKIND_RECORD); + + init_typeinfo(&ti, type, TKIND_RECORD); + append_data(&data, &ti, sizeof(ti)); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0007-widl-Write-SLTG-blocks-according-to-the-index-order.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0007-widl-Write-SLTG-blocks-according-to-the-index-order.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0007-widl-Write-SLTG-blocks-according-to-the-index-order.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0007-widl-Write-SLTG-blocks-according-to-the-index-order.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,64 @@ +From 8d03a0b285eb282b80d512ac9c28523cb464c209 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sun, 10 Jan 2016 15:59:19 +0800 +Subject: widl: Write SLTG blocks according to the index order. + +Now multiple types can be correctly parsed and displayed by oleview. +--- + tools/widl/write_sltg.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 04c6123..4b86bf9 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -291,9 +291,20 @@ static void add_block(struct sltg_typelib *sltg, void *data, int size, const cha + block->length = size; + block->data = data; + block->index_string = add_index(&sltg->index, name); +- block->next = sltg->blocks; ++ block->next = NULL; ++ ++ if (sltg->blocks) ++ { ++ struct sltg_block *blocks = sltg->blocks; ++ ++ while (blocks->next) ++ blocks = blocks->next; ++ ++ blocks->next = block; ++ } ++ else ++ sltg->blocks = block; + +- sltg->blocks = block; + sltg->n_file_blocks++; + } + +@@ -378,7 +389,7 @@ static void sltg_add_typeinfo(struct sltg_typelib *sltg, void *data, int size, c + { + struct sltg_block *typeinfo = sltg->typeinfo; + +- while (typeinfo && typeinfo->next) ++ while (typeinfo->next) + typeinfo = typeinfo->next; + + typeinfo->next = block; +@@ -1084,12 +1095,12 @@ int create_sltg_typelib(typelib_t *typelib) + init_name_table(&sltg); + init_library(&sltg); + +- add_library_block(&sltg); +- + if (typelib->stmts) + LIST_FOR_EACH_ENTRY(stmt, typelib->stmts, const statement_t, entry) + add_statement(&sltg, stmt); + ++ add_library_block(&sltg); ++ + save_all_changes(&sltg); + + return 1; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0008-widl-Write-correct-syskind-by-SLTG-typelib-generator.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0008-widl-Write-correct-syskind-by-SLTG-typelib-generator.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0008-widl-Write-correct-syskind-by-SLTG-typelib-generator.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0008-widl-Write-correct-syskind-by-SLTG-typelib-generator.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,25 @@ +From 179b74aeee8d4bf7a35b3a57d9395e4040175900 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sun, 10 Jan 2016 16:01:55 +0800 +Subject: widl: Write correct syskind by SLTG typelib generator. + +--- + tools/widl/write_sltg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 4b86bf9..61632ee 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -232,7 +232,7 @@ static void init_library(struct sltg_typelib *sltg) + sltg->library.name = add_name(sltg, sltg->typelib->name); + sltg->library.helpstring = NULL; + sltg->library.helpcontext = 0; +- sltg->library.syskind = SYS_WIN32; ++ sltg->library.syskind = typelib_kind; + sltg->library.lcid = 0x0409; + sltg->library.libflags = 0; + sltg->library.version = 0; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0009-widl-Add-support-for-VT_VOID-and-VT_VARIANT-to-SLTG-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0009-widl-Add-support-for-VT_VOID-and-VT_VARIANT-to-SLTG-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0009-widl-Add-support-for-VT_VOID-and-VT_VARIANT-to-SLTG-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0009-widl-Add-support-for-VT_VOID-and-VT_VARIANT-to-SLTG-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,30 @@ +From 5e54bd9690e6b969ea5cccfd58b8f6ffb8800fef Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sun, 10 Jan 2016 16:03:33 +0800 +Subject: widl: Add support for VT_VOID and VT_VARIANT to SLTG typelib + generator. + +--- + tools/widl/write_sltg.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 61632ee..08bb25e 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -549,6 +549,12 @@ static int get_element_size(type_t *type) + case VT_LPWSTR: + return pointer_size; + ++ case VT_VOID: ++ return 0; ++ ++ case VT_VARIANT: ++ return pointer_size == 8 ? 24 : 16; ++ + default: + error("get_element_size: unrecognized vt %d\n", vt); + break; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0010-widl-Add-support-for-VT_USERDEFINED-to-SLTG-typelib-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0010-widl-Add-support-for-VT_USERDEFINED-to-SLTG-typelib-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0010-widl-Add-support-for-VT_USERDEFINED-to-SLTG-typelib-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0010-widl-Add-support-for-VT_USERDEFINED-to-SLTG-typelib-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,322 @@ +From 49aa53fe28df7d9e93c93bfa6fa0304134153a7c Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Wed, 13 Jan 2016 15:58:50 +0800 +Subject: widl: Add support for VT_USERDEFINED to SLTG typelib generator. + +--- + tools/widl/write_sltg.c | 211 ++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 196 insertions(+), 15 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 08bb25e..dbe75c6 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -83,6 +83,12 @@ struct sltg_typelib + struct sltg_block *typeinfo; + }; + ++struct sltg_hrefmap ++{ ++ int href_count; ++ int *href; ++}; ++ + #include "pshpack1.h" + struct sltg_typeinfo_header + { +@@ -155,6 +161,46 @@ struct sltg_tail + short res32; /* unknown */ + short type_bytes; /* bytes used by type descriptions */ + }; ++ ++struct sltg_hrefinfo ++{ ++ char magic; /* 0xdf */ ++ char res01; /* 0x00 */ ++ int res02; /* 0xffffffff */ ++ int res06; /* 0xffffffff */ ++ int res0a; /* 0xffffffff */ ++ int res0e; /* 0xffffffff */ ++ int res12; /* 0xffffffff */ ++ int res16; /* 0xffffffff */ ++ int res1a; /* 0xffffffff */ ++ int res1e; /* 0xffffffff */ ++ int res22; /* 0xffffffff */ ++ int res26; /* 0xffffffff */ ++ int res2a; /* 0xffffffff */ ++ int res2e; /* 0xffffffff */ ++ int res32; /* 0xffffffff */ ++ int res36; /* 0xffffffff */ ++ int res3a; /* 0xffffffff */ ++ int res3e; /* 0xffffffff */ ++ short res42;/* 0xffff */ ++ int number; /* this is 8 times the number of refs */ ++ /* Now we have number bytes (8 for each ref) of SLTG_UnknownRefInfo */ ++ ++ short res50;/* 0xffff */ ++ char res52; /* 0x01 */ ++ int res53; /* 0x00000000 */ ++ /* Now we have number/8 SLTG_Names (first WORD is no of bytes in the ascii ++ * string). Strings look like "*\Rxxxx*#n". If xxxx == ffff then the ++ * ref refers to the nth type listed in this library (0 based). Else ++ * the xxxx (which maybe fewer than 4 digits) is the offset into the name ++ * table to a string "*\G{}#1.0#0#C:\WINNT\System32\stdole32.tlb#" ++ * The guid is the typelib guid; the ref again refers to the nth type of ++ * the imported typelib. ++ */ ++ ++ char resxx; /* 0xdf */ ++}; ++ + #include "poppack.h" + + static void init_sltg_data(struct sltg_data *data) +@@ -474,12 +520,12 @@ static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t + return index_name; + } + +-static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, int kind) ++static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, int kind, ++ const struct sltg_hrefmap *hrefmap) + { + ti->magic = 0x0501; + ti->href_offset = -1; + ti->res06 = -1; +- ti->member_offset = sizeof(*ti); + ti->res0e = -1; + ti->version = get_attrv(type->attrs, ATTR_VERSION); + ti->res16 = 0xfffe0000; +@@ -488,6 +534,79 @@ static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, i + ti->misc.unknown2 = 0x02; + ti->misc.typekind = kind; + ti->res1e = -1; ++ ++ ti->member_offset = sizeof(*ti); ++ ++ if (hrefmap->href_count) ++ { ++ char name[64]; ++ int i, hrefinfo_size; ++ ++ hrefinfo_size = sizeof(struct sltg_hrefinfo); ++ ++ for (i = 0; i < hrefmap->href_count; i++) ++ { ++ sprintf(name, "*\\Rffff*#%x", hrefmap->href[i]); ++ hrefinfo_size += 8 + 2 + strlen(name); ++ } ++ ++ ti->href_offset = ti->member_offset; ++ ti->member_offset += hrefinfo_size; ++ } ++} ++ ++static void write_hrefmap(struct sltg_data *data, const struct sltg_hrefmap *hrefmap) ++{ ++ struct sltg_hrefinfo hrefinfo; ++ char name[64]; ++ int i; ++ ++ if (!hrefmap->href_count) return; ++ ++ hrefinfo.magic = 0xdf; ++ hrefinfo.res01 = 0; ++ hrefinfo.res02 = -1; ++ hrefinfo.res06 = -1; ++ hrefinfo.res0a = -1; ++ hrefinfo.res0e = -1; ++ hrefinfo.res12 = -1; ++ hrefinfo.res16 = -1; ++ hrefinfo.res1a = -1; ++ hrefinfo.res1e = -1; ++ hrefinfo.res22 = -1; ++ hrefinfo.res26 = -1; ++ hrefinfo.res2a = -1; ++ hrefinfo.res2e = -1; ++ hrefinfo.res32 = -1; ++ hrefinfo.res36 = -1; ++ hrefinfo.res3a = -1; ++ hrefinfo.res3e = -1; ++ hrefinfo.res42 = -1; ++ hrefinfo.number = hrefmap->href_count * 8; ++ hrefinfo.res50 = -1; ++ hrefinfo.res52 = 1; ++ hrefinfo.res53 = 0; ++ hrefinfo.resxx = 0xdf; ++ ++ append_data(data, &hrefinfo, offsetof(struct sltg_hrefinfo, res50)); ++ ++ for (i = 0; i < hrefmap->href_count; i++) ++ append_data(data, "\xff\xff\xff\xff\xff\xff\xff\xff", 8); ++ ++ append_data(data, &hrefinfo.res50, 7); ++ ++ for (i = 0; i < hrefmap->href_count; i++) ++ { ++ short len; ++ ++ sprintf(name, "*\\Rffff*#%x", hrefmap->href[i]); ++ len = strlen(name); ++ ++ append_data(data, &len, sizeof(len)); ++ append_data(data, name, len); ++ } ++ ++ append_data(data, &hrefinfo.resxx, sizeof(hrefinfo.resxx)); + } + + static void dump_var_desc(const char *data, int size) +@@ -555,6 +674,9 @@ static int get_element_size(type_t *type) + case VT_VARIANT: + return pointer_size == 8 ? 24 : 16; + ++ case VT_USERDEFINED: ++ return 0; ++ + default: + error("get_element_size: unrecognized vt %d\n", vt); + break; +@@ -563,9 +685,41 @@ static int get_element_size(type_t *type) + return 0; + } + +-static short write_var_desc(struct sltg_data *data, type_t *type, short flags, short base_offset, int *size_instance) ++static int local_href(struct sltg_hrefmap *hrefmap, int typelib_href) ++{ ++ int i, href = -1; ++ ++ for (i = 0; i < hrefmap->href_count; i++) ++ { ++ if (hrefmap->href[i] == typelib_href) ++ { ++ href = i; ++ break; ++ } ++ } ++ ++ if (href == -1) ++ { ++ href = hrefmap->href_count; ++ ++ if (hrefmap->href) ++ hrefmap->href = xrealloc(hrefmap->href, sizeof(*hrefmap->href) * (hrefmap->href_count + 1)); ++ else ++ hrefmap->href = xmalloc(sizeof(*hrefmap->href)); ++ ++ hrefmap->href[hrefmap->href_count] = typelib_href; ++ hrefmap->href_count++; ++ } ++ ++ chat("typelib href %d mapped to local href %d\n", typelib_href, href); ++ ++ return href << 2; ++} ++ ++static short write_var_desc(struct sltg_data *data, type_t *type, short flags, short base_offset, ++ int *size_instance, struct sltg_hrefmap *hrefmap) + { +- short vt, desc_offset; ++ short vt, vt_flags, desc_offset; + + chat("write_var_desc: type %p, type->name %s\n", + type, type->name ? type->name : "NULL"); +@@ -655,27 +809,47 @@ static short write_var_desc(struct sltg_data *data, type_t *type, short flags, s + chat("write_var_desc: vt VT_PTR | 0x0400\n"); + vt = VT_PTR | 0x0400; + append_data(data, &vt, sizeof(vt)); +- write_var_desc(data, ref, 0, base_offset, size_instance); ++ write_var_desc(data, ref, 0, base_offset, size_instance, hrefmap); + } + else +- write_var_desc(data, ref, 0x0e00, base_offset, size_instance); ++ write_var_desc(data, ref, 0x0e00, base_offset, size_instance, hrefmap); + return desc_offset; + } + + chat("write_var_desc: vt %d, flags %04x\n", vt, flags); + ++ vt_flags = vt | flags; ++ append_data(data, &vt_flags, sizeof(vt_flags)); ++ ++ if (vt == VT_USERDEFINED) ++ { ++ short href; ++ ++ while (type->typelib_idx < 0 && type_is_alias(type)) ++ type = type_alias_get_aliasee(type); ++ ++ chat("write_var_desc: VT_USERDEFINED, type %p, name %s, real type %d, href %d\n", ++ type, type->name, type_get_type(type), type->typelib_idx); ++ ++ if (type->typelib_idx == -1) ++ error("write_var_desc: trying to ref not added type\n"); ++ ++ href = local_href(hrefmap, type->typelib_idx); ++ chat("write_var_desc: VT_USERDEFINED, local href %d\n", href); ++ ++ append_data(data, &href, sizeof(href)); ++ } ++ + if (size_instance) + *size_instance += get_element_size(type); + +- vt |= flags; +- append_data(data, &vt, sizeof(vt)); +- + return desc_offset; + } + +-static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *type) ++static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) + { + struct sltg_data data, *var_data = NULL; ++ struct sltg_hrefmap hrefmap; + const char *index_name; + struct sltg_typeinfo_header ti; + struct sltg_member_header member; +@@ -683,15 +857,17 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + int member_offset, var_count = 0, var_data_size = 0, size_instance = 0; + short *type_desc_offset = NULL; + +- chat("add_structure_typeinfo: %s\n", type->name); ++ chat("add_structure_typeinfo: type %p, type->name %s\n", type, type->name); ++ ++ type->typelib_idx = typelib->n_file_blocks; ++ ++ hrefmap.href_count = 0; ++ hrefmap.href = NULL; + + init_sltg_data(&data); + + index_name = add_typeinfo_block(typelib, type, TKIND_RECORD); + +- init_typeinfo(&ti, type, TKIND_RECORD); +- append_data(&data, &ti, sizeof(ti)); +- + if (type_struct_get_fields(type)) + { + int i = 0; +@@ -712,7 +888,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + init_sltg_data(&var_data[i]); + + base_offset = var_data_size + (i + 1) * sizeof(struct sltg_variable); +- type_desc_offset[i] = write_var_desc(&var_data[i], var->type, 0, base_offset, &size_instance); ++ type_desc_offset[i] = write_var_desc(&var_data[i], var->type, 0, base_offset, &size_instance, &hrefmap); + dump_var_desc(var_data[i].data, var_data[i].size); + + if (var_data[i].size > sizeof(short)) +@@ -721,6 +897,11 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t + } + } + ++ init_typeinfo(&ti, type, TKIND_RECORD, &hrefmap); ++ append_data(&data, &ti, sizeof(ti)); ++ ++ write_hrefmap(&data, &hrefmap); ++ + member_offset = data.size; + + member.res00 = 0x0001; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0011-widl-Factor-out-SLTG-tail-initialization.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0011-widl-Factor-out-SLTG-tail-initialization.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0011-widl-Factor-out-SLTG-tail-initialization.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0011-widl-Factor-out-SLTG-tail-initialization.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,89 @@ +From 42f5da70a5224b25d783ee628b18adc856d2eac4 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Wed, 13 Jan 2016 16:25:00 +0800 +Subject: widl: Factor out SLTG tail initialization. + +--- + tools/widl/write_sltg.c | 56 +++++++++++++++++++++++++++++-------------------- + 1 file changed, 33 insertions(+), 23 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index dbe75c6..b417dc2 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -555,6 +555,37 @@ static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, i + } + } + ++static void init_sltg_tail(struct sltg_tail *tail) ++{ ++ tail->cFuncs = 0; ++ tail->cVars = 0; ++ tail->cImplTypes = 0; ++ tail->res06 = 0; ++ tail->funcs_off = -1; ++ tail->vars_off = 0; ++ tail->impls_off = -1; ++ tail->funcs_bytes = -1; ++ tail->vars_bytes = 0; ++ tail->impls_bytes = -1; ++ tail->tdescalias_vt = -1; ++ tail->res16 = -1; ++ tail->res18 = 0; ++ tail->res1a = 0; ++ tail->simple_alias = 0; ++ tail->res1e = 0; ++ tail->cbSizeInstance = 0; ++ tail->cbAlignment = 4; ++ tail->res24 = -1; ++ tail->res26 = -1; ++ tail->cbSizeVft = 0; ++ tail->res2a = -1; ++ tail->res2c = -1; ++ tail->res2e = -1; ++ tail->res30 = -1; ++ tail->res32 = 0; ++ tail->type_bytes = 0; ++} ++ + static void write_hrefmap(struct sltg_data *data, const struct sltg_hrefmap *hrefmap) + { + struct sltg_hrefinfo hrefinfo; +@@ -953,32 +984,11 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) + } + } + +- tail.cFuncs = 0; ++ init_sltg_tail(&tail); ++ + tail.cVars = var_count; +- tail.cImplTypes = 0; +- tail.res06 = 0; +- tail.funcs_off = -1; +- tail.vars_off = 0; +- tail.impls_off = -1; +- tail.funcs_bytes = -1; + tail.vars_bytes = var_data_size; +- tail.impls_bytes = -1; +- tail.tdescalias_vt = -1; +- tail.res16 = -1; +- tail.res18 = 0; +- tail.res1a = 0; +- tail.simple_alias = 0; +- tail.res1e = 0; + tail.cbSizeInstance = size_instance; +- tail.cbAlignment = 4; +- tail.res24 = -1; +- tail.res26 = -1; +- tail.cbSizeVft = 0; +- tail.res2a = -1; +- tail.res2c = -1; +- tail.res2e = -1; +- tail.res30 = -1; +- tail.res32 = 0; + tail.type_bytes = data.size - member_offset - sizeof(member); + append_data(&data, &tail, sizeof(tail)); + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0012-widl-Add-support-for-recursive-type-references-to-SL.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0012-widl-Add-support-for-recursive-type-references-to-SL.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0012-widl-Add-support-for-recursive-type-references-to-SL.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0012-widl-Add-support-for-recursive-type-references-to-SL.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,159 @@ +From e35374deb70ca2dd7e26df954b57e61dd21668a4 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Thu, 14 Jan 2016 15:16:37 +0800 +Subject: widl: Add support for recursive type references to SLTG typelib + generator. + +--- + tools/widl/write_sltg.c | 66 ++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 46 insertions(+), 20 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index b417dc2..4d9ee01 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -203,6 +203,12 @@ struct sltg_hrefinfo + + #include "poppack.h" + ++static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type); ++static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *type); ++static void add_enum_typeinfo(struct sltg_typelib *typelib, type_t *type); ++static void add_union_typeinfo(struct sltg_typelib *typelib, type_t *type); ++static void add_coclass_typeinfo(struct sltg_typelib *typelib, type_t *type); ++ + static void init_sltg_data(struct sltg_data *data) + { + data->size = 0; +@@ -461,11 +467,6 @@ static void append_data(struct sltg_data *block, const void *data, int size) + block->size = new_size; + } + +-static void add_typedef_typeinfo(struct sltg_typelib *typelib, type_t *type) +-{ +- error("add_typedef_typeinfo: %s not implemented\n", type->name); +-} +- + static void add_module_typeinfo(struct sltg_typelib *typelib, type_t *type) + { + error("add_module_typeinfo: %s not implemented\n", type->name); +@@ -747,8 +748,8 @@ static int local_href(struct sltg_hrefmap *hrefmap, int typelib_href) + return href << 2; + } + +-static short write_var_desc(struct sltg_data *data, type_t *type, short flags, short base_offset, +- int *size_instance, struct sltg_hrefmap *hrefmap) ++static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data, type_t *type, short flags, ++ short base_offset, int *size_instance, struct sltg_hrefmap *hrefmap) + { + short vt, vt_flags, desc_offset; + +@@ -840,10 +841,10 @@ static short write_var_desc(struct sltg_data *data, type_t *type, short flags, s + chat("write_var_desc: vt VT_PTR | 0x0400\n"); + vt = VT_PTR | 0x0400; + append_data(data, &vt, sizeof(vt)); +- write_var_desc(data, ref, 0, base_offset, size_instance, hrefmap); ++ write_var_desc(typelib, data, ref, 0, base_offset, size_instance, hrefmap); + } + else +- write_var_desc(data, ref, 0x0e00, base_offset, size_instance, hrefmap); ++ write_var_desc(typelib, data, ref, 0x0e00, base_offset, size_instance, hrefmap); + return desc_offset; + } + +@@ -863,6 +864,33 @@ static short write_var_desc(struct sltg_data *data, type_t *type, short flags, s + type, type->name, type_get_type(type), type->typelib_idx); + + if (type->typelib_idx == -1) ++ { ++ chat("write_var_desc: trying to ref not added type\n"); ++ ++ switch (type_get_type(type)) ++ { ++ case TYPE_STRUCT: ++ add_structure_typeinfo(typelib, type); ++ break; ++ case TYPE_INTERFACE: ++ add_interface_typeinfo(typelib, type); ++ break; ++ case TYPE_ENUM: ++ add_enum_typeinfo(typelib, type); ++ break; ++ case TYPE_UNION: ++ add_union_typeinfo(typelib, type); ++ break; ++ case TYPE_COCLASS: ++ add_coclass_typeinfo(typelib, type); ++ break; ++ default: ++ error("write_var_desc: VT_USERDEFINED - unhandled type %d\n", ++ type_get_type(type)); ++ } ++ } ++ ++ if (type->typelib_idx == -1) + error("write_var_desc: trying to ref not added type\n"); + + href = local_href(hrefmap, type->typelib_idx); +@@ -888,6 +916,8 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) + int member_offset, var_count = 0, var_data_size = 0, size_instance = 0; + short *type_desc_offset = NULL; + ++ if (type->typelib_idx != -1) return; ++ + chat("add_structure_typeinfo: type %p, type->name %s\n", type, type->name); + + type->typelib_idx = typelib->n_file_blocks; +@@ -897,8 +927,6 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) + + init_sltg_data(&data); + +- index_name = add_typeinfo_block(typelib, type, TKIND_RECORD); +- + if (type_struct_get_fields(type)) + { + int i = 0; +@@ -913,13 +941,13 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) + { + short base_offset; + +- chat("add_structure_typeinfo: var %p, name %s, type %p\n", +- var, var->name, var->type); ++ chat("add_structure_typeinfo: var %p (%s), type %p (%s)\n", ++ var, var->name, var->type, var->type->name); + + init_sltg_data(&var_data[i]); + + base_offset = var_data_size + (i + 1) * sizeof(struct sltg_variable); +- type_desc_offset[i] = write_var_desc(&var_data[i], var->type, 0, base_offset, &size_instance, &hrefmap); ++ type_desc_offset[i] = write_var_desc(typelib, &var_data[i], var->type, 0, base_offset, &size_instance, &hrefmap); + dump_var_desc(var_data[i].data, var_data[i].size); + + if (var_data[i].size > sizeof(short)) +@@ -928,6 +956,8 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) + } + } + ++ index_name = add_typeinfo_block(typelib, type, TKIND_RECORD); ++ + init_typeinfo(&ti, type, TKIND_RECORD, &hrefmap); + append_data(&data, &ti, sizeof(ti)); + +@@ -1060,12 +1090,8 @@ static void add_statement(struct sltg_typelib *typelib, const statement_t *stmt) + const type_list_t *type_entry = stmt->u.type_list; + for (; type_entry; type_entry = type_entry->next) + { +- /* if the type is public then add the typedef, otherwise attempt +- * to add the aliased type */ +- if (is_attr(type_entry->type->attrs, ATTR_PUBLIC)) +- add_typedef_typeinfo(typelib, type_entry->type); +- else +- add_type_typeinfo(typelib, type_alias_get_aliasee(type_entry->type)); ++ /* in old style typelibs all types are public */ ++ add_type_typeinfo(typelib, type_entry->type); + } + break; + } +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0013-widl-Add-support-for-interfaces-to-SLTG-typelib-gene.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0013-widl-Add-support-for-interfaces-to-SLTG-typelib-gene.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0013-widl-Add-support-for-interfaces-to-SLTG-typelib-gene.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0013-widl-Add-support-for-interfaces-to-SLTG-typelib-gene.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,519 @@ +From 28b03b8cabf03e68c6a11822e66518b7b1e578c4 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 19 Jan 2016 17:01:01 +0800 +Subject: widl: Add support for interfaces to SLTG typelib generator. + +--- + tools/widl/write_sltg.c | 431 ++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 417 insertions(+), 14 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 4d9ee01..556816f 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -151,8 +151,8 @@ struct sltg_tail + short res1e; /* always 0000 */ + short cbSizeInstance; + short cbAlignment; +- short res24; /* always ffff */ +- short res26; /* always ffff */ ++ short res24; ++ short res26; + short cbSizeVft; + short res2a; /* always ffff */ + short res2c; /* always ffff */ +@@ -201,6 +201,30 @@ struct sltg_hrefinfo + char resxx; /* 0xdf */ + }; + ++struct sltg_function ++{ ++ char magic; /* 0x4c, 0xcb or 0x8b with optional SLTG_FUNCTION_FLAGS_PRESENT flag */ ++ char flags; /* high nibble is INVOKE_KIND, low nibble = 2 */ ++ short next; /* byte offset from beginning of group to next fn */ ++ short name; /* Offset within name table to name */ ++ int dispid; /* dispid */ ++ short helpcontext; /* helpcontext (again 1 is special) */ ++ short helpstring; /* helpstring offset to offset */ ++ short arg_off; /* offset to args from start of block */ ++ char nacc; /* lowest 3bits are CALLCONV, rest are no of args */ ++ char retnextopt; /* if 0x80 bit set ret type follows else next WORD ++ is offset to ret type. No of optional args is ++ middle 6 bits */ ++ short rettype; /* return type VT_?? or offset to ret type */ ++ short vtblpos; /* position in vtbl? */ ++ short funcflags; /* present if magic & 0x20 */ ++/* Param list starts, repeat next two as required */ ++#if 0 ++ WORD name; /* offset to 2nd letter of name */ ++ WORD+ type; /* VT_ of param */ ++#endif ++}; ++ + #include "poppack.h" + + static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type); +@@ -472,11 +496,6 @@ static void add_module_typeinfo(struct sltg_typelib *typelib, type_t *type) + error("add_module_typeinfo: %s not implemented\n", type->name); + } + +-static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *type) +-{ +- error("add_interface_typeinfo: %s not implemented\n", type->name); +-} +- + static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t *type, int kind) + { + const char *index_name, *other_name; +@@ -534,7 +553,7 @@ static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, i + ti->misc.flags = 0; /* FIXME */ + ti->misc.unknown2 = 0x02; + ti->misc.typekind = kind; +- ti->res1e = -1; ++ ti->res1e = 0; + + ti->member_offset = sizeof(*ti); + +@@ -563,10 +582,10 @@ static void init_sltg_tail(struct sltg_tail *tail) + tail->cImplTypes = 0; + tail->res06 = 0; + tail->funcs_off = -1; +- tail->vars_off = 0; ++ tail->vars_off = -1; + tail->impls_off = -1; + tail->funcs_bytes = -1; +- tail->vars_bytes = 0; ++ tail->vars_bytes = -1; + tail->impls_bytes = -1; + tail->tdescalias_vt = -1; + tail->res16 = -1; +@@ -813,8 +832,11 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data + atype = type_array_get_element(atype); + } + +- *size_instance += array_size; +- size_instance = NULL; /* don't account for element size */ ++ if (size_instance) ++ { ++ *size_instance += array_size; ++ size_instance = NULL; /* don't account for element size */ ++ } + + append_data(data, array, size); + +@@ -925,8 +947,6 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) + hrefmap.href_count = 0; + hrefmap.href = NULL; + +- init_sltg_data(&data); +- + if (type_struct_get_fields(type)) + { + int i = 0; +@@ -956,6 +976,8 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) + } + } + ++ init_sltg_data(&data); ++ + index_name = add_typeinfo_block(typelib, type, TKIND_RECORD); + + init_typeinfo(&ti, type, TKIND_RECORD, &hrefmap); +@@ -1017,6 +1039,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) + init_sltg_tail(&tail); + + tail.cVars = var_count; ++ tail.vars_off = 0; + tail.vars_bytes = var_data_size; + tail.cbSizeInstance = size_instance; + tail.type_bytes = data.size - member_offset - sizeof(member); +@@ -1025,6 +1048,386 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) + add_block(typelib, data.data, data.size, index_name); + } + ++static importinfo_t *find_importinfo(typelib_t *typelib, const char *name) ++{ ++ importlib_t *importlib; ++ ++ LIST_FOR_EACH_ENTRY(importlib, &typelib->importlibs, importlib_t, entry) ++ { ++ int i; ++ ++ for (i = 0; i < importlib->ntypeinfos; i++) ++ { ++ if (!strcmp(name, importlib->importinfos[i].name)) ++ { ++ chat("Found %s in importlib list\n", name); ++ return &importlib->importinfos[i]; ++ } ++ } ++ } ++ ++ return NULL; ++} ++ ++static int get_func_flags(const var_t *func, int *dispid, int *invokekind, int *helpcontext, const char **helpstring) ++{ ++ static int dispid_base = 0x60000000; ++ const attr_t *attr; ++ int flags; ++ ++ *dispid = dispid_base++; ++ *invokekind = 1 /* INVOKE_FUNC */; ++ *helpcontext = -2; ++ *helpstring = NULL; ++ ++ if (!func->attrs) return 0; ++ ++ flags = 0; ++ ++ LIST_FOR_EACH_ENTRY(attr, func->attrs, const attr_t, entry) ++ { ++ expr_t *expr = attr->u.pval; ++ switch(attr->type) ++ { ++ case ATTR_BINDABLE: ++ flags |= 0x4; /* FUNCFLAG_FBINDABLE */ ++ break; ++ case ATTR_DEFAULTBIND: ++ flags |= 0x20; /* FUNCFLAG_FDEFAULTBIND */ ++ break; ++ case ATTR_DEFAULTCOLLELEM: ++ flags |= 0x100; /* FUNCFLAG_FDEFAULTCOLLELEM */ ++ break; ++ case ATTR_DISPLAYBIND: ++ flags |= 0x10; /* FUNCFLAG_FDISPLAYBIND */ ++ break; ++ case ATTR_HELPCONTEXT: ++ *helpcontext = expr->u.lval; ++ break; ++ case ATTR_HELPSTRING: ++ *helpstring = attr->u.pval; ++ break; ++ case ATTR_HIDDEN: ++ flags |= 0x40; /* FUNCFLAG_FHIDDEN */ ++ break; ++ case ATTR_ID: ++ *dispid = expr->cval; ++ break; ++ case ATTR_IMMEDIATEBIND: ++ flags |= 0x1000; /* FUNCFLAG_FIMMEDIATEBIND */ ++ break; ++ case ATTR_NONBROWSABLE: ++ flags |= 0x400; /* FUNCFLAG_FNONBROWSABLE */ ++ break; ++ case ATTR_PROPGET: ++ *invokekind = 0x2; /* INVOKE_PROPERTYGET */ ++ break; ++ case ATTR_PROPPUT: ++ *invokekind = 0x4; /* INVOKE_PROPERTYPUT */ ++ break; ++ case ATTR_PROPPUTREF: ++ *invokekind = 0x8; /* INVOKE_PROPERTYPUTREF */ ++ break; ++ /* FIXME: FUNCFLAG_FREPLACEABLE */ ++ case ATTR_REQUESTEDIT: ++ flags |= 0x8; /* FUNCFLAG_FREQUESTEDIT */ ++ break; ++ case ATTR_RESTRICTED: ++ flags |= 0x1; /* FUNCFLAG_FRESTRICTED */ ++ break; ++ case ATTR_SOURCE: ++ flags |= 0x2; /* FUNCFLAG_FSOURCE */ ++ break; ++ case ATTR_UIDEFAULT: ++ flags |= 0x200; /* FUNCFLAG_FUIDEFAULT */ ++ break; ++ case ATTR_USESGETLASTERROR: ++ flags |= 0x80; /* FUNCFLAG_FUSESGETLASTERROR */ ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return flags; ++} ++ ++static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, var_t *func, ++ int idx, short base_offset, struct sltg_hrefmap *hrefmap) ++{ ++ struct sltg_data ret_data, *arg_data; ++ int arg_count = 0, arg_data_size, optional = 0, defaults = 0, old_size; ++ int funcflags = 0, dispid, invokekind = 1 /* INVOKE_FUNC */, helpcontext; ++ const char *helpstring; ++ const var_t *arg; ++ short ret_desc_offset, *arg_desc_offset, arg_offset; ++ struct sltg_function func_desc; ++ ++ chat("add_func_desc: %s, idx %#x\n", func->name, idx); ++ ++ old_size = data->size; ++ ++ init_sltg_data(&ret_data); ++ ret_desc_offset = write_var_desc(typelib, &ret_data, type_function_get_rettype(func->type), ++ 0, base_offset, NULL, hrefmap); ++ dump_var_desc(ret_data.data, ret_data.size); ++ ++ arg_data_size = 0; ++ arg_offset = base_offset + sizeof(struct sltg_function); ++ ++ if (ret_data.size > sizeof(short)) ++ { ++ arg_data_size += ret_data.size; ++ arg_offset += ret_data.size; ++ } ++ ++ if (type_get_function_args(func->type)) ++ { ++ int i = 0; ++ ++ arg_count = list_count(type_get_function_args(func->type)); ++ ++ arg_data = xmalloc(arg_count * sizeof(*arg_data)); ++ arg_desc_offset = xmalloc(arg_count * sizeof(*arg_desc_offset)); ++ ++ arg_offset += arg_count * 2 * sizeof(short); ++ ++ LIST_FOR_EACH_ENTRY(arg, type_get_function_args(func->type), const var_t, entry) ++ { ++ const attr_t *attr; ++ ++ chat("add_func_desc: arg[%d] %p (%s), type %p (%s)\n", ++ i, arg, arg->name, arg->type, arg->type->name); ++ ++ init_sltg_data(&arg_data[i]); ++ ++ arg_desc_offset[i] = write_var_desc(typelib, &arg_data[i], arg->type, 0, arg_offset, NULL, hrefmap); ++ dump_var_desc(arg_data[i].data, arg_data[i].size); ++ ++ if (arg_data[i].size > sizeof(short)) ++ { ++ arg_data_size += arg_data[i].size; ++ arg_offset += arg_data[i].size;; ++ } ++ ++ i++; ++ ++ if (!arg->attrs) continue; ++ ++ LIST_FOR_EACH_ENTRY(attr, arg->attrs, const attr_t, entry) ++ { ++ if (attr->type == ATTR_DEFAULTVALUE) ++ defaults++; ++ else if(attr->type == ATTR_OPTIONAL) ++ optional++; ++ } ++ } ++ } ++ ++ funcflags = get_func_flags(func, &dispid, &invokekind, &helpcontext, &helpstring); ++ ++ if (base_offset != -1) ++ chat("add_func_desc: flags %#x, dispid %#x, invokekind %d, helpcontext %#x, helpstring %s\n", ++ funcflags, dispid, invokekind, helpcontext, helpstring); ++ ++ func_desc.magic = 0x6c; /* always write flags to simplify calculations */ ++ func_desc.flags = (invokekind << 4) | 0x02; ++ if (idx & 0x80000000) ++ { ++ func_desc.next = -1; ++ idx &= ~0x80000000; ++ } ++ else ++ func_desc.next = base_offset + sizeof(func_desc) + arg_data_size + arg_count * 2 * sizeof(short); ++ func_desc.name = base_offset != -1 ? add_name(typelib, func->name) : -1; ++ func_desc.dispid = dispid; ++ func_desc.helpcontext = helpcontext; ++ func_desc.helpstring = (helpstring && base_offset != -1) ? add_name(typelib, helpstring) : -1; ++ func_desc.arg_off = arg_count ? base_offset + sizeof(func_desc) : -1; ++ func_desc.nacc = (arg_count << 3) | 4 /* CC_STDCALL */; ++ func_desc.retnextopt = (optional << 1); ++ if (ret_data.size > sizeof(short)) ++ { ++ func_desc.rettype = base_offset + sizeof(func_desc) + ret_desc_offset; ++ if (arg_count) ++ func_desc.arg_off += ret_data.size; ++ } ++ else ++ { ++ func_desc.retnextopt |= 0x80; ++ func_desc.rettype = *(short *)ret_data.data; ++ } ++ func_desc.vtblpos = idx * pointer_size; ++ func_desc.funcflags = funcflags; ++ ++ append_data(data, &func_desc, sizeof(func_desc)); ++ ++ arg_offset = base_offset + sizeof(struct sltg_function); ++ ++ if (ret_data.size > sizeof(short)) ++ { ++ append_data(data, ret_data.data, ret_data.size); ++ func_desc.arg_off += ret_data.size; ++ arg_offset += ret_data.size; ++ } ++ ++ if (arg_count) ++ { ++ int i = 0; ++ ++ arg_offset += arg_count * 2 * sizeof(short); ++ ++ LIST_FOR_EACH_ENTRY(arg, type_get_function_args(func->type), const var_t, entry) ++ { ++ short name, type_offset; ++ ++ name = base_offset != -1 ? add_name(typelib, arg->name) : -1; ++ append_data(data, &name, sizeof(name)); ++ ++ if (arg_data[i].size > sizeof(short)) ++ { ++ type_offset = (arg_offset + arg_desc_offset[i]); ++ arg_offset += arg_data[i].size; ++ } ++ else ++ type_offset = *(short *)arg_data[i].data; ++ ++ append_data(data, &type_offset, sizeof(type_offset)); ++ ++ if (base_offset != -1) ++ chat("add_func_desc: arg[%d] - name %s (%#x), type_offset %#x\n", ++ i, arg->name, name, type_offset); ++ ++ i++; ++ } ++ ++ for (i = 0; i < arg_count; i++) ++ { ++ if (arg_data[i].size > sizeof(short)) ++ append_data(data, arg_data[i].data, arg_data[i].size); ++ } ++ } ++ ++ return data->size - old_size; ++} ++ ++static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) ++{ ++ const statement_t *stmt_func; ++ importinfo_t *ref_importinfo = NULL; ++ type_t *inherit; ++ struct sltg_data data; ++ struct sltg_hrefmap hrefmap; ++ const char *index_name; ++ struct sltg_typeinfo_header ti; ++ struct sltg_member_header member; ++ struct sltg_tail tail; ++ int member_offset, base_offset, func_count, func_data_size, i; ++ ++ if (iface->typelib_idx != -1) return; ++ ++ chat("add_interface_typeinfo: type %p, type->name %s\n", iface, iface->name); ++ ++ if (!iface->details.iface) ++ { ++ error("interface %s is referenced but not defined\n", iface->name); ++ return; ++ } ++ ++ if (is_attr(iface->attrs, ATTR_DISPINTERFACE)) ++ { ++ error("support for dispinterface %s is not implemented\n", iface->name); ++ return; ++ } ++ ++ inherit = type_iface_get_inherit(iface); ++ ++ if (inherit) ++ { ++ chat("add_interface_typeinfo: inheriting from base interface %s\n", inherit->name); ++ ++ warning("inheriting from base interface %s is not implemented\n", inherit->name); ++ ++ ref_importinfo = find_importinfo(typelib->typelib, inherit->name); ++ ++ if (!ref_importinfo && type_iface_get_inherit(inherit)) ++ add_interface_typeinfo(typelib, inherit); ++ ++ if (ref_importinfo) ++ error("support for imported interfaces is not implemented\n"); ++ } ++ ++ /* check typelib_idx again, it could have been added while resolving the parent interface */ ++ if (iface->typelib_idx != -1) return; ++ ++ iface->typelib_idx = typelib->n_file_blocks; ++ ++ /* pass 1: calculate function descriptions data size */ ++ hrefmap.href_count = 0; ++ hrefmap.href = NULL; ++ ++ init_sltg_data(&data); ++ ++ STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface)) ++ { ++ add_func_desc(typelib, &data, stmt_func->u.var, -1, -1, &hrefmap); ++ } ++ ++ func_data_size = data.size; ++ ++ /* pass 2: write function descriptions */ ++ init_sltg_data(&data); ++ ++ func_count = list_count(type_iface_get_stmts(iface)); ++ ++ index_name = add_typeinfo_block(typelib, iface, TKIND_INTERFACE); ++ ++ init_typeinfo(&ti, iface, TKIND_INTERFACE, &hrefmap); ++ append_data(&data, &ti, sizeof(ti)); ++ ++ write_hrefmap(&data, &hrefmap); ++ ++ member_offset = data.size; ++ ++ member.res00 = 0x0001; ++ member.res02 = 0xffff; ++ member.res04 = 0x01; ++ member.extra = func_data_size; ++ append_data(&data, &member, sizeof(member)); ++ ++ base_offset = 0; ++ ++ /* inheriting from base interface is not implemented yet ++ if (type_iface_get_inherit(iface)) ++ add_impl_type(typeinfo, type_iface_get_inherit(iface), ref_importinfo); ++ */ ++ ++ i = 0; ++ ++ STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface)) ++ { ++ if (i == func_count - 1) i |= 0x80000000; ++ ++ base_offset += add_func_desc(typelib, &data, stmt_func->u.var, i, base_offset, &hrefmap); ++ i++; ++ } ++ ++ init_sltg_tail(&tail); ++ ++ tail.cFuncs = func_count; ++ tail.funcs_off = 0; ++ tail.funcs_bytes = func_data_size; ++ tail.cbSizeInstance = pointer_size; ++ tail.cbAlignment = pointer_size; ++ tail.cbSizeVft = func_count * pointer_size; ++ tail.type_bytes = data.size - member_offset - sizeof(member); ++ tail.res24 = 0; ++ tail.res26 = 0; ++ append_data(&data, &tail, sizeof(tail)); ++ ++ add_block(typelib, data.data, data.size, index_name); ++} ++ + static void add_enum_typeinfo(struct sltg_typelib *typelib, type_t *type) + { + error("add_enum_typeinfo: %s not implemented\n", type->name); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0014-widl-Add-support-for-inherited-interfaces-to-SLTG-ty.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0014-widl-Add-support-for-inherited-interfaces-to-SLTG-ty.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0014-widl-Add-support-for-inherited-interfaces-to-SLTG-ty.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0014-widl-Add-support-for-inherited-interfaces-to-SLTG-ty.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,185 @@ +From 95266a585cb4c924250c900a3b8c3c63ebbf0699 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 19 Jan 2016 18:44:00 +0800 +Subject: widl: Add support for inherited interfaces to SLTG typelib generator. + +--- + tools/widl/write_sltg.c | 90 +++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 73 insertions(+), 17 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 556816f..c8a8cfb 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -225,6 +225,22 @@ struct sltg_function + #endif + }; + ++struct sltg_impl_info ++{ ++ short res00; ++ short next; ++ short res04; ++ char impltypeflags; ++ char res07; ++ short res08; ++ short ref; ++ short res0c; ++ short res0e; ++ short res10; ++ short res12; ++ short pos; ++}; ++ + #include "poppack.h" + + static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type); +@@ -1311,18 +1327,39 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v + return data->size - old_size; + } + ++static void write_impl_href(struct sltg_data *data, short href) ++{ ++ struct sltg_impl_info impl_info; ++ ++ impl_info.res00 = 0x004a; ++ impl_info.next = -1; ++ impl_info.res04 = -1; ++ impl_info.impltypeflags = 0; ++ impl_info.res07 = 0x80; ++ impl_info.res08 = 0x0012; ++ impl_info.ref = href; ++ impl_info.res0c = 0x4001; ++ impl_info.res0e = -2; /* 0xfffe */ ++ impl_info.res10 = -1; ++ impl_info.res12 = 0x001d; ++ impl_info.pos = 0; ++ ++ append_data(data, &impl_info, sizeof(impl_info)); ++} ++ + static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + { + const statement_t *stmt_func; + importinfo_t *ref_importinfo = NULL; +- type_t *inherit; ++ short inherit_href = -1; + struct sltg_data data; + struct sltg_hrefmap hrefmap; + const char *index_name; + struct sltg_typeinfo_header ti; + struct sltg_member_header member; + struct sltg_tail tail; +- int member_offset, base_offset, func_count, func_data_size, i; ++ int member_offset, base_offset, func_data_size, i; ++ int func_count, inherited_func_count = 0; + + if (iface->typelib_idx != -1) return; + +@@ -1340,13 +1377,16 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + return; + } + +- inherit = type_iface_get_inherit(iface); ++ hrefmap.href_count = 0; ++ hrefmap.href = NULL; + +- if (inherit) ++ if (type_iface_get_inherit(iface)) + { +- chat("add_interface_typeinfo: inheriting from base interface %s\n", inherit->name); ++ type_t *inherit; + +- warning("inheriting from base interface %s is not implemented\n", inherit->name); ++ inherit = type_iface_get_inherit(iface); ++ ++ chat("add_interface_typeinfo: inheriting from base interface %s\n", inherit->name); + + ref_importinfo = find_importinfo(typelib->typelib, inherit->name); + +@@ -1355,6 +1395,14 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + + if (ref_importinfo) + error("support for imported interfaces is not implemented\n"); ++ ++ inherit_href = local_href(&hrefmap, inherit->typelib_idx); ++ ++ while (inherit) ++ { ++ inherited_func_count += list_count(type_iface_get_stmts(inherit)); ++ inherit = type_iface_get_inherit(inherit); ++ } + } + + /* check typelib_idx again, it could have been added while resolving the parent interface */ +@@ -1363,9 +1411,6 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + iface->typelib_idx = typelib->n_file_blocks; + + /* pass 1: calculate function descriptions data size */ +- hrefmap.href_count = 0; +- hrefmap.href = NULL; +- + init_sltg_data(&data); + + STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface)) +@@ -1388,19 +1433,21 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + write_hrefmap(&data, &hrefmap); + + member_offset = data.size; ++ base_offset = 0; + + member.res00 = 0x0001; + member.res02 = 0xffff; + member.res04 = 0x01; + member.extra = func_data_size; ++ if (inherit_href != -1) ++ { ++ member.extra += sizeof(struct sltg_impl_info); ++ base_offset += sizeof(struct sltg_impl_info); ++ } + append_data(&data, &member, sizeof(member)); + +- base_offset = 0; +- +- /* inheriting from base interface is not implemented yet +- if (type_iface_get_inherit(iface)) +- add_impl_type(typeinfo, type_iface_get_inherit(iface), ref_importinfo); +- */ ++ if (inherit_href != -1) ++ write_impl_href(&data, inherit_href); + + i = 0; + +@@ -1408,7 +1455,8 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + { + if (i == func_count - 1) i |= 0x80000000; + +- base_offset += add_func_desc(typelib, &data, stmt_func->u.var, i, base_offset, &hrefmap); ++ base_offset += add_func_desc(typelib, &data, stmt_func->u.var, ++ inherited_func_count + i, base_offset, &hrefmap); + i++; + } + +@@ -1419,10 +1467,18 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + tail.funcs_bytes = func_data_size; + tail.cbSizeInstance = pointer_size; + tail.cbAlignment = pointer_size; +- tail.cbSizeVft = func_count * pointer_size; ++ tail.cbSizeVft = (inherited_func_count + func_count) * pointer_size; + tail.type_bytes = data.size - member_offset - sizeof(member); + tail.res24 = 0; + tail.res26 = 0; ++ if (inherit_href != -1) ++ { ++ tail.cImplTypes++; ++ tail.impls_off = 0; ++ tail.impls_bytes = 0; ++ ++ tail.funcs_off += sizeof(struct sltg_impl_info); ++ } + append_data(&data, &tail, sizeof(tail)); + + add_block(typelib, data.data, data.size, index_name); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0015-widl-Make-automatic-dispid-generation-scheme-better-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0015-widl-Make-automatic-dispid-generation-scheme-better-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0015-widl-Make-automatic-dispid-generation-scheme-better-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0015-widl-Make-automatic-dispid-generation-scheme-better-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,92 @@ +From 547416b9ea25c0aa2841b36ed0332304ac70d568 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Wed, 20 Jan 2016 11:04:00 +0800 +Subject: widl: Make automatic dispid generation scheme better match what midl + does. + +--- + tools/widl/write_sltg.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index c8a8cfb..ffecb59 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -1087,11 +1087,9 @@ static importinfo_t *find_importinfo(typelib_t *typelib, const char *name) + + static int get_func_flags(const var_t *func, int *dispid, int *invokekind, int *helpcontext, const char **helpstring) + { +- static int dispid_base = 0x60000000; + const attr_t *attr; + int flags; + +- *dispid = dispid_base++; + *invokekind = 1 /* INVOKE_FUNC */; + *helpcontext = -2; + *helpstring = NULL; +@@ -1169,17 +1167,17 @@ static int get_func_flags(const var_t *func, int *dispid, int *invokekind, int * + } + + static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, var_t *func, +- int idx, short base_offset, struct sltg_hrefmap *hrefmap) ++ int idx, int dispid, short base_offset, struct sltg_hrefmap *hrefmap) + { + struct sltg_data ret_data, *arg_data; + int arg_count = 0, arg_data_size, optional = 0, defaults = 0, old_size; +- int funcflags = 0, dispid, invokekind = 1 /* INVOKE_FUNC */, helpcontext; ++ int funcflags = 0, invokekind = 1 /* INVOKE_FUNC */, helpcontext; + const char *helpstring; + const var_t *arg; + short ret_desc_offset, *arg_desc_offset, arg_offset; + struct sltg_function func_desc; + +- chat("add_func_desc: %s, idx %#x\n", func->name, idx); ++ chat("add_func_desc: %s, idx %#x, dispid %#x\n", func->name, idx, dispid); + + old_size = data->size; + +@@ -1360,6 +1358,7 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + struct sltg_tail tail; + int member_offset, base_offset, func_data_size, i; + int func_count, inherited_func_count = 0; ++ int dispid, inherit_level = 0; + + if (iface->typelib_idx != -1) return; + +@@ -1400,6 +1399,7 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + + while (inherit) + { ++ inherit_level++; + inherited_func_count += list_count(type_iface_get_stmts(inherit)); + inherit = type_iface_get_inherit(inherit); + } +@@ -1415,7 +1415,7 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + + STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface)) + { +- add_func_desc(typelib, &data, stmt_func->u.var, -1, -1, &hrefmap); ++ add_func_desc(typelib, &data, stmt_func->u.var, -1, -1, -1, &hrefmap); + } + + func_data_size = data.size; +@@ -1450,13 +1450,15 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + write_impl_href(&data, inherit_href); + + i = 0; ++ dispid = 0x60000000 | (inherit_level << 16); + + STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface)) + { + if (i == func_count - 1) i |= 0x80000000; + + base_offset += add_func_desc(typelib, &data, stmt_func->u.var, +- inherited_func_count + i, base_offset, &hrefmap); ++ inherited_func_count + i, ++ dispid++, base_offset, &hrefmap); + i++; + } + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0016-widl-Create-library-block-index-right-after-the-Comp.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0016-widl-Create-library-block-index-right-after-the-Comp.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0016-widl-Create-library-block-index-right-after-the-Comp.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0016-widl-Create-library-block-index-right-after-the-Comp.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,105 @@ +From b7e44becb728a5e250d34819501a0e7919e48265 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Wed, 20 Jan 2016 13:26:49 +0800 +Subject: widl: Create library block index right after the CompObj one. + +Otherwise Wine's oleaut32 refuses to load a typelib. +--- + tools/widl/write_sltg.c | 39 +++++++++++++++++++++++++++------------ + 1 file changed, 27 insertions(+), 12 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index ffecb59..bf2ba5f 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -374,15 +374,13 @@ static void init_library(struct sltg_typelib *sltg) + } + } + +-static void add_block(struct sltg_typelib *sltg, void *data, int size, const char *name) ++static void add_block_index(struct sltg_typelib *sltg, void *data, int size, int index) + { + struct sltg_block *block = xmalloc(sizeof(*block)); + +- chat("add_block: %p,%d,\"%s\"\n", data, size, name); +- + block->length = size; + block->data = data; +- block->index_string = add_index(&sltg->index, name); ++ block->index_string = index; + block->next = NULL; + + if (sltg->blocks) +@@ -400,17 +398,28 @@ static void add_block(struct sltg_typelib *sltg, void *data, int size, const cha + sltg->n_file_blocks++; + } + +-static void add_library_block(struct sltg_typelib *typelib) ++static void add_block(struct sltg_typelib *sltg, void *data, int size, const char *name) ++{ ++ struct sltg_block *block = xmalloc(sizeof(*block)); ++ int index; ++ ++ chat("add_block: %p,%d,\"%s\"\n", data, size, name); ++ ++ index = add_index(&sltg->index, name); ++ ++ add_block_index(sltg, data, size, index); ++} ++ ++static void *create_library_block(struct sltg_typelib *typelib, int *size, int *index) + { + void *block; + short *p; +- int size; + +- size = sizeof(short) * 9 + sizeof(int) * 3 + sizeof(GUID); +- if (typelib->library.helpstring) size += strlen(typelib->library.helpstring); +- if (typelib->library.helpfile) size += strlen(typelib->library.helpfile); ++ *size = sizeof(short) * 9 + sizeof(int) * 3 + sizeof(GUID); ++ if (typelib->library.helpstring) *size += strlen(typelib->library.helpstring); ++ if (typelib->library.helpfile) *size += strlen(typelib->library.helpfile); + +- block = xmalloc(size); ++ block = xmalloc(*size); + p = block; + *p++ = 0x51cc; /* magic */ + *p++ = 3; /* res02 */ +@@ -443,7 +452,9 @@ static void add_library_block(struct sltg_typelib *typelib) + p += 2; + *(GUID *)p = typelib->library.uuid; + +- add_block(typelib, block, size, "dir"); ++ *index = add_index(&typelib->index, "dir"); ++ ++ return block; + } + + static const char *new_index_name(void) +@@ -1764,6 +1775,8 @@ int create_sltg_typelib(typelib_t *typelib) + { + struct sltg_typelib sltg; + const statement_t *stmt; ++ void *library_block; ++ int library_block_size, library_block_index; + + pointer_size = (typelib_kind == SYS_WIN64) ? 8 : 4; + +@@ -1779,11 +1792,13 @@ int create_sltg_typelib(typelib_t *typelib) + init_name_table(&sltg); + init_library(&sltg); + ++ library_block = create_library_block(&sltg, &library_block_size, &library_block_index); ++ + if (typelib->stmts) + LIST_FOR_EACH_ENTRY(stmt, typelib->stmts, const statement_t, entry) + add_statement(&sltg, stmt); + +- add_library_block(&sltg); ++ add_block_index(&sltg, library_block, library_block_size, library_block_index); + + save_all_changes(&sltg); + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0017-widl-Fix-generation-of-resources-containing-an-old-t.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0017-widl-Fix-generation-of-resources-containing-an-old-t.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0017-widl-Fix-generation-of-resources-containing-an-old-t.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0017-widl-Fix-generation-of-resources-containing-an-old-t.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,69 @@ +From 901d73cf56c406816555912ab2f089d80bba49db Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Wed, 20 Jan 2016 14:26:48 +0800 +Subject: widl: Fix generation of resources containing an old typelib. + +--- + tools/widl/typelib.c | 2 +- + tools/widl/widl.c | 5 +++-- + tools/widl/widl.h | 1 + + 3 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c +index aa3305c..3de8691 100644 +--- a/tools/widl/typelib.c ++++ b/tools/widl/typelib.c +@@ -249,7 +249,7 @@ void end_typelib(void) + { + if (!typelib) return; + +- if (do_typelib == 2) ++ if (do_old_typelib) + create_sltg_typelib(typelib); + else + create_msft_typelib(typelib); +diff --git a/tools/widl/widl.c b/tools/widl/widl.c +index 1180e65..afeea39 100644 +--- a/tools/widl/widl.c ++++ b/tools/widl/widl.c +@@ -103,6 +103,7 @@ int do_everything = 1; + static int preprocess_only = 0; + int do_header = 0; + int do_typelib = 0; ++int do_old_typelib = 0; + int do_proxies = 0; + int do_client = 0; + int do_server = 0; +@@ -308,6 +309,7 @@ static void set_everything(int x) + { + do_header = x; + do_typelib = x; ++ do_old_typelib = x; + do_proxies = x; + do_client = x; + do_server = x; +@@ -682,8 +684,7 @@ int main(int argc,char *argv[]) + do_typelib = 1; + break; + case OLD_TYPELIB_OPTION: +- do_everything = 0; +- do_typelib = 2; ++ do_old_typelib = 1; + break; + case 'T': + typelib_name = xstrdup(optarg); +diff --git a/tools/widl/widl.h b/tools/widl/widl.h +index 09e7871..90b6366 100644 +--- a/tools/widl/widl.h ++++ b/tools/widl/widl.h +@@ -38,6 +38,7 @@ extern int pedantic; + extern int do_everything; + extern int do_header; + extern int do_typelib; ++extern int do_old_typelib; + extern int do_proxies; + extern int do_client; + extern int do_server; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0018-widl-Add-oldtlb-switch-in-usage-message.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0018-widl-Add-oldtlb-switch-in-usage-message.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0018-widl-Add-oldtlb-switch-in-usage-message.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0018-widl-Add-oldtlb-switch-in-usage-message.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,24 @@ +From 3f9d49c152b1116b2349ad9cc9acf98da017f39a Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 21 Jan 2016 02:51:56 +0100 +Subject: widl: Add --oldtlb switch in usage message. + +--- + tools/widl/widl.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/widl/widl.c b/tools/widl/widl.c +index afeea39..c90b806 100644 +--- a/tools/widl/widl.c ++++ b/tools/widl/widl.c +@@ -65,6 +65,7 @@ static const char usage[] = + " -m32, -m64 Set the kind of typelib to build (Win32 or Win64)\n" + " -N Do not preprocess input\n" + " --oldnames Use old naming conventions\n" ++" --oldtlb Use old typelib (SLTG) format\n" + " -o, --output=NAME Set the output file name\n" + " -Otype Type of stubs to generate (-Os, -Oi, -Oif)\n" + " -p Generate proxy\n" +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0019-widl-Avoid-relying-on-side-effects-when-marking-func.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0019-widl-Avoid-relying-on-side-effects-when-marking-func.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0019-widl-Avoid-relying-on-side-effects-when-marking-func.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0019-widl-Avoid-relying-on-side-effects-when-marking-func.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,33 @@ +From 2404f4a367d658dc2b54f89381e6038a1bb68660 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 22 Jan 2016 11:52:22 +0800 +Subject: widl: Avoid relying on side effects when marking function index as + the last one. + +--- + tools/widl/write_sltg.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index bf2ba5f..acfc039 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -1465,11 +1465,12 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) + + STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface)) + { +- if (i == func_count - 1) i |= 0x80000000; ++ int idx = inherited_func_count + i; ++ ++ if (i == func_count - 1) idx |= 0x80000000; + + base_offset += add_func_desc(typelib, &data, stmt_func->u.var, +- inherited_func_count + i, +- dispid++, base_offset, &hrefmap); ++ idx, dispid + i, base_offset, &hrefmap); + i++; + } + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0020-widl-Set-the-lowest-bit-in-the-param-name-to-indicat.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0020-widl-Set-the-lowest-bit-in-the-param-name-to-indicat.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0020-widl-Set-the-lowest-bit-in-the-param-name-to-indicat.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0020-widl-Set-the-lowest-bit-in-the-param-name-to-indicat.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,45 @@ +From f52df44c1930e62fa9096f24ba8b1b84765c0e34 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Mon, 25 Jan 2016 15:05:03 +0800 +Subject: widl: Set the lowest bit in the param name to indicate whether type + description follows the name. + +It looks like the lowest bit in the param name offset actually indicates +whether type description follows the name, and since the name offsets are +always aligned that makes sense. + +This makes oleview.exe from PSDK running under Windows7 correctly show mix +of different very complex and relatively simple type descriptions generated +by widl's SLTG generator. +--- + tools/widl/write_sltg.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index acfc039..2ec1770 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -1307,7 +1307,6 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v + short name, type_offset; + + name = base_offset != -1 ? add_name(typelib, arg->name) : -1; +- append_data(data, &name, sizeof(name)); + + if (arg_data[i].size > sizeof(short)) + { +@@ -1315,8 +1314,12 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v + arg_offset += arg_data[i].size; + } + else ++ { ++ name |= 1; + type_offset = *(short *)arg_data[i].data; ++ } + ++ append_data(data, &name, sizeof(name)); + append_data(data, &type_offset, sizeof(type_offset)); + + if (base_offset != -1) +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0021-oleaut32-Fix-logic-for-deciding-whether-type-descrip.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0021-oleaut32-Fix-logic-for-deciding-whether-type-descrip.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0021-oleaut32-Fix-logic-for-deciding-whether-type-descrip.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0021-oleaut32-Fix-logic-for-deciding-whether-type-descrip.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,63 @@ +From ed5f6c45666a220fd9f2532d0ab55bc9e4e7054c Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Wed, 20 Jan 2016 14:04:08 +0800 +Subject: oleaut32: Fix logic for deciding whether type description follows the + name (v2). + +This makes it possible to load an SLTG typelib generated by widl. + +It looks like the lowest bit actually indicates whether type description +follows the name, and since the name offsets are always aligned that makes +sense. +--- + dlls/oleaut32/typelib.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c +index 0a83b79..d8d8ec8 100644 +--- a/dlls/oleaut32/typelib.c ++++ b/dlls/oleaut32/typelib.c +@@ -4214,7 +4214,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, + pArg = (WORD*)(pBlk + pFunc->arg_off); + + for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) { +- char *paramName = pNameTable + *pArg; ++ char *paramName = pNameTable + (*pArg & ~1); + BOOL HaveOffs; + /* If arg type follows then paramName points to the 2nd + letter of the name, else the next WORD is an offset to +@@ -4225,26 +4225,21 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, + meaning that the next WORD is the type, the latter + meaning that the next WORD is an offset to the type. */ + +- HaveOffs = FALSE; +- if(*pArg == 0xffff) ++ if(*pArg == 0xffff || *pArg == 0xfffe) + paramName = NULL; +- else if(*pArg == 0xfffe) { +- paramName = NULL; +- HaveOffs = TRUE; +- } +- else if(paramName[-1] && !isalnum(paramName[-1])) +- HaveOffs = TRUE; + ++ HaveOffs = !(*pArg & 1); + pArg++; + ++ TRACE_(typelib)("param %d: paramName %s, *pArg %#x\n", ++ param, debugstr_a(paramName), *pArg); ++ + if(HaveOffs) { /* the next word is an offset to type */ + pType = (WORD*)(pBlk + *pArg); + SLTG_DoElem(pType, pBlk, + &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup); + pArg++; + } else { +- if(paramName) +- paramName--; + pArg = SLTG_DoElem(pArg, pBlk, + &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup); + } +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0022-widl-Add-support-for-function-parameter-flags-to-SLT.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0022-widl-Add-support-for-function-parameter-flags-to-SLT.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0022-widl-Add-support-for-function-parameter-flags-to-SLT.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0022-widl-Add-support-for-function-parameter-flags-to-SLT.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,145 @@ +From 95352b40a973bc72e3cd32e1a02b6842f15deea9 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Mon, 25 Jan 2016 15:26:12 +0800 +Subject: widl: Add support for function parameter flags to SLTG typelib + generator. + +This makes stdole32.tlb generated by widl have proper [in,out,retval] +parameter flags. +--- + tools/widl/write_sltg.c | 70 ++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 60 insertions(+), 10 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 2ec1770..3cb137c 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -794,8 +794,8 @@ static int local_href(struct sltg_hrefmap *hrefmap, int typelib_href) + return href << 2; + } + +-static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data, type_t *type, short flags, +- short base_offset, int *size_instance, struct sltg_hrefmap *hrefmap) ++static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data, type_t *type, short param_flags, ++ short flags, short base_offset, int *size_instance, struct sltg_hrefmap *hrefmap) + { + short vt, vt_flags, desc_offset; + +@@ -887,19 +887,20 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data + + if (is_ptr(ref)) + { +- chat("write_var_desc: vt VT_PTR | 0x0400\n"); +- vt = VT_PTR | 0x0400; ++ chat("write_var_desc: vt VT_PTR | 0x0400 | %04x\n", param_flags); ++ vt = VT_PTR | 0x0400 | param_flags; ++ param_flags = 0; + append_data(data, &vt, sizeof(vt)); +- write_var_desc(typelib, data, ref, 0, base_offset, size_instance, hrefmap); ++ write_var_desc(typelib, data, ref, param_flags, 0, base_offset, size_instance, hrefmap); + } + else +- write_var_desc(typelib, data, ref, 0x0e00, base_offset, size_instance, hrefmap); ++ write_var_desc(typelib, data, ref, param_flags, 0x0e00, base_offset, size_instance, hrefmap); + return desc_offset; + } + + chat("write_var_desc: vt %d, flags %04x\n", vt, flags); + +- vt_flags = vt | flags; ++ vt_flags = vt | flags | param_flags; + append_data(data, &vt_flags, sizeof(vt_flags)); + + if (vt == VT_USERDEFINED) +@@ -994,7 +995,8 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type) + init_sltg_data(&var_data[i]); + + base_offset = var_data_size + (i + 1) * sizeof(struct sltg_variable); +- type_desc_offset[i] = write_var_desc(typelib, &var_data[i], var->type, 0, base_offset, &size_instance, &hrefmap); ++ type_desc_offset[i] = write_var_desc(typelib, &var_data[i], var->type, 0, 0, ++ base_offset, &size_instance, &hrefmap); + dump_var_desc(var_data[i].data, var_data[i].size); + + if (var_data[i].size > sizeof(short)) +@@ -1177,6 +1179,52 @@ static int get_func_flags(const var_t *func, int *dispid, int *invokekind, int * + return flags; + } + ++static int get_param_flags(const var_t *param) ++{ ++ const attr_t *attr; ++ int flags, in, out; ++ ++ if (!param->attrs) return 0; ++ ++ flags = 0; ++ in = out = 0; ++ ++ LIST_FOR_EACH_ENTRY(attr, param->attrs, const attr_t, entry) ++ { ++ switch(attr->type) ++ { ++ case ATTR_IN: ++ in++; ++ break; ++ case ATTR_OUT: ++ out++; ++ break; ++ case ATTR_PARAMLCID: ++ flags |= 0x2000; ++ break; ++ case ATTR_RETVAL: ++ flags |= 0x80; ++ break; ++ default: ++ chat("unhandled param attr %d\n", attr->type); ++ break; ++ } ++ } ++ ++ if (out) ++ { ++ if (in) ++ flags |= 0x8000; ++ else ++ flags |= 0x4000; ++ } ++ else if (!in) ++ flags |= 0xc000; ++ ++ return flags; ++} ++ ++ + static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, var_t *func, + int idx, int dispid, short base_offset, struct sltg_hrefmap *hrefmap) + { +@@ -1194,7 +1242,7 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v + + init_sltg_data(&ret_data); + ret_desc_offset = write_var_desc(typelib, &ret_data, type_function_get_rettype(func->type), +- 0, base_offset, NULL, hrefmap); ++ 0, 0, base_offset, NULL, hrefmap); + dump_var_desc(ret_data.data, ret_data.size); + + arg_data_size = 0; +@@ -1220,13 +1268,15 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v + LIST_FOR_EACH_ENTRY(arg, type_get_function_args(func->type), const var_t, entry) + { + const attr_t *attr; ++ short param_flags = get_param_flags(arg); + + chat("add_func_desc: arg[%d] %p (%s), type %p (%s)\n", + i, arg, arg->name, arg->type, arg->type->name); + + init_sltg_data(&arg_data[i]); + +- arg_desc_offset[i] = write_var_desc(typelib, &arg_data[i], arg->type, 0, arg_offset, NULL, hrefmap); ++ arg_desc_offset[i] = write_var_desc(typelib, &arg_data[i], arg->type, param_flags, 0, ++ arg_offset, NULL, hrefmap); + dump_var_desc(arg_data[i].data, arg_data[i].size); + + if (arg_data[i].size > sizeof(short)) +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0023-oleaut32-Implement-decoding-of-SLTG-help-strings.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0023-oleaut32-Implement-decoding-of-SLTG-help-strings.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0023-oleaut32-Implement-decoding-of-SLTG-help-strings.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0023-oleaut32-Implement-decoding-of-SLTG-help-strings.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,245 @@ +From a0bdaee449916e202a5cac26f3e66c28d1566efb Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 26 Jan 2016 15:05:54 +0800 +Subject: oleaut32: Implement decoding of SLTG help strings. + +Based on the patch by Sebastian Lackner . +--- + dlls/oleaut32/typelib.c | 130 +++++++++++++++++++++++++++++++++++++++--------- + dlls/oleaut32/typelib.h | 4 +- + 2 files changed, 109 insertions(+), 25 deletions(-) + +diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c +index d8d8ec8..4fb5a95 100644 +--- a/dlls/oleaut32/typelib.c ++++ b/dlls/oleaut32/typelib.c +@@ -3717,6 +3717,87 @@ static BOOL TLB_GUIDFromString(const char *str, GUID *guid) + return TRUE; + } + ++struct bitstream ++{ ++ const BYTE *buffer; ++ DWORD length; ++ WORD current; ++}; ++ ++static const char *lookup_code(const BYTE *table, DWORD table_size, struct bitstream *bits) ++{ ++ const BYTE *p = table; ++ ++ while (p < table + table_size && *p == 0x80) ++ { ++ if (p + 2 >= table + table_size) return NULL; ++ ++ if (!(bits->current & 0xff)) ++ { ++ if (!bits->length) return NULL; ++ bits->current = (*bits->buffer << 8) | 1; ++ bits->buffer++; ++ bits->length--; ++ } ++ ++ if (bits->current & 0x8000) ++ { ++ p += 3; ++ } ++ else ++ { ++ p = table + (*(p + 2) | (*(p + 1) << 8)); ++ } ++ ++ bits->current <<= 1; ++ } ++ ++ if (p + 1 < table + table_size && *(p + 1)) ++ { ++ /* FIXME: Whats the meaning of *p? */ ++ const BYTE *q = p + 1; ++ while (q < table + table_size && *q) q++; ++ return (q < table + table_size) ? (const char *)(p + 1) : NULL; ++ } ++ ++ return NULL; ++} ++ ++static const TLBString *decode_string(const BYTE *table, const char *stream, DWORD stream_length, ITypeLibImpl *lib) ++{ ++ DWORD buf_size, table_size; ++ const char *p; ++ struct bitstream bits; ++ BSTR buf; ++ TLBString *tlbstr; ++ ++ if (!stream_length) return NULL; ++ ++ bits.buffer = (const BYTE *)stream; ++ bits.length = stream_length; ++ bits.current = 0; ++ ++ buf_size = *(const WORD *)table; ++ table += sizeof(WORD); ++ table_size = *(const DWORD *)table; ++ table += sizeof(DWORD); ++ ++ buf = SysAllocStringLen(NULL, buf_size); ++ buf[0] = 0; ++ ++ while ((p = lookup_code(table, table_size, &bits))) ++ { ++ static const WCHAR spaceW[] = { ' ',0 }; ++ if (buf[0]) strcatW(buf, spaceW); ++ MultiByteToWideChar(CP_ACP, 0, p, -1, buf + strlenW(buf), buf_size - strlenW(buf)); ++ } ++ ++ tlbstr = TLB_append_str(&lib->string_list, buf); ++ SysFreeString(buf); ++ ++ return tlbstr; ++} ++ + static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib) + { + WORD bytelen; +@@ -4400,17 +4481,17 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, + /* Because SLTG_OtherTypeInfo is such a painful struct, we make a more + manageable copy of it into this */ + typedef struct { +- WORD small_no; + char *index_name; + char *other_name; + WORD res1a; + WORD name_offs; +- WORD more_bytes; ++ WORD hlpstr_len; + char *extra; + WORD res20; + DWORD helpcontext; + WORD res26; + GUID uuid; ++ WORD typekind; + } SLTG_InternalOtherTypeInfo; + + /**************************************************************************** +@@ -4429,8 +4510,8 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + LPVOID pBlk, pFirstBlk; + SLTG_LibBlk *pLibBlk; + SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks; +- char *pAfterOTIBlks = NULL; + char *pNameTable, *ptr; ++ const BYTE *hlp_strings; + int i; + DWORD len, order; + ITypeInfoImpl **ppTypeInfoImpl; +@@ -4496,53 +4577,55 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + len += 0x40; + + /* And now TypeInfoCount of SLTG_OtherTypeInfo */ ++ pTypeLibImpl->TypeInfoCount = *(WORD *)((char *)pLibBlk + len); ++ len += sizeof(WORD); + + pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * pTypeLibImpl->TypeInfoCount); + +- + ptr = (char*)pLibBlk + len; + + for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) { + WORD w, extra; + len = 0; + +- pOtherTypeInfoBlks[i].small_no = *(WORD*)ptr; +- +- w = *(WORD*)(ptr + 2); ++ w = *(WORD*)ptr; + if(w != 0xffff) { + len += w; + pOtherTypeInfoBlks[i].index_name = heap_alloc(w+1); +- memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 4, w); ++ memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 2, w); + pOtherTypeInfoBlks[i].index_name[w] = '\0'; + } +- w = *(WORD*)(ptr + 4 + len); ++ w = *(WORD*)(ptr + 2 + len); + if(w != 0xffff) { +- TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w)); +- len += w; ++ TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 4 + len, w)); + pOtherTypeInfoBlks[i].other_name = heap_alloc(w+1); +- memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 6 + len, w); ++ memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 4 + len, w); + pOtherTypeInfoBlks[i].other_name[w] = '\0'; ++ len += w; + } +- pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + len + 6); +- pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8); +- extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len); ++ pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + 4 + len); ++ pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + 6 + len); ++ extra = pOtherTypeInfoBlks[i].hlpstr_len = *(WORD*)(ptr + 8 + len); + if(extra) { + pOtherTypeInfoBlks[i].extra = heap_alloc(extra); +- memcpy(pOtherTypeInfoBlks[i].extra, ptr + 12, extra); ++ memcpy(pOtherTypeInfoBlks[i].extra, ptr + 10 + len, extra); + len += extra; + } +- pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 12 + len); +- pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 14 + len); +- pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 18 + len); +- memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 20 + len, sizeof(GUID)); ++ pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 10 + len); ++ pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 12 + len); ++ pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 16 + len); ++ memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 18 + len, sizeof(GUID)); ++ pOtherTypeInfoBlks[i].typekind = *(WORD*)(ptr + 18 + sizeof(GUID) + len); + len += sizeof(SLTG_OtherTypeInfo); + ptr += len; + } + +- pAfterOTIBlks = ptr; ++ /* Get the next DWORD */ ++ len = *(DWORD*)ptr; + +- /* Skip this WORD and get the next DWORD */ +- len = *(DWORD*)(pAfterOTIBlks + 2); ++ hlp_strings = (const BYTE *)ptr + sizeof(DWORD); ++ TRACE("max help string length %#x, help strings length %#x\n", ++ *(WORD *)hlp_strings, *(DWORD *)(hlp_strings + 2)); + + /* Now add this to pLibBLk look at what we're pointing at and + possibly add 0x20, then add 0x216, sprinkle a bit a magic +@@ -4608,6 +4691,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + (*ppTypeInfoImpl)->index = i; + (*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl); + (*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext; ++ (*ppTypeInfoImpl)->DocString = decode_string(hlp_strings, pOtherTypeInfoBlks[i].extra, pOtherTypeInfoBlks[i].hlpstr_len, pTypeLibImpl); + (*ppTypeInfoImpl)->guid = TLB_append_guid(&pTypeLibImpl->guid_list, &pOtherTypeInfoBlks[i].uuid, 2); + (*ppTypeInfoImpl)->typekind = pTIHeader->typekind; + (*ppTypeInfoImpl)->wMajorVerNum = pTIHeader->major_version; +diff --git a/dlls/oleaut32/typelib.h b/dlls/oleaut32/typelib.h +index 8f274ba..94ec8f2 100644 +--- a/dlls/oleaut32/typelib.h ++++ b/dlls/oleaut32/typelib.h +@@ -387,18 +387,18 @@ typedef struct { + /* we then get 0x40 bytes worth of 0xffff or small numbers followed by + nrOfFileBlks - 2 of these */ + typedef struct { +- WORD small_no; + SLTG_Name index_name; /* This refers to a name in the directory */ + SLTG_Name other_name; /* Another one of these weird names */ + WORD res1a; /* 0xffff */ + WORD name_offs; /* offset to name in name table */ +- WORD more_bytes; /* if this is non-zero we get this many ++ WORD hlpstr_len; /* if this is non-zero we get this many + bytes before the next element, which seem + to reference the docstring of the type ? */ + WORD res20; /* 0xffff */ + DWORD helpcontext; + WORD res26; /* 0xffff */ + GUID uuid; ++ WORD typekind; + } SLTG_OtherTypeInfo; + + /* Next we get WORD 0x0003 followed by a DWORD which if we add to +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0024-oleaut32-Add-support-for-decoding-SLTG-function-help.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0024-oleaut32-Add-support-for-decoding-SLTG-function-help.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0024-oleaut32-Add-support-for-decoding-SLTG-function-help.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0024-oleaut32-Add-support-for-decoding-SLTG-function-help.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,113 @@ +From 3d5236979b081ae707d7f047fbf9e24a3cd0e4cf Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 26 Jan 2016 15:41:06 +0800 +Subject: oleaut32: Add support for decoding SLTG function help strings. + +--- + dlls/oleaut32/typelib.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c +index 4fb5a95..b9d8cbb 100644 +--- a/dlls/oleaut32/typelib.c ++++ b/dlls/oleaut32/typelib.c +@@ -4240,7 +4240,8 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign + } + + static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, +- unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup) ++ unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup, ++ const BYTE *hlp_strings) + { + SLTG_Function *pFunc; + unsigned short i; +@@ -4277,6 +4278,8 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, + pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3; + pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1; + pFuncDesc->funcdesc.oVft = pFunc->vtblpos & ~1; ++ if (pFunc->helpstring != 0xffff) ++ pFuncDesc->HelpString = decode_string(hlp_strings, pBlk + pFunc->helpstring, pNameTable - pBlk, pTI->pTypeLib); + + if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT) + pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags; +@@ -4364,7 +4367,7 @@ static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI, + + static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, +- const SLTG_TypeInfoTail *pTITail) ++ const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + { + char *pFirstItem; + sltg_ref_lookup_t *ref_lookup = NULL; +@@ -4381,7 +4384,7 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, + } + + if (pTITail->funcs_off != 0xffff) +- SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); ++ SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); + + heap_free(ref_lookup); + +@@ -4426,7 +4429,7 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, + + static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, +- const SLTG_TypeInfoTail *pTITail) ++ const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + { + sltg_ref_lookup_t *ref_lookup = NULL; + if (pTIHeader->href_table != 0xffffffff) +@@ -4437,7 +4440,7 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, + SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); + + if (pTITail->funcs_off != 0xffff) +- SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); ++ SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); + + if (pTITail->impls_off != 0xffff) + SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup); +@@ -4461,7 +4464,7 @@ static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, + + static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, +- const SLTG_TypeInfoTail *pTITail) ++ const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + { + sltg_ref_lookup_t *ref_lookup = NULL; + if (pTIHeader->href_table != 0xffffffff) +@@ -4472,7 +4475,7 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, + SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); + + if (pTITail->funcs_off != 0xffff) +- SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); ++ SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); + heap_free(ref_lookup); + if (TRACE_ON(typelib)) + dump_TypeInfo(pTI); +@@ -4734,7 +4737,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + + case TKIND_INTERFACE: + SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, +- pTIHeader, pTITail); ++ pTIHeader, pTITail, hlp_strings); + break; + + case TKIND_COCLASS: +@@ -4749,12 +4752,12 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + + case TKIND_DISPATCH: + SLTG_ProcessDispatch((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, +- pTIHeader, pTITail); ++ pTIHeader, pTITail, hlp_strings); + break; + + case TKIND_MODULE: + SLTG_ProcessModule((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, +- pTIHeader, pTITail); ++ pTIHeader, pTITail, hlp_strings); + break; + + default: +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0025-oleaut32-Add-support-for-decoding-SLTG-variable-help.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0025-oleaut32-Add-support-for-decoding-SLTG-variable-help.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0025-oleaut32-Add-support-for-decoding-SLTG-variable-help.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0025-oleaut32-Add-support-for-decoding-SLTG-variable-help.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,95 @@ +From 1d25ef1b6e9ef476686a3103604850ec5005b658 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Tue, 26 Jan 2016 16:17:21 +0800 +Subject: oleaut32: Add support for decoding SLTG variable help strings. + +--- + dlls/oleaut32/typelib.c | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c +index b9d8cbb..6699e0b 100644 +--- a/dlls/oleaut32/typelib.c ++++ b/dlls/oleaut32/typelib.c +@@ -4129,7 +4129,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, + } + + static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, +- const char *pNameTable, const sltg_ref_lookup_t *ref_lookup) ++ const char *pNameTable, const sltg_ref_lookup_t *ref_lookup, const BYTE *hlp_strings) + { + TLBVarDesc *pVarDesc; + const TLBString *prevName = NULL; +@@ -4159,6 +4159,12 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign + TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs); + TRACE_(typelib)("memid = 0x%x\n", pItem->memid); + ++ if (pItem->helpstring != 0xffff) ++ { ++ pVarDesc->HelpString = decode_string(hlp_strings, pBlk + pItem->helpstring, pNameTable - pBlk, pTI->pTypeLib); ++ TRACE_(typelib)("helpstring = %s\n", debugstr_w(pVarDesc->HelpString->str)); ++ } ++ + if(pItem->flags & 0x02) + pType = &pItem->type; + else +@@ -4394,9 +4400,9 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, + + static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI, + const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, +- const SLTG_TypeInfoTail *pTITail) ++ const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + { +- SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL); ++ SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL, hlp_strings); + } + + static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, +@@ -4437,7 +4443,7 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, + pNameTable); + + if (pTITail->vars_off != 0xffff) +- SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); ++ SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup, hlp_strings); + + if (pTITail->funcs_off != 0xffff) + SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); +@@ -4457,9 +4463,9 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, + + static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, + const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, +- const SLTG_TypeInfoTail *pTITail) ++ const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings) + { +- SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL); ++ SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL, hlp_strings); + } + + static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, +@@ -4472,7 +4478,7 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, + pNameTable); + + if (pTITail->vars_off != 0xffff) +- SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup); ++ SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup, hlp_strings); + + if (pTITail->funcs_off != 0xffff) + SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings); +@@ -4727,12 +4733,12 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) + switch(pTIHeader->typekind) { + case TKIND_ENUM: + SLTG_ProcessEnum((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, +- pTIHeader, pTITail); ++ pTIHeader, pTITail, hlp_strings); + break; + + case TKIND_RECORD: + SLTG_ProcessRecord((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable, +- pTIHeader, pTITail); ++ pTIHeader, pTITail, hlp_strings); + break; + + case TKIND_INTERFACE: +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0026-widl-Minor-cosmetic-clean-up.patch wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0026-widl-Minor-cosmetic-clean-up.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0026-widl-Minor-cosmetic-clean-up.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/0026-widl-Minor-cosmetic-clean-up.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,39 @@ +From 3ad26c39f490daab83f32e87ec6b1b32a27f1bfa Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Thu, 28 Jan 2016 15:36:12 +0800 +Subject: widl: Minor/cosmetic clean up. + +--- + tools/widl/write_sltg.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c +index 3cb137c..04313e6 100644 +--- a/tools/widl/write_sltg.c ++++ b/tools/widl/write_sltg.c +@@ -298,9 +298,9 @@ static int add_name(struct sltg_typelib *sltg, const char *name) + else + new_size = (new_size + 1) & ~1; + +- if (aligned_size > sltg->name_table.allocated) ++ if (new_size > sltg->name_table.allocated) + { +- sltg->name_table.allocated = max(sltg->name_table.allocated * 2, aligned_size); ++ sltg->name_table.allocated = max(sltg->name_table.allocated * 2, new_size); + sltg->name_table.data = xrealloc(sltg->name_table.data, sltg->name_table.allocated); + } + +@@ -889,9 +889,8 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data + { + chat("write_var_desc: vt VT_PTR | 0x0400 | %04x\n", param_flags); + vt = VT_PTR | 0x0400 | param_flags; +- param_flags = 0; + append_data(data, &vt, sizeof(vt)); +- write_var_desc(typelib, data, ref, param_flags, 0, base_offset, size_instance, hrefmap); ++ write_var_desc(typelib, data, ref, 0, 0, base_offset, size_instance, hrefmap); + } + else + write_var_desc(typelib, data, ref, param_flags, 0x0e00, base_offset, size_instance, hrefmap); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/definition wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/widl-SLTG_Typelib_Support/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: Implement support for SLTG typelibs in widl diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Helper/0001-wined3d-Rename-wined3d_resource_-un-map-to-wined3d_r.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Helper/0001-wined3d-Rename-wined3d_resource_-un-map-to-wined3d_r.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Helper/0001-wined3d-Rename-wined3d_resource_-un-map-to-wined3d_r.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Helper/0001-wined3d-Rename-wined3d_resource_-un-map-to-wined3d_r.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ -From 8eaad5ab61fe01c56e9d2622b11fd9f1e058273e Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 4 Nov 2015 19:31:30 +0100 -Subject: wined3d: Rename wined3d_resource_(un)map to - wined3d_resource_sub_resource_(un)map. - -To avoid name conflicts in the CSMT patchset. ---- - dlls/d3d11/device.c | 4 ++-- - dlls/d3d11/texture.c | 8 ++++---- - dlls/d3d8/surface.c | 4 ++-- - dlls/d3d8/volume.c | 4 ++-- - dlls/d3d9/surface.c | 4 ++-- - dlls/d3d9/volume.c | 4 ++-- - dlls/wined3d/resource.c | 4 ++-- - dlls/wined3d/wined3d.spec | 4 ++-- - include/wine/wined3d.h | 6 +++--- - 9 files changed, 21 insertions(+), 21 deletions(-) - -diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c -index 4560f52..b5cb5ed 100644 ---- a/dlls/d3d11/device.c -+++ b/dlls/d3d11/device.c -@@ -215,7 +215,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_immediate_context_Map(ID3D11DeviceContext - wined3d_resource = wined3d_resource_from_d3d11_resource(resource); - - wined3d_mutex_lock(); -- hr = wined3d_resource_map(wined3d_resource, subresource_idx, -+ hr = wined3d_resource_sub_resource_map(wined3d_resource, subresource_idx, - &map_desc, NULL, wined3d_map_flags_from_d3d11_map_type(map_type)); - wined3d_mutex_unlock(); - -@@ -236,7 +236,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_Unmap(ID3D11DeviceContext - wined3d_resource = wined3d_resource_from_d3d11_resource(resource); - - wined3d_mutex_lock(); -- wined3d_resource_unmap(wined3d_resource, subresource_idx); -+ wined3d_resource_sub_resource_unmap(wined3d_resource, subresource_idx); - wined3d_mutex_unlock(); - } - -diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c -index 011a5f7..99e531a 100644 ---- a/dlls/d3d11/texture.c -+++ b/dlls/d3d11/texture.c -@@ -366,7 +366,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_texture2d_Map(ID3D10Texture2D *iface, UIN - FIXME("Ignoring map_flags %#x.\n", map_flags); - - wined3d_mutex_lock(); -- if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx, -+ if (SUCCEEDED(hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx, - &wined3d_map_desc, NULL, wined3d_map_flags_from_d3d11_map_type(map_type)))) - { - mapped_texture->pData = wined3d_map_desc.data; -@@ -384,7 +384,7 @@ static void STDMETHODCALLTYPE d3d10_texture2d_Unmap(ID3D10Texture2D *iface, UINT - TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx); - - wined3d_mutex_lock(); -- wined3d_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx); -+ wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx); - wined3d_mutex_unlock(); - } - -@@ -823,7 +823,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_texture3d_Map(ID3D10Texture3D *iface, UIN - FIXME("Ignoring map_flags %#x.\n", map_flags); - - wined3d_mutex_lock(); -- if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx, -+ if (SUCCEEDED(hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx, - &wined3d_map_desc, NULL, wined3d_map_flags_from_d3d11_map_type(map_type)))) - { - mapped_texture->pData = wined3d_map_desc.data; -@@ -842,7 +842,7 @@ static void STDMETHODCALLTYPE d3d10_texture3d_Unmap(ID3D10Texture3D *iface, UINT - TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx); - - wined3d_mutex_lock(); -- wined3d_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx); -+ wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx); - wined3d_mutex_unlock(); - } - -diff --git a/dlls/d3d8/surface.c b/dlls/d3d8/surface.c -index 679f094..21f1438 100644 ---- a/dlls/d3d8/surface.c -+++ b/dlls/d3d8/surface.c -@@ -234,7 +234,7 @@ static HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface, - box.back = 1; - } - -- hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, -+ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, - &map_desc, rect ? &box : NULL, flags); - wined3d_mutex_unlock(); - -@@ -260,7 +260,7 @@ static HRESULT WINAPI d3d8_surface_UnlockRect(IDirect3DSurface8 *iface) - TRACE("iface %p.\n", iface); - - wined3d_mutex_lock(); -- hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); -+ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); - wined3d_mutex_unlock(); - - switch(hr) -diff --git a/dlls/d3d8/volume.c b/dlls/d3d8/volume.c -index f26e424..d1ee0b5 100644 ---- a/dlls/d3d8/volume.c -+++ b/dlls/d3d8/volume.c -@@ -148,7 +148,7 @@ static HRESULT WINAPI d3d8_volume_LockBox(IDirect3DVolume8 *iface, - iface, locked_box, box, flags); - - wined3d_mutex_lock(); -- hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, -+ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, - &map_desc, (const struct wined3d_box *)box, flags); - wined3d_mutex_unlock(); - -@@ -167,7 +167,7 @@ static HRESULT WINAPI d3d8_volume_UnlockBox(IDirect3DVolume8 *iface) - TRACE("iface %p.\n", iface); - - wined3d_mutex_lock(); -- hr = wined3d_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); -+ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); - wined3d_mutex_unlock(); - - return hr; -diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c -index 833c1f4..54baf83 100644 ---- a/dlls/d3d9/surface.c -+++ b/dlls/d3d9/surface.c -@@ -251,7 +251,7 @@ static HRESULT WINAPI d3d9_surface_LockRect(IDirect3DSurface9 *iface, - } - - wined3d_mutex_lock(); -- hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, -+ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, - &map_desc, rect ? &box : NULL, flags); - wined3d_mutex_unlock(); - -@@ -272,7 +272,7 @@ static HRESULT WINAPI d3d9_surface_UnlockRect(IDirect3DSurface9 *iface) - TRACE("iface %p.\n", iface); - - wined3d_mutex_lock(); -- hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); -+ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); - wined3d_mutex_unlock(); - - switch(hr) -diff --git a/dlls/d3d9/volume.c b/dlls/d3d9/volume.c -index 52502bf..a81b6c7 100644 ---- a/dlls/d3d9/volume.c -+++ b/dlls/d3d9/volume.c -@@ -148,7 +148,7 @@ static HRESULT WINAPI d3d9_volume_LockBox(IDirect3DVolume9 *iface, - iface, locked_box, box, flags); - - wined3d_mutex_lock(); -- hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, -+ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, - &map_desc, (const struct wined3d_box *)box, flags); - wined3d_mutex_unlock(); - -@@ -167,7 +167,7 @@ static HRESULT WINAPI d3d9_volume_UnlockBox(IDirect3DVolume9 *iface) - TRACE("iface %p.\n", iface); - - wined3d_mutex_lock(); -- hr = wined3d_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); -+ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); - wined3d_mutex_unlock(); - - return hr; -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index d466764..74be48d 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -295,7 +295,7 @@ void CDECL wined3d_resource_get_desc(const struct wined3d_resource *resource, st - desc->size = resource->size; - } - --HRESULT CDECL wined3d_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, -+HRESULT CDECL wined3d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) - { - TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %p, flags %#x.\n", -@@ -304,7 +304,7 @@ HRESULT CDECL wined3d_resource_map(struct wined3d_resource *resource, unsigned i - return resource->resource_ops->resource_sub_resource_map(resource, sub_resource_idx, map_desc, box, flags); - } - --HRESULT CDECL wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) -+HRESULT CDECL wined3d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) - { - TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx); - -diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec -index a7e625d..b6be230 100644 ---- a/dlls/wined3d/wined3d.spec -+++ b/dlls/wined3d/wined3d.spec -@@ -182,10 +182,10 @@ - @ cdecl wined3d_resource_get_desc(ptr ptr) - @ cdecl wined3d_resource_get_parent(ptr) - @ cdecl wined3d_resource_get_priority(ptr) --@ cdecl wined3d_resource_map(ptr long ptr ptr long) - @ cdecl wined3d_resource_set_parent(ptr ptr) - @ cdecl wined3d_resource_set_priority(ptr long) --@ cdecl wined3d_resource_unmap(ptr long) -+@ cdecl wined3d_resource_sub_resource_map(ptr long ptr ptr long) -+@ cdecl wined3d_resource_sub_resource_unmap(ptr long) - - @ cdecl wined3d_rendertarget_view_create(ptr ptr ptr ptr ptr) - @ cdecl wined3d_rendertarget_view_create_from_surface(ptr ptr ptr ptr) -diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h -index 2deb450..e25aa69 100644 ---- a/include/wine/wined3d.h -+++ b/include/wine/wined3d.h -@@ -2422,11 +2422,11 @@ void __cdecl wined3d_resource_get_desc(const struct wined3d_resource *resource, - struct wined3d_resource_desc *desc); - void * __cdecl wined3d_resource_get_parent(const struct wined3d_resource *resource); - DWORD __cdecl wined3d_resource_get_priority(const struct wined3d_resource *resource); --HRESULT __cdecl wined3d_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, -- struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); - void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent); - DWORD __cdecl wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority); --HRESULT __cdecl wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx); -+HRESULT __cdecl wined3d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, -+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); -+HRESULT __cdecl wined3d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx); - - HRESULT __cdecl wined3d_rendertarget_view_create(const struct wined3d_rendertarget_view_desc *desc, - struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Helper/definition wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Helper/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Helper/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Helper/definition 2016-02-08 20:07:32.000000000 +0000 @@ -1,3 +1,4 @@ Depends: wined3d-DXTn +Depends: wined3d-resource_map Depends: makedep-PARENTSPEC Depends: ntdll-DllRedirects diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0003-wined3d-Make-surface_load_location-return-nothing.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0003-wined3d-Make-surface_load_location-return-nothing.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0003-wined3d-Make-surface_load_location-return-nothing.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0003-wined3d-Make-surface_load_location-return-nothing.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 8ac3b701d1b19249fff35e7db8bc4e12212c0886 Mon Sep 17 00:00:00 2001 +From bc6576d6ab3915b43d6b70206138622ead42110e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sun, 17 Nov 2013 20:25:01 +0100 Subject: wined3d: Make surface_load_location return nothing. @@ -9,10 +9,10 @@ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 0f16f79..6490235 100644 +index 4e593e4..8b8ac0d 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c -@@ -4239,7 +4239,7 @@ static void surface_load_renderbuffer(struct wined3d_surface *surface, struct wi +@@ -4118,7 +4118,7 @@ static void surface_load_renderbuffer(struct wined3d_surface *surface, struct wi } /* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */ @@ -21,7 +21,7 @@ { HRESULT hr; -@@ -4251,26 +4251,26 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co +@@ -4130,26 +4130,26 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co && surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_DISCARDED)) { surface_load_ds_location(surface, context, location); @@ -52,7 +52,7 @@ } if (WARN_ON(d3d_surface)) -@@ -4284,7 +4284,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co +@@ -4163,7 +4163,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co if (!surface->locations) { ERR("Surface %p does not have any up to date location.\n", surface); @@ -61,7 +61,7 @@ } switch (location) -@@ -4298,7 +4298,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co +@@ -4177,7 +4177,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co case WINED3D_LOCATION_DRAWABLE: if (FAILED(hr = surface_load_drawable(surface, context))) @@ -70,7 +70,7 @@ break; case WINED3D_LOCATION_RB_RESOLVED: -@@ -4310,7 +4310,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co +@@ -4189,7 +4189,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co case WINED3D_LOCATION_TEXTURE_SRGB: if (FAILED(hr = surface_load_texture(surface, context, location == WINED3D_LOCATION_TEXTURE_SRGB))) @@ -79,7 +79,7 @@ break; default: -@@ -4323,7 +4323,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co +@@ -4202,7 +4202,7 @@ HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_co if (location != WINED3D_LOCATION_SYSMEM && (surface->locations & WINED3D_LOCATION_SYSMEM)) surface_evict_sysmem(surface); @@ -89,18 +89,18 @@ static HRESULT ffp_blit_alloc(struct wined3d_device *device) { return WINED3D_OK; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 593456e..c120937 100644 +index 02c09af..1c0c689 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2463,7 +2463,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, +@@ -2549,7 +2549,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct wined3d_context *context) DECLSPEC_HIDDEN; -HRESULT surface_load_location(struct wined3d_surface *surface, +void surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; - void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; - void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_context *context, + HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, + const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0004-wined3d-Store-volume-locations-in-the-resource.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0004-wined3d-Store-volume-locations-in-the-resource.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0004-wined3d-Store-volume-locations-in-the-resource.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0004-wined3d-Store-volume-locations-in-the-resource.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,15 +1,15 @@ -From 81726de3e2c63759ff771038ec1a829758314bc7 Mon Sep 17 00:00:00 2001 +From d9832814763ffc0c5b9f43223507f049a60859f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Thu, 3 Oct 2013 12:31:24 +0200 Subject: wined3d: Store volume locations in the resource. --- dlls/wined3d/volume.c | 46 +++++++++++++++++++++--------------------- - dlls/wined3d/wined3d_private.h | 5 +++-- - 2 files changed, 26 insertions(+), 25 deletions(-) + dlls/wined3d/wined3d_private.h | 4 ++-- + 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index 1a5e629..5f5fe8b 100644 +index c4bd3e7..d9405b9 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -102,15 +102,15 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine @@ -32,7 +32,7 @@ } /* Context activation is done by the caller. */ -@@ -218,9 +218,9 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, +@@ -216,9 +216,9 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, DWORD required_access = volume_access_from_location(location); TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location), @@ -44,7 +44,7 @@ { TRACE("Location(s) already up to date.\n"); return; -@@ -243,36 +243,36 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, +@@ -241,36 +241,36 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, && !(volume->container->flags & WINED3D_TEXTURE_SRGB_ALLOCATED))) ERR("Trying to load (s)RGB texture without prior allocation.\n"); @@ -87,7 +87,7 @@ return; } wined3d_volume_validate_location(volume, location); -@@ -286,16 +286,16 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, +@@ -284,16 +284,16 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, if (!volume->resource.heap_memory) ERR("Trying to load WINED3D_LOCATION_SYSMEM without setting it up first.\n"); @@ -107,7 +107,7 @@ wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); else wined3d_texture_bind_and_dirtify(volume->container, context, TRUE); -@@ -306,7 +306,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, +@@ -304,7 +304,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, else { FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", @@ -116,7 +116,7 @@ return; } wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM); -@@ -316,16 +316,16 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, +@@ -314,16 +314,16 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, if (!volume->pbo) ERR("Trying to load WINED3D_LOCATION_BUFFER without setting it up first.\n"); @@ -136,7 +136,7 @@ wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); else wined3d_texture_bind_and_dirtify(volume->container, context, TRUE); -@@ -335,7 +335,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, +@@ -333,7 +333,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, else { FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", @@ -145,7 +145,7 @@ return; } wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER); -@@ -343,7 +343,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, +@@ -341,7 +341,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, default: FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), @@ -154,7 +154,7 @@ } } -@@ -600,7 +600,7 @@ HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume, +@@ -565,7 +565,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, { wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM); } @@ -163,7 +163,7 @@ { context = context_acquire(device, NULL); wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM); -@@ -748,7 +748,7 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture +@@ -724,7 +724,7 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture } volume->texture_level = level; @@ -173,7 +173,7 @@ if (desc->pool == WINED3D_POOL_DEFAULT && desc->usage & WINED3DUSAGE_DYNAMIC && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 254dfd7..f2d3943 100644 +index f4b06a4..b25ce65 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -5,7 +5,7 @@ @@ -185,7 +185,7 @@ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public -@@ -2123,6 +2123,7 @@ struct wined3d_resource +@@ -2197,6 +2197,7 @@ struct wined3d_resource void *heap_memory; UINT custom_row_pitch, custom_slice_pitch; struct list resource_list_entry; @@ -193,15 +193,14 @@ void *parent; const struct wined3d_parent_ops *parent_ops; -@@ -2271,7 +2272,7 @@ struct wined3d_volume +@@ -2345,7 +2346,6 @@ struct wined3d_volume struct wined3d_resource resource; struct wined3d_texture *container; -- DWORD flags, locations; -+ DWORD flags; +- DWORD locations; GLint texture_level; DWORD download_count; GLuint pbo; -- -2.3.5 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0006-wined3d-Move-surface-locations-into-the-resource.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0006-wined3d-Move-surface-locations-into-the-resource.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0006-wined3d-Move-surface-locations-into-the-resource.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0006-wined3d-Move-surface-locations-into-the-resource.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 5fd25633a2e78ad336af898e466f4afc2e2ab1a0 Mon Sep 17 00:00:00 2001 +From 5cdc790a6ec9c5995f42586d85d3e95e74877c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 21 Jan 2014 12:22:30 +0100 Subject: wined3d: Move surface locations into the resource. @@ -12,10 +12,10 @@ 5 files changed, 53 insertions(+), 53 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c -index 6851620..28939c0 100644 +index 84b85c4..b97ff12 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c -@@ -7844,7 +7844,7 @@ static void arbfp_blit_surface(struct wined3d_device *device, enum wined3d_blit_ +@@ -7855,7 +7855,7 @@ static void arbfp_blit_surface(struct wined3d_device *device, enum wined3d_blit_ /* Now load the surface */ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO @@ -25,7 +25,7 @@ && !wined3d_resource_is_offscreen(&src_surface->container->resource)) { diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 057ae18..2312267 100644 +index 7c5a4c2..b9b39859 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -236,7 +236,7 @@ static void prepare_ds_clear(struct wined3d_surface *ds, struct wined3d_context @@ -47,7 +47,7 @@ ds->ds_current_size.cx, ds->ds_current_size.cy); diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c -index 3761830..943a829 100644 +index ff62850..75489db 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -655,7 +655,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co @@ -60,7 +60,7 @@ else SetRectEmpty(¤t_rect); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 94934a5..c971031 100644 +index ac74457..a04cc1b 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -556,7 +556,7 @@ static void surface_prepare_system_memory(struct wined3d_surface *surface) @@ -72,7 +72,7 @@ ERR("Surface without system memory has WINED3D_LOCATION_SYSMEM set.\n"); } -@@ -706,7 +706,7 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface) +@@ -682,7 +682,7 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface) } if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) @@ -81,7 +81,7 @@ if (surface_use_pbo(surface)) surface->resource.map_binding = WINED3D_LOCATION_BUFFER; -@@ -746,7 +746,7 @@ static void surface_unmap(struct wined3d_surface *surface) +@@ -722,7 +722,7 @@ static void surface_unmap(struct wined3d_surface *surface) ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); } @@ -90,7 +90,7 @@ { TRACE("Not dirtified, nothing to do.\n"); return; -@@ -1687,7 +1687,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P +@@ -1669,7 +1669,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P surface_load_location(dst_surface, context, WINED3D_LOCATION_TEXTURE_RGB); wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE); @@ -99,7 +99,7 @@ wined3d_resource_get_pitch(&src_surface->resource, &src_row_pitch, &src_slice_pitch); wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect, -@@ -1810,7 +1810,7 @@ void surface_load(struct wined3d_surface *surface, struct wined3d_context *conte +@@ -1792,7 +1792,7 @@ void surface_load(struct wined3d_surface *surface, struct wined3d_context *conte if (surface->resource.pool == WINED3D_POOL_SCRATCH) ERR("Not supported on scratch surfaces.\n"); @@ -108,7 +108,7 @@ { TRACE("surface is already in texture\n"); return; -@@ -2060,7 +2060,7 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, +@@ -2042,7 +2042,7 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, create_dib = TRUE; } @@ -117,7 +117,7 @@ wined3d_resource_free_sysmem(&surface->resource); width = texture_resource->width; -@@ -3236,7 +3236,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st +@@ -3212,7 +3212,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st checkGLcall("glEnable(texture_target)"); /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */ @@ -126,7 +126,7 @@ } /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag -@@ -3763,13 +3763,14 @@ void surface_modify_ds_location(struct wined3d_surface *surface, +@@ -3739,13 +3739,14 @@ void surface_modify_ds_location(struct wined3d_surface *surface, { TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h); @@ -144,7 +144,7 @@ } /* Context activation is done by the caller. */ -@@ -3784,7 +3785,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co +@@ -3760,7 +3761,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co /* TODO: Make this work for modes other than FBO */ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return; @@ -153,15 +153,14 @@ { w = surface->ds_current_size.cx; h = surface->ds_current_size.cy; -@@ -3810,21 +3811,21 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co - return; +@@ -3787,20 +3788,20 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co } + wined3d_surface_prepare(surface, context, location); - if (surface->locations & WINED3D_LOCATION_DISCARDED) + if (surface->resource.locations & WINED3D_LOCATION_DISCARDED) { TRACE("Surface was discarded, no need copy data.\n"); - wined3d_surface_prepare(surface, context, location); - surface->locations &= ~WINED3D_LOCATION_DISCARDED; - surface->locations |= location; + surface->resource.locations &= ~WINED3D_LOCATION_DISCARDED; @@ -180,7 +179,7 @@ surface->ds_current_size.cx = surface->resource.width; surface->ds_current_size.cy = surface->resource.height; return; -@@ -3912,7 +3913,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co +@@ -3888,7 +3889,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co ERR("Invalid location (%#x) specified.\n", location); } @@ -189,7 +188,7 @@ surface->ds_current_size.cx = surface->resource.width; surface->ds_current_size.cy = surface->resource.height; } -@@ -3921,7 +3922,7 @@ void surface_validate_location(struct wined3d_surface *surface, DWORD location) +@@ -3897,7 +3898,7 @@ void surface_validate_location(struct wined3d_surface *surface, DWORD location) { TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); @@ -198,7 +197,7 @@ } void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) -@@ -3930,9 +3931,9 @@ void surface_invalidate_location(struct wined3d_surface *surface, DWORD location +@@ -3906,9 +3907,9 @@ void surface_invalidate_location(struct wined3d_surface *surface, DWORD location if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) wined3d_texture_set_dirty(surface->container); @@ -210,7 +209,7 @@ ERR("Surface %p does not have any up to date location.\n", surface); } -@@ -3968,7 +3969,7 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD +@@ -3944,7 +3945,7 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD UINT size = surface->resource.size; surface_get_memory(surface, &dst, location); @@ -219,7 +218,7 @@ if (dst.buffer_object) { -@@ -4001,33 +4002,33 @@ static void surface_load_sysmem(struct wined3d_surface *surface, +@@ -3977,33 +3978,33 @@ static void surface_load_sysmem(struct wined3d_surface *surface, { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -259,7 +258,7 @@ } /* Context activation is done by the caller. */ -@@ -4067,14 +4068,14 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, +@@ -4043,14 +4044,14 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, if (wined3d_settings.offscreen_rendering_mode != ORM_FBO && wined3d_resource_is_offscreen(&texture->resource) @@ -276,7 +275,7 @@ && (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB) && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, NULL, surface->resource.usage, surface->resource.pool, surface->resource.format, -@@ -4090,13 +4091,13 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, +@@ -4066,13 +4067,13 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, return WINED3D_OK; } @@ -292,7 +291,7 @@ WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE; DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; RECT rect = {0, 0, surface->resource.width, surface->resource.height}; -@@ -4111,7 +4112,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, +@@ -4087,7 +4088,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, if (srgb) { @@ -301,7 +300,7 @@ == WINED3D_LOCATION_TEXTURE_RGB) { /* Performance warning... */ -@@ -4122,7 +4123,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, +@@ -4098,7 +4099,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, } else { @@ -310,7 +309,7 @@ == WINED3D_LOCATION_TEXTURE_SRGB) { /* Performance warning... */ -@@ -4132,7 +4133,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, +@@ -4108,7 +4109,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, } } @@ -319,7 +318,7 @@ { WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); /* Lets hope we get it from somewhere... */ -@@ -4167,7 +4168,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, +@@ -4143,7 +4144,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, surface_remove_pbo(surface, gl_info); } @@ -328,7 +327,7 @@ if (format.convert) { /* This code is entered for texture formats which need a fixup. */ -@@ -4225,11 +4226,11 @@ static void surface_load_renderbuffer(struct wined3d_surface *surface, struct wi +@@ -4201,11 +4202,11 @@ static void surface_load_renderbuffer(struct wined3d_surface *surface, struct wi const RECT rect = {0, 0, surface->resource.width, surface->resource.height}; DWORD src_location; @@ -343,7 +342,7 @@ src_location = WINED3D_LOCATION_TEXTURE_SRGB; else /* surface_blt_fbo will load the source location if necessary. */ src_location = WINED3D_LOCATION_TEXTURE_RGB; -@@ -4248,12 +4249,12 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte +@@ -4224,12 +4225,12 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) { if (location == WINED3D_LOCATION_TEXTURE_RGB @@ -358,7 +357,7 @@ && surface->container->resource.draw_binding != WINED3D_LOCATION_DRAWABLE) { /* Already up to date, nothing to do. */ -@@ -4262,12 +4263,12 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte +@@ -4238,12 +4239,12 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte else { FIXME("Unimplemented copy from %s to %s for depth/stencil buffers.\n", @@ -373,7 +372,7 @@ { TRACE("Location already up to date.\n"); return; -@@ -4281,7 +4282,7 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte +@@ -4257,7 +4258,7 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte required_access, surface->resource.access_flags); } @@ -382,7 +381,7 @@ { ERR("Surface %p does not have any up to date location.\n", surface); return; -@@ -4320,7 +4321,7 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte +@@ -4296,7 +4297,7 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte surface_validate_location(surface, location); @@ -391,7 +390,7 @@ surface_evict_sysmem(surface); return; -@@ -5382,8 +5383,8 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC +@@ -5358,8 +5359,8 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC /* In principle this would apply to depth blits as well, but we don't * implement those in the CPU blitter at the moment. */ @@ -402,7 +401,7 @@ { if (scale) TRACE("Not doing sysmem blit because of scaling.\n"); -@@ -5427,8 +5428,8 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC +@@ -5403,8 +5404,8 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC { blit_op = WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST; } @@ -414,10 +413,10 @@ /* Upload */ if (scale) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 93ede78..91a5495 100644 +index b759426..1a39f97 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2409,7 +2409,6 @@ struct wined3d_surface +@@ -2422,7 +2422,6 @@ struct wined3d_surface const struct wined3d_surface_ops *surface_ops; struct wined3d_texture *container; void *user_memory; @@ -426,5 +425,5 @@ DWORD flags; -- -2.6.2 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0007-wined3d-Remove-surface_validate_location.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0007-wined3d-Remove-surface_validate_location.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0007-wined3d-Remove-surface_validate_location.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0007-wined3d-Remove-surface_validate_location.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 803e39eb0ca711ad7a2867bdac796cc4360c4c27 Mon Sep 17 00:00:00 2001 +From 4aad31fd3b9d3949b86cc73e4b4b5f98cce42ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sat, 4 Jan 2014 00:53:47 +0100 Subject: wined3d: Remove surface_validate_location. @@ -13,10 +13,10 @@ 6 files changed, 18 insertions(+), 28 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c -index e8526d8..a87b09b 100644 +index 7731230..78f24cd 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c -@@ -7888,7 +7888,7 @@ static void arbfp_blit_surface(struct wined3d_device *device, DWORD filter, +@@ -7902,7 +7902,7 @@ static void arbfp_blit_surface(struct wined3d_device *device, enum wined3d_blit_ context_release(context); @@ -26,7 +26,7 @@ } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 2312267..c10c1fc 100644 +index 7c9e96d..613235d 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -398,7 +398,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c @@ -38,7 +38,7 @@ surface_invalidate_location(rt, ~rt->container->resource.draw_binding); } } -@@ -4047,7 +4047,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str +@@ -4124,7 +4124,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str context_release(context); @@ -48,10 +48,10 @@ } diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 50282c0..4fb2578 100644 +index ea601ff..516b50f1 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c -@@ -1158,14 +1158,14 @@ static void surface_unload(struct wined3d_resource *resource) +@@ -1134,14 +1134,14 @@ static void surface_unload(struct wined3d_resource *resource) * and all flags get lost */ if (resource->usage & WINED3DUSAGE_DEPTHSTENCIL) { @@ -68,7 +68,7 @@ surface_invalidate_location(surface, ~WINED3D_LOCATION_SYSMEM); } } -@@ -1695,7 +1695,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P +@@ -1677,7 +1677,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P context_release(context); @@ -77,7 +77,7 @@ surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); return WINED3D_OK; -@@ -2133,7 +2133,7 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, +@@ -2115,7 +2115,7 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, valid_location = WINED3D_LOCATION_SYSMEM; } @@ -86,7 +86,7 @@ return WINED3D_OK; } -@@ -2679,7 +2679,7 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, +@@ -2662,7 +2662,7 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, { TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", wined3d_debug_location(surface->resource.map_binding)); @@ -95,7 +95,7 @@ } else { -@@ -3167,7 +3167,7 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc +@@ -3144,7 +3144,7 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc /* The texture is now most up to date - If the surface is a render target * and has a drawable, this path is never entered. */ @@ -104,7 +104,7 @@ surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); } -@@ -3440,7 +3440,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st +@@ -3417,7 +3417,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st /* The texture is now most up to date - If the surface is a render target * and has a drawable, this path is never entered. */ @@ -113,7 +113,7 @@ surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); } -@@ -3918,13 +3918,6 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co +@@ -3895,13 +3895,6 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co surface->ds_current_size.cy = surface->resource.height; } @@ -127,7 +127,7 @@ void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) { TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); -@@ -4319,7 +4312,7 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte +@@ -4296,7 +4289,7 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte break; } @@ -136,7 +136,7 @@ if (location != WINED3D_LOCATION_SYSMEM && (surface->resource.locations & WINED3D_LOCATION_SYSMEM)) surface_evict_sysmem(surface); -@@ -4493,7 +4486,7 @@ static void ffp_blit_blit_surface(struct wined3d_device *device, DWORD filter, +@@ -4479,7 +4472,7 @@ static void ffp_blit_blit_surface(struct wined3d_device *device, enum wined3d_bl wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL); @@ -145,8 +145,8 @@ surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); } -@@ -5474,7 +5467,7 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC - dst_surface, dst_surface->container->resource.draw_binding, &dst_rect); +@@ -5456,7 +5449,7 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC + dst_surface, dst_surface->container->resource.draw_binding, dst_rect); context_release(context); - surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); @@ -154,7 +154,7 @@ surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); return WINED3D_OK; -@@ -5564,7 +5557,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text +@@ -5543,7 +5536,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text } surface->container = container; @@ -163,7 +163,7 @@ list_init(&surface->renderbuffers); list_init(&surface->overlays); -@@ -5596,7 +5589,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text +@@ -5575,7 +5568,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text if (surface->resource.map_binding == WINED3D_LOCATION_DIB) { wined3d_resource_free_sysmem(&surface->resource); @@ -173,10 +173,10 @@ } diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c -index e45fe17..9758be4 100644 +index 7728cdc..a97d1f7 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c -@@ -562,7 +562,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT +@@ -570,7 +570,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT front = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); @@ -185,7 +185,7 @@ surface_invalidate_location(front, ~WINED3D_LOCATION_DRAWABLE); /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM * and INTEXTURE copies can keep their old content if they have any defined content. -@@ -835,7 +835,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 +@@ -843,7 +843,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 front_buffer = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); if (!(device->wined3d->flags & WINED3D_NO3D)) { @@ -195,7 +195,7 @@ } diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 0f40a3c..6b41db8 100644 +index 093cc56..40b668c 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -795,9 +795,7 @@ static void texture2d_sub_resource_invalidate_location(struct wined3d_resource * @@ -210,10 +210,10 @@ static void texture2d_sub_resource_upload_data(struct wined3d_resource *sub_resource, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 87cd0d0..3848e76 100644 +index f03e8a1..d912668 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2477,7 +2477,6 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, +@@ -2505,7 +2505,6 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, void *mem, unsigned int pitch) DECLSPEC_HIDDEN; HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN; @@ -222,5 +222,5 @@ GLenum target, unsigned int level, unsigned int layer, DWORD flags, struct wined3d_surface **surface) DECLSPEC_HIDDEN; -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0009-wined3d-Invalidate-containers-via-callback.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0009-wined3d-Invalidate-containers-via-callback.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0009-wined3d-Invalidate-containers-via-callback.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0009-wined3d-Invalidate-containers-via-callback.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From bc240cf9d9401914b2685b66f21af86aca21bccb Mon Sep 17 00:00:00 2001 +From 790f8208a4873a5d172d7c11a36477e9a6b8e7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sun, 17 Nov 2013 18:44:48 +0100 Subject: wined3d: Invalidate containers via callback. @@ -13,10 +13,10 @@ 6 files changed, 30 insertions(+), 3 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index ba4ed5d..638c9b9 100644 +index 1e66cae..8aac5cb 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c -@@ -1161,6 +1161,11 @@ static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resou +@@ -1188,6 +1188,11 @@ static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resou return WINED3D_OK; } @@ -28,7 +28,7 @@ static const struct wined3d_resource_ops buffer_resource_ops = { buffer_resource_incref, -@@ -1168,6 +1173,7 @@ static const struct wined3d_resource_ops buffer_resource_ops = +@@ -1195,6 +1200,7 @@ static const struct wined3d_resource_ops buffer_resource_ops = buffer_unload, buffer_resource_sub_resource_map, buffer_resource_sub_resource_unmap, @@ -37,10 +37,10 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device *device, diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 2a42535..c259eba 100644 +index c4a3a7b..39346b5 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c -@@ -474,4 +474,6 @@ void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWO +@@ -484,4 +484,6 @@ void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWO TRACE("Resource %p, setting %s.\n", resource, wined3d_debug_location(location)); resource->locations &= ~location; TRACE("new location flags are %s.\n", wined3d_debug_location(resource->locations)); @@ -48,10 +48,10 @@ + resource->resource_ops->resource_location_invalidated(resource, location); } diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 0d95db3..f5bc72c 100644 +index e286384..c4b9cac 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c -@@ -1220,6 +1220,11 @@ static HRESULT surface_resource_sub_resource_unmap(struct wined3d_resource *reso +@@ -1222,6 +1222,11 @@ static HRESULT surface_resource_sub_resource_unmap(struct wined3d_resource *reso return WINED3DERR_INVALIDCALL; } @@ -63,7 +63,7 @@ static const struct wined3d_resource_ops surface_resource_ops = { surface_resource_incref, -@@ -1227,6 +1232,7 @@ static const struct wined3d_resource_ops surface_resource_ops = +@@ -1229,6 +1234,7 @@ static const struct wined3d_resource_ops surface_resource_ops = surface_unload, surface_resource_sub_resource_map, surface_resource_sub_resource_unmap, @@ -72,10 +72,10 @@ static const struct wined3d_surface_ops surface_ops = diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 2e5276a..520647d 100644 +index 72f00fd..82ddeeb 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c -@@ -978,6 +978,11 @@ static HRESULT texture2d_resource_sub_resource_unmap(struct wined3d_resource *re +@@ -938,6 +938,11 @@ static HRESULT texture2d_resource_sub_resource_unmap(struct wined3d_resource *re return wined3d_surface_unmap(surface_from_resource(sub_resource)); } @@ -87,19 +87,19 @@ static const struct wined3d_resource_ops texture2d_resource_ops = { texture_resource_incref, -@@ -985,6 +990,7 @@ static const struct wined3d_resource_ops texture2d_resource_ops = +@@ -945,6 +950,7 @@ static const struct wined3d_resource_ops texture2d_resource_ops = wined3d_texture_unload, texture2d_resource_sub_resource_map, texture2d_resource_sub_resource_unmap, + wined3d_texture_load_location_invalidated, }; - static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, + static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index eefdb06..f150795 100644 +index b3b2fe2..00b9814 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c -@@ -604,10 +604,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, +@@ -601,10 +601,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, } if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) @@ -110,7 +110,7 @@ volume->resource.map_count++; -@@ -675,6 +672,14 @@ static HRESULT volume_resource_sub_resource_unmap(struct wined3d_resource *resou +@@ -672,6 +669,14 @@ static HRESULT volume_resource_sub_resource_unmap(struct wined3d_resource *resou return WINED3DERR_INVALIDCALL; } @@ -125,7 +125,7 @@ static const struct wined3d_resource_ops volume_resource_ops = { volume_resource_incref, -@@ -682,6 +687,7 @@ static const struct wined3d_resource_ops volume_resource_ops = +@@ -679,6 +684,7 @@ static const struct wined3d_resource_ops volume_resource_ops = volume_unload, volume_resource_sub_resource_map, volume_resource_sub_resource_unmap, @@ -134,10 +134,10 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture *container, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 429a093..53e9fe9 100644 +index a282b95..dc24c36 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2159,6 +2159,7 @@ struct wined3d_resource_ops +@@ -2250,6 +2250,7 @@ struct wined3d_resource_ops HRESULT (*resource_sub_resource_map)(struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); HRESULT (*resource_sub_resource_unmap)(struct wined3d_resource *resource, unsigned int sub_resource_idx); @@ -146,5 +146,5 @@ struct wined3d_resource -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0010-wined3d-Remove-surface_invalidate_location.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0010-wined3d-Remove-surface_invalidate_location.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0010-wined3d-Remove-surface_invalidate_location.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0010-wined3d-Remove-surface_invalidate_location.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From c1235a5f6ed86eefc1b797df0836a1b61d6fceb7 Mon Sep 17 00:00:00 2001 +From 03998dcf5391b8b5da7b8cecbfe2ac6b82c77502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sat, 4 Jan 2014 01:02:15 +0100 Subject: wined3d: Remove surface_invalidate_location. @@ -8,17 +8,17 @@ dlls/wined3d/context.c | 2 +- dlls/wined3d/device.c | 4 ++-- dlls/wined3d/drawprim.c | 2 +- - dlls/wined3d/surface.c | 47 ++++++++++++++++----------------------- - dlls/wined3d/swapchain.c | 6 ++--- - dlls/wined3d/texture.c | 6 ++--- + dlls/wined3d/surface.c | 43 ++++++++++++++++----------------------- + dlls/wined3d/swapchain.c | 6 +++--- + dlls/wined3d/texture.c | 10 ++++----- dlls/wined3d/wined3d_private.h | 1 - 8 files changed, 29 insertions(+), 41 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c -index a87b09b..4df6e2f 100644 +index 60d2560..eb09795 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c -@@ -7889,7 +7889,7 @@ static void arbfp_blit_surface(struct wined3d_device *device, DWORD filter, +@@ -7919,7 +7919,7 @@ static void arbfp_blit_surface(struct wined3d_device *device, enum wined3d_blit_ context_release(context); wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); @@ -26,12 +26,12 @@ + wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding); } - static HRESULT arbfp_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface, + static HRESULT arbfp_blit_color_fill(struct wined3d_device *device, struct wined3d_rendertarget_view *view, diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c -index 1e357e7..230946d 100644 +index 490c20f..9408cd9 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c -@@ -3311,7 +3311,7 @@ static void context_setup_target(struct wined3d_context *context, struct wined3d +@@ -3322,7 +3322,7 @@ static void context_setup_target(struct wined3d_context *context, struct wined3d if (texture->texture_srgb.name) wined3d_texture_load(texture, context, TRUE); wined3d_texture_load(texture, context, FALSE); @@ -41,7 +41,7 @@ } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 58edac3..143cf9c 100644 +index 3cfff6e..1f061fd 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -399,7 +399,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c @@ -53,7 +53,7 @@ } } -@@ -4048,7 +4048,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str +@@ -4140,7 +4140,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str context_release(context); wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_TEXTURE_RGB); @@ -63,7 +63,7 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device, diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c -index 943a829..95245a9 100644 +index 75489db..9ba6ef7 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -628,7 +628,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co @@ -76,10 +76,10 @@ else { diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index ad43381..7c0594f 100644 +index c4b9cac..b292adc 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c -@@ -599,7 +599,7 @@ static void surface_evict_sysmem(struct wined3d_surface *surface) +@@ -597,7 +597,7 @@ static void surface_evict_sysmem(struct wined3d_surface *surface) return; wined3d_resource_free_sysmem(&surface->resource); @@ -87,8 +87,8 @@ + wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); } - static void surface_release_client_storage(struct wined3d_surface *surface) -@@ -1119,7 +1119,7 @@ static void surface_remove_pbo(struct wined3d_surface *surface, const struct win + static BOOL surface_use_pbo(const struct wined3d_surface *surface) +@@ -1111,7 +1111,7 @@ static void surface_remove_pbo(struct wined3d_surface *surface, const struct win checkGLcall("glDeleteBuffers(1, &surface->pbo)"); surface->pbo = 0; @@ -134,7 +134,7 @@ } static const struct wined3d_resource_ops surface_resource_ops = -@@ -1702,7 +1705,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P +@@ -1708,7 +1711,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P context_release(context); wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); @@ -143,7 +143,7 @@ return WINED3D_OK; } -@@ -2702,7 +2705,7 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, +@@ -2677,7 +2680,7 @@ HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_ } if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) @@ -152,25 +152,7 @@ switch (surface->resource.map_binding) { -@@ -2818,7 +2821,7 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) - } - - surface_load_location(surface, context, WINED3D_LOCATION_DIB); -- surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB); -+ wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_DIB); - - if (context) - context_release(context); -@@ -2867,7 +2870,7 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) - context = context_acquire(device, NULL); - - surface_load_location(surface, context, surface->resource.map_binding); -- surface_invalidate_location(surface, WINED3D_LOCATION_DIB); -+ wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_DIB); - if (context) - context_release(context); - } -@@ -3174,7 +3177,7 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc +@@ -3069,7 +3072,7 @@ static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struc /* The texture is now most up to date - If the surface is a render target * and has a drawable, this path is never entered. */ wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); @@ -179,7 +161,7 @@ } /* Uses the hardware to stretch and flip the image */ -@@ -3242,7 +3245,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st +@@ -3137,7 +3140,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st checkGLcall("glEnable(texture_target)"); /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */ @@ -188,7 +170,7 @@ } /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag -@@ -3447,7 +3450,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st +@@ -3342,7 +3345,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st /* The texture is now most up to date - If the surface is a render target * and has a drawable, this path is never entered. */ wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); @@ -197,7 +179,7 @@ } /* Front buffer coordinates are always full screen coordinates, but our GL -@@ -3924,18 +3927,6 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co +@@ -3836,18 +3839,6 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co surface->ds_current_size.cy = surface->resource.height; } @@ -216,7 +198,7 @@ static DWORD resource_access_from_location(DWORD location) { switch (location) -@@ -4493,7 +4484,7 @@ static void ffp_blit_blit_surface(struct wined3d_device *device, DWORD filter, +@@ -4395,7 +4386,7 @@ static void ffp_blit_blit_surface(struct wined3d_device *device, enum wined3d_bl (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL); wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); @@ -225,7 +207,7 @@ } const struct blit_shader ffp_blit = { -@@ -5474,7 +5465,7 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC +@@ -5373,7 +5364,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst context_release(context); wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); @@ -234,7 +216,7 @@ return WINED3D_OK; } -@@ -5596,7 +5587,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text +@@ -5492,7 +5483,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text { wined3d_resource_free_sysmem(&surface->resource); wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_DIB); @@ -244,10 +226,10 @@ return hr; diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c -index 9758be4..4e50ef9 100644 +index a97d1f7..a054c05 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c -@@ -518,7 +518,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT +@@ -526,7 +526,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT if (!swapchain->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO) { surface_load_location(back_buffer, context, WINED3D_LOCATION_TEXTURE_RGB); @@ -256,7 +238,7 @@ swapchain->render_to_fbo = TRUE; swapchain_update_draw_bindings(swapchain); } -@@ -563,7 +563,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT +@@ -571,7 +571,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT front = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); wined3d_resource_validate_location(&front->resource, WINED3D_LOCATION_DRAWABLE); @@ -265,7 +247,7 @@ /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM * and INTEXTURE copies can keep their old content if they have any defined content. * If the swapeffect is COPY, the content remains the same. -@@ -836,7 +836,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 +@@ -844,7 +844,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 if (!(device->wined3d->flags & WINED3D_NO3D)) { wined3d_resource_validate_location(&front_buffer->resource, WINED3D_LOCATION_DRAWABLE); @@ -275,7 +257,7 @@ /* MSDN says we're only allowed a single fullscreen swapchain per device, diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 7e31832..be378fc 100644 +index 535159a..da1bbbb 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -776,7 +776,7 @@ static void texture2d_sub_resource_add_dirty_region(struct wined3d_resource *sub @@ -298,11 +280,29 @@ } static void texture2d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) +@@ -1560,7 +1558,7 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i + } + + surface_load_location(surface, context, WINED3D_LOCATION_DIB); +- surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB); ++ wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_DIB); + + if (context) + context_release(context); +@@ -1623,7 +1621,7 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign + context = context_acquire(device, NULL); + + surface_load_location(surface, context, surface->resource.map_binding); +- surface_invalidate_location(surface, WINED3D_LOCATION_DIB); ++ wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_DIB); + if (context) + context_release(context); + } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index ed013a9..54f95e3 100644 +index dc24c36..428eadd 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2458,7 +2458,6 @@ HRESULT surface_color_fill(struct wined3d_surface *s, +@@ -2544,7 +2544,6 @@ HRESULT surface_create_dib_section(struct wined3d_surface *surface) DECLSPEC_HID GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) DECLSPEC_HIDDEN; void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context, unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN; @@ -311,5 +311,5 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0012-wined3d-Move-load_location-into-the-resource.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0012-wined3d-Move-load_location-into-the-resource.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0012-wined3d-Move-load_location-into-the-resource.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0012-wined3d-Move-load_location-into-the-resource.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From baafba4da7e88b445e043b45fd1b852c7e0a1f61 Mon Sep 17 00:00:00 2001 +From 9508926776cb6d94f7d184fae9642a379f4ee7ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Thu, 3 Oct 2013 12:47:01 +0200 Subject: wined3d: Move load_location into the resource. @@ -16,10 +16,10 @@ 6 files changed, 91 insertions(+), 36 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 638c9b9..e1bd034 100644 +index 8aac5cb..4e91176 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c -@@ -1166,6 +1166,13 @@ static void wined3d_buffer_location_invalidated(struct wined3d_resource *resourc +@@ -1193,6 +1193,13 @@ static void wined3d_buffer_location_invalidated(struct wined3d_resource *resourc ERR("Not yet implemented.\n"); } @@ -33,7 +33,7 @@ static const struct wined3d_resource_ops buffer_resource_ops = { buffer_resource_incref, -@@ -1174,6 +1181,7 @@ static const struct wined3d_resource_ops buffer_resource_ops = +@@ -1201,6 +1208,7 @@ static const struct wined3d_resource_ops buffer_resource_ops = buffer_resource_sub_resource_map, buffer_resource_sub_resource_unmap, wined3d_buffer_location_invalidated, @@ -42,10 +42,10 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device *device, diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index c259eba..bff4997 100644 +index 39346b5..d1f9fd9 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c -@@ -477,3 +477,53 @@ void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWO +@@ -487,3 +487,53 @@ void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWO resource->resource_ops->resource_location_invalidated(resource, location); } @@ -100,10 +100,10 @@ + resource->resource_ops->resource_load_location(resource, context, location); +} diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 34f589b..fed3aaf 100644 +index 146d647..791f351 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c -@@ -1228,6 +1228,13 @@ static void wined3d_surface_location_invalidated(struct wined3d_resource *resour +@@ -1230,6 +1230,13 @@ static void wined3d_surface_location_invalidated(struct wined3d_resource *resour wined3d_texture_set_dirty(surface->container); } @@ -117,7 +117,7 @@ static const struct wined3d_resource_ops surface_resource_ops = { surface_resource_incref, -@@ -1236,6 +1243,7 @@ static const struct wined3d_resource_ops surface_resource_ops = +@@ -1238,6 +1245,7 @@ static const struct wined3d_resource_ops surface_resource_ops = surface_resource_sub_resource_map, surface_resource_sub_resource_unmap, wined3d_surface_location_invalidated, @@ -125,7 +125,7 @@ }; static const struct wined3d_surface_ops surface_ops = -@@ -3941,7 +3949,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co +@@ -3839,7 +3847,7 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co surface->ds_current_size.cy = surface->resource.height; } @@ -134,7 +134,7 @@ { switch (location) { -@@ -4273,7 +4281,7 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte +@@ -4178,7 +4186,7 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte if (WARN_ON(d3d_surface)) { @@ -144,10 +144,10 @@ WARN("Operation requires %#x access, but surface only has %#x.\n", required_access, surface->resource.access_flags); diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index e2df18d..7650f36 100644 +index 377d1bc..bcdf96f 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c -@@ -981,6 +981,13 @@ static void wined3d_texture_load_location_invalidated(struct wined3d_resource *r +@@ -941,6 +941,13 @@ static void wined3d_texture_load_location_invalidated(struct wined3d_resource *r ERR("Should not be called on textures.\n"); } @@ -161,16 +161,16 @@ static const struct wined3d_resource_ops texture2d_resource_ops = { texture_resource_incref, -@@ -989,6 +996,7 @@ static const struct wined3d_resource_ops texture2d_resource_ops = +@@ -949,6 +956,7 @@ static const struct wined3d_resource_ops texture2d_resource_ops = texture2d_resource_sub_resource_map, texture2d_resource_sub_resource_unmap, wined3d_texture_load_location_invalidated, + wined3d_texture_load_location, }; - static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, + static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index f150795..82bc3b0 100644 +index 00b9814..457548e 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -137,27 +137,6 @@ static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume) @@ -201,7 +201,7 @@ /* Context activation is done by the caller. */ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume, struct wined3d_context *context, BOOL dest_is_srgb) -@@ -197,21 +176,17 @@ static BOOL wined3d_volume_can_evict(const struct wined3d_volume *volume) +@@ -195,21 +174,17 @@ static BOOL wined3d_volume_can_evict(const struct wined3d_volume *volume) return TRUE; } @@ -227,7 +227,7 @@ if ((volume->resource.access_flags & required_access) != required_access) { ERR("Operation requires %#x access, but volume only has %#x.\n", -@@ -337,7 +312,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, +@@ -335,7 +310,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) { wined3d_texture_prepare_texture(volume->container, context, srgb_mode); @@ -236,7 +236,7 @@ srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB); } -@@ -396,7 +371,7 @@ static void volume_unload(struct wined3d_resource *resource) +@@ -394,7 +369,7 @@ static void volume_unload(struct wined3d_resource *resource) if (volume_prepare_system_memory(volume)) { context = context_acquire(device, NULL); @@ -245,7 +245,7 @@ context_release(context); wined3d_resource_invalidate_location(&volume->resource, ~WINED3D_LOCATION_SYSMEM); } -@@ -519,7 +494,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, +@@ -516,7 +491,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, if (flags & WINED3D_MAP_DISCARD) wined3d_resource_validate_location(&volume->resource, WINED3D_LOCATION_BUFFER); else @@ -254,7 +254,7 @@ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo)); -@@ -557,7 +532,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, +@@ -554,7 +529,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, else if (!(volume->resource.locations & WINED3D_LOCATION_SYSMEM)) { context = context_acquire(device, NULL); @@ -263,7 +263,7 @@ context_release(context); } base_memory = volume->resource.heap_memory; -@@ -688,6 +663,7 @@ static const struct wined3d_resource_ops volume_resource_ops = +@@ -685,6 +660,7 @@ static const struct wined3d_resource_ops volume_resource_ops = volume_resource_sub_resource_map, volume_resource_sub_resource_unmap, wined3d_volume_location_invalidated, @@ -272,10 +272,10 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture *container, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 4282508..e970088 100644 +index bcd6589..7e60c22 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2160,6 +2160,8 @@ struct wined3d_resource_ops +@@ -2251,6 +2251,8 @@ struct wined3d_resource_ops struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); HRESULT (*resource_sub_resource_unmap)(struct wined3d_resource *resource, unsigned int sub_resource_idx); void (*resource_location_invalidated)(struct wined3d_resource *resource, DWORD location); @@ -284,7 +284,7 @@ }; struct wined3d_resource -@@ -2212,17 +2214,20 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * +@@ -2303,17 +2305,20 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN; void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; @@ -307,5 +307,5 @@ /* Tests show that the start address of resources is 32 byte aligned */ #define RESOURCE_ALIGNMENT 16 -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0013-wined3d-Replace-surface_load_location-with-resource_.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0013-wined3d-Replace-surface_load_location-with-resource_.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0013-wined3d-Replace-surface_load_location-with-resource_.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0013-wined3d-Replace-surface_load_location-with-resource_.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From b26629e64f25b8a3a431f7b784fc4d70d1539c48 Mon Sep 17 00:00:00 2001 +From 5c7c9517db811764d7c14ec2fb10ee4ded9ea4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sun, 17 Nov 2013 20:33:17 +0100 Subject: wined3d: Replace surface_load_location with resource_load_location. @@ -8,17 +8,17 @@ dlls/wined3d/context.c | 2 +- dlls/wined3d/device.c | 4 +- dlls/wined3d/drawprim.c | 2 +- - dlls/wined3d/surface.c | 115 +++++++++++++---------------------------- + dlls/wined3d/surface.c | 109 +++++++++++++---------------------------- dlls/wined3d/swapchain.c | 8 +-- - dlls/wined3d/texture.c | 2 +- + dlls/wined3d/texture.c | 6 +-- dlls/wined3d/wined3d_private.h | 2 - - 7 files changed, 46 insertions(+), 89 deletions(-) + 7 files changed, 45 insertions(+), 88 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c -index 52fb407..15a2dc3 100644 +index 9408cd9..0d9de90 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c -@@ -2287,7 +2287,7 @@ static void context_validate_onscreen_formats(struct wined3d_context *context, +@@ -2293,7 +2293,7 @@ static void context_validate_onscreen_formats(struct wined3d_context *context, WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n"); /* The currently active context is the necessary context to access the swapchain's onscreen buffers */ @@ -28,10 +28,10 @@ swapchain_update_draw_bindings(swapchain); context_set_render_offscreen(context, TRUE); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 77ea1e9..367dc22 100644 +index 0a5b48d..ce31e25 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c -@@ -323,7 +323,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c +@@ -324,7 +324,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c if (rt && rt->resource.format->id != WINED3DFMT_NULL) { if (flags & WINED3DCLEAR_TARGET && !is_full_clear(target, draw_rect, clear_rect)) @@ -40,7 +40,7 @@ else wined3d_surface_prepare(rt, context, rt->container->resource.draw_binding); } -@@ -4010,7 +4010,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str +@@ -4123,7 +4123,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str && src_rect.bottom == sub_resource->height) wined3d_texture_prepare_texture(texture, context, FALSE); else @@ -50,7 +50,7 @@ wined3d_surface_upload_data(surface, gl_info, resource->format, diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c -index 95245a9..4b01b7d 100644 +index 9ba6ef7..0afeff9 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -627,7 +627,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co @@ -63,10 +63,10 @@ } else diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 9aff2f2..421b1ed 100644 +index 078befb..1721c6e 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c -@@ -759,7 +759,7 @@ static void surface_unmap(struct wined3d_surface *surface) +@@ -735,7 +735,7 @@ static void surface_unmap(struct wined3d_surface *surface) if (device->d3d_initialized) context = context_acquire(device, surface); @@ -75,7 +75,7 @@ if (context) context_release(context); } -@@ -825,9 +825,9 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, +@@ -801,9 +801,9 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, /* Make sure the locations are up-to-date. Loading the destination * surface isn't required if the entire surface is overwritten. */ @@ -87,7 +87,7 @@ else wined3d_surface_prepare(dst_surface, context, dst_location); -@@ -918,9 +918,9 @@ static void surface_blt_fbo(const struct wined3d_device *device, +@@ -894,9 +894,9 @@ static void surface_blt_fbo(const struct wined3d_device *device, * surface isn't required if the entire surface is overwritten. (And is * in fact harmful if we're being called by surface_load_location() with * the purpose of loading the destination surface.) */ @@ -99,7 +99,7 @@ else wined3d_surface_prepare(dst_surface, old_ctx, dst_location); -@@ -1178,7 +1178,7 @@ static void surface_unload(struct wined3d_resource *resource) +@@ -1156,7 +1156,7 @@ static void surface_unload(struct wined3d_resource *resource) else { surface_prepare_map_memory(surface); @@ -108,7 +108,7 @@ wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); } -@@ -1236,24 +1236,6 @@ static void wined3d_surface_location_invalidated(struct wined3d_resource *resour +@@ -1214,24 +1214,6 @@ static void wined3d_surface_location_invalidated(struct wined3d_resource *resour wined3d_texture_set_dirty(surface->container); } @@ -133,7 +133,7 @@ static const struct wined3d_surface_ops surface_ops = { surface_private_setup, -@@ -1707,7 +1689,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P +@@ -1691,7 +1673,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P if (update_w == dst_w && update_h == dst_h) wined3d_texture_prepare_texture(dst_surface->container, context, FALSE); else @@ -142,7 +142,7 @@ wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE); surface_get_memory(src_surface, &data, src_surface->resource.locations); -@@ -1840,7 +1822,7 @@ void surface_load(struct wined3d_surface *surface, struct wined3d_context *conte +@@ -1824,7 +1806,7 @@ void surface_load(struct wined3d_surface *surface, struct wined3d_context *conte } TRACE("Reloading because surface is dirty.\n"); @@ -151,7 +151,7 @@ surface_evict_sysmem(surface); } -@@ -2729,7 +2711,7 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, +@@ -2666,7 +2648,7 @@ HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_ if (surface->resource.device->d3d_initialized) context = context_acquire(surface->resource.device, NULL); @@ -160,34 +160,7 @@ if (context) context_release(context); } -@@ -2834,7 +2816,7 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) - { - if (surface->flags & SFLAG_CLIENT) - { -- surface_load_location(surface, context, WINED3D_LOCATION_SYSMEM); -+ wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_SYSMEM); - surface_release_client_storage(surface); - } - hr = surface_create_dib_section(surface); -@@ -2850,7 +2832,7 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) - surface->resource.map_binding = WINED3D_LOCATION_DIB; - } - -- surface_load_location(surface, context, WINED3D_LOCATION_DIB); -+ wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_DIB); - wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_DIB); - - if (context) -@@ -2899,7 +2881,7 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) - if (device->d3d_initialized) - context = context_acquire(device, NULL); - -- surface_load_location(surface, context, surface->resource.map_binding); -+ wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_DIB); - if (context) - context_release(context); -@@ -3536,8 +3518,8 @@ static void surface_blt_to_drawable(const struct wined3d_device *device, +@@ -3393,8 +3375,8 @@ static void surface_blt_to_drawable(const struct wined3d_device *device, gl_info = context->gl_info; /* Make sure the surface is up-to-date. This should probably use @@ -198,7 +171,7 @@ wined3d_texture_load(src_surface->container, context, FALSE); /* Activate the destination context, set it up for blitting */ -@@ -3957,29 +3939,6 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co +@@ -3814,29 +3796,6 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co surface->ds_current_size.cy = surface->resource.height; } @@ -228,7 +201,7 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD location) { struct wined3d_device *device = surface->resource.device; -@@ -4029,7 +3988,7 @@ static void surface_load_sysmem(struct wined3d_surface *surface, +@@ -3886,7 +3845,7 @@ static void surface_load_sysmem(struct wined3d_surface *surface, } if (surface->resource.locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) @@ -237,7 +210,7 @@ /* Download the surface to system memory. */ if (surface->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) -@@ -4065,7 +4024,7 @@ static HRESULT surface_load_drawable(struct wined3d_surface *surface, +@@ -3922,7 +3881,7 @@ static HRESULT surface_load_drawable(struct wined3d_surface *surface, } surface_get_rect(surface, NULL, &r); @@ -246,7 +219,7 @@ surface_blt_to_drawable(surface->resource.device, context, WINED3D_TEXF_POINT, FALSE, surface, &r, surface, &r); -@@ -4138,7 +4097,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, +@@ -3995,7 +3954,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, /* Performance warning... */ FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface); surface_prepare_map_memory(surface); @@ -255,7 +228,7 @@ } } else -@@ -4149,7 +4108,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, +@@ -4006,7 +3965,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, /* Performance warning... */ FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface); surface_prepare_map_memory(surface); @@ -264,7 +237,7 @@ } } -@@ -4158,7 +4117,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, +@@ -4015,7 +3974,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); /* Lets hope we get it from somewhere... */ surface_prepare_system_memory(surface); @@ -273,7 +246,7 @@ } wined3d_texture_prepare_texture(texture, context, srgb); -@@ -4184,7 +4143,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, +@@ -4041,7 +4000,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, surface->resource.map_binding = WINED3D_LOCATION_SYSMEM; surface_prepare_map_memory(surface); @@ -282,7 +255,7 @@ surface_remove_pbo(surface, gl_info); } -@@ -4259,9 +4218,11 @@ static void surface_load_renderbuffer(struct wined3d_surface *surface, struct wi +@@ -4116,9 +4075,11 @@ static void surface_load_renderbuffer(struct wined3d_surface *surface, struct wi surface, src_location, &rect, surface, dst_location, &rect); } @@ -296,7 +269,7 @@ HRESULT hr; TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); -@@ -4288,20 +4249,6 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte +@@ -4145,20 +4106,6 @@ void surface_load_location(struct wined3d_surface *surface, struct wined3d_conte } } @@ -317,7 +290,7 @@ if (!surface->resource.locations) { ERR("Surface %p does not have any up to date location.\n", surface); -@@ -5452,7 +5399,8 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC +@@ -5313,7 +5260,8 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst if (!wined3d_resource_is_offscreen(&dst_surface->container->resource)) { struct wined3d_context *context = context_acquire(device, dst_surface); @@ -327,8 +300,8 @@ context_release(context); } return WINED3D_OK; -@@ -5525,6 +5473,17 @@ cpu: - return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter); +@@ -5383,6 +5331,17 @@ cpu: + return surface_cpu_blt(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter); } +static const struct wined3d_resource_ops surface_resource_ops = @@ -346,7 +319,7 @@ const struct wined3d_resource_desc *desc, GLenum target, unsigned int level, unsigned int layer, DWORD flags) { diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c -index e87a209..b9bf4c1 100644 +index 4009dac..346129e 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -315,7 +315,7 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain, @@ -358,7 +331,7 @@ } context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, backbuffer, NULL, location); -@@ -517,14 +517,14 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT +@@ -525,14 +525,14 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT */ if (!swapchain->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO) { @@ -375,7 +348,7 @@ } if (swapchain->render_to_fbo) -@@ -617,7 +617,7 @@ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *r +@@ -625,7 +625,7 @@ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *r TRACE("Copying surface %p to screen.\n", front); @@ -385,7 +358,7 @@ src_dc = front->hDC; window = swapchain->win_handle; diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 2a183e8..29c7eec 100644 +index 49bc782..dd3a600 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -774,7 +774,7 @@ static void texture2d_sub_resource_add_dirty_region(struct wined3d_resource *sub @@ -397,19 +370,37 @@ context_release(context); wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); } +@@ -1565,7 +1565,7 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i + surface->resource.map_binding = WINED3D_LOCATION_DIB; + } + +- surface_load_location(surface, context, WINED3D_LOCATION_DIB); ++ wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_DIB); + wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_DIB); + + if (context) +@@ -1628,7 +1628,7 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign + if (device->d3d_initialized) + context = context_acquire(device, NULL); + +- surface_load_location(surface, context, surface->resource.map_binding); ++ wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); + wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_DIB); + if (context) + context_release(context); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 031e684..879d5f0 100644 +index 0ef35dd..c9985c0 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2466,8 +2466,6 @@ void surface_load_ds_location(struct wined3d_surface *surface, +@@ -2551,8 +2551,6 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, struct wined3d_context *context) DECLSPEC_HIDDEN; -void surface_load_location(struct wined3d_surface *surface, - struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; + HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, + const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; - void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_context *context, - DWORD location) DECLSPEC_HIDDEN; -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0015-wined3d-Move-volume-PBO-infrastructure-into-the-reso.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0015-wined3d-Move-volume-PBO-infrastructure-into-the-reso.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0015-wined3d-Move-volume-PBO-infrastructure-into-the-reso.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0015-wined3d-Move-volume-PBO-infrastructure-into-the-reso.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 5b00654bc918a13d1c702d102de41bdaaf0dc360 Mon Sep 17 00:00:00 2001 +From 7131fa240dda38ce201e9e6dfa45ed3adbaf264d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Thu, 16 Jan 2014 22:07:17 +0100 Subject: wined3d: Move volume PBO infrastructure into the resource. @@ -10,10 +10,10 @@ 3 files changed, 83 insertions(+), 80 deletions(-) diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 39df397..5f0a98e 100644 +index bff4997..16c4ab9 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c -@@ -373,7 +373,7 @@ GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) +@@ -389,7 +389,7 @@ GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) return ret; } @@ -22,7 +22,7 @@ { if (d3d_flags & WINED3D_MAP_READONLY) return GL_READ_ONLY_ARB; -@@ -511,3 +511,65 @@ void wined3d_resource_load_location(struct wined3d_resource *resource, +@@ -527,3 +527,65 @@ void wined3d_resource_load_location(struct wined3d_resource *resource, resource->resource_ops->resource_load_location(resource, context, location); } @@ -89,10 +89,10 @@ + } +} diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index af3f055..084e0e6 100644 +index c274eb7..78b153d 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c -@@ -218,7 +218,7 @@ static void wined3d_volume_load_location(struct wined3d_resource *resource, +@@ -216,7 +216,7 @@ static void wined3d_volume_load_location(struct wined3d_resource *resource, } else if (volume->resource.locations & WINED3D_LOCATION_BUFFER) { @@ -101,7 +101,7 @@ wined3d_texture_bind_and_dirtify(volume->container, context, location == WINED3D_LOCATION_TEXTURE_SRGB); wined3d_volume_upload_data(volume, context, &data); -@@ -274,7 +274,7 @@ static void wined3d_volume_load_location(struct wined3d_resource *resource, +@@ -272,7 +272,7 @@ static void wined3d_volume_load_location(struct wined3d_resource *resource, break; case WINED3D_LOCATION_BUFFER: @@ -110,7 +110,7 @@ ERR("Trying to load WINED3D_LOCATION_BUFFER without setting it up first.\n"); if (volume->resource.locations & WINED3D_LOCATION_DISCARDED) -@@ -284,7 +284,7 @@ static void wined3d_volume_load_location(struct wined3d_resource *resource, +@@ -282,7 +282,7 @@ static void wined3d_volume_load_location(struct wined3d_resource *resource, } else if (volume->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { @@ -119,7 +119,7 @@ if (volume->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); -@@ -321,16 +321,16 @@ static void wined3d_volume_prepare_pbo(struct wined3d_volume *volume, struct win +@@ -319,16 +319,16 @@ static void wined3d_volume_prepare_pbo(struct wined3d_volume *volume, struct win { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -140,7 +140,7 @@ } static void wined3d_volume_free_pbo(struct wined3d_volume *volume) -@@ -338,10 +338,10 @@ static void wined3d_volume_free_pbo(struct wined3d_volume *volume) +@@ -336,10 +336,10 @@ static void wined3d_volume_free_pbo(struct wined3d_volume *volume) struct wined3d_context *context = context_acquire(volume->resource.device, NULL); const struct wined3d_gl_info *gl_info = context->gl_info; @@ -155,7 +155,7 @@ context_release(context); } -@@ -349,7 +349,7 @@ void wined3d_volume_destroy(struct wined3d_volume *volume) +@@ -347,7 +347,7 @@ void wined3d_volume_destroy(struct wined3d_volume *volume) { TRACE("volume %p.\n", volume); @@ -164,7 +164,7 @@ wined3d_volume_free_pbo(volume); resource_cleanup(&volume->resource); -@@ -382,7 +382,7 @@ static void volume_unload(struct wined3d_resource *resource) +@@ -380,7 +380,7 @@ static void volume_unload(struct wined3d_resource *resource) wined3d_resource_invalidate_location(&volume->resource, ~WINED3D_LOCATION_DISCARDED); } @@ -173,7 +173,7 @@ { /* Should not happen because only dynamic default pool volumes * have a buffer, and those are not evicted by device_evit_managed_resources -@@ -486,44 +486,6 @@ static BOOL wined3d_volume_prepare_map_memory(struct wined3d_volume *volume, str +@@ -462,44 +462,6 @@ static BOOL wined3d_volume_prepare_map_memory(struct wined3d_volume *volume, str } } @@ -218,7 +218,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) { -@@ -575,7 +537,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, +@@ -551,7 +513,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, else wined3d_resource_load_location(&volume->resource, context, volume->resource.map_binding); @@ -227,7 +227,7 @@ context_release(context); TRACE("Base memory pointer %p.\n", base_memory); -@@ -629,30 +591,6 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, +@@ -605,30 +567,6 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, return WINED3D_OK; } @@ -258,7 +258,7 @@ HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) { struct wined3d_device *device = volume->resource.device; -@@ -666,7 +604,7 @@ HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) +@@ -642,7 +580,7 @@ HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) } context = context_acquire(device, NULL); @@ -268,10 +268,10 @@ volume->resource.map_count--; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 394ea0e..2a113e0 100644 +index a5af340..db60de5 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2174,6 +2174,7 @@ struct wined3d_resource +@@ -2199,6 +2199,7 @@ struct wined3d_resource DWORD priority; void *heap_memory, *user_memory, *bitmap_data; UINT custom_row_pitch, custom_slice_pitch; @@ -279,7 +279,7 @@ struct list resource_list_entry; DWORD locations; -@@ -2203,14 +2204,17 @@ void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; +@@ -2228,14 +2229,17 @@ void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; @@ -298,8 +298,8 @@ DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_resource_validate_location(struct wined3d_resource *resource, DWORD location) DECLSPEC_HIDDEN; -@@ -2337,7 +2341,6 @@ struct wined3d_volume - DWORD flags; +@@ -2356,7 +2360,6 @@ struct wined3d_volume + GLint texture_level; DWORD download_count; - GLuint pbo; @@ -307,5 +307,5 @@ static inline struct wined3d_volume *volume_from_resource(struct wined3d_resource *resource) -- -2.6.0 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0016-wined3d-Remove-surface-pbo.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0016-wined3d-Remove-surface-pbo.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0016-wined3d-Remove-surface-pbo.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0016-wined3d-Remove-surface-pbo.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,15 +1,16 @@ -From 2e105cc77b4f86b1dc044e3dc174a61df5d30a43 Mon Sep 17 00:00:00 2001 +From 1c6393b228a4764d3b7383fea540948ba147e009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 21 Jan 2014 13:25:48 +0100 Subject: wined3d: Remove surface->pbo. --- - dlls/wined3d/surface.c | 36 ++++++++++++++++++------------------ + dlls/wined3d/surface.c | 34 +++++++++++++++++----------------- + dlls/wined3d/texture.c | 2 +- dlls/wined3d/wined3d_private.h | 2 -- - 2 files changed, 18 insertions(+), 20 deletions(-) + 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 58d825c..4cdd104 100644 +index 604a79c..75abc0a 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -46,7 +46,7 @@ static void surface_cleanup(struct wined3d_surface *surface) @@ -70,7 +71,7 @@ checkGLcall("glBindBuffer"); GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, surface->resource.size + 4, -@@ -735,7 +735,7 @@ static void surface_unmap(struct wined3d_surface *surface) +@@ -711,7 +711,7 @@ static void surface_unmap(struct wined3d_surface *surface) context = context_acquire(device, NULL); gl_info = context->gl_info; @@ -79,7 +80,7 @@ GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); checkGLcall("glUnmapBuffer"); -@@ -1127,10 +1127,10 @@ HRESULT CDECL wined3d_surface_get_render_target_data(struct wined3d_surface *sur +@@ -1091,10 +1091,10 @@ static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, DW /* Context activation is done by the caller. */ static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) { @@ -93,7 +94,7 @@ wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_BUFFER); } -@@ -1187,7 +1187,7 @@ static void surface_unload(struct wined3d_resource *resource) +@@ -1161,7 +1161,7 @@ static void surface_unload(struct wined3d_resource *resource) } /* Destroy PBOs, but load them into real sysmem before */ @@ -102,7 +103,7 @@ surface_remove_pbo(surface, gl_info); /* Destroy fbo render buffers. This is needed for implicit render targets, for -@@ -2753,7 +2753,7 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, +@@ -2674,7 +2674,7 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, context = context_acquire(device, NULL); gl_info = context->gl_info; @@ -111,16 +112,7 @@ base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE)); GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); checkGLcall("map PBO"); -@@ -2844,7 +2844,7 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) - } - if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY - || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM -- || surface->pbo)) -+ || surface->resource.buffer_object)) - surface->resource.map_binding = WINED3D_LOCATION_DIB; - } - -@@ -4180,7 +4180,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, +@@ -3990,7 +3990,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, /* Don't use PBOs for converted surfaces. During PBO conversion we look at * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is * getting called. */ @@ -129,11 +121,24 @@ { TRACE("Removing the pbo attached to surface %p.\n", surface); +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index dd3a600..d41b79e 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -1561,7 +1561,7 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i + } + if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY + || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM +- || surface->pbo)) ++ || surface->resource.buffer_object)) + surface->resource.map_binding = WINED3D_LOCATION_DIB; + } + diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index f948f73..839dc7f 100644 +index 3bbe506..7aba4a7 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2390,8 +2390,6 @@ struct wined3d_surface +@@ -2468,8 +2468,6 @@ struct wined3d_surface UINT pow2Width; UINT pow2Height; @@ -143,5 +148,5 @@ GLuint rb_resolved; GLenum texture_target; -- -2.5.1 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0017-wined3d-Use-resource-buffer-mapping-facilities-in-su.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0017-wined3d-Use-resource-buffer-mapping-facilities-in-su.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0017-wined3d-Use-resource-buffer-mapping-facilities-in-su.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0017-wined3d-Use-resource-buffer-mapping-facilities-in-su.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 0c74d61fdaa16fbb70f443f6863d864024b8e615 Mon Sep 17 00:00:00 2001 +From cfcfa390db417008fc6824074bc396e0cfa85190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 21 Jan 2014 13:30:59 +0100 Subject: wined3d: Use resource buffer mapping facilities in surfaces. @@ -9,10 +9,10 @@ 2 files changed, 23 insertions(+), 63 deletions(-) diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 5f0a98e..dda77f0 100644 +index 98653cd..3d5b574 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c -@@ -544,6 +544,12 @@ BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, +@@ -570,6 +570,12 @@ BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, case WINED3D_LOCATION_SYSMEM: return resource->heap_memory; @@ -25,7 +25,7 @@ default: ERR("Unexpected map binding %s.\n", wined3d_debug_location(resource->map_binding)); return NULL; -@@ -566,6 +572,8 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, +@@ -592,6 +598,8 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, return; case WINED3D_LOCATION_SYSMEM: @@ -35,10 +35,10 @@ default: diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 62f74bd..583fa59 100644 +index 043e257..9b96625 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c -@@ -716,36 +716,10 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface) +@@ -692,36 +692,10 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface) static void surface_unmap(struct wined3d_surface *surface) { @@ -75,16 +75,16 @@ if (surface->resource.locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)) { TRACE("Not dirtified, nothing to do.\n"); -@@ -2623,6 +2597,8 @@ struct wined3d_surface * CDECL wined3d_surface_from_resource(struct wined3d_reso +@@ -2585,6 +2559,8 @@ do { \ - HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface) + HRESULT wined3d_surface_unmap(struct wined3d_surface *surface) { + struct wined3d_device *device = surface->resource.device; + struct wined3d_context *context = NULL; TRACE("surface %p.\n", surface); if (!surface->resource.map_count) -@@ -2632,6 +2608,12 @@ HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface) +@@ -2594,6 +2570,12 @@ HRESULT wined3d_surface_unmap(struct wined3d_surface *surface) } --surface->resource.map_count; @@ -97,7 +97,7 @@ surface->surface_ops->surface_unmap(surface); return WINED3D_OK; -@@ -2643,8 +2625,7 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, +@@ -2605,8 +2587,7 @@ HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_ const struct wined3d_format *format = surface->resource.format; unsigned int fmt_flags = surface->container->resource.format_flags; struct wined3d_device *device = surface->resource.device; @@ -106,8 +106,8 @@ + struct wined3d_context *context = NULL; BYTE *base_memory; - TRACE("surface %p, map_desc %p, box %p, flags %#x.\n", -@@ -2686,6 +2667,9 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, + TRACE("surface %p, map_desc %p, box %s, flags %#x.\n", +@@ -2648,6 +2629,9 @@ HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_ } } @@ -117,7 +117,7 @@ surface_prepare_map_memory(surface); if (flags & WINED3D_MAP_DISCARD) { -@@ -2695,51 +2679,19 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, +@@ -2657,51 +2641,19 @@ HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_ } else { @@ -149,12 +149,12 @@ - case WINED3D_LOCATION_DIB: - base_memory = surface->resource.bitmap_data; - break; -- ++ base_memory = wined3d_resource_get_map_ptr(&surface->resource, context, flags); + - case WINED3D_LOCATION_BUFFER: - context = context_acquire(device, NULL); - gl_info = context->gl_info; -+ base_memory = wined3d_resource_get_map_ptr(&surface->resource, context, flags); - +- - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->resource.buffer_object)); - base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); @@ -173,5 +173,5 @@ if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) map_desc->row_pitch = surface->resource.width * format->byte_count; -- -2.6.0 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0018-wined3d-Move-buffer-creation-into-the-resource.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0018-wined3d-Move-buffer-creation-into-the-resource.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0018-wined3d-Move-buffer-creation-into-the-resource.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0018-wined3d-Move-buffer-creation-into-the-resource.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From e6f030ca36c31b52f7dce040eb03552a2a73b2e7 Mon Sep 17 00:00:00 2001 +From bd7832b10a3c2c43e33abff97a9447d52166da3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Wed, 18 Sep 2013 22:49:34 +0200 Subject: wined3d: Move buffer creation into the resource. @@ -9,13 +9,12 @@ surface_load_location will write a lot of ERRs. --- dlls/wined3d/resource.c | 66 ++++++++++++++++++++++++++++++++++++++++++ - dlls/wined3d/texture.c | 2 +- dlls/wined3d/volume.c | 63 ++-------------------------------------- dlls/wined3d/wined3d_private.h | 4 ++- - 4 files changed, 72 insertions(+), 63 deletions(-) + 3 files changed, 71 insertions(+), 62 deletions(-) diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index dda77f0..e20f353 100644 +index 5204fee..0d2145f 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -223,6 +223,18 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * @@ -57,7 +56,7 @@ context_resource_unloaded(resource->device, resource, resource->type); } -@@ -581,3 +599,51 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, +@@ -597,3 +615,51 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, return; } } @@ -109,24 +108,11 @@ + return FALSE; + } +} -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 0241309..abd2d8a 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -1289,7 +1289,7 @@ static void texture3d_prepare_texture(struct wined3d_texture *texture, struct wi - void *mem = NULL; - - if (gl_info->supported[APPLE_CLIENT_STORAGE] && !format->convert -- && volume_prepare_system_memory(volume)) -+ && wined3d_resource_prepare_system_memory(&volume->resource)) - { - TRACE("Enabling GL_UNPACK_CLIENT_STORAGE_APPLE for volume %p\n", volume); - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index 084e0e6..d823ebd 100644 +index 78b153d..c95af94 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c -@@ -316,42 +316,10 @@ void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context * +@@ -314,42 +314,10 @@ void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context * srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB); } @@ -169,7 +155,7 @@ resource_cleanup(&volume->resource); volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent); HeapFree(GetProcessHeap(), 0, volume); -@@ -368,7 +336,7 @@ static void volume_unload(struct wined3d_resource *resource) +@@ -366,7 +334,7 @@ static void volume_unload(struct wined3d_resource *resource) TRACE("texture %p.\n", resource); @@ -178,7 +164,7 @@ { context = context_acquire(device, NULL); wined3d_resource_load_location(&volume->resource, context, WINED3D_LOCATION_SYSMEM); -@@ -382,15 +350,6 @@ static void volume_unload(struct wined3d_resource *resource) +@@ -380,15 +348,6 @@ static void volume_unload(struct wined3d_resource *resource) wined3d_resource_invalidate_location(&volume->resource, ~WINED3D_LOCATION_DISCARDED); } @@ -192,9 +178,9 @@ - } - /* The texture name is managed by the container. */ - volume->flags &= ~WINED3D_VFLAG_CLIENT_STORAGE; -@@ -468,24 +427,6 @@ static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *vol + resource_unload(resource); +@@ -444,24 +403,6 @@ static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *vol return TRUE; } @@ -219,7 +205,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) { -@@ -524,7 +465,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, +@@ -500,7 +441,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags); context = context_acquire(device, NULL); @@ -229,10 +215,10 @@ WARN("Out of memory.\n"); map_desc->data = NULL; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 828f9a7..67c1de2 100644 +index 6dc1b04..0049165 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -2213,6 +2213,9 @@ void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWO +@@ -2238,6 +2238,9 @@ void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWO BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_resource_load_location(struct wined3d_resource *resource, struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; @@ -242,7 +228,7 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, const struct wined3d_context *context) DECLSPEC_HIDDEN; DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; -@@ -2348,7 +2351,6 @@ static inline struct wined3d_volume *volume_from_resource(struct wined3d_resourc +@@ -2367,7 +2370,6 @@ static inline struct wined3d_volume *volume_from_resource(struct wined3d_resourc return CONTAINING_RECORD(resource, struct wined3d_volume, resource); } @@ -251,5 +237,5 @@ unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN; void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN; -- -2.6.0 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0025-wined3d-Allocate-sysmem-for-client-storage-if-it-doe.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0025-wined3d-Allocate-sysmem-for-client-storage-if-it-doe.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0025-wined3d-Allocate-sysmem-for-client-storage-if-it-doe.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0025-wined3d-Allocate-sysmem-for-client-storage-if-it-doe.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -From d0f1f1278a8225075bd03c9586112bf29318563c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Mon, 16 Sep 2013 22:22:39 +0200 -Subject: wined3d: Allocate sysmem for client storage if it doesn't exist - already. - ---- - dlls/wined3d/texture.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 41cf61d..8298e53 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -904,8 +904,7 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi - if (gl_info->supported[APPLE_CLIENT_STORAGE]) - { - if (surface->flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION) -- || texture->flags & WINED3D_TEXTURE_CONVERTED -- || !surface->resource.heap_memory) -+ || texture->flags & WINED3D_TEXTURE_CONVERTED) - { - /* In some cases we want to disable client storage. - * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches -@@ -917,6 +916,9 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi - } - else - { -+ if (!surface->resource.heap_memory) -+ wined3d_resource_allocate_sysmem(&surface->resource); -+ - surface->flags |= SFLAG_CLIENT; - mem = surface->resource.heap_memory; - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0025-wined3d-Introduce-a-function-to-retrieve-resource-me.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0025-wined3d-Introduce-a-function-to-retrieve-resource-me.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0025-wined3d-Introduce-a-function-to-retrieve-resource-me.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0025-wined3d-Introduce-a-function-to-retrieve-resource-me.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,159 @@ +From 4fbfd7b2bbc5f5dd3b99653d223214901597cbad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Mon, 16 Sep 2013 22:44:33 +0200 +Subject: wined3d: Introduce a function to retrieve resource memory. + +--- + dlls/wined3d/resource.c | 30 ++++++++++++++++++++++++++++ + dlls/wined3d/surface.c | 45 ++++++------------------------------------ + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 38 insertions(+), 39 deletions(-) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index b756bf1..40267e7 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -506,6 +506,36 @@ DWORD wined3d_resource_access_from_location(DWORD location) + } + } + ++void wined3d_resource_get_memory(const struct wined3d_resource *resource, ++ DWORD location, struct wined3d_bo_address *data) ++{ ++ if (location & WINED3D_LOCATION_BUFFER) ++ { ++ data->buffer_object = resource->buffer_object; ++ data->addr = NULL; ++ return; ++ } ++ if (location & WINED3D_LOCATION_USER_MEMORY) ++ { ++ data->buffer_object = 0; ++ data->addr = resource->user_memory; ++ return; ++ } ++ if (location & WINED3D_LOCATION_DIB) ++ { ++ data->buffer_object = 0; ++ data->addr = resource->bitmap_data; ++ return; ++ } ++ if (location & WINED3D_LOCATION_SYSMEM) ++ { ++ data->buffer_object = 0; ++ data->addr = resource->heap_memory; ++ return; ++ } ++ ERR("Unexpected location %s.\n", wined3d_debug_location(location)); ++} ++ + /* Context activation is optionally by the caller. Context may be NULL. */ + void wined3d_resource_load_location(struct wined3d_resource *resource, + struct wined3d_context *context, DWORD location) +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 2abc494..857c620 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -479,39 +479,6 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface) + return WINED3D_OK; + } + +-static void surface_get_memory(const struct wined3d_surface *surface, struct wined3d_bo_address *data, +- DWORD location) +-{ +- if (location & WINED3D_LOCATION_BUFFER) +- { +- data->addr = NULL; +- data->buffer_object = surface->resource.buffer_object; +- return; +- } +- if (location & WINED3D_LOCATION_USER_MEMORY) +- { +- data->addr = surface->resource.user_memory; +- data->buffer_object = 0; +- return; +- } +- if (location & WINED3D_LOCATION_DIB) +- { +- data->addr = surface->resource.bitmap_data; +- data->buffer_object = 0; +- return; +- } +- if (location & WINED3D_LOCATION_SYSMEM) +- { +- data->addr = surface->resource.heap_memory; +- data->buffer_object = 0; +- return; +- } +- +- ERR("Unexpected locations %s.\n", wined3d_debug_location(location)); +- data->addr = NULL; +- data->buffer_object = 0; +-} +- + static void surface_prepare_buffer(struct wined3d_surface *surface) + { + struct wined3d_context *context; +@@ -1265,7 +1232,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct + return; + } + +- surface_get_memory(surface, &data, dst_location); ++ wined3d_resource_get_memory(&surface->resource, dst_location, &data); + + if (surface->container->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) + { +@@ -1641,7 +1608,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P + wined3d_resource_load_location(&dst_surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE); + +- surface_get_memory(src_surface, &data, src_surface->resource.locations); ++ wined3d_resource_get_memory(&src_surface->resource, src_surface->resource.locations, &data); + wined3d_resource_get_pitch(&src_surface->resource, &src_row_pitch, &src_slice_pitch); + + wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect, +@@ -2831,7 +2798,7 @@ static void read_from_framebuffer(struct wined3d_surface *surface, + struct wined3d_bo_address data; + DWORD slice_pitch, pitch; + +- surface_get_memory(surface, &data, dst_location); ++ wined3d_resource_get_memory(&surface->resource, dst_location, &data); + + if (surface != old_ctx->current_rt) + { +@@ -3881,8 +3848,8 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD + struct wined3d_bo_address dst, src; + UINT size = surface->resource.size; + +- surface_get_memory(surface, &dst, location); +- surface_get_memory(surface, &src, surface->resource.locations); ++ wined3d_resource_get_memory(&surface->resource, location, &dst); ++ wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &src); + + if (dst.buffer_object) + { +@@ -4094,7 +4061,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, + surface_remove_pbo(surface, gl_info); + } + +- surface_get_memory(surface, &data, surface->resource.locations); ++ wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &data); + if (format.convert) + { + /* This code is entered for texture formats which need a fixup. */ +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 49d9674..dec7787 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2211,6 +2211,8 @@ BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPE + void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, + const struct wined3d_context *context, DWORD flags) DECLSPEC_HIDDEN; ++void wined3d_resource_get_memory(const struct wined3d_resource *resource, ++ DWORD location, struct wined3d_bo_address *data) DECLSPEC_HIDDEN; + void wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch, + UINT *slice_pitch) DECLSPEC_HIDDEN; + GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; +-- +2.6.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0026-wined3d-Introduce-a-function-to-retrieve-resource-me.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0026-wined3d-Introduce-a-function-to-retrieve-resource-me.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0026-wined3d-Introduce-a-function-to-retrieve-resource-me.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0026-wined3d-Introduce-a-function-to-retrieve-resource-me.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,159 +0,0 @@ -From 4fbfd7b2bbc5f5dd3b99653d223214901597cbad Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Mon, 16 Sep 2013 22:44:33 +0200 -Subject: wined3d: Introduce a function to retrieve resource memory. - ---- - dlls/wined3d/resource.c | 30 ++++++++++++++++++++++++++++ - dlls/wined3d/surface.c | 45 ++++++------------------------------------ - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 38 insertions(+), 39 deletions(-) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index b756bf1..40267e7 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -506,6 +506,36 @@ DWORD wined3d_resource_access_from_location(DWORD location) - } - } - -+void wined3d_resource_get_memory(const struct wined3d_resource *resource, -+ DWORD location, struct wined3d_bo_address *data) -+{ -+ if (location & WINED3D_LOCATION_BUFFER) -+ { -+ data->buffer_object = resource->buffer_object; -+ data->addr = NULL; -+ return; -+ } -+ if (location & WINED3D_LOCATION_USER_MEMORY) -+ { -+ data->buffer_object = 0; -+ data->addr = resource->user_memory; -+ return; -+ } -+ if (location & WINED3D_LOCATION_DIB) -+ { -+ data->buffer_object = 0; -+ data->addr = resource->bitmap_data; -+ return; -+ } -+ if (location & WINED3D_LOCATION_SYSMEM) -+ { -+ data->buffer_object = 0; -+ data->addr = resource->heap_memory; -+ return; -+ } -+ ERR("Unexpected location %s.\n", wined3d_debug_location(location)); -+} -+ - /* Context activation is optionally by the caller. Context may be NULL. */ - void wined3d_resource_load_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 2abc494..857c620 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -479,39 +479,6 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface) - return WINED3D_OK; - } - --static void surface_get_memory(const struct wined3d_surface *surface, struct wined3d_bo_address *data, -- DWORD location) --{ -- if (location & WINED3D_LOCATION_BUFFER) -- { -- data->addr = NULL; -- data->buffer_object = surface->resource.buffer_object; -- return; -- } -- if (location & WINED3D_LOCATION_USER_MEMORY) -- { -- data->addr = surface->resource.user_memory; -- data->buffer_object = 0; -- return; -- } -- if (location & WINED3D_LOCATION_DIB) -- { -- data->addr = surface->resource.bitmap_data; -- data->buffer_object = 0; -- return; -- } -- if (location & WINED3D_LOCATION_SYSMEM) -- { -- data->addr = surface->resource.heap_memory; -- data->buffer_object = 0; -- return; -- } -- -- ERR("Unexpected locations %s.\n", wined3d_debug_location(location)); -- data->addr = NULL; -- data->buffer_object = 0; --} -- - static void surface_prepare_buffer(struct wined3d_surface *surface) - { - struct wined3d_context *context; -@@ -1265,7 +1232,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct - return; - } - -- surface_get_memory(surface, &data, dst_location); -+ wined3d_resource_get_memory(&surface->resource, dst_location, &data); - - if (surface->container->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) - { -@@ -1641,7 +1608,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P - wined3d_resource_load_location(&dst_surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE); - -- surface_get_memory(src_surface, &data, src_surface->resource.locations); -+ wined3d_resource_get_memory(&src_surface->resource, src_surface->resource.locations, &data); - wined3d_resource_get_pitch(&src_surface->resource, &src_row_pitch, &src_slice_pitch); - - wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect, -@@ -2831,7 +2798,7 @@ static void read_from_framebuffer(struct wined3d_surface *surface, - struct wined3d_bo_address data; - DWORD slice_pitch, pitch; - -- surface_get_memory(surface, &data, dst_location); -+ wined3d_resource_get_memory(&surface->resource, dst_location, &data); - - if (surface != old_ctx->current_rt) - { -@@ -3881,8 +3848,8 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD - struct wined3d_bo_address dst, src; - UINT size = surface->resource.size; - -- surface_get_memory(surface, &dst, location); -- surface_get_memory(surface, &src, surface->resource.locations); -+ wined3d_resource_get_memory(&surface->resource, location, &dst); -+ wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &src); - - if (dst.buffer_object) - { -@@ -4094,7 +4061,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, - surface_remove_pbo(surface, gl_info); - } - -- surface_get_memory(surface, &data, surface->resource.locations); -+ wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &data); - if (format.convert) - { - /* This code is entered for texture formats which need a fixup. */ -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 49d9674..dec7787 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2211,6 +2211,8 @@ BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPE - void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, - const struct wined3d_context *context, DWORD flags) DECLSPEC_HIDDEN; -+void wined3d_resource_get_memory(const struct wined3d_resource *resource, -+ DWORD location, struct wined3d_bo_address *data) DECLSPEC_HIDDEN; - void wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch, - UINT *slice_pitch) DECLSPEC_HIDDEN; - GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; --- -2.6.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0026-wined3d-Make-surface_ops-unmap-specific-for-front-bu.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0026-wined3d-Make-surface_ops-unmap-specific-for-front-bu.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0026-wined3d-Make-surface_ops-unmap-specific-for-front-bu.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0026-wined3d-Make-surface_ops-unmap-specific-for-front-bu.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,116 @@ +From 10058dd5be622aefa90a05d8e793573da1140bf7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 19 Sep 2013 13:36:00 +0200 +Subject: wined3d: Make surface_ops->unmap specific for front buffers. + +--- + dlls/wined3d/surface.c | 45 +++++++++++++++--------------------------- + dlls/wined3d/wined3d_private.h | 2 +- + 2 files changed, 17 insertions(+), 30 deletions(-) + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 3e9a8ef..175f05e 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -681,31 +681,22 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface) + return WINED3D_OK; + } + +-static void surface_unmap(struct wined3d_surface *surface) ++static void surface_frontbuffer_updated(struct wined3d_surface *surface) + { +- TRACE("surface %p.\n", surface); +- +- memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); ++ struct wined3d_context *context = NULL; ++ struct wined3d_device *device = surface->resource.device; + +- if (surface->resource.locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)) ++ if (surface->resource.locations & WINED3D_LOCATION_DRAWABLE) + { + TRACE("Not dirtified, nothing to do.\n"); + return; + } + +- if (surface->container->swapchain && surface->container->swapchain->front_buffer == surface->container) +- { +- struct wined3d_device *device = surface->resource.device; +- struct wined3d_context *context = NULL; +- +- if (device->d3d_initialized) +- context = context_acquire(device, surface); +- wined3d_resource_load_location(&surface->resource, context, surface->container->resource.draw_binding); +- if (context) +- context_release(context); +- } +- else if (surface->container->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) +- FIXME("Depth / stencil buffer locking is not implemented.\n"); ++ if (device->d3d_initialized) ++ context = context_acquire(surface->resource.device, NULL); ++ wined3d_resource_load_location(&surface->resource, context, surface->container->resource.draw_binding); ++ if (context) ++ context_release(context); + } + + static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r) +@@ -1164,7 +1155,7 @@ static void wined3d_surface_location_invalidated(struct wined3d_resource *resour + static const struct wined3d_surface_ops surface_ops = + { + surface_private_setup, +- surface_unmap, ++ surface_frontbuffer_updated, + }; + + /***************************************************************************** +@@ -1208,21 +1199,15 @@ static HRESULT gdi_surface_private_setup(struct wined3d_surface *surface) + return WINED3D_OK; + } + +-static void gdi_surface_unmap(struct wined3d_surface *surface) ++static void gdi_surface_frontbuffer_updated(struct wined3d_surface *surface) + { +- TRACE("surface %p.\n", surface); +- +- /* Tell the swapchain to update the screen. */ +- if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) +- x11_copy_to_screen(surface->container->swapchain, &surface->lockedRect); +- +- memset(&surface->lockedRect, 0, sizeof(RECT)); ++ x11_copy_to_screen(surface->container->swapchain, &surface->lockedRect); + } + + static const struct wined3d_surface_ops gdi_surface_ops = + { + gdi_surface_private_setup, +- gdi_surface_unmap, ++ gdi_surface_frontbuffer_updated, + }; + + /* This call just downloads data, the caller is responsible for binding the +@@ -2612,7 +2597,9 @@ HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface) + if (context) + context_release(context); + +- surface->surface_ops->surface_unmap(surface); ++ if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) ++ surface->surface_ops->surface_frontbuffer_updated(surface); ++ memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); + + return WINED3D_OK; + } +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index f8733ad..b0986cd 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2350,7 +2350,7 @@ struct fbo_entry + struct wined3d_surface_ops + { + HRESULT (*surface_private_setup)(struct wined3d_surface *surface); +- void (*surface_unmap)(struct wined3d_surface *surface); ++ void (*surface_frontbuffer_updated)(struct wined3d_surface *surface); + }; + + struct wined3d_surface +-- +2.4.2 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0027-wined3d-Make-surface_ops-unmap-specific-for-front-bu.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0027-wined3d-Make-surface_ops-unmap-specific-for-front-bu.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0027-wined3d-Make-surface_ops-unmap-specific-for-front-bu.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0027-wined3d-Make-surface_ops-unmap-specific-for-front-bu.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -From 10058dd5be622aefa90a05d8e793573da1140bf7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 19 Sep 2013 13:36:00 +0200 -Subject: wined3d: Make surface_ops->unmap specific for front buffers. - ---- - dlls/wined3d/surface.c | 45 +++++++++++++++--------------------------- - dlls/wined3d/wined3d_private.h | 2 +- - 2 files changed, 17 insertions(+), 30 deletions(-) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 3e9a8ef..175f05e 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -681,31 +681,22 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface) - return WINED3D_OK; - } - --static void surface_unmap(struct wined3d_surface *surface) -+static void surface_frontbuffer_updated(struct wined3d_surface *surface) - { -- TRACE("surface %p.\n", surface); -- -- memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); -+ struct wined3d_context *context = NULL; -+ struct wined3d_device *device = surface->resource.device; - -- if (surface->resource.locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)) -+ if (surface->resource.locations & WINED3D_LOCATION_DRAWABLE) - { - TRACE("Not dirtified, nothing to do.\n"); - return; - } - -- if (surface->container->swapchain && surface->container->swapchain->front_buffer == surface->container) -- { -- struct wined3d_device *device = surface->resource.device; -- struct wined3d_context *context = NULL; -- -- if (device->d3d_initialized) -- context = context_acquire(device, surface); -- wined3d_resource_load_location(&surface->resource, context, surface->container->resource.draw_binding); -- if (context) -- context_release(context); -- } -- else if (surface->container->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) -- FIXME("Depth / stencil buffer locking is not implemented.\n"); -+ if (device->d3d_initialized) -+ context = context_acquire(surface->resource.device, NULL); -+ wined3d_resource_load_location(&surface->resource, context, surface->container->resource.draw_binding); -+ if (context) -+ context_release(context); - } - - static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r) -@@ -1164,7 +1155,7 @@ static void wined3d_surface_location_invalidated(struct wined3d_resource *resour - static const struct wined3d_surface_ops surface_ops = - { - surface_private_setup, -- surface_unmap, -+ surface_frontbuffer_updated, - }; - - /***************************************************************************** -@@ -1208,21 +1199,15 @@ static HRESULT gdi_surface_private_setup(struct wined3d_surface *surface) - return WINED3D_OK; - } - --static void gdi_surface_unmap(struct wined3d_surface *surface) -+static void gdi_surface_frontbuffer_updated(struct wined3d_surface *surface) - { -- TRACE("surface %p.\n", surface); -- -- /* Tell the swapchain to update the screen. */ -- if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) -- x11_copy_to_screen(surface->container->swapchain, &surface->lockedRect); -- -- memset(&surface->lockedRect, 0, sizeof(RECT)); -+ x11_copy_to_screen(surface->container->swapchain, &surface->lockedRect); - } - - static const struct wined3d_surface_ops gdi_surface_ops = - { - gdi_surface_private_setup, -- gdi_surface_unmap, -+ gdi_surface_frontbuffer_updated, - }; - - /* This call just downloads data, the caller is responsible for binding the -@@ -2612,7 +2597,9 @@ HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface) - if (context) - context_release(context); - -- surface->surface_ops->surface_unmap(surface); -+ if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) -+ surface->surface_ops->surface_frontbuffer_updated(surface); -+ memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); - - return WINED3D_OK; - } -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index f8733ad..b0986cd 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2350,7 +2350,7 @@ struct fbo_entry - struct wined3d_surface_ops - { - HRESULT (*surface_private_setup)(struct wined3d_surface *surface); -- void (*surface_unmap)(struct wined3d_surface *surface); -+ void (*surface_frontbuffer_updated)(struct wined3d_surface *surface); - }; - - struct wined3d_surface --- -2.4.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0027-wined3d-Move-check_block_align-to-resource.c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0027-wined3d-Move-check_block_align-to-resource.c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0027-wined3d-Move-check_block_align-to-resource.c.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0027-wined3d-Move-check_block_align-to-resource.c.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,147 @@ +From e7bd14cde60905b56bce90d9ec660b560f67a2fc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 19 Sep 2013 14:55:00 +0200 +Subject: wined3d: Move check_block_align to resource.c + +--- + dlls/wined3d/resource.c | 28 ++++++++++++++++++++++++++++ + dlls/wined3d/surface.c | 18 +----------------- + dlls/wined3d/volume.c | 30 +----------------------------- + dlls/wined3d/wined3d_private.h | 2 ++ + 4 files changed, 32 insertions(+), 46 deletions(-) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 01070a6..b95e17a 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -715,3 +715,31 @@ BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource, stru + return FALSE; + } + } ++ ++BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, ++ const struct wined3d_box *box) ++{ ++ UINT width_mask, height_mask; ++ const struct wined3d_format *format = resource->format; ++ ++ if (!box) ++ return TRUE; ++ ++ /* This assumes power of two block sizes, but NPOT block sizes would be ++ * silly anyway. ++ * ++ * This also assumes that the format's block depth is 1. */ ++ width_mask = format->block_width - 1; ++ height_mask = format->block_height - 1; ++ ++ if (box->left & width_mask) ++ return FALSE; ++ if (box->top & height_mask) ++ return FALSE; ++ if (box->right & width_mask && box->right != resource->width) ++ return FALSE; ++ if (box->bottom & height_mask && box->bottom != resource->height) ++ return FALSE; ++ ++ return TRUE; ++} +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 84975ba..0aa8115 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -1472,29 +1472,13 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w + + static BOOL surface_check_block_align(struct wined3d_surface *surface, const struct wined3d_box *box) + { +- UINT width_mask, height_mask; +- +- if (!box->left && !box->top +- && box->right == surface->resource.width +- && box->bottom == surface->resource.height) +- return TRUE; +- + if ((box->left >= box->right) + || (box->top >= box->bottom) + || (box->right > surface->resource.width) + || (box->bottom > surface->resource.height)) + return FALSE; + +- /* This assumes power of two block sizes, but NPOT block sizes would be +- * silly anyway. */ +- width_mask = surface->resource.format->block_width - 1; +- height_mask = surface->resource.format->block_height - 1; +- +- if (!(box->left & width_mask) && !(box->top & height_mask) +- && !(box->right & width_mask) && !(box->bottom & height_mask)) +- return TRUE; +- +- return FALSE; ++ return wined3d_resource_check_block_align(&surface->resource, box); + } + + static BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) +diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c +index b0bcd16..e598e1b 100644 +--- a/dlls/wined3d/volume.c ++++ b/dlls/wined3d/volume.c +@@ -343,34 +343,6 @@ static void volume_unload(struct wined3d_resource *resource) + resource_unload(resource); + } + +-static BOOL volume_check_block_align(const struct wined3d_volume *volume, +- const struct wined3d_box *box) +-{ +- UINT width_mask, height_mask; +- const struct wined3d_format *format = volume->resource.format; +- +- if (!box) +- return TRUE; +- +- /* This assumes power of two block sizes, but NPOT block sizes would be +- * silly anyway. +- * +- * This also assumes that the format's block depth is 1. */ +- width_mask = format->block_width - 1; +- height_mask = format->block_height - 1; +- +- if (box->left & width_mask) +- return FALSE; +- if (box->top & height_mask) +- return FALSE; +- if (box->right & width_mask && box->right != volume->resource.width) +- return FALSE; +- if (box->bottom & height_mask && box->bottom != volume->resource.height) +- return FALSE; +- +- return TRUE; +-} +- + static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *volume, + const struct wined3d_box *box) + { +@@ -421,7 +393,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, + WARN("Map box is invalid.\n"); + return WINED3DERR_INVALIDCALL; + } +- if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !volume_check_block_align(volume, box)) ++ if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !wined3d_resource_check_block_align(&volume->resource, box)) + { + WARN("Map box %s is misaligned for %ux%u blocks.\n", + debug_box(box), format->block_width, format->block_height); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 8b88406..7c3b82f 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2308,6 +2308,8 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * + void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; + BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, ++ const struct wined3d_box *box) DECLSPEC_HIDDEN; + void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, + const struct wined3d_context *context, DWORD flags) DECLSPEC_HIDDEN; +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0028-wined3d-Move-check_block_align-to-resource.c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0028-wined3d-Move-check_block_align-to-resource.c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0028-wined3d-Move-check_block_align-to-resource.c.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0028-wined3d-Move-check_block_align-to-resource.c.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,141 +0,0 @@ -From 229f5e781649be372e0c19c65009bd776677b251 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 19 Sep 2013 14:55:00 +0200 -Subject: wined3d: Move check_block_align to resource.c - ---- - dlls/wined3d/resource.c | 28 ++++++++++++++++++++++++++++ - dlls/wined3d/surface.c | 18 +----------------- - dlls/wined3d/volume.c | 30 +----------------------------- - dlls/wined3d/wined3d_private.h | 2 ++ - 4 files changed, 32 insertions(+), 46 deletions(-) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 40267e7..c8bbf3d 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -689,3 +689,31 @@ BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource, stru - return FALSE; - } - } -+ -+BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, -+ const struct wined3d_box *box) -+{ -+ UINT width_mask, height_mask; -+ const struct wined3d_format *format = resource->format; -+ -+ if (!box) -+ return TRUE; -+ -+ /* This assumes power of two block sizes, but NPOT block sizes would be -+ * silly anyway. -+ * -+ * This also assumes that the format's block depth is 1. */ -+ width_mask = format->block_width - 1; -+ height_mask = format->block_height - 1; -+ -+ if (box->left & width_mask) -+ return FALSE; -+ if (box->top & height_mask) -+ return FALSE; -+ if (box->right & width_mask && box->right != resource->width) -+ return FALSE; -+ if (box->bottom & height_mask && box->bottom != resource->height) -+ return FALSE; -+ -+ return TRUE; -+} -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 469790e..4e17620 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -1477,23 +1477,7 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w - - static BOOL surface_check_block_align(struct wined3d_surface *surface, const struct wined3d_box *box) - { -- UINT width_mask, height_mask; -- -- if (!box->left && !box->top -- && box->right == surface->resource.width -- && box->bottom == surface->resource.height) -- return TRUE; -- -- /* This assumes power of two block sizes, but NPOT block sizes would be -- * silly anyway. */ -- width_mask = surface->resource.format->block_width - 1; -- height_mask = surface->resource.format->block_height - 1; -- -- if (!(box->left & width_mask) && !(box->top & height_mask) -- && !(box->right & width_mask) && !(box->bottom & height_mask)) -- return TRUE; -- -- return FALSE; -+ return wined3d_resource_check_block_align(&surface->resource, box); - } - - static BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) -diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index f12d8d6..d182a46 100644 ---- a/dlls/wined3d/volume.c -+++ b/dlls/wined3d/volume.c -@@ -346,34 +346,6 @@ static void volume_unload(struct wined3d_resource *resource) - resource_unload(resource); - } - --static BOOL volume_check_block_align(const struct wined3d_volume *volume, -- const struct wined3d_box *box) --{ -- UINT width_mask, height_mask; -- const struct wined3d_format *format = volume->resource.format; -- -- if (!box) -- return TRUE; -- -- /* This assumes power of two block sizes, but NPOT block sizes would be -- * silly anyway. -- * -- * This also assumes that the format's block depth is 1. */ -- width_mask = format->block_width - 1; -- height_mask = format->block_height - 1; -- -- if (box->left & width_mask) -- return FALSE; -- if (box->top & height_mask) -- return FALSE; -- if (box->right & width_mask && box->right != volume->resource.width) -- return FALSE; -- if (box->bottom & height_mask && box->bottom != volume->resource.height) -- return FALSE; -- -- return TRUE; --} -- - static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *volume, - const struct wined3d_box *box) - { -@@ -424,7 +396,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, - WARN("Map box is invalid.\n"); - return WINED3DERR_INVALIDCALL; - } -- if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !volume_check_block_align(volume, box)) -+ if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !wined3d_resource_check_block_align(&volume->resource, box)) - { - WARN("Map box is misaligned for %ux%u blocks.\n", - format->block_width, format->block_height); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index b97d1d9..0cc48d8 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2203,6 +2203,8 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * - void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; - BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, -+ const struct wined3d_box *box) DECLSPEC_HIDDEN; - void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, - const struct wined3d_context *context, DWORD flags) DECLSPEC_HIDDEN; --- -2.6.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0028-wined3d-Replace-surface-alloc-functions-with-resourc.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0028-wined3d-Replace-surface-alloc-functions-with-resourc.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0028-wined3d-Replace-surface-alloc-functions-with-resourc.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0028-wined3d-Replace-surface-alloc-functions-with-resourc.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,211 @@ +From 1505be1b5bedf3387daa7dc558314f3480b2004e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 21 Jan 2014 16:40:56 +0100 +Subject: wined3d: Replace surface alloc functions with resource ones. + +--- + dlls/wined3d/resource.c | 10 +++++ + dlls/wined3d/surface.c | 89 ++++-------------------------------------- + dlls/wined3d/texture.c | 2 +- + dlls/wined3d/wined3d_private.h | 1 - + 4 files changed, 18 insertions(+), 84 deletions(-) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index b47536a..261b386 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -700,6 +700,16 @@ BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource, stru + case WINED3D_LOCATION_SYSMEM: + return wined3d_resource_prepare_system_memory(resource); + ++ case WINED3D_LOCATION_USER_MEMORY: ++ if (!resource->user_memory) ++ ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but resource->user_memory is NULL.\n"); ++ return TRUE; ++ ++ case WINED3D_LOCATION_DIB: ++ if (!resource->bitmap_data) ++ ERR("Map binding is set to WINED3D_LOCATION_DIB but resource->bitmap_data is NULL.\n"); ++ return TRUE; ++ + default: + ERR("Unexpected map binding %s.\n", wined3d_debug_location(resource->map_binding)); + return FALSE; +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index af4de99..2287523 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -479,81 +479,6 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface) + return WINED3D_OK; + } + +-static void surface_prepare_buffer(struct wined3d_surface *surface) +-{ +- struct wined3d_context *context; +- GLenum error; +- const struct wined3d_gl_info *gl_info; +- +- if (surface->resource.buffer_object) +- return; +- +- context = context_acquire(surface->resource.device, NULL); +- gl_info = context->gl_info; +- +- GL_EXTCALL(glGenBuffers(1, &surface->resource.buffer_object)); +- error = gl_info->gl_ops.gl.p_glGetError(); +- if (!surface->resource.buffer_object || error != GL_NO_ERROR) +- ERR("Failed to create a PBO with error %s (%#x).\n", debug_glerror(error), error); +- +- TRACE("Binding PBO %u.\n", surface->resource.buffer_object); +- +- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->resource.buffer_object)); +- checkGLcall("glBindBuffer"); +- +- GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, surface->resource.size + 4, +- NULL, GL_STREAM_DRAW)); +- checkGLcall("glBufferData"); +- +- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); +- checkGLcall("glBindBuffer"); +- +- context_release(context); +-} +- +-static void surface_prepare_system_memory(struct wined3d_surface *surface) +-{ +- TRACE("surface %p.\n", surface); +- +- if (surface->resource.heap_memory) +- return; +- +- /* Whatever surface we have, make sure that there is memory allocated +- * for the downloaded copy, or a PBO to map. */ +- if (!wined3d_resource_allocate_sysmem(&surface->resource)) +- ERR("Failed to allocate system memory.\n"); +- +- if (surface->resource.locations & WINED3D_LOCATION_SYSMEM) +- ERR("Surface without system memory has WINED3D_LOCATION_SYSMEM set.\n"); +-} +- +-void surface_prepare_map_memory(struct wined3d_surface *surface) +-{ +- switch (surface->resource.map_binding) +- { +- case WINED3D_LOCATION_SYSMEM: +- surface_prepare_system_memory(surface); +- break; +- +- case WINED3D_LOCATION_USER_MEMORY: +- if (!surface->resource.user_memory) +- ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but surface->resource.user_memory is NULL.\n"); +- break; +- +- case WINED3D_LOCATION_DIB: +- if (!surface->resource.bitmap_data) +- ERR("Map binding is set to WINED3D_LOCATION_DIB but surface->resource.bitmap_data is NULL.\n"); +- break; +- +- case WINED3D_LOCATION_BUFFER: +- surface_prepare_buffer(surface); +- break; +- +- default: +- ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); +- } +-} +- + static void surface_evict_sysmem(struct wined3d_surface *surface) + { + /* In some conditions the surface memory must not be freed: +@@ -1064,7 +989,7 @@ static void surface_unload(struct wined3d_resource *resource) + } + else + { +- surface_prepare_map_memory(surface); ++ wined3d_resource_prepare_map_memory(&surface->resource, context); + wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); + wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); + } +@@ -1999,7 +1924,7 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, + + if (!valid_location) + { +- surface_prepare_system_memory(surface); ++ wined3d_resource_prepare_system_memory(&surface->resource); + valid_location = WINED3D_LOCATION_SYSMEM; + } + +@@ -2556,7 +2481,7 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, + if (device->d3d_initialized) + context = context_acquire(device, NULL); + +- surface_prepare_map_memory(surface); ++ wined3d_resource_prepare_map_memory(&surface->resource, context); + if (flags & WINED3D_MAP_DISCARD) + { + TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", +@@ -3932,7 +3857,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, + { + /* Performance warning... */ + FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface); +- surface_prepare_map_memory(surface); ++ wined3d_resource_prepare_map_memory(&surface->resource, context); + wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); + } + } +@@ -3943,7 +3868,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, + { + /* Performance warning... */ + FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface); +- surface_prepare_map_memory(surface); ++ wined3d_resource_prepare_map_memory(&surface->resource, context); + wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); + } + } +@@ -3952,7 +3877,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, + { + WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); + /* Lets hope we get it from somewhere... */ +- surface_prepare_system_memory(surface); ++ wined3d_resource_prepare_system_memory(&surface->resource); + wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_SYSMEM); + } + +@@ -3978,7 +3903,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, + else + surface->resource.map_binding = WINED3D_LOCATION_SYSMEM; + +- surface_prepare_map_memory(surface); ++ wined3d_resource_prepare_map_memory(&surface->resource, context); + wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); + surface_remove_pbo(surface, gl_info); + } +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index 174cea4..746131c 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -772,8 +772,8 @@ static void texture2d_sub_resource_add_dirty_region(struct wined3d_resource *sub + struct wined3d_surface *surface = surface_from_resource(sub_resource); + struct wined3d_context *context; + +- surface_prepare_map_memory(surface); + context = context_acquire(surface->resource.device, NULL); ++ wined3d_resource_prepare_map_memory(&surface->resource, context); + wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); + context_release(context); + wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index b882152..915d529 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2490,7 +2490,6 @@ HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct w + GLenum target, unsigned int level, unsigned int layer, DWORD flags, + struct wined3d_surface **surface) DECLSPEC_HIDDEN; + void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN; +-void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN; + void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, + const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, + BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0029-wined3d-Don-t-delete-the-buffer-in-surface_cleanup.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0029-wined3d-Don-t-delete-the-buffer-in-surface_cleanup.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0029-wined3d-Don-t-delete-the-buffer-in-surface_cleanup.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0029-wined3d-Don-t-delete-the-buffer-in-surface_cleanup.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,29 @@ +From 408f3f44631f7d3b32e936129e380992c5396094 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 21 Jan 2014 16:41:33 +0100 +Subject: wined3d: Don't delete the buffer in surface_cleanup. + +--- + dlls/wined3d/surface.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 48de325..e5edd34 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -56,12 +56,6 @@ static void surface_cleanup(struct wined3d_surface *surface) + context = context_acquire(surface->resource.device, NULL); + gl_info = context->gl_info; + +- if (surface->resource.buffer_object) +- { +- TRACE("Deleting PBO %u.\n", surface->resource.buffer_object); +- GL_EXTCALL(glDeleteBuffers(1, &surface->resource.buffer_object)); +- } +- + if (surface->rb_multisample) + { + TRACE("Deleting multisample renderbuffer %u.\n", surface->rb_multisample); +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0029-wined3d-Replace-surface-alloc-functions-with-resourc.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0029-wined3d-Replace-surface-alloc-functions-with-resourc.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0029-wined3d-Replace-surface-alloc-functions-with-resourc.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0029-wined3d-Replace-surface-alloc-functions-with-resourc.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ -From 4345b09b18121021362ea09caa4232d1b97bcf37 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 21 Jan 2014 16:40:56 +0100 -Subject: wined3d: Replace surface alloc functions with resource ones. - ---- - dlls/wined3d/resource.c | 10 +++++ - dlls/wined3d/surface.c | 89 ++++-------------------------------------- - dlls/wined3d/texture.c | 5 +-- - dlls/wined3d/wined3d_private.h | 1 - - 4 files changed, 19 insertions(+), 86 deletions(-) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 9b87d6b..1da4da5 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -610,6 +610,16 @@ BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource, stru - case WINED3D_LOCATION_SYSMEM: - return wined3d_resource_prepare_system_memory(resource); - -+ case WINED3D_LOCATION_USER_MEMORY: -+ if (!resource->user_memory) -+ ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but resource->user_memory is NULL.\n"); -+ return TRUE; -+ -+ case WINED3D_LOCATION_DIB: -+ if (!resource->bitmap_data) -+ ERR("Map binding is set to WINED3D_LOCATION_DIB but resource->bitmap_data is NULL.\n"); -+ return TRUE; -+ - default: - ERR("Unexpected map binding %s.\n", wined3d_debug_location(resource->map_binding)); - return FALSE; -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 3bcf0ab..0a908b1 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -478,81 +478,6 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface) - return WINED3D_OK; - } - --static void surface_prepare_buffer(struct wined3d_surface *surface) --{ -- struct wined3d_context *context; -- GLenum error; -- const struct wined3d_gl_info *gl_info; -- -- if (surface->resource.buffer_object) -- return; -- -- context = context_acquire(surface->resource.device, NULL); -- gl_info = context->gl_info; -- -- GL_EXTCALL(glGenBuffers(1, &surface->resource.buffer_object)); -- error = gl_info->gl_ops.gl.p_glGetError(); -- if (!surface->resource.buffer_object || error != GL_NO_ERROR) -- ERR("Failed to create a PBO with error %s (%#x).\n", debug_glerror(error), error); -- -- TRACE("Binding PBO %u.\n", surface->resource.buffer_object); -- -- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->resource.buffer_object)); -- checkGLcall("glBindBuffer"); -- -- GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, surface->resource.size + 4, -- NULL, GL_STREAM_DRAW)); -- checkGLcall("glBufferData"); -- -- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); -- checkGLcall("glBindBuffer"); -- -- context_release(context); --} -- --static void surface_prepare_system_memory(struct wined3d_surface *surface) --{ -- TRACE("surface %p.\n", surface); -- -- if (surface->resource.heap_memory) -- return; -- -- /* Whatever surface we have, make sure that there is memory allocated -- * for the downloaded copy, or a PBO to map. */ -- if (!wined3d_resource_allocate_sysmem(&surface->resource)) -- ERR("Failed to allocate system memory.\n"); -- -- if (surface->resource.locations & WINED3D_LOCATION_SYSMEM) -- ERR("Surface without system memory has WINED3D_LOCATION_SYSMEM set.\n"); --} -- --void surface_prepare_map_memory(struct wined3d_surface *surface) --{ -- switch (surface->resource.map_binding) -- { -- case WINED3D_LOCATION_SYSMEM: -- surface_prepare_system_memory(surface); -- break; -- -- case WINED3D_LOCATION_USER_MEMORY: -- if (!surface->resource.user_memory) -- ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but surface->resource.user_memory is NULL.\n"); -- break; -- -- case WINED3D_LOCATION_DIB: -- if (!surface->resource.bitmap_data) -- ERR("Map binding is set to WINED3D_LOCATION_DIB but surface->resource.bitmap_data is NULL.\n"); -- break; -- -- case WINED3D_LOCATION_BUFFER: -- surface_prepare_buffer(surface); -- break; -- -- default: -- ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); -- } --} -- - static void surface_evict_sysmem(struct wined3d_surface *surface) - { - /* In some conditions the surface memory must not be freed: -@@ -1159,7 +1084,7 @@ static void surface_unload(struct wined3d_resource *resource) - } - else - { -- surface_prepare_map_memory(surface); -+ wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); - } -@@ -2139,7 +2064,7 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, - - if (!valid_location) - { -- surface_prepare_system_memory(surface); -+ wined3d_resource_prepare_system_memory(&surface->resource); - valid_location = WINED3D_LOCATION_SYSMEM; - } - -@@ -2695,7 +2620,7 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, - if (device->d3d_initialized) - context = context_acquire(device, NULL); - -- surface_prepare_map_memory(surface); -+ wined3d_resource_prepare_map_memory(&surface->resource, context); - if (flags & WINED3D_MAP_DISCARD) - { - TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", -@@ -4226,7 +4151,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, - { - /* Performance warning... */ - FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface); -- surface_prepare_map_memory(surface); -+ wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - } - } -@@ -4237,7 +4162,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, - { - /* Performance warning... */ - FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface); -- surface_prepare_map_memory(surface); -+ wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - } - } -@@ -4246,7 +4171,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, - { - WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); - /* Lets hope we get it from somewhere... */ -- surface_prepare_system_memory(surface); -+ wined3d_resource_prepare_system_memory(&surface->resource); - wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_SYSMEM); - } - -@@ -4272,7 +4197,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, - else - surface->resource.map_binding = WINED3D_LOCATION_SYSMEM; - -- surface_prepare_map_memory(surface); -+ wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - surface_remove_pbo(surface, gl_info); - } -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 2ae36ef..8faeefa 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -783,8 +783,8 @@ static void texture2d_sub_resource_add_dirty_region(struct wined3d_resource *sub - struct wined3d_surface *surface = surface_from_resource(sub_resource); - struct wined3d_context *context; - -- surface_prepare_map_memory(surface); - context = context_acquire(surface->resource.device, NULL); -+ wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - context_release(context); - wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); -@@ -896,8 +896,7 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi - } - else - { -- if (!surface->resource.heap_memory) -- wined3d_resource_allocate_sysmem(&surface->resource); -+ wined3d_resource_prepare_system_memory(&surface->resource); - - surface->flags |= SFLAG_CLIENT; - mem = surface->resource.heap_memory; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 4540df1..bbf9128 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2397,7 +2397,6 @@ HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct w - GLenum target, unsigned int level, unsigned int layer, DWORD flags, - struct wined3d_surface **surface) DECLSPEC_HIDDEN; - void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN; --void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN; - void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, - const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, - BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; --- -2.3.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0030-wined3d-Don-t-delete-the-buffer-in-surface_cleanup.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0030-wined3d-Don-t-delete-the-buffer-in-surface_cleanup.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0030-wined3d-Don-t-delete-the-buffer-in-surface_cleanup.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0030-wined3d-Don-t-delete-the-buffer-in-surface_cleanup.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -From 408f3f44631f7d3b32e936129e380992c5396094 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 21 Jan 2014 16:41:33 +0100 -Subject: wined3d: Don't delete the buffer in surface_cleanup. - ---- - dlls/wined3d/surface.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 48de325..e5edd34 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -56,12 +56,6 @@ static void surface_cleanup(struct wined3d_surface *surface) - context = context_acquire(surface->resource.device, NULL); - gl_info = context->gl_info; - -- if (surface->resource.buffer_object) -- { -- TRACE("Deleting PBO %u.\n", surface->resource.buffer_object); -- GL_EXTCALL(glDeleteBuffers(1, &surface->resource.buffer_object)); -- } -- - if (surface->rb_multisample) - { - TRACE("Deleting multisample renderbuffer %u.\n", surface->rb_multisample); --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0030-wined3d-Use-resource-facilities-to-destroy-PBOs.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0030-wined3d-Use-resource-facilities-to-destroy-PBOs.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0030-wined3d-Use-resource-facilities-to-destroy-PBOs.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0030-wined3d-Use-resource-facilities-to-destroy-PBOs.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,81 @@ +From 1ad9f7310d40524027fbb81d998bf8eb1a5dd067 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 21 Jan 2014 16:49:21 +0100 +Subject: wined3d: Use resource facilities to destroy PBOs. + +--- + dlls/wined3d/resource.c | 2 +- + dlls/wined3d/surface.c | 17 ++--------------- + dlls/wined3d/wined3d_private.h | 1 + + 3 files changed, 4 insertions(+), 16 deletions(-) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 2ad66de..362da3d 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -233,7 +233,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * + return WINED3D_OK; + } + +-static void wined3d_resource_free_bo(struct wined3d_resource *resource) ++void wined3d_resource_free_bo(struct wined3d_resource *resource) + { + struct wined3d_context *context = context_acquire(resource->device, NULL); + const struct wined3d_gl_info *gl_info = context->gl_info; +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 91f1229..83c5ad4 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -939,16 +939,6 @@ static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, DW + return WINED3D_OK; + } + +-/* Context activation is done by the caller. */ +-static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) +-{ +- GL_EXTCALL(glDeleteBuffers(1, &surface->resource.buffer_object)); +- checkGLcall("glDeleteBuffers(1, &surface->resource.buffer_object)"); +- +- surface->resource.buffer_object = 0; +- wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_BUFFER); +-} +- + static ULONG surface_resource_incref(struct wined3d_resource *resource) + { + struct wined3d_surface *surface = surface_from_resource(resource); +@@ -996,10 +986,6 @@ static void surface_unload(struct wined3d_resource *resource) + wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); + } + +- /* Destroy PBOs, but load them into real sysmem before */ +- if (surface->resource.buffer_object) +- surface_remove_pbo(surface, gl_info); +- + /* Destroy fbo render buffers. This is needed for implicit render targets, for + * all application-created targets the application has to release the surface + * before calling _Reset +@@ -3918,7 +3904,8 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, + + wined3d_resource_prepare_map_memory(&surface->resource, context); + wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); +- surface_remove_pbo(surface, gl_info); ++ wined3d_resource_free_bo(&surface->resource); ++ wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_BUFFER); + } + + wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &data); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 8864b3b..9813d84 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2261,6 +2261,7 @@ DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; + BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, + const struct wined3d_box *box) DECLSPEC_HIDDEN; ++void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, + const struct wined3d_context *context, DWORD flags) DECLSPEC_HIDDEN; +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0031-wined3d-Move-simple-location-copying-to-the-resource.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0031-wined3d-Move-simple-location-copying-to-the-resource.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0031-wined3d-Move-simple-location-copying-to-the-resource.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0031-wined3d-Move-simple-location-copying-to-the-resource.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,158 @@ +From ff992d330fdc3184bdfdf2daf55b87cc49235587 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 21 Jan 2014 16:58:08 +0100 +Subject: wined3d: Move simple location copying to the resource. + +--- + dlls/wined3d/resource.c | 38 ++++++++++++++++++++++++++++++++++++ + dlls/wined3d/surface.c | 51 ++++--------------------------------------------- + 2 files changed, 42 insertions(+), 47 deletions(-) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 9783b78..939377f 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -454,6 +454,38 @@ void wined3d_resource_get_memory(const struct wined3d_resource *resource, + } + + /* Context activation is optionally by the caller. Context may be NULL. */ ++static void wined3d_resource_copy_simple_location(struct wined3d_resource *resource, ++ struct wined3d_context *context, DWORD location) ++{ ++ const struct wined3d_gl_info *gl_info; ++ struct wined3d_bo_address dst, src; ++ UINT size = resource->size; ++ ++ wined3d_resource_get_memory(resource, location, &dst); ++ wined3d_resource_get_memory(resource, resource->locations, &src); ++ ++ if (dst.buffer_object) ++ { ++ gl_info = context->gl_info; ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); ++ GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); ++ checkGLcall("Upload PBO"); ++ return; ++ } ++ if (src.buffer_object) ++ { ++ gl_info = context->gl_info; ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); ++ GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); ++ checkGLcall("Download PBO"); ++ return; ++ } ++ memcpy(dst.addr, src.addr, size); ++} ++ ++/* Context activation is optionally by the caller. Context may be NULL. */ + void wined3d_resource_load_location(struct wined3d_resource *resource, + struct wined3d_context *context, DWORD location) + { +@@ -480,6 +512,12 @@ void wined3d_resource_load_location(struct wined3d_resource *resource, + resource->locations |= location; + return; + } ++ if (resource->locations & simple_locations) ++ { ++ wined3d_resource_copy_simple_location(resource, context, location); ++ resource->locations |= location; ++ return; ++ } + } + + /* Context is NULL in ddraw-only operation without OpenGL. */ +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index b197655..b620b02 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -36,10 +36,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); + + #define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */ + +-static const DWORD surface_simple_locations = +- WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY +- | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER; +- + static void surface_cleanup(struct wined3d_surface *surface) + { + struct wined3d_surface *overlay, *cur; +@@ -3986,54 +3982,12 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co + surface->ds_current_size.cy = surface->resource.height; + } + +-static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD location) +-{ +- struct wined3d_device *device = surface->resource.device; +- struct wined3d_context *context; +- const struct wined3d_gl_info *gl_info; +- struct wined3d_bo_address dst, src; +- UINT size = surface->resource.size; +- +- wined3d_resource_get_memory(&surface->resource, location, &dst); +- wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &src); +- +- if (dst.buffer_object) +- { +- context = context_acquire(device, NULL); +- gl_info = context->gl_info; +- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); +- GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); +- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); +- checkGLcall("Upload PBO"); +- context_release(context); +- return; +- } +- if (src.buffer_object) +- { +- context = context_acquire(device, NULL); +- gl_info = context->gl_info; +- GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); +- GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); +- GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); +- checkGLcall("Download PBO"); +- context_release(context); +- return; +- } +- memcpy(dst.addr, src.addr, size); +-} +- + /* Context activation is done by the caller. */ + static void surface_load_sysmem(struct wined3d_surface *surface, + struct wined3d_context *context, DWORD dst_location) + { + const struct wined3d_gl_info *gl_info = context->gl_info; + +- if (surface->resource.locations & surface_simple_locations) +- { +- surface_copy_simple_location(surface, dst_location); +- return; +- } +- + if (surface->resource.locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) + wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); + +@@ -4097,6 +4051,9 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, + struct wined3d_format format; + POINT dst_point = {0, 0}; + BYTE *mem = NULL; ++ const DWORD simple_locations = ++ WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY ++ | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER; + + if (surface->resource.locations & WINED3D_LOCATION_DISCARDED) + { +@@ -4172,7 +4129,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, + } + } + +- if (!(surface->resource.locations & surface_simple_locations)) ++ if (!(surface->resource.locations & simple_locations)) + { + WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); + /* Lets hope we get it from somewhere... */ +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0031-wined3d-Use-resource-facilities-to-destroy-PBOs.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0031-wined3d-Use-resource-facilities-to-destroy-PBOs.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0031-wined3d-Use-resource-facilities-to-destroy-PBOs.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0031-wined3d-Use-resource-facilities-to-destroy-PBOs.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -From 42b6ba4bb832d0191cda985e2701c61626c103b6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 21 Jan 2014 16:49:21 +0100 -Subject: wined3d: Use resource facilities to destroy PBOs. - ---- - dlls/wined3d/resource.c | 2 +- - dlls/wined3d/surface.c | 17 ++--------------- - dlls/wined3d/wined3d_private.h | 1 + - 3 files changed, 4 insertions(+), 16 deletions(-) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 882491c..e10ba41 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -223,7 +223,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * - return WINED3D_OK; - } - --static void wined3d_resource_free_bo(struct wined3d_resource *resource) -+void wined3d_resource_free_bo(struct wined3d_resource *resource) - { - struct wined3d_context *context = context_acquire(resource->device, NULL); - const struct wined3d_gl_info *gl_info = context->gl_info; -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 273da13..8ae36af 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -958,16 +958,6 @@ static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, DW - return WINED3D_OK; - } - --/* Context activation is done by the caller. */ --static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) --{ -- GL_EXTCALL(glDeleteBuffers(1, &surface->resource.buffer_object)); -- checkGLcall("glDeleteBuffers(1, &surface->resource.buffer_object)"); -- -- surface->resource.buffer_object = 0; -- wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_BUFFER); --} -- - static ULONG surface_resource_incref(struct wined3d_resource *resource) - { - return wined3d_surface_incref(surface_from_resource(resource)); -@@ -1013,10 +1003,6 @@ static void surface_unload(struct wined3d_resource *resource) - wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); - } - -- /* Destroy PBOs, but load them into real sysmem before */ -- if (surface->resource.buffer_object) -- surface_remove_pbo(surface, gl_info); -- - /* Destroy fbo render buffers. This is needed for implicit render targets, for - * all application-created targets the application has to release the surface - * before calling _Reset -@@ -3949,7 +3935,8 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, - - wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); -- surface_remove_pbo(surface, gl_info); -+ wined3d_resource_free_bo(&surface->resource); -+ wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_BUFFER); - } - - wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &data); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 4fd8b62..50fc36b 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2216,6 +2216,7 @@ DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; - BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, - const struct wined3d_box *box) DECLSPEC_HIDDEN; -+void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, - const struct wined3d_context *context, DWORD flags) DECLSPEC_HIDDEN; --- -2.6.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0032-wined3d-Move-most-of-volume_map-to-resource.c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0032-wined3d-Move-most-of-volume_map-to-resource.c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0032-wined3d-Move-most-of-volume_map-to-resource.c.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0032-wined3d-Move-most-of-volume_map-to-resource.c.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,285 @@ +From 50d846247350c8fbc9823769337016e6f800064e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 19 Sep 2013 17:51:38 +0200 +Subject: wined3d: Move most of volume_map to resource.c + +The CPU access check can be moved once surfaces don't have to lock for +sysmem blits. Surfaces and volume have different block alignment and +boundary check behaviours. +--- + dlls/wined3d/resource.c | 111 +++++++++++++++++++++++++++++++++++++++++ + dlls/wined3d/volume.c | 97 +++-------------------------------- + dlls/wined3d/wined3d_private.h | 3 ++ + 3 files changed, 120 insertions(+), 91 deletions(-) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 2a73c0e..a08631f 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -791,3 +791,114 @@ BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, + + return TRUE; + } ++ ++HRESULT wined3d_resource_map(struct wined3d_resource *resource, ++ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) ++{ ++ struct wined3d_device *device = resource->device; ++ struct wined3d_context *context = NULL; ++ BYTE *base_memory; ++ const struct wined3d_format *format = resource->format; ++ const unsigned int fmt_flags = resource->format->flags[WINED3D_GL_RES_TYPE_TEX_2D]; ++ ++ TRACE("resource %p, map_desc %p, box %s, flags %#x.\n", ++ resource, map_desc, debug_box(box), flags); ++ ++ if (resource->map_count) ++ { ++ WARN("Volume is already mapped.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ flags = wined3d_resource_sanitize_map_flags(resource, flags); ++ ++ if (device->d3d_initialized) ++ context = context_acquire(device, NULL); ++ ++ if (!wined3d_resource_prepare_map_memory(resource, context)) ++ { ++ WARN("Out of memory.\n"); ++ map_desc->data = NULL; ++ context_release(context); ++ return E_OUTOFMEMORY; ++ } ++ ++ if (flags & WINED3D_MAP_DISCARD) ++ wined3d_resource_validate_location(resource, resource->map_binding); ++ else ++ wined3d_resource_load_location(resource, context, resource->map_binding); ++ ++ base_memory = wined3d_resource_get_map_ptr(resource, context, flags); ++ ++ if (context) ++ context_release(context); ++ ++ TRACE("Base memory pointer %p.\n", base_memory); ++ ++ if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) ++ { ++ map_desc->row_pitch = resource->width * format->byte_count; ++ map_desc->slice_pitch = map_desc->row_pitch * resource->height; ++ } ++ else ++ { ++ wined3d_resource_get_pitch(resource, &map_desc->row_pitch, &map_desc->slice_pitch); ++ } ++ ++ if (!box) ++ { ++ map_desc->data = base_memory; ++ } ++ else ++ { ++ if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) ++ { ++ /* Compressed textures are block based, so calculate the offset of ++ * the block that contains the top-left pixel of the locked rectangle. */ ++ map_desc->data = base_memory ++ + (box->front * map_desc->slice_pitch) ++ + ((box->top / format->block_height) * map_desc->row_pitch) ++ + ((box->left / format->block_width) * format->block_byte_count); ++ } ++ else ++ { ++ map_desc->data = base_memory ++ + (map_desc->slice_pitch * box->front) ++ + (map_desc->row_pitch * box->top) ++ + (box->left * format->byte_count); ++ } ++ } ++ ++ if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) ++ wined3d_resource_invalidate_location(resource, ~resource->map_binding); ++ ++ resource->map_count++; ++ ++ TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n", ++ map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); ++ ++ return WINED3D_OK; ++} ++ ++HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) ++{ ++ struct wined3d_device *device = resource->device; ++ struct wined3d_context *context = NULL; ++ TRACE("resource %p.\n", resource); ++ ++ if (!resource->map_count) ++ { ++ WARN("Trying to unlock an unlocked resource %p.\n", resource); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ if (device->d3d_initialized) ++ context = context_acquire(device, NULL); ++ wined3d_resource_release_map_ptr(resource, context); ++ if (context) ++ context_release(context); ++ ++ resource->map_count--; ++ ++ return WINED3D_OK; ++} +diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c +index e598e1b..925c833 100644 +--- a/dlls/wined3d/volume.c ++++ b/dlls/wined3d/volume.c +@@ -368,26 +368,16 @@ static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *vol + HRESULT wined3d_volume_map(struct wined3d_volume *volume, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) + { +- struct wined3d_device *device = volume->resource.device; +- struct wined3d_context *context; +- BYTE *base_memory; ++ HRESULT hr; + const struct wined3d_format *format = volume->resource.format; + const unsigned int fmt_flags = volume->container->resource.format_flags; + +- TRACE("volume %p, map_desc %p, box %s, flags %#x.\n", +- volume, map_desc, debug_box(box), flags); +- + map_desc->data = NULL; + if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) + { + WARN("Volume %p is not CPU accessible.\n", volume); + return WINED3DERR_INVALIDCALL; + } +- if (volume->resource.map_count) +- { +- WARN("Volume is already mapped.\n"); +- return WINED3DERR_INVALIDCALL; +- } + if (!wined3d_volume_check_box_dimensions(volume, box)) + { + WARN("Map box is invalid.\n"); +@@ -400,91 +390,16 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, + return WINED3DERR_INVALIDCALL; + } + +- flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags); +- +- context = context_acquire(device, NULL); +- if (!wined3d_resource_prepare_map_memory(&volume->resource, context)) +- { +- WARN("Out of memory.\n"); +- map_desc->data = NULL; +- context_release(context); +- return E_OUTOFMEMORY; +- } +- +- if (flags & WINED3D_MAP_DISCARD) +- wined3d_resource_validate_location(&volume->resource, volume->resource.map_binding); +- else +- wined3d_resource_load_location(&volume->resource, context, volume->resource.map_binding); +- +- base_memory = wined3d_resource_get_map_ptr(&volume->resource, context, flags); +- context_release(context); +- +- TRACE("Base memory pointer %p.\n", base_memory); +- +- if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) +- { +- map_desc->row_pitch = volume->resource.width * format->byte_count; +- map_desc->slice_pitch = map_desc->row_pitch * volume->resource.height; +- } +- else +- { +- wined3d_resource_get_pitch(&volume->resource, &map_desc->row_pitch, &map_desc->slice_pitch); +- } +- +- if (!box) +- { +- map_desc->data = base_memory; +- } +- else +- { +- if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) +- { +- /* Compressed textures are block based, so calculate the offset of +- * the block that contains the top-left pixel of the locked rectangle. */ +- map_desc->data = base_memory +- + (box->front * map_desc->slice_pitch) +- + ((box->top / format->block_height) * map_desc->row_pitch) +- + ((box->left / format->block_width) * format->block_byte_count); +- } +- else +- { +- map_desc->data = base_memory +- + (map_desc->slice_pitch * box->front) +- + (map_desc->row_pitch * box->top) +- + (box->left * volume->resource.format->byte_count); +- } +- } +- +- if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) +- wined3d_resource_invalidate_location(&volume->resource, ~volume->resource.map_binding); +- +- volume->resource.map_count++; +- +- TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n", +- map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); ++ hr = wined3d_resource_map(&volume->resource, map_desc, box, flags); ++ if (FAILED(hr)) ++ return hr; + +- return WINED3D_OK; ++ return hr; + } + + HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) + { +- struct wined3d_device *device = volume->resource.device; +- struct wined3d_context *context; +- TRACE("volume %p.\n", volume); +- +- if (!volume->resource.map_count) +- { +- WARN("Trying to unlock an unlocked volume %p.\n", volume); +- return WINED3DERR_INVALIDCALL; +- } +- +- context = context_acquire(device, NULL); +- wined3d_resource_release_map_ptr(&volume->resource, context); +- context_release(context); +- +- volume->resource.map_count--; +- +- return WINED3D_OK; ++ return wined3d_resource_unmap(&volume->resource); + } + + static ULONG volume_resource_incref(struct wined3d_resource *resource) +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 647abec..4fc4784 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2323,12 +2323,15 @@ void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWO + BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_load_location(struct wined3d_resource *resource, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; ++HRESULT wined3d_resource_map(struct wined3d_resource *resource, struct wined3d_map_desc *map_desc, ++ const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; + BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource, + struct wined3d_context *context) DECLSPEC_HIDDEN; + BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, + const struct wined3d_context *context) DECLSPEC_HIDDEN; + DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; ++HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_validate_location(struct wined3d_resource *resource, DWORD location) DECLSPEC_HIDDEN; + +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0032-wined3d-Move-simple-location-copying-to-the-resource.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0032-wined3d-Move-simple-location-copying-to-the-resource.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0032-wined3d-Move-simple-location-copying-to-the-resource.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0032-wined3d-Move-simple-location-copying-to-the-resource.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,158 +0,0 @@ -From ff992d330fdc3184bdfdf2daf55b87cc49235587 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 21 Jan 2014 16:58:08 +0100 -Subject: wined3d: Move simple location copying to the resource. - ---- - dlls/wined3d/resource.c | 38 ++++++++++++++++++++++++++++++++++++ - dlls/wined3d/surface.c | 51 ++++--------------------------------------------- - 2 files changed, 42 insertions(+), 47 deletions(-) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 9783b78..939377f 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -454,6 +454,38 @@ void wined3d_resource_get_memory(const struct wined3d_resource *resource, - } - - /* Context activation is optionally by the caller. Context may be NULL. */ -+static void wined3d_resource_copy_simple_location(struct wined3d_resource *resource, -+ struct wined3d_context *context, DWORD location) -+{ -+ const struct wined3d_gl_info *gl_info; -+ struct wined3d_bo_address dst, src; -+ UINT size = resource->size; -+ -+ wined3d_resource_get_memory(resource, location, &dst); -+ wined3d_resource_get_memory(resource, resource->locations, &src); -+ -+ if (dst.buffer_object) -+ { -+ gl_info = context->gl_info; -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); -+ GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); -+ checkGLcall("Upload PBO"); -+ return; -+ } -+ if (src.buffer_object) -+ { -+ gl_info = context->gl_info; -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); -+ GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); -+ checkGLcall("Download PBO"); -+ return; -+ } -+ memcpy(dst.addr, src.addr, size); -+} -+ -+/* Context activation is optionally by the caller. Context may be NULL. */ - void wined3d_resource_load_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) - { -@@ -480,6 +512,12 @@ void wined3d_resource_load_location(struct wined3d_resource *resource, - resource->locations |= location; - return; - } -+ if (resource->locations & simple_locations) -+ { -+ wined3d_resource_copy_simple_location(resource, context, location); -+ resource->locations |= location; -+ return; -+ } - } - - /* Context is NULL in ddraw-only operation without OpenGL. */ -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index b197655..b620b02 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -36,10 +36,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); - - #define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */ - --static const DWORD surface_simple_locations = -- WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY -- | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER; -- - static void surface_cleanup(struct wined3d_surface *surface) - { - struct wined3d_surface *overlay, *cur; -@@ -3986,54 +3982,12 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co - surface->ds_current_size.cy = surface->resource.height; - } - --static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD location) --{ -- struct wined3d_device *device = surface->resource.device; -- struct wined3d_context *context; -- const struct wined3d_gl_info *gl_info; -- struct wined3d_bo_address dst, src; -- UINT size = surface->resource.size; -- -- wined3d_resource_get_memory(&surface->resource, location, &dst); -- wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &src); -- -- if (dst.buffer_object) -- { -- context = context_acquire(device, NULL); -- gl_info = context->gl_info; -- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); -- GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); -- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); -- checkGLcall("Upload PBO"); -- context_release(context); -- return; -- } -- if (src.buffer_object) -- { -- context = context_acquire(device, NULL); -- gl_info = context->gl_info; -- GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); -- GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); -- GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); -- checkGLcall("Download PBO"); -- context_release(context); -- return; -- } -- memcpy(dst.addr, src.addr, size); --} -- - /* Context activation is done by the caller. */ - static void surface_load_sysmem(struct wined3d_surface *surface, - struct wined3d_context *context, DWORD dst_location) - { - const struct wined3d_gl_info *gl_info = context->gl_info; - -- if (surface->resource.locations & surface_simple_locations) -- { -- surface_copy_simple_location(surface, dst_location); -- return; -- } -- - if (surface->resource.locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) - wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); - -@@ -4097,6 +4051,9 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, - struct wined3d_format format; - POINT dst_point = {0, 0}; - BYTE *mem = NULL; -+ const DWORD simple_locations = -+ WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY -+ | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER; - - if (surface->resource.locations & WINED3D_LOCATION_DISCARDED) - { -@@ -4172,7 +4129,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, - } - } - -- if (!(surface->resource.locations & surface_simple_locations)) -+ if (!(surface->resource.locations & simple_locations)) - { - WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); - /* Lets hope we get it from somewhere... */ --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0033-wined3d-Move-most-of-volume_map-to-resource.c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0033-wined3d-Move-most-of-volume_map-to-resource.c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0033-wined3d-Move-most-of-volume_map-to-resource.c.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0033-wined3d-Move-most-of-volume_map-to-resource.c.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,293 +0,0 @@ -From fe66d6b8129533d88849527339ca52a19e343509 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 19 Sep 2013 17:51:38 +0200 -Subject: wined3d: Move most of volume_map to resource.c - -The CPU access check can be moved once surfaces don't have to lock for -sysmem blits. Surfaces and volume have different block alignment and -boundary check behaviours. ---- - dlls/wined3d/resource.c | 115 +++++++++++++++++++++++++++++++++++++++++ - dlls/wined3d/volume.c | 101 +++--------------------------------- - dlls/wined3d/wined3d_private.h | 3 ++ - 3 files changed, 124 insertions(+), 95 deletions(-) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 2e06f21..e5af445 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -765,3 +765,118 @@ BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, - - return TRUE; - } -+ -+HRESULT wined3d_resource_map(struct wined3d_resource *resource, -+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -+{ -+ struct wined3d_device *device = resource->device; -+ struct wined3d_context *context = NULL; -+ BYTE *base_memory; -+ const struct wined3d_format *format = resource->format; -+ const unsigned int fmt_flags = resource->format->flags[WINED3D_GL_RES_TYPE_TEX_2D]; -+ -+ TRACE("resource %p, map_desc %p, box %p, flags %#x.\n", -+ resource, map_desc, box, flags); -+ -+ if (resource->map_count) -+ { -+ WARN("Volume is already mapped.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ flags = wined3d_resource_sanitize_map_flags(resource, flags); -+ -+ if (device->d3d_initialized) -+ context = context_acquire(device, NULL); -+ -+ if (!wined3d_resource_prepare_map_memory(resource, context)) -+ { -+ WARN("Out of memory.\n"); -+ map_desc->data = NULL; -+ context_release(context); -+ return E_OUTOFMEMORY; -+ } -+ -+ if (flags & WINED3D_MAP_DISCARD) -+ wined3d_resource_validate_location(resource, resource->map_binding); -+ else -+ wined3d_resource_load_location(resource, context, resource->map_binding); -+ -+ base_memory = wined3d_resource_get_map_ptr(resource, context, flags); -+ -+ if (context) -+ context_release(context); -+ -+ TRACE("Base memory pointer %p.\n", base_memory); -+ -+ if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) -+ { -+ map_desc->row_pitch = resource->width * format->byte_count; -+ map_desc->slice_pitch = map_desc->row_pitch * resource->height; -+ } -+ else -+ { -+ wined3d_resource_get_pitch(resource, &map_desc->row_pitch, &map_desc->slice_pitch); -+ } -+ -+ if (!box) -+ { -+ TRACE("No box supplied - all is ok\n"); -+ map_desc->data = base_memory; -+ } -+ else -+ { -+ TRACE("Lock Box (%p) = l %u, t %u, r %u, b %u, fr %u, ba %u\n", -+ box, box->left, box->top, box->right, box->bottom, box->front, box->back); -+ -+ if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) -+ { -+ /* Compressed textures are block based, so calculate the offset of -+ * the block that contains the top-left pixel of the locked rectangle. */ -+ map_desc->data = base_memory -+ + (box->front * map_desc->slice_pitch) -+ + ((box->top / format->block_height) * map_desc->row_pitch) -+ + ((box->left / format->block_width) * format->block_byte_count); -+ } -+ else -+ { -+ map_desc->data = base_memory -+ + (map_desc->slice_pitch * box->front) -+ + (map_desc->row_pitch * box->top) -+ + (box->left * format->byte_count); -+ } -+ } -+ -+ if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) -+ wined3d_resource_invalidate_location(resource, ~resource->map_binding); -+ -+ resource->map_count++; -+ -+ TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n", -+ map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); -+ -+ return WINED3D_OK; -+} -+ -+HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) -+{ -+ struct wined3d_device *device = resource->device; -+ struct wined3d_context *context = NULL; -+ TRACE("resource %p.\n", resource); -+ -+ if (!resource->map_count) -+ { -+ WARN("Trying to unlock an unlocked resource %p.\n", resource); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ if (device->d3d_initialized) -+ context = context_acquire(device, NULL); -+ wined3d_resource_release_map_ptr(resource, context); -+ if (context) -+ context_release(context); -+ -+ resource->map_count--; -+ -+ return WINED3D_OK; -+} -diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index 38fe516..08dbecb 100644 ---- a/dlls/wined3d/volume.c -+++ b/dlls/wined3d/volume.c -@@ -392,26 +392,16 @@ static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *vol - HRESULT wined3d_volume_map(struct wined3d_volume *volume, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) - { -- struct wined3d_device *device = volume->resource.device; -- struct wined3d_context *context; -- BYTE *base_memory; -+ HRESULT hr; - const struct wined3d_format *format = volume->resource.format; - const unsigned int fmt_flags = volume->container->resource.format_flags; - -- TRACE("volume %p, map_desc %p, box %p, flags %#x.\n", -- volume, map_desc, box, flags); -- - map_desc->data = NULL; - if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) - { - WARN("Volume %p is not CPU accessible.\n", volume); - return WINED3DERR_INVALIDCALL; - } -- if (volume->resource.map_count) -- { -- WARN("Volume is already mapped.\n"); -- return WINED3DERR_INVALIDCALL; -- } - if (!wined3d_volume_check_box_dimensions(volume, box)) - { - WARN("Map box is invalid.\n"); -@@ -424,95 +414,16 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, - return WINED3DERR_INVALIDCALL; - } - -- flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags); -- -- context = context_acquire(device, NULL); -- if (!wined3d_resource_prepare_map_memory(&volume->resource, context)) -- { -- WARN("Out of memory.\n"); -- map_desc->data = NULL; -- context_release(context); -- return E_OUTOFMEMORY; -- } -- -- if (flags & WINED3D_MAP_DISCARD) -- wined3d_resource_validate_location(&volume->resource, volume->resource.map_binding); -- else -- wined3d_resource_load_location(&volume->resource, context, volume->resource.map_binding); -- -- base_memory = wined3d_resource_get_map_ptr(&volume->resource, context, flags); -- context_release(context); -- -- TRACE("Base memory pointer %p.\n", base_memory); -- -- if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) -- { -- map_desc->row_pitch = volume->resource.width * format->byte_count; -- map_desc->slice_pitch = map_desc->row_pitch * volume->resource.height; -- } -- else -- { -- wined3d_resource_get_pitch(&volume->resource, &map_desc->row_pitch, &map_desc->slice_pitch); -- } -- -- if (!box) -- { -- TRACE("No box supplied - all is ok\n"); -- map_desc->data = base_memory; -- } -- else -- { -- TRACE("Lock Box (%p) = l %u, t %u, r %u, b %u, fr %u, ba %u\n", -- box, box->left, box->top, box->right, box->bottom, box->front, box->back); -- -- if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) -- { -- /* Compressed textures are block based, so calculate the offset of -- * the block that contains the top-left pixel of the locked rectangle. */ -- map_desc->data = base_memory -- + (box->front * map_desc->slice_pitch) -- + ((box->top / format->block_height) * map_desc->row_pitch) -- + ((box->left / format->block_width) * format->block_byte_count); -- } -- else -- { -- map_desc->data = base_memory -- + (map_desc->slice_pitch * box->front) -- + (map_desc->row_pitch * box->top) -- + (box->left * volume->resource.format->byte_count); -- } -- } -- -- if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) -- wined3d_resource_invalidate_location(&volume->resource, ~volume->resource.map_binding); -- -- volume->resource.map_count++; -- -- TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n", -- map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); -+ hr = wined3d_resource_map(&volume->resource, map_desc, box, flags); -+ if (FAILED(hr)) -+ return hr; - -- return WINED3D_OK; -+ return hr; - } - - HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) - { -- struct wined3d_device *device = volume->resource.device; -- struct wined3d_context *context; -- TRACE("volume %p.\n", volume); -- -- if (!volume->resource.map_count) -- { -- WARN("Trying to unlock an unlocked volume %p.\n", volume); -- return WINED3DERR_INVALIDCALL; -- } -- -- context = context_acquire(device, NULL); -- wined3d_resource_release_map_ptr(&volume->resource, context); -- context_release(context); -- -- volume->resource.map_count--; -- -- return WINED3D_OK; -+ return wined3d_resource_unmap(&volume->resource); - } - - static ULONG volume_resource_incref(struct wined3d_resource *resource) -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 949b27b..ac6cd4e 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2218,12 +2218,15 @@ void wined3d_resource_invalidate_location(struct wined3d_resource *resource, DWO - BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_load_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -+HRESULT wined3d_resource_map(struct wined3d_resource *resource, struct wined3d_map_desc *map_desc, -+ const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; - BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource, - struct wined3d_context *context) DECLSPEC_HIDDEN; - BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, - const struct wined3d_context *context) DECLSPEC_HIDDEN; - DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; -+HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_validate_location(struct wined3d_resource *resource, DWORD location) DECLSPEC_HIDDEN; - --- -2.6.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0033-wined3d-Use-resource_map-for-surface_map.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0033-wined3d-Use-resource_map-for-surface_map.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0033-wined3d-Use-resource_map-for-surface_map.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0033-wined3d-Use-resource_map-for-surface_map.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,193 @@ +From 90e387618c439a928d4a7cebc299415f4d1e381e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 19 Sep 2013 18:00:23 +0200 +Subject: wined3d: Use resource_map for surface_map. + +--- + dlls/wined3d/resource.c | 2 +- + dlls/wined3d/surface.c | 99 ++++++------------------------------------------- + dlls/wined3d/volume.c | 7 +++- + 3 files changed, 18 insertions(+), 90 deletions(-) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index a08631f..8d372b9 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -889,7 +889,7 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) + if (!resource->map_count) + { + WARN("Trying to unlock an unlocked resource %p.\n", resource); +- return WINED3DERR_INVALIDCALL; ++ return WINEDDERR_NOTLOCKED; + } + + if (device->d3d_initialized) +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 8392614..4d3b47f 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -2381,28 +2381,18 @@ do { \ + + HRESULT wined3d_surface_unmap(struct wined3d_surface *surface) + { +- struct wined3d_device *device = surface->resource.device; +- struct wined3d_context *context = NULL; ++ HRESULT hr; + TRACE("surface %p.\n", surface); + +- if (!surface->resource.map_count) +- { +- WARN("Trying to unmap unmapped surface.\n"); +- return WINEDDERR_NOTLOCKED; +- } +- --surface->resource.map_count; +- +- if (device->d3d_initialized) +- context = context_acquire(device, NULL); +- wined3d_resource_release_map_ptr(&surface->resource, context); +- if (context) +- context_release(context); ++ hr = wined3d_resource_unmap(&surface->resource); ++ if (FAILED(hr)) ++ return hr; + + if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) + surface->surface_ops->surface_frontbuffer_updated(surface); + memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); + +- return WINED3D_OK; ++ return hr; + } + + HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, +@@ -2410,18 +2400,6 @@ HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_ + { + const struct wined3d_format *format = surface->resource.format; + unsigned int fmt_flags = surface->container->resource.format_flags; +- struct wined3d_device *device = surface->resource.device; +- struct wined3d_context *context = NULL; +- BYTE *base_memory; +- +- TRACE("surface %p, map_desc %p, box %s, flags %#x.\n", +- surface, map_desc, debug_box(box), flags); +- +- if (surface->resource.map_count) +- { +- WARN("Surface is already mapped.\n"); +- return WINED3DERR_INVALIDCALL; +- } + + if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box + && !surface_check_block_align(surface, box)) +@@ -2433,11 +2411,6 @@ HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_ + return WINED3DERR_INVALIDCALL; + } + +- ++surface->resource.map_count; +- +- if (!(surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) +- WARN("Trying to lock unlockable surface.\n"); +- + /* Performance optimization: Count how often a surface is mapped, if it is + * mapped regularly do not throw away the system memory copy. This avoids + * the need to download the surface from OpenGL all the time. The surface +@@ -2453,72 +2426,22 @@ HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_ + } + } + +- if (device->d3d_initialized) +- context = context_acquire(device, NULL); +- +- wined3d_resource_prepare_map_memory(&surface->resource, context); +- if (flags & WINED3D_MAP_DISCARD) +- { +- TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", +- wined3d_debug_location(surface->resource.map_binding)); +- wined3d_resource_validate_location(&surface->resource, surface->resource.map_binding); +- } +- else ++ if (box) + { +- if (surface->resource.usage & WINED3DUSAGE_DYNAMIC) +- WARN_(d3d_perf)("Mapping a dynamic surface without WINED3D_MAP_DISCARD.\n"); +- +- wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); ++ surface->lockedRect.left = box->left; ++ surface->lockedRect.top = box->top; ++ surface->lockedRect.right = box->right; ++ surface->lockedRect.bottom = box->bottom; + } +- +- if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) +- wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); +- +- base_memory = wined3d_resource_get_map_ptr(&surface->resource, context, flags); +- +- if (context) +- context_release(context); +- +- if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) +- map_desc->row_pitch = surface->resource.width * format->byte_count; + else +- wined3d_resource_get_pitch(&surface->resource, &map_desc->row_pitch, &map_desc->slice_pitch); +- map_desc->slice_pitch = surface->resource.height * map_desc->row_pitch; +- +- if (!box) + { +- map_desc->data = base_memory; + surface->lockedRect.left = 0; + surface->lockedRect.top = 0; + surface->lockedRect.right = surface->resource.width; + surface->lockedRect.bottom = surface->resource.height; + } +- else +- { +- if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) +- { +- /* Compressed textures are block based, so calculate the offset of +- * the block that contains the top-left pixel of the locked rectangle. */ +- map_desc->data = base_memory +- + ((box->top / format->block_height) * map_desc->row_pitch) +- + ((box->left / format->block_width) * format->block_byte_count); +- } +- else +- { +- map_desc->data = base_memory +- + (map_desc->row_pitch * box->top) +- + (box->left * format->byte_count); +- } +- surface->lockedRect.left = box->left; +- surface->lockedRect.top = box->top; +- surface->lockedRect.right = box->right; +- surface->lockedRect.bottom = box->bottom; +- } +- +- TRACE("Locked rect %s.\n", wine_dbgstr_rect(&surface->lockedRect)); +- TRACE("Returning memory %p, pitch %u.\n", map_desc->data, map_desc->row_pitch); + +- return WINED3D_OK; ++ return wined3d_resource_map(&surface->resource, map_desc, box, flags); + } + + static void read_from_framebuffer(struct wined3d_surface *surface, +diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c +index 925c833..fc43958 100644 +--- a/dlls/wined3d/volume.c ++++ b/dlls/wined3d/volume.c +@@ -399,7 +399,12 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, + + HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) + { +- return wined3d_resource_unmap(&volume->resource); ++ HRESULT hr; ++ ++ hr = wined3d_resource_unmap(&volume->resource); ++ if (hr == WINEDDERR_NOTLOCKED) ++ return WINED3DERR_INVALIDCALL; ++ return hr; + } + + static ULONG volume_resource_incref(struct wined3d_resource *resource) +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0034-wined3d-Don-t-call-the-public-map-function-in-surfac.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0034-wined3d-Don-t-call-the-public-map-function-in-surfac.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0034-wined3d-Don-t-call-the-public-map-function-in-surfac.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0034-wined3d-Don-t-call-the-public-map-function-in-surfac.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,101 @@ +From 89a2597787017d7bc966c2a146fa4c4fc59e9ebb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Mon, 23 Sep 2013 23:58:41 +0200 +Subject: wined3d: Don't call the public map function in + surface_convert_format. + +TODO: Creating a helper surface and releasing it won't work with the CS. +surface_cpu_blt will be called via the CS, so it can't call external +methods that enqueue commands in the stream. +--- + dlls/wined3d/surface.c | 57 +++++++++++++++++++++++++++++++++----------------- + 1 file changed, 38 insertions(+), 19 deletions(-) + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 303a0dc..045ede5 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -2253,11 +2253,14 @@ static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_fo + + static struct wined3d_texture *surface_convert_format(struct wined3d_surface *source, enum wined3d_format_id to_fmt) + { +- struct wined3d_map_desc src_map, dst_map; ++ void *dst_data = NULL, *src_data = NULL; ++ UINT src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; + const struct d3dfmt_converter_desc *conv; + struct wined3d_texture *ret = NULL; + struct wined3d_resource_desc desc; + struct wined3d_surface *dst; ++ struct wined3d_context *context = NULL; ++ struct wined3d_device *device = source->resource.device; + + conv = find_converter(source->resource.format->id, to_fmt); + if (!conv) +@@ -2281,30 +2284,46 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_surface *so + } + dst = surface_from_resource(wined3d_texture_get_sub_resource(ret, 0)); + +- memset(&src_map, 0, sizeof(src_map)); +- memset(&dst_map, 0, sizeof(dst_map)); ++ wined3d_resource_get_pitch(&source->resource, &src_row_pitch, &src_slice_pitch); ++ wined3d_resource_get_pitch(&ret->resource, &dst_row_pitch, &dst_slice_pitch); + +- if (FAILED(wined3d_surface_map(source, &src_map, NULL, WINED3D_MAP_READONLY))) +- { +- ERR("Failed to lock the source surface.\n"); +- wined3d_texture_decref(ret); +- return NULL; +- } +- if (FAILED(wined3d_surface_map(dst, &dst_map, NULL, 0))) +- { +- ERR("Failed to lock the destination surface.\n"); +- wined3d_surface_unmap(source); +- wined3d_texture_decref(ret); +- return NULL; +- } ++ if (device->d3d_initialized) ++ context = context_acquire(device, NULL); ++ ++ wined3d_resource_load_location(&source->resource, context, source->resource.map_binding); ++ src_data = wined3d_resource_get_map_ptr(&source->resource, context, WINED3D_MAP_READONLY); ++ if (!src_data) ++ goto error; + +- conv->convert(src_map.data, dst_map.data, src_map.row_pitch, dst_map.row_pitch, ++ if (!wined3d_resource_prepare_map_memory(&dst->resource, context)) ++ goto error; ++ dst_data = wined3d_resource_get_map_ptr(&dst->resource, context, 0); ++ if (!dst_data) ++ goto error; ++ ++ conv->convert(src_data, dst_data, src_row_pitch, dst_row_pitch, + source->resource.width, source->resource.height); + +- wined3d_surface_unmap(dst); +- wined3d_surface_unmap(source); ++ wined3d_resource_release_map_ptr(&dst->resource, context); ++ wined3d_resource_release_map_ptr(&source->resource, context); ++ ++ if (context) ++ context_release(context); + + return ret; ++ ++error: ++ ERR("Surface conversion failed.\n"); ++ ++ if (src_data) ++ wined3d_resource_release_map_ptr(&source->resource, context); ++ if (dst_data) ++ wined3d_resource_release_map_ptr(&ret->resource, context); ++ if (ret) ++ wined3d_texture_decref(ret); ++ if (context) ++ context_release(context); ++ return NULL; + } + + static HRESULT _Blt_ColorFill(BYTE *buf, unsigned int width, unsigned int height, +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0034-wined3d-Use-resource_map-for-surface_map.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0034-wined3d-Use-resource_map-for-surface_map.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0034-wined3d-Use-resource_map-for-surface_map.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0034-wined3d-Use-resource_map-for-surface_map.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,193 +0,0 @@ -From 4ca448b9c9fb4ed0e94eaa82b98d7677d486a92c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 19 Sep 2013 18:00:23 +0200 -Subject: wined3d: Use resource_map for surface_map. - ---- - dlls/wined3d/resource.c | 2 +- - dlls/wined3d/surface.c | 99 ++++++------------------------------------------- - dlls/wined3d/volume.c | 7 +++- - 3 files changed, 18 insertions(+), 90 deletions(-) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 7743a40..74cb6c1 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -883,7 +883,7 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) - if (!resource->map_count) - { - WARN("Trying to unlock an unlocked resource %p.\n", resource); -- return WINED3DERR_INVALIDCALL; -+ return WINEDDERR_NOTLOCKED; - } - - if (device->d3d_initialized) -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index f00f6c3..3f7f54c 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -2428,28 +2428,18 @@ struct wined3d_surface * CDECL wined3d_surface_from_resource(struct wined3d_reso - - HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface) - { -- struct wined3d_device *device = surface->resource.device; -- struct wined3d_context *context = NULL; -+ HRESULT hr; - TRACE("surface %p.\n", surface); - -- if (!surface->resource.map_count) -- { -- WARN("Trying to unmap unmapped surface.\n"); -- return WINEDDERR_NOTLOCKED; -- } -- --surface->resource.map_count; -- -- if (device->d3d_initialized) -- context = context_acquire(device, NULL); -- wined3d_resource_release_map_ptr(&surface->resource, context); -- if (context) -- context_release(context); -+ hr = wined3d_resource_unmap(&surface->resource); -+ if (FAILED(hr)) -+ return hr; - - if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) - surface->surface_ops->surface_frontbuffer_updated(surface); - memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); - -- return WINED3D_OK; -+ return hr; - } - - HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, -@@ -2457,18 +2447,6 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, - { - const struct wined3d_format *format = surface->resource.format; - unsigned int fmt_flags = surface->container->resource.format_flags; -- struct wined3d_device *device = surface->resource.device; -- struct wined3d_context *context = NULL; -- BYTE *base_memory; -- -- TRACE("surface %p, map_desc %p, box %p, flags %#x.\n", -- surface, map_desc, box, flags); -- -- if (surface->resource.map_count) -- { -- WARN("Surface is already mapped.\n"); -- return WINED3DERR_INVALIDCALL; -- } - - if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box - && !surface_check_block_align(surface, box)) -@@ -2480,11 +2458,6 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, - return WINED3DERR_INVALIDCALL; - } - -- ++surface->resource.map_count; -- -- if (!(surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) -- WARN("Trying to lock unlockable surface.\n"); -- - /* Performance optimization: Count how often a surface is mapped, if it is - * mapped regularly do not throw away the system memory copy. This avoids - * the need to download the surface from OpenGL all the time. The surface -@@ -2500,72 +2473,22 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, - } - } - -- if (device->d3d_initialized) -- context = context_acquire(device, NULL); -- -- wined3d_resource_prepare_map_memory(&surface->resource, context); -- if (flags & WINED3D_MAP_DISCARD) -- { -- TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", -- wined3d_debug_location(surface->resource.map_binding)); -- wined3d_resource_validate_location(&surface->resource, surface->resource.map_binding); -- } -- else -+ if (box) - { -- if (surface->resource.usage & WINED3DUSAGE_DYNAMIC) -- WARN_(d3d_perf)("Mapping a dynamic surface without WINED3D_MAP_DISCARD.\n"); -- -- wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); -+ surface->lockedRect.left = box->left; -+ surface->lockedRect.top = box->top; -+ surface->lockedRect.right = box->right; -+ surface->lockedRect.bottom = box->bottom; - } -- -- if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) -- wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); -- -- base_memory = wined3d_resource_get_map_ptr(&surface->resource, context, flags); -- -- if (context) -- context_release(context); -- -- if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) -- map_desc->row_pitch = surface->resource.width * format->byte_count; - else -- wined3d_resource_get_pitch(&surface->resource, &map_desc->row_pitch, &map_desc->slice_pitch); -- map_desc->slice_pitch = surface->resource.height * map_desc->row_pitch; -- -- if (!box) - { -- map_desc->data = base_memory; - surface->lockedRect.left = 0; - surface->lockedRect.top = 0; - surface->lockedRect.right = surface->resource.width; - surface->lockedRect.bottom = surface->resource.height; - } -- else -- { -- if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) -- { -- /* Compressed textures are block based, so calculate the offset of -- * the block that contains the top-left pixel of the locked rectangle. */ -- map_desc->data = base_memory -- + ((box->top / format->block_height) * map_desc->row_pitch) -- + ((box->left / format->block_width) * format->block_byte_count); -- } -- else -- { -- map_desc->data = base_memory -- + (map_desc->row_pitch * box->top) -- + (box->left * format->byte_count); -- } -- surface->lockedRect.left = box->left; -- surface->lockedRect.top = box->top; -- surface->lockedRect.right = box->right; -- surface->lockedRect.bottom = box->bottom; -- } -- -- TRACE("Locked rect %s.\n", wine_dbgstr_rect(&surface->lockedRect)); -- TRACE("Returning memory %p, pitch %u.\n", map_desc->data, map_desc->row_pitch); - -- return WINED3D_OK; -+ return wined3d_resource_map(&surface->resource, map_desc, box, flags); - } - - HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) -diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index a237bf6..0e97cd1 100644 ---- a/dlls/wined3d/volume.c -+++ b/dlls/wined3d/volume.c -@@ -402,7 +402,12 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, - - HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) - { -- return wined3d_resource_unmap(&volume->resource); -+ HRESULT hr; -+ -+ hr = wined3d_resource_unmap(&volume->resource); -+ if (hr == WINEDDERR_NOTLOCKED) -+ return WINED3DERR_INVALIDCALL; -+ return hr; - } - - static ULONG volume_resource_incref(struct wined3d_resource *resource) --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0035-wined3d-Don-t-call-the-public-map-function-in-surfac.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0035-wined3d-Don-t-call-the-public-map-function-in-surfac.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0035-wined3d-Don-t-call-the-public-map-function-in-surfac.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0035-wined3d-Don-t-call-the-public-map-function-in-surfac.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,282 @@ +From 74de56cff82b598bb71d556767bcd1c53dcb16e2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 24 Sep 2013 00:31:39 +0200 +Subject: wined3d: Don't call the public map function in surface_cpu_blt. + +--- + dlls/wined3d/surface.c | 108 ++++++++++++++++++++++++++++++++----------------- + 1 file changed, 72 insertions(+), 36 deletions(-) + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 5c30f78..a32ce1d 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -4306,26 +4306,40 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * + struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, + const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) + { +- const struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; + int bpp, srcheight, srcwidth, dstheight, dstwidth, width; + const struct wined3d_format *src_format, *dst_format; + unsigned int src_fmt_flags, dst_fmt_flags; + struct wined3d_texture *src_texture = NULL; +- struct wined3d_map_desc dst_map, src_map; ++ void *src_data = NULL, *dst_data = NULL; ++ UINT src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; + const BYTE *sbase = NULL; + HRESULT hr = WINED3D_OK; + const BYTE *sbuf; + BYTE *dbuf; + int x, y; ++ struct wined3d_device *device = dst_surface->resource.device; ++ struct wined3d_context *context = NULL; + + TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", + dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), + flags, fx, debug_d3dtexturefiltertype(filter)); + ++ if (device->d3d_initialized) ++ context = context_acquire(device, NULL); ++ ++ if (!wined3d_resource_prepare_map_memory(&dst_surface->resource, context)) ++ { ++ hr = E_OUTOFMEMORY; ++ goto error; ++ } ++ wined3d_resource_load_location(&dst_surface->resource, context, dst_surface->resource.map_binding); ++ + if (src_surface == dst_surface) + { +- wined3d_surface_map(dst_surface, &dst_map, NULL, 0); +- src_map = dst_map; ++ dst_data = wined3d_resource_get_map_ptr(&dst_surface->resource, context, 0); ++ wined3d_resource_get_pitch(&dst_surface->resource, &dst_row_pitch, &dst_slice_pitch); ++ src_data = dst_data; ++ src_row_pitch = dst_row_pitch; + src_format = dst_surface->resource.format; + dst_format = src_format; + dst_fmt_flags = dst_surface->container->resource.format_flags; +@@ -4337,6 +4351,12 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * + dst_fmt_flags = dst_surface->container->resource.format_flags; + if (src_surface) + { ++ if (!wined3d_resource_prepare_map_memory(&src_surface->resource, context)) ++ { ++ hr = E_OUTOFMEMORY; ++ goto error; ++ } ++ + if (dst_surface->resource.format->id != src_surface->resource.format->id) + { + if (!(src_texture = surface_convert_format(src_surface, dst_format->id))) +@@ -4347,7 +4367,9 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * + } + src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, 0)); + } +- wined3d_surface_map(src_surface, &src_map, NULL, WINED3D_MAP_READONLY); ++ wined3d_resource_load_location(&src_surface->resource, context, src_surface->resource.map_binding); ++ wined3d_resource_get_pitch(&src_surface->resource, &src_row_pitch, &src_slice_pitch); ++ src_data = wined3d_resource_get_map_ptr(&src_surface->resource, context, 0); + src_format = src_surface->resource.format; + src_fmt_flags = src_surface->container->resource.format_flags; + } +@@ -4357,7 +4379,8 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * + src_fmt_flags = dst_fmt_flags; + } + +- wined3d_surface_map(dst_surface, &dst_map, &dst_box, 0); ++ wined3d_resource_get_pitch(&dst_surface->resource, &dst_row_pitch, &dst_slice_pitch); ++ dst_data = wined3d_resource_get_map_ptr(&dst_surface->resource, context, 0); + } + + bpp = dst_surface->resource.format->byte_count; +@@ -4368,15 +4391,12 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * + width = (dst_rect->right - dst_rect->left) * bpp; + + if (src_surface) +- sbase = (BYTE *)src_map.data +- + ((src_rect->top / src_format->block_height) * src_map.row_pitch) ++ sbase = (BYTE *)src_data ++ + ((src_rect->top / src_format->block_height) * src_row_pitch) + + ((src_rect->left / src_format->block_width) * src_format->block_byte_count); +- if (src_surface != dst_surface) +- dbuf = dst_map.data; +- else +- dbuf = (BYTE *)dst_map.data +- + ((dst_rect->top / dst_format->block_height) * dst_map.row_pitch) +- + ((dst_rect->left / dst_format->block_width) * dst_format->block_byte_count); ++ dbuf = (BYTE *)dst_data ++ + ((dst_rect->top / dst_format->block_height) * dst_row_pitch) ++ + ((dst_rect->left / dst_format->block_width) * dst_format->block_byte_count); + + if (src_fmt_flags & dst_fmt_flags & WINED3DFMT_FLAG_BLOCKS) + { +@@ -4411,7 +4431,7 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * + } + + hr = surface_cpu_blt_compressed(sbase, dbuf, +- src_map.row_pitch, dst_map.row_pitch, dstwidth, dstheight, ++ src_row_pitch, dst_row_pitch, dstwidth, dstheight, + src_format, flags, fx); + goto release; + } +@@ -4419,7 +4439,7 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * + /* First, all the 'source-less' blits */ + if (flags & WINEDDBLT_COLORFILL) + { +- hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_map.row_pitch, fx->u5.dwFillColor); ++ hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_row_pitch, fx->u5.dwFillColor); + flags &= ~WINEDDBLT_COLORFILL; + } + +@@ -4468,19 +4488,19 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * + for (y = 0; y < dstheight; ++y) + { + memcpy(dbuf, sbuf, width); +- sbuf += src_map.row_pitch; +- dbuf += dst_map.row_pitch; ++ sbuf += src_row_pitch; ++ dbuf += dst_row_pitch; + } + } + else if (dst_rect->top > src_rect->top) + { + /* Copy from bottom upwards. */ +- sbuf += src_map.row_pitch * dstheight; +- dbuf += dst_map.row_pitch * dstheight; ++ sbuf += src_row_pitch * dstheight; ++ dbuf += dst_row_pitch * dstheight; + for (y = 0; y < dstheight; ++y) + { +- sbuf -= src_map.row_pitch; +- dbuf -= dst_map.row_pitch; ++ sbuf -= src_row_pitch; ++ dbuf -= dst_row_pitch; + memcpy(dbuf, sbuf, width); + } + } +@@ -4490,8 +4510,8 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * + for (y = 0; y < dstheight; ++y) + { + memmove(dbuf, sbuf, width); +- sbuf += src_map.row_pitch; +- dbuf += dst_map.row_pitch; ++ sbuf += src_row_pitch; ++ dbuf += dst_row_pitch; + } + } + } +@@ -4500,9 +4520,9 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * + /* Stretching in y direction only. */ + for (y = sy = 0; y < dstheight; ++y, sy += yinc) + { +- sbuf = sbase + (sy >> 16) * src_map.row_pitch; ++ sbuf = sbase + (sy >> 16) * src_row_pitch; + memcpy(dbuf, sbuf, width); +- dbuf += dst_map.row_pitch; ++ dbuf += dst_row_pitch; + } + } + } +@@ -4512,13 +4532,13 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * + int last_sy = -1; + for (y = sy = 0; y < dstheight; ++y, sy += yinc) + { +- sbuf = sbase + (sy >> 16) * src_map.row_pitch; ++ sbuf = sbase + (sy >> 16) * src_row_pitch; + + if ((sy >> 16) == (last_sy >> 16)) + { + /* This source row is the same as last source row - + * Copy the already stretched row. */ +- memcpy(dbuf, dbuf - dst_map.row_pitch, width); ++ memcpy(dbuf, dbuf - dst_row_pitch, width); + } + else + { +@@ -4565,14 +4585,14 @@ do { \ + } + #undef STRETCH_ROW + } +- dbuf += dst_map.row_pitch; ++ dbuf += dst_row_pitch; + last_sy = sy; + } + } + } + else + { +- LONG dstyinc = dst_map.row_pitch, dstxinc = bpp; ++ LONG dstyinc = dst_row_pitch, dstxinc = bpp; + DWORD keylow = 0xffffffff, keyhigh = 0, keymask = 0xffffffff; + DWORD destkeylow = 0x0, destkeyhigh = 0xffffffff, destkeymask = 0xffffffff; + if (flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYDEST | WINEDDBLT_KEYSRCOVERRIDE | WINEDDBLT_KEYDESTOVERRIDE)) +@@ -4622,7 +4642,7 @@ do { \ + LONG tmpxy; + dTopLeft = dbuf; + dTopRight = dbuf + ((dstwidth - 1) * bpp); +- dBottomLeft = dTopLeft + ((dstheight - 1) * dst_map.row_pitch); ++ dBottomLeft = dTopLeft + ((dstheight - 1) * dst_row_pitch); + dBottomRight = dBottomLeft + ((dstwidth - 1) * bpp); + + if (fx->dwDDFX & WINEDDBLTFX_ARITHSTRETCHY) +@@ -4705,7 +4725,7 @@ do { \ + type *d = (type *)dbuf, *dx, tmp; \ + for (y = sy = 0; y < dstheight; ++y, sy += yinc) \ + { \ +- s = (const type *)(sbase + (sy >> 16) * src_map.row_pitch); \ ++ s = (const type *)(sbase + (sy >> 16) * src_row_pitch); \ + dx = d; \ + for (x = sx = 0; x < dstwidth; ++x, sx += xinc) \ + { \ +@@ -4738,7 +4758,7 @@ do { \ + BYTE *d = dbuf, *dx; + for (y = sy = 0; y < dstheight; ++y, sy += yinc) + { +- sbuf = sbase + (sy >> 16) * src_map.row_pitch; ++ sbuf = sbase + (sy >> 16) * src_row_pitch; + dx = d; + for (x = sx = 0; x < dstwidth; ++x, sx+= xinc) + { +@@ -4769,6 +4789,10 @@ do { \ + } + } + ++ wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->resource.map_binding); ++ if (dst_surface->container) ++ wined3d_texture_set_dirty(dst_surface->container); ++ + error: + if (flags && FIXME_ON(d3d_surface)) + { +@@ -4776,12 +4800,24 @@ error: + } + + release: +- wined3d_surface_unmap(dst_surface); +- if (src_surface && src_surface != dst_surface) +- wined3d_surface_unmap(src_surface); ++ if (dst_data) ++ { ++ wined3d_resource_release_map_ptr(&dst_surface->resource, context); ++ ++ if (dst_surface->container->swapchain ++ && dst_surface->container == dst_surface->container->swapchain->front_buffer) ++ { ++ dst_surface->lockedRect = *dst_rect; ++ dst_surface->surface_ops->surface_frontbuffer_updated(dst_surface); ++ } ++ } ++ if (src_surface && src_surface != dst_surface && src_data) ++ wined3d_resource_release_map_ptr(&src_surface->resource, context); + /* Release the converted surface, if any. */ + if (src_texture) + wined3d_texture_decref(src_texture); ++ if (context) ++ context_release(context); + + return hr; + } +-- +2.6.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0035-wined3d-Use-client-storage-with-DIB-sections.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0035-wined3d-Use-client-storage-with-DIB-sections.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0035-wined3d-Use-client-storage-with-DIB-sections.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0035-wined3d-Use-client-storage-with-DIB-sections.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -From e2500c76e7b1b762eeb610d580ce90eec9798773 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 21 Jan 2014 17:06:20 +0100 -Subject: wined3d: Use client storage with DIB sections. - -Now that DIBs are a separate location, we can keep the sysmem around for -OpenGL's use. ---- - dlls/wined3d/surface.c | 27 --------------------------- - dlls/wined3d/texture.c | 3 +-- - 2 files changed, 1 insertion(+), 29 deletions(-) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 16233d3..303a0dc 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -484,28 +484,6 @@ static void surface_evict_sysmem(struct wined3d_surface *surface) - wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); - } - --static void surface_release_client_storage(struct wined3d_surface *surface) --{ -- struct wined3d_context *context = context_acquire(surface->resource.device, NULL); -- const struct wined3d_gl_info *gl_info = context->gl_info; -- -- if (surface->container->texture_rgb.name) -- { -- wined3d_texture_bind_and_dirtify(surface->container, context, FALSE); -- gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, -- GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); -- } -- if (surface->container->texture_srgb.name) -- { -- wined3d_texture_bind_and_dirtify(surface->container, context, TRUE); -- gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, -- GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); -- } -- wined3d_texture_force_reload(surface->container); -- -- context_release(context); --} -- - static BOOL surface_use_pbo(const struct wined3d_surface *surface) - { - const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info; -@@ -2483,11 +2461,6 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) - /* Create a DIB section if there isn't a dc yet. */ - if (!surface->hDC) - { -- if (surface->flags & SFLAG_CLIENT) -- { -- wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_SYSMEM); -- surface_release_client_storage(surface); -- } - hr = surface_create_dib_section(surface); - if (FAILED(hr)) - { -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 429eb89..ec5c847 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -903,12 +903,11 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi - - if (gl_info->supported[APPLE_CLIENT_STORAGE]) - { -- if (surface->flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION) -+ if (surface->flags & (SFLAG_NONPOW2) - || texture->flags & WINED3D_TEXTURE_CONVERTED) - { - /* In some cases we want to disable client storage. - * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches -- * SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues... - * WINED3D_TEXTURE_CONVERTED: The conversion destination memory is freed after loading the surface - * heap_memory == NULL: Not defined in the extension. Seems to disable client storage effectively - */ --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0036-wined3d-Don-t-call-the-public-map-function-in-surfac.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0036-wined3d-Don-t-call-the-public-map-function-in-surfac.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0036-wined3d-Don-t-call-the-public-map-function-in-surfac.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0036-wined3d-Don-t-call-the-public-map-function-in-surfac.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -From 89a2597787017d7bc966c2a146fa4c4fc59e9ebb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Mon, 23 Sep 2013 23:58:41 +0200 -Subject: wined3d: Don't call the public map function in - surface_convert_format. - -TODO: Creating a helper surface and releasing it won't work with the CS. -surface_cpu_blt will be called via the CS, so it can't call external -methods that enqueue commands in the stream. ---- - dlls/wined3d/surface.c | 57 +++++++++++++++++++++++++++++++++----------------- - 1 file changed, 38 insertions(+), 19 deletions(-) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 303a0dc..045ede5 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -2253,11 +2253,14 @@ static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_fo - - static struct wined3d_texture *surface_convert_format(struct wined3d_surface *source, enum wined3d_format_id to_fmt) - { -- struct wined3d_map_desc src_map, dst_map; -+ void *dst_data = NULL, *src_data = NULL; -+ UINT src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; - const struct d3dfmt_converter_desc *conv; - struct wined3d_texture *ret = NULL; - struct wined3d_resource_desc desc; - struct wined3d_surface *dst; -+ struct wined3d_context *context = NULL; -+ struct wined3d_device *device = source->resource.device; - - conv = find_converter(source->resource.format->id, to_fmt); - if (!conv) -@@ -2281,30 +2284,46 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_surface *so - } - dst = surface_from_resource(wined3d_texture_get_sub_resource(ret, 0)); - -- memset(&src_map, 0, sizeof(src_map)); -- memset(&dst_map, 0, sizeof(dst_map)); -+ wined3d_resource_get_pitch(&source->resource, &src_row_pitch, &src_slice_pitch); -+ wined3d_resource_get_pitch(&ret->resource, &dst_row_pitch, &dst_slice_pitch); - -- if (FAILED(wined3d_surface_map(source, &src_map, NULL, WINED3D_MAP_READONLY))) -- { -- ERR("Failed to lock the source surface.\n"); -- wined3d_texture_decref(ret); -- return NULL; -- } -- if (FAILED(wined3d_surface_map(dst, &dst_map, NULL, 0))) -- { -- ERR("Failed to lock the destination surface.\n"); -- wined3d_surface_unmap(source); -- wined3d_texture_decref(ret); -- return NULL; -- } -+ if (device->d3d_initialized) -+ context = context_acquire(device, NULL); -+ -+ wined3d_resource_load_location(&source->resource, context, source->resource.map_binding); -+ src_data = wined3d_resource_get_map_ptr(&source->resource, context, WINED3D_MAP_READONLY); -+ if (!src_data) -+ goto error; - -- conv->convert(src_map.data, dst_map.data, src_map.row_pitch, dst_map.row_pitch, -+ if (!wined3d_resource_prepare_map_memory(&dst->resource, context)) -+ goto error; -+ dst_data = wined3d_resource_get_map_ptr(&dst->resource, context, 0); -+ if (!dst_data) -+ goto error; -+ -+ conv->convert(src_data, dst_data, src_row_pitch, dst_row_pitch, - source->resource.width, source->resource.height); - -- wined3d_surface_unmap(dst); -- wined3d_surface_unmap(source); -+ wined3d_resource_release_map_ptr(&dst->resource, context); -+ wined3d_resource_release_map_ptr(&source->resource, context); -+ -+ if (context) -+ context_release(context); - - return ret; -+ -+error: -+ ERR("Surface conversion failed.\n"); -+ -+ if (src_data) -+ wined3d_resource_release_map_ptr(&source->resource, context); -+ if (dst_data) -+ wined3d_resource_release_map_ptr(&ret->resource, context); -+ if (ret) -+ wined3d_texture_decref(ret); -+ if (context) -+ context_release(context); -+ return NULL; - } - - static HRESULT _Blt_ColorFill(BYTE *buf, unsigned int width, unsigned int height, --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0036-wined3d-Move-the-framebuffer-into-wined3d_state.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0036-wined3d-Move-the-framebuffer-into-wined3d_state.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0036-wined3d-Move-the-framebuffer-into-wined3d_state.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0036-wined3d-Move-the-framebuffer-into-wined3d_state.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,940 @@ +From 0846dc3670f5f7520a544570627283a4b4e9ced9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 20 Dec 2012 13:09:17 +0100 +Subject: wined3d: Move the framebuffer into wined3d_state + +--- + dlls/wined3d/arb_program_shader.c | 4 +- + dlls/wined3d/context.c | 20 +++++-- + dlls/wined3d/cs.c | 21 ++----- + dlls/wined3d/device.c | 117 +++++++++++++++++--------------------- + dlls/wined3d/drawprim.c | 14 ++--- + dlls/wined3d/glsl_shader.c | 2 +- + dlls/wined3d/shader.c | 2 +- + dlls/wined3d/state.c | 20 +++---- + dlls/wined3d/stateblock.c | 45 +++++++++++++-- + dlls/wined3d/surface.c | 2 +- + dlls/wined3d/swapchain.c | 2 +- + dlls/wined3d/utils.c | 4 +- + dlls/wined3d/wined3d_private.h | 46 +++++++++++---- + 13 files changed, 172 insertions(+), 127 deletions(-) + +diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c +index b2ddf55..31f005a 100644 +--- a/dlls/wined3d/arb_program_shader.c ++++ b/dlls/wined3d/arb_program_shader.c +@@ -684,7 +684,7 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, + { + const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; + const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog; +- UINT rt_height = state->fb->render_targets[0]->height; ++ UINT rt_height = state->fb.render_targets[0]->height; + + /* Load DirectX 9 float constants for pixel shader */ + priv->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, +@@ -4712,7 +4712,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context + } + else + { +- UINT rt_height = state->fb->render_targets[0]->height; ++ UINT rt_height = state->fb.render_targets[0]->height; + shader_arb_ps_local_constants(compiled, context, state, rt_height); + } + +diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c +index 0d9de90..cb40148 100644 +--- a/dlls/wined3d/context.c ++++ b/dlls/wined3d/context.c +@@ -1511,6 +1511,12 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, + goto out; + } + ++ ret->current_fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ++ sizeof(*ret->current_fb.render_targets) * gl_info->limits.buffers); ++ ret->current_fb.rt_size = gl_info->limits.buffers; ++ if (!ret->current_fb.render_targets) ++ goto out; ++ + /* Initialize the texture unit mapping to a 1:1 mapping */ + for (s = 0; s < MAX_COMBINED_SAMPLERS; ++s) + { +@@ -1840,6 +1846,7 @@ out: + if (hdc) wined3d_release_dc(swapchain->win_handle, hdc); + device->shader_backend->shader_free_context_data(ret); + device->adapter->fragment_pipe->free_context_data(ret); ++ HeapFree(GetProcessHeap(), 0, ret->current_fb.render_targets); + HeapFree(GetProcessHeap(), 0, ret->free_event_queries); + HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries); + HeapFree(GetProcessHeap(), 0, ret->free_timestamp_queries); +@@ -1874,6 +1881,7 @@ void context_destroy(struct wined3d_device *device, struct wined3d_context *cont + + device->shader_backend->shader_free_context_data(context); + device->adapter->fragment_pipe->free_context_data(context); ++ HeapFree(GetProcessHeap(), 0, context->current_fb.render_targets); + HeapFree(GetProcessHeap(), 0, context->draw_buffers); + HeapFree(GetProcessHeap(), 0, context->blit_targets); + device_context_remove(device, context); +@@ -2385,7 +2393,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win + DWORD rt_mask = 0, *cur_mask; + UINT i; + +- if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != &device->fb ++ if (isStateDirty(context, STATE_FRAMEBUFFER) || !wined3d_fb_equal(fb, &context->current_fb) + || rt_count != context->gl_info->limits.buffers) + { + if (!context_validate_rt_config(rt_count, rts, dsv)) +@@ -2430,6 +2438,8 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win + rt_mask = context_generate_rt_mask_no_fbo(device, + rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); + } ++ ++ wined3d_fb_copy(&context->current_fb, fb); + } + else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO + && (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))) +@@ -2488,7 +2498,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win + static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_device *device) + { + const struct wined3d_state *state = &device->state; +- struct wined3d_rendertarget_view **rts = state->fb->render_targets; ++ struct wined3d_rendertarget_view **rts = state->fb.render_targets; + struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; + DWORD rt_mask, rt_mask_bits; + unsigned int i; +@@ -2518,7 +2528,7 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const + void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { + const struct wined3d_device *device = context->swapchain->device; +- const struct wined3d_fb_state *fb = state->fb; ++ const struct wined3d_fb_state *fb = &state->fb; + DWORD rt_mask = find_draw_buffers_mask(context, device); + DWORD *cur_mask; + +@@ -2550,6 +2560,8 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat + context_apply_draw_buffers(context, rt_mask); + *cur_mask = rt_mask; + } ++ ++ wined3d_fb_copy(&context->current_fb, &state->fb); + } + + static void context_map_stage(struct wined3d_context *context, DWORD stage, DWORD unit) +@@ -3193,7 +3205,7 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de + { + const struct wined3d_state *state = &device->state; + const struct StateEntry *state_table = context->state_table; +- const struct wined3d_fb_state *fb = state->fb; ++ const struct wined3d_fb_state *fb = &state->fb; + unsigned int i; + WORD map; + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 316ccb8..eefa142 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -290,7 +290,7 @@ static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) + device = cs->device; + wined3d_get_draw_rect(&device->state, &draw_rect); + device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, +- &device->fb, op->rect_count, op->rects, &draw_rect, op->flags, ++ &cs->state.fb, op->rect_count, op->rects, &draw_rect, op->flags, + op->color, op->depth, op->stencil); + } + +@@ -397,7 +397,7 @@ static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const v + { + const struct wined3d_cs_set_rendertarget_view *op = data; + +- cs->state.fb->render_targets[op->view_idx] = op->view; ++ cs->state.fb.render_targets[op->view_idx] = op->view; + device_invalidate_state(cs->device, STATE_FRAMEBUFFER); + } + +@@ -420,7 +420,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const + struct wined3d_device *device = cs->device; + struct wined3d_rendertarget_view *prev; + +- if ((prev = cs->state.fb->depth_stencil)) ++ if ((prev = cs->state.fb.depth_stencil)) + { + struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev); + +@@ -436,7 +436,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const + } + } + +- cs->fb.depth_stencil = op->view; ++ cs->state.fb.depth_stencil = op->view; + + if (!prev != !op->view) + { +@@ -1005,7 +1005,7 @@ static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) + + state_cleanup(&cs->state); + memset(&cs->state, 0, sizeof(cs->state)); +- if (FAILED(hr = state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info, ++ if (FAILED(hr = state_init(&cs->state, &adapter->gl_info, &adapter->d3d_info, + WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) + ERR("Failed to initialize CS state, hr %#x.\n", hr); + } +@@ -1088,17 +1088,9 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) + if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs)))) + return NULL; + +- if (!(cs->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, +- sizeof(*cs->fb.render_targets) * gl_info->limits.buffers))) +- { +- HeapFree(GetProcessHeap(), 0, cs); +- return NULL; +- } +- +- if (FAILED(state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info, ++ if (FAILED(state_init(&cs->state, gl_info, &device->adapter->d3d_info, + WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) + { +- HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); + HeapFree(GetProcessHeap(), 0, cs); + return NULL; + } +@@ -1119,7 +1111,6 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) + void wined3d_cs_destroy(struct wined3d_cs *cs) + { + state_cleanup(&cs->state); +- HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); + HeapFree(GetProcessHeap(), 0, cs->data); + HeapFree(GetProcessHeap(), 0, cs); + } +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 5e02b97..9ea1d67 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -939,7 +939,7 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi + BOOL ds_enable = !!swapchain->desc.enable_auto_depth_stencil; + unsigned int i; + +- if (device->fb.render_targets) ++ if (device->state.fb.render_targets) + { + for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + { +@@ -957,7 +957,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, + struct wined3d_swapchain_desc *swapchain_desc) + { + static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f}; +- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_swapchain *swapchain = NULL; + struct wined3d_context *context; + DWORD clear_flags = 0; +@@ -970,9 +969,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, + if (device->wined3d->flags & WINED3D_NO3D) + return WINED3DERR_INVALIDCALL; + +- device->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, +- sizeof(*device->fb.render_targets) * gl_info->limits.buffers); +- + if (FAILED(hr = device->shader_backend->shader_alloc_private(device, + device->adapter->vertex_pipe, device->adapter->fragment_pipe))) + { +@@ -1061,7 +1057,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, + return WINED3D_OK; + + err_out: +- HeapFree(GetProcessHeap(), 0, device->fb.render_targets); + HeapFree(GetProcessHeap(), 0, device->swapchains); + device->swapchain_count = 0; + if (device->back_buffer_view) +@@ -1140,8 +1135,25 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) + if (device->cursor_texture) + wined3d_texture_decref(device->cursor_texture); + ++ /* Release the buffers (with sanity checks). ++ * FIXME: Move this move into a separate patch. I think the idea ++ * behind this is that those surfaces should be freed before unloading ++ * remaining resources below. */ ++ if (device->onscreen_depth_stencil) ++ { ++ surface = device->onscreen_depth_stencil; ++ device->onscreen_depth_stencil = NULL; ++ wined3d_texture_decref(surface->container); ++ } ++ + state_unbind_resources(&device->state); + ++ if (device->auto_depth_stencil_view) ++ { ++ wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); ++ device->auto_depth_stencil_view = NULL; ++ } ++ + /* Unload resources */ + LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) + { +@@ -1173,37 +1185,6 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) + * destroy the context. */ + context_release(context); + +- /* Release the buffers (with sanity checks)*/ +- if (device->onscreen_depth_stencil) +- { +- surface = device->onscreen_depth_stencil; +- device->onscreen_depth_stencil = NULL; +- wined3d_texture_decref(surface->container); +- } +- +- if (device->fb.depth_stencil) +- { +- struct wined3d_rendertarget_view *view = device->fb.depth_stencil; +- +- TRACE("Releasing depth/stencil view %p.\n", view); +- +- device->fb.depth_stencil = NULL; +- wined3d_rendertarget_view_decref(view); +- } +- +- if (device->auto_depth_stencil_view) +- { +- struct wined3d_rendertarget_view *view = device->auto_depth_stencil_view; +- +- device->auto_depth_stencil_view = NULL; +- if (wined3d_rendertarget_view_decref(view)) +- ERR("Something's still holding the auto depth/stencil view (%p).\n", view); +- } +- +- for (i = 0; i < gl_info->limits.buffers; ++i) +- { +- wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); +- } + if (device->back_buffer_view) + { + wined3d_rendertarget_view_decref(device->back_buffer_view); +@@ -1221,9 +1202,6 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) + device->swapchains = NULL; + device->swapchain_count = 0; + +- HeapFree(GetProcessHeap(), 0, device->fb.render_targets); +- device->fb.render_targets = NULL; +- + device->d3d_initialized = FALSE; + + return WINED3D_OK; +@@ -2021,7 +1999,7 @@ static void resolve_depth_buffer(struct wined3d_state *state) + || !(texture->resource.format_flags & WINED3DFMT_FLAG_DEPTH)) + return; + surface = surface_from_resource(texture->sub_resources[0]); +- if (!(depth_stencil = wined3d_rendertarget_view_get_surface(state->fb->depth_stencil))) ++ if (!(depth_stencil = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil))) + return; + + SetRect(&dst_rect, 0, 0, surface->resource.width, surface->resource.height); +@@ -3378,6 +3356,8 @@ HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) + HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, + const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) + { ++ const struct wined3d_fb_state *fb = &device->state.fb; ++ + TRACE("device %p, rect_count %u, rects %p, flags %#x, color {%.8e, %.8e, %.8e, %.8e}, depth %.8e, stencil %u.\n", + device, rect_count, rects, flags, color->r, color->g, color->b, color->a, depth, stencil); + +@@ -3389,7 +3369,7 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou + + if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) + { +- struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; ++ struct wined3d_rendertarget_view *ds = fb->depth_stencil; + if (!ds) + { + WARN("Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL\n"); +@@ -3398,8 +3378,8 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou + } + else if (flags & WINED3DCLEAR_TARGET) + { +- if (ds->width < device->fb.render_targets[0]->width +- || ds->height < device->fb.render_targets[0]->height) ++ if (ds->width < fb->render_targets[0]->width ++ || ds->height < fb->render_targets[0]->height) + { + WARN("Silently ignoring depth and target clear with mismatching sizes\n"); + return WINED3D_OK; +@@ -3749,8 +3729,8 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device + if (state->render_states[WINED3D_RS_ZENABLE] || state->render_states[WINED3D_RS_ZWRITEENABLE] + || state->render_states[WINED3D_RS_STENCILENABLE]) + { +- struct wined3d_rendertarget_view *rt = device->fb.render_targets[0]; +- struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; ++ struct wined3d_rendertarget_view *rt = state->fb.render_targets[0]; ++ struct wined3d_rendertarget_view *ds = state->fb.depth_stencil; + + if (ds && rt && (ds->width < rt->width || ds->height < rt->height)) + { +@@ -4172,20 +4152,21 @@ struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(co + return NULL; + } + +- return device->fb.render_targets[view_idx]; ++ return device->state.fb.render_targets[view_idx]; + } + + struct wined3d_rendertarget_view * CDECL wined3d_device_get_depth_stencil_view(const struct wined3d_device *device) + { + TRACE("device %p.\n", device); + +- return device->fb.depth_stencil; ++ return device->state.fb.depth_stencil; + } + + HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device, + unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport) + { + struct wined3d_rendertarget_view *prev; ++ struct wined3d_fb_state *fb = &device->state.fb; + + TRACE("device %p, view_idx %u, view %p, set_viewport %#x.\n", + device, view_idx, view, set_viewport); +@@ -4225,13 +4206,13 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device + } + + +- prev = device->fb.render_targets[view_idx]; ++ prev = fb->render_targets[view_idx]; + if (view == prev) + return WINED3D_OK; + + if (view) + wined3d_rendertarget_view_incref(view); +- device->fb.render_targets[view_idx] = view; ++ fb->render_targets[view_idx] = view; + wined3d_cs_emit_set_rendertarget_view(device->cs, view_idx, view); + /* Release after the assignment, to prevent device_resource_released() + * from seeing the surface as still in use. */ +@@ -4243,18 +4224,19 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device + + void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view) + { ++ struct wined3d_fb_state *fb = &device->state.fb; + struct wined3d_rendertarget_view *prev; + + TRACE("device %p, view %p.\n", device, view); + +- prev = device->fb.depth_stencil; ++ prev = fb->depth_stencil; + if (prev == view) + { + TRACE("Trying to do a NOP SetRenderTarget operation.\n"); + return; + } + +- if ((device->fb.depth_stencil = view)) ++ if ((fb->depth_stencil = view)) + wined3d_rendertarget_view_incref(view); + wined3d_cs_emit_set_depth_stencil_view(device->cs, view); + if (prev) +@@ -4620,10 +4602,9 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + wined3d_texture_decref(device->cursor_texture); + device->cursor_texture = NULL; + } +- state_unbind_resources(&device->state); + } + +- if (device->fb.render_targets) ++ if (device->state.fb.render_targets) + { + for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + { +@@ -4632,6 +4613,11 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + } + wined3d_device_set_depth_stencil_view(device, NULL); + ++ if (reset_state) ++ { ++ state_unbind_resources(&device->state); ++ } ++ + if (device->onscreen_depth_stencil) + { + wined3d_texture_decref(device->onscreen_depth_stencil->container); +@@ -4850,7 +4836,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + if (device->d3d_initialized) + delete_opengl_contexts(device, swapchain); + +- if (FAILED(hr = state_init(&device->state, &device->fb, &device->adapter->gl_info, ++ if (FAILED(hr = state_init(&device->state, &device->adapter->gl_info, + &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) + ERR("Failed to initialize device state, hr %#x.\n", hr); + device->update_state = &device->state; +@@ -4859,22 +4845,21 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + } + else if (device->back_buffer_view) + { +- struct wined3d_rendertarget_view *view = device->back_buffer_view; + struct wined3d_state *state = &device->state; + +- wined3d_device_set_rendertarget_view(device, 0, view, FALSE); ++ wined3d_device_set_rendertarget_view(device, 0, device->back_buffer_view, FALSE); + + /* Note the min_z / max_z is not reset. */ + state->viewport.x = 0; + state->viewport.y = 0; +- state->viewport.width = view->width; +- state->viewport.height = view->height; ++ state->viewport.width = swapchain->desc.backbuffer_width; ++ state->viewport.height = swapchain->desc.backbuffer_height; + wined3d_cs_emit_set_viewport(device->cs, &state->viewport); + + state->scissor_rect.top = 0; + state->scissor_rect.left = 0; +- state->scissor_rect.right = view->width; +- state->scissor_rect.bottom = view->height; ++ state->scissor_rect.right = swapchain->desc.backbuffer_width; ++ state->scissor_rect.bottom = swapchain->desc.backbuffer_height; + wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); + } + +@@ -4962,17 +4947,17 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso + + for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + { +- if (wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]) == surface) ++ if (wined3d_rendertarget_view_get_surface(device->state.fb.render_targets[i]) == surface) + { + ERR("Surface %p is still in use as render target %u.\n", surface, i); +- device->fb.render_targets[i] = NULL; ++ device->state.fb.render_targets[i] = NULL; + } + } + +- if (wined3d_rendertarget_view_get_surface(device->fb.depth_stencil) == surface) ++ if (wined3d_rendertarget_view_get_surface(device->state.fb.depth_stencil) == surface) + { + ERR("Surface %p is still in use as depth/stencil buffer.\n", surface); +- device->fb.depth_stencil = NULL; ++ device->state.fb.depth_stencil = NULL; + } + } + break; +@@ -5134,7 +5119,7 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, + + device->blitter = adapter->blitter; + +- if (FAILED(hr = state_init(&device->state, &device->fb, &adapter->gl_info, ++ if (FAILED(hr = state_init(&device->state, &adapter->gl_info, + &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) + { + ERR("Failed to initialize device state, hr %#x.\n", hr); +diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c +index 0afeff9..4e66f01 100644 +--- a/dlls/wined3d/drawprim.c ++++ b/dlls/wined3d/drawprim.c +@@ -611,7 +611,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co + + if (!index_count) return; + +- context = context_acquire(device, wined3d_rendertarget_view_get_surface(device->fb.render_targets[0])); ++ context = context_acquire(device, wined3d_rendertarget_view_get_surface(state->fb.render_targets[0])); + if (!context->valid) + { + context_release(context); +@@ -622,7 +622,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co + + for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + { +- struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]); ++ struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(state->fb.render_targets[i]); + if (target && target->resource.format->id != WINED3DFMT_NULL) + { + if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) +@@ -637,16 +637,16 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co + } + } + +- if (device->fb.depth_stencil) ++ if (state->fb.depth_stencil) + { + /* Note that this depends on the context_acquire() call above to set + * context->render_offscreen properly. We don't currently take the + * Z-compare function into account, but we could skip loading the + * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note + * that we never copy the stencil data.*/ +- DWORD location = context->render_offscreen ? device->fb.depth_stencil->resource->draw_binding ++ DWORD location = context->render_offscreen ? state->fb.depth_stencil->resource->draw_binding + : WINED3D_LOCATION_DRAWABLE; +- struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil); ++ struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil); + + if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) + { +@@ -679,9 +679,9 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co + return; + } + +- if (device->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE]) ++ if (state->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE]) + { +- struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil); ++ struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil); + DWORD location = context->render_offscreen ? ds->container->resource.draw_binding : WINED3D_LOCATION_DRAWABLE; + + surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); +diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c +index 1eb7e6d..56e4bb9 100644 +--- a/dlls/wined3d/glsl_shader.c ++++ b/dlls/wined3d/glsl_shader.c +@@ -1627,7 +1627,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont + const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; + const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; + const struct wined3d_gl_info *gl_info = context->gl_info; +- const struct wined3d_fb_state *fb = &shader->device->fb; ++ const struct wined3d_fb_state *fb = &state->fb; + unsigned int i, extra_constants_needed = 0; + const struct wined3d_shader_lconst *lconst; + const char *prefix; +diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c +index 140665e..cc18f88 100644 +--- a/dlls/wined3d/shader.c ++++ b/dlls/wined3d/shader.c +@@ -2451,7 +2451,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 + memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */ + if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && state->render_states[WINED3D_RS_SRGBWRITEENABLE]) + { +- unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; ++ unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; + if (rt_fmt_flags & WINED3DFMT_FLAG_SRGB_WRITE) + { + static unsigned int warned = 0; +diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c +index 1d80fa0..b9263a7 100644 +--- a/dlls/wined3d/state.c ++++ b/dlls/wined3d/state.c +@@ -105,7 +105,7 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_ + const struct wined3d_gl_info *gl_info = context->gl_info; + + /* No z test without depth stencil buffers */ +- if (!state->fb->depth_stencil) ++ if (!state->fb.depth_stencil) + { + TRACE("No Z buffer - disabling depth test\n"); + zenable = WINED3D_ZB_FALSE; +@@ -367,8 +367,8 @@ static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_fo + + static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { +- const struct wined3d_format *rt_format = state->fb->render_targets[0]->format; +- unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; ++ const struct wined3d_format *rt_format = state->fb.render_targets[0]->format; ++ unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; + const struct wined3d_gl_info *gl_info = context->gl_info; + GLenum srcBlend, dstBlend; + enum wined3d_blend d3d_blend; +@@ -813,7 +813,7 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ + GLint depthFail_ccw; + + /* No stencil test without a stencil buffer. */ +- if (!state->fb->depth_stencil) ++ if (!state->fb.depth_stencil) + { + gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST); + checkGLcall("glDisable GL_STENCIL_TEST"); +@@ -909,7 +909,7 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ + + static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { +- DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; ++ DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; + const struct wined3d_gl_info *gl_info = context->gl_info; + + GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); +@@ -923,7 +923,7 @@ static void state_stencilwrite2s(struct wined3d_context *context, const struct w + + static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { +- DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; ++ DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; + const struct wined3d_gl_info *gl_info = context->gl_info; + + gl_info->gl_ops.gl.p_glStencilMask(mask); +@@ -1650,7 +1650,7 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3 + if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS] + || state->render_states[WINED3D_RS_DEPTHBIAS]) + { +- const struct wined3d_rendertarget_view *depth = state->fb->depth_stencil; ++ const struct wined3d_rendertarget_view *depth = state->fb.depth_stencil; + float scale; + + union +@@ -4543,7 +4543,7 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine + + static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { +- const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; ++ const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_viewport vp = state->viewport; + +@@ -4721,7 +4721,7 @@ static void scissorrect(struct wined3d_context *context, const struct wined3d_st + } + else + { +- const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; ++ const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; + UINT height; + UINT width; + +@@ -4785,7 +4785,7 @@ static void psorigin(struct wined3d_context *context, const struct wined3d_state + + void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { +- unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; ++ unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; + const struct wined3d_gl_info *gl_info = context->gl_info; + + TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); +diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c +index cb3d494..6b348b8 100644 +--- a/dlls/wined3d/stateblock.c ++++ b/dlls/wined3d/stateblock.c +@@ -464,6 +464,7 @@ void state_unbind_resources(struct wined3d_state *state) + struct wined3d_texture *texture; + struct wined3d_buffer *buffer; + struct wined3d_shader *shader; ++ struct wined3d_rendertarget_view *view; + unsigned int i, j; + + if ((decl = state->vertex_declaration)) +@@ -540,6 +541,31 @@ void state_unbind_resources(struct wined3d_state *state) + } + } + } ++ ++ if (state->fb.depth_stencil) ++ { ++ view = state->fb.depth_stencil; ++ ++ TRACE("Releasing depth/stencil buffer %p.\n", view); ++ ++ state->fb.depth_stencil = NULL; ++ wined3d_rendertarget_view_decref(view); ++ } ++ ++ if (state->fb.render_targets) ++ { ++ for (i = 0; i < state->fb.rt_size; i++) ++ { ++ view = state->fb.render_targets[i]; ++ TRACE("Setting rendertarget %u to NULL\n", i); ++ state->fb.render_targets[i] = NULL; ++ if (view) ++ { ++ TRACE("Releasing the rendertarget view at %p\n", view); ++ wined3d_rendertarget_view_decref(view); ++ } ++ } ++ } + } + + void state_cleanup(struct wined3d_state *state) +@@ -567,6 +593,7 @@ void state_cleanup(struct wined3d_state *state) + + HeapFree(GetProcessHeap(), 0, state->vs_consts_f); + HeapFree(GetProcessHeap(), 0, state->ps_consts_f); ++ HeapFree(GetProcessHeap(), 0, state->fb.render_targets); + } + + ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock) +@@ -1310,14 +1337,12 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d + } + } + +-HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, +- const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, +- DWORD flags) ++HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl_info, ++ const struct wined3d_d3d_info *d3d_info, DWORD flags) + { + unsigned int i; + + state->flags = flags; +- state->fb = fb; + + for (i = 0; i < LIGHTMAP_SIZE; i++) + { +@@ -1335,6 +1360,15 @@ HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, + return E_OUTOFMEMORY; + } + ++ if (!(state->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ++ sizeof(*state->fb.render_targets) * gl_info->limits.buffers))) ++ { ++ HeapFree(GetProcessHeap(), 0, state->ps_consts_f); ++ HeapFree(GetProcessHeap(), 0, state->vs_consts_f); ++ return E_OUTOFMEMORY; ++ } ++ state->fb.rt_size = gl_info->limits.buffers; ++ + if (flags & WINED3D_STATE_INIT_DEFAULT) + state_init_default(state, gl_info); + +@@ -1345,12 +1379,13 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, + struct wined3d_device *device, enum wined3d_stateblock_type type) + { + HRESULT hr; ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; + + stateblock->ref = 1; + stateblock->device = device; + +- if (FAILED(hr = state_init(&stateblock->state, NULL, &device->adapter->gl_info, d3d_info, 0))) ++ if (FAILED(hr = state_init(&stateblock->state, gl_info, d3d_info, 0))) + return hr; + + if (FAILED(hr = stateblock_allocate_shader_constants(stateblock))) +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 817ef6f..35bf399 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -3265,8 +3265,8 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE + enum wined3d_texture_filter_type filter) + { + struct wined3d_device *device = dst_surface->resource.device; +- const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]); + struct wined3d_swapchain *src_swapchain, *dst_swapchain; ++ const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->state.fb.render_targets[0]); + + TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, blt_fx %p, filter %s.\n", + dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), +diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c +index dbf2c8b..73730cd 100644 +--- a/dlls/wined3d/swapchain.c ++++ b/dlls/wined3d/swapchain.c +@@ -427,7 +427,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT + { + struct wined3d_surface *back_buffer = surface_from_resource( + wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); +- const struct wined3d_fb_state *fb = &swapchain->device->fb; ++ const struct wined3d_fb_state *fb = &swapchain->device->state.fb; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + struct wined3d_surface *front; +diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c +index 28a3216..d28994e 100644 +--- a/dlls/wined3d/utils.c ++++ b/dlls/wined3d/utils.c +@@ -3776,7 +3776,7 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w + float y_offset = context->render_offscreen + ? (center_offset - (2.0f * y) - h) / h + : (center_offset - (2.0f * y) - h) / -h; +- enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ? ++ enum wined3d_depth_buffer_type zenable = state->fb.depth_stencil ? + state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; + float z_scale = zenable ? 2.0f : 0.0f; + float z_offset = zenable ? -1.0f : 0.0f; +@@ -4357,7 +4357,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d + unsigned int i; + DWORD ttff; + DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; +- unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; ++ unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; + const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_d3d_info *d3d_info = context->d3d_info; + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 6ae6072..df9d5fa 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -1176,6 +1176,36 @@ struct wined3d_timestamp_query + void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; + void context_free_timestamp_query(struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; + ++struct wined3d_fb_state ++{ ++ struct wined3d_rendertarget_view **render_targets; ++ struct wined3d_rendertarget_view *depth_stencil; ++ UINT rt_size; ++}; ++ ++static inline BOOL wined3d_fb_equal(const struct wined3d_fb_state *fb1, const struct wined3d_fb_state *fb2) ++{ ++ UINT i; ++ ++ if (fb1->depth_stencil != fb2->depth_stencil) ++ return FALSE; ++ if (fb1->rt_size != fb2->rt_size) ++ return FALSE; ++ for (i = 0; i < fb1->rt_size; i++) ++ if (fb1->render_targets[i] != fb2->render_targets[i]) ++ return FALSE; ++ return TRUE; ++} ++ ++static inline void wined3d_fb_copy(struct wined3d_fb_state *dst, const struct wined3d_fb_state *src) ++{ ++ UINT i; ++ ++ dst->depth_stencil = src->depth_stencil; ++ for (i = 0; i < min(dst->rt_size, src->rt_size); i++) ++ dst->render_targets[i] = src->render_targets[i]; ++} ++ + struct wined3d_context + { + const struct wined3d_gl_info *gl_info; +@@ -1190,6 +1220,7 @@ struct wined3d_context + DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */ + DWORD numDirtyEntries; + DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ ++ struct wined3d_fb_state current_fb; + + struct wined3d_swapchain *swapchain; + struct wined3d_surface *current_rt; +@@ -1292,12 +1323,6 @@ struct wined3d_context + GLuint dummy_arbfp_prog; + }; + +-struct wined3d_fb_state +-{ +- struct wined3d_rendertarget_view **render_targets; +- struct wined3d_rendertarget_view *depth_stencil; +-}; +- + typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id); + + struct StateEntry +@@ -2020,7 +2045,7 @@ struct wined3d_stream_state + struct wined3d_state + { + DWORD flags; +- const struct wined3d_fb_state *fb; ++ struct wined3d_fb_state fb; + + struct wined3d_vertex_declaration *vertex_declaration; + struct wined3d_stream_output stream_output[MAX_STREAM_OUT]; +@@ -2126,7 +2151,6 @@ struct wined3d_device + struct wine_rb_tree samplers; + + /* Render Target Support */ +- struct wined3d_fb_state fb; + struct wined3d_surface *onscreen_depth_stencil; + struct wined3d_rendertarget_view *auto_depth_stencil_view; + +@@ -2638,9 +2662,8 @@ struct wined3d_stateblock + void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN; + + void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; +-HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, +- const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, +- DWORD flags) DECLSPEC_HIDDEN; ++HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl_info, ++ const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; + void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; + + struct wined3d_cs_ops +@@ -2653,7 +2676,6 @@ struct wined3d_cs + { + const struct wined3d_cs_ops *ops; + struct wined3d_device *device; +- struct wined3d_fb_state fb; + struct wined3d_state state; + + size_t data_size; +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0037-wined3d-Don-t-call-the-public-map-function-in-surfac.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0037-wined3d-Don-t-call-the-public-map-function-in-surfac.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0037-wined3d-Don-t-call-the-public-map-function-in-surfac.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0037-wined3d-Don-t-call-the-public-map-function-in-surfac.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,282 +0,0 @@ -From 74de56cff82b598bb71d556767bcd1c53dcb16e2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 24 Sep 2013 00:31:39 +0200 -Subject: wined3d: Don't call the public map function in surface_cpu_blt. - ---- - dlls/wined3d/surface.c | 108 ++++++++++++++++++++++++++++++++----------------- - 1 file changed, 72 insertions(+), 36 deletions(-) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 5c30f78..a32ce1d 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -4306,26 +4306,40 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) - { -- const struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; - int bpp, srcheight, srcwidth, dstheight, dstwidth, width; - const struct wined3d_format *src_format, *dst_format; - unsigned int src_fmt_flags, dst_fmt_flags; - struct wined3d_texture *src_texture = NULL; -- struct wined3d_map_desc dst_map, src_map; -+ void *src_data = NULL, *dst_data = NULL; -+ UINT src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; - const BYTE *sbase = NULL; - HRESULT hr = WINED3D_OK; - const BYTE *sbuf; - BYTE *dbuf; - int x, y; -+ struct wined3d_device *device = dst_surface->resource.device; -+ struct wined3d_context *context = NULL; - - TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", - dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), - flags, fx, debug_d3dtexturefiltertype(filter)); - -+ if (device->d3d_initialized) -+ context = context_acquire(device, NULL); -+ -+ if (!wined3d_resource_prepare_map_memory(&dst_surface->resource, context)) -+ { -+ hr = E_OUTOFMEMORY; -+ goto error; -+ } -+ wined3d_resource_load_location(&dst_surface->resource, context, dst_surface->resource.map_binding); -+ - if (src_surface == dst_surface) - { -- wined3d_surface_map(dst_surface, &dst_map, NULL, 0); -- src_map = dst_map; -+ dst_data = wined3d_resource_get_map_ptr(&dst_surface->resource, context, 0); -+ wined3d_resource_get_pitch(&dst_surface->resource, &dst_row_pitch, &dst_slice_pitch); -+ src_data = dst_data; -+ src_row_pitch = dst_row_pitch; - src_format = dst_surface->resource.format; - dst_format = src_format; - dst_fmt_flags = dst_surface->container->resource.format_flags; -@@ -4337,6 +4351,12 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * - dst_fmt_flags = dst_surface->container->resource.format_flags; - if (src_surface) - { -+ if (!wined3d_resource_prepare_map_memory(&src_surface->resource, context)) -+ { -+ hr = E_OUTOFMEMORY; -+ goto error; -+ } -+ - if (dst_surface->resource.format->id != src_surface->resource.format->id) - { - if (!(src_texture = surface_convert_format(src_surface, dst_format->id))) -@@ -4347,7 +4367,9 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * - } - src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, 0)); - } -- wined3d_surface_map(src_surface, &src_map, NULL, WINED3D_MAP_READONLY); -+ wined3d_resource_load_location(&src_surface->resource, context, src_surface->resource.map_binding); -+ wined3d_resource_get_pitch(&src_surface->resource, &src_row_pitch, &src_slice_pitch); -+ src_data = wined3d_resource_get_map_ptr(&src_surface->resource, context, 0); - src_format = src_surface->resource.format; - src_fmt_flags = src_surface->container->resource.format_flags; - } -@@ -4357,7 +4379,8 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * - src_fmt_flags = dst_fmt_flags; - } - -- wined3d_surface_map(dst_surface, &dst_map, &dst_box, 0); -+ wined3d_resource_get_pitch(&dst_surface->resource, &dst_row_pitch, &dst_slice_pitch); -+ dst_data = wined3d_resource_get_map_ptr(&dst_surface->resource, context, 0); - } - - bpp = dst_surface->resource.format->byte_count; -@@ -4368,15 +4391,12 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * - width = (dst_rect->right - dst_rect->left) * bpp; - - if (src_surface) -- sbase = (BYTE *)src_map.data -- + ((src_rect->top / src_format->block_height) * src_map.row_pitch) -+ sbase = (BYTE *)src_data -+ + ((src_rect->top / src_format->block_height) * src_row_pitch) - + ((src_rect->left / src_format->block_width) * src_format->block_byte_count); -- if (src_surface != dst_surface) -- dbuf = dst_map.data; -- else -- dbuf = (BYTE *)dst_map.data -- + ((dst_rect->top / dst_format->block_height) * dst_map.row_pitch) -- + ((dst_rect->left / dst_format->block_width) * dst_format->block_byte_count); -+ dbuf = (BYTE *)dst_data -+ + ((dst_rect->top / dst_format->block_height) * dst_row_pitch) -+ + ((dst_rect->left / dst_format->block_width) * dst_format->block_byte_count); - - if (src_fmt_flags & dst_fmt_flags & WINED3DFMT_FLAG_BLOCKS) - { -@@ -4411,7 +4431,7 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * - } - - hr = surface_cpu_blt_compressed(sbase, dbuf, -- src_map.row_pitch, dst_map.row_pitch, dstwidth, dstheight, -+ src_row_pitch, dst_row_pitch, dstwidth, dstheight, - src_format, flags, fx); - goto release; - } -@@ -4419,7 +4439,7 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * - /* First, all the 'source-less' blits */ - if (flags & WINEDDBLT_COLORFILL) - { -- hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_map.row_pitch, fx->u5.dwFillColor); -+ hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_row_pitch, fx->u5.dwFillColor); - flags &= ~WINEDDBLT_COLORFILL; - } - -@@ -4468,19 +4488,19 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * - for (y = 0; y < dstheight; ++y) - { - memcpy(dbuf, sbuf, width); -- sbuf += src_map.row_pitch; -- dbuf += dst_map.row_pitch; -+ sbuf += src_row_pitch; -+ dbuf += dst_row_pitch; - } - } - else if (dst_rect->top > src_rect->top) - { - /* Copy from bottom upwards. */ -- sbuf += src_map.row_pitch * dstheight; -- dbuf += dst_map.row_pitch * dstheight; -+ sbuf += src_row_pitch * dstheight; -+ dbuf += dst_row_pitch * dstheight; - for (y = 0; y < dstheight; ++y) - { -- sbuf -= src_map.row_pitch; -- dbuf -= dst_map.row_pitch; -+ sbuf -= src_row_pitch; -+ dbuf -= dst_row_pitch; - memcpy(dbuf, sbuf, width); - } - } -@@ -4490,8 +4510,8 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * - for (y = 0; y < dstheight; ++y) - { - memmove(dbuf, sbuf, width); -- sbuf += src_map.row_pitch; -- dbuf += dst_map.row_pitch; -+ sbuf += src_row_pitch; -+ dbuf += dst_row_pitch; - } - } - } -@@ -4500,9 +4520,9 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * - /* Stretching in y direction only. */ - for (y = sy = 0; y < dstheight; ++y, sy += yinc) - { -- sbuf = sbase + (sy >> 16) * src_map.row_pitch; -+ sbuf = sbase + (sy >> 16) * src_row_pitch; - memcpy(dbuf, sbuf, width); -- dbuf += dst_map.row_pitch; -+ dbuf += dst_row_pitch; - } - } - } -@@ -4512,13 +4532,13 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * - int last_sy = -1; - for (y = sy = 0; y < dstheight; ++y, sy += yinc) - { -- sbuf = sbase + (sy >> 16) * src_map.row_pitch; -+ sbuf = sbase + (sy >> 16) * src_row_pitch; - - if ((sy >> 16) == (last_sy >> 16)) - { - /* This source row is the same as last source row - - * Copy the already stretched row. */ -- memcpy(dbuf, dbuf - dst_map.row_pitch, width); -+ memcpy(dbuf, dbuf - dst_row_pitch, width); - } - else - { -@@ -4565,14 +4585,14 @@ do { \ - } - #undef STRETCH_ROW - } -- dbuf += dst_map.row_pitch; -+ dbuf += dst_row_pitch; - last_sy = sy; - } - } - } - else - { -- LONG dstyinc = dst_map.row_pitch, dstxinc = bpp; -+ LONG dstyinc = dst_row_pitch, dstxinc = bpp; - DWORD keylow = 0xffffffff, keyhigh = 0, keymask = 0xffffffff; - DWORD destkeylow = 0x0, destkeyhigh = 0xffffffff, destkeymask = 0xffffffff; - if (flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYDEST | WINEDDBLT_KEYSRCOVERRIDE | WINEDDBLT_KEYDESTOVERRIDE)) -@@ -4622,7 +4642,7 @@ do { \ - LONG tmpxy; - dTopLeft = dbuf; - dTopRight = dbuf + ((dstwidth - 1) * bpp); -- dBottomLeft = dTopLeft + ((dstheight - 1) * dst_map.row_pitch); -+ dBottomLeft = dTopLeft + ((dstheight - 1) * dst_row_pitch); - dBottomRight = dBottomLeft + ((dstwidth - 1) * bpp); - - if (fx->dwDDFX & WINEDDBLTFX_ARITHSTRETCHY) -@@ -4705,7 +4725,7 @@ do { \ - type *d = (type *)dbuf, *dx, tmp; \ - for (y = sy = 0; y < dstheight; ++y, sy += yinc) \ - { \ -- s = (const type *)(sbase + (sy >> 16) * src_map.row_pitch); \ -+ s = (const type *)(sbase + (sy >> 16) * src_row_pitch); \ - dx = d; \ - for (x = sx = 0; x < dstwidth; ++x, sx += xinc) \ - { \ -@@ -4738,7 +4758,7 @@ do { \ - BYTE *d = dbuf, *dx; - for (y = sy = 0; y < dstheight; ++y, sy += yinc) - { -- sbuf = sbase + (sy >> 16) * src_map.row_pitch; -+ sbuf = sbase + (sy >> 16) * src_row_pitch; - dx = d; - for (x = sx = 0; x < dstwidth; ++x, sx+= xinc) - { -@@ -4769,6 +4789,10 @@ do { \ - } - } - -+ wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->resource.map_binding); -+ if (dst_surface->container) -+ wined3d_texture_set_dirty(dst_surface->container); -+ - error: - if (flags && FIXME_ON(d3d_surface)) - { -@@ -4776,12 +4800,24 @@ error: - } - - release: -- wined3d_surface_unmap(dst_surface); -- if (src_surface && src_surface != dst_surface) -- wined3d_surface_unmap(src_surface); -+ if (dst_data) -+ { -+ wined3d_resource_release_map_ptr(&dst_surface->resource, context); -+ -+ if (dst_surface->container->swapchain -+ && dst_surface->container == dst_surface->container->swapchain->front_buffer) -+ { -+ dst_surface->lockedRect = *dst_rect; -+ dst_surface->surface_ops->surface_frontbuffer_updated(dst_surface); -+ } -+ } -+ if (src_surface && src_surface != dst_surface && src_data) -+ wined3d_resource_release_map_ptr(&src_surface->resource, context); - /* Release the converted surface, if any. */ - if (src_texture) - wined3d_texture_decref(src_texture); -+ if (context) -+ context_release(context); - - return hr; - } --- -2.6.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0037-wined3d-Get-rid-of-state-access-in-shader_generate_g.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0037-wined3d-Get-rid-of-state-access-in-shader_generate_g.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0037-wined3d-Get-rid-of-state-access-in-shader_generate_g.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0037-wined3d-Get-rid-of-state-access-in-shader_generate_g.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,64 @@ +From ffb226d59c82df5c438b47a1a3d7ae29dc98f861 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 20 Dec 2012 14:19:52 +0100 +Subject: wined3d: Get rid of state access in shader_generate_glsl_declarations + +--- + dlls/wined3d/glsl_shader.c | 21 ++++++--------------- + 1 file changed, 6 insertions(+), 15 deletions(-) + +diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c +index eddabee..edc8ce4 100644 +--- a/dlls/wined3d/glsl_shader.c ++++ b/dlls/wined3d/glsl_shader.c +@@ -1592,11 +1592,9 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont + const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv) + { + const struct wined3d_shader_version *version = ®_maps->shader_version; +- const struct wined3d_state *state = &shader->device->state; + const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; + const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; + const struct wined3d_gl_info *gl_info = context->gl_info; +- const struct wined3d_fb_state *fb = &state->fb; + unsigned int i, extra_constants_needed = 0; + const struct wined3d_shader_lconst *lconst; + const char *prefix; +@@ -1870,7 +1868,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont + { + UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input); + +- if (use_vs(state)) ++ if (ps_args->vp_mode == vertexshader) + declare_in_varying(gl_info, buffer, FALSE, "vec4 %s_link[%u];\n", prefix, in_count); + shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); + } +@@ -1911,21 +1909,14 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont + } + else + { +- float ycorrection[] = +- { +- context->render_offscreen ? 0.0f : fb->render_targets[0]->height, +- context->render_offscreen ? 1.0f : -1.0f, +- 0.0f, +- 0.0f, +- }; +- + /* This happens because we do not have proper tracking of the + * constant registers that are actually used, only the max +- * limit of the shader version. */ ++ * limit of the shader version. ++ * ++ * FIXME 2: This is wrong, there's no need to do this. Get rid of ++ * it and just create the uniform. ++ */ + FIXME("Cannot find a free uniform for vpos correction params\n"); +- shader_addline(buffer, "const vec4 ycorrection = "); +- shader_glsl_append_imm_vec4(buffer, ycorrection); +- shader_addline(buffer, ";\n"); + } + shader_addline(buffer, "vec4 vpos;\n"); + } +-- +2.6.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0038-wined3d-Move-the-framebuffer-into-wined3d_state.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0038-wined3d-Move-the-framebuffer-into-wined3d_state.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0038-wined3d-Move-the-framebuffer-into-wined3d_state.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0038-wined3d-Move-the-framebuffer-into-wined3d_state.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,940 +0,0 @@ -From 68280056e300f90beae6bac338aa94ebacaa4bfc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 20 Dec 2012 13:09:17 +0100 -Subject: wined3d: Move the framebuffer into wined3d_state - ---- - dlls/wined3d/arb_program_shader.c | 4 +- - dlls/wined3d/context.c | 20 +++++-- - dlls/wined3d/cs.c | 21 ++----- - dlls/wined3d/device.c | 117 +++++++++++++++++--------------------- - dlls/wined3d/drawprim.c | 14 ++--- - dlls/wined3d/glsl_shader.c | 2 +- - dlls/wined3d/shader.c | 2 +- - dlls/wined3d/state.c | 20 +++---- - dlls/wined3d/stateblock.c | 45 +++++++++++++-- - dlls/wined3d/surface.c | 2 +- - dlls/wined3d/swapchain.c | 2 +- - dlls/wined3d/utils.c | 4 +- - dlls/wined3d/wined3d_private.h | 46 +++++++++++---- - 13 files changed, 172 insertions(+), 127 deletions(-) - -diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c -index 9a882cc..df89a05 100644 ---- a/dlls/wined3d/arb_program_shader.c -+++ b/dlls/wined3d/arb_program_shader.c -@@ -684,7 +684,7 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, - { - const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; - const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog; -- UINT rt_height = state->fb->render_targets[0]->height; -+ UINT rt_height = state->fb.render_targets[0]->height; - - /* Load DirectX 9 float constants for pixel shader */ - priv->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, -@@ -4712,7 +4712,7 @@ static void shader_arb_select(void *shader_priv, struct wined3d_context *context - } - else - { -- UINT rt_height = state->fb->render_targets[0]->height; -+ UINT rt_height = state->fb.render_targets[0]->height; - shader_arb_ps_local_constants(compiled, context, state, rt_height); - } - -diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c -index 6d08df9..104172f 100644 ---- a/dlls/wined3d/context.c -+++ b/dlls/wined3d/context.c -@@ -1506,6 +1506,12 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, - goto out; - } - -+ ret->current_fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(*ret->current_fb.render_targets) * gl_info->limits.buffers); -+ ret->current_fb.rt_size = gl_info->limits.buffers; -+ if (!ret->current_fb.render_targets) -+ goto out; -+ - /* Initialize the texture unit mapping to a 1:1 mapping */ - for (s = 0; s < MAX_COMBINED_SAMPLERS; ++s) - { -@@ -1833,6 +1839,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, - out: - device->shader_backend->shader_free_context_data(ret); - device->adapter->fragment_pipe->free_context_data(ret); -+ HeapFree(GetProcessHeap(), 0, ret->current_fb.render_targets); - HeapFree(GetProcessHeap(), 0, ret->free_event_queries); - HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries); - HeapFree(GetProcessHeap(), 0, ret->free_timestamp_queries); -@@ -1867,6 +1874,7 @@ void context_destroy(struct wined3d_device *device, struct wined3d_context *cont - - device->shader_backend->shader_free_context_data(context); - device->adapter->fragment_pipe->free_context_data(context); -+ HeapFree(GetProcessHeap(), 0, context->current_fb.render_targets); - HeapFree(GetProcessHeap(), 0, context->draw_buffers); - HeapFree(GetProcessHeap(), 0, context->blit_targets); - device_context_remove(device, context); -@@ -2378,7 +2386,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win - DWORD rt_mask = 0, *cur_mask; - UINT i; - -- if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != &device->fb -+ if (isStateDirty(context, STATE_FRAMEBUFFER) || !wined3d_fb_equal(fb, &context->current_fb) - || rt_count != context->gl_info->limits.buffers) - { - if (!context_validate_rt_config(rt_count, rts, dsv)) -@@ -2423,6 +2431,8 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win - rt_mask = context_generate_rt_mask_no_fbo(device, - rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); - } -+ -+ wined3d_fb_copy(&context->current_fb, fb); - } - else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO - && (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))) -@@ -2473,7 +2483,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win - static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_device *device) - { - const struct wined3d_state *state = &device->state; -- struct wined3d_rendertarget_view **rts = state->fb->render_targets; -+ struct wined3d_rendertarget_view **rts = state->fb.render_targets; - struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; - DWORD rt_mask, rt_mask_bits; - unsigned int i; -@@ -2503,7 +2513,7 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const - void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) - { - const struct wined3d_device *device = context->swapchain->device; -- const struct wined3d_fb_state *fb = state->fb; -+ const struct wined3d_fb_state *fb = &state->fb; - DWORD rt_mask = find_draw_buffers_mask(context, device); - DWORD *cur_mask; - -@@ -2535,6 +2545,8 @@ void context_state_fb(struct wined3d_context *context, const struct wined3d_stat - context_apply_draw_buffers(context, rt_mask); - *cur_mask = rt_mask; - } -+ -+ wined3d_fb_copy(&context->current_fb, &state->fb); - } - - static void context_map_stage(struct wined3d_context *context, DWORD stage, DWORD unit) -@@ -3159,7 +3171,7 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de - { - const struct wined3d_state *state = &device->state; - const struct StateEntry *state_table = context->state_table; -- const struct wined3d_fb_state *fb = state->fb; -+ const struct wined3d_fb_state *fb = &state->fb; - unsigned int i; - WORD map; - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 316ccb8..eefa142 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -290,7 +290,7 @@ static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) - device = cs->device; - wined3d_get_draw_rect(&device->state, &draw_rect); - device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, -- &device->fb, op->rect_count, op->rects, &draw_rect, op->flags, -+ &cs->state.fb, op->rect_count, op->rects, &draw_rect, op->flags, - op->color, op->depth, op->stencil); - } - -@@ -397,7 +397,7 @@ static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const v - { - const struct wined3d_cs_set_rendertarget_view *op = data; - -- cs->state.fb->render_targets[op->view_idx] = op->view; -+ cs->state.fb.render_targets[op->view_idx] = op->view; - device_invalidate_state(cs->device, STATE_FRAMEBUFFER); - } - -@@ -420,7 +420,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const - struct wined3d_device *device = cs->device; - struct wined3d_rendertarget_view *prev; - -- if ((prev = cs->state.fb->depth_stencil)) -+ if ((prev = cs->state.fb.depth_stencil)) - { - struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev); - -@@ -436,7 +436,7 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const - } - } - -- cs->fb.depth_stencil = op->view; -+ cs->state.fb.depth_stencil = op->view; - - if (!prev != !op->view) - { -@@ -1005,7 +1005,7 @@ static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) - - state_cleanup(&cs->state); - memset(&cs->state, 0, sizeof(cs->state)); -- if (FAILED(hr = state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info, -+ if (FAILED(hr = state_init(&cs->state, &adapter->gl_info, &adapter->d3d_info, - WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) - ERR("Failed to initialize CS state, hr %#x.\n", hr); - } -@@ -1088,17 +1088,9 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) - if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs)))) - return NULL; - -- if (!(cs->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -- sizeof(*cs->fb.render_targets) * gl_info->limits.buffers))) -- { -- HeapFree(GetProcessHeap(), 0, cs); -- return NULL; -- } -- -- if (FAILED(state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info, -+ if (FAILED(state_init(&cs->state, gl_info, &device->adapter->d3d_info, - WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) - { -- HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); - HeapFree(GetProcessHeap(), 0, cs); - return NULL; - } -@@ -1119,7 +1111,6 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) - void wined3d_cs_destroy(struct wined3d_cs *cs) - { - state_cleanup(&cs->state); -- HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); - HeapFree(GetProcessHeap(), 0, cs->data); - HeapFree(GetProcessHeap(), 0, cs); - } -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index a5c1e59..42c5d14 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -865,7 +865,7 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi - BOOL ds_enable = !!swapchain->desc.enable_auto_depth_stencil; - unsigned int i; - -- if (device->fb.render_targets) -+ if (device->state.fb.render_targets) - { - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) - { -@@ -883,7 +883,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, - struct wined3d_swapchain_desc *swapchain_desc) - { - static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f}; -- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_swapchain *swapchain = NULL; - struct wined3d_context *context; - DWORD clear_flags = 0; -@@ -896,9 +895,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, - if (device->wined3d->flags & WINED3D_NO3D) - return WINED3DERR_INVALIDCALL; - -- device->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -- sizeof(*device->fb.render_targets) * gl_info->limits.buffers); -- - if (FAILED(hr = device->shader_backend->shader_alloc_private(device, - device->adapter->vertex_pipe, device->adapter->fragment_pipe))) - { -@@ -986,7 +982,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, - return WINED3D_OK; - - err_out: -- HeapFree(GetProcessHeap(), 0, device->fb.render_targets); - HeapFree(GetProcessHeap(), 0, device->swapchains); - device->swapchain_count = 0; - if (device->back_buffer_view) -@@ -1065,8 +1060,25 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) - if (device->cursor_texture) - wined3d_texture_decref(device->cursor_texture); - -+ /* Release the buffers (with sanity checks). -+ * FIXME: Move this move into a separate patch. I think the idea -+ * behind this is that those surfaces should be freed before unloading -+ * remaining resources below. */ -+ if (device->onscreen_depth_stencil) -+ { -+ surface = device->onscreen_depth_stencil; -+ device->onscreen_depth_stencil = NULL; -+ wined3d_texture_decref(surface->container); -+ } -+ - state_unbind_resources(&device->state); - -+ if (device->auto_depth_stencil_view) -+ { -+ wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); -+ device->auto_depth_stencil_view = NULL; -+ } -+ - /* Unload resources */ - LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) - { -@@ -1097,37 +1109,6 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) - * destroy the context. */ - context_release(context); - -- /* Release the buffers (with sanity checks)*/ -- if (device->onscreen_depth_stencil) -- { -- surface = device->onscreen_depth_stencil; -- device->onscreen_depth_stencil = NULL; -- wined3d_texture_decref(surface->container); -- } -- -- if (device->fb.depth_stencil) -- { -- struct wined3d_rendertarget_view *view = device->fb.depth_stencil; -- -- TRACE("Releasing depth/stencil view %p.\n", view); -- -- device->fb.depth_stencil = NULL; -- wined3d_rendertarget_view_decref(view); -- } -- -- if (device->auto_depth_stencil_view) -- { -- struct wined3d_rendertarget_view *view = device->auto_depth_stencil_view; -- -- device->auto_depth_stencil_view = NULL; -- if (wined3d_rendertarget_view_decref(view)) -- ERR("Something's still holding the auto depth/stencil view (%p).\n", view); -- } -- -- for (i = 0; i < gl_info->limits.buffers; ++i) -- { -- wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); -- } - if (device->back_buffer_view) - { - wined3d_rendertarget_view_decref(device->back_buffer_view); -@@ -1145,9 +1126,6 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) - device->swapchains = NULL; - device->swapchain_count = 0; - -- HeapFree(GetProcessHeap(), 0, device->fb.render_targets); -- device->fb.render_targets = NULL; -- - device->d3d_initialized = FALSE; - - return WINED3D_OK; -@@ -1943,7 +1921,7 @@ static void resolve_depth_buffer(struct wined3d_state *state) - || !(texture->resource.format_flags & WINED3DFMT_FLAG_DEPTH)) - return; - surface = surface_from_resource(texture->sub_resources[0]); -- if (!(depth_stencil = wined3d_rendertarget_view_get_surface(state->fb->depth_stencil))) -+ if (!(depth_stencil = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil))) - return; - - wined3d_surface_blt(surface, NULL, depth_stencil, NULL, 0, NULL, WINED3D_TEXF_POINT); -@@ -3298,6 +3276,8 @@ HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) - HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, - const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) - { -+ const struct wined3d_fb_state *fb = &device->state.fb; -+ - TRACE("device %p, rect_count %u, rects %p, flags %#x, color {%.8e, %.8e, %.8e, %.8e}, depth %.8e, stencil %u.\n", - device, rect_count, rects, flags, color->r, color->g, color->b, color->a, depth, stencil); - -@@ -3309,7 +3289,7 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou - - if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) - { -- struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; -+ struct wined3d_rendertarget_view *ds = fb->depth_stencil; - if (!ds) - { - WARN("Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL\n"); -@@ -3318,8 +3298,8 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou - } - else if (flags & WINED3DCLEAR_TARGET) - { -- if (ds->width < device->fb.render_targets[0]->width -- || ds->height < device->fb.render_targets[0]->height) -+ if (ds->width < fb->render_targets[0]->width -+ || ds->height < fb->render_targets[0]->height) - { - WARN("Silently ignoring depth and target clear with mismatching sizes\n"); - return WINED3D_OK; -@@ -3682,8 +3662,8 @@ HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device - if (state->render_states[WINED3D_RS_ZENABLE] || state->render_states[WINED3D_RS_ZWRITEENABLE] - || state->render_states[WINED3D_RS_STENCILENABLE]) - { -- struct wined3d_rendertarget_view *rt = device->fb.render_targets[0]; -- struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; -+ struct wined3d_rendertarget_view *rt = state->fb.render_targets[0]; -+ struct wined3d_rendertarget_view *ds = state->fb.depth_stencil; - - if (ds && rt && (ds->width < rt->width || ds->height < rt->height)) - { -@@ -4065,20 +4045,21 @@ struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(co - return NULL; - } - -- return device->fb.render_targets[view_idx]; -+ return device->state.fb.render_targets[view_idx]; - } - - struct wined3d_rendertarget_view * CDECL wined3d_device_get_depth_stencil_view(const struct wined3d_device *device) - { - TRACE("device %p.\n", device); - -- return device->fb.depth_stencil; -+ return device->state.fb.depth_stencil; - } - - HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device, - unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport) - { - struct wined3d_rendertarget_view *prev; -+ struct wined3d_fb_state *fb = &device->state.fb; - - TRACE("device %p, view_idx %u, view %p, set_viewport %#x.\n", - device, view_idx, view, set_viewport); -@@ -4118,13 +4099,13 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device - } - - -- prev = device->fb.render_targets[view_idx]; -+ prev = fb->render_targets[view_idx]; - if (view == prev) - return WINED3D_OK; - - if (view) - wined3d_rendertarget_view_incref(view); -- device->fb.render_targets[view_idx] = view; -+ fb->render_targets[view_idx] = view; - wined3d_cs_emit_set_rendertarget_view(device->cs, view_idx, view); - /* Release after the assignment, to prevent device_resource_released() - * from seeing the surface as still in use. */ -@@ -4136,18 +4117,19 @@ HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device - - void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view) - { -+ struct wined3d_fb_state *fb = &device->state.fb; - struct wined3d_rendertarget_view *prev; - - TRACE("device %p, view %p.\n", device, view); - -- prev = device->fb.depth_stencil; -+ prev = fb->depth_stencil; - if (prev == view) - { - TRACE("Trying to do a NOP SetRenderTarget operation.\n"); - return; - } - -- if ((device->fb.depth_stencil = view)) -+ if ((fb->depth_stencil = view)) - wined3d_rendertarget_view_incref(view); - wined3d_cs_emit_set_depth_stencil_view(device->cs, view); - if (prev) -@@ -4511,10 +4493,9 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - wined3d_texture_decref(device->cursor_texture); - device->cursor_texture = NULL; - } -- state_unbind_resources(&device->state); - } - -- if (device->fb.render_targets) -+ if (device->state.fb.render_targets) - { - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) - { -@@ -4523,6 +4504,11 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - } - wined3d_device_set_depth_stencil_view(device, NULL); - -+ if (reset_state) -+ { -+ state_unbind_resources(&device->state); -+ } -+ - if (device->onscreen_depth_stencil) - { - wined3d_texture_decref(device->onscreen_depth_stencil->container); -@@ -4741,7 +4727,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - if (device->d3d_initialized) - delete_opengl_contexts(device, swapchain); - -- if (FAILED(hr = state_init(&device->state, &device->fb, &device->adapter->gl_info, -+ if (FAILED(hr = state_init(&device->state, &device->adapter->gl_info, - &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) - ERR("Failed to initialize device state, hr %#x.\n", hr); - device->update_state = &device->state; -@@ -4750,22 +4736,21 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - } - else if (device->back_buffer_view) - { -- struct wined3d_rendertarget_view *view = device->back_buffer_view; - struct wined3d_state *state = &device->state; - -- wined3d_device_set_rendertarget_view(device, 0, view, FALSE); -+ wined3d_device_set_rendertarget_view(device, 0, device->back_buffer_view, FALSE); - - /* Note the min_z / max_z is not reset. */ - state->viewport.x = 0; - state->viewport.y = 0; -- state->viewport.width = view->width; -- state->viewport.height = view->height; -+ state->viewport.width = swapchain->desc.backbuffer_width; -+ state->viewport.height = swapchain->desc.backbuffer_height; - wined3d_cs_emit_set_viewport(device->cs, &state->viewport); - - state->scissor_rect.top = 0; - state->scissor_rect.left = 0; -- state->scissor_rect.right = view->width; -- state->scissor_rect.bottom = view->height; -+ state->scissor_rect.right = swapchain->desc.backbuffer_width; -+ state->scissor_rect.bottom = swapchain->desc.backbuffer_height; - wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); - } - -@@ -4853,17 +4838,17 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso - - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) - { -- if (wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]) == surface) -+ if (wined3d_rendertarget_view_get_surface(device->state.fb.render_targets[i]) == surface) - { - ERR("Surface %p is still in use as render target %u.\n", surface, i); -- device->fb.render_targets[i] = NULL; -+ device->state.fb.render_targets[i] = NULL; - } - } - -- if (wined3d_rendertarget_view_get_surface(device->fb.depth_stencil) == surface) -+ if (wined3d_rendertarget_view_get_surface(device->state.fb.depth_stencil) == surface) - { - ERR("Surface %p is still in use as depth/stencil buffer.\n", surface); -- device->fb.depth_stencil = NULL; -+ device->state.fb.depth_stencil = NULL; - } - } - break; -@@ -5026,7 +5011,7 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, - - device->blitter = adapter->blitter; - -- if (FAILED(hr = state_init(&device->state, &device->fb, &adapter->gl_info, -+ if (FAILED(hr = state_init(&device->state, &adapter->gl_info, - &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) - { - ERR("Failed to initialize device state, hr %#x.\n", hr); -diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c -index 4b01b7d..7e3a7f7 100644 ---- a/dlls/wined3d/drawprim.c -+++ b/dlls/wined3d/drawprim.c -@@ -611,7 +611,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co - - if (!index_count) return; - -- context = context_acquire(device, wined3d_rendertarget_view_get_surface(device->fb.render_targets[0])); -+ context = context_acquire(device, wined3d_rendertarget_view_get_surface(state->fb.render_targets[0])); - if (!context->valid) - { - context_release(context); -@@ -622,7 +622,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co - - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) - { -- struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]); -+ struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(state->fb.render_targets[i]); - if (target && target->resource.format->id != WINED3DFMT_NULL) - { - if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) -@@ -637,16 +637,16 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co - } - } - -- if (device->fb.depth_stencil) -+ if (state->fb.depth_stencil) - { - /* Note that this depends on the context_acquire() call above to set - * context->render_offscreen properly. We don't currently take the - * Z-compare function into account, but we could skip loading the - * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note - * that we never copy the stencil data.*/ -- DWORD location = context->render_offscreen ? device->fb.depth_stencil->resource->draw_binding -+ DWORD location = context->render_offscreen ? state->fb.depth_stencil->resource->draw_binding - : WINED3D_LOCATION_DRAWABLE; -- struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil); -+ struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil); - - if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) - { -@@ -679,9 +679,9 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co - return; - } - -- if (device->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE]) -+ if (state->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE]) - { -- struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil); -+ struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil); - DWORD location = context->render_offscreen ? ds->container->resource.draw_binding : WINED3D_LOCATION_DRAWABLE; - - surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); -diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c -index 44e7090..787f64a 100644 ---- a/dlls/wined3d/glsl_shader.c -+++ b/dlls/wined3d/glsl_shader.c -@@ -1626,7 +1626,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont - const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; - const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; - const struct wined3d_gl_info *gl_info = context->gl_info; -- const struct wined3d_fb_state *fb = &shader->device->fb; -+ const struct wined3d_fb_state *fb = &state->fb; - unsigned int i, extra_constants_needed = 0; - const struct wined3d_shader_lconst *lconst; - const char *prefix; -diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c -index c3a842e..ae3770d 100644 ---- a/dlls/wined3d/shader.c -+++ b/dlls/wined3d/shader.c -@@ -2411,7 +2411,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 - memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */ - if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && state->render_states[WINED3D_RS_SRGBWRITEENABLE]) - { -- unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; -+ unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; - if (rt_fmt_flags & WINED3DFMT_FLAG_SRGB_WRITE) - { - static unsigned int warned = 0; -diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c -index 2be3cab..e789786 100644 ---- a/dlls/wined3d/state.c -+++ b/dlls/wined3d/state.c -@@ -105,7 +105,7 @@ static void state_zenable(struct wined3d_context *context, const struct wined3d_ - const struct wined3d_gl_info *gl_info = context->gl_info; - - /* No z test without depth stencil buffers */ -- if (!state->fb->depth_stencil) -+ if (!state->fb.depth_stencil) - { - TRACE("No Z buffer - disabling depth test\n"); - zenable = WINED3D_ZB_FALSE; -@@ -367,8 +367,8 @@ static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_fo - - static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) - { -- const struct wined3d_format *rt_format = state->fb->render_targets[0]->format; -- unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; -+ const struct wined3d_format *rt_format = state->fb.render_targets[0]->format; -+ unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; - const struct wined3d_gl_info *gl_info = context->gl_info; - GLenum srcBlend, dstBlend; - enum wined3d_blend d3d_blend; -@@ -813,7 +813,7 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ - GLint depthFail_ccw; - - /* No stencil test without a stencil buffer. */ -- if (!state->fb->depth_stencil) -+ if (!state->fb.depth_stencil) - { - gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST); - checkGLcall("glDisable GL_STENCIL_TEST"); -@@ -909,7 +909,7 @@ static void state_stencil(struct wined3d_context *context, const struct wined3d_ - - static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) - { -- DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; -+ DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; - const struct wined3d_gl_info *gl_info = context->gl_info; - - GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); -@@ -923,7 +923,7 @@ static void state_stencilwrite2s(struct wined3d_context *context, const struct w - - static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) - { -- DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; -+ DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; - const struct wined3d_gl_info *gl_info = context->gl_info; - - gl_info->gl_ops.gl.p_glStencilMask(mask); -@@ -1650,7 +1650,7 @@ static void state_depthbias(struct wined3d_context *context, const struct wined3 - if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS] - || state->render_states[WINED3D_RS_DEPTHBIAS]) - { -- const struct wined3d_rendertarget_view *depth = state->fb->depth_stencil; -+ const struct wined3d_rendertarget_view *depth = state->fb.depth_stencil; - float scale; - - union -@@ -4543,7 +4543,7 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine - - static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) - { -- const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; -+ const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_viewport vp = state->viewport; - -@@ -4721,7 +4721,7 @@ static void scissorrect(struct wined3d_context *context, const struct wined3d_st - } - else - { -- const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; -+ const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; - UINT height; - UINT width; - -@@ -4785,7 +4785,7 @@ static void psorigin(struct wined3d_context *context, const struct wined3d_state - - void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) - { -- unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; -+ unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; - const struct wined3d_gl_info *gl_info = context->gl_info; - - TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); -diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c -index cb3d494..6b348b8 100644 ---- a/dlls/wined3d/stateblock.c -+++ b/dlls/wined3d/stateblock.c -@@ -464,6 +464,7 @@ void state_unbind_resources(struct wined3d_state *state) - struct wined3d_texture *texture; - struct wined3d_buffer *buffer; - struct wined3d_shader *shader; -+ struct wined3d_rendertarget_view *view; - unsigned int i, j; - - if ((decl = state->vertex_declaration)) -@@ -540,6 +541,31 @@ void state_unbind_resources(struct wined3d_state *state) - } - } - } -+ -+ if (state->fb.depth_stencil) -+ { -+ view = state->fb.depth_stencil; -+ -+ TRACE("Releasing depth/stencil buffer %p.\n", view); -+ -+ state->fb.depth_stencil = NULL; -+ wined3d_rendertarget_view_decref(view); -+ } -+ -+ if (state->fb.render_targets) -+ { -+ for (i = 0; i < state->fb.rt_size; i++) -+ { -+ view = state->fb.render_targets[i]; -+ TRACE("Setting rendertarget %u to NULL\n", i); -+ state->fb.render_targets[i] = NULL; -+ if (view) -+ { -+ TRACE("Releasing the rendertarget view at %p\n", view); -+ wined3d_rendertarget_view_decref(view); -+ } -+ } -+ } - } - - void state_cleanup(struct wined3d_state *state) -@@ -567,6 +593,7 @@ void state_cleanup(struct wined3d_state *state) - - HeapFree(GetProcessHeap(), 0, state->vs_consts_f); - HeapFree(GetProcessHeap(), 0, state->ps_consts_f); -+ HeapFree(GetProcessHeap(), 0, state->fb.render_targets); - } - - ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock) -@@ -1310,14 +1337,12 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d - } - } - --HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, -- const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, -- DWORD flags) -+HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl_info, -+ const struct wined3d_d3d_info *d3d_info, DWORD flags) - { - unsigned int i; - - state->flags = flags; -- state->fb = fb; - - for (i = 0; i < LIGHTMAP_SIZE; i++) - { -@@ -1335,6 +1360,15 @@ HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, - return E_OUTOFMEMORY; - } - -+ if (!(state->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(*state->fb.render_targets) * gl_info->limits.buffers))) -+ { -+ HeapFree(GetProcessHeap(), 0, state->ps_consts_f); -+ HeapFree(GetProcessHeap(), 0, state->vs_consts_f); -+ return E_OUTOFMEMORY; -+ } -+ state->fb.rt_size = gl_info->limits.buffers; -+ - if (flags & WINED3D_STATE_INIT_DEFAULT) - state_init_default(state, gl_info); - -@@ -1345,12 +1379,13 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, - struct wined3d_device *device, enum wined3d_stateblock_type type) - { - HRESULT hr; -+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; - - stateblock->ref = 1; - stateblock->device = device; - -- if (FAILED(hr = state_init(&stateblock->state, NULL, &device->adapter->gl_info, d3d_info, 0))) -+ if (FAILED(hr = state_init(&stateblock->state, gl_info, d3d_info, 0))) - return hr; - - if (FAILED(hr = stateblock_allocate_shader_constants(stateblock))) -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index de8d6dc..db36a59 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -3283,8 +3283,8 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE - enum wined3d_texture_filter_type filter) - { - struct wined3d_device *device = dst_surface->resource.device; -- const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]); - struct wined3d_swapchain *src_swapchain, *dst_swapchain; -+ const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->state.fb.render_targets[0]); - - TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, blt_fx %p, filter %s.\n", - dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), -diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c -index b826445..e1e705b 100644 ---- a/dlls/wined3d/swapchain.c -+++ b/dlls/wined3d/swapchain.c -@@ -427,7 +427,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT - { - struct wined3d_surface *back_buffer = surface_from_resource( - wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); -- const struct wined3d_fb_state *fb = &swapchain->device->fb; -+ const struct wined3d_fb_state *fb = &swapchain->device->state.fb; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - struct wined3d_surface *front; -diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c -index 4ddfead..32519eb 100644 ---- a/dlls/wined3d/utils.c -+++ b/dlls/wined3d/utils.c -@@ -3733,7 +3733,7 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w - float y_offset = context->render_offscreen - ? (center_offset - (2.0f * y) - h) / h - : (center_offset - (2.0f * y) - h) / -h; -- enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ? -+ enum wined3d_depth_buffer_type zenable = state->fb.depth_stencil ? - state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; - float z_scale = zenable ? 2.0f : 0.0f; - float z_offset = zenable ? -1.0f : 0.0f; -@@ -4325,7 +4325,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d - unsigned int i; - DWORD ttff; - DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; -- unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; -+ unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_d3d_info *d3d_info = context->d3d_info; - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 720eb3a..6a10ad7 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -1149,6 +1149,36 @@ struct wined3d_timestamp_query - void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; - void context_free_timestamp_query(struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; - -+struct wined3d_fb_state -+{ -+ struct wined3d_rendertarget_view **render_targets; -+ struct wined3d_rendertarget_view *depth_stencil; -+ UINT rt_size; -+}; -+ -+static inline BOOL wined3d_fb_equal(const struct wined3d_fb_state *fb1, const struct wined3d_fb_state *fb2) -+{ -+ UINT i; -+ -+ if (fb1->depth_stencil != fb2->depth_stencil) -+ return FALSE; -+ if (fb1->rt_size != fb2->rt_size) -+ return FALSE; -+ for (i = 0; i < fb1->rt_size; i++) -+ if (fb1->render_targets[i] != fb2->render_targets[i]) -+ return FALSE; -+ return TRUE; -+} -+ -+static inline void wined3d_fb_copy(struct wined3d_fb_state *dst, const struct wined3d_fb_state *src) -+{ -+ UINT i; -+ -+ dst->depth_stencil = src->depth_stencil; -+ for (i = 0; i < min(dst->rt_size, src->rt_size); i++) -+ dst->render_targets[i] = src->render_targets[i]; -+} -+ - struct wined3d_context - { - const struct wined3d_gl_info *gl_info; -@@ -1163,6 +1193,7 @@ struct wined3d_context - DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */ - DWORD numDirtyEntries; - DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ -+ struct wined3d_fb_state current_fb; - - struct wined3d_swapchain *swapchain; - struct wined3d_surface *current_rt; -@@ -1264,12 +1295,6 @@ struct wined3d_context - GLuint dummy_arbfp_prog; - }; - --struct wined3d_fb_state --{ -- struct wined3d_rendertarget_view **render_targets; -- struct wined3d_rendertarget_view *depth_stencil; --}; -- - typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id); - - struct StateEntry -@@ -1986,7 +2011,7 @@ struct wined3d_stream_state - struct wined3d_state - { - DWORD flags; -- const struct wined3d_fb_state *fb; -+ struct wined3d_fb_state fb; - - struct wined3d_vertex_declaration *vertex_declaration; - struct wined3d_stream_output stream_output[MAX_STREAM_OUT]; -@@ -2092,7 +2117,6 @@ struct wined3d_device - struct wine_rb_tree samplers; - - /* Render Target Support */ -- struct wined3d_fb_state fb; - struct wined3d_surface *onscreen_depth_stencil; - struct wined3d_rendertarget_view *auto_depth_stencil_view; - -@@ -2608,9 +2632,8 @@ struct wined3d_stateblock - void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN; - - void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; --HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, -- const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, -- DWORD flags) DECLSPEC_HIDDEN; -+HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl_info, -+ const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; - void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; - - struct wined3d_cs_ops -@@ -2623,7 +2646,6 @@ struct wined3d_cs - { - const struct wined3d_cs_ops *ops; - struct wined3d_device *device; -- struct wined3d_fb_state fb; - struct wined3d_state state; - - size_t data_size; --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0038-wined3d-Preload-buffers-if-streamsrc-is-not-dirty.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0038-wined3d-Preload-buffers-if-streamsrc-is-not-dirty.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0038-wined3d-Preload-buffers-if-streamsrc-is-not-dirty.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0038-wined3d-Preload-buffers-if-streamsrc-is-not-dirty.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,65 @@ +From e2f09806ffc0332e4b3fdb3a6112ad9a2bedb1c2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sun, 7 Jul 2013 12:06:31 +0200 +Subject: wined3d: Preload buffers if streamsrc is not dirty + +FIXME: Merge this with the preload calls done by +context_update_stream_info, preload only used buffers + +FIXME2: Merge this patch with the patch that removes +PreLoad from buffer_unmap + +FIXME3: There may be more unintended consequences of calling preload +here... +--- + dlls/wined3d/buffer.c | 2 +- + dlls/wined3d/context.c | 6 +++++- + dlls/wined3d/wined3d_private.h | 1 - + 3 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 4e91176..7eef51e 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -711,7 +711,7 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined + checkGLcall("glUnmapBuffer"); + } + +-void buffer_mark_used(struct wined3d_buffer *buffer) ++static void buffer_mark_used(struct wined3d_buffer *buffer) + { + buffer->flags &= ~(WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); + } +diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c +index 46aa0cc..116bf67 100644 +--- a/dlls/wined3d/context.c ++++ b/dlls/wined3d/context.c +@@ -3227,8 +3227,12 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de + for (i = 0, map = context->stream_info.use_map; map; map >>= 1, ++i) + { + if (map & 1) +- buffer_mark_used(state->streams[context->stream_info.elements[i].stream_idx].buffer); ++ buffer_internal_preload(state->streams[context->stream_info.elements[i].stream_idx].buffer, ++ context, state); + } ++ /* PreLoad may kick buffers out of vram. */ ++ if (isStateDirty(context, STATE_STREAMSRC)) ++ context_update_stream_info(context, state); + } + if (state->index_buffer) + { +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index d320a62..4bbfe42 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2786,7 +2786,6 @@ void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *co + BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *context) DECLSPEC_HIDDEN; + void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, + const struct wined3d_state *state) DECLSPEC_HIDDEN; +-void buffer_mark_used(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; + HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, + const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN; + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0039-wined3d-Get-rid-of-state-access-in-shader_generate_g.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0039-wined3d-Get-rid-of-state-access-in-shader_generate_g.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0039-wined3d-Get-rid-of-state-access-in-shader_generate_g.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0039-wined3d-Get-rid-of-state-access-in-shader_generate_g.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -From ffb226d59c82df5c438b47a1a3d7ae29dc98f861 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 20 Dec 2012 14:19:52 +0100 -Subject: wined3d: Get rid of state access in shader_generate_glsl_declarations - ---- - dlls/wined3d/glsl_shader.c | 21 ++++++--------------- - 1 file changed, 6 insertions(+), 15 deletions(-) - -diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c -index eddabee..edc8ce4 100644 ---- a/dlls/wined3d/glsl_shader.c -+++ b/dlls/wined3d/glsl_shader.c -@@ -1592,11 +1592,9 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont - const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv) - { - const struct wined3d_shader_version *version = ®_maps->shader_version; -- const struct wined3d_state *state = &shader->device->state; - const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; - const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; - const struct wined3d_gl_info *gl_info = context->gl_info; -- const struct wined3d_fb_state *fb = &state->fb; - unsigned int i, extra_constants_needed = 0; - const struct wined3d_shader_lconst *lconst; - const char *prefix; -@@ -1870,7 +1868,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont - { - UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input); - -- if (use_vs(state)) -+ if (ps_args->vp_mode == vertexshader) - declare_in_varying(gl_info, buffer, FALSE, "vec4 %s_link[%u];\n", prefix, in_count); - shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); - } -@@ -1911,21 +1909,14 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont - } - else - { -- float ycorrection[] = -- { -- context->render_offscreen ? 0.0f : fb->render_targets[0]->height, -- context->render_offscreen ? 1.0f : -1.0f, -- 0.0f, -- 0.0f, -- }; -- - /* This happens because we do not have proper tracking of the - * constant registers that are actually used, only the max -- * limit of the shader version. */ -+ * limit of the shader version. -+ * -+ * FIXME 2: This is wrong, there's no need to do this. Get rid of -+ * it and just create the uniform. -+ */ - FIXME("Cannot find a free uniform for vpos correction params\n"); -- shader_addline(buffer, "const vec4 ycorrection = "); -- shader_glsl_append_imm_vec4(buffer, ycorrection); -- shader_addline(buffer, ";\n"); - } - shader_addline(buffer, "vec4 vpos;\n"); - } --- -2.6.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0039-wined3d-Hackily-introduce-a-multithreaded-command-st.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0039-wined3d-Hackily-introduce-a-multithreaded-command-st.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0039-wined3d-Hackily-introduce-a-multithreaded-command-st.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0039-wined3d-Hackily-introduce-a-multithreaded-command-st.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,888 @@ +From 37df70888f1e9c12f63d5fc3a511ec34fce4b10d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 1 Oct 2013 14:31:56 +0200 +Subject: wined3d: Hackily introduce a multithreaded command stream + +--- + dlls/wined3d/cs.c | 380 ++++++++++++++++++++++++++++++++++++----- + dlls/wined3d/wined3d_main.c | 9 + + dlls/wined3d/wined3d_private.h | 18 ++ + 3 files changed, 368 insertions(+), 39 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index daebc94..40c04db 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -24,8 +24,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); + + #define WINED3D_INITIAL_CS_SIZE 4096 + ++static CRITICAL_SECTION wined3d_cs_list_mutex; ++static CRITICAL_SECTION_DEBUG wined3d_cs_list_mutex_debug = ++{ ++ 0, 0, &wined3d_cs_list_mutex, ++ {&wined3d_cs_list_mutex_debug.ProcessLocksList, ++ &wined3d_cs_list_mutex_debug.ProcessLocksList}, ++ 0, 0, {(DWORD_PTR)(__FILE__ ": wined3d_cs_list_mutex")} ++}; ++static CRITICAL_SECTION wined3d_cs_list_mutex = {&wined3d_cs_list_mutex_debug, -1, 0, 0, 0, 0}; ++ + enum wined3d_cs_op + { ++ WINED3D_CS_OP_FENCE, + WINED3D_CS_OP_PRESENT, + WINED3D_CS_OP_CLEAR, + WINED3D_CS_OP_DRAW, +@@ -52,6 +63,18 @@ enum wined3d_cs_op + WINED3D_CS_OP_SET_COLOR_KEY, + WINED3D_CS_OP_SET_MATERIAL, + WINED3D_CS_OP_RESET_STATE, ++ WINED3D_CS_OP_STOP, ++}; ++ ++struct wined3d_cs_stop ++{ ++ enum wined3d_cs_op opcode; ++}; ++ ++struct wined3d_cs_fence ++{ ++ enum wined3d_cs_op opcode; ++ BOOL *signalled; + }; + + struct wined3d_cs_present +@@ -102,7 +125,7 @@ struct wined3d_cs_set_viewport + struct wined3d_cs_set_scissor_rect + { + enum wined3d_cs_op opcode; +- const RECT *rect; ++ RECT rect; + }; + + struct wined3d_cs_set_rendertarget_view +@@ -230,20 +253,20 @@ struct wined3d_cs_set_transform + { + enum wined3d_cs_op opcode; + enum wined3d_transform_state state; +- const struct wined3d_matrix *matrix; ++ struct wined3d_matrix matrix; + }; + + struct wined3d_cs_set_clip_plane + { + enum wined3d_cs_op opcode; + UINT plane_idx; +- const struct wined3d_vec4 *plane; ++ struct wined3d_vec4 plane; + }; + + struct wined3d_cs_set_material + { + enum wined3d_cs_op opcode; +- const struct wined3d_material *material; ++ struct wined3d_material material; + }; + + struct wined3d_cs_reset_state +@@ -251,7 +274,134 @@ struct wined3d_cs_reset_state + enum wined3d_cs_op opcode; + }; + +-static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) ++/* FIXME: The list synchronization probably isn't particularly fast. */ ++static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) ++{ ++ EnterCriticalSection(&wined3d_cs_list_mutex); ++ list_add_tail(&list->blocks, &block->entry); ++ LeaveCriticalSection(&wined3d_cs_list_mutex); ++} ++ ++static struct wined3d_cs_block *wined3d_cs_list_dequeue(struct wined3d_cs_list *list) ++{ ++ struct list *head; ++ ++ EnterCriticalSection(&wined3d_cs_list_mutex); ++ if (!(head = list_head(&list->blocks))) ++ { ++ LeaveCriticalSection(&wined3d_cs_list_mutex); ++ return NULL; ++ } ++ list_remove(head); ++ LeaveCriticalSection(&wined3d_cs_list_mutex); ++ ++ return LIST_ENTRY(head, struct wined3d_cs_block, entry); ++} ++ ++static struct wined3d_cs_block *wined3d_cs_list_dequeue_blocking(struct wined3d_cs_list *list) ++{ ++ struct wined3d_cs_block *block; ++ ++ /* FIXME: Use an event to wait after a couple of spins. */ ++ for (;;) ++ { ++ if ((block = wined3d_cs_list_dequeue(list))) ++ return block; ++ } ++} ++ ++static void wined3d_cs_list_init(struct wined3d_cs_list *list) ++{ ++ list_init(&list->blocks); ++} ++ ++static struct wined3d_cs_block *wined3d_cs_get_thread_block(const struct wined3d_cs *cs) ++{ ++ return TlsGetValue(cs->tls_idx); ++} ++ ++static void wined3d_cs_set_thread_block(const struct wined3d_cs *cs, struct wined3d_cs_block *block) ++{ ++ if (!TlsSetValue(cs->tls_idx, block)) ++ ERR("Failed to set thread block.\n"); ++} ++ ++static void wined3d_cs_flush(struct wined3d_cs *cs) ++{ ++ wined3d_cs_list_enqueue(&cs->exec_list, wined3d_cs_get_thread_block(cs)); ++ wined3d_cs_set_thread_block(cs, NULL); ++} ++ ++static struct wined3d_cs_block *wined3d_cs_get_block(struct wined3d_cs *cs) ++{ ++ struct wined3d_cs_block *block; ++ ++ if (!(block = wined3d_cs_list_dequeue(&cs->free_list))) ++ { ++ if (!(block = HeapAlloc(GetProcessHeap(), 0, sizeof(*block)))) ++ { ++ ERR("Failed to get new block.\n"); ++ return NULL; ++ } ++ } ++ ++ block->pos = 0; ++ ++ return block; ++} ++ ++static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) ++{ ++ struct wined3d_cs_block *block = wined3d_cs_get_thread_block(cs); ++ void *data; ++ ++ if (!block || block->pos + size > sizeof(block->data)) ++ { ++ if (block) ++ wined3d_cs_flush(cs); ++ block = wined3d_cs_get_block(cs); ++ wined3d_cs_set_thread_block(cs, block); ++ } ++ ++ data = &block->data[block->pos]; ++ block->pos += size; ++ ++ return data; ++} ++ ++static UINT wined3d_cs_exec_fence(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_fence *op = data; ++ ++ InterlockedExchange(op->signalled, TRUE); ++ ++ return sizeof(*op); ++} ++ ++static void wined3d_cs_emit_fence(struct wined3d_cs *cs, BOOL *signalled) ++{ ++ struct wined3d_cs_fence *op; ++ ++ *signalled = FALSE; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_FENCE; ++ op->signalled = signalled; ++} ++ ++static void wined3d_cs_flush_and_wait(struct wined3d_cs *cs) ++{ ++ BOOL fence; ++ ++ wined3d_cs_emit_fence(cs, &fence); ++ wined3d_cs_flush(cs); ++ ++ /* A busy wait should be fine, we're not supposed to have to wait very ++ * long. */ ++ while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); ++} ++ ++static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_present *op = data; + struct wined3d_swapchain *swapchain; +@@ -261,6 +411,8 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) + + swapchain->swapchain_ops->swapchain_present(swapchain, + op->src_rect, op->dst_rect, op->dirty_region, op->flags); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, +@@ -281,7 +433,7 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_clear *op = data; + struct wined3d_device *device; +@@ -292,6 +444,8 @@ static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) + device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, + &cs->state.fb, op->rect_count, op->rects, &draw_rect, op->flags, + op->color, op->depth, op->stencil); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, +@@ -311,12 +465,14 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_draw *op = data; + + draw_primitive(cs->device, op->start_idx, op->index_count, + op->start_instance, op->instance_count, op->indexed); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count, +@@ -335,12 +491,14 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_predication *op = data; + + cs->state.predicate = op->predicate; + cs->state.predicate_value = op->value; ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value) +@@ -355,12 +513,14 @@ void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_viewport *op = data; + + cs->state.viewport = *op->viewport; + device_invalidate_state(cs->device, STATE_VIEWPORT); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) +@@ -374,12 +534,14 @@ void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_vi + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_scissor_rect *op = data; + +- cs->state.scissor_rect = *op->rect; ++ cs->state.scissor_rect = op->rect; + device_invalidate_state(cs->device, STATE_SCISSORRECT); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) +@@ -388,17 +550,19 @@ void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT; +- op->rect = rect; ++ op->rect = *rect; + + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_rendertarget_view *op = data; + + cs->state.fb.render_targets[op->view_idx] = op->view; + device_invalidate_state(cs->device, STATE_FRAMEBUFFER); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx, +@@ -414,7 +578,7 @@ void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int v + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_depth_stencil_view *op = data; + struct wined3d_device *device = cs->device; +@@ -452,6 +616,8 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const + } + + device_invalidate_state(device, STATE_FRAMEBUFFER); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) +@@ -465,12 +631,14 @@ void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3 + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_vertex_declaration *op = data; + + cs->state.vertex_declaration = op->declaration; + device_invalidate_state(cs->device, STATE_VDECL); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration) +@@ -484,7 +652,7 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3 + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_stream_source *op = data; + struct wined3d_stream_state *stream; +@@ -502,6 +670,8 @@ static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void + InterlockedDecrement(&prev->resource.bind_count); + + device_invalidate_state(cs->device, STATE_STREAMSRC); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, +@@ -519,7 +689,7 @@ void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_stream_source_freq *op = data; + struct wined3d_stream_state *stream; +@@ -529,6 +699,8 @@ static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const + stream->flags = op->flags; + + device_invalidate_state(cs->device, STATE_STREAMSRC); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags) +@@ -544,7 +716,7 @@ void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_i + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_stream_output *op = data; + struct wined3d_stream_output *stream; +@@ -559,6 +731,8 @@ static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void + InterlockedIncrement(&op->buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, +@@ -575,7 +749,7 @@ void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_index_buffer *op = data; + struct wined3d_buffer *prev; +@@ -590,6 +764,8 @@ static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void * + InterlockedDecrement(&prev->resource.bind_count); + + device_invalidate_state(cs->device, STATE_INDEXBUFFER); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, +@@ -605,7 +781,7 @@ void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buff + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_constant_buffer *op = data; + struct wined3d_buffer *prev; +@@ -619,6 +795,7 @@ static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const voi + InterlockedDecrement(&prev->resource.bind_count); + + device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type)); ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, +@@ -635,7 +812,7 @@ void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_sha + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; + const struct wined3d_cs_set_texture *op = data; +@@ -710,6 +887,8 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) + + if (new_use_color_key) + device_invalidate_state(cs->device, STATE_COLOR_KEY); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture) +@@ -724,12 +903,14 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_shader_resource_view *op = data; + + cs->state.shader_resource_view[op->type][op->view_idx] = op->view; + device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type, +@@ -746,12 +927,14 @@ void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3 + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_sampler *op = data; + + cs->state.sampler[op->type][op->sampler_idx] = op->sampler; + device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type, +@@ -768,13 +951,15 @@ void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_shader *op = data; + + cs->state.shader[op->type] = op->shader; + device_invalidate_state(cs->device, STATE_SHADER(op->type)); + device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) +@@ -789,12 +974,14 @@ void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_render_state *op = data; + + cs->state.render_states[op->state] = op->value; + device_invalidate_state(cs->device, STATE_RENDER(op->state)); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value) +@@ -809,12 +996,14 @@ void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_texture_state *op = data; + + cs->state.texture_states[op->stage][op->state] = op->value; + device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state)); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, +@@ -831,12 +1020,14 @@ void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_sampler_state *op = data; + + cs->state.sampler_states[op->sampler_idx][op->state] = op->value; + device_invalidate_state(cs->device, STATE_SAMPLER(op->sampler_idx)); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, +@@ -853,13 +1044,15 @@ void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_transform *op = data; + +- cs->state.transforms[op->state] = *op->matrix; ++ cs->state.transforms[op->state] = op->matrix; + if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices)) + device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state, +@@ -870,17 +1063,19 @@ void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_TRANSFORM; + op->state = state; +- op->matrix = matrix; ++ op->matrix = *matrix; + + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_clip_plane *op = data; + +- cs->state.clip_planes[op->plane_idx] = *op->plane; ++ cs->state.clip_planes[op->plane_idx] = op->plane; + device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx)); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane) +@@ -890,12 +1085,12 @@ void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE; + op->plane_idx = plane_idx; +- op->plane = plane; ++ op->plane = *plane; + + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_color_key *op = data; + struct wined3d_texture *texture = op->texture; +@@ -956,6 +1151,8 @@ static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *dat + break; + } + } ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture, +@@ -978,12 +1175,14 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_material *op = data; + +- cs->state.material = *op->material; ++ cs->state.material = op->material; + device_invalidate_state(cs->device, STATE_MATERIAL); ++ ++ return sizeof(*op); + } + + void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material) +@@ -992,12 +1191,12 @@ void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_ma + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_MATERIAL; +- op->material = material; ++ op->material = *material; + + cs->ops->submit(cs); + } + +-static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) ++static UINT wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) + { + struct wined3d_adapter *adapter = cs->device->adapter; + HRESULT hr; +@@ -1007,6 +1206,8 @@ static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) + if (FAILED(hr = state_init(&cs->state, &adapter->gl_info, &adapter->d3d_info, + WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) + ERR("Failed to initialize CS state, hr %#x.\n", hr); ++ ++ return sizeof(struct wined3d_cs_reset_state); + } + + void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) +@@ -1019,8 +1220,9 @@ void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) + cs->ops->submit(cs); + } + +-static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = ++static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { ++ /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, + /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, + /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, + /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, +@@ -1079,6 +1281,58 @@ static const struct wined3d_cs_ops wined3d_cs_st_ops = + wined3d_cs_st_submit, + }; + ++static const struct wined3d_cs_ops wined3d_cs_mt_ops = ++{ ++ wined3d_cs_mt_require_space, ++ wined3d_cs_flush_and_wait, ++}; ++ ++/* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an ++ * OP itself. */ ++static void wined3d_cs_emit_stop(struct wined3d_cs *cs) ++{ ++ struct wined3d_cs_stop *op; ++ ++ op = wined3d_cs_mt_require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_STOP; ++ ++ wined3d_cs_flush(cs); ++} ++ ++static DWORD WINAPI wined3d_cs_run(void *thread_param) ++{ ++ struct wined3d_cs *cs = thread_param; ++ ++ TRACE("Started.\n"); ++ ++ for (;;) ++ { ++ struct wined3d_cs_block *block; ++ UINT pos = 0; ++ ++ block = wined3d_cs_list_dequeue_blocking(&cs->exec_list); ++ while (pos < block->pos) ++ { ++ enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)&block->data[pos]; ++ ++ if (opcode >= WINED3D_CS_OP_STOP) ++ { ++ if (opcode > WINED3D_CS_OP_STOP) ++ ERR("Invalid opcode %#x.\n", opcode); ++ goto done; ++ } ++ ++ pos += wined3d_cs_op_handlers[opcode](cs, &block->data[pos]); ++ } ++ ++ wined3d_cs_list_enqueue(&cs->free_list, block); ++ } ++ ++done: ++ TRACE("Stopped.\n"); ++ return 0; ++} ++ + struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) + { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; +@@ -1104,12 +1358,60 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) + return NULL; + } + ++ if ((cs->tls_idx = TlsAlloc()) == TLS_OUT_OF_INDEXES) ++ { ++ ERR("Failed to allocate cs TLS index, err %#x.\n", GetLastError()); ++ HeapFree(GetProcessHeap(), 0, cs->data); ++ HeapFree(GetProcessHeap(), 0, cs); ++ return NULL; ++ } ++ ++ if (wined3d_settings.cs_multithreaded) ++ { ++ cs->ops = &wined3d_cs_mt_ops; ++ ++ wined3d_cs_list_init(&cs->free_list); ++ wined3d_cs_list_init(&cs->exec_list); ++ ++ if (!(cs->thread = CreateThread(NULL, 0, wined3d_cs_run, cs, 0, NULL))) ++ { ++ ERR("Failed to create wined3d command stream thread.\n"); ++ if (!TlsFree(cs->tls_idx)) ++ ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); ++ HeapFree(GetProcessHeap(), 0, cs->data); ++ HeapFree(GetProcessHeap(), 0, cs); ++ return NULL; ++ } ++ } ++ + return cs; + } + + void wined3d_cs_destroy(struct wined3d_cs *cs) + { ++ DWORD ret; ++ + state_cleanup(&cs->state); ++ ++ if (wined3d_settings.cs_multithreaded) ++ { ++ wined3d_cs_emit_stop(cs); ++ ++ ret = WaitForSingleObject(cs->thread, INFINITE); ++ CloseHandle(cs->thread); ++ if (ret != WAIT_OBJECT_0) ++ ERR("Wait failed (%#x).\n", ret); ++ ++ /* FIXME: Cleanup the block lists on thread exit. */ ++#if 0 ++ wined3d_cs_list_cleanup(&cs->exec_list); ++ wined3d_cs_list_cleanup(&cs->free_list); ++#endif ++ } ++ ++ if (!TlsFree(cs->tls_idx)) ++ ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); ++ + HeapFree(GetProcessHeap(), 0, cs->data); + HeapFree(GetProcessHeap(), 0, cs); + } +diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c +index 08021a2..088e59a 100644 +--- a/dlls/wined3d/wined3d_main.c ++++ b/dlls/wined3d/wined3d_main.c +@@ -85,6 +85,7 @@ struct wined3d_settings wined3d_settings = + ~0U, /* No GS shader model limit by default. */ + ~0U, /* No PS shader model limit by default. */ + FALSE, /* 3D support enabled by default. */ ++ FALSE, /* No multithreaded CS by default. */ + }; + + struct wined3d * CDECL wined3d_create(DWORD flags) +@@ -304,6 +305,14 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) + TRACE("Disabling 3D support.\n"); + wined3d_settings.no_3d = TRUE; + } ++ if (!get_config_key(hkey, appkey, "CSMT", buffer, size) ++ && !strcmp(buffer,"enabled")) ++ { ++ TRACE("Enabling multithreaded command stream.\n"); ++ wined3d_settings.cs_multithreaded = TRUE; ++ TRACE("Enforcing strict draw ordering for multithreaded command stream.\n"); ++ wined3d_settings.strict_draw_ordering = TRUE; ++ } + } + + if (appkey) RegCloseKey( appkey ); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 59f9772..01c045b 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -279,6 +279,7 @@ struct wined3d_settings + unsigned int max_sm_gs; + unsigned int max_sm_ps; + BOOL no_3d; ++ BOOL cs_multithreaded; + }; + + extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN; +@@ -2589,6 +2590,18 @@ HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl + const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; + void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; + ++struct wined3d_cs_list ++{ ++ struct list blocks; ++}; ++ ++struct wined3d_cs_block ++{ ++ struct list entry; ++ UINT pos; ++ BYTE data[4000]; /* FIXME? The size is somewhat arbitrary. */ ++}; ++ + struct wined3d_cs_ops + { + void *(*require_space)(struct wined3d_cs *cs, size_t size); +@@ -2600,9 +2613,14 @@ struct wined3d_cs + const struct wined3d_cs_ops *ops; + struct wined3d_device *device; + struct wined3d_state state; ++ HANDLE thread; ++ DWORD tls_idx; + + size_t data_size; + void *data; ++ ++ struct wined3d_cs_list free_list; ++ struct wined3d_cs_list exec_list; + }; + + struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; +-- +2.4.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0040-wined3d-Preload-buffers-if-streamsrc-is-not-dirty.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0040-wined3d-Preload-buffers-if-streamsrc-is-not-dirty.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0040-wined3d-Preload-buffers-if-streamsrc-is-not-dirty.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0040-wined3d-Preload-buffers-if-streamsrc-is-not-dirty.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -From 3ccf9437225eff52fd9cad94d861e4d8fa2f5ec0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sun, 7 Jul 2013 12:06:31 +0200 -Subject: wined3d: Preload buffers if streamsrc is not dirty - -FIXME: Merge this with the preload calls done by -context_update_stream_info, preload only used buffers - -FIXME2: Merge this patch with the patch that removes -PreLoad from buffer_unmap - -FIXME3: There may be more unintended consequences of calling preload -here... ---- - dlls/wined3d/buffer.c | 2 +- - dlls/wined3d/context.c | 6 +++++- - dlls/wined3d/wined3d_private.h | 1 - - 3 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 2386410..3de580e 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -711,7 +711,7 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined - checkGLcall("glUnmapBuffer"); - } - --void buffer_mark_used(struct wined3d_buffer *buffer) -+static void buffer_mark_used(struct wined3d_buffer *buffer) - { - buffer->flags &= ~(WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); - } -diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c -index 2204d29..861af29 100644 ---- a/dlls/wined3d/context.c -+++ b/dlls/wined3d/context.c -@@ -2999,8 +2999,12 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de - for (i = 0, map = context->stream_info.use_map; map; map >>= 1, ++i) - { - if (map & 1) -- buffer_mark_used(state->streams[context->stream_info.elements[i].stream_idx].buffer); -+ buffer_internal_preload(state->streams[context->stream_info.elements[i].stream_idx].buffer, -+ context, state); - } -+ /* PreLoad may kick buffers out of vram. */ -+ if (isStateDirty(context, STATE_STREAMSRC)) -+ context_update_stream_info(context, state); - } - if (state->index_buffer) - { -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index fd7e8f9..69c984ba 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2686,7 +2686,6 @@ void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *co - BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *context) DECLSPEC_HIDDEN; - void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, - const struct wined3d_state *state) DECLSPEC_HIDDEN; --void buffer_mark_used(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; - - struct wined3d_rendertarget_view - { --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0040-wined3d-Wait-for-resource-updates-to-finish-when-usi.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0040-wined3d-Wait-for-resource-updates-to-finish-when-usi.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0040-wined3d-Wait-for-resource-updates-to-finish-when-usi.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0040-wined3d-Wait-for-resource-updates-to-finish-when-usi.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,190 @@ +From ff3ebefd7ff7834c3c1a7c9b7998592929e40714 Mon Sep 17 00:00:00 2001 +From: Henri Verbeet +Date: Sat, 8 Dec 2012 19:28:54 +0100 +Subject: wined3d: Wait for resource updates to finish when using the + multithreaded command stream. + +As opposed to just making sure they're submitted to the GPU for +"StrictDrawOrdering". This will eventually be disabled by default, but even +then it's probably useful for debugging. +--- + dlls/wined3d/arb_program_shader.c | 4 +++- + dlls/wined3d/buffer.c | 4 +++- + dlls/wined3d/device.c | 9 +++++++-- + dlls/wined3d/drawprim.c | 4 +++- + dlls/wined3d/surface.c | 28 +++++++++++++++++++++------- + dlls/wined3d/swapchain.c | 4 +++- + 6 files changed, 40 insertions(+), 13 deletions(-) + +diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c +index 9f29aa4..59c3409 100644 +--- a/dlls/wined3d/arb_program_shader.c ++++ b/dlls/wined3d/arb_program_shader.c +@@ -7679,7 +7679,9 @@ HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter, + /* Leave the opengl state valid for blitting */ + arbfp_blit_unset(context->gl_info); + +- if (wined3d_settings.strict_draw_ordering ++ if (wined3d_settings.cs_multithreaded) ++ context->gl_info->gl_ops.gl.p_glFinish(); ++ else if (wined3d_settings.strict_draw_ordering + || (dst_surface->container->swapchain + && (dst_surface->container->swapchain->front_buffer == dst_surface->container))) + context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 3de580e..41bc6f0 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -1100,7 +1100,9 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) + } + + GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint)); +- if (wined3d_settings.strict_draw_ordering) ++ if (wined3d_settings.cs_multithreaded) ++ gl_info->gl_ops.gl.p_glFinish(); ++ else if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + context_release(context); + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index e33d0c0..b9935e0 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -463,7 +463,9 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c + } + } + +- if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET ++ if (wined3d_settings.cs_multithreaded) ++ gl_info->gl_ops.gl.p_glFinish(); ++ else if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET + && target->container->swapchain && target->container->swapchain->front_buffer == target->container)) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + +@@ -3247,7 +3249,10 @@ HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) + + context = context_acquire(device, NULL); + /* We only have to do this if we need to read the, swapbuffers performs a flush for us */ +- context->gl_info->gl_ops.gl.p_glFlush(); ++ if (wined3d_settings.cs_multithreaded) ++ context->gl_info->gl_ops.gl.p_glFinish(); ++ else ++ context->gl_info->gl_ops.gl.p_glFlush(); + /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever + * fails. */ + context_release(context); +diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c +index 98261f9..d3a9e03 100644 +--- a/dlls/wined3d/drawprim.c ++++ b/dlls/wined3d/drawprim.c +@@ -781,7 +781,9 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co + wined3d_event_query_issue(context->buffer_queries[i], device); + } + +- if (wined3d_settings.strict_draw_ordering) ++ if (wined3d_settings.cs_multithreaded) ++ gl_info->gl_ops.gl.p_glFinish(); ++ else if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + + context_release(context); +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 1aafda1..caf9618 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -687,7 +687,9 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, + dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, gl_mask, GL_NEAREST); + checkGLcall("glBlitFramebuffer()"); + +- if (wined3d_settings.strict_draw_ordering) ++ if (wined3d_settings.cs_multithreaded) ++ gl_info->gl_ops.gl.p_glFinish(); ++ else if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + + context_release(context); +@@ -816,7 +818,9 @@ static void surface_blt_fbo(const struct wined3d_device *device, + dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, GL_COLOR_BUFFER_BIT, gl_filter); + checkGLcall("glBlitFramebuffer()"); + +- if (wined3d_settings.strict_draw_ordering ++ if (wined3d_settings.cs_multithreaded) ++ gl_info->gl_ops.gl.p_glFinish(); ++ else if (wined3d_settings.strict_draw_ordering + || (dst_location == WINED3D_LOCATION_DRAWABLE + && dst_surface->container->swapchain->front_buffer == dst_surface->container)) + gl_info->gl_ops.gl.p_glFlush(); +@@ -1393,7 +1397,9 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w + checkGLcall("glBindBuffer"); + } + +- if (wined3d_settings.strict_draw_ordering) ++ if (wined3d_settings.cs_multithreaded) ++ gl_info->gl_ops.gl.p_glFinish(); ++ else if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); + + if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE) +@@ -3337,7 +3343,9 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st + checkGLcall("glDeleteTextures(1, &backup)"); + } + +- if (wined3d_settings.strict_draw_ordering) ++ if (wined3d_settings.cs_multithreaded) ++ gl_info->gl_ops.gl.p_glFinish(); ++ else if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + + context_release(context); +@@ -3452,7 +3460,9 @@ static void surface_blt_to_drawable(const struct wined3d_device *device, + /* Leave the opengl state valid for blitting */ + device->blitter->unset_shader(context->gl_info); + +- if (wined3d_settings.strict_draw_ordering ++ if (wined3d_settings.cs_multithreaded) ++ gl_info->gl_ops.gl.p_glFinish(); ++ else if (wined3d_settings.strict_draw_ordering + || (dst_surface->container->swapchain + && dst_surface->container->swapchain->front_buffer == dst_surface->container)) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ +@@ -3873,7 +3883,9 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co + + context_invalidate_state(context, STATE_FRAMEBUFFER); + +- if (wined3d_settings.strict_draw_ordering) ++ if (wined3d_settings.cs_multithreaded) ++ gl_info->gl_ops.gl.p_glFinish(); ++ else if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + } + else if (location == WINED3D_LOCATION_DRAWABLE) +@@ -3889,7 +3901,9 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co + + context_invalidate_state(context, STATE_FRAMEBUFFER); + +- if (wined3d_settings.strict_draw_ordering) ++ if (wined3d_settings.cs_multithreaded) ++ gl_info->gl_ops.gl.p_glFinish(); ++ else if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + } + else +diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c +index ed2964e..60504ef 100644 +--- a/dlls/wined3d/swapchain.c ++++ b/dlls/wined3d/swapchain.c +@@ -531,8 +531,10 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT + swapchain_blit(swapchain, context, &src_rect, &dst_rect); + } + +- if (swapchain->num_contexts > 1) ++ if (wined3d_settings.cs_multithreaded) + gl_info->gl_ops.gl.p_glFinish(); ++ else if (swapchain->num_contexts > 1) ++ gl_info->gl_ops.gl.p_glFlush(); + + /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */ + gl_info->gl_ops.wgl.p_wglSwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */ +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0041-wined3d-Don-t-store-pointers-in-struct-wined3d_cs_pr.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0041-wined3d-Don-t-store-pointers-in-struct-wined3d_cs_pr.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0041-wined3d-Don-t-store-pointers-in-struct-wined3d_cs_pr.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0041-wined3d-Don-t-store-pointers-in-struct-wined3d_cs_pr.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,82 @@ +From 72ea1f2801924c3856ae7a2b8045beef511b6e9e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 12 Mar 2013 11:34:58 -0700 +Subject: wined3d: Don't store pointers in struct wined3d_cs_present + +--- + dlls/wined3d/cs.c | 34 +++++++++++++++++++++++++++------- + 1 file changed, 27 insertions(+), 7 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 1122073..b30e62a 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -76,15 +76,19 @@ struct wined3d_cs_fence + BOOL *signalled; + }; + ++#define CS_PRESENT_SRC_RECT 1 ++#define CS_PRESENT_DST_RECT 2 ++#define CS_PRESENT_DIRTY_RGN 4 + struct wined3d_cs_present + { + enum wined3d_cs_op opcode; + HWND dst_window_override; + struct wined3d_swapchain *swapchain; +- const RECT *src_rect; +- const RECT *dst_rect; +- const RGNDATA *dirty_region; ++ RECT src_rect; ++ RECT dst_rect; ++ RGNDATA dirty_region; + DWORD flags; ++ DWORD set_data; + }; + + struct wined3d_cs_clear +@@ -395,12 +399,15 @@ static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_present *op = data; + struct wined3d_swapchain *swapchain; ++ const RECT *src_rect = op->set_data & CS_PRESENT_SRC_RECT ? &op->src_rect : NULL; ++ const RECT *dst_rect = op->set_data & CS_PRESENT_DST_RECT ? &op->dst_rect : NULL; ++ const RGNDATA *dirty_region = op->set_data & CS_PRESENT_DIRTY_RGN ? &op->dirty_region : NULL; + + swapchain = op->swapchain; + wined3d_swapchain_set_window(swapchain, op->dst_window_override); + + swapchain->swapchain_ops->swapchain_present(swapchain, +- op->src_rect, op->dst_rect, op->dirty_region, op->flags); ++ src_rect, dst_rect, dirty_region, op->flags); + + return sizeof(*op); + } +@@ -415,9 +422,22 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw + op->opcode = WINED3D_CS_OP_PRESENT; + op->dst_window_override = dst_window_override; + op->swapchain = swapchain; +- op->src_rect = src_rect; +- op->dst_rect = dst_rect; +- op->dirty_region = dirty_region; ++ op->set_data = 0; ++ if (src_rect) ++ { ++ op->src_rect = *src_rect; ++ op->set_data |= CS_PRESENT_SRC_RECT; ++ } ++ if (dst_rect) ++ { ++ op->dst_rect = *dst_rect; ++ op->set_data |= CS_PRESENT_DST_RECT; ++ } ++ if (dirty_region) ++ { ++ op->dirty_region = *dirty_region; ++ op->set_data = CS_PRESENT_DIRTY_RGN; ++ } + op->flags = flags; + + cs->ops->submit(cs); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0041-wined3d-Hackily-introduce-a-multithreaded-command-st.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0041-wined3d-Hackily-introduce-a-multithreaded-command-st.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0041-wined3d-Hackily-introduce-a-multithreaded-command-st.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0041-wined3d-Hackily-introduce-a-multithreaded-command-st.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,888 +0,0 @@ -From 37df70888f1e9c12f63d5fc3a511ec34fce4b10d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 1 Oct 2013 14:31:56 +0200 -Subject: wined3d: Hackily introduce a multithreaded command stream - ---- - dlls/wined3d/cs.c | 380 ++++++++++++++++++++++++++++++++++++----- - dlls/wined3d/wined3d_main.c | 9 + - dlls/wined3d/wined3d_private.h | 18 ++ - 3 files changed, 368 insertions(+), 39 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index daebc94..40c04db 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -24,8 +24,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); - - #define WINED3D_INITIAL_CS_SIZE 4096 - -+static CRITICAL_SECTION wined3d_cs_list_mutex; -+static CRITICAL_SECTION_DEBUG wined3d_cs_list_mutex_debug = -+{ -+ 0, 0, &wined3d_cs_list_mutex, -+ {&wined3d_cs_list_mutex_debug.ProcessLocksList, -+ &wined3d_cs_list_mutex_debug.ProcessLocksList}, -+ 0, 0, {(DWORD_PTR)(__FILE__ ": wined3d_cs_list_mutex")} -+}; -+static CRITICAL_SECTION wined3d_cs_list_mutex = {&wined3d_cs_list_mutex_debug, -1, 0, 0, 0, 0}; -+ - enum wined3d_cs_op - { -+ WINED3D_CS_OP_FENCE, - WINED3D_CS_OP_PRESENT, - WINED3D_CS_OP_CLEAR, - WINED3D_CS_OP_DRAW, -@@ -52,6 +63,18 @@ enum wined3d_cs_op - WINED3D_CS_OP_SET_COLOR_KEY, - WINED3D_CS_OP_SET_MATERIAL, - WINED3D_CS_OP_RESET_STATE, -+ WINED3D_CS_OP_STOP, -+}; -+ -+struct wined3d_cs_stop -+{ -+ enum wined3d_cs_op opcode; -+}; -+ -+struct wined3d_cs_fence -+{ -+ enum wined3d_cs_op opcode; -+ BOOL *signalled; - }; - - struct wined3d_cs_present -@@ -102,7 +125,7 @@ struct wined3d_cs_set_viewport - struct wined3d_cs_set_scissor_rect - { - enum wined3d_cs_op opcode; -- const RECT *rect; -+ RECT rect; - }; - - struct wined3d_cs_set_rendertarget_view -@@ -230,20 +253,20 @@ struct wined3d_cs_set_transform - { - enum wined3d_cs_op opcode; - enum wined3d_transform_state state; -- const struct wined3d_matrix *matrix; -+ struct wined3d_matrix matrix; - }; - - struct wined3d_cs_set_clip_plane - { - enum wined3d_cs_op opcode; - UINT plane_idx; -- const struct wined3d_vec4 *plane; -+ struct wined3d_vec4 plane; - }; - - struct wined3d_cs_set_material - { - enum wined3d_cs_op opcode; -- const struct wined3d_material *material; -+ struct wined3d_material material; - }; - - struct wined3d_cs_reset_state -@@ -251,7 +274,134 @@ struct wined3d_cs_reset_state - enum wined3d_cs_op opcode; - }; - --static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) -+/* FIXME: The list synchronization probably isn't particularly fast. */ -+static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) -+{ -+ EnterCriticalSection(&wined3d_cs_list_mutex); -+ list_add_tail(&list->blocks, &block->entry); -+ LeaveCriticalSection(&wined3d_cs_list_mutex); -+} -+ -+static struct wined3d_cs_block *wined3d_cs_list_dequeue(struct wined3d_cs_list *list) -+{ -+ struct list *head; -+ -+ EnterCriticalSection(&wined3d_cs_list_mutex); -+ if (!(head = list_head(&list->blocks))) -+ { -+ LeaveCriticalSection(&wined3d_cs_list_mutex); -+ return NULL; -+ } -+ list_remove(head); -+ LeaveCriticalSection(&wined3d_cs_list_mutex); -+ -+ return LIST_ENTRY(head, struct wined3d_cs_block, entry); -+} -+ -+static struct wined3d_cs_block *wined3d_cs_list_dequeue_blocking(struct wined3d_cs_list *list) -+{ -+ struct wined3d_cs_block *block; -+ -+ /* FIXME: Use an event to wait after a couple of spins. */ -+ for (;;) -+ { -+ if ((block = wined3d_cs_list_dequeue(list))) -+ return block; -+ } -+} -+ -+static void wined3d_cs_list_init(struct wined3d_cs_list *list) -+{ -+ list_init(&list->blocks); -+} -+ -+static struct wined3d_cs_block *wined3d_cs_get_thread_block(const struct wined3d_cs *cs) -+{ -+ return TlsGetValue(cs->tls_idx); -+} -+ -+static void wined3d_cs_set_thread_block(const struct wined3d_cs *cs, struct wined3d_cs_block *block) -+{ -+ if (!TlsSetValue(cs->tls_idx, block)) -+ ERR("Failed to set thread block.\n"); -+} -+ -+static void wined3d_cs_flush(struct wined3d_cs *cs) -+{ -+ wined3d_cs_list_enqueue(&cs->exec_list, wined3d_cs_get_thread_block(cs)); -+ wined3d_cs_set_thread_block(cs, NULL); -+} -+ -+static struct wined3d_cs_block *wined3d_cs_get_block(struct wined3d_cs *cs) -+{ -+ struct wined3d_cs_block *block; -+ -+ if (!(block = wined3d_cs_list_dequeue(&cs->free_list))) -+ { -+ if (!(block = HeapAlloc(GetProcessHeap(), 0, sizeof(*block)))) -+ { -+ ERR("Failed to get new block.\n"); -+ return NULL; -+ } -+ } -+ -+ block->pos = 0; -+ -+ return block; -+} -+ -+static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) -+{ -+ struct wined3d_cs_block *block = wined3d_cs_get_thread_block(cs); -+ void *data; -+ -+ if (!block || block->pos + size > sizeof(block->data)) -+ { -+ if (block) -+ wined3d_cs_flush(cs); -+ block = wined3d_cs_get_block(cs); -+ wined3d_cs_set_thread_block(cs, block); -+ } -+ -+ data = &block->data[block->pos]; -+ block->pos += size; -+ -+ return data; -+} -+ -+static UINT wined3d_cs_exec_fence(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_fence *op = data; -+ -+ InterlockedExchange(op->signalled, TRUE); -+ -+ return sizeof(*op); -+} -+ -+static void wined3d_cs_emit_fence(struct wined3d_cs *cs, BOOL *signalled) -+{ -+ struct wined3d_cs_fence *op; -+ -+ *signalled = FALSE; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_FENCE; -+ op->signalled = signalled; -+} -+ -+static void wined3d_cs_flush_and_wait(struct wined3d_cs *cs) -+{ -+ BOOL fence; -+ -+ wined3d_cs_emit_fence(cs, &fence); -+ wined3d_cs_flush(cs); -+ -+ /* A busy wait should be fine, we're not supposed to have to wait very -+ * long. */ -+ while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); -+} -+ -+static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_present *op = data; - struct wined3d_swapchain *swapchain; -@@ -261,6 +411,8 @@ static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) - - swapchain->swapchain_ops->swapchain_present(swapchain, - op->src_rect, op->dst_rect, op->dirty_region, op->flags); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, -@@ -281,7 +433,7 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_clear *op = data; - struct wined3d_device *device; -@@ -292,6 +444,8 @@ static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) - device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, - &cs->state.fb, op->rect_count, op->rects, &draw_rect, op->flags, - op->color, op->depth, op->stencil); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, -@@ -311,12 +465,14 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_draw *op = data; - - draw_primitive(cs->device, op->start_idx, op->index_count, - op->start_instance, op->instance_count, op->indexed); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count, -@@ -335,12 +491,14 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_predication *op = data; - - cs->state.predicate = op->predicate; - cs->state.predicate_value = op->value; -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value) -@@ -355,12 +513,14 @@ void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_viewport *op = data; - - cs->state.viewport = *op->viewport; - device_invalidate_state(cs->device, STATE_VIEWPORT); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) -@@ -374,12 +534,14 @@ void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_vi - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_scissor_rect *op = data; - -- cs->state.scissor_rect = *op->rect; -+ cs->state.scissor_rect = op->rect; - device_invalidate_state(cs->device, STATE_SCISSORRECT); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) -@@ -388,17 +550,19 @@ void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT; -- op->rect = rect; -+ op->rect = *rect; - - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_rendertarget_view *op = data; - - cs->state.fb.render_targets[op->view_idx] = op->view; - device_invalidate_state(cs->device, STATE_FRAMEBUFFER); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx, -@@ -414,7 +578,7 @@ void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int v - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_depth_stencil_view *op = data; - struct wined3d_device *device = cs->device; -@@ -452,6 +616,8 @@ static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const - } - - device_invalidate_state(device, STATE_FRAMEBUFFER); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) -@@ -465,12 +631,14 @@ void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3 - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_vertex_declaration *op = data; - - cs->state.vertex_declaration = op->declaration; - device_invalidate_state(cs->device, STATE_VDECL); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration) -@@ -484,7 +652,7 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3 - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_stream_source *op = data; - struct wined3d_stream_state *stream; -@@ -502,6 +670,8 @@ static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void - InterlockedDecrement(&prev->resource.bind_count); - - device_invalidate_state(cs->device, STATE_STREAMSRC); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, -@@ -519,7 +689,7 @@ void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_stream_source_freq *op = data; - struct wined3d_stream_state *stream; -@@ -529,6 +699,8 @@ static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const - stream->flags = op->flags; - - device_invalidate_state(cs->device, STATE_STREAMSRC); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags) -@@ -544,7 +716,7 @@ void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_i - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_stream_output *op = data; - struct wined3d_stream_output *stream; -@@ -559,6 +731,8 @@ static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void - InterlockedIncrement(&op->buffer->resource.bind_count); - if (prev) - InterlockedDecrement(&prev->resource.bind_count); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, -@@ -575,7 +749,7 @@ void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_index_buffer *op = data; - struct wined3d_buffer *prev; -@@ -590,6 +764,8 @@ static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void * - InterlockedDecrement(&prev->resource.bind_count); - - device_invalidate_state(cs->device, STATE_INDEXBUFFER); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, -@@ -605,7 +781,7 @@ void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buff - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_constant_buffer *op = data; - struct wined3d_buffer *prev; -@@ -619,6 +795,7 @@ static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const voi - InterlockedDecrement(&prev->resource.bind_count); - - device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type)); -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, -@@ -635,7 +812,7 @@ void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_sha - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; - const struct wined3d_cs_set_texture *op = data; -@@ -710,6 +887,8 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) - - if (new_use_color_key) - device_invalidate_state(cs->device, STATE_COLOR_KEY); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture) -@@ -724,12 +903,14 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_shader_resource_view *op = data; - - cs->state.shader_resource_view[op->type][op->view_idx] = op->view; - device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type, -@@ -746,12 +927,14 @@ void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3 - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_sampler *op = data; - - cs->state.sampler[op->type][op->sampler_idx] = op->sampler; - device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type, -@@ -768,13 +951,15 @@ void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_shader *op = data; - - cs->state.shader[op->type] = op->shader; - device_invalidate_state(cs->device, STATE_SHADER(op->type)); - device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) -@@ -789,12 +974,14 @@ void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_render_state *op = data; - - cs->state.render_states[op->state] = op->value; - device_invalidate_state(cs->device, STATE_RENDER(op->state)); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value) -@@ -809,12 +996,14 @@ void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_texture_state *op = data; - - cs->state.texture_states[op->stage][op->state] = op->value; - device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state)); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, -@@ -831,12 +1020,14 @@ void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_sampler_state *op = data; - - cs->state.sampler_states[op->sampler_idx][op->state] = op->value; - device_invalidate_state(cs->device, STATE_SAMPLER(op->sampler_idx)); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, -@@ -853,13 +1044,15 @@ void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_transform *op = data; - -- cs->state.transforms[op->state] = *op->matrix; -+ cs->state.transforms[op->state] = op->matrix; - if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices)) - device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state, -@@ -870,17 +1063,19 @@ void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_TRANSFORM; - op->state = state; -- op->matrix = matrix; -+ op->matrix = *matrix; - - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_clip_plane *op = data; - -- cs->state.clip_planes[op->plane_idx] = *op->plane; -+ cs->state.clip_planes[op->plane_idx] = op->plane; - device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx)); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane) -@@ -890,12 +1085,12 @@ void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE; - op->plane_idx = plane_idx; -- op->plane = plane; -+ op->plane = *plane; - - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_color_key *op = data; - struct wined3d_texture *texture = op->texture; -@@ -956,6 +1151,8 @@ static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *dat - break; - } - } -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture, -@@ -978,12 +1175,14 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_material *op = data; - -- cs->state.material = *op->material; -+ cs->state.material = op->material; - device_invalidate_state(cs->device, STATE_MATERIAL); -+ -+ return sizeof(*op); - } - - void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material) -@@ -992,12 +1191,12 @@ void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_ma - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_MATERIAL; -- op->material = material; -+ op->material = *material; - - cs->ops->submit(cs); - } - --static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) -+static UINT wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) - { - struct wined3d_adapter *adapter = cs->device->adapter; - HRESULT hr; -@@ -1007,6 +1206,8 @@ static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) - if (FAILED(hr = state_init(&cs->state, &adapter->gl_info, &adapter->d3d_info, - WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) - ERR("Failed to initialize CS state, hr %#x.\n", hr); -+ -+ return sizeof(struct wined3d_cs_reset_state); - } - - void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) -@@ -1019,8 +1220,9 @@ void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) - cs->ops->submit(cs); - } - --static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = -+static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { -+ /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, - /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, - /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, - /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, -@@ -1079,6 +1281,58 @@ static const struct wined3d_cs_ops wined3d_cs_st_ops = - wined3d_cs_st_submit, - }; - -+static const struct wined3d_cs_ops wined3d_cs_mt_ops = -+{ -+ wined3d_cs_mt_require_space, -+ wined3d_cs_flush_and_wait, -+}; -+ -+/* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an -+ * OP itself. */ -+static void wined3d_cs_emit_stop(struct wined3d_cs *cs) -+{ -+ struct wined3d_cs_stop *op; -+ -+ op = wined3d_cs_mt_require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_STOP; -+ -+ wined3d_cs_flush(cs); -+} -+ -+static DWORD WINAPI wined3d_cs_run(void *thread_param) -+{ -+ struct wined3d_cs *cs = thread_param; -+ -+ TRACE("Started.\n"); -+ -+ for (;;) -+ { -+ struct wined3d_cs_block *block; -+ UINT pos = 0; -+ -+ block = wined3d_cs_list_dequeue_blocking(&cs->exec_list); -+ while (pos < block->pos) -+ { -+ enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)&block->data[pos]; -+ -+ if (opcode >= WINED3D_CS_OP_STOP) -+ { -+ if (opcode > WINED3D_CS_OP_STOP) -+ ERR("Invalid opcode %#x.\n", opcode); -+ goto done; -+ } -+ -+ pos += wined3d_cs_op_handlers[opcode](cs, &block->data[pos]); -+ } -+ -+ wined3d_cs_list_enqueue(&cs->free_list, block); -+ } -+ -+done: -+ TRACE("Stopped.\n"); -+ return 0; -+} -+ - struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) - { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -@@ -1104,12 +1358,60 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) - return NULL; - } - -+ if ((cs->tls_idx = TlsAlloc()) == TLS_OUT_OF_INDEXES) -+ { -+ ERR("Failed to allocate cs TLS index, err %#x.\n", GetLastError()); -+ HeapFree(GetProcessHeap(), 0, cs->data); -+ HeapFree(GetProcessHeap(), 0, cs); -+ return NULL; -+ } -+ -+ if (wined3d_settings.cs_multithreaded) -+ { -+ cs->ops = &wined3d_cs_mt_ops; -+ -+ wined3d_cs_list_init(&cs->free_list); -+ wined3d_cs_list_init(&cs->exec_list); -+ -+ if (!(cs->thread = CreateThread(NULL, 0, wined3d_cs_run, cs, 0, NULL))) -+ { -+ ERR("Failed to create wined3d command stream thread.\n"); -+ if (!TlsFree(cs->tls_idx)) -+ ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); -+ HeapFree(GetProcessHeap(), 0, cs->data); -+ HeapFree(GetProcessHeap(), 0, cs); -+ return NULL; -+ } -+ } -+ - return cs; - } - - void wined3d_cs_destroy(struct wined3d_cs *cs) - { -+ DWORD ret; -+ - state_cleanup(&cs->state); -+ -+ if (wined3d_settings.cs_multithreaded) -+ { -+ wined3d_cs_emit_stop(cs); -+ -+ ret = WaitForSingleObject(cs->thread, INFINITE); -+ CloseHandle(cs->thread); -+ if (ret != WAIT_OBJECT_0) -+ ERR("Wait failed (%#x).\n", ret); -+ -+ /* FIXME: Cleanup the block lists on thread exit. */ -+#if 0 -+ wined3d_cs_list_cleanup(&cs->exec_list); -+ wined3d_cs_list_cleanup(&cs->free_list); -+#endif -+ } -+ -+ if (!TlsFree(cs->tls_idx)) -+ ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); -+ - HeapFree(GetProcessHeap(), 0, cs->data); - HeapFree(GetProcessHeap(), 0, cs); - } -diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c -index 08021a2..088e59a 100644 ---- a/dlls/wined3d/wined3d_main.c -+++ b/dlls/wined3d/wined3d_main.c -@@ -85,6 +85,7 @@ struct wined3d_settings wined3d_settings = - ~0U, /* No GS shader model limit by default. */ - ~0U, /* No PS shader model limit by default. */ - FALSE, /* 3D support enabled by default. */ -+ FALSE, /* No multithreaded CS by default. */ - }; - - struct wined3d * CDECL wined3d_create(DWORD flags) -@@ -304,6 +305,14 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) - TRACE("Disabling 3D support.\n"); - wined3d_settings.no_3d = TRUE; - } -+ if (!get_config_key(hkey, appkey, "CSMT", buffer, size) -+ && !strcmp(buffer,"enabled")) -+ { -+ TRACE("Enabling multithreaded command stream.\n"); -+ wined3d_settings.cs_multithreaded = TRUE; -+ TRACE("Enforcing strict draw ordering for multithreaded command stream.\n"); -+ wined3d_settings.strict_draw_ordering = TRUE; -+ } - } - - if (appkey) RegCloseKey( appkey ); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 59f9772..01c045b 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -279,6 +279,7 @@ struct wined3d_settings - unsigned int max_sm_gs; - unsigned int max_sm_ps; - BOOL no_3d; -+ BOOL cs_multithreaded; - }; - - extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN; -@@ -2589,6 +2590,18 @@ HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl - const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; - void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; - -+struct wined3d_cs_list -+{ -+ struct list blocks; -+}; -+ -+struct wined3d_cs_block -+{ -+ struct list entry; -+ UINT pos; -+ BYTE data[4000]; /* FIXME? The size is somewhat arbitrary. */ -+}; -+ - struct wined3d_cs_ops - { - void *(*require_space)(struct wined3d_cs *cs, size_t size); -@@ -2600,9 +2613,14 @@ struct wined3d_cs - const struct wined3d_cs_ops *ops; - struct wined3d_device *device; - struct wined3d_state state; -+ HANDLE thread; -+ DWORD tls_idx; - - size_t data_size; - void *data; -+ -+ struct wined3d_cs_list free_list; -+ struct wined3d_cs_list exec_list; - }; - - struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; --- -2.4.4 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0042-wined3d-Don-t-put-rectangle-pointers-into-wined3d_cs.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0042-wined3d-Don-t-put-rectangle-pointers-into-wined3d_cs.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0042-wined3d-Don-t-put-rectangle-pointers-into-wined3d_cs.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0042-wined3d-Don-t-put-rectangle-pointers-into-wined3d_cs.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,76 @@ +From 6a9d163ab416a7d1c44a11b75716ee32fb3c9f0b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 2 Apr 2013 16:17:34 +0200 +Subject: wined3d: Don't put rectangle pointers into wined3d_cs_clear + +--- + dlls/wined3d/cs.c | 13 ++++++++----- + dlls/wined3d/device.c | 2 ++ + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index b30e62a..bac3fdb 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -95,11 +95,11 @@ struct wined3d_cs_clear + { + enum wined3d_cs_op opcode; + DWORD rect_count; +- const RECT *rects; + DWORD flags; + const struct wined3d_color *color; + float depth; + DWORD stencil; ++ RECT rects[1]; + }; + + struct wined3d_cs_draw +@@ -448,25 +448,28 @@ static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) + const struct wined3d_cs_clear *op = data; + struct wined3d_device *device; + RECT draw_rect; ++ unsigned int extra_rects = op->rect_count ? op->rect_count - 1 : 0; + + device = cs->device; + wined3d_get_draw_rect(&device->state, &draw_rect); + device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, +- &cs->state.fb, op->rect_count, op->rects, &draw_rect, op->flags, ++ &cs->state.fb, op->rect_count, op->rect_count ? op->rects : NULL, &draw_rect, op->flags, + op->color, op->depth, op->stencil); + +- return sizeof(*op); ++ return sizeof(*op) + sizeof(*op->rects) * extra_rects; + } + + void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, + DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) + { + struct wined3d_cs_clear *op; ++ unsigned int extra_rects = rect_count ? rect_count - 1 : 0; + +- op = cs->ops->require_space(cs, sizeof(*op)); ++ op = cs->ops->require_space(cs, sizeof(*op) + sizeof(*op->rects) * extra_rects); + op->opcode = WINED3D_CS_OP_CLEAR; + op->rect_count = rect_count; +- op->rects = rects; ++ if (rect_count) ++ memcpy(op->rects, rects, rect_count * sizeof(*rects)); + op->flags = flags; + op->color = color; + op->depth = depth; +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 08422ad..3bb3cf0 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -3292,6 +3292,8 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou + WARN("Rects is %p, but rect_count is 0, ignoring clear\n", rects); + return WINED3D_OK; + } ++ if (rect_count && !rects) ++ rect_count = 0; + + if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) + { +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0042-wined3d-Wait-for-resource-updates-to-finish-when-usi.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0042-wined3d-Wait-for-resource-updates-to-finish-when-usi.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0042-wined3d-Wait-for-resource-updates-to-finish-when-usi.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0042-wined3d-Wait-for-resource-updates-to-finish-when-usi.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,190 +0,0 @@ -From ff3ebefd7ff7834c3c1a7c9b7998592929e40714 Mon Sep 17 00:00:00 2001 -From: Henri Verbeet -Date: Sat, 8 Dec 2012 19:28:54 +0100 -Subject: wined3d: Wait for resource updates to finish when using the - multithreaded command stream. - -As opposed to just making sure they're submitted to the GPU for -"StrictDrawOrdering". This will eventually be disabled by default, but even -then it's probably useful for debugging. ---- - dlls/wined3d/arb_program_shader.c | 4 +++- - dlls/wined3d/buffer.c | 4 +++- - dlls/wined3d/device.c | 9 +++++++-- - dlls/wined3d/drawprim.c | 4 +++- - dlls/wined3d/surface.c | 28 +++++++++++++++++++++------- - dlls/wined3d/swapchain.c | 4 +++- - 6 files changed, 40 insertions(+), 13 deletions(-) - -diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c -index 9f29aa4..59c3409 100644 ---- a/dlls/wined3d/arb_program_shader.c -+++ b/dlls/wined3d/arb_program_shader.c -@@ -7679,7 +7679,9 @@ HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter, - /* Leave the opengl state valid for blitting */ - arbfp_blit_unset(context->gl_info); - -- if (wined3d_settings.strict_draw_ordering -+ if (wined3d_settings.cs_multithreaded) -+ context->gl_info->gl_ops.gl.p_glFinish(); -+ else if (wined3d_settings.strict_draw_ordering - || (dst_surface->container->swapchain - && (dst_surface->container->swapchain->front_buffer == dst_surface->container))) - context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 3de580e..41bc6f0 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -1100,7 +1100,9 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) - } - - GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint)); -- if (wined3d_settings.strict_draw_ordering) -+ if (wined3d_settings.cs_multithreaded) -+ gl_info->gl_ops.gl.p_glFinish(); -+ else if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - context_release(context); - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index e33d0c0..b9935e0 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -463,7 +463,9 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c - } - } - -- if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET -+ if (wined3d_settings.cs_multithreaded) -+ gl_info->gl_ops.gl.p_glFinish(); -+ else if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET - && target->container->swapchain && target->container->swapchain->front_buffer == target->container)) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - -@@ -3247,7 +3249,10 @@ HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) - - context = context_acquire(device, NULL); - /* We only have to do this if we need to read the, swapbuffers performs a flush for us */ -- context->gl_info->gl_ops.gl.p_glFlush(); -+ if (wined3d_settings.cs_multithreaded) -+ context->gl_info->gl_ops.gl.p_glFinish(); -+ else -+ context->gl_info->gl_ops.gl.p_glFlush(); - /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever - * fails. */ - context_release(context); -diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c -index 98261f9..d3a9e03 100644 ---- a/dlls/wined3d/drawprim.c -+++ b/dlls/wined3d/drawprim.c -@@ -781,7 +781,9 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co - wined3d_event_query_issue(context->buffer_queries[i], device); - } - -- if (wined3d_settings.strict_draw_ordering) -+ if (wined3d_settings.cs_multithreaded) -+ gl_info->gl_ops.gl.p_glFinish(); -+ else if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - context_release(context); -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 1aafda1..caf9618 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -687,7 +687,9 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, - dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, gl_mask, GL_NEAREST); - checkGLcall("glBlitFramebuffer()"); - -- if (wined3d_settings.strict_draw_ordering) -+ if (wined3d_settings.cs_multithreaded) -+ gl_info->gl_ops.gl.p_glFinish(); -+ else if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - context_release(context); -@@ -816,7 +818,9 @@ static void surface_blt_fbo(const struct wined3d_device *device, - dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, GL_COLOR_BUFFER_BIT, gl_filter); - checkGLcall("glBlitFramebuffer()"); - -- if (wined3d_settings.strict_draw_ordering -+ if (wined3d_settings.cs_multithreaded) -+ gl_info->gl_ops.gl.p_glFinish(); -+ else if (wined3d_settings.strict_draw_ordering - || (dst_location == WINED3D_LOCATION_DRAWABLE - && dst_surface->container->swapchain->front_buffer == dst_surface->container)) - gl_info->gl_ops.gl.p_glFlush(); -@@ -1393,7 +1397,9 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w - checkGLcall("glBindBuffer"); - } - -- if (wined3d_settings.strict_draw_ordering) -+ if (wined3d_settings.cs_multithreaded) -+ gl_info->gl_ops.gl.p_glFinish(); -+ else if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); - - if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE) -@@ -3337,7 +3343,9 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st - checkGLcall("glDeleteTextures(1, &backup)"); - } - -- if (wined3d_settings.strict_draw_ordering) -+ if (wined3d_settings.cs_multithreaded) -+ gl_info->gl_ops.gl.p_glFinish(); -+ else if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - context_release(context); -@@ -3452,7 +3460,9 @@ static void surface_blt_to_drawable(const struct wined3d_device *device, - /* Leave the opengl state valid for blitting */ - device->blitter->unset_shader(context->gl_info); - -- if (wined3d_settings.strict_draw_ordering -+ if (wined3d_settings.cs_multithreaded) -+ gl_info->gl_ops.gl.p_glFinish(); -+ else if (wined3d_settings.strict_draw_ordering - || (dst_surface->container->swapchain - && dst_surface->container->swapchain->front_buffer == dst_surface->container)) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ -@@ -3873,7 +3883,9 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co - - context_invalidate_state(context, STATE_FRAMEBUFFER); - -- if (wined3d_settings.strict_draw_ordering) -+ if (wined3d_settings.cs_multithreaded) -+ gl_info->gl_ops.gl.p_glFinish(); -+ else if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - } - else if (location == WINED3D_LOCATION_DRAWABLE) -@@ -3889,7 +3901,9 @@ void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_co - - context_invalidate_state(context, STATE_FRAMEBUFFER); - -- if (wined3d_settings.strict_draw_ordering) -+ if (wined3d_settings.cs_multithreaded) -+ gl_info->gl_ops.gl.p_glFinish(); -+ else if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - } - else -diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c -index ed2964e..60504ef 100644 ---- a/dlls/wined3d/swapchain.c -+++ b/dlls/wined3d/swapchain.c -@@ -531,8 +531,10 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT - swapchain_blit(swapchain, context, &src_rect, &dst_rect); - } - -- if (swapchain->num_contexts > 1) -+ if (wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFinish(); -+ else if (swapchain->num_contexts > 1) -+ gl_info->gl_ops.gl.p_glFlush(); - - /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */ - gl_info->gl_ops.wgl.p_wglSwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */ --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0043-wined3d-Don-t-store-pointers-in-struct-wined3d_cs_pr.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0043-wined3d-Don-t-store-pointers-in-struct-wined3d_cs_pr.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0043-wined3d-Don-t-store-pointers-in-struct-wined3d_cs_pr.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0043-wined3d-Don-t-store-pointers-in-struct-wined3d_cs_pr.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -From 72ea1f2801924c3856ae7a2b8045beef511b6e9e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 12 Mar 2013 11:34:58 -0700 -Subject: wined3d: Don't store pointers in struct wined3d_cs_present - ---- - dlls/wined3d/cs.c | 34 +++++++++++++++++++++++++++------- - 1 file changed, 27 insertions(+), 7 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 1122073..b30e62a 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -76,15 +76,19 @@ struct wined3d_cs_fence - BOOL *signalled; - }; - -+#define CS_PRESENT_SRC_RECT 1 -+#define CS_PRESENT_DST_RECT 2 -+#define CS_PRESENT_DIRTY_RGN 4 - struct wined3d_cs_present - { - enum wined3d_cs_op opcode; - HWND dst_window_override; - struct wined3d_swapchain *swapchain; -- const RECT *src_rect; -- const RECT *dst_rect; -- const RGNDATA *dirty_region; -+ RECT src_rect; -+ RECT dst_rect; -+ RGNDATA dirty_region; - DWORD flags; -+ DWORD set_data; - }; - - struct wined3d_cs_clear -@@ -395,12 +399,15 @@ static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_present *op = data; - struct wined3d_swapchain *swapchain; -+ const RECT *src_rect = op->set_data & CS_PRESENT_SRC_RECT ? &op->src_rect : NULL; -+ const RECT *dst_rect = op->set_data & CS_PRESENT_DST_RECT ? &op->dst_rect : NULL; -+ const RGNDATA *dirty_region = op->set_data & CS_PRESENT_DIRTY_RGN ? &op->dirty_region : NULL; - - swapchain = op->swapchain; - wined3d_swapchain_set_window(swapchain, op->dst_window_override); - - swapchain->swapchain_ops->swapchain_present(swapchain, -- op->src_rect, op->dst_rect, op->dirty_region, op->flags); -+ src_rect, dst_rect, dirty_region, op->flags); - - return sizeof(*op); - } -@@ -415,9 +422,22 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw - op->opcode = WINED3D_CS_OP_PRESENT; - op->dst_window_override = dst_window_override; - op->swapchain = swapchain; -- op->src_rect = src_rect; -- op->dst_rect = dst_rect; -- op->dirty_region = dirty_region; -+ op->set_data = 0; -+ if (src_rect) -+ { -+ op->src_rect = *src_rect; -+ op->set_data |= CS_PRESENT_SRC_RECT; -+ } -+ if (dst_rect) -+ { -+ op->dst_rect = *dst_rect; -+ op->set_data |= CS_PRESENT_DST_RECT; -+ } -+ if (dirty_region) -+ { -+ op->dirty_region = *dirty_region; -+ op->set_data = CS_PRESENT_DIRTY_RGN; -+ } - op->flags = flags; - - cs->ops->submit(cs); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0043-wined3d-Store-the-color-in-clear-ops-instead-of-a-po.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0043-wined3d-Store-the-color-in-clear-ops-instead-of-a-po.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0043-wined3d-Store-the-color-in-clear-ops-instead-of-a-po.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0043-wined3d-Store-the-color-in-clear-ops-instead-of-a-po.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,43 @@ +From 95126fce6331a34c71f5ff736192d25e78e67dde Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 2 Apr 2013 16:20:13 +0200 +Subject: wined3d: Store the color in clear ops instead of a pointer + +--- + dlls/wined3d/cs.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index bac3fdb..fa1ee3a 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -96,7 +96,7 @@ struct wined3d_cs_clear + enum wined3d_cs_op opcode; + DWORD rect_count; + DWORD flags; +- const struct wined3d_color *color; ++ struct wined3d_color color; + float depth; + DWORD stencil; + RECT rects[1]; +@@ -454,7 +454,7 @@ static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) + wined3d_get_draw_rect(&device->state, &draw_rect); + device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, + &cs->state.fb, op->rect_count, op->rect_count ? op->rects : NULL, &draw_rect, op->flags, +- op->color, op->depth, op->stencil); ++ &op->color, op->depth, op->stencil); + + return sizeof(*op) + sizeof(*op->rects) * extra_rects; + } +@@ -471,7 +471,7 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * + if (rect_count) + memcpy(op->rects, rects, rect_count * sizeof(*rects)); + op->flags = flags; +- op->color = color; ++ op->color = *color; + op->depth = depth; + op->stencil = stencil; + +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0044-wined3d-Don-t-put-rectangle-pointers-into-wined3d_cs.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0044-wined3d-Don-t-put-rectangle-pointers-into-wined3d_cs.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0044-wined3d-Don-t-put-rectangle-pointers-into-wined3d_cs.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0044-wined3d-Don-t-put-rectangle-pointers-into-wined3d_cs.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -From 6a9d163ab416a7d1c44a11b75716ee32fb3c9f0b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 2 Apr 2013 16:17:34 +0200 -Subject: wined3d: Don't put rectangle pointers into wined3d_cs_clear - ---- - dlls/wined3d/cs.c | 13 ++++++++----- - dlls/wined3d/device.c | 2 ++ - 2 files changed, 10 insertions(+), 5 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index b30e62a..bac3fdb 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -95,11 +95,11 @@ struct wined3d_cs_clear - { - enum wined3d_cs_op opcode; - DWORD rect_count; -- const RECT *rects; - DWORD flags; - const struct wined3d_color *color; - float depth; - DWORD stencil; -+ RECT rects[1]; - }; - - struct wined3d_cs_draw -@@ -448,25 +448,28 @@ static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) - const struct wined3d_cs_clear *op = data; - struct wined3d_device *device; - RECT draw_rect; -+ unsigned int extra_rects = op->rect_count ? op->rect_count - 1 : 0; - - device = cs->device; - wined3d_get_draw_rect(&device->state, &draw_rect); - device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, -- &cs->state.fb, op->rect_count, op->rects, &draw_rect, op->flags, -+ &cs->state.fb, op->rect_count, op->rect_count ? op->rects : NULL, &draw_rect, op->flags, - op->color, op->depth, op->stencil); - -- return sizeof(*op); -+ return sizeof(*op) + sizeof(*op->rects) * extra_rects; - } - - void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, - DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) - { - struct wined3d_cs_clear *op; -+ unsigned int extra_rects = rect_count ? rect_count - 1 : 0; - -- op = cs->ops->require_space(cs, sizeof(*op)); -+ op = cs->ops->require_space(cs, sizeof(*op) + sizeof(*op->rects) * extra_rects); - op->opcode = WINED3D_CS_OP_CLEAR; - op->rect_count = rect_count; -- op->rects = rects; -+ if (rect_count) -+ memcpy(op->rects, rects, rect_count * sizeof(*rects)); - op->flags = flags; - op->color = color; - op->depth = depth; -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 08422ad..3bb3cf0 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -3292,6 +3292,8 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou - WARN("Rects is %p, but rect_count is 0, ignoring clear\n", rects); - return WINED3D_OK; - } -+ if (rect_count && !rects) -+ rect_count = 0; - - if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) - { --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0044-wined3d-Pass-the-state-to-draw_primitive.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0044-wined3d-Pass-the-state-to-draw_primitive.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0044-wined3d-Pass-the-state-to-draw_primitive.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0044-wined3d-Pass-the-state-to-draw_primitive.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,263 @@ +From 78e1e4771d85128087e911b9a0ad81998fb98096 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 2 Apr 2013 17:25:19 +0200 +Subject: wined3d: Pass the state to draw_primitive + +--- + dlls/wined3d/buffer.c | 6 +++--- + dlls/wined3d/context.c | 6 +++--- + dlls/wined3d/cs.c | 2 +- + dlls/wined3d/directx.c | 2 +- + dlls/wined3d/drawprim.c | 27 +++++++++++++-------------- + dlls/wined3d/state.c | 4 ++-- + dlls/wined3d/utils.c | 2 +- + dlls/wined3d/wined3d_private.h | 8 +++++--- + 8 files changed, 29 insertions(+), 28 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 6fff047..4f4827f 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -423,7 +423,7 @@ static inline void fixup_d3dcolor(DWORD *dst_color) + { + DWORD src_color = *dst_color; + +- /* Color conversion like in drawStridedSlow. watch out for little endianity ++ /* Color conversion like in draw_strided_slow. watch out for little endianity + * If we want that stuff to work on big endian machines too we have to consider more things + * + * 0xff000000: Alpha mask +@@ -1190,11 +1190,11 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device + + dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE]; + +- /* Observations show that drawStridedSlow is faster on dynamic VBs than converting + ++ /* Observations show that draw_strided_slow is faster on dynamic VBs than converting + + * drawStridedFast (half-life 2 and others). + * + * Basically converting the vertices in the buffer is quite expensive, and observations +- * show that drawStridedSlow is faster than converting + uploading + drawStridedFast. ++ * show that draw_strided_slow is faster than converting + uploading + drawStridedFast. + * Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers. + */ + if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT]) +diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c +index c1b6e01..d9e2bc1 100644 +--- a/dlls/wined3d/context.c ++++ b/dlls/wined3d/context.c +@@ -2992,7 +2992,7 @@ static void context_update_stream_info(struct wined3d_context *context, const st + { + if (state->vertex_declaration->half_float_conv_needed && !stream_info->all_vbo) + { +- TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion.\n"); ++ TRACE("Using draw_strided_slow with vertex shaders for FLOAT16 conversion.\n"); + context->use_immediate_mode_draw = TRUE; + } + else +@@ -3167,9 +3167,9 @@ static void context_bind_shader_resources(struct wined3d_context *context, const + } + + /* Context activation is done by the caller. */ +-BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) ++BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, ++ const struct wined3d_state *state) + { +- const struct wined3d_state *state = &device->state; + const struct StateEntry *state_table = context->state_table; + const struct wined3d_fb_state *fb = &state->fb; + unsigned int i; +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 784de6e..d14fd82 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -492,7 +492,7 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_draw *op = data; + +- draw_primitive(cs->device, op->start_idx, op->index_count, ++ draw_primitive(cs->device, &cs->device->state, op->start_idx, op->index_count, + op->start_instance, op->instance_count, op->indexed); + + return sizeof(*op); +diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c +index d7f0512..71688a5 100644 +--- a/dlls/wined3d/directx.c ++++ b/dlls/wined3d/directx.c +@@ -5503,7 +5503,7 @@ static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data) + } + + /* Helper functions for providing vertex data to opengl. The arrays are initialized based on +- * the extension detection and are used in drawStridedSlow ++ * the extension detection and are used in draw_strided_slow + */ + static void WINE_GLAPI position_d3dcolor(const void *data) + { +diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c +index af51dfd..bfbdf8c 100644 +--- a/dlls/wined3d/drawprim.c ++++ b/dlls/wined3d/drawprim.c +@@ -36,7 +36,7 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); + #include + + /* Context activation is done by the caller. */ +-static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, ++static void draw_strided_fast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, + const void *idx_data, UINT start_idx, INT base_vertex_index, UINT start_instance, UINT instance_count) + { + if (idx_size) +@@ -95,7 +95,7 @@ static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primit + */ + + /* Context activation is done by the caller. */ +-static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_context *context, ++static void draw_strided_slow(const struct wined3d_state *state, struct wined3d_context *context, + const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType, + const void *idxData, UINT idxSize, UINT startIdx) + { +@@ -103,7 +103,6 @@ static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_ + const WORD *pIdxBufS = NULL; + const DWORD *pIdxBufL = NULL; + UINT vx_index; +- const struct wined3d_state *state = &device->state; + LONG SkipnStrides = startIdx; + BOOL pixelShader = use_ps(state); + BOOL specular_fog = FALSE; +@@ -453,7 +452,7 @@ static inline void send_attribute(const struct wined3d_gl_info *gl_info, + } + + /* Context activation is done by the caller. */ +-static void drawStridedSlowVs(struct wined3d_context *context, const struct wined3d_state *state, ++static void draw_strided_slow_vs(struct wined3d_context *context, const struct wined3d_state *state, + const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, + const void *idxData, UINT idxSize, UINT startIdx) + { +@@ -510,7 +509,7 @@ static void drawStridedSlowVs(struct wined3d_context *context, const struct wine + } + + /* Context activation is done by the caller. */ +-static void drawStridedInstanced(struct wined3d_context *context, const struct wined3d_state *state, ++static void draw_strided_instanced(struct wined3d_context *context, const struct wined3d_state *state, + const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, + const void *idxData, UINT idxSize, UINT startIdx, UINT base_vertex_index, UINT instance_count) + { +@@ -595,10 +594,10 @@ static void remove_vbos(struct wined3d_context *context, + } + + /* Routine common to the draw primitive and draw indexed primitive routines */ +-void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count, +- UINT start_instance, UINT instance_count, BOOL indexed) ++void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, ++ UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count, ++ BOOL indexed) + { +- const struct wined3d_state *state = &device->state; + const struct wined3d_stream_info *stream_info; + struct wined3d_event_query *ib_query = NULL; + struct wined3d_stream_info si_emulated; +@@ -672,7 +671,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co + wined3d_surface_prepare(ds, context, location); + } + +- if (!context_apply_draw_state(context, device)) ++ if (!context_apply_draw_state(context, device, state)) + { + context_release(context); + WARN("Unable to apply draw state, skipping draw.\n"); +@@ -764,28 +763,28 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co + else + WARN_(d3d_perf)("Using immediate mode with vertex shaders for half float emulation.\n"); + +- drawStridedSlowVs(context, state, stream_info, index_count, ++ draw_strided_slow_vs(context, state, stream_info, index_count, + state->gl_primitive_type, idx_data, idx_size, start_idx); + } + else + { + if (context->d3d_info->ffp_generic_attributes) +- drawStridedSlowVs(context, state, stream_info, index_count, ++ draw_strided_slow_vs(context, state, stream_info, index_count, + state->gl_primitive_type, idx_data, idx_size, start_idx); + else +- drawStridedSlow(device, context, stream_info, index_count, ++ draw_strided_slow(state, context, stream_info, index_count, + state->gl_primitive_type, idx_data, idx_size, start_idx); + } + } + else if (!gl_info->supported[ARB_INSTANCED_ARRAYS] && instance_count) + { + /* Instancing emulation by mixing immediate mode and arrays. */ +- drawStridedInstanced(context, state, stream_info, index_count, state->gl_primitive_type, ++ draw_strided_instanced(context, state, stream_info, index_count, state->gl_primitive_type, + idx_data, idx_size, start_idx, state->base_vertex_index, instance_count); + } + else + { +- drawStridedFast(gl_info, state->gl_primitive_type, index_count, idx_size, idx_data, ++ draw_strided_fast(gl_info, state->gl_primitive_type, index_count, idx_size, idx_data, + start_idx, state->base_vertex_index, start_instance, instance_count); + } + +diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c +index e789786..8362ef8 100644 +--- a/dlls/wined3d/state.c ++++ b/dlls/wined3d/state.c +@@ -1126,7 +1126,7 @@ void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_st + + case WINED3D_FOG_NONE: + /* Both are none? According to msdn the alpha channel of the specular +- * color contains a fog factor. Set it in drawStridedSlow. ++ * color contains a fog factor. Set it in draw_strided_slow. + * Same happens with Vertexfog on transformed vertices + */ + new_source = FOGSOURCE_COORD; +@@ -4187,7 +4187,7 @@ static void load_vertex_data(struct wined3d_context *context, + } + } + } else { +- /* TODO: support blends in drawStridedSlow ++ /* TODO: support blends in draw_strided_slow + * No need to write a FIXME here, this is done after the general vertex decl decoding + */ + WARN("unsupported blending in openGl\n"); +diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c +index 81af9d5..64e6d6a 100644 +--- a/dlls/wined3d/utils.c ++++ b/dlls/wined3d/utils.c +@@ -3866,7 +3866,7 @@ static void compute_texture_matrix(const struct wined3d_gl_info *gl_info, const + * check for pixel shaders, and the shader has to undo the default gl divide. + * + * A more serious problem occurs if the app passes 4 coordinates in, and the +- * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow ++ * 4th is != 1.0(opengl default). This would have to be fixed in draw_strided_slow + * or a replacement shader. */ + default: + mat._14 = mat._24 = mat._34 = 0.0f; mat._44 = 1.0f; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 2667936..2467c22 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -1021,8 +1021,9 @@ struct wined3d_stream_info + WORD use_map; /* MAX_ATTRIBS, 16 */ + }; + +-void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count, +- UINT start_instance, UINT instance_count, BOOL indexed) DECLSPEC_HIDDEN; ++void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, ++ UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count, ++ BOOL indexed) DECLSPEC_HIDDEN; + DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; + + #define eps 1e-8f +@@ -1433,7 +1434,8 @@ void context_alloc_occlusion_query(struct wined3d_context *context, + void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN; + BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_device *device, + UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN; +-BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) DECLSPEC_HIDDEN; ++BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, ++ const struct wined3d_state *state) DECLSPEC_HIDDEN; + void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, + struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN; + void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, +-- +2.6.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0045-wined3d-Store-the-color-in-clear-ops-instead-of-a-po.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0045-wined3d-Store-the-color-in-clear-ops-instead-of-a-po.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0045-wined3d-Store-the-color-in-clear-ops-instead-of-a-po.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0045-wined3d-Store-the-color-in-clear-ops-instead-of-a-po.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -From 95126fce6331a34c71f5ff736192d25e78e67dde Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 2 Apr 2013 16:20:13 +0200 -Subject: wined3d: Store the color in clear ops instead of a pointer - ---- - dlls/wined3d/cs.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index bac3fdb..fa1ee3a 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -96,7 +96,7 @@ struct wined3d_cs_clear - enum wined3d_cs_op opcode; - DWORD rect_count; - DWORD flags; -- const struct wined3d_color *color; -+ struct wined3d_color color; - float depth; - DWORD stencil; - RECT rects[1]; -@@ -454,7 +454,7 @@ static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) - wined3d_get_draw_rect(&device->state, &draw_rect); - device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, - &cs->state.fb, op->rect_count, op->rect_count ? op->rects : NULL, &draw_rect, op->flags, -- op->color, op->depth, op->stencil); -+ &op->color, op->depth, op->stencil); - - return sizeof(*op) + sizeof(*op->rects) * extra_rects; - } -@@ -471,7 +471,7 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * - if (rect_count) - memcpy(op->rects, rects, rect_count * sizeof(*rects)); - op->flags = flags; -- op->color = color; -+ op->color = *color; - op->depth = depth; - op->stencil = stencil; - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0045-wined3d-Wait-for-the-cs-before-destroying-objects.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0045-wined3d-Wait-for-the-cs-before-destroying-objects.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0045-wined3d-Wait-for-the-cs-before-destroying-objects.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0045-wined3d-Wait-for-the-cs-before-destroying-objects.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,135 @@ +From 534d7a18db58161682a42210ced42e8e7cf55ba8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 3 Apr 2013 18:01:34 +0200 +Subject: wined3d: Wait for the cs before destroying objects + +This is to avoid destroying objects that are still referenced in +commands in the cs. Later patches will migrate resource destruction to +the CS. +--- + dlls/wined3d/buffer.c | 6 ++++++ + dlls/wined3d/cs.c | 2 ++ + dlls/wined3d/shader.c | 5 +++++ + dlls/wined3d/surface.c | 6 ++++++ + dlls/wined3d/texture.c | 6 ++++++ + dlls/wined3d/vertexdeclaration.c | 5 +++++ + dlls/wined3d/wined3d_private.h | 1 + + 7 files changed, 31 insertions(+) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 8165d6b..bc34050 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -552,6 +552,12 @@ ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) + + if (!refcount) + { ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ buffer->resource.device->cs->ops->finish(buffer->resource.device->cs); ++ } ++ + if (buffer->buffer_object) + { + context = context_acquire(buffer->resource.device, NULL); +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index eac7739..8823c9a 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -1188,12 +1188,14 @@ static const struct wined3d_cs_ops wined3d_cs_st_ops = + { + wined3d_cs_st_require_space, + wined3d_cs_st_submit, ++ wined3d_cs_st_submit, + }; + + static const struct wined3d_cs_ops wined3d_cs_mt_ops = + { + wined3d_cs_mt_require_space, + wined3d_cs_flush_and_wait, ++ wined3d_cs_flush_and_wait, + }; + + /* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an +diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c +index cc969b8..0faabaa 100644 +--- a/dlls/wined3d/shader.c ++++ b/dlls/wined3d/shader.c +@@ -1957,6 +1957,11 @@ ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader) + + if (!refcount) + { ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ shader->device->cs->ops->finish(shader->device->cs); ++ } + shader_cleanup(shader); + shader->parent_ops->wined3d_object_destroyed(shader->parent); + HeapFree(GetProcessHeap(), 0, shader); +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 8fa2c9f..8f8af4d 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -42,6 +42,12 @@ static void surface_cleanup(struct wined3d_surface *surface) + + TRACE("surface %p.\n", surface); + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ surface->resource.device->cs->ops->finish(surface->resource.device->cs); ++ } ++ + if (surface->resource.buffer_object || surface->rb_multisample + || surface->rb_resolved || !list_empty(&surface->renderbuffers)) + { +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index ec5c847..68889e5 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -136,6 +136,12 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture) + + TRACE("texture %p.\n", texture); + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ texture->resource.device->cs->ops->finish(texture->resource.device->cs); ++ } ++ + for (i = 0; i < sub_count; ++i) + { + struct wined3d_resource *sub_resource = texture->sub_resources[i]; +diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c +index cf5378c..3f4d5e4 100644 +--- a/dlls/wined3d/vertexdeclaration.c ++++ b/dlls/wined3d/vertexdeclaration.c +@@ -56,6 +56,11 @@ ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration + + if (!refcount) + { ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ declaration->device->cs->ops->finish(declaration->device->cs); ++ } + HeapFree(GetProcessHeap(), 0, declaration->elements); + declaration->parent_ops->wined3d_object_destroyed(declaration->parent); + HeapFree(GetProcessHeap(), 0, declaration); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index a48cc7d..b856b6f 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2544,6 +2544,7 @@ struct wined3d_cs_ops + { + void *(*require_space)(struct wined3d_cs *cs, size_t size); + void (*submit)(struct wined3d_cs *cs); ++ void (*finish)(struct wined3d_cs *cs); + }; + + struct wined3d_cs +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0046-wined3d-Give-the-cs-its-own-state.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0046-wined3d-Give-the-cs-its-own-state.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0046-wined3d-Give-the-cs-its-own-state.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0046-wined3d-Give-the-cs-its-own-state.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,255 @@ +From 35f36ec3b2bf7fa8bdfabd7d698b118ba2030ccf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 1 Oct 2013 15:30:26 +0200 +Subject: wined3d: Give the cs its own state + +--- + dlls/wined3d/cs.c | 108 +++++++++++++++++++++++++++++++++++------ + dlls/wined3d/device.c | 3 ++ + dlls/wined3d/wined3d_private.h | 4 +- + 3 files changed, 99 insertions(+), 16 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index a8327d1..1b466c3 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -63,6 +63,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_SET_COLOR_KEY, + WINED3D_CS_OP_SET_MATERIAL, + WINED3D_CS_OP_RESET_STATE, ++ WINED3D_CS_OP_STATEBLOCK, + WINED3D_CS_OP_STOP, + }; + +@@ -278,6 +279,13 @@ struct wined3d_cs_reset_state + enum wined3d_cs_op opcode; + }; + ++struct wined3d_cs_stateblock ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_state state; ++ float vs_consts_f[256 * 4], ps_consts_f[256 * 4]; ++}; ++ + /* FIXME: The list synchronization probably isn't particularly fast. */ + static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) + { +@@ -461,7 +469,7 @@ static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) + unsigned int extra_rects = op->rect_count ? op->rect_count - 1 : 0; + + device = cs->device; +- wined3d_get_draw_rect(&device->state, &draw_rect); ++ wined3d_get_draw_rect(&cs->state, &draw_rect); + device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, + &cs->state.fb, op->rect_count, op->rect_count ? op->rects : NULL, &draw_rect, op->flags, + &op->color, op->depth, op->stencil); +@@ -492,7 +500,7 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_draw *op = data; + +- draw_primitive(cs->device, &cs->device->state, op->start_idx, op->index_count, ++ draw_primitive(cs->device, &cs->state, op->start_idx, op->index_count, + op->start_instance, op->instance_count, op->indexed); + + return sizeof(*op); +@@ -907,6 +915,72 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined + op->opcode = WINED3D_CS_OP_SET_TEXTURE; + op->stage = stage; + op->texture = texture; ++ cs->ops->submit(cs); ++} ++ ++static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_adapter *adapter = cs->device->adapter; ++ const struct wined3d_cs_stateblock *op = data; ++ UINT num_vs_consts_f = sizeof(op->vs_consts_f) / sizeof(*op->vs_consts_f) / 4; ++ UINT num_ps_consts_f = sizeof(op->ps_consts_f) / sizeof(*op->ps_consts_f) / 4; ++ ++ num_vs_consts_f = min(num_vs_consts_f, adapter->d3d_info.limits.vs_uniform_count); ++ num_ps_consts_f = min(num_ps_consts_f, adapter->d3d_info.limits.ps_uniform_count); ++ ++ /* Don't memcpy the entire struct, we'll remove single items as we add dedicated ++ * ops for setting states */ ++ ++ cs->state.base_vertex_index = op->state.base_vertex_index; ++ cs->state.load_base_vertex_index = op->state.load_base_vertex_index; ++ cs->state.gl_primitive_type = op->state.gl_primitive_type; ++ ++ memcpy(cs->state.vs_consts_b, op->state.vs_consts_b, sizeof(cs->state.vs_consts_b)); ++ memcpy(cs->state.vs_consts_i, op->state.vs_consts_i, sizeof(cs->state.vs_consts_i)); ++ memcpy(cs->state.vs_consts_f, op->state.vs_consts_f, sizeof(*cs->state.vs_consts_f) * num_vs_consts_f); ++ ++ memcpy(cs->state.ps_consts_b, op->state.ps_consts_b, sizeof(cs->state.ps_consts_b)); ++ memcpy(cs->state.ps_consts_i, op->state.ps_consts_i, sizeof(cs->state.ps_consts_i)); ++ memcpy(cs->state.ps_consts_f, op->state.ps_consts_f, sizeof(*cs->state.ps_consts_f) * num_ps_consts_f); ++ ++ memcpy(cs->state.lights, op->state.lights, sizeof(cs->state.lights)); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct wined3d_state *state) ++{ ++ const struct wined3d_device *device = cs->device; ++ const struct wined3d_adapter *adapter = device->adapter; ++ struct wined3d_cs_stateblock *op; ++ UINT num_vs_consts_f = sizeof(op->vs_consts_f) / sizeof(*op->vs_consts_f) / 4; ++ UINT num_ps_consts_f = sizeof(op->ps_consts_f) / sizeof(*op->ps_consts_f) / 4; ++ ++ num_vs_consts_f = min(num_vs_consts_f, adapter->d3d_info.limits.vs_uniform_count); ++ num_ps_consts_f = min(num_ps_consts_f, adapter->d3d_info.limits.ps_uniform_count); ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_STATEBLOCK; ++ ++ /* Don't memcpy the entire struct, we'll remove single items as we add dedicated ++ * ops for setting states */ ++ op->state.base_vertex_index = state->base_vertex_index; ++ op->state.load_base_vertex_index = state->load_base_vertex_index; ++ op->state.gl_primitive_type = state->gl_primitive_type; ++ ++ memcpy(op->state.vs_consts_b, state->vs_consts_b, sizeof(op->state.vs_consts_b)); ++ memcpy(op->state.vs_consts_i, state->vs_consts_i, sizeof(op->state.vs_consts_i)); ++ op->state.vs_consts_f = op->vs_consts_f; ++ memcpy(op->state.vs_consts_f, state->vs_consts_f, sizeof(*op->state.vs_consts_f) * num_vs_consts_f); ++ ++ memcpy(op->state.ps_consts_b, state->ps_consts_b, sizeof(op->state.ps_consts_b)); ++ memcpy(op->state.ps_consts_i, state->ps_consts_i, sizeof(op->state.ps_consts_i)); ++ op->state.ps_consts_f = op->ps_consts_f; ++ memcpy(op->state.ps_consts_f, state->ps_consts_f, sizeof(*op->state.ps_consts_f) * num_ps_consts_f); ++ ++ /* FIXME: This is not ideal. CS is still running synchronously, so this is ok. ++ * It will go away soon anyway. */ ++ memcpy(op->state.lights, state->lights, sizeof(op->state.lights)); + + cs->ops->submit(cs); + } +@@ -1250,6 +1324,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, + /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, + /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, ++ /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, + }; + + static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) +@@ -1339,7 +1414,7 @@ done: + struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) + { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; +- struct wined3d_cs *cs; ++ struct wined3d_cs *cs = NULL; + + if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs)))) + return NULL; +@@ -1347,8 +1422,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) + if (FAILED(state_init(&cs->state, gl_info, &device->adapter->d3d_info, + WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) + { +- HeapFree(GetProcessHeap(), 0, cs); +- return NULL; ++ goto err; + } + + cs->ops = &wined3d_cs_st_ops; +@@ -1357,16 +1431,13 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) + cs->data_size = WINED3D_INITIAL_CS_SIZE; + if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size))) + { +- HeapFree(GetProcessHeap(), 0, cs); +- return NULL; ++ goto err; + } + + if ((cs->tls_idx = TlsAlloc()) == TLS_OUT_OF_INDEXES) + { + ERR("Failed to allocate cs TLS index, err %#x.\n", GetLastError()); +- HeapFree(GetProcessHeap(), 0, cs->data); +- HeapFree(GetProcessHeap(), 0, cs); +- return NULL; ++ goto err; + } + + if (wined3d_settings.cs_multithreaded) +@@ -1379,15 +1450,22 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) + if (!(cs->thread = CreateThread(NULL, 0, wined3d_cs_run, cs, 0, NULL))) + { + ERR("Failed to create wined3d command stream thread.\n"); +- if (!TlsFree(cs->tls_idx)) +- ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); +- HeapFree(GetProcessHeap(), 0, cs->data); +- HeapFree(GetProcessHeap(), 0, cs); +- return NULL; ++ goto err; + } + } + + return cs; ++ ++err: ++ if (cs) ++ { ++ state_cleanup(&cs->state); ++ if (cs->tls_idx != TLS_OUT_OF_INDEXES && !TlsFree(cs->tls_idx)) ++ ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); ++ HeapFree(GetProcessHeap(), 0, cs->data); ++ } ++ HeapFree(GetProcessHeap(), 0, cs); ++ return NULL; + } + + void wined3d_cs_destroy(struct wined3d_cs *cs) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 3bd45da..b936039 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -3409,6 +3409,7 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT + device_invalidate_state(device, STATE_BASEVERTEXINDEX); + } + ++ wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); + wined3d_cs_emit_draw(device->cs, start_vertex, vertex_count, 0, 0, FALSE); + + return WINED3D_OK; +@@ -3452,6 +3453,7 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic + device_invalidate_state(device, STATE_BASEVERTEXINDEX); + } + ++ wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); + wined3d_cs_emit_draw(device->cs, start_idx, index_count, 0, 0, TRUE); + + return WINED3D_OK; +@@ -3463,6 +3465,7 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device + TRACE("device %p, start_idx %u, index_count %u, start_instance %u, instance_count %u.\n", + device, start_idx, index_count, start_instance, instance_count); + ++ wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); + wined3d_cs_emit_draw(device->cs, start_idx, index_count, start_instance, instance_count, TRUE); + } + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 1f95a50..d8b24a5 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2584,7 +2584,7 @@ struct wined3d_cs_block + { + struct list entry; + UINT pos; +- BYTE data[4000]; /* FIXME? The size is somewhat arbitrary. */ ++ BYTE data[sizeof(struct wined3d_state) * 2]; /* FIXME? The size is somewhat arbitrary. */ + }; + + struct wined3d_cs_ops +@@ -2626,6 +2626,8 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture + WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, + UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, ++ const struct wined3d_state *state) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, + struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, +-- +2.3.5 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0046-wined3d-Pass-the-state-to-draw_primitive.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0046-wined3d-Pass-the-state-to-draw_primitive.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0046-wined3d-Pass-the-state-to-draw_primitive.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0046-wined3d-Pass-the-state-to-draw_primitive.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,263 +0,0 @@ -From 78e1e4771d85128087e911b9a0ad81998fb98096 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 2 Apr 2013 17:25:19 +0200 -Subject: wined3d: Pass the state to draw_primitive - ---- - dlls/wined3d/buffer.c | 6 +++--- - dlls/wined3d/context.c | 6 +++--- - dlls/wined3d/cs.c | 2 +- - dlls/wined3d/directx.c | 2 +- - dlls/wined3d/drawprim.c | 27 +++++++++++++-------------- - dlls/wined3d/state.c | 4 ++-- - dlls/wined3d/utils.c | 2 +- - dlls/wined3d/wined3d_private.h | 8 +++++--- - 8 files changed, 29 insertions(+), 28 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 6fff047..4f4827f 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -423,7 +423,7 @@ static inline void fixup_d3dcolor(DWORD *dst_color) - { - DWORD src_color = *dst_color; - -- /* Color conversion like in drawStridedSlow. watch out for little endianity -+ /* Color conversion like in draw_strided_slow. watch out for little endianity - * If we want that stuff to work on big endian machines too we have to consider more things - * - * 0xff000000: Alpha mask -@@ -1190,11 +1190,11 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device - - dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE]; - -- /* Observations show that drawStridedSlow is faster on dynamic VBs than converting + -+ /* Observations show that draw_strided_slow is faster on dynamic VBs than converting + - * drawStridedFast (half-life 2 and others). - * - * Basically converting the vertices in the buffer is quite expensive, and observations -- * show that drawStridedSlow is faster than converting + uploading + drawStridedFast. -+ * show that draw_strided_slow is faster than converting + uploading + drawStridedFast. - * Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers. - */ - if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT]) -diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c -index c1b6e01..d9e2bc1 100644 ---- a/dlls/wined3d/context.c -+++ b/dlls/wined3d/context.c -@@ -2992,7 +2992,7 @@ static void context_update_stream_info(struct wined3d_context *context, const st - { - if (state->vertex_declaration->half_float_conv_needed && !stream_info->all_vbo) - { -- TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion.\n"); -+ TRACE("Using draw_strided_slow with vertex shaders for FLOAT16 conversion.\n"); - context->use_immediate_mode_draw = TRUE; - } - else -@@ -3167,9 +3167,9 @@ static void context_bind_shader_resources(struct wined3d_context *context, const - } - - /* Context activation is done by the caller. */ --BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) -+BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, -+ const struct wined3d_state *state) - { -- const struct wined3d_state *state = &device->state; - const struct StateEntry *state_table = context->state_table; - const struct wined3d_fb_state *fb = &state->fb; - unsigned int i; -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 784de6e..d14fd82 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -492,7 +492,7 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_draw *op = data; - -- draw_primitive(cs->device, op->start_idx, op->index_count, -+ draw_primitive(cs->device, &cs->device->state, op->start_idx, op->index_count, - op->start_instance, op->instance_count, op->indexed); - - return sizeof(*op); -diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c -index d7f0512..71688a5 100644 ---- a/dlls/wined3d/directx.c -+++ b/dlls/wined3d/directx.c -@@ -5503,7 +5503,7 @@ static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data) - } - - /* Helper functions for providing vertex data to opengl. The arrays are initialized based on -- * the extension detection and are used in drawStridedSlow -+ * the extension detection and are used in draw_strided_slow - */ - static void WINE_GLAPI position_d3dcolor(const void *data) - { -diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c -index af51dfd..bfbdf8c 100644 ---- a/dlls/wined3d/drawprim.c -+++ b/dlls/wined3d/drawprim.c -@@ -36,7 +36,7 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); - #include - - /* Context activation is done by the caller. */ --static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, -+static void draw_strided_fast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, - const void *idx_data, UINT start_idx, INT base_vertex_index, UINT start_instance, UINT instance_count) - { - if (idx_size) -@@ -95,7 +95,7 @@ static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primit - */ - - /* Context activation is done by the caller. */ --static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_context *context, -+static void draw_strided_slow(const struct wined3d_state *state, struct wined3d_context *context, - const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType, - const void *idxData, UINT idxSize, UINT startIdx) - { -@@ -103,7 +103,6 @@ static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_ - const WORD *pIdxBufS = NULL; - const DWORD *pIdxBufL = NULL; - UINT vx_index; -- const struct wined3d_state *state = &device->state; - LONG SkipnStrides = startIdx; - BOOL pixelShader = use_ps(state); - BOOL specular_fog = FALSE; -@@ -453,7 +452,7 @@ static inline void send_attribute(const struct wined3d_gl_info *gl_info, - } - - /* Context activation is done by the caller. */ --static void drawStridedSlowVs(struct wined3d_context *context, const struct wined3d_state *state, -+static void draw_strided_slow_vs(struct wined3d_context *context, const struct wined3d_state *state, - const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, - const void *idxData, UINT idxSize, UINT startIdx) - { -@@ -510,7 +509,7 @@ static void drawStridedSlowVs(struct wined3d_context *context, const struct wine - } - - /* Context activation is done by the caller. */ --static void drawStridedInstanced(struct wined3d_context *context, const struct wined3d_state *state, -+static void draw_strided_instanced(struct wined3d_context *context, const struct wined3d_state *state, - const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, - const void *idxData, UINT idxSize, UINT startIdx, UINT base_vertex_index, UINT instance_count) - { -@@ -595,10 +594,10 @@ static void remove_vbos(struct wined3d_context *context, - } - - /* Routine common to the draw primitive and draw indexed primitive routines */ --void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count, -- UINT start_instance, UINT instance_count, BOOL indexed) -+void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, -+ UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count, -+ BOOL indexed) - { -- const struct wined3d_state *state = &device->state; - const struct wined3d_stream_info *stream_info; - struct wined3d_event_query *ib_query = NULL; - struct wined3d_stream_info si_emulated; -@@ -672,7 +671,7 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co - wined3d_surface_prepare(ds, context, location); - } - -- if (!context_apply_draw_state(context, device)) -+ if (!context_apply_draw_state(context, device, state)) - { - context_release(context); - WARN("Unable to apply draw state, skipping draw.\n"); -@@ -764,28 +763,28 @@ void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_co - else - WARN_(d3d_perf)("Using immediate mode with vertex shaders for half float emulation.\n"); - -- drawStridedSlowVs(context, state, stream_info, index_count, -+ draw_strided_slow_vs(context, state, stream_info, index_count, - state->gl_primitive_type, idx_data, idx_size, start_idx); - } - else - { - if (context->d3d_info->ffp_generic_attributes) -- drawStridedSlowVs(context, state, stream_info, index_count, -+ draw_strided_slow_vs(context, state, stream_info, index_count, - state->gl_primitive_type, idx_data, idx_size, start_idx); - else -- drawStridedSlow(device, context, stream_info, index_count, -+ draw_strided_slow(state, context, stream_info, index_count, - state->gl_primitive_type, idx_data, idx_size, start_idx); - } - } - else if (!gl_info->supported[ARB_INSTANCED_ARRAYS] && instance_count) - { - /* Instancing emulation by mixing immediate mode and arrays. */ -- drawStridedInstanced(context, state, stream_info, index_count, state->gl_primitive_type, -+ draw_strided_instanced(context, state, stream_info, index_count, state->gl_primitive_type, - idx_data, idx_size, start_idx, state->base_vertex_index, instance_count); - } - else - { -- drawStridedFast(gl_info, state->gl_primitive_type, index_count, idx_size, idx_data, -+ draw_strided_fast(gl_info, state->gl_primitive_type, index_count, idx_size, idx_data, - start_idx, state->base_vertex_index, start_instance, instance_count); - } - -diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c -index e789786..8362ef8 100644 ---- a/dlls/wined3d/state.c -+++ b/dlls/wined3d/state.c -@@ -1126,7 +1126,7 @@ void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_st - - case WINED3D_FOG_NONE: - /* Both are none? According to msdn the alpha channel of the specular -- * color contains a fog factor. Set it in drawStridedSlow. -+ * color contains a fog factor. Set it in draw_strided_slow. - * Same happens with Vertexfog on transformed vertices - */ - new_source = FOGSOURCE_COORD; -@@ -4187,7 +4187,7 @@ static void load_vertex_data(struct wined3d_context *context, - } - } - } else { -- /* TODO: support blends in drawStridedSlow -+ /* TODO: support blends in draw_strided_slow - * No need to write a FIXME here, this is done after the general vertex decl decoding - */ - WARN("unsupported blending in openGl\n"); -diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c -index 81af9d5..64e6d6a 100644 ---- a/dlls/wined3d/utils.c -+++ b/dlls/wined3d/utils.c -@@ -3866,7 +3866,7 @@ static void compute_texture_matrix(const struct wined3d_gl_info *gl_info, const - * check for pixel shaders, and the shader has to undo the default gl divide. - * - * A more serious problem occurs if the app passes 4 coordinates in, and the -- * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow -+ * 4th is != 1.0(opengl default). This would have to be fixed in draw_strided_slow - * or a replacement shader. */ - default: - mat._14 = mat._24 = mat._34 = 0.0f; mat._44 = 1.0f; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 2667936..2467c22 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -1021,8 +1021,9 @@ struct wined3d_stream_info - WORD use_map; /* MAX_ATTRIBS, 16 */ - }; - --void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count, -- UINT start_instance, UINT instance_count, BOOL indexed) DECLSPEC_HIDDEN; -+void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, -+ UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count, -+ BOOL indexed) DECLSPEC_HIDDEN; - DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; - - #define eps 1e-8f -@@ -1433,7 +1434,8 @@ void context_alloc_occlusion_query(struct wined3d_context *context, - void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN; - BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_device *device, - UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN; --BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) DECLSPEC_HIDDEN; -+BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, -+ const struct wined3d_state *state) DECLSPEC_HIDDEN; - void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, - struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN; - void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, --- -2.6.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0047-wined3d-Send-float-constant-updates-through-the-comm.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0047-wined3d-Send-float-constant-updates-through-the-comm.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0047-wined3d-Send-float-constant-updates-through-the-comm.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0047-wined3d-Send-float-constant-updates-through-the-comm.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,208 @@ +From bbd02a077bf5ba977724ada68709f46150e482fb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 20 Aug 2013 15:12:26 +0200 +Subject: wined3d: Send float constant updates through the command stream + +--- + dlls/wined3d/cs.c | 88 ++++++++++++++++++++++++++++++++---------- + dlls/wined3d/device.c | 7 ++-- + dlls/wined3d/wined3d_private.h | 2 + + 3 files changed, 74 insertions(+), 23 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index d252773..56cbcb6 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -63,6 +63,8 @@ enum wined3d_cs_op + WINED3D_CS_OP_SET_MATERIAL, + WINED3D_CS_OP_RESET_STATE, + WINED3D_CS_OP_STATEBLOCK, ++ WINED3D_CS_OP_SET_VS_CONSTS_F, ++ WINED3D_CS_OP_SET_PS_CONSTS_F, + WINED3D_CS_OP_STOP, + }; + +@@ -273,7 +275,13 @@ struct wined3d_cs_stateblock + { + enum wined3d_cs_op opcode; + struct wined3d_state state; +- float vs_consts_f[256 * 4], ps_consts_f[256 * 4]; ++}; ++ ++struct wined3d_cs_set_consts_f ++{ ++ enum wined3d_cs_op opcode; ++ UINT start_register, vector4f_count; ++ float constants[4]; + }; + + /* FIXME: The list synchronization probably isn't particularly fast. */ +@@ -910,13 +918,7 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined + + static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const void *data) + { +- const struct wined3d_adapter *adapter = cs->device->adapter; + const struct wined3d_cs_stateblock *op = data; +- UINT num_vs_consts_f = sizeof(op->vs_consts_f) / sizeof(*op->vs_consts_f) / 4; +- UINT num_ps_consts_f = sizeof(op->ps_consts_f) / sizeof(*op->ps_consts_f) / 4; +- +- num_vs_consts_f = min(num_vs_consts_f, adapter->d3d_info.limits.vs_uniform_count); +- num_ps_consts_f = min(num_ps_consts_f, adapter->d3d_info.limits.ps_uniform_count); + + /* Don't memcpy the entire struct, we'll remove single items as we add dedicated + * ops for setting states */ +@@ -927,11 +929,9 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi + + memcpy(cs->state.vs_consts_b, op->state.vs_consts_b, sizeof(cs->state.vs_consts_b)); + memcpy(cs->state.vs_consts_i, op->state.vs_consts_i, sizeof(cs->state.vs_consts_i)); +- memcpy(cs->state.vs_consts_f, op->state.vs_consts_f, sizeof(*cs->state.vs_consts_f) * num_vs_consts_f); + + memcpy(cs->state.ps_consts_b, op->state.ps_consts_b, sizeof(cs->state.ps_consts_b)); + memcpy(cs->state.ps_consts_i, op->state.ps_consts_i, sizeof(cs->state.ps_consts_i)); +- memcpy(cs->state.ps_consts_f, op->state.ps_consts_f, sizeof(*cs->state.ps_consts_f) * num_ps_consts_f); + + memcpy(cs->state.lights, op->state.lights, sizeof(cs->state.lights)); + +@@ -940,14 +940,7 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi + + void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct wined3d_state *state) + { +- const struct wined3d_device *device = cs->device; +- const struct wined3d_adapter *adapter = device->adapter; + struct wined3d_cs_stateblock *op; +- UINT num_vs_consts_f = sizeof(op->vs_consts_f) / sizeof(*op->vs_consts_f) / 4; +- UINT num_ps_consts_f = sizeof(op->ps_consts_f) / sizeof(*op->ps_consts_f) / 4; +- +- num_vs_consts_f = min(num_vs_consts_f, adapter->d3d_info.limits.vs_uniform_count); +- num_ps_consts_f = min(num_ps_consts_f, adapter->d3d_info.limits.ps_uniform_count); + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_STATEBLOCK; +@@ -960,13 +953,9 @@ void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct win + + memcpy(op->state.vs_consts_b, state->vs_consts_b, sizeof(op->state.vs_consts_b)); + memcpy(op->state.vs_consts_i, state->vs_consts_i, sizeof(op->state.vs_consts_i)); +- op->state.vs_consts_f = op->vs_consts_f; +- memcpy(op->state.vs_consts_f, state->vs_consts_f, sizeof(*op->state.vs_consts_f) * num_vs_consts_f); + + memcpy(op->state.ps_consts_b, state->ps_consts_b, sizeof(op->state.ps_consts_b)); + memcpy(op->state.ps_consts_i, state->ps_consts_i, sizeof(op->state.ps_consts_i)); +- op->state.ps_consts_f = op->ps_consts_f; +- memcpy(op->state.ps_consts_f, state->ps_consts_f, sizeof(*op->state.ps_consts_f) * num_ps_consts_f); + + /* FIXME: This is not ideal. CS is still running synchronously, so this is ok. + * It will go away soon anyway. */ +@@ -1039,6 +1028,63 @@ void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type + op->opcode = WINED3D_CS_OP_SET_SHADER; + op->type = type; + op->shader = shader; ++} ++ ++static UINT wined3d_cs_exec_set_vs_consts_f(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_consts_f *op = data; ++ struct wined3d_device *device = cs->device; ++ ++ memcpy(cs->state.vs_consts_f + op->start_register * 4, op->constants, ++ sizeof(*cs->state.vs_consts_f) * 4 * op->vector4f_count); ++ ++ device->shader_backend->shader_update_float_vertex_constants(device, ++ op->start_register, op->vector4f_count); ++ ++ return sizeof(*op) + sizeof(op->constants) * (op->vector4f_count - 1); ++} ++ ++static UINT wined3d_cs_exec_set_ps_consts_f(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_consts_f *op = data; ++ struct wined3d_device *device = cs->device; ++ ++ memcpy(cs->state.ps_consts_f + op->start_register * 4, op->constants, ++ sizeof(*cs->state.ps_consts_f) * 4 * op->vector4f_count); ++ ++ device->shader_backend->shader_update_float_pixel_constants(device, ++ op->start_register, op->vector4f_count); ++ ++ return sizeof(*op) + sizeof(op->constants) * (op->vector4f_count - 1); ++} ++ ++void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, ++ const float *constants, UINT vector4f_count, enum wined3d_shader_type type) ++{ ++ struct wined3d_cs_set_consts_f *op; ++ UINT extra_space = vector4f_count - 1; ++ ++ op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); ++ switch (type) ++ { ++ case WINED3D_SHADER_TYPE_PIXEL: ++ op->opcode = WINED3D_CS_OP_SET_PS_CONSTS_F; ++ break; ++ ++ case WINED3D_SHADER_TYPE_VERTEX: ++ op->opcode = WINED3D_CS_OP_SET_VS_CONSTS_F; ++ break; ++ ++ case WINED3D_SHADER_TYPE_GEOMETRY: ++ FIXME("Invalid for geometry shaders\n"); ++ return; ++ ++ case WINED3D_SHADER_TYPE_COUNT: ++ break; ++ } ++ op->start_register = start_register; ++ op->vector4f_count = vector4f_count; ++ memcpy(op->constants, constants, sizeof(*constants) * 4 * vector4f_count); + + cs->ops->submit(cs); + } +@@ -1233,6 +1279,8 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, + /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, + /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, ++ /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, ++ /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, + }; + + static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 6ea0b9a..2aba2a4 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -2341,8 +2341,8 @@ HRESULT CDECL wined3d_device_set_vs_consts_f(struct wined3d_device *device, + memset(device->recording->changed.vertexShaderConstantsF + start_register, 1, + sizeof(*device->recording->changed.vertexShaderConstantsF) * vector4f_count); + else +- device->shader_backend->shader_update_float_vertex_constants(device, start_register, vector4f_count); +- ++ wined3d_cs_emit_set_consts_f(device->cs, start_register, constants, vector4f_count, ++ WINED3D_SHADER_TYPE_VERTEX); + + return WINED3D_OK; + } +@@ -2576,7 +2576,8 @@ HRESULT CDECL wined3d_device_set_ps_consts_f(struct wined3d_device *device, + memset(device->recording->changed.pixelShaderConstantsF + start_register, 1, + sizeof(*device->recording->changed.pixelShaderConstantsF) * vector4f_count); + else +- device->shader_backend->shader_update_float_pixel_constants(device, start_register, vector4f_count); ++ wined3d_cs_emit_set_consts_f(device->cs, start_register, constants, vector4f_count, ++ WINED3D_SHADER_TYPE_PIXEL); + + return WINED3D_OK; + } +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 02104ce..d673a8f 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2613,6 +2613,8 @@ void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform + void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, + struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, ++ UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0047-wined3d-Wait-for-the-cs-before-destroying-objects.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0047-wined3d-Wait-for-the-cs-before-destroying-objects.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0047-wined3d-Wait-for-the-cs-before-destroying-objects.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0047-wined3d-Wait-for-the-cs-before-destroying-objects.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,135 +0,0 @@ -From 534d7a18db58161682a42210ced42e8e7cf55ba8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 3 Apr 2013 18:01:34 +0200 -Subject: wined3d: Wait for the cs before destroying objects - -This is to avoid destroying objects that are still referenced in -commands in the cs. Later patches will migrate resource destruction to -the CS. ---- - dlls/wined3d/buffer.c | 6 ++++++ - dlls/wined3d/cs.c | 2 ++ - dlls/wined3d/shader.c | 5 +++++ - dlls/wined3d/surface.c | 6 ++++++ - dlls/wined3d/texture.c | 6 ++++++ - dlls/wined3d/vertexdeclaration.c | 5 +++++ - dlls/wined3d/wined3d_private.h | 1 + - 7 files changed, 31 insertions(+) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 8165d6b..bc34050 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -552,6 +552,12 @@ ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) - - if (!refcount) - { -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ buffer->resource.device->cs->ops->finish(buffer->resource.device->cs); -+ } -+ - if (buffer->buffer_object) - { - context = context_acquire(buffer->resource.device, NULL); -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index eac7739..8823c9a 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -1188,12 +1188,14 @@ static const struct wined3d_cs_ops wined3d_cs_st_ops = - { - wined3d_cs_st_require_space, - wined3d_cs_st_submit, -+ wined3d_cs_st_submit, - }; - - static const struct wined3d_cs_ops wined3d_cs_mt_ops = - { - wined3d_cs_mt_require_space, - wined3d_cs_flush_and_wait, -+ wined3d_cs_flush_and_wait, - }; - - /* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an -diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c -index cc969b8..0faabaa 100644 ---- a/dlls/wined3d/shader.c -+++ b/dlls/wined3d/shader.c -@@ -1957,6 +1957,11 @@ ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader) - - if (!refcount) - { -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ shader->device->cs->ops->finish(shader->device->cs); -+ } - shader_cleanup(shader); - shader->parent_ops->wined3d_object_destroyed(shader->parent); - HeapFree(GetProcessHeap(), 0, shader); -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 8fa2c9f..8f8af4d 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -42,6 +42,12 @@ static void surface_cleanup(struct wined3d_surface *surface) - - TRACE("surface %p.\n", surface); - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ surface->resource.device->cs->ops->finish(surface->resource.device->cs); -+ } -+ - if (surface->resource.buffer_object || surface->rb_multisample - || surface->rb_resolved || !list_empty(&surface->renderbuffers)) - { -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index ec5c847..68889e5 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -136,6 +136,12 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture) - - TRACE("texture %p.\n", texture); - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ texture->resource.device->cs->ops->finish(texture->resource.device->cs); -+ } -+ - for (i = 0; i < sub_count; ++i) - { - struct wined3d_resource *sub_resource = texture->sub_resources[i]; -diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c -index cf5378c..3f4d5e4 100644 ---- a/dlls/wined3d/vertexdeclaration.c -+++ b/dlls/wined3d/vertexdeclaration.c -@@ -56,6 +56,11 @@ ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration - - if (!refcount) - { -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ declaration->device->cs->ops->finish(declaration->device->cs); -+ } - HeapFree(GetProcessHeap(), 0, declaration->elements); - declaration->parent_ops->wined3d_object_destroyed(declaration->parent); - HeapFree(GetProcessHeap(), 0, declaration); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index a48cc7d..b856b6f 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2544,6 +2544,7 @@ struct wined3d_cs_ops - { - void *(*require_space)(struct wined3d_cs *cs, size_t size); - void (*submit)(struct wined3d_cs *cs); -+ void (*finish)(struct wined3d_cs *cs); - }; - - struct wined3d_cs --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0048-wined3d-Give-the-cs-its-own-state.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0048-wined3d-Give-the-cs-its-own-state.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0048-wined3d-Give-the-cs-its-own-state.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0048-wined3d-Give-the-cs-its-own-state.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,255 +0,0 @@ -From 35f36ec3b2bf7fa8bdfabd7d698b118ba2030ccf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 1 Oct 2013 15:30:26 +0200 -Subject: wined3d: Give the cs its own state - ---- - dlls/wined3d/cs.c | 108 +++++++++++++++++++++++++++++++++++------ - dlls/wined3d/device.c | 3 ++ - dlls/wined3d/wined3d_private.h | 4 +- - 3 files changed, 99 insertions(+), 16 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index a8327d1..1b466c3 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -63,6 +63,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_SET_COLOR_KEY, - WINED3D_CS_OP_SET_MATERIAL, - WINED3D_CS_OP_RESET_STATE, -+ WINED3D_CS_OP_STATEBLOCK, - WINED3D_CS_OP_STOP, - }; - -@@ -278,6 +279,13 @@ struct wined3d_cs_reset_state - enum wined3d_cs_op opcode; - }; - -+struct wined3d_cs_stateblock -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_state state; -+ float vs_consts_f[256 * 4], ps_consts_f[256 * 4]; -+}; -+ - /* FIXME: The list synchronization probably isn't particularly fast. */ - static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) - { -@@ -461,7 +469,7 @@ static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) - unsigned int extra_rects = op->rect_count ? op->rect_count - 1 : 0; - - device = cs->device; -- wined3d_get_draw_rect(&device->state, &draw_rect); -+ wined3d_get_draw_rect(&cs->state, &draw_rect); - device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, - &cs->state.fb, op->rect_count, op->rect_count ? op->rects : NULL, &draw_rect, op->flags, - &op->color, op->depth, op->stencil); -@@ -492,7 +500,7 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_draw *op = data; - -- draw_primitive(cs->device, &cs->device->state, op->start_idx, op->index_count, -+ draw_primitive(cs->device, &cs->state, op->start_idx, op->index_count, - op->start_instance, op->instance_count, op->indexed); - - return sizeof(*op); -@@ -907,6 +915,72 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined - op->opcode = WINED3D_CS_OP_SET_TEXTURE; - op->stage = stage; - op->texture = texture; -+ cs->ops->submit(cs); -+} -+ -+static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_adapter *adapter = cs->device->adapter; -+ const struct wined3d_cs_stateblock *op = data; -+ UINT num_vs_consts_f = sizeof(op->vs_consts_f) / sizeof(*op->vs_consts_f) / 4; -+ UINT num_ps_consts_f = sizeof(op->ps_consts_f) / sizeof(*op->ps_consts_f) / 4; -+ -+ num_vs_consts_f = min(num_vs_consts_f, adapter->d3d_info.limits.vs_uniform_count); -+ num_ps_consts_f = min(num_ps_consts_f, adapter->d3d_info.limits.ps_uniform_count); -+ -+ /* Don't memcpy the entire struct, we'll remove single items as we add dedicated -+ * ops for setting states */ -+ -+ cs->state.base_vertex_index = op->state.base_vertex_index; -+ cs->state.load_base_vertex_index = op->state.load_base_vertex_index; -+ cs->state.gl_primitive_type = op->state.gl_primitive_type; -+ -+ memcpy(cs->state.vs_consts_b, op->state.vs_consts_b, sizeof(cs->state.vs_consts_b)); -+ memcpy(cs->state.vs_consts_i, op->state.vs_consts_i, sizeof(cs->state.vs_consts_i)); -+ memcpy(cs->state.vs_consts_f, op->state.vs_consts_f, sizeof(*cs->state.vs_consts_f) * num_vs_consts_f); -+ -+ memcpy(cs->state.ps_consts_b, op->state.ps_consts_b, sizeof(cs->state.ps_consts_b)); -+ memcpy(cs->state.ps_consts_i, op->state.ps_consts_i, sizeof(cs->state.ps_consts_i)); -+ memcpy(cs->state.ps_consts_f, op->state.ps_consts_f, sizeof(*cs->state.ps_consts_f) * num_ps_consts_f); -+ -+ memcpy(cs->state.lights, op->state.lights, sizeof(cs->state.lights)); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct wined3d_state *state) -+{ -+ const struct wined3d_device *device = cs->device; -+ const struct wined3d_adapter *adapter = device->adapter; -+ struct wined3d_cs_stateblock *op; -+ UINT num_vs_consts_f = sizeof(op->vs_consts_f) / sizeof(*op->vs_consts_f) / 4; -+ UINT num_ps_consts_f = sizeof(op->ps_consts_f) / sizeof(*op->ps_consts_f) / 4; -+ -+ num_vs_consts_f = min(num_vs_consts_f, adapter->d3d_info.limits.vs_uniform_count); -+ num_ps_consts_f = min(num_ps_consts_f, adapter->d3d_info.limits.ps_uniform_count); -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_STATEBLOCK; -+ -+ /* Don't memcpy the entire struct, we'll remove single items as we add dedicated -+ * ops for setting states */ -+ op->state.base_vertex_index = state->base_vertex_index; -+ op->state.load_base_vertex_index = state->load_base_vertex_index; -+ op->state.gl_primitive_type = state->gl_primitive_type; -+ -+ memcpy(op->state.vs_consts_b, state->vs_consts_b, sizeof(op->state.vs_consts_b)); -+ memcpy(op->state.vs_consts_i, state->vs_consts_i, sizeof(op->state.vs_consts_i)); -+ op->state.vs_consts_f = op->vs_consts_f; -+ memcpy(op->state.vs_consts_f, state->vs_consts_f, sizeof(*op->state.vs_consts_f) * num_vs_consts_f); -+ -+ memcpy(op->state.ps_consts_b, state->ps_consts_b, sizeof(op->state.ps_consts_b)); -+ memcpy(op->state.ps_consts_i, state->ps_consts_i, sizeof(op->state.ps_consts_i)); -+ op->state.ps_consts_f = op->ps_consts_f; -+ memcpy(op->state.ps_consts_f, state->ps_consts_f, sizeof(*op->state.ps_consts_f) * num_ps_consts_f); -+ -+ /* FIXME: This is not ideal. CS is still running synchronously, so this is ok. -+ * It will go away soon anyway. */ -+ memcpy(op->state.lights, state->lights, sizeof(op->state.lights)); - - cs->ops->submit(cs); - } -@@ -1250,6 +1324,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, - /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, - /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, -+ /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, - }; - - static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -@@ -1339,7 +1414,7 @@ done: - struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) - { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -- struct wined3d_cs *cs; -+ struct wined3d_cs *cs = NULL; - - if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs)))) - return NULL; -@@ -1347,8 +1422,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) - if (FAILED(state_init(&cs->state, gl_info, &device->adapter->d3d_info, - WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) - { -- HeapFree(GetProcessHeap(), 0, cs); -- return NULL; -+ goto err; - } - - cs->ops = &wined3d_cs_st_ops; -@@ -1357,16 +1431,13 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) - cs->data_size = WINED3D_INITIAL_CS_SIZE; - if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size))) - { -- HeapFree(GetProcessHeap(), 0, cs); -- return NULL; -+ goto err; - } - - if ((cs->tls_idx = TlsAlloc()) == TLS_OUT_OF_INDEXES) - { - ERR("Failed to allocate cs TLS index, err %#x.\n", GetLastError()); -- HeapFree(GetProcessHeap(), 0, cs->data); -- HeapFree(GetProcessHeap(), 0, cs); -- return NULL; -+ goto err; - } - - if (wined3d_settings.cs_multithreaded) -@@ -1379,15 +1450,22 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) - if (!(cs->thread = CreateThread(NULL, 0, wined3d_cs_run, cs, 0, NULL))) - { - ERR("Failed to create wined3d command stream thread.\n"); -- if (!TlsFree(cs->tls_idx)) -- ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); -- HeapFree(GetProcessHeap(), 0, cs->data); -- HeapFree(GetProcessHeap(), 0, cs); -- return NULL; -+ goto err; - } - } - - return cs; -+ -+err: -+ if (cs) -+ { -+ state_cleanup(&cs->state); -+ if (cs->tls_idx != TLS_OUT_OF_INDEXES && !TlsFree(cs->tls_idx)) -+ ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); -+ HeapFree(GetProcessHeap(), 0, cs->data); -+ } -+ HeapFree(GetProcessHeap(), 0, cs); -+ return NULL; - } - - void wined3d_cs_destroy(struct wined3d_cs *cs) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 3bd45da..b936039 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -3409,6 +3409,7 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT - device_invalidate_state(device, STATE_BASEVERTEXINDEX); - } - -+ wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); - wined3d_cs_emit_draw(device->cs, start_vertex, vertex_count, 0, 0, FALSE); - - return WINED3D_OK; -@@ -3452,6 +3453,7 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic - device_invalidate_state(device, STATE_BASEVERTEXINDEX); - } - -+ wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); - wined3d_cs_emit_draw(device->cs, start_idx, index_count, 0, 0, TRUE); - - return WINED3D_OK; -@@ -3463,6 +3465,7 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device - TRACE("device %p, start_idx %u, index_count %u, start_instance %u, instance_count %u.\n", - device, start_idx, index_count, start_instance, instance_count); - -+ wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); - wined3d_cs_emit_draw(device->cs, start_idx, index_count, start_instance, instance_count, TRUE); - } - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 1f95a50..d8b24a5 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2584,7 +2584,7 @@ struct wined3d_cs_block - { - struct list entry; - UINT pos; -- BYTE data[4000]; /* FIXME? The size is somewhat arbitrary. */ -+ BYTE data[sizeof(struct wined3d_state) * 2]; /* FIXME? The size is somewhat arbitrary. */ - }; - - struct wined3d_cs_ops -@@ -2626,6 +2626,8 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture - WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, - UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, -+ const struct wined3d_state *state) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, - struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, --- -2.3.5 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0048-wined3d-Request-a-glFinish-before-modifying-resource.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0048-wined3d-Request-a-glFinish-before-modifying-resource.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0048-wined3d-Request-a-glFinish-before-modifying-resource.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0048-wined3d-Request-a-glFinish-before-modifying-resource.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,253 @@ +From a79863383e3dc7dfff564432e6c5086aa612d8af Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Apr 2013 11:50:09 +0200 +Subject: wined3d: Request a glFinish before modifying resources outside the cs + +--- + dlls/wined3d/buffer.c | 17 +++++++++++++++++ + dlls/wined3d/cs.c | 30 ++++++++++++++++++++++++++++++ + dlls/wined3d/device.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + dlls/wined3d/resource.c | 7 +++++++ + dlls/wined3d/surface.c | 7 +++++++ + dlls/wined3d/wined3d_private.h | 1 + + 6 files changed, 104 insertions(+) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 0735ab7..3f740dd 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -931,6 +931,15 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte + void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) + { + struct wined3d_context *context; ++ struct wined3d_device *device = buffer->resource.device; ++ ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + context = context_acquire(buffer->resource.device, NULL); + buffer_internal_preload(buffer, context, NULL); + context_release(context); +@@ -947,9 +956,17 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + { + LONG count; + BYTE *base; ++ struct wined3d_device *device = buffer->resource.device; + + TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags); + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags); + /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001 multitexture + * fill rate test seems to depend on this. When we map a buffer with +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 63ac035..b7bedbf 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -66,6 +66,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_STATEBLOCK, + WINED3D_CS_OP_SET_VS_CONSTS_F, + WINED3D_CS_OP_SET_PS_CONSTS_F, ++ WINED3D_CS_OP_GLFINISH, + WINED3D_CS_OP_STOP, + }; + +@@ -294,6 +295,11 @@ struct wined3d_cs_set_consts_f + float constants[4]; + }; + ++struct wined3d_cs_finish ++{ ++ enum wined3d_cs_op opcode; ++}; ++ + /* FIXME: The list synchronization probably isn't particularly fast. */ + static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) + { +@@ -1364,6 +1370,29 @@ void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) + cs->ops->submit(cs); + } + ++static UINT wined3d_cs_exec_glfinish(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_finish *op = data; ++ struct wined3d_device *device = cs->device; ++ struct wined3d_context *context; ++ ++ context = context_acquire(device, NULL); ++ context->gl_info->gl_ops.gl.p_glFinish(); ++ context_release(context); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) ++{ ++ struct wined3d_cs_finish *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_GLFINISH; ++ ++ cs->ops->submit(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, +@@ -1396,6 +1425,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, + /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, + /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, ++ /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, + }; + + static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index d43075b..5e5f3f5 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -2765,6 +2765,13 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO + return hr; + } + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + wined3d_device_get_transform(device, WINED3D_TS_VIEW, &view_mat); + wined3d_device_get_transform(device, WINED3D_TS_PROJECTION, &proj_mat); + wined3d_device_get_transform(device, WINED3D_TS_WORLD_MATRIX(0), &world_mat); +@@ -3562,6 +3569,13 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, + ++src_skip_levels; + } + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + /* Make sure that the destination texture is loaded. */ + context = context_acquire(device, NULL); + wined3d_texture_load(dst_texture, context, FALSE); +@@ -3810,6 +3824,13 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, + return WINED3DERR_INVALIDCALL; + } + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + return surface_upload_from_surface(dst_surface, dst_point, src_surface, src_rect); + } + +@@ -4064,6 +4085,13 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi + rect = &r; + } + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), view->sub_resource_idx); + + return surface_color_fill(surface_from_resource(resource), rect, color); +@@ -4377,6 +4405,13 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) + + TRACE("device %p.\n", device); + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) + { + TRACE("Checking resource %p for eviction.\n", resource); +@@ -4499,6 +4534,13 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + TRACE("device %p, swapchain_desc %p, mode %p, callback %p, reset_state %#x.\n", + device, swapchain_desc, mode, callback, reset_state); + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + if (!(swapchain = wined3d_device_get_swapchain(device, 0))) + { + ERR("Failed to get the first implicit swapchain.\n"); +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 9c40d42..c72987c 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -786,6 +786,13 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, + + flags = wined3d_resource_sanitize_map_flags(resource, flags); + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + if (device->d3d_initialized) + context = context_acquire(device, NULL); + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index cba9da9..5e44494 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -5007,6 +5007,13 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC + flags &= ~WINEDDBLT_DONOTWAIT; + } + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("Waiting for cs.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + if (!device->d3d_initialized) + { + WARN("D3D not initialized, using fallback.\n"); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index d018cd9..2e42c79 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2702,6 +2702,7 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, + void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, + UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.5.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0049-wined3d-Finish-the-cs-before-changing-the-texture-lo.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0049-wined3d-Finish-the-cs-before-changing-the-texture-lo.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0049-wined3d-Finish-the-cs-before-changing-the-texture-lo.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0049-wined3d-Finish-the-cs-before-changing-the-texture-lo.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,30 @@ +From 58db2f20f55fd78d4831475a5bdce14339c1e66f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 10 Apr 2013 19:53:44 +0200 +Subject: wined3d: Finish the cs before changing the texture lod + +--- + dlls/wined3d/texture.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index 6381613..0eb191e 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -510,6 +510,13 @@ DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod) + + if (texture->lod != lod) + { ++ if (wined3d_settings.cs_multithreaded) ++ { ++ struct wined3d_device *device = texture->resource.device; ++ FIXME("Waiting for cs.\n"); ++ device->cs->ops->finish(device->cs); ++ } ++ + texture->lod = lod; + + texture->texture_rgb.base_level = ~0u; +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0049-wined3d-Send-float-constant-updates-through-the-comm.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0049-wined3d-Send-float-constant-updates-through-the-comm.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0049-wined3d-Send-float-constant-updates-through-the-comm.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0049-wined3d-Send-float-constant-updates-through-the-comm.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,208 +0,0 @@ -From bbd02a077bf5ba977724ada68709f46150e482fb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 20 Aug 2013 15:12:26 +0200 -Subject: wined3d: Send float constant updates through the command stream - ---- - dlls/wined3d/cs.c | 88 ++++++++++++++++++++++++++++++++---------- - dlls/wined3d/device.c | 7 ++-- - dlls/wined3d/wined3d_private.h | 2 + - 3 files changed, 74 insertions(+), 23 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index d252773..56cbcb6 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -63,6 +63,8 @@ enum wined3d_cs_op - WINED3D_CS_OP_SET_MATERIAL, - WINED3D_CS_OP_RESET_STATE, - WINED3D_CS_OP_STATEBLOCK, -+ WINED3D_CS_OP_SET_VS_CONSTS_F, -+ WINED3D_CS_OP_SET_PS_CONSTS_F, - WINED3D_CS_OP_STOP, - }; - -@@ -273,7 +275,13 @@ struct wined3d_cs_stateblock - { - enum wined3d_cs_op opcode; - struct wined3d_state state; -- float vs_consts_f[256 * 4], ps_consts_f[256 * 4]; -+}; -+ -+struct wined3d_cs_set_consts_f -+{ -+ enum wined3d_cs_op opcode; -+ UINT start_register, vector4f_count; -+ float constants[4]; - }; - - /* FIXME: The list synchronization probably isn't particularly fast. */ -@@ -910,13 +918,7 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined - - static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const void *data) - { -- const struct wined3d_adapter *adapter = cs->device->adapter; - const struct wined3d_cs_stateblock *op = data; -- UINT num_vs_consts_f = sizeof(op->vs_consts_f) / sizeof(*op->vs_consts_f) / 4; -- UINT num_ps_consts_f = sizeof(op->ps_consts_f) / sizeof(*op->ps_consts_f) / 4; -- -- num_vs_consts_f = min(num_vs_consts_f, adapter->d3d_info.limits.vs_uniform_count); -- num_ps_consts_f = min(num_ps_consts_f, adapter->d3d_info.limits.ps_uniform_count); - - /* Don't memcpy the entire struct, we'll remove single items as we add dedicated - * ops for setting states */ -@@ -927,11 +929,9 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi - - memcpy(cs->state.vs_consts_b, op->state.vs_consts_b, sizeof(cs->state.vs_consts_b)); - memcpy(cs->state.vs_consts_i, op->state.vs_consts_i, sizeof(cs->state.vs_consts_i)); -- memcpy(cs->state.vs_consts_f, op->state.vs_consts_f, sizeof(*cs->state.vs_consts_f) * num_vs_consts_f); - - memcpy(cs->state.ps_consts_b, op->state.ps_consts_b, sizeof(cs->state.ps_consts_b)); - memcpy(cs->state.ps_consts_i, op->state.ps_consts_i, sizeof(cs->state.ps_consts_i)); -- memcpy(cs->state.ps_consts_f, op->state.ps_consts_f, sizeof(*cs->state.ps_consts_f) * num_ps_consts_f); - - memcpy(cs->state.lights, op->state.lights, sizeof(cs->state.lights)); - -@@ -940,14 +940,7 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi - - void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct wined3d_state *state) - { -- const struct wined3d_device *device = cs->device; -- const struct wined3d_adapter *adapter = device->adapter; - struct wined3d_cs_stateblock *op; -- UINT num_vs_consts_f = sizeof(op->vs_consts_f) / sizeof(*op->vs_consts_f) / 4; -- UINT num_ps_consts_f = sizeof(op->ps_consts_f) / sizeof(*op->ps_consts_f) / 4; -- -- num_vs_consts_f = min(num_vs_consts_f, adapter->d3d_info.limits.vs_uniform_count); -- num_ps_consts_f = min(num_ps_consts_f, adapter->d3d_info.limits.ps_uniform_count); - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_STATEBLOCK; -@@ -960,13 +953,9 @@ void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct win - - memcpy(op->state.vs_consts_b, state->vs_consts_b, sizeof(op->state.vs_consts_b)); - memcpy(op->state.vs_consts_i, state->vs_consts_i, sizeof(op->state.vs_consts_i)); -- op->state.vs_consts_f = op->vs_consts_f; -- memcpy(op->state.vs_consts_f, state->vs_consts_f, sizeof(*op->state.vs_consts_f) * num_vs_consts_f); - - memcpy(op->state.ps_consts_b, state->ps_consts_b, sizeof(op->state.ps_consts_b)); - memcpy(op->state.ps_consts_i, state->ps_consts_i, sizeof(op->state.ps_consts_i)); -- op->state.ps_consts_f = op->ps_consts_f; -- memcpy(op->state.ps_consts_f, state->ps_consts_f, sizeof(*op->state.ps_consts_f) * num_ps_consts_f); - - /* FIXME: This is not ideal. CS is still running synchronously, so this is ok. - * It will go away soon anyway. */ -@@ -1039,6 +1028,63 @@ void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type - op->opcode = WINED3D_CS_OP_SET_SHADER; - op->type = type; - op->shader = shader; -+} -+ -+static UINT wined3d_cs_exec_set_vs_consts_f(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_consts_f *op = data; -+ struct wined3d_device *device = cs->device; -+ -+ memcpy(cs->state.vs_consts_f + op->start_register * 4, op->constants, -+ sizeof(*cs->state.vs_consts_f) * 4 * op->vector4f_count); -+ -+ device->shader_backend->shader_update_float_vertex_constants(device, -+ op->start_register, op->vector4f_count); -+ -+ return sizeof(*op) + sizeof(op->constants) * (op->vector4f_count - 1); -+} -+ -+static UINT wined3d_cs_exec_set_ps_consts_f(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_consts_f *op = data; -+ struct wined3d_device *device = cs->device; -+ -+ memcpy(cs->state.ps_consts_f + op->start_register * 4, op->constants, -+ sizeof(*cs->state.ps_consts_f) * 4 * op->vector4f_count); -+ -+ device->shader_backend->shader_update_float_pixel_constants(device, -+ op->start_register, op->vector4f_count); -+ -+ return sizeof(*op) + sizeof(op->constants) * (op->vector4f_count - 1); -+} -+ -+void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, -+ const float *constants, UINT vector4f_count, enum wined3d_shader_type type) -+{ -+ struct wined3d_cs_set_consts_f *op; -+ UINT extra_space = vector4f_count - 1; -+ -+ op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); -+ switch (type) -+ { -+ case WINED3D_SHADER_TYPE_PIXEL: -+ op->opcode = WINED3D_CS_OP_SET_PS_CONSTS_F; -+ break; -+ -+ case WINED3D_SHADER_TYPE_VERTEX: -+ op->opcode = WINED3D_CS_OP_SET_VS_CONSTS_F; -+ break; -+ -+ case WINED3D_SHADER_TYPE_GEOMETRY: -+ FIXME("Invalid for geometry shaders\n"); -+ return; -+ -+ case WINED3D_SHADER_TYPE_COUNT: -+ break; -+ } -+ op->start_register = start_register; -+ op->vector4f_count = vector4f_count; -+ memcpy(op->constants, constants, sizeof(*constants) * 4 * vector4f_count); - - cs->ops->submit(cs); - } -@@ -1233,6 +1279,8 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, - /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, - /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, -+ /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, -+ /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, - }; - - static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 6ea0b9a..2aba2a4 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -2341,8 +2341,8 @@ HRESULT CDECL wined3d_device_set_vs_consts_f(struct wined3d_device *device, - memset(device->recording->changed.vertexShaderConstantsF + start_register, 1, - sizeof(*device->recording->changed.vertexShaderConstantsF) * vector4f_count); - else -- device->shader_backend->shader_update_float_vertex_constants(device, start_register, vector4f_count); -- -+ wined3d_cs_emit_set_consts_f(device->cs, start_register, constants, vector4f_count, -+ WINED3D_SHADER_TYPE_VERTEX); - - return WINED3D_OK; - } -@@ -2576,7 +2576,8 @@ HRESULT CDECL wined3d_device_set_ps_consts_f(struct wined3d_device *device, - memset(device->recording->changed.pixelShaderConstantsF + start_register, 1, - sizeof(*device->recording->changed.pixelShaderConstantsF) * vector4f_count); - else -- device->shader_backend->shader_update_float_pixel_constants(device, start_register, vector4f_count); -+ wined3d_cs_emit_set_consts_f(device->cs, start_register, constants, vector4f_count, -+ WINED3D_SHADER_TYPE_PIXEL); - - return WINED3D_OK; - } -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 02104ce..d673a8f 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2613,6 +2613,8 @@ void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform - void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, - struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, -+ UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0050-wined3d-Don-t-call-glFinish-after-clears.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0050-wined3d-Don-t-call-glFinish-after-clears.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0050-wined3d-Don-t-call-glFinish-after-clears.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0050-wined3d-Don-t-call-glFinish-after-clears.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,27 @@ +From d4014863c602be40898af0f2be9b718ee6abe7d0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Apr 2013 11:51:13 +0200 +Subject: wined3d: Don't call glFinish after clears + +--- + dlls/wined3d/device.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 4d15518..98c0717 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -463,9 +463,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c + } + } + +- if (wined3d_settings.cs_multithreaded) +- gl_info->gl_ops.gl.p_glFinish(); +- else if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET ++ if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET + && target->container->swapchain && target->container->swapchain->front_buffer == target->container)) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0050-wined3d-Request-a-glFinish-before-modifying-resource.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0050-wined3d-Request-a-glFinish-before-modifying-resource.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0050-wined3d-Request-a-glFinish-before-modifying-resource.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0050-wined3d-Request-a-glFinish-before-modifying-resource.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,253 +0,0 @@ -From a79863383e3dc7dfff564432e6c5086aa612d8af Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Apr 2013 11:50:09 +0200 -Subject: wined3d: Request a glFinish before modifying resources outside the cs - ---- - dlls/wined3d/buffer.c | 17 +++++++++++++++++ - dlls/wined3d/cs.c | 30 ++++++++++++++++++++++++++++++ - dlls/wined3d/device.c | 42 ++++++++++++++++++++++++++++++++++++++++++ - dlls/wined3d/resource.c | 7 +++++++ - dlls/wined3d/surface.c | 7 +++++++ - dlls/wined3d/wined3d_private.h | 1 + - 6 files changed, 104 insertions(+) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 0735ab7..3f740dd 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -931,6 +931,15 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte - void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) - { - struct wined3d_context *context; -+ struct wined3d_device *device = buffer->resource.device; -+ -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - context = context_acquire(buffer->resource.device, NULL); - buffer_internal_preload(buffer, context, NULL); - context_release(context); -@@ -947,9 +956,17 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - { - LONG count; - BYTE *base; -+ struct wined3d_device *device = buffer->resource.device; - - TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags); - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags); - /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001 multitexture - * fill rate test seems to depend on this. When we map a buffer with -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 63ac035..b7bedbf 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -66,6 +66,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_STATEBLOCK, - WINED3D_CS_OP_SET_VS_CONSTS_F, - WINED3D_CS_OP_SET_PS_CONSTS_F, -+ WINED3D_CS_OP_GLFINISH, - WINED3D_CS_OP_STOP, - }; - -@@ -294,6 +295,11 @@ struct wined3d_cs_set_consts_f - float constants[4]; - }; - -+struct wined3d_cs_finish -+{ -+ enum wined3d_cs_op opcode; -+}; -+ - /* FIXME: The list synchronization probably isn't particularly fast. */ - static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) - { -@@ -1364,6 +1370,29 @@ void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) - cs->ops->submit(cs); - } - -+static UINT wined3d_cs_exec_glfinish(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_finish *op = data; -+ struct wined3d_device *device = cs->device; -+ struct wined3d_context *context; -+ -+ context = context_acquire(device, NULL); -+ context->gl_info->gl_ops.gl.p_glFinish(); -+ context_release(context); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) -+{ -+ struct wined3d_cs_finish *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_GLFINISH; -+ -+ cs->ops->submit(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, -@@ -1396,6 +1425,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, - /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, - /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, -+ /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, - }; - - static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index d43075b..5e5f3f5 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -2765,6 +2765,13 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO - return hr; - } - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - wined3d_device_get_transform(device, WINED3D_TS_VIEW, &view_mat); - wined3d_device_get_transform(device, WINED3D_TS_PROJECTION, &proj_mat); - wined3d_device_get_transform(device, WINED3D_TS_WORLD_MATRIX(0), &world_mat); -@@ -3562,6 +3569,13 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, - ++src_skip_levels; - } - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - /* Make sure that the destination texture is loaded. */ - context = context_acquire(device, NULL); - wined3d_texture_load(dst_texture, context, FALSE); -@@ -3810,6 +3824,13 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, - return WINED3DERR_INVALIDCALL; - } - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - return surface_upload_from_surface(dst_surface, dst_point, src_surface, src_rect); - } - -@@ -4064,6 +4085,13 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi - rect = &r; - } - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), view->sub_resource_idx); - - return surface_color_fill(surface_from_resource(resource), rect, color); -@@ -4377,6 +4405,13 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) - - TRACE("device %p.\n", device); - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) - { - TRACE("Checking resource %p for eviction.\n", resource); -@@ -4499,6 +4534,13 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - TRACE("device %p, swapchain_desc %p, mode %p, callback %p, reset_state %#x.\n", - device, swapchain_desc, mode, callback, reset_state); - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - if (!(swapchain = wined3d_device_get_swapchain(device, 0))) - { - ERR("Failed to get the first implicit swapchain.\n"); -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 9c40d42..c72987c 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -786,6 +786,13 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, - - flags = wined3d_resource_sanitize_map_flags(resource, flags); - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - if (device->d3d_initialized) - context = context_acquire(device, NULL); - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index cba9da9..5e44494 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -5007,6 +5007,13 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC - flags &= ~WINEDDBLT_DONOTWAIT; - } - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("Waiting for cs.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - if (!device->d3d_initialized) - { - WARN("D3D not initialized, using fallback.\n"); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index d018cd9..2e42c79 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2702,6 +2702,7 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, - void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, - UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0051-wined3d-Don-t-call-glFinish-after-draws.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0051-wined3d-Don-t-call-glFinish-after-draws.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0051-wined3d-Don-t-call-glFinish-after-draws.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0051-wined3d-Don-t-call-glFinish-after-draws.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,27 @@ +From 7fd4d602c8a324c5f474370457363910e074296f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Apr 2013 11:53:10 +0200 +Subject: wined3d: Don't call glFinish after draws + +--- + dlls/wined3d/drawprim.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c +index 1627cfa..43d867d 100644 +--- a/dlls/wined3d/drawprim.c ++++ b/dlls/wined3d/drawprim.c +@@ -780,9 +780,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s + wined3d_event_query_issue(context->buffer_queries[i], device); + } + +- if (wined3d_settings.cs_multithreaded) +- gl_info->gl_ops.gl.p_glFinish(); +- else if (wined3d_settings.strict_draw_ordering) ++ if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + + context_release(context); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0051-wined3d-Finish-the-cs-before-changing-the-texture-lo.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0051-wined3d-Finish-the-cs-before-changing-the-texture-lo.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0051-wined3d-Finish-the-cs-before-changing-the-texture-lo.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0051-wined3d-Finish-the-cs-before-changing-the-texture-lo.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -From 58db2f20f55fd78d4831475a5bdce14339c1e66f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 10 Apr 2013 19:53:44 +0200 -Subject: wined3d: Finish the cs before changing the texture lod - ---- - dlls/wined3d/texture.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 6381613..0eb191e 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -510,6 +510,13 @@ DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod) - - if (texture->lod != lod) - { -+ if (wined3d_settings.cs_multithreaded) -+ { -+ struct wined3d_device *device = texture->resource.device; -+ FIXME("Waiting for cs.\n"); -+ device->cs->ops->finish(device->cs); -+ } -+ - texture->lod = lod; - - texture->texture_rgb.base_level = ~0u; --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0052-wined3d-Don-t-call-glFinish-after-clears.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0052-wined3d-Don-t-call-glFinish-after-clears.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0052-wined3d-Don-t-call-glFinish-after-clears.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0052-wined3d-Don-t-call-glFinish-after-clears.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -From d4014863c602be40898af0f2be9b718ee6abe7d0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Apr 2013 11:51:13 +0200 -Subject: wined3d: Don't call glFinish after clears - ---- - dlls/wined3d/device.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 4d15518..98c0717 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -463,9 +463,7 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c - } - } - -- if (wined3d_settings.cs_multithreaded) -- gl_info->gl_ops.gl.p_glFinish(); -- else if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET -+ if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET - && target->container->swapchain && target->container->swapchain->front_buffer == target->container)) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0052-wined3d-Shadow-device-offscreenBuffer-in-the-context.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0052-wined3d-Shadow-device-offscreenBuffer-in-the-context.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0052-wined3d-Shadow-device-offscreenBuffer-in-the-context.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0052-wined3d-Shadow-device-offscreenBuffer-in-the-context.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,54 @@ +From e0c083d32b61b7a5bee9371bcf8a1b03964303a0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Apr 2013 14:40:47 +0200 +Subject: wined3d: Shadow device->offscreenBuffer in the context + +Meh. Should probably go into the adapter, or non-fbo ORM should just die +TODO 2: See what this is actually used for. +--- + dlls/wined3d/context.c | 2 ++ + dlls/wined3d/device.c | 1 + + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 5 insertions(+) + +diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c +index 7ba4086..fc66ff1 100644 +--- a/dlls/wined3d/context.c ++++ b/dlls/wined3d/context.c +@@ -1453,6 +1453,8 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, + ret->current_fb.rt_size = gl_info->limits.buffers; + if (!ret->current_fb.render_targets) + goto out; ++ if (device->context_count) ++ ret->offscreenBuffer = device->contexts[0]->offscreenBuffer; + + /* Initialize the texture unit mapping to a 1:1 mapping */ + for (s = 0; s < MAX_COMBINED_SAMPLERS; ++s) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 98c0717..ee8b418 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -948,6 +948,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, + } + } + } ++ device->contexts[0]->offscreenBuffer = device->offscreenBuffer; + + TRACE("All defaults now set up, leaving 3D init.\n"); + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index ba0ce26..a16909c 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -1232,6 +1232,8 @@ struct wined3d_context + GLfloat fog_coord_value; + GLfloat color[4], fogstart, fogend, fogcolor[4]; + GLuint dummy_arbfp_prog; ++ ++ GLenum offscreenBuffer; + }; + + typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0053-wined3d-Don-t-access-the-stateblock-in-find_draw_buf.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0053-wined3d-Don-t-access-the-stateblock-in-find_draw_buf.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0053-wined3d-Don-t-access-the-stateblock-in-find_draw_buf.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0053-wined3d-Don-t-access-the-stateblock-in-find_draw_buf.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,105 @@ +From 61077043981635623c0f2eda20aa252c18fc4104 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Apr 2013 14:43:23 +0200 +Subject: wined3d: Don't access the stateblock in find_draw_buffers_mask + +--- + dlls/wined3d/context.c | 21 +++++++++------------ + 1 file changed, 9 insertions(+), 12 deletions(-) + +diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c +index fc66ff1..39c9464 100644 +--- a/dlls/wined3d/context.c ++++ b/dlls/wined3d/context.c +@@ -2231,14 +2231,14 @@ static void context_validate_onscreen_formats(struct wined3d_context *context, + context_set_render_offscreen(context, TRUE); + } + +-static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_device *device, const struct wined3d_surface *rt) ++static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context, const struct wined3d_surface *rt) + { + if (!rt || rt->resource.format->id == WINED3DFMT_NULL) + return 0; + else if (rt->container->swapchain) + return context_generate_rt_mask_from_surface(rt); + else +- return context_generate_rt_mask(device->offscreenBuffer); ++ return context_generate_rt_mask(context->offscreenBuffer); + } + + /* Context activation is done by the caller. */ +@@ -2270,7 +2270,7 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine + } + else + { +- rt_mask = context_generate_rt_mask_no_fbo(device, rt); ++ rt_mask = context_generate_rt_mask_no_fbo(context, rt); + } + + cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; +@@ -2356,7 +2356,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win + } + else + { +- rt_mask = context_generate_rt_mask_no_fbo(device, ++ rt_mask = context_generate_rt_mask_no_fbo(context, + rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); + } + +@@ -2373,7 +2373,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win + } + else + { +- rt_mask = context_generate_rt_mask_no_fbo(device, ++ rt_mask = context_generate_rt_mask_no_fbo(context, + rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); + } + +@@ -2408,16 +2408,15 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win + return TRUE; + } + +-static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_device *device) ++static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_state *state) + { +- const struct wined3d_state *state = &device->state; + struct wined3d_rendertarget_view **rts = state->fb.render_targets; + struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; + DWORD rt_mask, rt_mask_bits; + unsigned int i; + + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) +- return context_generate_rt_mask_no_fbo(device, wined3d_rendertarget_view_get_surface(rts[0])); ++ return context_generate_rt_mask_no_fbo(context, wined3d_rendertarget_view_get_surface(rts[0])); + else if (!context->render_offscreen) + return context_generate_rt_mask_from_surface(wined3d_rendertarget_view_get_surface(rts[0])); + +@@ -2440,9 +2439,8 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const + /* Context activation is done by the caller. */ + void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { +- const struct wined3d_device *device = context->swapchain->device; + const struct wined3d_fb_state *fb = &state->fb; +- DWORD rt_mask = find_draw_buffers_mask(context, device); ++ DWORD rt_mask = find_draw_buffers_mask(context, state); + DWORD *cur_mask; + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) +@@ -2710,13 +2708,12 @@ static void context_update_tex_unit_map(struct wined3d_context *context, const s + /* Context activation is done by the caller. */ + void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { +- const struct wined3d_device *device = context->swapchain->device; + DWORD rt_mask, *cur_mask; + + if (isStateDirty(context, STATE_FRAMEBUFFER)) return; + + cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; +- rt_mask = find_draw_buffers_mask(context, device); ++ rt_mask = find_draw_buffers_mask(context, state); + if (rt_mask != *cur_mask) + { + context_apply_draw_buffers(context, rt_mask); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0053-wined3d-Don-t-call-glFinish-after-draws.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0053-wined3d-Don-t-call-glFinish-after-draws.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0053-wined3d-Don-t-call-glFinish-after-draws.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0053-wined3d-Don-t-call-glFinish-after-draws.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -From 7fd4d602c8a324c5f474370457363910e074296f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Apr 2013 11:53:10 +0200 -Subject: wined3d: Don't call glFinish after draws - ---- - dlls/wined3d/drawprim.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c -index 1627cfa..43d867d 100644 ---- a/dlls/wined3d/drawprim.c -+++ b/dlls/wined3d/drawprim.c -@@ -780,9 +780,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s - wined3d_event_query_issue(context->buffer_queries[i], device); - } - -- if (wined3d_settings.cs_multithreaded) -- gl_info->gl_ops.gl.p_glFinish(); -- else if (wined3d_settings.strict_draw_ordering) -+ if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - context_release(context); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0054-wined3d-Pass-the-depth-stencil-to-swapchain-present.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0054-wined3d-Pass-the-depth-stencil-to-swapchain-present.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0054-wined3d-Pass-the-depth-stencil-to-swapchain-present.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0054-wined3d-Pass-the-depth-stencil-to-swapchain-present.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,95 @@ +From 1f1e2612071335c2b167345933ed23047a40103e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Apr 2013 14:52:24 +0200 +Subject: wined3d: Pass the depth stencil to swapchain->present + +TODO: Test if D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL discards the current +DS or the implicit DS. +--- + dlls/wined3d/cs.c | 3 ++- + dlls/wined3d/swapchain.c | 21 ++++++++++----------- + dlls/wined3d/wined3d_private.h | 3 ++- + 3 files changed, 14 insertions(+), 13 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index e42cbe0..4e99cd2 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -439,7 +439,8 @@ static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) + wined3d_swapchain_set_window(swapchain, op->dst_window_override); + + swapchain->swapchain_ops->swapchain_present(swapchain, +- src_rect, dst_rect, dirty_region, op->flags); ++ src_rect, dst_rect, dirty_region, op->flags, ++ wined3d_rendertarget_view_get_surface(cs->state.fb.depth_stencil)); + + return sizeof(*op); + } +diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c +index 74e59cf..6ded6cc 100644 +--- a/dlls/wined3d/swapchain.c ++++ b/dlls/wined3d/swapchain.c +@@ -423,11 +423,11 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain, + } + + static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in, +- const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags) ++ const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags, ++ struct wined3d_surface *depth_stencil) + { + struct wined3d_surface *back_buffer = surface_from_resource( + wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); +- const struct wined3d_fb_state *fb = &swapchain->device->state.fb; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + struct wined3d_surface *front; +@@ -581,16 +581,14 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT + break; + } + +- if (fb->depth_stencil) ++ if (depth_stencil) + { +- struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(fb->depth_stencil); +- +- if (ds && (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL +- || ds->flags & SFLAG_DISCARD)) ++ if (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL ++ || depth_stencil->flags & SFLAG_DISCARD) + { +- surface_modify_ds_location(ds, WINED3D_LOCATION_DISCARDED, +- fb->depth_stencil->width, fb->depth_stencil->height); +- if (ds == swapchain->device->onscreen_depth_stencil) ++ surface_modify_ds_location(depth_stencil, WINED3D_LOCATION_DISCARDED, ++ depth_stencil->resource.width, depth_stencil->resource.height); ++ if (depth_stencil == swapchain->device->onscreen_depth_stencil) + { + wined3d_texture_decref(swapchain->device->onscreen_depth_stencil->container); + swapchain->device->onscreen_depth_stencil = NULL; +@@ -654,7 +652,8 @@ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *r + } + + static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in, +- const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags) ++ const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags, ++ struct wined3d_surface *depth_stencil) + { + struct wined3d_surface *front, *back; + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 056c781..dec58e5 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2860,7 +2860,8 @@ struct wined3d_shader_resource_view + struct wined3d_swapchain_ops + { + void (*swapchain_present)(struct wined3d_swapchain *swapchain, const RECT *src_rect, +- const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags); ++ const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags, ++ struct wined3d_surface *depth_stencil); + }; + + struct wined3d_swapchain +-- +2.6.2 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0054-wined3d-Shadow-device-offscreenBuffer-in-the-context.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0054-wined3d-Shadow-device-offscreenBuffer-in-the-context.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0054-wined3d-Shadow-device-offscreenBuffer-in-the-context.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0054-wined3d-Shadow-device-offscreenBuffer-in-the-context.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -From e0c083d32b61b7a5bee9371bcf8a1b03964303a0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Apr 2013 14:40:47 +0200 -Subject: wined3d: Shadow device->offscreenBuffer in the context - -Meh. Should probably go into the adapter, or non-fbo ORM should just die -TODO 2: See what this is actually used for. ---- - dlls/wined3d/context.c | 2 ++ - dlls/wined3d/device.c | 1 + - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 5 insertions(+) - -diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c -index 7ba4086..fc66ff1 100644 ---- a/dlls/wined3d/context.c -+++ b/dlls/wined3d/context.c -@@ -1453,6 +1453,8 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, - ret->current_fb.rt_size = gl_info->limits.buffers; - if (!ret->current_fb.render_targets) - goto out; -+ if (device->context_count) -+ ret->offscreenBuffer = device->contexts[0]->offscreenBuffer; - - /* Initialize the texture unit mapping to a 1:1 mapping */ - for (s = 0; s < MAX_COMBINED_SAMPLERS; ++s) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 98c0717..ee8b418 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -948,6 +948,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, - } - } - } -+ device->contexts[0]->offscreenBuffer = device->offscreenBuffer; - - TRACE("All defaults now set up, leaving 3D init.\n"); - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index ba0ce26..a16909c 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -1232,6 +1232,8 @@ struct wined3d_context - GLfloat fog_coord_value; - GLfloat color[4], fogstart, fogend, fogcolor[4]; - GLuint dummy_arbfp_prog; -+ -+ GLenum offscreenBuffer; - }; - - typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0055-wined3d-Don-t-access-the-stateblock-in-find_draw_buf.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0055-wined3d-Don-t-access-the-stateblock-in-find_draw_buf.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0055-wined3d-Don-t-access-the-stateblock-in-find_draw_buf.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0055-wined3d-Don-t-access-the-stateblock-in-find_draw_buf.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -From 61077043981635623c0f2eda20aa252c18fc4104 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Apr 2013 14:43:23 +0200 -Subject: wined3d: Don't access the stateblock in find_draw_buffers_mask - ---- - dlls/wined3d/context.c | 21 +++++++++------------ - 1 file changed, 9 insertions(+), 12 deletions(-) - -diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c -index fc66ff1..39c9464 100644 ---- a/dlls/wined3d/context.c -+++ b/dlls/wined3d/context.c -@@ -2231,14 +2231,14 @@ static void context_validate_onscreen_formats(struct wined3d_context *context, - context_set_render_offscreen(context, TRUE); - } - --static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_device *device, const struct wined3d_surface *rt) -+static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *context, const struct wined3d_surface *rt) - { - if (!rt || rt->resource.format->id == WINED3DFMT_NULL) - return 0; - else if (rt->container->swapchain) - return context_generate_rt_mask_from_surface(rt); - else -- return context_generate_rt_mask(device->offscreenBuffer); -+ return context_generate_rt_mask(context->offscreenBuffer); - } - - /* Context activation is done by the caller. */ -@@ -2270,7 +2270,7 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine - } - else - { -- rt_mask = context_generate_rt_mask_no_fbo(device, rt); -+ rt_mask = context_generate_rt_mask_no_fbo(context, rt); - } - - cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; -@@ -2356,7 +2356,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win - } - else - { -- rt_mask = context_generate_rt_mask_no_fbo(device, -+ rt_mask = context_generate_rt_mask_no_fbo(context, - rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); - } - -@@ -2373,7 +2373,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win - } - else - { -- rt_mask = context_generate_rt_mask_no_fbo(device, -+ rt_mask = context_generate_rt_mask_no_fbo(context, - rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); - } - -@@ -2408,16 +2408,15 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win - return TRUE; - } - --static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_device *device) -+static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_state *state) - { -- const struct wined3d_state *state = &device->state; - struct wined3d_rendertarget_view **rts = state->fb.render_targets; - struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; - DWORD rt_mask, rt_mask_bits; - unsigned int i; - - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) -- return context_generate_rt_mask_no_fbo(device, wined3d_rendertarget_view_get_surface(rts[0])); -+ return context_generate_rt_mask_no_fbo(context, wined3d_rendertarget_view_get_surface(rts[0])); - else if (!context->render_offscreen) - return context_generate_rt_mask_from_surface(wined3d_rendertarget_view_get_surface(rts[0])); - -@@ -2440,9 +2439,8 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const - /* Context activation is done by the caller. */ - void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) - { -- const struct wined3d_device *device = context->swapchain->device; - const struct wined3d_fb_state *fb = &state->fb; -- DWORD rt_mask = find_draw_buffers_mask(context, device); -+ DWORD rt_mask = find_draw_buffers_mask(context, state); - DWORD *cur_mask; - - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) -@@ -2710,13 +2708,12 @@ static void context_update_tex_unit_map(struct wined3d_context *context, const s - /* Context activation is done by the caller. */ - void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) - { -- const struct wined3d_device *device = context->swapchain->device; - DWORD rt_mask, *cur_mask; - - if (isStateDirty(context, STATE_FRAMEBUFFER)) return; - - cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; -- rt_mask = find_draw_buffers_mask(context, device); -+ rt_mask = find_draw_buffers_mask(context, state); - if (rt_mask != *cur_mask) - { - context_apply_draw_buffers(context, rt_mask); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0055-wined3d-Don-t-store-viewport-pointers-in-the-command.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0055-wined3d-Don-t-store-viewport-pointers-in-the-command.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0055-wined3d-Don-t-store-viewport-pointers-in-the-command.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0055-wined3d-Don-t-store-viewport-pointers-in-the-command.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,47 @@ +From eb236d88cef3c5c73289c1147466a1cc85657500 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 5 Apr 2013 10:12:06 +0200 +Subject: wined3d: Don't store viewport pointers in the command stream. + +--- + dlls/wined3d/cs.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 03e760d..4b1ed18 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -126,7 +126,7 @@ struct wined3d_cs_set_predication + struct wined3d_cs_set_viewport + { + enum wined3d_cs_op opcode; +- const struct wined3d_viewport *viewport; ++ struct wined3d_viewport viewport; + }; + + struct wined3d_cs_set_scissor_rect +@@ -552,9 +552,10 @@ void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query + static UINT wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_viewport *op = data; ++ struct wined3d_device *device = cs->device; + +- cs->state.viewport = *op->viewport; +- device_invalidate_state(cs->device, STATE_VIEWPORT); ++ cs->state.viewport = op->viewport; ++ device_invalidate_state(device, STATE_VIEWPORT); + + return sizeof(*op); + } +@@ -565,7 +566,7 @@ void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_vi + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_VIEWPORT; +- op->viewport = viewport; ++ op->viewport = *viewport; + + cs->ops->submit(cs); + } +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0056-wined3d-Keep-track-of-the-onscreen-depth-stencil-in-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0056-wined3d-Keep-track-of-the-onscreen-depth-stencil-in-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0056-wined3d-Keep-track-of-the-onscreen-depth-stencil-in-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0056-wined3d-Keep-track-of-the-onscreen-depth-stencil-in-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,217 @@ +From 8842cf6a7d2b87f69462e5fe513f51bc127a8140 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 5 Apr 2013 14:37:44 +0200 +Subject: wined3d: Keep track of the onscreen depth stencil in the command + stream instead of the device. + +Based on a patch by Henri Verbeet. + +TODO: Not sure if its the right way to go. There are certainly some +missing bits, e.g. accessing the cs via the device in all but one places +defeats the point of this at the moment. + +Since the GL onscreen depth stencil is part of the WGL framebuffer, +which belongs to the swapchain, storing this info in the swapchain might +be the right thing to do. This should help multi-window or multi-head +configurations. +--- + dlls/wined3d/cs.c | 22 +++++++++++++++++++--- + dlls/wined3d/device.c | 35 ++++++++++------------------------- + dlls/wined3d/drawprim.c | 4 ++-- + dlls/wined3d/swapchain.c | 6 +++--- + dlls/wined3d/wined3d_private.h | 10 ++++------ + 5 files changed, 38 insertions(+), 39 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index d5e2c52..b20d32f 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -639,10 +639,10 @@ static UINT wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const + || prev_surface->flags & SFLAG_DISCARD)) + { + surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height); +- if (prev_surface == device->onscreen_depth_stencil) ++ if (prev_surface == cs->onscreen_depth_stencil) + { +- wined3d_texture_decref(device->onscreen_depth_stencil->container); +- device->onscreen_depth_stencil = NULL; ++ wined3d_texture_decref(cs->onscreen_depth_stencil->container); ++ cs->onscreen_depth_stencil = NULL; + } + } + } +@@ -1480,6 +1480,22 @@ static void wined3d_cs_emit_stop(struct wined3d_cs *cs) + wined3d_cs_flush(cs); + } + ++void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, ++ struct wined3d_context *context, struct wined3d_surface *depth_stencil) ++{ ++ if (cs->onscreen_depth_stencil) ++ { ++ surface_load_ds_location(cs->onscreen_depth_stencil, context, WINED3D_LOCATION_TEXTURE_RGB); ++ ++ surface_modify_ds_location(cs->onscreen_depth_stencil, WINED3D_LOCATION_TEXTURE_RGB, ++ cs->onscreen_depth_stencil->ds_current_size.cx, ++ cs->onscreen_depth_stencil->ds_current_size.cy); ++ wined3d_texture_decref(cs->onscreen_depth_stencil->container); ++ } ++ cs->onscreen_depth_stencil = depth_stencil; ++ wined3d_texture_incref(cs->onscreen_depth_stencil->container); ++} ++ + static DWORD WINAPI wined3d_cs_run(void *thread_param) + { + struct wined3d_cs *cs = thread_param; +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 1fef5ff..4de7eb2 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -198,22 +198,6 @@ void device_context_remove(struct wined3d_device *device, struct wined3d_context + device->contexts = new_array; + } + +-void device_switch_onscreen_ds(struct wined3d_device *device, +- struct wined3d_context *context, struct wined3d_surface *depth_stencil) +-{ +- if (device->onscreen_depth_stencil) +- { +- surface_load_ds_location(device->onscreen_depth_stencil, context, WINED3D_LOCATION_TEXTURE_RGB); +- +- surface_modify_ds_location(device->onscreen_depth_stencil, WINED3D_LOCATION_TEXTURE_RGB, +- device->onscreen_depth_stencil->ds_current_size.cx, +- device->onscreen_depth_stencil->ds_current_size.cy); +- wined3d_texture_decref(device->onscreen_depth_stencil->container); +- } +- device->onscreen_depth_stencil = depth_stencil; +- wined3d_texture_incref(device->onscreen_depth_stencil->container); +-} +- + static BOOL is_full_clear(const struct wined3d_surface *target, const RECT *draw_rect, const RECT *clear_rect) + { + /* partial draw rect */ +@@ -348,8 +332,8 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c + { + DWORD location = render_offscreen ? fb->depth_stencil->resource->draw_binding : WINED3D_LOCATION_DRAWABLE; + +- if (!render_offscreen && depth_stencil != device->onscreen_depth_stencil) +- device_switch_onscreen_ds(device, context, depth_stencil); ++ if (!render_offscreen && depth_stencil != device->cs->onscreen_depth_stencil) ++ wined3d_cs_switch_onscreen_ds(device->cs, context, depth_stencil); + prepare_ds_clear(depth_stencil, context, location, + draw_rect, rect_count, clear_rect, &ds_rect); + } +@@ -1064,11 +1048,12 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) + /* Release the buffers (with sanity checks). + * FIXME: Move this move into a separate patch. I think the idea + * behind this is that those surfaces should be freed before unloading +- * remaining resources below. */ +- if (device->onscreen_depth_stencil) ++ * remaining resources below. ++ * FIXME 2: Shouldn't the cs take care of onscreen_depth_stencil? */ ++ if (device->cs->onscreen_depth_stencil) + { +- surface = device->onscreen_depth_stencil; +- device->onscreen_depth_stencil = NULL; ++ surface = device->cs->onscreen_depth_stencil; ++ device->cs->onscreen_depth_stencil = NULL; + wined3d_texture_decref(surface->container); + } + +@@ -4561,10 +4546,10 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + state_unbind_resources(&device->state); + } + +- if (device->onscreen_depth_stencil) ++ if (device->cs->onscreen_depth_stencil) + { +- wined3d_texture_decref(device->onscreen_depth_stencil->container); +- device->onscreen_depth_stencil = NULL; ++ wined3d_texture_decref(device->cs->onscreen_depth_stencil->container); ++ device->cs->onscreen_depth_stencil = NULL; + } + + if (reset_state) +diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c +index 21ce53a..9ec380a 100644 +--- a/dlls/wined3d/drawprim.c ++++ b/dlls/wined3d/drawprim.c +@@ -651,8 +651,8 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s + { + RECT current_rect, draw_rect, r; + +- if (!context->render_offscreen && ds != device->onscreen_depth_stencil) +- device_switch_onscreen_ds(device, context, ds); ++ if (!context->render_offscreen && ds != device->cs->onscreen_depth_stencil) ++ wined3d_cs_switch_onscreen_ds(device->cs, context, ds); + + if (ds->resource.locations & location) + SetRect(¤t_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy); +diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c +index 6ded6cc..0a8da3d 100644 +--- a/dlls/wined3d/swapchain.c ++++ b/dlls/wined3d/swapchain.c +@@ -588,10 +588,10 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT + { + surface_modify_ds_location(depth_stencil, WINED3D_LOCATION_DISCARDED, + depth_stencil->resource.width, depth_stencil->resource.height); +- if (depth_stencil == swapchain->device->onscreen_depth_stencil) ++ if (depth_stencil == swapchain->device->cs->onscreen_depth_stencil) + { +- wined3d_texture_decref(swapchain->device->onscreen_depth_stencil->container); +- swapchain->device->onscreen_depth_stencil = NULL; ++ wined3d_texture_decref(swapchain->device->cs->onscreen_depth_stencil->container); ++ swapchain->device->cs->onscreen_depth_stencil = NULL; + } + } + } +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index dec58e5..035517f 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2116,15 +2116,12 @@ struct wined3d_device + struct wined3d_rendertarget_view *back_buffer_view; + struct wined3d_swapchain **swapchains; + UINT swapchain_count; ++ struct wined3d_rendertarget_view *auto_depth_stencil_view; + + struct list resources; /* a linked list to track resources created by the device */ + struct list shaders; /* a linked list to track shaders (pixel and vertex) */ + struct wine_rb_tree samplers; + +- /* Render Target Support */ +- struct wined3d_surface *onscreen_depth_stencil; +- struct wined3d_rendertarget_view *auto_depth_stencil_view; +- + /* For rendering to a texture using glCopyTexImage */ + GLuint depth_blt_texture; + +@@ -2166,8 +2163,6 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL + UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN; + void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; +-void device_switch_onscreen_ds(struct wined3d_device *device, struct wined3d_context *context, +- struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; + void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; + + static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) +@@ -2667,6 +2662,7 @@ struct wined3d_cs + struct wined3d_state state; + HANDLE thread; + DWORD tls_idx; ++ struct wined3d_surface *onscreen_depth_stencil; + + size_t data_size; + void *data; +@@ -2677,6 +2673,8 @@ struct wined3d_cs + + struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; + void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN; ++void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, struct wined3d_context *context, ++ struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; + + void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, + DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; +-- +2.6.2 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0056-wined3d-Pass-the-depth-stencil-to-swapchain-present.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0056-wined3d-Pass-the-depth-stencil-to-swapchain-present.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0056-wined3d-Pass-the-depth-stencil-to-swapchain-present.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0056-wined3d-Pass-the-depth-stencil-to-swapchain-present.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -From 1f1e2612071335c2b167345933ed23047a40103e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Apr 2013 14:52:24 +0200 -Subject: wined3d: Pass the depth stencil to swapchain->present - -TODO: Test if D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL discards the current -DS or the implicit DS. ---- - dlls/wined3d/cs.c | 3 ++- - dlls/wined3d/swapchain.c | 21 ++++++++++----------- - dlls/wined3d/wined3d_private.h | 3 ++- - 3 files changed, 14 insertions(+), 13 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index e42cbe0..4e99cd2 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -439,7 +439,8 @@ static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) - wined3d_swapchain_set_window(swapchain, op->dst_window_override); - - swapchain->swapchain_ops->swapchain_present(swapchain, -- src_rect, dst_rect, dirty_region, op->flags); -+ src_rect, dst_rect, dirty_region, op->flags, -+ wined3d_rendertarget_view_get_surface(cs->state.fb.depth_stencil)); - - return sizeof(*op); - } -diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c -index 74e59cf..6ded6cc 100644 ---- a/dlls/wined3d/swapchain.c -+++ b/dlls/wined3d/swapchain.c -@@ -423,11 +423,11 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain, - } - - static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in, -- const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags) -+ const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags, -+ struct wined3d_surface *depth_stencil) - { - struct wined3d_surface *back_buffer = surface_from_resource( - wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); -- const struct wined3d_fb_state *fb = &swapchain->device->state.fb; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - struct wined3d_surface *front; -@@ -581,16 +581,14 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT - break; - } - -- if (fb->depth_stencil) -+ if (depth_stencil) - { -- struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(fb->depth_stencil); -- -- if (ds && (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL -- || ds->flags & SFLAG_DISCARD)) -+ if (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL -+ || depth_stencil->flags & SFLAG_DISCARD) - { -- surface_modify_ds_location(ds, WINED3D_LOCATION_DISCARDED, -- fb->depth_stencil->width, fb->depth_stencil->height); -- if (ds == swapchain->device->onscreen_depth_stencil) -+ surface_modify_ds_location(depth_stencil, WINED3D_LOCATION_DISCARDED, -+ depth_stencil->resource.width, depth_stencil->resource.height); -+ if (depth_stencil == swapchain->device->onscreen_depth_stencil) - { - wined3d_texture_decref(swapchain->device->onscreen_depth_stencil->container); - swapchain->device->onscreen_depth_stencil = NULL; -@@ -654,7 +652,8 @@ void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *r - } - - static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in, -- const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags) -+ const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags, -+ struct wined3d_surface *depth_stencil) - { - struct wined3d_surface *front, *back; - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 056c781..dec58e5 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2860,7 +2860,8 @@ struct wined3d_shader_resource_view - struct wined3d_swapchain_ops - { - void (*swapchain_present)(struct wined3d_swapchain *swapchain, const RECT *src_rect, -- const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags); -+ const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags, -+ struct wined3d_surface *depth_stencil); - }; - - struct wined3d_swapchain --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0057-wined3d-Don-t-store-viewport-pointers-in-the-command.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0057-wined3d-Don-t-store-viewport-pointers-in-the-command.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0057-wined3d-Don-t-store-viewport-pointers-in-the-command.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0057-wined3d-Don-t-store-viewport-pointers-in-the-command.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -From eb236d88cef3c5c73289c1147466a1cc85657500 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 5 Apr 2013 10:12:06 +0200 -Subject: wined3d: Don't store viewport pointers in the command stream. - ---- - dlls/wined3d/cs.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 03e760d..4b1ed18 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -126,7 +126,7 @@ struct wined3d_cs_set_predication - struct wined3d_cs_set_viewport - { - enum wined3d_cs_op opcode; -- const struct wined3d_viewport *viewport; -+ struct wined3d_viewport viewport; - }; - - struct wined3d_cs_set_scissor_rect -@@ -552,9 +552,10 @@ void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query - static UINT wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_viewport *op = data; -+ struct wined3d_device *device = cs->device; - -- cs->state.viewport = *op->viewport; -- device_invalidate_state(cs->device, STATE_VIEWPORT); -+ cs->state.viewport = op->viewport; -+ device_invalidate_state(device, STATE_VIEWPORT); - - return sizeof(*op); - } -@@ -565,7 +566,7 @@ void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_vi - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_SET_VIEWPORT; -- op->viewport = viewport; -+ op->viewport = *viewport; - - cs->ops->submit(cs); - } --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0057-wined3d-Send-base-vertex-index-updates-through-the-c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0057-wined3d-Send-base-vertex-index-updates-through-the-c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0057-wined3d-Send-base-vertex-index-updates-through-the-c.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0057-wined3d-Send-base-vertex-index-updates-through-the-c.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,178 @@ +From 4b5e47ede0b1ac538b6439e8b1888e4da542ceee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sun, 7 Apr 2013 17:33:20 +0200 +Subject: wined3d: Send base vertex index updates through the cs + +--- + dlls/wined3d/cs.c | 49 ++++++++++++++++++++++++++++++++++++++---- + dlls/wined3d/device.c | 17 +++------------ + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 50 insertions(+), 18 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 236e2f2..0525a59 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -66,6 +66,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_SET_VS_CONSTS_F, + WINED3D_CS_OP_SET_PS_CONSTS_F, + WINED3D_CS_OP_GLFINISH, ++ WINED3D_CS_OP_SET_BASE_VERTEX_INDEX, + WINED3D_CS_OP_STOP, + }; + +@@ -290,6 +291,12 @@ struct wined3d_cs_finish + enum wined3d_cs_op opcode; + }; + ++struct wined3d_cs_set_base_vertex_index ++{ ++ enum wined3d_cs_op opcode; ++ UINT base_vertex_index; ++}; ++ + /* FIXME: The list synchronization probably isn't particularly fast. */ + static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) + { +@@ -504,6 +511,21 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * + static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_draw *op = data; ++ const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info; ++ ++ if (op->indexed && !gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) ++ { ++ if (cs->state.load_base_vertex_index != cs->state.base_vertex_index) ++ { ++ cs->state.load_base_vertex_index = cs->state.base_vertex_index; ++ device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX); ++ } ++ } ++ else if (cs->state.load_base_vertex_index) ++ { ++ cs->state.load_base_vertex_index = 0; ++ device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX); ++ } + + draw_primitive(cs->device, &cs->state, op->start_idx, op->index_count, + op->start_instance, op->instance_count, op->indexed); +@@ -931,8 +953,6 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi + /* Don't memcpy the entire struct, we'll remove single items as we add dedicated + * ops for setting states */ + +- cs->state.base_vertex_index = op->state.base_vertex_index; +- cs->state.load_base_vertex_index = op->state.load_base_vertex_index; + cs->state.gl_primitive_type = op->state.gl_primitive_type; + + memcpy(cs->state.vs_consts_b, op->state.vs_consts_b, sizeof(cs->state.vs_consts_b)); +@@ -955,8 +975,6 @@ void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct win + + /* Don't memcpy the entire struct, we'll remove single items as we add dedicated + * ops for setting states */ +- op->state.base_vertex_index = state->base_vertex_index; +- op->state.load_base_vertex_index = state->load_base_vertex_index; + op->state.gl_primitive_type = state->gl_primitive_type; + + memcpy(op->state.vs_consts_b, state->vs_consts_b, sizeof(op->state.vs_consts_b)); +@@ -1281,6 +1299,28 @@ void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) + cs->ops->submit(cs); + } + ++static UINT wined3d_cs_exec_set_base_vertex_index(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_base_vertex_index *op = data; ++ ++ cs->state.base_vertex_index = op->base_vertex_index; ++ device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, ++ UINT base_vertex_index) ++{ ++ struct wined3d_cs_set_base_vertex_index *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_BASE_VERTEX_INDEX; ++ op->base_vertex_index = base_vertex_index; ++ ++ cs->ops->submit(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, +@@ -1313,6 +1353,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, + /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, + /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, ++ /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, + }; + + static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index dfc0619..a80784b 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -1830,6 +1830,9 @@ void CDECL wined3d_device_set_base_vertex_index(struct wined3d_device *device, I + TRACE("device %p, base_index %d.\n", device, base_index); + + device->update_state->base_vertex_index = base_index; ++ ++ if (!device->recording) ++ wined3d_cs_emit_set_base_vertex_index(device->cs, base_index); + } + + INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *device) +@@ -3377,12 +3380,6 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT + return WINED3DERR_INVALIDCALL; + } + +- if (device->state.load_base_vertex_index) +- { +- device->state.load_base_vertex_index = 0; +- device_invalidate_state(device, STATE_BASEVERTEXINDEX); +- } +- + wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); + wined3d_cs_emit_draw(device->cs, start_vertex, vertex_count, 0, 0, FALSE); + +@@ -3391,8 +3388,6 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT + + HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count) + { +- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; +- + TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count); + + if (!device->state.index_buffer) +@@ -3411,12 +3406,6 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic + return WINED3DERR_INVALIDCALL; + } + +- if (!gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] && +- device->state.load_base_vertex_index != device->state.base_vertex_index) +- { +- device->state.load_base_vertex_index = device->state.base_vertex_index; +- device_invalidate_state(device, STATE_BASEVERTEXINDEX); +- } + + wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); + wined3d_cs_emit_draw(device->cs, start_idx, index_count, 0, 0, TRUE); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index e4dbd9d..382c120 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2616,6 +2616,8 @@ void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_vi + void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, + UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; + void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, ++ UINT base_vertex_index) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0058-wined3d-Keep-track-of-the-onscreen-depth-stencil-in-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0058-wined3d-Keep-track-of-the-onscreen-depth-stencil-in-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0058-wined3d-Keep-track-of-the-onscreen-depth-stencil-in-.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0058-wined3d-Keep-track-of-the-onscreen-depth-stencil-in-.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,217 +0,0 @@ -From 8842cf6a7d2b87f69462e5fe513f51bc127a8140 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 5 Apr 2013 14:37:44 +0200 -Subject: wined3d: Keep track of the onscreen depth stencil in the command - stream instead of the device. - -Based on a patch by Henri Verbeet. - -TODO: Not sure if its the right way to go. There are certainly some -missing bits, e.g. accessing the cs via the device in all but one places -defeats the point of this at the moment. - -Since the GL onscreen depth stencil is part of the WGL framebuffer, -which belongs to the swapchain, storing this info in the swapchain might -be the right thing to do. This should help multi-window or multi-head -configurations. ---- - dlls/wined3d/cs.c | 22 +++++++++++++++++++--- - dlls/wined3d/device.c | 35 ++++++++++------------------------- - dlls/wined3d/drawprim.c | 4 ++-- - dlls/wined3d/swapchain.c | 6 +++--- - dlls/wined3d/wined3d_private.h | 10 ++++------ - 5 files changed, 38 insertions(+), 39 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index d5e2c52..b20d32f 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -639,10 +639,10 @@ static UINT wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const - || prev_surface->flags & SFLAG_DISCARD)) - { - surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height); -- if (prev_surface == device->onscreen_depth_stencil) -+ if (prev_surface == cs->onscreen_depth_stencil) - { -- wined3d_texture_decref(device->onscreen_depth_stencil->container); -- device->onscreen_depth_stencil = NULL; -+ wined3d_texture_decref(cs->onscreen_depth_stencil->container); -+ cs->onscreen_depth_stencil = NULL; - } - } - } -@@ -1480,6 +1480,22 @@ static void wined3d_cs_emit_stop(struct wined3d_cs *cs) - wined3d_cs_flush(cs); - } - -+void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, -+ struct wined3d_context *context, struct wined3d_surface *depth_stencil) -+{ -+ if (cs->onscreen_depth_stencil) -+ { -+ surface_load_ds_location(cs->onscreen_depth_stencil, context, WINED3D_LOCATION_TEXTURE_RGB); -+ -+ surface_modify_ds_location(cs->onscreen_depth_stencil, WINED3D_LOCATION_TEXTURE_RGB, -+ cs->onscreen_depth_stencil->ds_current_size.cx, -+ cs->onscreen_depth_stencil->ds_current_size.cy); -+ wined3d_texture_decref(cs->onscreen_depth_stencil->container); -+ } -+ cs->onscreen_depth_stencil = depth_stencil; -+ wined3d_texture_incref(cs->onscreen_depth_stencil->container); -+} -+ - static DWORD WINAPI wined3d_cs_run(void *thread_param) - { - struct wined3d_cs *cs = thread_param; -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 1fef5ff..4de7eb2 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -198,22 +198,6 @@ void device_context_remove(struct wined3d_device *device, struct wined3d_context - device->contexts = new_array; - } - --void device_switch_onscreen_ds(struct wined3d_device *device, -- struct wined3d_context *context, struct wined3d_surface *depth_stencil) --{ -- if (device->onscreen_depth_stencil) -- { -- surface_load_ds_location(device->onscreen_depth_stencil, context, WINED3D_LOCATION_TEXTURE_RGB); -- -- surface_modify_ds_location(device->onscreen_depth_stencil, WINED3D_LOCATION_TEXTURE_RGB, -- device->onscreen_depth_stencil->ds_current_size.cx, -- device->onscreen_depth_stencil->ds_current_size.cy); -- wined3d_texture_decref(device->onscreen_depth_stencil->container); -- } -- device->onscreen_depth_stencil = depth_stencil; -- wined3d_texture_incref(device->onscreen_depth_stencil->container); --} -- - static BOOL is_full_clear(const struct wined3d_surface *target, const RECT *draw_rect, const RECT *clear_rect) - { - /* partial draw rect */ -@@ -348,8 +332,8 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c - { - DWORD location = render_offscreen ? fb->depth_stencil->resource->draw_binding : WINED3D_LOCATION_DRAWABLE; - -- if (!render_offscreen && depth_stencil != device->onscreen_depth_stencil) -- device_switch_onscreen_ds(device, context, depth_stencil); -+ if (!render_offscreen && depth_stencil != device->cs->onscreen_depth_stencil) -+ wined3d_cs_switch_onscreen_ds(device->cs, context, depth_stencil); - prepare_ds_clear(depth_stencil, context, location, - draw_rect, rect_count, clear_rect, &ds_rect); - } -@@ -1064,11 +1048,12 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) - /* Release the buffers (with sanity checks). - * FIXME: Move this move into a separate patch. I think the idea - * behind this is that those surfaces should be freed before unloading -- * remaining resources below. */ -- if (device->onscreen_depth_stencil) -+ * remaining resources below. -+ * FIXME 2: Shouldn't the cs take care of onscreen_depth_stencil? */ -+ if (device->cs->onscreen_depth_stencil) - { -- surface = device->onscreen_depth_stencil; -- device->onscreen_depth_stencil = NULL; -+ surface = device->cs->onscreen_depth_stencil; -+ device->cs->onscreen_depth_stencil = NULL; - wined3d_texture_decref(surface->container); - } - -@@ -4561,10 +4546,10 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - state_unbind_resources(&device->state); - } - -- if (device->onscreen_depth_stencil) -+ if (device->cs->onscreen_depth_stencil) - { -- wined3d_texture_decref(device->onscreen_depth_stencil->container); -- device->onscreen_depth_stencil = NULL; -+ wined3d_texture_decref(device->cs->onscreen_depth_stencil->container); -+ device->cs->onscreen_depth_stencil = NULL; - } - - if (reset_state) -diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c -index 21ce53a..9ec380a 100644 ---- a/dlls/wined3d/drawprim.c -+++ b/dlls/wined3d/drawprim.c -@@ -651,8 +651,8 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s - { - RECT current_rect, draw_rect, r; - -- if (!context->render_offscreen && ds != device->onscreen_depth_stencil) -- device_switch_onscreen_ds(device, context, ds); -+ if (!context->render_offscreen && ds != device->cs->onscreen_depth_stencil) -+ wined3d_cs_switch_onscreen_ds(device->cs, context, ds); - - if (ds->resource.locations & location) - SetRect(¤t_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy); -diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c -index 6ded6cc..0a8da3d 100644 ---- a/dlls/wined3d/swapchain.c -+++ b/dlls/wined3d/swapchain.c -@@ -588,10 +588,10 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT - { - surface_modify_ds_location(depth_stencil, WINED3D_LOCATION_DISCARDED, - depth_stencil->resource.width, depth_stencil->resource.height); -- if (depth_stencil == swapchain->device->onscreen_depth_stencil) -+ if (depth_stencil == swapchain->device->cs->onscreen_depth_stencil) - { -- wined3d_texture_decref(swapchain->device->onscreen_depth_stencil->container); -- swapchain->device->onscreen_depth_stencil = NULL; -+ wined3d_texture_decref(swapchain->device->cs->onscreen_depth_stencil->container); -+ swapchain->device->cs->onscreen_depth_stencil = NULL; - } - } - } -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index dec58e5..035517f 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2116,15 +2116,12 @@ struct wined3d_device - struct wined3d_rendertarget_view *back_buffer_view; - struct wined3d_swapchain **swapchains; - UINT swapchain_count; -+ struct wined3d_rendertarget_view *auto_depth_stencil_view; - - struct list resources; /* a linked list to track resources created by the device */ - struct list shaders; /* a linked list to track shaders (pixel and vertex) */ - struct wine_rb_tree samplers; - -- /* Render Target Support */ -- struct wined3d_surface *onscreen_depth_stencil; -- struct wined3d_rendertarget_view *auto_depth_stencil_view; -- - /* For rendering to a texture using glCopyTexImage */ - GLuint depth_blt_texture; - -@@ -2166,8 +2163,6 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL - UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN; - void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; --void device_switch_onscreen_ds(struct wined3d_device *device, struct wined3d_context *context, -- struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; - void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; - - static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) -@@ -2667,6 +2662,7 @@ struct wined3d_cs - struct wined3d_state state; - HANDLE thread; - DWORD tls_idx; -+ struct wined3d_surface *onscreen_depth_stencil; - - size_t data_size; - void *data; -@@ -2677,6 +2673,8 @@ struct wined3d_cs - - struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; - void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN; -+void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, struct wined3d_context *context, -+ struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; - - void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, - DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0058-wined3d-Send-primitive-type-updates-through-the-comm.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0058-wined3d-Send-primitive-type-updates-through-the-comm.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0058-wined3d-Send-primitive-type-updates-through-the-comm.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0058-wined3d-Send-primitive-type-updates-through-the-comm.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,151 @@ +From 3f7a369ba516a2ebe970a5160293d190f806f65e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sun, 7 Apr 2013 17:53:43 +0200 +Subject: wined3d: Send primitive type updates through the command stream + +--- + dlls/wined3d/cs.c | 39 ++++++++++++++++++++++++++++++++++----- + dlls/wined3d/device.c | 5 ++--- + dlls/wined3d/stateblock.c | 4 ++-- + dlls/wined3d/wined3d_private.h | 2 ++ + 4 files changed, 40 insertions(+), 10 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index f385449..8a28c40 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -68,6 +68,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_SET_PS_CONSTS_F, + WINED3D_CS_OP_GLFINISH, + WINED3D_CS_OP_SET_BASE_VERTEX_INDEX, ++ WINED3D_CS_OP_SET_PRIMITIVE_TYPE, + WINED3D_CS_OP_STOP, + }; + +@@ -307,6 +308,12 @@ struct wined3d_cs_set_base_vertex_index + UINT base_vertex_index; + }; + ++struct wined3d_cs_set_primitive_type ++{ ++ enum wined3d_cs_op opcode; ++ GLenum gl_primitive_type; ++}; ++ + /* FIXME: The list synchronization probably isn't particularly fast. */ + static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) + { +@@ -977,9 +984,6 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi + + /* Don't memcpy the entire struct, we'll remove single items as we add dedicated + * ops for setting states */ +- +- cs->state.gl_primitive_type = op->state.gl_primitive_type; +- + memcpy(cs->state.vs_consts_b, op->state.vs_consts_b, sizeof(cs->state.vs_consts_b)); + memcpy(cs->state.vs_consts_i, op->state.vs_consts_i, sizeof(cs->state.vs_consts_i)); + +@@ -1000,8 +1004,6 @@ void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct win + + /* Don't memcpy the entire struct, we'll remove single items as we add dedicated + * ops for setting states */ +- op->state.gl_primitive_type = state->gl_primitive_type; +- + memcpy(op->state.vs_consts_b, state->vs_consts_b, sizeof(op->state.vs_consts_b)); + memcpy(op->state.vs_consts_i, state->vs_consts_i, sizeof(op->state.vs_consts_i)); + +@@ -1434,6 +1436,32 @@ void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, + cs->ops->submit(cs); + } + ++static UINT wined3d_cs_exec_set_primitive_type(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_primitive_type *op = data; ++ GLenum prev; ++ ++ prev = cs->state.gl_primitive_type; ++ ++ if (op->gl_primitive_type == GL_POINTS || prev == GL_POINTS) ++ device_invalidate_state(cs->device, STATE_POINT_ENABLE); ++ ++ cs->state.gl_primitive_type = op->gl_primitive_type; ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, GLenum primitive_type) ++{ ++ struct wined3d_cs_set_primitive_type *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_PRIMITIVE_TYPE; ++ op->gl_primitive_type = primitive_type; ++ ++ cs->ops->submit(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, +@@ -1468,6 +1496,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, + /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, + /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, ++ /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, + }; + + static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 939d525..49ec1dc 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -3377,7 +3377,6 @@ void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device, + enum wined3d_primitive_type primitive_type) + { + GLenum gl_primitive_type, prev; +- + TRACE("device %p, primitive_type %s\n", device, debug_d3dprimitivetype(primitive_type)); + + gl_primitive_type = gl_primitive_type_from_d3d(primitive_type); +@@ -3385,8 +3384,8 @@ void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device, + device->update_state->gl_primitive_type = gl_primitive_type; + if (device->recording) + device->recording->changed.primitive_type = TRUE; +- else if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS)) +- device_invalidate_state(device, STATE_POINT_ENABLE); ++ else if (gl_primitive_type != prev) ++ wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type); + } + + void CDECL wined3d_device_get_primitive_type(const struct wined3d_device *device, +diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c +index 790d769..cd07055 100644 +--- a/dlls/wined3d/stateblock.c ++++ b/dlls/wined3d/stateblock.c +@@ -1075,8 +1075,8 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) + gl_primitive_type = stateblock->state.gl_primitive_type; + prev = device->update_state->gl_primitive_type; + device->update_state->gl_primitive_type = gl_primitive_type; +- if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS)) +- device_invalidate_state(device, STATE_POINT_ENABLE); ++ if (gl_primitive_type != prev) ++ wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type); + } + + if (stateblock->changed.indices) +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 3d65d93..bae0336 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2675,6 +2675,8 @@ void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, co + void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, + UINT base_vertex_index) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, ++ GLenum primitive_type) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.4.2 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0059-wined3d-Send-base-vertex-index-updates-through-the-c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0059-wined3d-Send-base-vertex-index-updates-through-the-c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0059-wined3d-Send-base-vertex-index-updates-through-the-c.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0059-wined3d-Send-base-vertex-index-updates-through-the-c.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ -From 4b5e47ede0b1ac538b6439e8b1888e4da542ceee Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sun, 7 Apr 2013 17:33:20 +0200 -Subject: wined3d: Send base vertex index updates through the cs - ---- - dlls/wined3d/cs.c | 49 ++++++++++++++++++++++++++++++++++++++---- - dlls/wined3d/device.c | 17 +++------------ - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 50 insertions(+), 18 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 236e2f2..0525a59 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -66,6 +66,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_SET_VS_CONSTS_F, - WINED3D_CS_OP_SET_PS_CONSTS_F, - WINED3D_CS_OP_GLFINISH, -+ WINED3D_CS_OP_SET_BASE_VERTEX_INDEX, - WINED3D_CS_OP_STOP, - }; - -@@ -290,6 +291,12 @@ struct wined3d_cs_finish - enum wined3d_cs_op opcode; - }; - -+struct wined3d_cs_set_base_vertex_index -+{ -+ enum wined3d_cs_op opcode; -+ UINT base_vertex_index; -+}; -+ - /* FIXME: The list synchronization probably isn't particularly fast. */ - static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) - { -@@ -504,6 +511,21 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * - static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_draw *op = data; -+ const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info; -+ -+ if (op->indexed && !gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) -+ { -+ if (cs->state.load_base_vertex_index != cs->state.base_vertex_index) -+ { -+ cs->state.load_base_vertex_index = cs->state.base_vertex_index; -+ device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX); -+ } -+ } -+ else if (cs->state.load_base_vertex_index) -+ { -+ cs->state.load_base_vertex_index = 0; -+ device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX); -+ } - - draw_primitive(cs->device, &cs->state, op->start_idx, op->index_count, - op->start_instance, op->instance_count, op->indexed); -@@ -931,8 +953,6 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi - /* Don't memcpy the entire struct, we'll remove single items as we add dedicated - * ops for setting states */ - -- cs->state.base_vertex_index = op->state.base_vertex_index; -- cs->state.load_base_vertex_index = op->state.load_base_vertex_index; - cs->state.gl_primitive_type = op->state.gl_primitive_type; - - memcpy(cs->state.vs_consts_b, op->state.vs_consts_b, sizeof(cs->state.vs_consts_b)); -@@ -955,8 +975,6 @@ void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct win - - /* Don't memcpy the entire struct, we'll remove single items as we add dedicated - * ops for setting states */ -- op->state.base_vertex_index = state->base_vertex_index; -- op->state.load_base_vertex_index = state->load_base_vertex_index; - op->state.gl_primitive_type = state->gl_primitive_type; - - memcpy(op->state.vs_consts_b, state->vs_consts_b, sizeof(op->state.vs_consts_b)); -@@ -1281,6 +1299,28 @@ void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) - cs->ops->submit(cs); - } - -+static UINT wined3d_cs_exec_set_base_vertex_index(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_base_vertex_index *op = data; -+ -+ cs->state.base_vertex_index = op->base_vertex_index; -+ device_invalidate_state(cs->device, STATE_BASEVERTEXINDEX); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, -+ UINT base_vertex_index) -+{ -+ struct wined3d_cs_set_base_vertex_index *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_BASE_VERTEX_INDEX; -+ op->base_vertex_index = base_vertex_index; -+ -+ cs->ops->submit(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, -@@ -1313,6 +1353,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, - /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, - /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, -+ /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, - }; - - static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index dfc0619..a80784b 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -1830,6 +1830,9 @@ void CDECL wined3d_device_set_base_vertex_index(struct wined3d_device *device, I - TRACE("device %p, base_index %d.\n", device, base_index); - - device->update_state->base_vertex_index = base_index; -+ -+ if (!device->recording) -+ wined3d_cs_emit_set_base_vertex_index(device->cs, base_index); - } - - INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *device) -@@ -3377,12 +3380,6 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT - return WINED3DERR_INVALIDCALL; - } - -- if (device->state.load_base_vertex_index) -- { -- device->state.load_base_vertex_index = 0; -- device_invalidate_state(device, STATE_BASEVERTEXINDEX); -- } -- - wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); - wined3d_cs_emit_draw(device->cs, start_vertex, vertex_count, 0, 0, FALSE); - -@@ -3391,8 +3388,6 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT - - HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count) - { -- const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -- - TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count); - - if (!device->state.index_buffer) -@@ -3411,12 +3406,6 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic - return WINED3DERR_INVALIDCALL; - } - -- if (!gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] && -- device->state.load_base_vertex_index != device->state.base_vertex_index) -- { -- device->state.load_base_vertex_index = device->state.base_vertex_index; -- device_invalidate_state(device, STATE_BASEVERTEXINDEX); -- } - - wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); - wined3d_cs_emit_draw(device->cs, start_idx, index_count, 0, 0, TRUE); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index e4dbd9d..382c120 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2616,6 +2616,8 @@ void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_vi - void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, - UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; - void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, -+ UINT base_vertex_index) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0059-wined3d-Send-bool-constant-updates-through-the-comma.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0059-wined3d-Send-bool-constant-updates-through-the-comma.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0059-wined3d-Send-bool-constant-updates-through-the-comma.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0059-wined3d-Send-bool-constant-updates-through-the-comma.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,192 @@ +From 870ae689d58feb0e2c28603ab7a5c202dc1bf6c2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 9 Apr 2013 21:50:30 +0200 +Subject: wined3d: Send bool constant updates through the command stream + +--- + dlls/wined3d/cs.c | 72 +++++++++++++++++++++++++++++++++++++++--- + dlls/wined3d/device.c | 8 +++-- + dlls/wined3d/wined3d_private.h | 3 ++ + 3 files changed, 76 insertions(+), 7 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index a7ba2b4..9d8491a 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -64,7 +64,9 @@ enum wined3d_cs_op + WINED3D_CS_OP_RESET_STATE, + WINED3D_CS_OP_STATEBLOCK, + WINED3D_CS_OP_SET_VS_CONSTS_F, ++ WINED3D_CS_OP_SET_VS_CONSTS_B, + WINED3D_CS_OP_SET_PS_CONSTS_F, ++ WINED3D_CS_OP_SET_PS_CONSTS_B, + WINED3D_CS_OP_GLFINISH, + WINED3D_CS_OP_SET_BASE_VERTEX_INDEX, + WINED3D_CS_OP_SET_PRIMITIVE_TYPE, +@@ -287,6 +289,13 @@ struct wined3d_cs_set_consts_f + float constants[4]; + }; + ++struct wined3d_cs_set_consts_b ++{ ++ enum wined3d_cs_op opcode; ++ UINT start_register, bool_count; ++ BOOL constants[1]; ++}; ++ + struct wined3d_cs_finish + { + enum wined3d_cs_op opcode; +@@ -959,10 +968,8 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi + + /* Don't memcpy the entire struct, we'll remove single items as we add dedicated + * ops for setting states */ +- memcpy(cs->state.vs_consts_b, op->state.vs_consts_b, sizeof(cs->state.vs_consts_b)); + memcpy(cs->state.vs_consts_i, op->state.vs_consts_i, sizeof(cs->state.vs_consts_i)); + +- memcpy(cs->state.ps_consts_b, op->state.ps_consts_b, sizeof(cs->state.ps_consts_b)); + memcpy(cs->state.ps_consts_i, op->state.ps_consts_i, sizeof(cs->state.ps_consts_i)); + + memcpy(cs->state.lights, op->state.lights, sizeof(cs->state.lights)); +@@ -979,10 +986,8 @@ void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct win + + /* Don't memcpy the entire struct, we'll remove single items as we add dedicated + * ops for setting states */ +- memcpy(op->state.vs_consts_b, state->vs_consts_b, sizeof(op->state.vs_consts_b)); + memcpy(op->state.vs_consts_i, state->vs_consts_i, sizeof(op->state.vs_consts_i)); + +- memcpy(op->state.ps_consts_b, state->ps_consts_b, sizeof(op->state.ps_consts_b)); + memcpy(op->state.ps_consts_i, state->ps_consts_i, sizeof(op->state.ps_consts_i)); + + /* FIXME: This is not ideal. CS is still running synchronously, so this is ok. +@@ -1137,6 +1142,63 @@ void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render + op->value = value; + + cs->ops->submit(cs); ++}; ++ ++static UINT wined3d_cs_exec_set_vs_consts_b(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_consts_b *op = data; ++ struct wined3d_device *device = cs->device; ++ ++ memcpy(&cs->state.vs_consts_b[op->start_register], op->constants, ++ sizeof(*cs->state.vs_consts_b) * op->bool_count); ++ ++ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_B); ++ ++ return sizeof(*op) + sizeof(op->constants) * (op->bool_count - 1); ++} ++ ++static UINT wined3d_cs_exec_set_ps_consts_b(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_consts_b *op = data; ++ struct wined3d_device *device = cs->device; ++ ++ memcpy(&cs->state.ps_consts_b[op->start_register], op->constants, ++ sizeof(*cs->state.ps_consts_b) * op->bool_count); ++ ++ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_B); ++ ++ return sizeof(*op) + sizeof(op->constants) * (op->bool_count - 1); ++} ++ ++void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, ++ const BOOL *constants, UINT bool_count, enum wined3d_shader_type type) ++{ ++ struct wined3d_cs_set_consts_b *op; ++ UINT extra_space = bool_count - 1; ++ ++ op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); ++ switch (type) ++ { ++ case WINED3D_SHADER_TYPE_PIXEL: ++ op->opcode = WINED3D_CS_OP_SET_PS_CONSTS_B; ++ break; ++ ++ case WINED3D_SHADER_TYPE_VERTEX: ++ op->opcode = WINED3D_CS_OP_SET_VS_CONSTS_B; ++ break; ++ ++ case WINED3D_SHADER_TYPE_GEOMETRY: ++ FIXME("Invalid for geometry shaders\n"); ++ return; ++ ++ case WINED3D_SHADER_TYPE_COUNT: ++ break; ++ } ++ op->start_register = start_register; ++ op->bool_count = bool_count; ++ memcpy(op->constants, constants, sizeof(op->constants) * bool_count); ++ ++ cs->ops->submit(cs); + } + + static UINT wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) +@@ -1379,7 +1441,9 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, + /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, + /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, ++ /* WINED3D_CS_OP_SET_VS_CONSTS_B */ wined3d_cs_exec_set_vs_consts_b, + /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, ++ /* WINED3D_CS_OP_SET_PS_CONSTS_B */ wined3d_cs_exec_set_ps_consts_b, + /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, + /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, + /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index e87a52c..14d3080 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -2197,7 +2197,7 @@ struct wined3d_sampler * CDECL wined3d_device_get_vs_sampler(const struct wined3 + return device->state.sampler[WINED3D_SHADER_TYPE_VERTEX][idx]; + } + +-static void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) ++void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) + { + UINT i; + +@@ -2230,7 +2230,8 @@ HRESULT CDECL wined3d_device_set_vs_consts_b(struct wined3d_device *device, + } + else + { +- device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_B); ++ wined3d_cs_emit_set_consts_b(device->cs, start_register, constants, ++ bool_count, WINED3D_SHADER_TYPE_VERTEX); + } + + return WINED3D_OK; +@@ -2464,7 +2465,8 @@ HRESULT CDECL wined3d_device_set_ps_consts_b(struct wined3d_device *device, + } + else + { +- device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_B); ++ wined3d_cs_emit_set_consts_b(device->cs, start_register, constants, ++ bool_count, WINED3D_SHADER_TYPE_PIXEL); + } + + return WINED3D_OK; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index a647ca9..4ecb626 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2058,6 +2058,7 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL + void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; ++void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) DECLSPEC_HIDDEN; + + static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) + { +@@ -2615,6 +2616,8 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, + void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, + UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, ++ const BOOL *constants, UINT bool_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; + void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, + UINT base_vertex_index) DECLSPEC_HIDDEN; +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0060-wined3d-Send-int-constant-updates-through-the-comman.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0060-wined3d-Send-int-constant-updates-through-the-comman.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0060-wined3d-Send-int-constant-updates-through-the-comman.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0060-wined3d-Send-int-constant-updates-through-the-comman.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,175 @@ +From 68141ab2e84252e99bcf6801a5bcc629b1494665 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 10 Apr 2013 14:20:47 +0200 +Subject: wined3d: Send int constant updates through the command stream + +--- + dlls/wined3d/cs.c | 74 ++++++++++++++++++++++++++++++++++++++---- + dlls/wined3d/device.c | 6 ++-- + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 74 insertions(+), 8 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 9d8491a..cf3a523 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -65,8 +65,10 @@ enum wined3d_cs_op + WINED3D_CS_OP_STATEBLOCK, + WINED3D_CS_OP_SET_VS_CONSTS_F, + WINED3D_CS_OP_SET_VS_CONSTS_B, ++ WINED3D_CS_OP_SET_VS_CONSTS_I, + WINED3D_CS_OP_SET_PS_CONSTS_F, + WINED3D_CS_OP_SET_PS_CONSTS_B, ++ WINED3D_CS_OP_SET_PS_CONSTS_I, + WINED3D_CS_OP_GLFINISH, + WINED3D_CS_OP_SET_BASE_VERTEX_INDEX, + WINED3D_CS_OP_SET_PRIMITIVE_TYPE, +@@ -296,6 +298,13 @@ struct wined3d_cs_set_consts_b + BOOL constants[1]; + }; + ++struct wined3d_cs_set_consts_i ++{ ++ enum wined3d_cs_op opcode; ++ UINT start_register, vector4i_count; ++ int constants[4]; ++}; ++ + struct wined3d_cs_finish + { + enum wined3d_cs_op opcode; +@@ -968,9 +977,6 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi + + /* Don't memcpy the entire struct, we'll remove single items as we add dedicated + * ops for setting states */ +- memcpy(cs->state.vs_consts_i, op->state.vs_consts_i, sizeof(cs->state.vs_consts_i)); +- +- memcpy(cs->state.ps_consts_i, op->state.ps_consts_i, sizeof(cs->state.ps_consts_i)); + + memcpy(cs->state.lights, op->state.lights, sizeof(cs->state.lights)); + +@@ -986,9 +992,6 @@ void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct win + + /* Don't memcpy the entire struct, we'll remove single items as we add dedicated + * ops for setting states */ +- memcpy(op->state.vs_consts_i, state->vs_consts_i, sizeof(op->state.vs_consts_i)); +- +- memcpy(op->state.ps_consts_i, state->ps_consts_i, sizeof(op->state.ps_consts_i)); + + /* FIXME: This is not ideal. CS is still running synchronously, so this is ok. + * It will go away soon anyway. */ +@@ -1201,6 +1204,63 @@ void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, + cs->ops->submit(cs); + } + ++static UINT wined3d_cs_exec_set_vs_consts_i(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_consts_i *op = data; ++ struct wined3d_device *device = cs->device; ++ ++ memcpy(&cs->state.vs_consts_i[op->start_register * 4], op->constants, ++ sizeof(*cs->state.vs_consts_i) * 4 * op->vector4i_count); ++ ++ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_I); ++ ++ return sizeof(*op) + sizeof(op->constants) * (op->vector4i_count - 1); ++} ++ ++static UINT wined3d_cs_exec_set_ps_consts_i(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_consts_i *op = data; ++ struct wined3d_device *device = cs->device; ++ ++ memcpy(&cs->state.ps_consts_i[op->start_register * 4], op->constants, ++ sizeof(*cs->state.ps_consts_i) * 4 * op->vector4i_count); ++ ++ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_I); ++ ++ return sizeof(*op) + sizeof(op->constants) * (op->vector4i_count - 1); ++} ++ ++void wined3d_cs_emit_set_consts_i(struct wined3d_cs *cs, UINT start_register, ++ const int *constants, UINT vector4i_count, enum wined3d_shader_type type) ++{ ++ struct wined3d_cs_set_consts_i *op; ++ UINT extra_space = vector4i_count - 1; ++ ++ op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); ++ switch (type) ++ { ++ case WINED3D_SHADER_TYPE_PIXEL: ++ op->opcode = WINED3D_CS_OP_SET_PS_CONSTS_I; ++ break; ++ ++ case WINED3D_SHADER_TYPE_VERTEX: ++ op->opcode = WINED3D_CS_OP_SET_VS_CONSTS_I; ++ break; ++ ++ case WINED3D_SHADER_TYPE_GEOMETRY: ++ ERR("Invalid for geometry shaders\n"); ++ return; ++ ++ case WINED3D_SHADER_TYPE_COUNT: ++ break; ++ } ++ op->start_register = start_register; ++ op->vector4i_count = vector4i_count; ++ memcpy(op->constants, constants, sizeof(op->constants) * vector4i_count); ++ ++ cs->ops->submit(cs); ++} ++ + static UINT wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_texture_state *op = data; +@@ -1442,8 +1502,10 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, + /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, + /* WINED3D_CS_OP_SET_VS_CONSTS_B */ wined3d_cs_exec_set_vs_consts_b, ++ /* WINED3D_CS_OP_SET_VS_CONSTS_I */ wined3d_cs_exec_set_vs_consts_i, + /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, + /* WINED3D_CS_OP_SET_PS_CONSTS_B */ wined3d_cs_exec_set_ps_consts_b, ++ /* WINED3D_CS_OP_SET_PS_CONSTS_I */ wined3d_cs_exec_set_ps_consts_i, + /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, + /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, + /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 14d3080..9ba40df 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -2278,7 +2278,8 @@ HRESULT CDECL wined3d_device_set_vs_consts_i(struct wined3d_device *device, + } + else + { +- device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_I); ++ wined3d_cs_emit_set_consts_i(device->cs, start_register, constants, ++ vector4i_count, WINED3D_SHADER_TYPE_VERTEX); + } + + return WINED3D_OK; +@@ -2513,7 +2514,8 @@ HRESULT CDECL wined3d_device_set_ps_consts_i(struct wined3d_device *device, + } + else + { +- device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_I); ++ wined3d_cs_emit_set_consts_i(device->cs, start_register, constants, ++ vector4i_count, WINED3D_SHADER_TYPE_PIXEL); + } + + return WINED3D_OK; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 4ecb626..59149bd 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2618,6 +2618,8 @@ void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, co + UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, + const BOOL *constants, UINT bool_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_set_consts_i(struct wined3d_cs *cs, UINT start_register, ++ const int *constants, UINT vector4i_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; + void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, + UINT base_vertex_index) DECLSPEC_HIDDEN; +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0060-wined3d-Send-primitive-type-updates-through-the-comm.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0060-wined3d-Send-primitive-type-updates-through-the-comm.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0060-wined3d-Send-primitive-type-updates-through-the-comm.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0060-wined3d-Send-primitive-type-updates-through-the-comm.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,151 +0,0 @@ -From 3f7a369ba516a2ebe970a5160293d190f806f65e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sun, 7 Apr 2013 17:53:43 +0200 -Subject: wined3d: Send primitive type updates through the command stream - ---- - dlls/wined3d/cs.c | 39 ++++++++++++++++++++++++++++++++++----- - dlls/wined3d/device.c | 5 ++--- - dlls/wined3d/stateblock.c | 4 ++-- - dlls/wined3d/wined3d_private.h | 2 ++ - 4 files changed, 40 insertions(+), 10 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index f385449..8a28c40 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -68,6 +68,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_SET_PS_CONSTS_F, - WINED3D_CS_OP_GLFINISH, - WINED3D_CS_OP_SET_BASE_VERTEX_INDEX, -+ WINED3D_CS_OP_SET_PRIMITIVE_TYPE, - WINED3D_CS_OP_STOP, - }; - -@@ -307,6 +308,12 @@ struct wined3d_cs_set_base_vertex_index - UINT base_vertex_index; - }; - -+struct wined3d_cs_set_primitive_type -+{ -+ enum wined3d_cs_op opcode; -+ GLenum gl_primitive_type; -+}; -+ - /* FIXME: The list synchronization probably isn't particularly fast. */ - static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) - { -@@ -977,9 +984,6 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi - - /* Don't memcpy the entire struct, we'll remove single items as we add dedicated - * ops for setting states */ -- -- cs->state.gl_primitive_type = op->state.gl_primitive_type; -- - memcpy(cs->state.vs_consts_b, op->state.vs_consts_b, sizeof(cs->state.vs_consts_b)); - memcpy(cs->state.vs_consts_i, op->state.vs_consts_i, sizeof(cs->state.vs_consts_i)); - -@@ -1000,8 +1004,6 @@ void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct win - - /* Don't memcpy the entire struct, we'll remove single items as we add dedicated - * ops for setting states */ -- op->state.gl_primitive_type = state->gl_primitive_type; -- - memcpy(op->state.vs_consts_b, state->vs_consts_b, sizeof(op->state.vs_consts_b)); - memcpy(op->state.vs_consts_i, state->vs_consts_i, sizeof(op->state.vs_consts_i)); - -@@ -1434,6 +1436,32 @@ void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, - cs->ops->submit(cs); - } - -+static UINT wined3d_cs_exec_set_primitive_type(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_primitive_type *op = data; -+ GLenum prev; -+ -+ prev = cs->state.gl_primitive_type; -+ -+ if (op->gl_primitive_type == GL_POINTS || prev == GL_POINTS) -+ device_invalidate_state(cs->device, STATE_POINT_ENABLE); -+ -+ cs->state.gl_primitive_type = op->gl_primitive_type; -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, GLenum primitive_type) -+{ -+ struct wined3d_cs_set_primitive_type *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_PRIMITIVE_TYPE; -+ op->gl_primitive_type = primitive_type; -+ -+ cs->ops->submit(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, -@@ -1468,6 +1496,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, - /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, - /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, -+ /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, - }; - - static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 939d525..49ec1dc 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -3377,7 +3377,6 @@ void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device, - enum wined3d_primitive_type primitive_type) - { - GLenum gl_primitive_type, prev; -- - TRACE("device %p, primitive_type %s\n", device, debug_d3dprimitivetype(primitive_type)); - - gl_primitive_type = gl_primitive_type_from_d3d(primitive_type); -@@ -3385,8 +3384,8 @@ void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device, - device->update_state->gl_primitive_type = gl_primitive_type; - if (device->recording) - device->recording->changed.primitive_type = TRUE; -- else if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS)) -- device_invalidate_state(device, STATE_POINT_ENABLE); -+ else if (gl_primitive_type != prev) -+ wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type); - } - - void CDECL wined3d_device_get_primitive_type(const struct wined3d_device *device, -diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c -index 790d769..cd07055 100644 ---- a/dlls/wined3d/stateblock.c -+++ b/dlls/wined3d/stateblock.c -@@ -1075,8 +1075,8 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) - gl_primitive_type = stateblock->state.gl_primitive_type; - prev = device->update_state->gl_primitive_type; - device->update_state->gl_primitive_type = gl_primitive_type; -- if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS)) -- device_invalidate_state(device, STATE_POINT_ENABLE); -+ if (gl_primitive_type != prev) -+ wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type); - } - - if (stateblock->changed.indices) -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 3d65d93..bae0336 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2675,6 +2675,8 @@ void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, co - void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, - UINT base_vertex_index) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, -+ GLenum primitive_type) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.4.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0061-wined3d-Send-bool-constant-updates-through-the-comma.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0061-wined3d-Send-bool-constant-updates-through-the-comma.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0061-wined3d-Send-bool-constant-updates-through-the-comma.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0061-wined3d-Send-bool-constant-updates-through-the-comma.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,192 +0,0 @@ -From 870ae689d58feb0e2c28603ab7a5c202dc1bf6c2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 9 Apr 2013 21:50:30 +0200 -Subject: wined3d: Send bool constant updates through the command stream - ---- - dlls/wined3d/cs.c | 72 +++++++++++++++++++++++++++++++++++++++--- - dlls/wined3d/device.c | 8 +++-- - dlls/wined3d/wined3d_private.h | 3 ++ - 3 files changed, 76 insertions(+), 7 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index a7ba2b4..9d8491a 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -64,7 +64,9 @@ enum wined3d_cs_op - WINED3D_CS_OP_RESET_STATE, - WINED3D_CS_OP_STATEBLOCK, - WINED3D_CS_OP_SET_VS_CONSTS_F, -+ WINED3D_CS_OP_SET_VS_CONSTS_B, - WINED3D_CS_OP_SET_PS_CONSTS_F, -+ WINED3D_CS_OP_SET_PS_CONSTS_B, - WINED3D_CS_OP_GLFINISH, - WINED3D_CS_OP_SET_BASE_VERTEX_INDEX, - WINED3D_CS_OP_SET_PRIMITIVE_TYPE, -@@ -287,6 +289,13 @@ struct wined3d_cs_set_consts_f - float constants[4]; - }; - -+struct wined3d_cs_set_consts_b -+{ -+ enum wined3d_cs_op opcode; -+ UINT start_register, bool_count; -+ BOOL constants[1]; -+}; -+ - struct wined3d_cs_finish - { - enum wined3d_cs_op opcode; -@@ -959,10 +968,8 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi - - /* Don't memcpy the entire struct, we'll remove single items as we add dedicated - * ops for setting states */ -- memcpy(cs->state.vs_consts_b, op->state.vs_consts_b, sizeof(cs->state.vs_consts_b)); - memcpy(cs->state.vs_consts_i, op->state.vs_consts_i, sizeof(cs->state.vs_consts_i)); - -- memcpy(cs->state.ps_consts_b, op->state.ps_consts_b, sizeof(cs->state.ps_consts_b)); - memcpy(cs->state.ps_consts_i, op->state.ps_consts_i, sizeof(cs->state.ps_consts_i)); - - memcpy(cs->state.lights, op->state.lights, sizeof(cs->state.lights)); -@@ -979,10 +986,8 @@ void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct win - - /* Don't memcpy the entire struct, we'll remove single items as we add dedicated - * ops for setting states */ -- memcpy(op->state.vs_consts_b, state->vs_consts_b, sizeof(op->state.vs_consts_b)); - memcpy(op->state.vs_consts_i, state->vs_consts_i, sizeof(op->state.vs_consts_i)); - -- memcpy(op->state.ps_consts_b, state->ps_consts_b, sizeof(op->state.ps_consts_b)); - memcpy(op->state.ps_consts_i, state->ps_consts_i, sizeof(op->state.ps_consts_i)); - - /* FIXME: This is not ideal. CS is still running synchronously, so this is ok. -@@ -1137,6 +1142,63 @@ void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render - op->value = value; - - cs->ops->submit(cs); -+}; -+ -+static UINT wined3d_cs_exec_set_vs_consts_b(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_consts_b *op = data; -+ struct wined3d_device *device = cs->device; -+ -+ memcpy(&cs->state.vs_consts_b[op->start_register], op->constants, -+ sizeof(*cs->state.vs_consts_b) * op->bool_count); -+ -+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_B); -+ -+ return sizeof(*op) + sizeof(op->constants) * (op->bool_count - 1); -+} -+ -+static UINT wined3d_cs_exec_set_ps_consts_b(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_consts_b *op = data; -+ struct wined3d_device *device = cs->device; -+ -+ memcpy(&cs->state.ps_consts_b[op->start_register], op->constants, -+ sizeof(*cs->state.ps_consts_b) * op->bool_count); -+ -+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_B); -+ -+ return sizeof(*op) + sizeof(op->constants) * (op->bool_count - 1); -+} -+ -+void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, -+ const BOOL *constants, UINT bool_count, enum wined3d_shader_type type) -+{ -+ struct wined3d_cs_set_consts_b *op; -+ UINT extra_space = bool_count - 1; -+ -+ op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); -+ switch (type) -+ { -+ case WINED3D_SHADER_TYPE_PIXEL: -+ op->opcode = WINED3D_CS_OP_SET_PS_CONSTS_B; -+ break; -+ -+ case WINED3D_SHADER_TYPE_VERTEX: -+ op->opcode = WINED3D_CS_OP_SET_VS_CONSTS_B; -+ break; -+ -+ case WINED3D_SHADER_TYPE_GEOMETRY: -+ FIXME("Invalid for geometry shaders\n"); -+ return; -+ -+ case WINED3D_SHADER_TYPE_COUNT: -+ break; -+ } -+ op->start_register = start_register; -+ op->bool_count = bool_count; -+ memcpy(op->constants, constants, sizeof(op->constants) * bool_count); -+ -+ cs->ops->submit(cs); - } - - static UINT wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) -@@ -1379,7 +1441,9 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, - /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, - /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, -+ /* WINED3D_CS_OP_SET_VS_CONSTS_B */ wined3d_cs_exec_set_vs_consts_b, - /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, -+ /* WINED3D_CS_OP_SET_PS_CONSTS_B */ wined3d_cs_exec_set_ps_consts_b, - /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, - /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, - /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index e87a52c..14d3080 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -2197,7 +2197,7 @@ struct wined3d_sampler * CDECL wined3d_device_get_vs_sampler(const struct wined3 - return device->state.sampler[WINED3D_SHADER_TYPE_VERTEX][idx]; - } - --static void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) -+void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) - { - UINT i; - -@@ -2230,7 +2230,8 @@ HRESULT CDECL wined3d_device_set_vs_consts_b(struct wined3d_device *device, - } - else - { -- device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_B); -+ wined3d_cs_emit_set_consts_b(device->cs, start_register, constants, -+ bool_count, WINED3D_SHADER_TYPE_VERTEX); - } - - return WINED3D_OK; -@@ -2464,7 +2465,8 @@ HRESULT CDECL wined3d_device_set_ps_consts_b(struct wined3d_device *device, - } - else - { -- device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_B); -+ wined3d_cs_emit_set_consts_b(device->cs, start_register, constants, -+ bool_count, WINED3D_SHADER_TYPE_PIXEL); - } - - return WINED3D_OK; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index a647ca9..4ecb626 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2058,6 +2058,7 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL - void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; -+void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) DECLSPEC_HIDDEN; - - static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) - { -@@ -2615,6 +2616,8 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, - void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, - UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, -+ const BOOL *constants, UINT bool_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; - void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, - UINT base_vertex_index) DECLSPEC_HIDDEN; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0061-wined3d-Send-light-updates-through-the-command-strea.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0061-wined3d-Send-light-updates-through-the-command-strea.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0061-wined3d-Send-light-updates-through-the-command-strea.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0061-wined3d-Send-light-updates-through-the-command-strea.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,394 @@ +From 4e5db60def2e093e529a2f7b8c5c0c081fd48723 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 10 Apr 2013 17:16:02 +0200 +Subject: wined3d: Send light updates through the command stream + +--- + dlls/wined3d/cs.c | 200 +++++++++++++++++++++++++++++++++-------- + dlls/wined3d/device.c | 31 ++----- + dlls/wined3d/wined3d_private.h | 8 +- + 3 files changed, 174 insertions(+), 65 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 434ce9a..562323e 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -63,7 +63,6 @@ enum wined3d_cs_op + WINED3D_CS_OP_SET_COLOR_KEY, + WINED3D_CS_OP_SET_MATERIAL, + WINED3D_CS_OP_RESET_STATE, +- WINED3D_CS_OP_STATEBLOCK, + WINED3D_CS_OP_SET_VS_CONSTS_F, + WINED3D_CS_OP_SET_VS_CONSTS_B, + WINED3D_CS_OP_SET_VS_CONSTS_I, +@@ -73,6 +72,8 @@ enum wined3d_cs_op + WINED3D_CS_OP_GLFINISH, + WINED3D_CS_OP_SET_BASE_VERTEX_INDEX, + WINED3D_CS_OP_SET_PRIMITIVE_TYPE, ++ WINED3D_CS_OP_SET_LIGHT, ++ WINED3D_CS_OP_SET_LIGHT_ENABLE, + WINED3D_CS_OP_STOP, + }; + +@@ -288,12 +289,6 @@ struct wined3d_cs_reset_state + enum wined3d_cs_op opcode; + }; + +-struct wined3d_cs_stateblock +-{ +- enum wined3d_cs_op opcode; +- struct wined3d_state state; +-}; +- + struct wined3d_cs_set_consts_f + { + enum wined3d_cs_op opcode; +@@ -332,6 +327,19 @@ struct wined3d_cs_set_primitive_type + GLenum gl_primitive_type; + }; + ++struct wined3d_cs_set_light ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_light_info light; ++}; ++ ++struct wined3d_cs_set_light_enable ++{ ++ enum wined3d_cs_op opcode; ++ UINT idx; ++ BOOL enable; ++}; ++ + /* FIXME: The list synchronization probably isn't particularly fast. */ + static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) + { +@@ -997,35 +1005,6 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined + cs->ops->submit(cs); + } + +-static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const void *data) +-{ +- const struct wined3d_cs_stateblock *op = data; +- +- /* Don't memcpy the entire struct, we'll remove single items as we add dedicated +- * ops for setting states */ +- +- memcpy(cs->state.lights, op->state.lights, sizeof(cs->state.lights)); +- +- return sizeof(*op); +-} +- +-void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct wined3d_state *state) +-{ +- struct wined3d_cs_stateblock *op; +- +- op = cs->ops->require_space(cs, sizeof(*op)); +- op->opcode = WINED3D_CS_OP_STATEBLOCK; +- +- /* Don't memcpy the entire struct, we'll remove single items as we add dedicated +- * ops for setting states */ +- +- /* FIXME: This is not ideal. CS is still running synchronously, so this is ok. +- * It will go away soon anyway. */ +- memcpy(op->state.lights, state->lights, sizeof(op->state.lights)); +- +- cs->ops->submit(cs); +-} +- + static UINT wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_set_shader_resource_view *op = data; +@@ -1585,6 +1564,152 @@ void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, GLenum primitive_ + cs->ops->submit(cs); + } + ++static UINT wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_light *op = data; ++ ++ UINT light_idx = op->light.OriginalIndex; ++ UINT hash_idx = LIGHTMAP_HASHFUNC(op->light.OriginalIndex); ++ struct wined3d_light_info *object = NULL; ++ struct list *e; ++ ++ LIST_FOR_EACH(e, &cs->state.light_map[hash_idx]) ++ { ++ object = LIST_ENTRY(e, struct wined3d_light_info, entry); ++ if (object->OriginalIndex == light_idx) ++ break; ++ object = NULL; ++ } ++ ++ if (!object) ++ { ++ TRACE("Adding new light\n"); ++ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); ++ if (!object) ++ return E_OUTOFMEMORY; ++ ++ list_add_head(&cs->state.light_map[hash_idx], &object->entry); ++ object->glIndex = -1; ++ object->OriginalIndex = light_idx; ++ } ++ ++ /* Update the live definitions if the light is currently assigned a glIndex. */ ++ if (object->glIndex != -1) ++ { ++ if (object->OriginalParms.type != op->light.OriginalParms.type) ++ device_invalidate_state(cs->device, STATE_LIGHT_TYPE); ++ device_invalidate_state(cs->device, STATE_ACTIVELIGHT(object->glIndex)); ++ } ++ ++ object->OriginalParms = op->light.OriginalParms; ++ object->position = op->light.position; ++ object->direction = op->light.direction; ++ object->exponent = op->light.exponent; ++ object->cutoff = op->light.cutoff; ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) ++{ ++ struct wined3d_cs_set_light *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_LIGHT; ++ op->light = *light; ++ ++ cs->ops->submit(cs); ++} ++ ++static UINT wined3d_cs_exec_set_light_enable(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_light_enable *op = data; ++ UINT hash_idx = LIGHTMAP_HASHFUNC(op->idx); ++ struct wined3d_light_info *light_info = NULL; ++ struct list *e; ++ struct wined3d_device *device = cs->device; ++ ++ LIST_FOR_EACH(e, &cs->state.light_map[hash_idx]) ++ { ++ light_info = LIST_ENTRY(e, struct wined3d_light_info, entry); ++ if (light_info->OriginalIndex == op->idx) ++ break; ++ light_info = NULL; ++ } ++ TRACE("Found light %p.\n", light_info); ++ ++ /* Should be handled by the device by emitting a set_light op */ ++ if (!light_info) ++ { ++ ERR("Light enabled requested but light not defined in cs state!\n"); ++ return sizeof(*op); ++ } ++ ++ if (!op->enable) ++ { ++ if (light_info->glIndex != -1) ++ { ++ device_invalidate_state(device, STATE_LIGHT_TYPE); ++ device_invalidate_state(device, STATE_ACTIVELIGHT(light_info->glIndex)); ++ cs->state.lights[light_info->glIndex] = NULL; ++ light_info->glIndex = -1; ++ } ++ else ++ { ++ TRACE("Light already disabled, nothing to do\n"); ++ } ++ light_info->enabled = FALSE; ++ } ++ else ++ { ++ light_info->enabled = TRUE; ++ if (light_info->glIndex != -1) ++ { ++ TRACE("Nothing to do as light was enabled\n"); ++ } ++ else ++ { ++ unsigned int i; ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++ /* Find a free GL light. */ ++ for (i = 0; i < gl_info->limits.lights; ++i) ++ { ++ if (!cs->state.lights[i]) ++ { ++ cs->state.lights[i] = light_info; ++ light_info->glIndex = i; ++ break; ++ } ++ } ++ if (light_info->glIndex == -1) ++ { ++ /* Should be caught by the device before emitting ++ * the light_enable op */ ++ ERR("Too many concurrently active lights in cs\n"); ++ return sizeof(*op); ++ } ++ ++ /* i == light_info->glIndex */ ++ device_invalidate_state(device, STATE_LIGHT_TYPE); ++ device_invalidate_state(device, STATE_ACTIVELIGHT(i)); ++ } ++ } ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enable) ++{ ++ struct wined3d_cs_set_light_enable *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_LIGHT_ENABLE; ++ op->idx = idx; ++ op->enable = enable; ++ ++ cs->ops->submit(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, +@@ -1614,7 +1739,6 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, + /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, + /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, +- /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, + /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, + /* WINED3D_CS_OP_SET_VS_CONSTS_B */ wined3d_cs_exec_set_vs_consts_b, + /* WINED3D_CS_OP_SET_VS_CONSTS_I */ wined3d_cs_exec_set_vs_consts_i, +@@ -1624,6 +1748,8 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, + /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, + /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, ++ /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, ++ /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, + }; + + static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index d2ce327..74bff19 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -1469,14 +1469,6 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, + TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", + light->range, light->falloff, light->theta, light->phi); + +- /* Update the live definitions if the light is currently assigned a glIndex. */ +- if (object->glIndex != -1 && !device->recording) +- { +- if (object->OriginalParms.type != light->type) +- device_invalidate_state(device, STATE_LIGHT_TYPE); +- device_invalidate_state(device, STATE_ACTIVELIGHT(object->glIndex)); +- } +- + /* Save away the information. */ + object->OriginalParms = *light; + +@@ -1556,6 +1548,9 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, + FIXME("Unrecognized light type %#x.\n", light->type); + } + ++ if (!device->recording) ++ wined3d_cs_emit_set_light(device->cs, object); ++ + return WINED3D_OK; + } + +@@ -1628,12 +1623,6 @@ HRESULT CDECL wined3d_device_set_light_enable(struct wined3d_device *device, UIN + { + if (light_info->glIndex != -1) + { +- if (!device->recording) +- { +- device_invalidate_state(device, STATE_LIGHT_TYPE); +- device_invalidate_state(device, STATE_ACTIVELIGHT(light_info->glIndex)); +- } +- + device->update_state->lights[light_info->glIndex] = NULL; + light_info->glIndex = -1; + } +@@ -1675,16 +1664,12 @@ HRESULT CDECL wined3d_device_set_light_enable(struct wined3d_device *device, UIN + WARN("Too many concurrently active lights\n"); + return WINED3D_OK; + } +- +- /* i == light_info->glIndex */ +- if (!device->recording) +- { +- device_invalidate_state(device, STATE_LIGHT_TYPE); +- device_invalidate_state(device, STATE_ACTIVELIGHT(i)); +- } + } + } + ++ if (!device->recording) ++ wined3d_cs_emit_set_light_enable(device->cs, light_idx, enable); ++ + return WINED3D_OK; + } + +@@ -3395,7 +3380,6 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT + return WINED3DERR_INVALIDCALL; + } + +- wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); + wined3d_cs_emit_draw(device->cs, start_vertex, vertex_count, 0, 0, FALSE); + + return WINED3D_OK; +@@ -3430,8 +3414,6 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic + return WINED3DERR_INVALIDCALL; + } + +- +- wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); + wined3d_cs_emit_draw(device->cs, start_idx, index_count, 0, 0, TRUE); + + return WINED3D_OK; +@@ -3443,7 +3425,6 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device + TRACE("device %p, start_idx %u, index_count %u, start_instance %u, instance_count %u.\n", + device, start_idx, index_count, start_instance, instance_count); + +- wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); + wined3d_cs_emit_draw(device->cs, start_idx, index_count, start_instance, instance_count, TRUE); + } + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 13e28d4..5862540 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2622,7 +2622,9 @@ struct wined3d_cs_block + { + struct list entry; + UINT pos; +- BYTE data[sizeof(struct wined3d_state) * 2]; /* FIXME? The size is somewhat arbitrary. */ ++ /* FIXME? The size is somewhat arbitrary. It's big enough for huge ++ * shader constant set calls though */ ++ BYTE data[sizeof(float) * 4 * 256 * 2]; + }; + + struct wined3d_cs_ops +@@ -2667,8 +2669,6 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture + WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, + UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; +-void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, +- const struct wined3d_state *state) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, + struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, +@@ -2714,6 +2714,8 @@ void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, + UINT base_vertex_index) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, + GLenum primitive_type) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enable) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.5.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0062-wined3d-Prevent-the-command-stream-from-running-ahea.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0062-wined3d-Prevent-the-command-stream-from-running-ahea.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0062-wined3d-Prevent-the-command-stream-from-running-ahea.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0062-wined3d-Prevent-the-command-stream-from-running-ahea.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,60 @@ +From 0fe58ec92cc169b54b6d1f579ee59f70aa4554d0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 10 Apr 2013 19:10:41 +0200 +Subject: wined3d: Prevent the command stream from running ahead too far + +--- + dlls/wined3d/cs.c | 8 ++++++++ + dlls/wined3d/wined3d_private.h | 2 ++ + 2 files changed, 10 insertions(+) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index f48d14a..dbfd86d 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -472,6 +472,8 @@ static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) + src_rect, dst_rect, dirty_region, op->flags, + wined3d_rendertarget_view_get_surface(cs->state.fb.depth_stencil)); + ++ InterlockedDecrement(&cs->pending_presents); ++ + return sizeof(*op); + } + +@@ -480,6 +482,7 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw + const RGNDATA *dirty_region, DWORD flags) + { + struct wined3d_cs_present *op; ++ LONG pending; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_PRESENT; +@@ -503,7 +506,12 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw + } + op->flags = flags; + ++ pending = InterlockedIncrement(&cs->pending_presents); ++ + cs->ops->submit(cs); ++ ++ while (pending > 1) ++ pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0); + } + + static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 54cf7b5..ab3d07f 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2561,6 +2561,8 @@ struct wined3d_cs + + struct wined3d_cs_list free_list; + struct wined3d_cs_list exec_list; ++ ++ LONG pending_presents; + }; + + struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0062-wined3d-Send-int-constant-updates-through-the-comman.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0062-wined3d-Send-int-constant-updates-through-the-comman.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0062-wined3d-Send-int-constant-updates-through-the-comman.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0062-wined3d-Send-int-constant-updates-through-the-comman.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,175 +0,0 @@ -From 68141ab2e84252e99bcf6801a5bcc629b1494665 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 10 Apr 2013 14:20:47 +0200 -Subject: wined3d: Send int constant updates through the command stream - ---- - dlls/wined3d/cs.c | 74 ++++++++++++++++++++++++++++++++++++++---- - dlls/wined3d/device.c | 6 ++-- - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 74 insertions(+), 8 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 9d8491a..cf3a523 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -65,8 +65,10 @@ enum wined3d_cs_op - WINED3D_CS_OP_STATEBLOCK, - WINED3D_CS_OP_SET_VS_CONSTS_F, - WINED3D_CS_OP_SET_VS_CONSTS_B, -+ WINED3D_CS_OP_SET_VS_CONSTS_I, - WINED3D_CS_OP_SET_PS_CONSTS_F, - WINED3D_CS_OP_SET_PS_CONSTS_B, -+ WINED3D_CS_OP_SET_PS_CONSTS_I, - WINED3D_CS_OP_GLFINISH, - WINED3D_CS_OP_SET_BASE_VERTEX_INDEX, - WINED3D_CS_OP_SET_PRIMITIVE_TYPE, -@@ -296,6 +298,13 @@ struct wined3d_cs_set_consts_b - BOOL constants[1]; - }; - -+struct wined3d_cs_set_consts_i -+{ -+ enum wined3d_cs_op opcode; -+ UINT start_register, vector4i_count; -+ int constants[4]; -+}; -+ - struct wined3d_cs_finish - { - enum wined3d_cs_op opcode; -@@ -968,9 +977,6 @@ static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const voi - - /* Don't memcpy the entire struct, we'll remove single items as we add dedicated - * ops for setting states */ -- memcpy(cs->state.vs_consts_i, op->state.vs_consts_i, sizeof(cs->state.vs_consts_i)); -- -- memcpy(cs->state.ps_consts_i, op->state.ps_consts_i, sizeof(cs->state.ps_consts_i)); - - memcpy(cs->state.lights, op->state.lights, sizeof(cs->state.lights)); - -@@ -986,9 +992,6 @@ void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct win - - /* Don't memcpy the entire struct, we'll remove single items as we add dedicated - * ops for setting states */ -- memcpy(op->state.vs_consts_i, state->vs_consts_i, sizeof(op->state.vs_consts_i)); -- -- memcpy(op->state.ps_consts_i, state->ps_consts_i, sizeof(op->state.ps_consts_i)); - - /* FIXME: This is not ideal. CS is still running synchronously, so this is ok. - * It will go away soon anyway. */ -@@ -1201,6 +1204,63 @@ void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, - cs->ops->submit(cs); - } - -+static UINT wined3d_cs_exec_set_vs_consts_i(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_consts_i *op = data; -+ struct wined3d_device *device = cs->device; -+ -+ memcpy(&cs->state.vs_consts_i[op->start_register * 4], op->constants, -+ sizeof(*cs->state.vs_consts_i) * 4 * op->vector4i_count); -+ -+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_I); -+ -+ return sizeof(*op) + sizeof(op->constants) * (op->vector4i_count - 1); -+} -+ -+static UINT wined3d_cs_exec_set_ps_consts_i(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_consts_i *op = data; -+ struct wined3d_device *device = cs->device; -+ -+ memcpy(&cs->state.ps_consts_i[op->start_register * 4], op->constants, -+ sizeof(*cs->state.ps_consts_i) * 4 * op->vector4i_count); -+ -+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_I); -+ -+ return sizeof(*op) + sizeof(op->constants) * (op->vector4i_count - 1); -+} -+ -+void wined3d_cs_emit_set_consts_i(struct wined3d_cs *cs, UINT start_register, -+ const int *constants, UINT vector4i_count, enum wined3d_shader_type type) -+{ -+ struct wined3d_cs_set_consts_i *op; -+ UINT extra_space = vector4i_count - 1; -+ -+ op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); -+ switch (type) -+ { -+ case WINED3D_SHADER_TYPE_PIXEL: -+ op->opcode = WINED3D_CS_OP_SET_PS_CONSTS_I; -+ break; -+ -+ case WINED3D_SHADER_TYPE_VERTEX: -+ op->opcode = WINED3D_CS_OP_SET_VS_CONSTS_I; -+ break; -+ -+ case WINED3D_SHADER_TYPE_GEOMETRY: -+ ERR("Invalid for geometry shaders\n"); -+ return; -+ -+ case WINED3D_SHADER_TYPE_COUNT: -+ break; -+ } -+ op->start_register = start_register; -+ op->vector4i_count = vector4i_count; -+ memcpy(op->constants, constants, sizeof(op->constants) * vector4i_count); -+ -+ cs->ops->submit(cs); -+} -+ - static UINT wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_texture_state *op = data; -@@ -1442,8 +1502,10 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, - /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, - /* WINED3D_CS_OP_SET_VS_CONSTS_B */ wined3d_cs_exec_set_vs_consts_b, -+ /* WINED3D_CS_OP_SET_VS_CONSTS_I */ wined3d_cs_exec_set_vs_consts_i, - /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, - /* WINED3D_CS_OP_SET_PS_CONSTS_B */ wined3d_cs_exec_set_ps_consts_b, -+ /* WINED3D_CS_OP_SET_PS_CONSTS_I */ wined3d_cs_exec_set_ps_consts_i, - /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, - /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, - /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 14d3080..9ba40df 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -2278,7 +2278,8 @@ HRESULT CDECL wined3d_device_set_vs_consts_i(struct wined3d_device *device, - } - else - { -- device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_I); -+ wined3d_cs_emit_set_consts_i(device->cs, start_register, constants, -+ vector4i_count, WINED3D_SHADER_TYPE_VERTEX); - } - - return WINED3D_OK; -@@ -2513,7 +2514,8 @@ HRESULT CDECL wined3d_device_set_ps_consts_i(struct wined3d_device *device, - } - else - { -- device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_I); -+ wined3d_cs_emit_set_consts_i(device->cs, start_register, constants, -+ vector4i_count, WINED3D_SHADER_TYPE_PIXEL); - } - - return WINED3D_OK; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 4ecb626..59149bd 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2618,6 +2618,8 @@ void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, co - UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, - const BOOL *constants, UINT bool_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_set_consts_i(struct wined3d_cs *cs, UINT start_register, -+ const int *constants, UINT vector4i_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; - void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, - UINT base_vertex_index) DECLSPEC_HIDDEN; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0063-wined3d-Send-light-updates-through-the-command-strea.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0063-wined3d-Send-light-updates-through-the-command-strea.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0063-wined3d-Send-light-updates-through-the-command-strea.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0063-wined3d-Send-light-updates-through-the-command-strea.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,394 +0,0 @@ -From 4e5db60def2e093e529a2f7b8c5c0c081fd48723 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 10 Apr 2013 17:16:02 +0200 -Subject: wined3d: Send light updates through the command stream - ---- - dlls/wined3d/cs.c | 200 +++++++++++++++++++++++++++++++++-------- - dlls/wined3d/device.c | 31 ++----- - dlls/wined3d/wined3d_private.h | 8 +- - 3 files changed, 174 insertions(+), 65 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 434ce9a..562323e 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -63,7 +63,6 @@ enum wined3d_cs_op - WINED3D_CS_OP_SET_COLOR_KEY, - WINED3D_CS_OP_SET_MATERIAL, - WINED3D_CS_OP_RESET_STATE, -- WINED3D_CS_OP_STATEBLOCK, - WINED3D_CS_OP_SET_VS_CONSTS_F, - WINED3D_CS_OP_SET_VS_CONSTS_B, - WINED3D_CS_OP_SET_VS_CONSTS_I, -@@ -73,6 +72,8 @@ enum wined3d_cs_op - WINED3D_CS_OP_GLFINISH, - WINED3D_CS_OP_SET_BASE_VERTEX_INDEX, - WINED3D_CS_OP_SET_PRIMITIVE_TYPE, -+ WINED3D_CS_OP_SET_LIGHT, -+ WINED3D_CS_OP_SET_LIGHT_ENABLE, - WINED3D_CS_OP_STOP, - }; - -@@ -288,12 +289,6 @@ struct wined3d_cs_reset_state - enum wined3d_cs_op opcode; - }; - --struct wined3d_cs_stateblock --{ -- enum wined3d_cs_op opcode; -- struct wined3d_state state; --}; -- - struct wined3d_cs_set_consts_f - { - enum wined3d_cs_op opcode; -@@ -332,6 +327,19 @@ struct wined3d_cs_set_primitive_type - GLenum gl_primitive_type; - }; - -+struct wined3d_cs_set_light -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_light_info light; -+}; -+ -+struct wined3d_cs_set_light_enable -+{ -+ enum wined3d_cs_op opcode; -+ UINT idx; -+ BOOL enable; -+}; -+ - /* FIXME: The list synchronization probably isn't particularly fast. */ - static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) - { -@@ -997,35 +1005,6 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined - cs->ops->submit(cs); - } - --static UINT wined3d_cs_exec_transfer_stateblock(struct wined3d_cs *cs, const void *data) --{ -- const struct wined3d_cs_stateblock *op = data; -- -- /* Don't memcpy the entire struct, we'll remove single items as we add dedicated -- * ops for setting states */ -- -- memcpy(cs->state.lights, op->state.lights, sizeof(cs->state.lights)); -- -- return sizeof(*op); --} -- --void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, const struct wined3d_state *state) --{ -- struct wined3d_cs_stateblock *op; -- -- op = cs->ops->require_space(cs, sizeof(*op)); -- op->opcode = WINED3D_CS_OP_STATEBLOCK; -- -- /* Don't memcpy the entire struct, we'll remove single items as we add dedicated -- * ops for setting states */ -- -- /* FIXME: This is not ideal. CS is still running synchronously, so this is ok. -- * It will go away soon anyway. */ -- memcpy(op->state.lights, state->lights, sizeof(op->state.lights)); -- -- cs->ops->submit(cs); --} -- - static UINT wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_set_shader_resource_view *op = data; -@@ -1585,6 +1564,152 @@ void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, GLenum primitive_ - cs->ops->submit(cs); - } - -+static UINT wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_light *op = data; -+ -+ UINT light_idx = op->light.OriginalIndex; -+ UINT hash_idx = LIGHTMAP_HASHFUNC(op->light.OriginalIndex); -+ struct wined3d_light_info *object = NULL; -+ struct list *e; -+ -+ LIST_FOR_EACH(e, &cs->state.light_map[hash_idx]) -+ { -+ object = LIST_ENTRY(e, struct wined3d_light_info, entry); -+ if (object->OriginalIndex == light_idx) -+ break; -+ object = NULL; -+ } -+ -+ if (!object) -+ { -+ TRACE("Adding new light\n"); -+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); -+ if (!object) -+ return E_OUTOFMEMORY; -+ -+ list_add_head(&cs->state.light_map[hash_idx], &object->entry); -+ object->glIndex = -1; -+ object->OriginalIndex = light_idx; -+ } -+ -+ /* Update the live definitions if the light is currently assigned a glIndex. */ -+ if (object->glIndex != -1) -+ { -+ if (object->OriginalParms.type != op->light.OriginalParms.type) -+ device_invalidate_state(cs->device, STATE_LIGHT_TYPE); -+ device_invalidate_state(cs->device, STATE_ACTIVELIGHT(object->glIndex)); -+ } -+ -+ object->OriginalParms = op->light.OriginalParms; -+ object->position = op->light.position; -+ object->direction = op->light.direction; -+ object->exponent = op->light.exponent; -+ object->cutoff = op->light.cutoff; -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) -+{ -+ struct wined3d_cs_set_light *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_LIGHT; -+ op->light = *light; -+ -+ cs->ops->submit(cs); -+} -+ -+static UINT wined3d_cs_exec_set_light_enable(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_light_enable *op = data; -+ UINT hash_idx = LIGHTMAP_HASHFUNC(op->idx); -+ struct wined3d_light_info *light_info = NULL; -+ struct list *e; -+ struct wined3d_device *device = cs->device; -+ -+ LIST_FOR_EACH(e, &cs->state.light_map[hash_idx]) -+ { -+ light_info = LIST_ENTRY(e, struct wined3d_light_info, entry); -+ if (light_info->OriginalIndex == op->idx) -+ break; -+ light_info = NULL; -+ } -+ TRACE("Found light %p.\n", light_info); -+ -+ /* Should be handled by the device by emitting a set_light op */ -+ if (!light_info) -+ { -+ ERR("Light enabled requested but light not defined in cs state!\n"); -+ return sizeof(*op); -+ } -+ -+ if (!op->enable) -+ { -+ if (light_info->glIndex != -1) -+ { -+ device_invalidate_state(device, STATE_LIGHT_TYPE); -+ device_invalidate_state(device, STATE_ACTIVELIGHT(light_info->glIndex)); -+ cs->state.lights[light_info->glIndex] = NULL; -+ light_info->glIndex = -1; -+ } -+ else -+ { -+ TRACE("Light already disabled, nothing to do\n"); -+ } -+ light_info->enabled = FALSE; -+ } -+ else -+ { -+ light_info->enabled = TRUE; -+ if (light_info->glIndex != -1) -+ { -+ TRACE("Nothing to do as light was enabled\n"); -+ } -+ else -+ { -+ unsigned int i; -+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -+ /* Find a free GL light. */ -+ for (i = 0; i < gl_info->limits.lights; ++i) -+ { -+ if (!cs->state.lights[i]) -+ { -+ cs->state.lights[i] = light_info; -+ light_info->glIndex = i; -+ break; -+ } -+ } -+ if (light_info->glIndex == -1) -+ { -+ /* Should be caught by the device before emitting -+ * the light_enable op */ -+ ERR("Too many concurrently active lights in cs\n"); -+ return sizeof(*op); -+ } -+ -+ /* i == light_info->glIndex */ -+ device_invalidate_state(device, STATE_LIGHT_TYPE); -+ device_invalidate_state(device, STATE_ACTIVELIGHT(i)); -+ } -+ } -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enable) -+{ -+ struct wined3d_cs_set_light_enable *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_LIGHT_ENABLE; -+ op->idx = idx; -+ op->enable = enable; -+ -+ cs->ops->submit(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, -@@ -1614,7 +1739,6 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, - /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, - /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, -- /* WINED3D_CS_OP_STATEBLOCK */ wined3d_cs_exec_transfer_stateblock, - /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, - /* WINED3D_CS_OP_SET_VS_CONSTS_B */ wined3d_cs_exec_set_vs_consts_b, - /* WINED3D_CS_OP_SET_VS_CONSTS_I */ wined3d_cs_exec_set_vs_consts_i, -@@ -1624,6 +1748,8 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, - /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, - /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, -+ /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, -+ /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, - }; - - static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index d2ce327..74bff19 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -1469,14 +1469,6 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, - TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", - light->range, light->falloff, light->theta, light->phi); - -- /* Update the live definitions if the light is currently assigned a glIndex. */ -- if (object->glIndex != -1 && !device->recording) -- { -- if (object->OriginalParms.type != light->type) -- device_invalidate_state(device, STATE_LIGHT_TYPE); -- device_invalidate_state(device, STATE_ACTIVELIGHT(object->glIndex)); -- } -- - /* Save away the information. */ - object->OriginalParms = *light; - -@@ -1556,6 +1548,9 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, - FIXME("Unrecognized light type %#x.\n", light->type); - } - -+ if (!device->recording) -+ wined3d_cs_emit_set_light(device->cs, object); -+ - return WINED3D_OK; - } - -@@ -1628,12 +1623,6 @@ HRESULT CDECL wined3d_device_set_light_enable(struct wined3d_device *device, UIN - { - if (light_info->glIndex != -1) - { -- if (!device->recording) -- { -- device_invalidate_state(device, STATE_LIGHT_TYPE); -- device_invalidate_state(device, STATE_ACTIVELIGHT(light_info->glIndex)); -- } -- - device->update_state->lights[light_info->glIndex] = NULL; - light_info->glIndex = -1; - } -@@ -1675,16 +1664,12 @@ HRESULT CDECL wined3d_device_set_light_enable(struct wined3d_device *device, UIN - WARN("Too many concurrently active lights\n"); - return WINED3D_OK; - } -- -- /* i == light_info->glIndex */ -- if (!device->recording) -- { -- device_invalidate_state(device, STATE_LIGHT_TYPE); -- device_invalidate_state(device, STATE_ACTIVELIGHT(i)); -- } - } - } - -+ if (!device->recording) -+ wined3d_cs_emit_set_light_enable(device->cs, light_idx, enable); -+ - return WINED3D_OK; - } - -@@ -3395,7 +3380,6 @@ HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT - return WINED3DERR_INVALIDCALL; - } - -- wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); - wined3d_cs_emit_draw(device->cs, start_vertex, vertex_count, 0, 0, FALSE); - - return WINED3D_OK; -@@ -3430,8 +3414,6 @@ HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *devic - return WINED3DERR_INVALIDCALL; - } - -- -- wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); - wined3d_cs_emit_draw(device->cs, start_idx, index_count, 0, 0, TRUE); - - return WINED3D_OK; -@@ -3443,7 +3425,6 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device - TRACE("device %p, start_idx %u, index_count %u, start_instance %u, instance_count %u.\n", - device, start_idx, index_count, start_instance, instance_count); - -- wined3d_cs_emit_transfer_stateblock(device->cs, &device->state); - wined3d_cs_emit_draw(device->cs, start_idx, index_count, start_instance, instance_count, TRUE); - } - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 13e28d4..5862540 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2622,7 +2622,9 @@ struct wined3d_cs_block - { - struct list entry; - UINT pos; -- BYTE data[sizeof(struct wined3d_state) * 2]; /* FIXME? The size is somewhat arbitrary. */ -+ /* FIXME? The size is somewhat arbitrary. It's big enough for huge -+ * shader constant set calls though */ -+ BYTE data[sizeof(float) * 4 * 256 * 2]; - }; - - struct wined3d_cs_ops -@@ -2667,8 +2669,6 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture - WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, - UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; --void wined3d_cs_emit_transfer_stateblock(struct wined3d_cs *cs, -- const struct wined3d_state *state) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, - struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, -@@ -2714,6 +2714,8 @@ void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, - UINT base_vertex_index) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, - GLenum primitive_type) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enable) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0063-wined3d-Wait-for-the-cs-to-finish-before-destroying-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0063-wined3d-Wait-for-the-cs-to-finish-before-destroying-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0063-wined3d-Wait-for-the-cs-to-finish-before-destroying-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0063-wined3d-Wait-for-the-cs-to-finish-before-destroying-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,26 @@ +From 0f21b13a057d684fa30678d8c08e87614eca066a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 10 Apr 2013 20:09:55 +0200 +Subject: wined3d: Wait for the cs to finish before destroying the device + +--- + dlls/wined3d/device.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 05a353c..9ef99b2 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -1013,6 +1013,9 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) + if (!device->d3d_initialized) + return WINED3DERR_INVALIDCALL; + ++ if (wined3d_settings.cs_multithreaded) ++ device->cs->ops->finish(device->cs); ++ + /* I don't think that the interface guarantees that the device is destroyed from the same thread + * it was created. Thus make sure a context is active for the glDelete* calls + */ +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0064-wined3d-Prevent-the-command-stream-from-running-ahea.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0064-wined3d-Prevent-the-command-stream-from-running-ahea.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0064-wined3d-Prevent-the-command-stream-from-running-ahea.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0064-wined3d-Prevent-the-command-stream-from-running-ahea.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -From 0fe58ec92cc169b54b6d1f579ee59f70aa4554d0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 10 Apr 2013 19:10:41 +0200 -Subject: wined3d: Prevent the command stream from running ahead too far - ---- - dlls/wined3d/cs.c | 8 ++++++++ - dlls/wined3d/wined3d_private.h | 2 ++ - 2 files changed, 10 insertions(+) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index f48d14a..dbfd86d 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -472,6 +472,8 @@ static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) - src_rect, dst_rect, dirty_region, op->flags, - wined3d_rendertarget_view_get_surface(cs->state.fb.depth_stencil)); - -+ InterlockedDecrement(&cs->pending_presents); -+ - return sizeof(*op); - } - -@@ -480,6 +482,7 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw - const RGNDATA *dirty_region, DWORD flags) - { - struct wined3d_cs_present *op; -+ LONG pending; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_PRESENT; -@@ -503,7 +506,12 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw - } - op->flags = flags; - -+ pending = InterlockedIncrement(&cs->pending_presents); -+ - cs->ops->submit(cs); -+ -+ while (pending > 1) -+ pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0); - } - - static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 54cf7b5..ab3d07f 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2561,6 +2561,8 @@ struct wined3d_cs - - struct wined3d_cs_list free_list; - struct wined3d_cs_list exec_list; -+ -+ LONG pending_presents; - }; - - struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0064-wined3d-Run-the-cs-asynchronously.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0064-wined3d-Run-the-cs-asynchronously.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0064-wined3d-Run-the-cs-asynchronously.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0064-wined3d-Run-the-cs-asynchronously.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,25 @@ +From ae49b3a304769185e9f2a92ec21975d44a389654 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 10 Apr 2013 20:12:27 +0200 +Subject: wined3d: Run the cs asynchronously + +--- + dlls/wined3d/cs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index dbfd86d..949bd6b 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -1679,7 +1679,7 @@ static const struct wined3d_cs_ops wined3d_cs_st_ops = + static const struct wined3d_cs_ops wined3d_cs_mt_ops = + { + wined3d_cs_mt_require_space, +- wined3d_cs_flush_and_wait, ++ wined3d_cs_flush, + wined3d_cs_flush_and_wait, + }; + +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0065-wined3d-Send-blits-through-the-command-stream.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0065-wined3d-Send-blits-through-the-command-stream.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0065-wined3d-Send-blits-through-the-command-stream.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0065-wined3d-Send-blits-through-the-command-stream.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,494 @@ +From 5d8735b2ffacc388879177422898deffd32ef841 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Mon, 29 Apr 2013 18:49:53 +0200 +Subject: wined3d: Send blits through the command stream. + +This needs more work. This patch breaks error handling, and the split +between surface_blt and surface_blt_ugly isn't particularly nice. +--- + dlls/d3d9/tests/visual.c | 2 +- + dlls/wined3d/cs.c | 50 ++++++++ + dlls/wined3d/surface.c | 260 +++++++++++++++++++++++------------------ + dlls/wined3d/wined3d_private.h | 8 ++ + 4 files changed, 204 insertions(+), 116 deletions(-) + +diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c +index 8b56dbe..ae4004a 100644 +--- a/dlls/d3d9/tests/visual.c ++++ b/dlls/d3d9/tests/visual.c +@@ -1339,7 +1339,7 @@ static void color_fill_test(void) + * result on Wine. + * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0}, + * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */ +- {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS | TODO_FILL_RETURN, 0}, ++ {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS, 0}, + /* Vendor-specific formats like ATI2N are a non-issue here since they're not + * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET + * when created as texture. */ +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index de9fc9b..9fc92cf 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -74,6 +74,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_SET_PRIMITIVE_TYPE, + WINED3D_CS_OP_SET_LIGHT, + WINED3D_CS_OP_SET_LIGHT_ENABLE, ++ WINED3D_CS_OP_BLT, + WINED3D_CS_OP_STOP, + }; + +@@ -340,6 +341,18 @@ struct wined3d_cs_set_light_enable + BOOL enable; + }; + ++struct wined3d_cs_blt ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_surface *dst_surface; ++ RECT dst_rect; ++ struct wined3d_surface *src_surface; ++ RECT src_rect; ++ DWORD flags; ++ WINEDDBLTFX fx; ++ enum wined3d_texture_filter_type filter; ++}; ++ + /* FIXME: The list synchronization probably isn't particularly fast. */ + static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) + { +@@ -1507,6 +1520,9 @@ static UINT wined3d_cs_exec_glfinish(struct wined3d_cs *cs, const void *data) + struct wined3d_device *device = cs->device; + struct wined3d_context *context; + ++ if (!device->d3d_initialized) ++ return sizeof(*op); ++ + context = context_acquire(device, NULL); + context->gl_info->gl_ops.gl.p_glFinish(); + context_release(context); +@@ -1718,6 +1734,38 @@ void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enab + cs->ops->submit(cs); + } + ++static UINT wined3d_cs_exec_blt(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_blt *op = data; ++ ++ surface_blt_ugly(op->dst_surface, &op->dst_rect, ++ op->src_surface, &op->src_rect, ++ op->flags, &op->fx, op->filter); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surface, ++ const RECT *dst_rect, struct wined3d_surface *src_surface, ++ const RECT *src_rect, DWORD flags, const WINEDDBLTFX *fx, ++ enum wined3d_texture_filter_type filter) ++{ ++ struct wined3d_cs_blt *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_BLT; ++ op->dst_surface = dst_surface; ++ op->dst_rect = *dst_rect; ++ op->src_surface = src_surface; ++ op->src_rect = *src_rect; ++ op->flags = flags; ++ op->filter = filter; ++ if (fx) ++ op->fx = *fx; ++ ++ cs->ops->submit(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, +@@ -1758,6 +1806,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, + /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, + /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, ++ /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, + }; + + static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) +@@ -1832,6 +1881,7 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) + + TRACE("Started.\n"); + ++ cs->thread_id = GetCurrentThreadId(); + for (;;) + { + struct wined3d_cs_block *block; +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 9fafb6b..dfe5c73 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -4857,7 +4857,7 @@ const struct blit_shader cpu_blit = { + cpu_blit_blit_surface, + }; + +-HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, ++void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect, + struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, + const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) + { +@@ -4875,103 +4875,6 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst + | WINEDDBLT_DONOTWAIT + | WINEDDBLT_ALPHATEST; + +- TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", +- dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), +- flags, fx, debug_d3dtexturefiltertype(filter)); +- TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage)); +- +- if (fx) +- { +- TRACE("dwSize %#x.\n", fx->dwSize); +- TRACE("dwDDFX %#x.\n", fx->dwDDFX); +- TRACE("dwROP %#x.\n", fx->dwROP); +- TRACE("dwDDROP %#x.\n", fx->dwDDROP); +- TRACE("dwRotationAngle %#x.\n", fx->dwRotationAngle); +- TRACE("dwZBufferOpCode %#x.\n", fx->dwZBufferOpCode); +- TRACE("dwZBufferLow %#x.\n", fx->dwZBufferLow); +- TRACE("dwZBufferHigh %#x.\n", fx->dwZBufferHigh); +- TRACE("dwZBufferBaseDest %#x.\n", fx->dwZBufferBaseDest); +- TRACE("dwZDestConstBitDepth %#x.\n", fx->dwZDestConstBitDepth); +- TRACE("lpDDSZBufferDest %p.\n", fx->u1.lpDDSZBufferDest); +- TRACE("dwZSrcConstBitDepth %#x.\n", fx->dwZSrcConstBitDepth); +- TRACE("lpDDSZBufferSrc %p.\n", fx->u2.lpDDSZBufferSrc); +- TRACE("dwAlphaEdgeBlendBitDepth %#x.\n", fx->dwAlphaEdgeBlendBitDepth); +- TRACE("dwAlphaEdgeBlend %#x.\n", fx->dwAlphaEdgeBlend); +- TRACE("dwReserved %#x.\n", fx->dwReserved); +- TRACE("dwAlphaDestConstBitDepth %#x.\n", fx->dwAlphaDestConstBitDepth); +- TRACE("lpDDSAlphaDest %p.\n", fx->u3.lpDDSAlphaDest); +- TRACE("dwAlphaSrcConstBitDepth %#x.\n", fx->dwAlphaSrcConstBitDepth); +- TRACE("lpDDSAlphaSrc %p.\n", fx->u4.lpDDSAlphaSrc); +- TRACE("lpDDSPattern %p.\n", fx->u5.lpDDSPattern); +- TRACE("ddckDestColorkey {%#x, %#x}.\n", +- fx->ddckDestColorkey.color_space_low_value, +- fx->ddckDestColorkey.color_space_high_value); +- TRACE("ddckSrcColorkey {%#x, %#x}.\n", +- fx->ddckSrcColorkey.color_space_low_value, +- fx->ddckSrcColorkey.color_space_high_value); +- } +- +- if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) +- { +- WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); +- return WINEDDERR_SURFACEBUSY; +- } +- +- if (dst_rect->left >= dst_rect->right || dst_rect->top >= dst_rect->bottom +- || dst_rect->left > dst_surface->resource.width || dst_rect->left < 0 +- || dst_rect->top > dst_surface->resource.height || dst_rect->top < 0 +- || dst_rect->right > dst_surface->resource.width || dst_rect->right < 0 +- || dst_rect->bottom > dst_surface->resource.height || dst_rect->bottom < 0) +- { +- WARN("The application gave us a bad destination rectangle.\n"); +- return WINEDDERR_INVALIDRECT; +- } +- +- if (src_surface) +- { +- if (src_rect->left >= src_rect->right || src_rect->top >= src_rect->bottom +- || src_rect->left > src_surface->resource.width || src_rect->left < 0 +- || src_rect->top > src_surface->resource.height || src_rect->top < 0 +- || src_rect->right > src_surface->resource.width || src_rect->right < 0 +- || src_rect->bottom > src_surface->resource.height || src_rect->bottom < 0) +- { +- WARN("The application gave us a bad source rectangle.\n"); +- return WINEDDERR_INVALIDRECT; +- } +- } +- +- if (!fx || !(fx->dwDDFX)) +- flags &= ~WINEDDBLT_DDFX; +- +- if (flags & WINEDDBLT_WAIT) +- flags &= ~WINEDDBLT_WAIT; +- +- if (flags & WINEDDBLT_ASYNC) +- { +- static unsigned int once; +- +- if (!once++) +- FIXME("Can't handle WINEDDBLT_ASYNC flag.\n"); +- flags &= ~WINEDDBLT_ASYNC; +- } +- +- /* WINEDDBLT_DONOTWAIT appeared in DX7. */ +- if (flags & WINEDDBLT_DONOTWAIT) +- { +- static unsigned int once; +- +- if (!once++) +- FIXME("Can't handle WINEDDBLT_DONOTWAIT flag.\n"); +- flags &= ~WINEDDBLT_DONOTWAIT; +- } +- +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- wined3d_cs_emit_glfinish(device->cs); +- device->cs->ops->finish(device->cs); +- } +- + if (!device->d3d_initialized) + { + WARN("D3D not initialized, using fallback.\n"); +@@ -5035,22 +4938,16 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst + TRACE("Depth fill.\n"); + + if (!surface_convert_depth_to_float(dst_surface, fx->u5.dwFillDepth, &depth)) +- return WINED3DERR_INVALIDCALL; ++ return; + + if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, dst_rect, depth))) +- return WINED3D_OK; ++ return; + } + else + { +- if (src_ds_flags != dst_ds_flags) +- { +- WARN("Rejecting depth / stencil blit between incompatible formats.\n"); +- return WINED3DERR_INVALIDCALL; +- } +- + if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->container->resource.draw_binding, + src_rect, dst_surface, dst_surface->container->resource.draw_binding, dst_rect))) +- return WINED3D_OK; ++ return; + } + } + else +@@ -5082,7 +4979,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst + goto fallback; + + if (SUCCEEDED(surface_color_fill(dst_surface, dst_rect, &color))) +- return WINED3D_OK; ++ return; + } + else + { +@@ -5125,7 +5022,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst + dst_surface->container->resource.draw_binding); + context_release(context); + } +- return WINED3D_OK; ++ return; + } + } + } +@@ -5149,7 +5046,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst + wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, NULL, 0); + dst_swapchain->desc.swap_effect = swap_effect; + +- return WINED3D_OK; ++ return; + } + + if (fbo_blit_supported(&device->adapter->gl_info, blit_op, +@@ -5168,7 +5065,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst + wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); + wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding); + +- return WINED3D_OK; ++ return; + } + + blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, blit_op, +@@ -5178,18 +5075,151 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst + { + blitter->blit_surface(device, blit_op, filter, src_surface, + src_rect, dst_surface, dst_rect, color_key); +- return WINED3D_OK; ++ return; + } + } + } + + fallback: + /* Special cases for render targets. */ +- if (SUCCEEDED(surface_blt_special(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter))) +- return WINED3D_OK; ++ if ((dst_surface->resource.usage & WINED3DUSAGE_RENDERTARGET) ++ || (src_surface && (src_surface->resource.usage & WINED3DUSAGE_RENDERTARGET))) ++ { ++ if (SUCCEEDED(surface_blt_special(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter))) ++ return; ++ } + + cpu: +- return surface_cpu_blt(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter); ++ surface_cpu_blt(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter); ++ return; ++} ++ ++HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, ++ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, ++ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) ++{ ++ struct wined3d_device *device = dst_surface->resource.device; ++ ++ TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", ++ dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), ++ flags, fx, debug_d3dtexturefiltertype(filter)); ++ TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage)); ++ ++ if (fx) ++ { ++ TRACE("dwSize %#x.\n", fx->dwSize); ++ TRACE("dwDDFX %#x.\n", fx->dwDDFX); ++ TRACE("dwROP %#x.\n", fx->dwROP); ++ TRACE("dwDDROP %#x.\n", fx->dwDDROP); ++ TRACE("dwRotationAngle %#x.\n", fx->dwRotationAngle); ++ TRACE("dwZBufferOpCode %#x.\n", fx->dwZBufferOpCode); ++ TRACE("dwZBufferLow %#x.\n", fx->dwZBufferLow); ++ TRACE("dwZBufferHigh %#x.\n", fx->dwZBufferHigh); ++ TRACE("dwZBufferBaseDest %#x.\n", fx->dwZBufferBaseDest); ++ TRACE("dwZDestConstBitDepth %#x.\n", fx->dwZDestConstBitDepth); ++ TRACE("lpDDSZBufferDest %p.\n", fx->u1.lpDDSZBufferDest); ++ TRACE("dwZSrcConstBitDepth %#x.\n", fx->dwZSrcConstBitDepth); ++ TRACE("lpDDSZBufferSrc %p.\n", fx->u2.lpDDSZBufferSrc); ++ TRACE("dwAlphaEdgeBlendBitDepth %#x.\n", fx->dwAlphaEdgeBlendBitDepth); ++ TRACE("dwAlphaEdgeBlend %#x.\n", fx->dwAlphaEdgeBlend); ++ TRACE("dwReserved %#x.\n", fx->dwReserved); ++ TRACE("dwAlphaDestConstBitDepth %#x.\n", fx->dwAlphaDestConstBitDepth); ++ TRACE("lpDDSAlphaDest %p.\n", fx->u3.lpDDSAlphaDest); ++ TRACE("dwAlphaSrcConstBitDepth %#x.\n", fx->dwAlphaSrcConstBitDepth); ++ TRACE("lpDDSAlphaSrc %p.\n", fx->u4.lpDDSAlphaSrc); ++ TRACE("lpDDSPattern %p.\n", fx->u5.lpDDSPattern); ++ TRACE("ddckDestColorkey {%#x, %#x}.\n", ++ fx->ddckDestColorkey.color_space_low_value, ++ fx->ddckDestColorkey.color_space_high_value); ++ TRACE("ddckSrcColorkey {%#x, %#x}.\n", ++ fx->ddckSrcColorkey.color_space_low_value, ++ fx->ddckSrcColorkey.color_space_high_value); ++ } ++ ++ if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) ++ { ++ /* TODO: Separate application maps from internal maps */ ++ if (!wined3d_settings.cs_multithreaded) ++ { ++ WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); ++ return WINEDDERR_SURFACEBUSY; ++ } ++ ++ wined3d_cs_emit_glfinish(dst_surface->resource.device->cs); ++ dst_surface->resource.device->cs->ops->finish(dst_surface->resource.device->cs); ++ ++ if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) ++ { ++ WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); ++ return WINEDDERR_SURFACEBUSY; ++ } ++ } ++ ++ if (dst_rect->left >= dst_rect->right || dst_rect->top >= dst_rect->bottom ++ || dst_rect->left > dst_surface->resource.width || dst_rect->left < 0 ++ || dst_rect->top > dst_surface->resource.height || dst_rect->top < 0 ++ || dst_rect->right > dst_surface->resource.width || dst_rect->right < 0 ++ || dst_rect->bottom > dst_surface->resource.height || dst_rect->bottom < 0) ++ { ++ WARN("The application gave us a bad destination rectangle.\n"); ++ return WINEDDERR_INVALIDRECT; ++ } ++ ++ if (src_surface) ++ { ++ DWORD src_ds_flags, dst_ds_flags; ++ ++ if (src_rect->left >= src_rect->right || src_rect->top >= src_rect->bottom ++ || src_rect->left > src_surface->resource.width || src_rect->left < 0 ++ || src_rect->top > src_surface->resource.height || src_rect->top < 0 ++ || src_rect->right > src_surface->resource.width || src_rect->right < 0 ++ || src_rect->bottom > src_surface->resource.height || src_rect->bottom < 0) ++ { ++ WARN("The application gave us a bad source rectangle.\n"); ++ return WINEDDERR_INVALIDRECT; ++ } ++ ++ dst_ds_flags = dst_surface->container->resource.format_flags ++ & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); ++ src_ds_flags = src_surface->container->resource.format_flags ++ & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); ++ if (src_ds_flags != dst_ds_flags) ++ { ++ WARN("Rejecting depth / stencil blit between incompatible formats.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ } ++ ++ if (!fx || !(fx->dwDDFX)) ++ flags &= ~WINEDDBLT_DDFX; ++ ++ if (flags & WINEDDBLT_WAIT) ++ flags &= ~WINEDDBLT_WAIT; ++ ++ if (flags & WINEDDBLT_ASYNC) ++ { ++ static unsigned int once; ++ ++ if (!once++) ++ FIXME("Can't handle WINEDDBLT_ASYNC flag.\n"); ++ flags &= ~WINEDDBLT_ASYNC; ++ } ++ ++ /* WINEDDBLT_DONOTWAIT appeared in DX7. */ ++ if (flags & WINEDDBLT_DONOTWAIT) ++ { ++ static unsigned int once; ++ ++ if (!once++) ++ FIXME("Can't handle WINEDDBLT_DONOTWAIT flag.\n"); ++ flags &= ~WINEDDBLT_DONOTWAIT; ++ } ++ ++ TRACE("Emitting blit %p <== %p\n", dst_surface, src_surface); ++ wined3d_cs_emit_blt(device->cs, dst_surface, dst_rect, src_surface, src_rect, ++ flags, fx, filter); ++ ++ return WINED3D_OK; + } + + static const struct wined3d_resource_ops surface_resource_ops = +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 6b95f46..b93988c 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2557,6 +2557,9 @@ void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN; + void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, + const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, + BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; ++void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect_in, ++ struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, ++ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; + + void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, + const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; +@@ -2703,6 +2706,7 @@ struct wined3d_cs + struct wined3d_device *device; + struct wined3d_state state; + HANDLE thread; ++ DWORD thread_id; + DWORD tls_idx; + struct wined3d_surface *onscreen_depth_stencil; + +@@ -2781,6 +2785,10 @@ void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, + GLenum primitive_type) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enable) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surface, ++ const RECT *dst_rect, struct wined3d_surface *src_surface, ++ const RECT *src_rect, DWORD flags, const WINEDDBLTFX *fx, ++ enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0065-wined3d-Wait-for-the-cs-to-finish-before-destroying-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0065-wined3d-Wait-for-the-cs-to-finish-before-destroying-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0065-wined3d-Wait-for-the-cs-to-finish-before-destroying-.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0065-wined3d-Wait-for-the-cs-to-finish-before-destroying-.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -From 0f21b13a057d684fa30678d8c08e87614eca066a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 10 Apr 2013 20:09:55 +0200 -Subject: wined3d: Wait for the cs to finish before destroying the device - ---- - dlls/wined3d/device.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 05a353c..9ef99b2 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -1013,6 +1013,9 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) - if (!device->d3d_initialized) - return WINED3DERR_INVALIDCALL; - -+ if (wined3d_settings.cs_multithreaded) -+ device->cs->ops->finish(device->cs); -+ - /* I don't think that the interface guarantees that the device is destroyed from the same thread - * it was created. Thus make sure a context is active for the glDelete* calls - */ --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0066-wined3d-Put-update_surface-checks-back-in-place.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0066-wined3d-Put-update_surface-checks-back-in-place.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0066-wined3d-Put-update_surface-checks-back-in-place.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0066-wined3d-Put-update_surface-checks-back-in-place.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,127 @@ +From 843b306004f731e36e9d9d9336228cd2c06f9128 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 20 Aug 2014 14:14:23 +0200 +Subject: wined3d: Put update_surface checks back in place + +Unfortunately I can't remove the code from surface_update_from_surface +yet because blits depend on them. +--- + dlls/wined3d/device.c | 68 ++++++++++++++++++++++++++++++++++++++++++ + dlls/wined3d/surface.c | 2 +- + dlls/wined3d/wined3d_private.h | 1 + + 3 files changed, 70 insertions(+), 1 deletion(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 819e6de..e804afe 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -3773,6 +3773,13 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, + struct wined3d_surface *src_surface, const RECT *src_rect, + struct wined3d_surface *dst_surface, const POINT *dst_point) + { ++ const struct wined3d_format *src_format = src_surface->resource.format; ++ const struct wined3d_format *dst_format = dst_surface->resource.format; ++ UINT update_w, update_h; ++ UINT dst_w, dst_h; ++ RECT r, dst_rect; ++ POINT p; ++ + TRACE("device %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s.\n", + device, src_surface, wine_dbgstr_rect(src_rect), + dst_surface, wine_dbgstr_point(dst_point)); +@@ -3784,6 +3791,67 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, + return WINED3DERR_INVALIDCALL; + } + ++ if (src_format->id != dst_format->id) ++ { ++ WARN("Source and destination surfaces should have the same format.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ if (!dst_point) ++ { ++ p.x = 0; ++ p.y = 0; ++ dst_point = &p; ++ } ++ else if (dst_point->x < 0 || dst_point->y < 0) ++ { ++ WARN("Invalid destination point.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ if (!src_rect) ++ { ++ r.left = 0; ++ r.top = 0; ++ r.right = src_surface->resource.width; ++ r.bottom = src_surface->resource.height; ++ src_rect = &r; ++ } ++ else if (src_rect->left < 0 || src_rect->left >= src_rect->right ++ || src_rect->top < 0 || src_rect->top >= src_rect->bottom) ++ { ++ WARN("Invalid source rectangle.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ dst_w = dst_surface->resource.width; ++ dst_h = dst_surface->resource.height; ++ ++ update_w = src_rect->right - src_rect->left; ++ update_h = src_rect->bottom - src_rect->top; ++ ++ if (update_w > dst_w || dst_point->x > dst_w - update_w ++ || update_h > dst_h || dst_point->y > dst_h - update_h) ++ { ++ WARN("Destination out of bounds.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ if ((src_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) ++ && !surface_check_block_align_rect(src_surface, src_rect)) ++ { ++ WARN("Source rectangle not block-aligned.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ SetRect(&dst_rect, dst_point->x, dst_point->y, dst_point->x + update_w, dst_point->y + update_h); ++ if ((dst_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) ++ && !surface_check_block_align_rect(dst_surface, &dst_rect)) ++ { ++ WARN("Destination rectangle not block-aligned.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ + if (wined3d_settings.cs_multithreaded) + { + FIXME("Waiting for cs.\n"); +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 2d98a93..5a2b14e 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -1371,7 +1371,7 @@ static BOOL surface_check_block_align(struct wined3d_surface *surface, const str + return wined3d_resource_check_block_align(&surface->resource, box); + } + +-static BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) ++BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) + { + struct wined3d_box box = {rect->left, rect->top, rect->right, rect->bottom, 0, 1}; + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 73da744..99212de 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2494,6 +2494,7 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w + void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect_in, + struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, + const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; ++BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) DECLSPEC_HIDDEN; + + void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, + const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; +-- +2.6.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0066-wined3d-Run-the-cs-asynchronously.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0066-wined3d-Run-the-cs-asynchronously.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0066-wined3d-Run-the-cs-asynchronously.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0066-wined3d-Run-the-cs-asynchronously.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -From ae49b3a304769185e9f2a92ec21975d44a389654 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 10 Apr 2013 20:12:27 +0200 -Subject: wined3d: Run the cs asynchronously - ---- - dlls/wined3d/cs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index dbfd86d..949bd6b 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -1679,7 +1679,7 @@ static const struct wined3d_cs_ops wined3d_cs_st_ops = - static const struct wined3d_cs_ops wined3d_cs_mt_ops = - { - wined3d_cs_mt_require_space, -- wined3d_cs_flush_and_wait, -+ wined3d_cs_flush, - wined3d_cs_flush_and_wait, - }; - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0067-wined3d-Get-rid-of-WINED3D_BUFFER_FLUSH.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0067-wined3d-Get-rid-of-WINED3D_BUFFER_FLUSH.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0067-wined3d-Get-rid-of-WINED3D_BUFFER_FLUSH.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0067-wined3d-Get-rid-of-WINED3D_BUFFER_FLUSH.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,57 @@ +From 7a25ed307d8aa08209a3e56ad4aa0bfc5995a5f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 7 May 2013 14:53:48 +0200 +Subject: wined3d: Get rid of WINED3D_BUFFER_FLUSH + +--- + dlls/wined3d/buffer.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index d2c1d62..5544640 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -32,10 +32,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); + #define WINED3D_BUFFER_HASDESC 0x01 /* A vertex description has been found. */ + #define WINED3D_BUFFER_CREATEBO 0x02 /* Create a buffer object for this buffer. */ + #define WINED3D_BUFFER_DOUBLEBUFFER 0x04 /* Keep both a buffer object and a system memory copy for this buffer. */ +-#define WINED3D_BUFFER_FLUSH 0x08 /* Manual unmap flushing. */ +-#define WINED3D_BUFFER_DISCARD 0x10 /* A DISCARD lock has occurred since the last preload. */ +-#define WINED3D_BUFFER_SYNC 0x20 /* There has been at least one synchronized map since the last preload. */ +-#define WINED3D_BUFFER_APPLESYNC 0x40 /* Using sync as in GL_APPLE_flush_buffer_range. */ ++#define WINED3D_BUFFER_DISCARD 0x08 /* A DISCARD lock has occurred since the last preload. */ ++#define WINED3D_BUFFER_SYNC 0x10 /* There has been at least one synchronized map since the last preload. */ ++#define WINED3D_BUFFER_APPLESYNC 0x20 /* Using sync as in GL_APPLE_flush_buffer_range. */ + + #define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */ + #define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */ +@@ -167,8 +166,6 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine + { + GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); + checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)"); +- This->flags |= WINED3D_BUFFER_FLUSH; +- + GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); + checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)"); + This->flags |= WINED3D_BUFFER_APPLESYNC; +@@ -707,7 +704,7 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined + GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len)); + checkGLcall("glFlushMappedBufferRange"); + } +- else if (This->flags & WINED3D_BUFFER_FLUSH) ++ else if (This->flags & WINED3D_BUFFER_APPLESYNC) + { + GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len)); + checkGLcall("glFlushMappedBufferRangeAPPLE"); +@@ -1112,7 +1109,7 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) + checkGLcall("glFlushMappedBufferRange"); + } + } +- else if (buffer->flags & WINED3D_BUFFER_FLUSH) ++ else if (buffer->flags & WINED3D_BUFFER_APPLESYNC) + { + for (i = 0; i < buffer->modified_areas; ++i) + { +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0067-wined3d-Send-blits-through-the-command-stream.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0067-wined3d-Send-blits-through-the-command-stream.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0067-wined3d-Send-blits-through-the-command-stream.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0067-wined3d-Send-blits-through-the-command-stream.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,571 +0,0 @@ -From eb73b6b42378386ce8af3594094ad61cd2c61754 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Mon, 29 Apr 2013 18:49:53 +0200 -Subject: wined3d: Send blits through the command stream. - -This needs more work. This patch breaks error handling, and the split -between surface_blt and surface_blt_ugly isn't particularly nice. ---- - dlls/d3d9/tests/visual.c | 2 +- - dlls/wined3d/cs.c | 50 +++++++ - dlls/wined3d/surface.c | 309 +++++++++++++++++++++++------------------ - dlls/wined3d/wined3d_private.h | 8 ++ - 4 files changed, 229 insertions(+), 140 deletions(-) - -diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c -index 120d688..fadba7b 100644 ---- a/dlls/d3d9/tests/visual.c -+++ b/dlls/d3d9/tests/visual.c -@@ -1339,7 +1339,7 @@ static void color_fill_test(void) - * result on Wine. - * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0}, - * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */ -- {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS | TODO_FILL_RETURN, 0}, -+ {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS, 0}, - /* Vendor-specific formats like ATI2N are a non-issue here since they're not - * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET - * when created as texture. */ -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index de9fc9b..9fc92cf 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -74,6 +74,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_SET_PRIMITIVE_TYPE, - WINED3D_CS_OP_SET_LIGHT, - WINED3D_CS_OP_SET_LIGHT_ENABLE, -+ WINED3D_CS_OP_BLT, - WINED3D_CS_OP_STOP, - }; - -@@ -340,6 +341,18 @@ struct wined3d_cs_set_light_enable - BOOL enable; - }; - -+struct wined3d_cs_blt -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_surface *dst_surface; -+ RECT dst_rect; -+ struct wined3d_surface *src_surface; -+ RECT src_rect; -+ DWORD flags; -+ WINEDDBLTFX fx; -+ enum wined3d_texture_filter_type filter; -+}; -+ - /* FIXME: The list synchronization probably isn't particularly fast. */ - static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) - { -@@ -1507,6 +1520,9 @@ static UINT wined3d_cs_exec_glfinish(struct wined3d_cs *cs, const void *data) - struct wined3d_device *device = cs->device; - struct wined3d_context *context; - -+ if (!device->d3d_initialized) -+ return sizeof(*op); -+ - context = context_acquire(device, NULL); - context->gl_info->gl_ops.gl.p_glFinish(); - context_release(context); -@@ -1718,6 +1734,38 @@ void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enab - cs->ops->submit(cs); - } - -+static UINT wined3d_cs_exec_blt(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_blt *op = data; -+ -+ surface_blt_ugly(op->dst_surface, &op->dst_rect, -+ op->src_surface, &op->src_rect, -+ op->flags, &op->fx, op->filter); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surface, -+ const RECT *dst_rect, struct wined3d_surface *src_surface, -+ const RECT *src_rect, DWORD flags, const WINEDDBLTFX *fx, -+ enum wined3d_texture_filter_type filter) -+{ -+ struct wined3d_cs_blt *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_BLT; -+ op->dst_surface = dst_surface; -+ op->dst_rect = *dst_rect; -+ op->src_surface = src_surface; -+ op->src_rect = *src_rect; -+ op->flags = flags; -+ op->filter = filter; -+ if (fx) -+ op->fx = *fx; -+ -+ cs->ops->submit(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, -@@ -1758,6 +1806,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, - /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, - /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, -+ /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, - }; - - static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -@@ -1832,6 +1881,7 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) - - TRACE("Started.\n"); - -+ cs->thread_id = GetCurrentThreadId(); - for (;;) - { - struct wined3d_cs_block *block; -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 3c1ba32..c437fb3 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -4846,14 +4846,13 @@ const struct blit_shader cpu_blit = { - cpu_blit_blit_surface, - }; - --HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect_in, -- struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, -+void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect, -+ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) - { - struct wined3d_swapchain *src_swapchain, *dst_swapchain; - struct wined3d_device *device = dst_surface->resource.device; - DWORD src_ds_flags, dst_ds_flags; -- RECT src_rect, dst_rect; - BOOL scale, convert; - - static const DWORD simple_blit = WINEDDBLT_ASYNC -@@ -4865,111 +4864,6 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC - | WINEDDBLT_DONOTWAIT - | WINEDDBLT_ALPHATEST; - -- TRACE("dst_surface %p, dst_rect_in %s, src_surface %p, src_rect_in %s, flags %#x, fx %p, filter %s.\n", -- dst_surface, wine_dbgstr_rect(dst_rect_in), src_surface, wine_dbgstr_rect(src_rect_in), -- flags, fx, debug_d3dtexturefiltertype(filter)); -- TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage)); -- -- if (fx) -- { -- TRACE("dwSize %#x.\n", fx->dwSize); -- TRACE("dwDDFX %#x.\n", fx->dwDDFX); -- TRACE("dwROP %#x.\n", fx->dwROP); -- TRACE("dwDDROP %#x.\n", fx->dwDDROP); -- TRACE("dwRotationAngle %#x.\n", fx->dwRotationAngle); -- TRACE("dwZBufferOpCode %#x.\n", fx->dwZBufferOpCode); -- TRACE("dwZBufferLow %#x.\n", fx->dwZBufferLow); -- TRACE("dwZBufferHigh %#x.\n", fx->dwZBufferHigh); -- TRACE("dwZBufferBaseDest %#x.\n", fx->dwZBufferBaseDest); -- TRACE("dwZDestConstBitDepth %#x.\n", fx->dwZDestConstBitDepth); -- TRACE("lpDDSZBufferDest %p.\n", fx->u1.lpDDSZBufferDest); -- TRACE("dwZSrcConstBitDepth %#x.\n", fx->dwZSrcConstBitDepth); -- TRACE("lpDDSZBufferSrc %p.\n", fx->u2.lpDDSZBufferSrc); -- TRACE("dwAlphaEdgeBlendBitDepth %#x.\n", fx->dwAlphaEdgeBlendBitDepth); -- TRACE("dwAlphaEdgeBlend %#x.\n", fx->dwAlphaEdgeBlend); -- TRACE("dwReserved %#x.\n", fx->dwReserved); -- TRACE("dwAlphaDestConstBitDepth %#x.\n", fx->dwAlphaDestConstBitDepth); -- TRACE("lpDDSAlphaDest %p.\n", fx->u3.lpDDSAlphaDest); -- TRACE("dwAlphaSrcConstBitDepth %#x.\n", fx->dwAlphaSrcConstBitDepth); -- TRACE("lpDDSAlphaSrc %p.\n", fx->u4.lpDDSAlphaSrc); -- TRACE("lpDDSPattern %p.\n", fx->u5.lpDDSPattern); -- TRACE("ddckDestColorkey {%#x, %#x}.\n", -- fx->ddckDestColorkey.color_space_low_value, -- fx->ddckDestColorkey.color_space_high_value); -- TRACE("ddckSrcColorkey {%#x, %#x}.\n", -- fx->ddckSrcColorkey.color_space_low_value, -- fx->ddckSrcColorkey.color_space_high_value); -- } -- -- if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) -- { -- WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); -- return WINEDDERR_SURFACEBUSY; -- } -- -- surface_get_rect(dst_surface, dst_rect_in, &dst_rect); -- -- if (dst_rect.left >= dst_rect.right || dst_rect.top >= dst_rect.bottom -- || dst_rect.left > dst_surface->resource.width || dst_rect.left < 0 -- || dst_rect.top > dst_surface->resource.height || dst_rect.top < 0 -- || dst_rect.right > dst_surface->resource.width || dst_rect.right < 0 -- || dst_rect.bottom > dst_surface->resource.height || dst_rect.bottom < 0) -- { -- WARN("The application gave us a bad destination rectangle.\n"); -- return WINEDDERR_INVALIDRECT; -- } -- -- if (src_surface) -- { -- surface_get_rect(src_surface, src_rect_in, &src_rect); -- -- if (src_rect.left >= src_rect.right || src_rect.top >= src_rect.bottom -- || src_rect.left > src_surface->resource.width || src_rect.left < 0 -- || src_rect.top > src_surface->resource.height || src_rect.top < 0 -- || src_rect.right > src_surface->resource.width || src_rect.right < 0 -- || src_rect.bottom > src_surface->resource.height || src_rect.bottom < 0) -- { -- WARN("Application gave us bad source rectangle for Blt.\n"); -- return WINEDDERR_INVALIDRECT; -- } -- } -- else -- { -- memset(&src_rect, 0, sizeof(src_rect)); -- } -- -- if (!fx || !(fx->dwDDFX)) -- flags &= ~WINEDDBLT_DDFX; -- -- if (flags & WINEDDBLT_WAIT) -- flags &= ~WINEDDBLT_WAIT; -- -- if (flags & WINEDDBLT_ASYNC) -- { -- static unsigned int once; -- -- if (!once++) -- FIXME("Can't handle WINEDDBLT_ASYNC flag.\n"); -- flags &= ~WINEDDBLT_ASYNC; -- } -- -- /* WINEDDBLT_DONOTWAIT appeared in DX7. */ -- if (flags & WINEDDBLT_DONOTWAIT) -- { -- static unsigned int once; -- -- if (!once++) -- FIXME("Can't handle WINEDDBLT_DONOTWAIT flag.\n"); -- flags &= ~WINEDDBLT_DONOTWAIT; -- } -- -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- wined3d_cs_emit_glfinish(device->cs); -- device->cs->ops->finish(device->cs); -- } -- - if (!device->d3d_initialized) - { - WARN("D3D not initialized, using fallback.\n"); -@@ -5012,8 +4906,8 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC - } - - scale = src_surface -- && (src_rect.right - src_rect.left != dst_rect.right - dst_rect.left -- || src_rect.bottom - src_rect.top != dst_rect.bottom - dst_rect.top); -+ && (src_rect->right - src_rect->left != dst_rect->right - dst_rect->left -+ || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top); - convert = src_surface && src_surface->resource.format->id != dst_surface->resource.format->id; - - dst_ds_flags = dst_surface->container->resource.format_flags -@@ -5033,22 +4927,16 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC - TRACE("Depth fill.\n"); - - if (!surface_convert_depth_to_float(dst_surface, fx->u5.dwFillDepth, &depth)) -- return WINED3DERR_INVALIDCALL; -+ return; - -- if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, &dst_rect, depth))) -- return WINED3D_OK; -+ if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, dst_rect, depth))) -+ return; - } - else - { -- if (src_ds_flags != dst_ds_flags) -- { -- WARN("Rejecting depth / stencil blit between incompatible formats.\n"); -- return WINED3DERR_INVALIDCALL; -- } -- - if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->container->resource.draw_binding, -- &src_rect, dst_surface, dst_surface->container->resource.draw_binding, &dst_rect))) -- return WINED3D_OK; -+ src_rect, dst_surface, dst_surface->container->resource.draw_binding, dst_rect))) -+ return; - } - } - else -@@ -5079,8 +4967,8 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC - palette, fx->u5.dwFillColor, &color)) - goto fallback; - -- if (SUCCEEDED(surface_color_fill(dst_surface, &dst_rect, &color))) -- return WINED3D_OK; -+ if (SUCCEEDED(surface_color_fill(dst_surface, dst_rect, &color))) -+ return; - } - else - { -@@ -5112,9 +5000,9 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC - TRACE("Not doing upload because of format conversion.\n"); - else - { -- POINT dst_point = {dst_rect.left, dst_rect.top}; -+ POINT dst_point = {dst_rect->left, dst_rect->top}; - -- if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, &src_rect))) -+ if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, src_rect))) - { - if (!wined3d_resource_is_offscreen(&dst_surface->container->resource)) - { -@@ -5123,7 +5011,7 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC - dst_surface->container->resource.draw_binding); - context_release(context); - } -- return WINED3D_OK; -+ return; - } - } - } -@@ -5147,51 +5035,194 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC - wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, NULL, 0); - dst_swapchain->desc.swap_effect = swap_effect; - -- return WINED3D_OK; -+ return; - } - - if (fbo_blit_supported(&device->adapter->gl_info, blit_op, -- &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, -- &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format)) -+ src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, -+ dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format)) - { - struct wined3d_context *context; - TRACE("Using FBO blit.\n"); - - context = context_acquire(device, NULL); - surface_blt_fbo(device, context, filter, -- src_surface, src_surface->container->resource.draw_binding, &src_rect, -- dst_surface, dst_surface->container->resource.draw_binding, &dst_rect); -+ src_surface, src_surface->container->resource.draw_binding, src_rect, -+ dst_surface, dst_surface->container->resource.draw_binding, dst_rect); - context_release(context); - - wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); - wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding); - -- return WINED3D_OK; -+ return; - } - - blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, blit_op, -- &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, -- &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format); -+ src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, -+ dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format); - if (blitter) - { - blitter->blit_surface(device, blit_op, filter, src_surface, -- &src_rect, dst_surface, &dst_rect, color_key); -- return WINED3D_OK; -+ src_rect, dst_surface, dst_rect, color_key); -+ return; - } - } - } - - fallback: - /* Special cases for render targets. */ -- if (SUCCEEDED(surface_blt_special(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter))) -- return WINED3D_OK; -+ if ((dst_surface->resource.usage & WINED3DUSAGE_RENDERTARGET) -+ || (src_surface && (src_surface->resource.usage & WINED3DUSAGE_RENDERTARGET))) -+ { -+ if (SUCCEEDED(surface_blt_special(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter))) -+ return; -+ } - - cpu: - - /* For the rest call the X11 surface implementation. For render targets - * this should be implemented OpenGL accelerated in surface_blt_special(), - * other blits are rather rare. */ -- return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter); -+ surface_cpu_blt(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter); -+ return; -+} -+ -+HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect_in, -+ struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, -+ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) -+{ -+ struct wined3d_device *device = dst_surface->resource.device; -+ RECT src_rect, dst_rect; -+ -+ TRACE("dst_surface %p, dst_rect_in %s, src_surface %p, src_rect_in %s, flags %#x, fx %p, filter %s.\n", -+ dst_surface, wine_dbgstr_rect(dst_rect_in), src_surface, wine_dbgstr_rect(src_rect_in), -+ flags, fx, debug_d3dtexturefiltertype(filter)); -+ TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage)); -+ -+ if (fx) -+ { -+ TRACE("dwSize %#x.\n", fx->dwSize); -+ TRACE("dwDDFX %#x.\n", fx->dwDDFX); -+ TRACE("dwROP %#x.\n", fx->dwROP); -+ TRACE("dwDDROP %#x.\n", fx->dwDDROP); -+ TRACE("dwRotationAngle %#x.\n", fx->dwRotationAngle); -+ TRACE("dwZBufferOpCode %#x.\n", fx->dwZBufferOpCode); -+ TRACE("dwZBufferLow %#x.\n", fx->dwZBufferLow); -+ TRACE("dwZBufferHigh %#x.\n", fx->dwZBufferHigh); -+ TRACE("dwZBufferBaseDest %#x.\n", fx->dwZBufferBaseDest); -+ TRACE("dwZDestConstBitDepth %#x.\n", fx->dwZDestConstBitDepth); -+ TRACE("lpDDSZBufferDest %p.\n", fx->u1.lpDDSZBufferDest); -+ TRACE("dwZSrcConstBitDepth %#x.\n", fx->dwZSrcConstBitDepth); -+ TRACE("lpDDSZBufferSrc %p.\n", fx->u2.lpDDSZBufferSrc); -+ TRACE("dwAlphaEdgeBlendBitDepth %#x.\n", fx->dwAlphaEdgeBlendBitDepth); -+ TRACE("dwAlphaEdgeBlend %#x.\n", fx->dwAlphaEdgeBlend); -+ TRACE("dwReserved %#x.\n", fx->dwReserved); -+ TRACE("dwAlphaDestConstBitDepth %#x.\n", fx->dwAlphaDestConstBitDepth); -+ TRACE("lpDDSAlphaDest %p.\n", fx->u3.lpDDSAlphaDest); -+ TRACE("dwAlphaSrcConstBitDepth %#x.\n", fx->dwAlphaSrcConstBitDepth); -+ TRACE("lpDDSAlphaSrc %p.\n", fx->u4.lpDDSAlphaSrc); -+ TRACE("lpDDSPattern %p.\n", fx->u5.lpDDSPattern); -+ TRACE("ddckDestColorkey {%#x, %#x}.\n", -+ fx->ddckDestColorkey.color_space_low_value, -+ fx->ddckDestColorkey.color_space_high_value); -+ TRACE("ddckSrcColorkey {%#x, %#x}.\n", -+ fx->ddckSrcColorkey.color_space_low_value, -+ fx->ddckSrcColorkey.color_space_high_value); -+ } -+ -+ if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) -+ { -+ /* TODO: Separate application maps from internal maps */ -+ if (!wined3d_settings.cs_multithreaded) -+ { -+ WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); -+ return WINEDDERR_SURFACEBUSY; -+ } -+ -+ wined3d_cs_emit_glfinish(dst_surface->resource.device->cs); -+ dst_surface->resource.device->cs->ops->finish(dst_surface->resource.device->cs); -+ -+ if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) -+ { -+ WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); -+ return WINEDDERR_SURFACEBUSY; -+ } -+ } -+ -+ surface_get_rect(dst_surface, dst_rect_in, &dst_rect); -+ -+ if (dst_rect.left >= dst_rect.right || dst_rect.top >= dst_rect.bottom -+ || dst_rect.left > dst_surface->resource.width || dst_rect.left < 0 -+ || dst_rect.top > dst_surface->resource.height || dst_rect.top < 0 -+ || dst_rect.right > dst_surface->resource.width || dst_rect.right < 0 -+ || dst_rect.bottom > dst_surface->resource.height || dst_rect.bottom < 0) -+ { -+ WARN("The application gave us a bad destination rectangle.\n"); -+ return WINEDDERR_INVALIDRECT; -+ } -+ -+ if (src_surface) -+ { -+ DWORD src_ds_flags, dst_ds_flags; -+ -+ surface_get_rect(src_surface, src_rect_in, &src_rect); -+ -+ if (src_rect.left >= src_rect.right || src_rect.top >= src_rect.bottom -+ || src_rect.left > src_surface->resource.width || src_rect.left < 0 -+ || src_rect.top > src_surface->resource.height || src_rect.top < 0 -+ || src_rect.right > src_surface->resource.width || src_rect.right < 0 -+ || src_rect.bottom > src_surface->resource.height || src_rect.bottom < 0) -+ { -+ WARN("Application gave us bad source rectangle for Blt.\n"); -+ return WINEDDERR_INVALIDRECT; -+ } -+ -+ dst_ds_flags = dst_surface->container->resource.format_flags -+ & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); -+ src_ds_flags = src_surface->container->resource.format_flags -+ & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); -+ if (src_ds_flags != dst_ds_flags) -+ { -+ WARN("Rejecting depth / stencil blit between incompatible formats.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ } -+ else -+ { -+ memset(&src_rect, 0, sizeof(src_rect)); -+ } -+ -+ if (!fx || !(fx->dwDDFX)) -+ flags &= ~WINEDDBLT_DDFX; -+ -+ if (flags & WINEDDBLT_WAIT) -+ flags &= ~WINEDDBLT_WAIT; -+ -+ if (flags & WINEDDBLT_ASYNC) -+ { -+ static unsigned int once; -+ -+ if (!once++) -+ FIXME("Can't handle WINEDDBLT_ASYNC flag.\n"); -+ flags &= ~WINEDDBLT_ASYNC; -+ } -+ -+ /* WINEDDBLT_DONOTWAIT appeared in DX7. */ -+ if (flags & WINEDDBLT_DONOTWAIT) -+ { -+ static unsigned int once; -+ -+ if (!once++) -+ FIXME("Can't handle WINEDDBLT_DONOTWAIT flag.\n"); -+ flags &= ~WINEDDBLT_DONOTWAIT; -+ } -+ -+ TRACE("Emitting blit %p <== %p\n", dst_surface, src_surface); -+ wined3d_cs_emit_blt(device->cs, dst_surface, &dst_rect, src_surface, &src_rect, -+ flags, fx, filter); -+ -+ return WINED3D_OK; - } - - static const struct wined3d_resource_ops surface_resource_ops = -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 9979cb0..cca82ab 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2522,6 +2522,9 @@ void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN; - void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, - const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, - BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; -+void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect_in, -+ struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, -+ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; - - void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, - const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -@@ -2669,6 +2672,7 @@ struct wined3d_cs - struct wined3d_device *device; - struct wined3d_state state; - HANDLE thread; -+ DWORD thread_id; - DWORD tls_idx; - struct wined3d_surface *onscreen_depth_stencil; - -@@ -2747,6 +2751,10 @@ void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, - GLenum primitive_type) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enable) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surface, -+ const RECT *dst_rect, struct wined3d_surface *src_surface, -+ const RECT *src_rect, DWORD flags, const WINEDDBLTFX *fx, -+ enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0068-wined3d-Don-t-force-strict-draw-ordering-for-multith.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0068-wined3d-Don-t-force-strict-draw-ordering-for-multith.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0068-wined3d-Don-t-force-strict-draw-ordering-for-multith.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0068-wined3d-Don-t-force-strict-draw-ordering-for-multith.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,26 @@ +From 6464090c8161886fba8637324b7714d67accf7c9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Jul 2013 21:00:17 +0200 +Subject: wined3d: Don't force strict draw ordering for multithreaded CS + +Shouldn't be needed any more +--- + dlls/wined3d/wined3d_main.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c +index 5471e6e..e6dc444 100644 +--- a/dlls/wined3d/wined3d_main.c ++++ b/dlls/wined3d/wined3d_main.c +@@ -310,8 +310,6 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) + { + TRACE("Enabling multithreaded command stream.\n"); + wined3d_settings.cs_multithreaded = TRUE; +- TRACE("Enforcing strict draw ordering for multithreaded command stream.\n"); +- wined3d_settings.strict_draw_ordering = TRUE; + } + } + +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0068-wined3d-Put-update_surface-checks-back-in-place.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0068-wined3d-Put-update_surface-checks-back-in-place.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0068-wined3d-Put-update_surface-checks-back-in-place.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0068-wined3d-Put-update_surface-checks-back-in-place.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,127 +0,0 @@ -From 843b306004f731e36e9d9d9336228cd2c06f9128 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 20 Aug 2014 14:14:23 +0200 -Subject: wined3d: Put update_surface checks back in place - -Unfortunately I can't remove the code from surface_update_from_surface -yet because blits depend on them. ---- - dlls/wined3d/device.c | 68 ++++++++++++++++++++++++++++++++++++++++++ - dlls/wined3d/surface.c | 2 +- - dlls/wined3d/wined3d_private.h | 1 + - 3 files changed, 70 insertions(+), 1 deletion(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 819e6de..e804afe 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -3773,6 +3773,13 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, - struct wined3d_surface *src_surface, const RECT *src_rect, - struct wined3d_surface *dst_surface, const POINT *dst_point) - { -+ const struct wined3d_format *src_format = src_surface->resource.format; -+ const struct wined3d_format *dst_format = dst_surface->resource.format; -+ UINT update_w, update_h; -+ UINT dst_w, dst_h; -+ RECT r, dst_rect; -+ POINT p; -+ - TRACE("device %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s.\n", - device, src_surface, wine_dbgstr_rect(src_rect), - dst_surface, wine_dbgstr_point(dst_point)); -@@ -3784,6 +3791,67 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, - return WINED3DERR_INVALIDCALL; - } - -+ if (src_format->id != dst_format->id) -+ { -+ WARN("Source and destination surfaces should have the same format.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ if (!dst_point) -+ { -+ p.x = 0; -+ p.y = 0; -+ dst_point = &p; -+ } -+ else if (dst_point->x < 0 || dst_point->y < 0) -+ { -+ WARN("Invalid destination point.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ if (!src_rect) -+ { -+ r.left = 0; -+ r.top = 0; -+ r.right = src_surface->resource.width; -+ r.bottom = src_surface->resource.height; -+ src_rect = &r; -+ } -+ else if (src_rect->left < 0 || src_rect->left >= src_rect->right -+ || src_rect->top < 0 || src_rect->top >= src_rect->bottom) -+ { -+ WARN("Invalid source rectangle.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ dst_w = dst_surface->resource.width; -+ dst_h = dst_surface->resource.height; -+ -+ update_w = src_rect->right - src_rect->left; -+ update_h = src_rect->bottom - src_rect->top; -+ -+ if (update_w > dst_w || dst_point->x > dst_w - update_w -+ || update_h > dst_h || dst_point->y > dst_h - update_h) -+ { -+ WARN("Destination out of bounds.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ if ((src_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) -+ && !surface_check_block_align_rect(src_surface, src_rect)) -+ { -+ WARN("Source rectangle not block-aligned.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ SetRect(&dst_rect, dst_point->x, dst_point->y, dst_point->x + update_w, dst_point->y + update_h); -+ if ((dst_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) -+ && !surface_check_block_align_rect(dst_surface, &dst_rect)) -+ { -+ WARN("Destination rectangle not block-aligned.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ - if (wined3d_settings.cs_multithreaded) - { - FIXME("Waiting for cs.\n"); -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 2d98a93..5a2b14e 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -1371,7 +1371,7 @@ static BOOL surface_check_block_align(struct wined3d_surface *surface, const str - return wined3d_resource_check_block_align(&surface->resource, box); - } - --static BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) -+BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) - { - struct wined3d_box box = {rect->left, rect->top, rect->right, rect->bottom, 0, 1}; - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 73da744..99212de 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2494,6 +2494,7 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w - void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect_in, - struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, - const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -+BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) DECLSPEC_HIDDEN; - - void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, - const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; --- -2.6.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0069-wined3d-Get-rid-of-WINED3D_BUFFER_FLUSH.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0069-wined3d-Get-rid-of-WINED3D_BUFFER_FLUSH.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0069-wined3d-Get-rid-of-WINED3D_BUFFER_FLUSH.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0069-wined3d-Get-rid-of-WINED3D_BUFFER_FLUSH.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -From 7a25ed307d8aa08209a3e56ad4aa0bfc5995a5f3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 7 May 2013 14:53:48 +0200 -Subject: wined3d: Get rid of WINED3D_BUFFER_FLUSH - ---- - dlls/wined3d/buffer.c | 13 +++++-------- - 1 file changed, 5 insertions(+), 8 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index d2c1d62..5544640 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -32,10 +32,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); - #define WINED3D_BUFFER_HASDESC 0x01 /* A vertex description has been found. */ - #define WINED3D_BUFFER_CREATEBO 0x02 /* Create a buffer object for this buffer. */ - #define WINED3D_BUFFER_DOUBLEBUFFER 0x04 /* Keep both a buffer object and a system memory copy for this buffer. */ --#define WINED3D_BUFFER_FLUSH 0x08 /* Manual unmap flushing. */ --#define WINED3D_BUFFER_DISCARD 0x10 /* A DISCARD lock has occurred since the last preload. */ --#define WINED3D_BUFFER_SYNC 0x20 /* There has been at least one synchronized map since the last preload. */ --#define WINED3D_BUFFER_APPLESYNC 0x40 /* Using sync as in GL_APPLE_flush_buffer_range. */ -+#define WINED3D_BUFFER_DISCARD 0x08 /* A DISCARD lock has occurred since the last preload. */ -+#define WINED3D_BUFFER_SYNC 0x10 /* There has been at least one synchronized map since the last preload. */ -+#define WINED3D_BUFFER_APPLESYNC 0x20 /* Using sync as in GL_APPLE_flush_buffer_range. */ - - #define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */ - #define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */ -@@ -167,8 +166,6 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine - { - GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); - checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)"); -- This->flags |= WINED3D_BUFFER_FLUSH; -- - GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); - checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)"); - This->flags |= WINED3D_BUFFER_APPLESYNC; -@@ -707,7 +704,7 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined - GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len)); - checkGLcall("glFlushMappedBufferRange"); - } -- else if (This->flags & WINED3D_BUFFER_FLUSH) -+ else if (This->flags & WINED3D_BUFFER_APPLESYNC) - { - GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len)); - checkGLcall("glFlushMappedBufferRangeAPPLE"); -@@ -1112,7 +1109,7 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) - checkGLcall("glFlushMappedBufferRange"); - } - } -- else if (buffer->flags & WINED3D_BUFFER_FLUSH) -+ else if (buffer->flags & WINED3D_BUFFER_APPLESYNC) - { - for (i = 0; i < buffer->modified_areas; ++i) - { --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0069-wined3d-Send-render-target-view-clears-through-the-c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0069-wined3d-Send-render-target-view-clears-through-the-c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0069-wined3d-Send-render-target-view-clears-through-the-c.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0069-wined3d-Send-render-target-view-clears-through-the-c.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,118 @@ +From 793b7f174651b67263e170e1144b3c293eac651f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Jul 2013 21:10:16 +0200 +Subject: wined3d: Send render target view clears through the command stream + +--- + dlls/wined3d/cs.c | 36 ++++++++++++++++++++++++++++++++++++ + dlls/wined3d/device.c | 12 ++---------- + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 40 insertions(+), 10 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index dcaedfd..366a4d3 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -74,6 +74,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_SET_LIGHT, + WINED3D_CS_OP_SET_LIGHT_ENABLE, + WINED3D_CS_OP_BLT, ++ WINED3D_CS_OP_CLEAR_RTV, + WINED3D_CS_OP_STOP, + }; + +@@ -343,6 +344,14 @@ struct wined3d_cs_blt + enum wined3d_texture_filter_type filter; + }; + ++struct wined3d_cs_clear_rtv ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_rendertarget_view *view; ++ RECT rect; ++ struct wined3d_color color; ++}; ++ + /* FIXME: The list synchronization probably isn't particularly fast. */ + static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) + { +@@ -1652,6 +1661,32 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf + cs->ops->submit(cs); + } + ++static UINT wined3d_cs_exec_clear_rtv(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_clear_rtv *op = data; ++ struct wined3d_resource *resource = op->view->resource; ++ ++ resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), op->view->sub_resource_idx); ++ ++ surface_color_fill(surface_from_resource(resource), &op->rect, &op->color); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, ++ const RECT *rect, const struct wined3d_color *color) ++{ ++ struct wined3d_cs_clear_rtv *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_CLEAR_RTV; ++ op->view = view; ++ op->rect = *rect; ++ op->color = *color; ++ ++ cs->ops->submit(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, +@@ -1692,6 +1727,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, + /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, + /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, ++ /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, + }; + + static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 599a25d..b2e7ec3 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -3917,16 +3917,8 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi + rect = &r; + } + +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- wined3d_cs_emit_glfinish(device->cs); +- device->cs->ops->finish(device->cs); +- } +- +- resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), view->sub_resource_idx); +- +- return surface_color_fill(surface_from_resource(resource), rect, color); ++ wined3d_cs_emit_clear_rtv(device->cs, view, rect, color); ++ return WINED3D_OK; + } + + struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(const struct wined3d_device *device, +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 0d76377..e554099 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2638,6 +2638,8 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf + const RECT *dst_rect, struct wined3d_surface *src_surface, + const RECT *src_rect, DWORD flags, const WINEDDBLTFX *fx, + enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, ++ const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0070-wined3d-Don-t-force-strict-draw-ordering-for-multith.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0070-wined3d-Don-t-force-strict-draw-ordering-for-multith.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0070-wined3d-Don-t-force-strict-draw-ordering-for-multith.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0070-wined3d-Don-t-force-strict-draw-ordering-for-multith.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -From 6464090c8161886fba8637324b7714d67accf7c9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Jul 2013 21:00:17 +0200 -Subject: wined3d: Don't force strict draw ordering for multithreaded CS - -Shouldn't be needed any more ---- - dlls/wined3d/wined3d_main.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c -index 5471e6e..e6dc444 100644 ---- a/dlls/wined3d/wined3d_main.c -+++ b/dlls/wined3d/wined3d_main.c -@@ -310,8 +310,6 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) - { - TRACE("Enabling multithreaded command stream.\n"); - wined3d_settings.cs_multithreaded = TRUE; -- TRACE("Enforcing strict draw ordering for multithreaded command stream.\n"); -- wined3d_settings.strict_draw_ordering = TRUE; - } - } - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0070-wined3d-Wait-for-the-CS-in-GetDC.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0070-wined3d-Wait-for-the-CS-in-GetDC.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0070-wined3d-Wait-for-the-CS-in-GetDC.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0070-wined3d-Wait-for-the-CS-in-GetDC.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,37 @@ +From d7b34fde19f7788ee528276df9231e9658b2adbc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 26 Sep 2013 16:40:34 +0200 +Subject: wined3d: Wait for the CS in GetDC. + +--- + dlls/wined3d/texture.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index efb134b..fddbe93 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -1552,6 +1552,20 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i + + surface = surface_from_resource(sub_resource); + ++ if (!(surface->container->resource.format_flags & WINED3DFMT_FLAG_GETDC)) ++ { ++ WARN("Cannot use GetDC on a %s surface.\n", debug_d3dformat(surface->resource.format->id)); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ if (wined3d_settings.cs_multithreaded) ++ { ++ struct wined3d_device *device = surface->resource.device; ++ FIXME("Waiting for cs.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + /* Give more detailed info for ddraw. */ + if (surface->flags & SFLAG_DCINUSE) + return WINEDDERR_DCALREADYCREATED; +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0071-wined3d-Send-render-target-view-clears-through-the-c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0071-wined3d-Send-render-target-view-clears-through-the-c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0071-wined3d-Send-render-target-view-clears-through-the-c.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0071-wined3d-Send-render-target-view-clears-through-the-c.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -From 793b7f174651b67263e170e1144b3c293eac651f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Jul 2013 21:10:16 +0200 -Subject: wined3d: Send render target view clears through the command stream - ---- - dlls/wined3d/cs.c | 36 ++++++++++++++++++++++++++++++++++++ - dlls/wined3d/device.c | 12 ++---------- - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 40 insertions(+), 10 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index dcaedfd..366a4d3 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -74,6 +74,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_SET_LIGHT, - WINED3D_CS_OP_SET_LIGHT_ENABLE, - WINED3D_CS_OP_BLT, -+ WINED3D_CS_OP_CLEAR_RTV, - WINED3D_CS_OP_STOP, - }; - -@@ -343,6 +344,14 @@ struct wined3d_cs_blt - enum wined3d_texture_filter_type filter; - }; - -+struct wined3d_cs_clear_rtv -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_rendertarget_view *view; -+ RECT rect; -+ struct wined3d_color color; -+}; -+ - /* FIXME: The list synchronization probably isn't particularly fast. */ - static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) - { -@@ -1652,6 +1661,32 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf - cs->ops->submit(cs); - } - -+static UINT wined3d_cs_exec_clear_rtv(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_clear_rtv *op = data; -+ struct wined3d_resource *resource = op->view->resource; -+ -+ resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), op->view->sub_resource_idx); -+ -+ surface_color_fill(surface_from_resource(resource), &op->rect, &op->color); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, -+ const RECT *rect, const struct wined3d_color *color) -+{ -+ struct wined3d_cs_clear_rtv *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_CLEAR_RTV; -+ op->view = view; -+ op->rect = *rect; -+ op->color = *color; -+ -+ cs->ops->submit(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, -@@ -1692,6 +1727,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, - /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, - /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, -+ /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, - }; - - static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 599a25d..b2e7ec3 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -3917,16 +3917,8 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi - rect = &r; - } - -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- wined3d_cs_emit_glfinish(device->cs); -- device->cs->ops->finish(device->cs); -- } -- -- resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), view->sub_resource_idx); -- -- return surface_color_fill(surface_from_resource(resource), rect, color); -+ wined3d_cs_emit_clear_rtv(device->cs, view, rect, color); -+ return WINED3D_OK; - } - - struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(const struct wined3d_device *device, -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 0d76377..e554099 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2638,6 +2638,8 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf - const RECT *dst_rect, struct wined3d_surface *src_surface, - const RECT *src_rect, DWORD flags, const WINEDDBLTFX *fx, - enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, -+ const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0071-wined3d-send-resource-maps-through-the-command-strea.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0071-wined3d-send-resource-maps-through-the-command-strea.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0071-wined3d-send-resource-maps-through-the-command-strea.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0071-wined3d-send-resource-maps-through-the-command-strea.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,275 @@ +From fb342d2c58b51885f224b1e4a8a9805fa319fbe6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 26 Sep 2013 16:41:00 +0200 +Subject: wined3d: send resource maps through the command stream + +Slow version only. Good enough to dodge some Nvidia bugs in the ddraw tests. +--- + dlls/wined3d/cs.c | 69 ++++++++++++++++++++++++++++++++++++ + dlls/wined3d/resource.c | 79 ++++++++++++++++++++++++------------------ + dlls/wined3d/wined3d_private.h | 5 +++ + 3 files changed, 120 insertions(+), 33 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 636ff0d..a5d5bde 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -76,6 +76,8 @@ enum wined3d_cs_op + WINED3D_CS_OP_SET_LIGHT_ENABLE, + WINED3D_CS_OP_BLT, + WINED3D_CS_OP_CLEAR_RTV, ++ WINED3D_CS_OP_RESOURCE_MAP, ++ WINED3D_CS_OP_RESOURCE_UNMAP, + WINED3D_CS_OP_STOP, + }; + +@@ -362,6 +364,20 @@ struct wined3d_cs_clear_rtv + struct wined3d_color color; + }; + ++struct wined3d_cs_resource_map ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_resource *resource; ++ DWORD flags; ++ void **mem; ++}; ++ ++struct wined3d_cs_resource_unmap ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_resource *resource; ++}; ++ + /* FIXME: The list synchronization probably isn't particularly fast. */ + static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) + { +@@ -1801,6 +1817,57 @@ void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarge + cs->ops->submit(cs); + } + ++static UINT wined3d_cs_exec_resource_map(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_resource_map *op = data; ++ ++ *op->mem = wined3d_resource_map_internal(op->resource, op->flags); ++ ++ return sizeof(*op); ++} ++ ++void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, ++ DWORD flags) ++{ ++ struct wined3d_cs_resource_map *op; ++ void *ret; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_RESOURCE_MAP; ++ op->resource = resource; ++ op->flags = flags; ++ op->mem = &ret; ++ ++ cs->ops->finish(cs); ++ ++ if (flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD)) ++ { ++ FIXME("Dynamic resource map is inefficient\n"); ++ } ++ return ret; ++} ++ ++static UINT wined3d_cs_exec_resource_unmap(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_resource_unmap *op = data; ++ struct wined3d_resource *resource = op->resource; ++ ++ wined3d_resource_unmap_internal(resource); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) ++{ ++ struct wined3d_cs_resource_unmap *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_RESOURCE_UNMAP; ++ op->resource = resource; ++ ++ cs->ops->submit(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, +@@ -1843,6 +1910,8 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, + /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, + /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, ++ /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, ++ /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, + }; + + static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index fb84a0f..e1ae8d4 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -792,32 +792,11 @@ BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, + return TRUE; + } + +-HRESULT wined3d_resource_map(struct wined3d_resource *resource, +- struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) ++void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD flags) + { + struct wined3d_device *device = resource->device; + struct wined3d_context *context = NULL; +- BYTE *base_memory; +- const struct wined3d_format *format = resource->format; +- const unsigned int fmt_flags = resource->format->flags[WINED3D_GL_RES_TYPE_TEX_2D]; +- +- TRACE("resource %p, map_desc %p, box %s, flags %#x.\n", +- resource, map_desc, debug_box(box), flags); +- +- if (resource->map_count) +- { +- WARN("Volume is already mapped.\n"); +- return WINED3DERR_INVALIDCALL; +- } +- +- flags = wined3d_resource_sanitize_map_flags(resource, flags); +- +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- wined3d_cs_emit_glfinish(device->cs); +- device->cs->ops->finish(device->cs); +- } ++ void *mem; + + if (device->d3d_initialized) + context = context_acquire(device, NULL); +@@ -825,9 +804,8 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, + if (!wined3d_resource_prepare_map_memory(resource, context)) + { + WARN("Out of memory.\n"); +- map_desc->data = NULL; + context_release(context); +- return E_OUTOFMEMORY; ++ return NULL; + } + + if (flags & WINED3D_MAP_DISCARD) +@@ -835,11 +813,40 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, + else + wined3d_resource_load_location(resource, context, resource->map_binding); + +- base_memory = wined3d_resource_get_map_ptr(resource, context, flags); ++ mem = wined3d_resource_get_map_ptr(resource, context, flags); + + if (context) + context_release(context); + ++ return mem; ++} ++ ++HRESULT wined3d_resource_map(struct wined3d_resource *resource, ++ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) ++{ ++ struct wined3d_device *device = resource->device; ++ BYTE *base_memory; ++ const struct wined3d_format *format = resource->format; ++ const unsigned int fmt_flags = resource->format->flags[WINED3D_GL_RES_TYPE_TEX_2D]; ++ ++ TRACE("resource %p, map_desc %p, box %s, flags %#x.\n", ++ resource, map_desc, debug_box(box), flags); ++ ++ if (resource->map_count) ++ { ++ WARN("Volume is already mapped.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ flags = wined3d_resource_sanitize_map_flags(resource, flags); ++ ++ base_memory = wined3d_cs_emit_resource_map(device->cs, resource, flags); ++ if (!base_memory) ++ { ++ WARN("Map failed.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ + TRACE("Base memory pointer %p.\n", base_memory); + + if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) +@@ -887,10 +894,21 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, + return WINED3D_OK; + } + +-HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) ++void wined3d_resource_unmap_internal(struct wined3d_resource *resource) + { + struct wined3d_device *device = resource->device; + struct wined3d_context *context = NULL; ++ ++ if (device->d3d_initialized) ++ context = context_acquire(device, NULL); ++ wined3d_resource_release_map_ptr(resource, context); ++ if (context) ++ context_release(context); ++} ++ ++HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) ++{ ++ struct wined3d_device *device = resource->device; + TRACE("resource %p.\n", resource); + + if (!resource->map_count) +@@ -899,12 +917,7 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) + return WINEDDERR_NOTLOCKED; + } + +- if (device->d3d_initialized) +- context = context_acquire(device, NULL); +- wined3d_resource_release_map_ptr(resource, context); +- if (context) +- context_release(context); +- ++ wined3d_cs_emit_resource_unmap(device->cs, resource); + resource->map_count--; + + return WINED3D_OK; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 18fae74..bbbccdd 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2350,6 +2350,7 @@ void wined3d_resource_load_location(struct wined3d_resource *resource, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; + HRESULT wined3d_resource_map(struct wined3d_resource *resource, struct wined3d_map_desc *map_desc, + const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; ++void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; + BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource, + struct wined3d_context *context) DECLSPEC_HIDDEN; + BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) DECLSPEC_HIDDEN; +@@ -2357,6 +2358,7 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, + const struct wined3d_context *context) DECLSPEC_HIDDEN; + DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; + HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++void wined3d_resource_unmap_internal(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_validate_location(struct wined3d_resource *resource, DWORD location) DECLSPEC_HIDDEN; + +@@ -2844,6 +2846,9 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf + enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; + void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, + const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; ++void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, ++ DWORD flags) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0072-wined3d-Get-rid-of-the-end_scene-flush-and-finish.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0072-wined3d-Get-rid-of-the-end_scene-flush-and-finish.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0072-wined3d-Get-rid-of-the-end_scene-flush-and-finish.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0072-wined3d-Get-rid-of-the-end_scene-flush-and-finish.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,45 @@ +From 907befb9104d166a5423d92c8aec0e8d6835bb92 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Jul 2013 22:59:33 +0200 +Subject: wined3d: Get rid of the end_scene flush and finish + +Either keep the patch this way, or send a flush through the CS. I'm not +sure it's worth it though, this has never had any real performance +impact. +--- + dlls/wined3d/device.c | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index b2e7ec3..cd90c76 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -3224,8 +3224,6 @@ HRESULT CDECL wined3d_device_begin_scene(struct wined3d_device *device) + + HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) + { +- struct wined3d_context *context; +- + TRACE("device %p.\n", device); + + if (!device->inScene) +@@ -3234,16 +3232,6 @@ HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) + return WINED3DERR_INVALIDCALL; + } + +- context = context_acquire(device, NULL); +- /* We only have to do this if we need to read the, swapbuffers performs a flush for us */ +- if (wined3d_settings.cs_multithreaded) +- context->gl_info->gl_ops.gl.p_glFinish(); +- else +- context->gl_info->gl_ops.gl.p_glFlush(); +- /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever +- * fails. */ +- context_release(context); +- + device->inScene = FALSE; + return WINED3D_OK; + } +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0072-wined3d-Wait-for-the-CS-in-GetDC.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0072-wined3d-Wait-for-the-CS-in-GetDC.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0072-wined3d-Wait-for-the-CS-in-GetDC.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0072-wined3d-Wait-for-the-CS-in-GetDC.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -From 6abbf0a97d9e72b5f599f48c5a591a0d2917eee6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 26 Sep 2013 16:40:34 +0200 -Subject: wined3d: Wait for the CS in GetDC. - ---- - dlls/wined3d/surface.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index bef62bb..3653626 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -2548,6 +2548,20 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) - - TRACE("surface %p, dc %p.\n", surface, dc); - -+ if (!(surface->container->resource.format_flags & WINED3DFMT_FLAG_GETDC)) -+ { -+ WARN("Cannot use GetDC on a %s surface.\n", debug_d3dformat(surface->resource.format->id)); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ if (wined3d_settings.cs_multithreaded) -+ { -+ struct wined3d_device *device = surface->resource.device; -+ FIXME("Waiting for cs.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - /* Give more detailed info for ddraw. */ - if (surface->flags & SFLAG_DCINUSE) - return WINEDDERR_DCALREADYCREATED; --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0073-wined3d-Replace-the-linked-lists-with-a-ringbuffer.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0073-wined3d-Replace-the-linked-lists-with-a-ringbuffer.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0073-wined3d-Replace-the-linked-lists-with-a-ringbuffer.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0073-wined3d-Replace-the-linked-lists-with-a-ringbuffer.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,852 @@ +From c115a25b8aba4ade5fa04cfb469b030eb29b941a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Jul 2013 23:33:14 +0200 +Subject: wined3d: Replace the linked lists with a ringbuffer + +--- + dlls/wined3d/cs.c | 362 ++++++++++++++++++----------------------- + dlls/wined3d/wined3d_private.h | 20 +-- + 2 files changed, 162 insertions(+), 220 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 6204e57..66c784b 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -22,20 +22,10 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(d3d); + +-#define WINED3D_INITIAL_CS_SIZE 4096 +- +-static CRITICAL_SECTION wined3d_cs_list_mutex; +-static CRITICAL_SECTION_DEBUG wined3d_cs_list_mutex_debug = +-{ +- 0, 0, &wined3d_cs_list_mutex, +- {&wined3d_cs_list_mutex_debug.ProcessLocksList, +- &wined3d_cs_list_mutex_debug.ProcessLocksList}, +- 0, 0, {(DWORD_PTR)(__FILE__ ": wined3d_cs_list_mutex")} +-}; +-static CRITICAL_SECTION wined3d_cs_list_mutex = {&wined3d_cs_list_mutex_debug, -1, 0, 0, 0, 0}; +- + enum wined3d_cs_op + { ++ WINED3D_CS_OP_NOP, ++ WINED3D_CS_OP_SKIP, + WINED3D_CS_OP_FENCE, + WINED3D_CS_OP_PRESENT, + WINED3D_CS_OP_CLEAR, +@@ -378,99 +368,30 @@ struct wined3d_cs_resource_unmap + struct wined3d_resource *resource; + }; + +-/* FIXME: The list synchronization probably isn't particularly fast. */ +-static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) +-{ +- EnterCriticalSection(&wined3d_cs_list_mutex); +- list_add_tail(&list->blocks, &block->entry); +- LeaveCriticalSection(&wined3d_cs_list_mutex); +-} +- +-static struct wined3d_cs_block *wined3d_cs_list_dequeue(struct wined3d_cs_list *list) +-{ +- struct list *head; +- +- EnterCriticalSection(&wined3d_cs_list_mutex); +- if (!(head = list_head(&list->blocks))) +- { +- LeaveCriticalSection(&wined3d_cs_list_mutex); +- return NULL; +- } +- list_remove(head); +- LeaveCriticalSection(&wined3d_cs_list_mutex); +- +- return LIST_ENTRY(head, struct wined3d_cs_block, entry); +-} +- +-static struct wined3d_cs_block *wined3d_cs_list_dequeue_blocking(struct wined3d_cs_list *list) +-{ +- struct wined3d_cs_block *block; +- +- /* FIXME: Use an event to wait after a couple of spins. */ +- for (;;) +- { +- if ((block = wined3d_cs_list_dequeue(list))) +- return block; +- } +-} +- +-static void wined3d_cs_list_init(struct wined3d_cs_list *list) +-{ +- list_init(&list->blocks); +-} +- +-static struct wined3d_cs_block *wined3d_cs_get_thread_block(const struct wined3d_cs *cs) +-{ +- return TlsGetValue(cs->tls_idx); +-} +- +-static void wined3d_cs_set_thread_block(const struct wined3d_cs *cs, struct wined3d_cs_block *block) ++struct wined3d_cs_skip + { +- if (!TlsSetValue(cs->tls_idx, block)) +- ERR("Failed to set thread block.\n"); +-} ++ enum wined3d_cs_op opcode; ++ DWORD size; ++}; + +-static void wined3d_cs_flush(struct wined3d_cs *cs) ++static void wined3d_cs_submit(struct wined3d_cs *cs, size_t size) + { +- wined3d_cs_list_enqueue(&cs->exec_list, wined3d_cs_get_thread_block(cs)); +- wined3d_cs_set_thread_block(cs, NULL); ++ LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); ++ /* There is only one thread writing to queue.head, InterlockedExchange ++ * is used for the memory barrier. */ ++ InterlockedExchange(&cs->queue.head, new_val); + } + +-static struct wined3d_cs_block *wined3d_cs_get_block(struct wined3d_cs *cs) ++static UINT wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data) + { +- struct wined3d_cs_block *block; +- +- if (!(block = wined3d_cs_list_dequeue(&cs->free_list))) +- { +- if (!(block = HeapAlloc(GetProcessHeap(), 0, sizeof(*block)))) +- { +- ERR("Failed to get new block.\n"); +- return NULL; +- } +- } +- +- block->pos = 0; +- +- return block; ++ return sizeof(enum wined3d_cs_op); + } + +-static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) ++static UINT wined3d_cs_exec_skip(struct wined3d_cs *cs, const void *data) + { +- struct wined3d_cs_block *block = wined3d_cs_get_thread_block(cs); +- void *data; +- +- if (!block || block->pos + size > sizeof(block->data)) +- { +- if (block) +- wined3d_cs_flush(cs); +- block = wined3d_cs_get_block(cs); +- wined3d_cs_set_thread_block(cs, block); +- } ++ const struct wined3d_cs_skip *op = data; + +- data = &block->data[block->pos]; +- block->pos += size; +- +- return data; ++ return op->size; + } + + static UINT wined3d_cs_exec_fence(struct wined3d_cs *cs, const void *data) +@@ -491,14 +412,14 @@ static void wined3d_cs_emit_fence(struct wined3d_cs *cs, BOOL *signalled) + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_FENCE; + op->signalled = signalled; ++ cs->ops->submit(cs, sizeof(*op)); + } + +-static void wined3d_cs_flush_and_wait(struct wined3d_cs *cs) ++static void wined3d_cs_finish(struct wined3d_cs *cs) + { + BOOL fence; + + wined3d_cs_emit_fence(cs, &fence); +- wined3d_cs_flush(cs); + + /* A busy wait should be fine, we're not supposed to have to wait very + * long. */ +@@ -556,7 +477,7 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw + + pending = InterlockedIncrement(&cs->pending_presents); + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + + while (pending > 1) + pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0); +@@ -583,8 +504,9 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * + { + struct wined3d_cs_clear *op; + unsigned int extra_rects = rect_count ? rect_count - 1 : 0; ++ size_t size = sizeof(*op) + sizeof(*op->rects) * extra_rects; + +- op = cs->ops->require_space(cs, sizeof(*op) + sizeof(*op->rects) * extra_rects); ++ op = cs->ops->require_space(cs, size); + op->opcode = WINED3D_CS_OP_CLEAR; + op->rect_count = rect_count; + if (rect_count) +@@ -594,7 +516,7 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * + op->depth = depth; + op->stencil = stencil; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, size); + } + + static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) +@@ -635,7 +557,7 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun + op->instance_count = instance_count; + op->indexed = indexed; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data) +@@ -657,7 +579,7 @@ void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query + op->predicate = predicate; + op->value = value; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) +@@ -679,7 +601,7 @@ void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_vi + op->opcode = WINED3D_CS_OP_SET_VIEWPORT; + op->viewport = *viewport; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) +@@ -700,7 +622,7 @@ void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) + op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT; + op->rect = *rect; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) +@@ -723,7 +645,7 @@ void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int v + op->view_idx = view_idx; + op->view = view; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data) +@@ -776,7 +698,7 @@ void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3 + op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW; + op->view = view; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) +@@ -797,7 +719,7 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3 + op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION; + op->declaration = declaration; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) +@@ -834,7 +756,7 @@ void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, + op->offset = offset; + op->stride = stride; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) +@@ -861,7 +783,7 @@ void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_i + op->frequency = frequency; + op->flags = flags; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) +@@ -894,7 +816,7 @@ void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, + op->buffer = buffer; + op->offset = offset; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) +@@ -926,7 +848,7 @@ void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buff + op->buffer = buffer; + op->format_id = format_id; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) +@@ -957,7 +879,7 @@ void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_sha + op->cb_idx = cb_idx; + op->buffer = buffer; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) +@@ -1032,7 +954,7 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined + op->opcode = WINED3D_CS_OP_SET_TEXTURE; + op->stage = stage; + op->texture = texture; +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) +@@ -1056,7 +978,7 @@ void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3 + op->view_idx = view_idx; + op->view = view; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) +@@ -1080,7 +1002,7 @@ void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type + op->sampler_idx = sampler_idx; + op->sampler = sampler; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) +@@ -1102,6 +1024,8 @@ void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type + op->opcode = WINED3D_CS_OP_SET_SHADER; + op->type = type; + op->shader = shader; ++ ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_vs_consts_f(struct wined3d_cs *cs, const void *data) +@@ -1137,8 +1061,9 @@ void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, + { + struct wined3d_cs_set_consts_f *op; + UINT extra_space = vector4f_count - 1; ++ size_t size = sizeof(*op) + sizeof(op->constants) * extra_space; + +- op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); ++ op = cs->ops->require_space(cs, size); + switch (type) + { + case WINED3D_SHADER_TYPE_PIXEL: +@@ -1160,7 +1085,7 @@ void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, + op->vector4f_count = vector4f_count; + memcpy(op->constants, constants, sizeof(*constants) * 4 * vector4f_count); + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, size); + } + + static UINT wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) +@@ -1182,8 +1107,8 @@ void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render + op->state = state; + op->value = value; + +- cs->ops->submit(cs); +-}; ++ cs->ops->submit(cs, sizeof(*op)); ++} + + static UINT wined3d_cs_exec_set_vs_consts_b(struct wined3d_cs *cs, const void *data) + { +@@ -1216,8 +1141,9 @@ void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, + { + struct wined3d_cs_set_consts_b *op; + UINT extra_space = bool_count - 1; ++ size_t size = sizeof(*op) + sizeof(op->constants) * extra_space; + +- op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); ++ op = cs->ops->require_space(cs, size); + switch (type) + { + case WINED3D_SHADER_TYPE_PIXEL: +@@ -1239,7 +1165,7 @@ void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, + op->bool_count = bool_count; + memcpy(op->constants, constants, sizeof(op->constants) * bool_count); + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, size); + } + + static UINT wined3d_cs_exec_set_vs_consts_i(struct wined3d_cs *cs, const void *data) +@@ -1273,8 +1199,9 @@ void wined3d_cs_emit_set_consts_i(struct wined3d_cs *cs, UINT start_register, + { + struct wined3d_cs_set_consts_i *op; + UINT extra_space = vector4i_count - 1; ++ size_t size = sizeof(*op) + sizeof(op->constants) * extra_space; + +- op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); ++ op = cs->ops->require_space(cs, size); + switch (type) + { + case WINED3D_SHADER_TYPE_PIXEL: +@@ -1296,7 +1223,7 @@ void wined3d_cs_emit_set_consts_i(struct wined3d_cs *cs, UINT start_register, + op->vector4i_count = vector4i_count; + memcpy(op->constants, constants, sizeof(op->constants) * vector4i_count); + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, size); + } + + static UINT wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) +@@ -1320,7 +1247,7 @@ void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, + op->state = state; + op->value = value; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) +@@ -1344,7 +1271,7 @@ void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, + op->state = state; + op->value = value; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) +@@ -1368,7 +1295,7 @@ void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform + op->state = state; + op->matrix = *matrix; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) +@@ -1390,7 +1317,7 @@ void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const + op->plane_idx = plane_idx; + op->plane = *plane; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data) +@@ -1468,7 +1395,7 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture + else + op->set = 0; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) +@@ -1489,7 +1416,7 @@ void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_ma + op->opcode = WINED3D_CS_OP_SET_MATERIAL; + op->material = *material; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) +@@ -1513,7 +1440,7 @@ void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_RESET_STATE; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_glfinish(struct wined3d_cs *cs, const void *data) +@@ -1539,7 +1466,7 @@ void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_GLFINISH; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_base_vertex_index(struct wined3d_cs *cs, const void *data) +@@ -1561,7 +1488,7 @@ void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, + op->opcode = WINED3D_CS_OP_SET_BASE_VERTEX_INDEX; + op->base_vertex_index = base_vertex_index; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_primitive_type(struct wined3d_cs *cs, const void *data) +@@ -1587,7 +1514,7 @@ void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, GLenum primitive_ + op->opcode = WINED3D_CS_OP_SET_PRIMITIVE_TYPE; + op->gl_primitive_type = primitive_type; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) +@@ -1644,7 +1571,7 @@ void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light + op->opcode = WINED3D_CS_OP_SET_LIGHT; + op->light = *light; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_set_light_enable(struct wined3d_cs *cs, const void *data) +@@ -1733,7 +1660,7 @@ void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enab + op->idx = idx; + op->enable = enable; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_blt(struct wined3d_cs *cs, const void *data) +@@ -1765,7 +1692,7 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf + if (fx) + op->fx = *fx; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_clear_rtv(struct wined3d_cs *cs, const void *data) +@@ -1791,7 +1718,7 @@ void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarge + op->rect = *rect; + op->color = *color; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_resource_map(struct wined3d_cs *cs, const void *data) +@@ -1815,12 +1742,14 @@ void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resourc + op->flags = flags; + op->mem = &ret; + +- cs->ops->finish(cs); ++ cs->ops->submit(cs, sizeof(*op)); + + if (flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD)) + { + FIXME("Dynamic resource map is inefficient\n"); + } ++ cs->ops->finish(cs); ++ + return ret; + } + +@@ -1842,11 +1771,13 @@ void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resour + op->opcode = WINED3D_CS_OP_RESOURCE_UNMAP; + op->resource = resource; + +- cs->ops->submit(cs); ++ cs->ops->submit(cs, sizeof(*op)); + } + + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { ++ /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, ++ /* WINED3D_CS_OP_SKIP */ wined3d_cs_exec_skip, + /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, + /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, + /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, +@@ -1891,42 +1822,59 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, + }; + +-static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) ++static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) + { +- if (size > cs->data_size) ++ struct wined3d_cs_queue *queue = &cs->queue; ++ size_t queue_size = sizeof(queue->data) / sizeof(*queue->data); ++ ++ if (queue_size - size < queue->head) + { +- void *new_data; ++ struct wined3d_cs_skip *skip; ++ size_t nop_size = queue_size - queue->head; + +- size = max( size, cs->data_size * 2 ); +- if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size))) +- return NULL; ++ skip = wined3d_cs_mt_require_space(cs, nop_size); ++ if (nop_size < sizeof(*skip)) ++ { ++ skip->opcode = WINED3D_CS_OP_NOP; ++ } ++ else ++ { ++ skip->opcode = WINED3D_CS_OP_SKIP; ++ skip->size = nop_size; ++ } + +- cs->data_size = size; +- cs->data = new_data; ++ cs->ops->submit(cs, nop_size); ++ assert(!queue->head); + } + +- return cs->data; +-} ++ while(1) ++ { ++ LONG head = queue->head; ++ LONG tail = *((volatile LONG *)&queue->tail); ++ LONG new_pos; ++ /* Empty */ ++ if (head == tail) ++ break; ++ /* Head ahead of tail, take care of wrap-around */ ++ new_pos = (head + size) & (WINED3D_CS_QUEUE_SIZE - 1); ++ if (head > tail && (new_pos || tail)) ++ break; ++ /* Tail ahead of head, but still enough space */ ++ if (new_pos < tail && new_pos) ++ break; + +-static void wined3d_cs_st_submit(struct wined3d_cs *cs) +-{ +- enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)cs->data; ++ TRACE("Waiting for free space. Head %u, tail %u, want %u\n", head, tail, ++ (unsigned int) size); ++ } + +- wined3d_cs_op_handlers[opcode](cs, cs->data); ++ return &queue->data[queue->head]; + } + +-static const struct wined3d_cs_ops wined3d_cs_st_ops = +-{ +- wined3d_cs_st_require_space, +- wined3d_cs_st_submit, +- wined3d_cs_st_submit, +-}; +- + static const struct wined3d_cs_ops wined3d_cs_mt_ops = + { + wined3d_cs_mt_require_space, +- wined3d_cs_flush, +- wined3d_cs_flush_and_wait, ++ wined3d_cs_submit, ++ wined3d_cs_finish, + }; + + /* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an +@@ -1938,9 +1886,38 @@ static void wined3d_cs_emit_stop(struct wined3d_cs *cs) + op = wined3d_cs_mt_require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_STOP; + +- wined3d_cs_flush(cs); ++ wined3d_cs_submit(cs, sizeof(*op)); ++} ++ ++static void wined3d_cs_st_submit(struct wined3d_cs *cs, size_t size) ++{ ++ enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)&cs->queue.data; ++ ++ if (opcode >= WINED3D_CS_OP_STOP) ++ { ++ ERR("Invalid opcode %#x.\n", opcode); ++ return; ++ } ++ ++ wined3d_cs_op_handlers[opcode](cs, &cs->queue.data); + } + ++static void wined3d_cs_st_finish(struct wined3d_cs *cs) ++{ ++} ++ ++static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) ++{ ++ return cs->queue.data; ++} ++ ++static const struct wined3d_cs_ops wined3d_cs_st_ops = ++{ ++ wined3d_cs_st_require_space, ++ wined3d_cs_st_submit, ++ wined3d_cs_st_finish, ++}; ++ + void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, + struct wined3d_context *context, struct wined3d_surface *depth_stencil) + { +@@ -1960,31 +1937,32 @@ void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, + static DWORD WINAPI wined3d_cs_run(void *thread_param) + { + struct wined3d_cs *cs = thread_param; ++ enum wined3d_cs_op opcode; ++ LONG tail; + + TRACE("Started.\n"); + + cs->thread_id = GetCurrentThreadId(); + for (;;) + { +- struct wined3d_cs_block *block; +- UINT pos = 0; +- +- block = wined3d_cs_list_dequeue_blocking(&cs->exec_list); +- while (pos < block->pos) ++ if (*((volatile LONG *)&cs->queue.head) == cs->queue.tail) + { +- enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)&block->data[pos]; ++ continue; ++ } + +- if (opcode >= WINED3D_CS_OP_STOP) +- { +- if (opcode > WINED3D_CS_OP_STOP) +- ERR("Invalid opcode %#x.\n", opcode); +- goto done; +- } ++ tail = cs->queue.tail; ++ opcode = *(const enum wined3d_cs_op *)&cs->queue.data[tail]; + +- pos += wined3d_cs_op_handlers[opcode](cs, &block->data[pos]); ++ if (opcode >= WINED3D_CS_OP_STOP) ++ { ++ if (opcode > WINED3D_CS_OP_STOP) ++ ERR("Invalid opcode %#x.\n", opcode); ++ goto done; + } + +- wined3d_cs_list_enqueue(&cs->free_list, block); ++ tail += wined3d_cs_op_handlers[opcode](cs, &cs->queue.data[tail]); ++ tail &= (WINED3D_CS_QUEUE_SIZE - 1); ++ InterlockedExchange(&cs->queue.tail, tail); + } + + done: +@@ -2009,25 +1987,10 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) + cs->ops = &wined3d_cs_st_ops; + cs->device = device; + +- cs->data_size = WINED3D_INITIAL_CS_SIZE; +- if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size))) +- { +- goto err; +- } +- +- if ((cs->tls_idx = TlsAlloc()) == TLS_OUT_OF_INDEXES) +- { +- ERR("Failed to allocate cs TLS index, err %#x.\n", GetLastError()); +- goto err; +- } +- + if (wined3d_settings.cs_multithreaded) + { + cs->ops = &wined3d_cs_mt_ops; + +- wined3d_cs_list_init(&cs->free_list); +- wined3d_cs_list_init(&cs->exec_list); +- + if (!(cs->thread = CreateThread(NULL, 0, wined3d_cs_run, cs, 0, NULL))) + { + ERR("Failed to create wined3d command stream thread.\n"); +@@ -2039,12 +2002,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) + + err: + if (cs) +- { + state_cleanup(&cs->state); +- if (cs->tls_idx != TLS_OUT_OF_INDEXES && !TlsFree(cs->tls_idx)) +- ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); +- HeapFree(GetProcessHeap(), 0, cs->data); +- } + HeapFree(GetProcessHeap(), 0, cs); + return NULL; + } +@@ -2063,17 +2021,7 @@ void wined3d_cs_destroy(struct wined3d_cs *cs) + CloseHandle(cs->thread); + if (ret != WAIT_OBJECT_0) + ERR("Wait failed (%#x).\n", ret); +- +- /* FIXME: Cleanup the block lists on thread exit. */ +-#if 0 +- wined3d_cs_list_cleanup(&cs->exec_list); +- wined3d_cs_list_cleanup(&cs->free_list); +-#endif + } + +- if (!TlsFree(cs->tls_idx)) +- ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); +- +- HeapFree(GetProcessHeap(), 0, cs->data); + HeapFree(GetProcessHeap(), 0, cs); + } +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index ed4d94b..35384e1 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -31,6 +31,7 @@ + #define WINE_GLAPI + #endif + ++#include + #include + #include + #include +@@ -2584,19 +2585,17 @@ struct wined3d_cs_list + struct list blocks; + }; + +-struct wined3d_cs_block ++#define WINED3D_CS_QUEUE_SIZE 0x100000 ++struct wined3d_cs_queue + { +- struct list entry; +- UINT pos; +- /* FIXME? The size is somewhat arbitrary. It's big enough for huge +- * shader constant set calls though */ +- BYTE data[sizeof(float) * 4 * 256 * 2]; ++ LONG head, tail; ++ BYTE data[WINED3D_CS_QUEUE_SIZE]; + }; + + struct wined3d_cs_ops + { + void *(*require_space)(struct wined3d_cs *cs, size_t size); +- void (*submit)(struct wined3d_cs *cs); ++ void (*submit)(struct wined3d_cs *cs, size_t size); + void (*finish)(struct wined3d_cs *cs); + }; + +@@ -2607,14 +2606,9 @@ struct wined3d_cs + struct wined3d_state state; + HANDLE thread; + DWORD thread_id; +- DWORD tls_idx; + struct wined3d_surface *onscreen_depth_stencil; + +- size_t data_size; +- void *data; +- +- struct wined3d_cs_list free_list; +- struct wined3d_cs_list exec_list; ++ struct wined3d_cs_queue queue; + + LONG pending_presents; + }; +-- +2.3.5 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0073-wined3d-send-resource-maps-through-the-command-strea.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0073-wined3d-send-resource-maps-through-the-command-strea.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0073-wined3d-send-resource-maps-through-the-command-strea.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0073-wined3d-send-resource-maps-through-the-command-strea.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,275 +0,0 @@ -From 84bfd1772cafbfdfba4f0fa02703c24fba74c3bb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 26 Sep 2013 16:41:00 +0200 -Subject: wined3d: send resource maps through the command stream - -Slow version only. Good enough to dodge some Nvidia bugs in the ddraw tests. ---- - dlls/wined3d/cs.c | 69 ++++++++++++++++++++++++++++++++++++ - dlls/wined3d/resource.c | 79 ++++++++++++++++++++++++------------------ - dlls/wined3d/wined3d_private.h | 5 +++ - 3 files changed, 120 insertions(+), 33 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 6ade585..5e96859 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -76,6 +76,8 @@ enum wined3d_cs_op - WINED3D_CS_OP_SET_LIGHT_ENABLE, - WINED3D_CS_OP_BLT, - WINED3D_CS_OP_CLEAR_RTV, -+ WINED3D_CS_OP_RESOURCE_MAP, -+ WINED3D_CS_OP_RESOURCE_UNMAP, - WINED3D_CS_OP_STOP, - }; - -@@ -362,6 +364,20 @@ struct wined3d_cs_clear_rtv - struct wined3d_color color; - }; - -+struct wined3d_cs_resource_map -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_resource *resource; -+ DWORD flags; -+ void **mem; -+}; -+ -+struct wined3d_cs_resource_unmap -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_resource *resource; -+}; -+ - /* FIXME: The list synchronization probably isn't particularly fast. */ - static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) - { -@@ -1801,6 +1817,57 @@ void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarge - cs->ops->submit(cs); - } - -+static UINT wined3d_cs_exec_resource_map(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_resource_map *op = data; -+ -+ *op->mem = wined3d_resource_map_internal(op->resource, op->flags); -+ -+ return sizeof(*op); -+} -+ -+void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, -+ DWORD flags) -+{ -+ struct wined3d_cs_resource_map *op; -+ void *ret; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_RESOURCE_MAP; -+ op->resource = resource; -+ op->flags = flags; -+ op->mem = &ret; -+ -+ cs->ops->finish(cs); -+ -+ if (flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD)) -+ { -+ FIXME("Dynamic resource map is inefficient\n"); -+ } -+ return ret; -+} -+ -+static UINT wined3d_cs_exec_resource_unmap(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_resource_unmap *op = data; -+ struct wined3d_resource *resource = op->resource; -+ -+ wined3d_resource_unmap_internal(resource); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) -+{ -+ struct wined3d_cs_resource_unmap *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_RESOURCE_UNMAP; -+ op->resource = resource; -+ -+ cs->ops->submit(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, -@@ -1843,6 +1910,8 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, - /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, - /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, -+ /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, -+ /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, - }; - - static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 8594992..a2fdefb 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -766,32 +766,11 @@ BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, - return TRUE; - } - --HRESULT wined3d_resource_map(struct wined3d_resource *resource, -- struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -+void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD flags) - { - struct wined3d_device *device = resource->device; - struct wined3d_context *context = NULL; -- BYTE *base_memory; -- const struct wined3d_format *format = resource->format; -- const unsigned int fmt_flags = resource->format->flags[WINED3D_GL_RES_TYPE_TEX_2D]; -- -- TRACE("resource %p, map_desc %p, box %p, flags %#x.\n", -- resource, map_desc, box, flags); -- -- if (resource->map_count) -- { -- WARN("Volume is already mapped.\n"); -- return WINED3DERR_INVALIDCALL; -- } -- -- flags = wined3d_resource_sanitize_map_flags(resource, flags); -- -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- wined3d_cs_emit_glfinish(device->cs); -- device->cs->ops->finish(device->cs); -- } -+ void *mem; - - if (device->d3d_initialized) - context = context_acquire(device, NULL); -@@ -799,9 +778,8 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, - if (!wined3d_resource_prepare_map_memory(resource, context)) - { - WARN("Out of memory.\n"); -- map_desc->data = NULL; - context_release(context); -- return E_OUTOFMEMORY; -+ return NULL; - } - - if (flags & WINED3D_MAP_DISCARD) -@@ -809,11 +787,40 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, - else - wined3d_resource_load_location(resource, context, resource->map_binding); - -- base_memory = wined3d_resource_get_map_ptr(resource, context, flags); -+ mem = wined3d_resource_get_map_ptr(resource, context, flags); - - if (context) - context_release(context); - -+ return mem; -+} -+ -+HRESULT wined3d_resource_map(struct wined3d_resource *resource, -+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) -+{ -+ struct wined3d_device *device = resource->device; -+ BYTE *base_memory; -+ const struct wined3d_format *format = resource->format; -+ const unsigned int fmt_flags = resource->format->flags[WINED3D_GL_RES_TYPE_TEX_2D]; -+ -+ TRACE("resource %p, map_desc %p, box %p, flags %#x.\n", -+ resource, map_desc, box, flags); -+ -+ if (resource->map_count) -+ { -+ WARN("Volume is already mapped.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ flags = wined3d_resource_sanitize_map_flags(resource, flags); -+ -+ base_memory = wined3d_cs_emit_resource_map(device->cs, resource, flags); -+ if (!base_memory) -+ { -+ WARN("Map failed.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ - TRACE("Base memory pointer %p.\n", base_memory); - - if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) -@@ -865,10 +872,21 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, - return WINED3D_OK; - } - --HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) -+void wined3d_resource_unmap_internal(struct wined3d_resource *resource) - { - struct wined3d_device *device = resource->device; - struct wined3d_context *context = NULL; -+ -+ if (device->d3d_initialized) -+ context = context_acquire(device, NULL); -+ wined3d_resource_release_map_ptr(resource, context); -+ if (context) -+ context_release(context); -+} -+ -+HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) -+{ -+ struct wined3d_device *device = resource->device; - TRACE("resource %p.\n", resource); - - if (!resource->map_count) -@@ -877,12 +895,7 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) - return WINEDDERR_NOTLOCKED; - } - -- if (device->d3d_initialized) -- context = context_acquire(device, NULL); -- wined3d_resource_release_map_ptr(resource, context); -- if (context) -- context_release(context); -- -+ wined3d_cs_emit_resource_unmap(device->cs, resource); - resource->map_count--; - - return WINED3D_OK; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index aa7b47b..3592bcc 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2239,6 +2239,7 @@ void wined3d_resource_load_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; - HRESULT wined3d_resource_map(struct wined3d_resource *resource, struct wined3d_map_desc *map_desc, - const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; -+void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; - BOOL wined3d_resource_prepare_map_memory(struct wined3d_resource *resource, - struct wined3d_context *context) DECLSPEC_HIDDEN; - BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -@@ -2246,6 +2247,7 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, - const struct wined3d_context *context) DECLSPEC_HIDDEN; - DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; - HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+void wined3d_resource_unmap_internal(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_validate_location(struct wined3d_resource *resource, DWORD location) DECLSPEC_HIDDEN; - -@@ -2728,6 +2730,9 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf - enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; - void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, - const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; -+void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, -+ DWORD flags) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0074-wined3d-Don-t-preload-buffers-on-unmap.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0074-wined3d-Don-t-preload-buffers-on-unmap.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0074-wined3d-Don-t-preload-buffers-on-unmap.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0074-wined3d-Don-t-preload-buffers-on-unmap.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,27 @@ +From e65b83c7523a8c124cd04dc97b3f617175e24541 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Jul 2013 23:40:56 +0200 +Subject: wined3d: Don't preload buffers on unmap + +--- + dlls/wined3d/buffer.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index c519fcd..3c8c681 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -1129,10 +1129,6 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) + buffer_clear_dirty_areas(buffer); + buffer->map_ptr = NULL; + } +- else if (buffer->flags & WINED3D_BUFFER_HASDESC) +- { +- wined3d_buffer_preload(buffer); +- } + } + + HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0074-wined3d-Get-rid-of-the-end_scene-flush-and-finish.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0074-wined3d-Get-rid-of-the-end_scene-flush-and-finish.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0074-wined3d-Get-rid-of-the-end_scene-flush-and-finish.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0074-wined3d-Get-rid-of-the-end_scene-flush-and-finish.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -From 907befb9104d166a5423d92c8aec0e8d6835bb92 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Jul 2013 22:59:33 +0200 -Subject: wined3d: Get rid of the end_scene flush and finish - -Either keep the patch this way, or send a flush through the CS. I'm not -sure it's worth it though, this has never had any real performance -impact. ---- - dlls/wined3d/device.c | 12 ------------ - 1 file changed, 12 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index b2e7ec3..cd90c76 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -3224,8 +3224,6 @@ HRESULT CDECL wined3d_device_begin_scene(struct wined3d_device *device) - - HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) - { -- struct wined3d_context *context; -- - TRACE("device %p.\n", device); - - if (!device->inScene) -@@ -3234,16 +3232,6 @@ HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) - return WINED3DERR_INVALIDCALL; - } - -- context = context_acquire(device, NULL); -- /* We only have to do this if we need to read the, swapbuffers performs a flush for us */ -- if (wined3d_settings.cs_multithreaded) -- context->gl_info->gl_ops.gl.p_glFinish(); -- else -- context->gl_info->gl_ops.gl.p_glFlush(); -- /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever -- * fails. */ -- context_release(context); -- - device->inScene = FALSE; - return WINED3D_OK; - } --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0075-wined3d-Don-t-call-glFinish-before-swapping.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0075-wined3d-Don-t-call-glFinish-before-swapping.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0075-wined3d-Don-t-call-glFinish-before-swapping.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0075-wined3d-Don-t-call-glFinish-before-swapping.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,29 @@ +From 808198079459086ac70236bacaacd85aa717f7ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Jul 2013 23:50:20 +0200 +Subject: wined3d: Don't call glFinish before swapping + +The code is probably not ready yet, so delay this patch until everything +is CSified. Right now I need it for performance testing. +--- + dlls/wined3d/swapchain.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c +index fa0c241..7ebdd1b 100644 +--- a/dlls/wined3d/swapchain.c ++++ b/dlls/wined3d/swapchain.c +@@ -531,9 +531,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT + swapchain_blit(swapchain, context, &src_rect, &dst_rect); + } + +- if (wined3d_settings.cs_multithreaded) +- gl_info->gl_ops.gl.p_glFinish(); +- else if (swapchain->num_contexts > 1) ++ if (swapchain->num_contexts > 1 && !wined3d_settings.cs_multithreaded) + gl_info->gl_ops.gl.p_glFlush(); + + /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */ +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0075-wined3d-Replace-the-linked-lists-with-a-ringbuffer.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0075-wined3d-Replace-the-linked-lists-with-a-ringbuffer.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0075-wined3d-Replace-the-linked-lists-with-a-ringbuffer.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0075-wined3d-Replace-the-linked-lists-with-a-ringbuffer.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,852 +0,0 @@ -From c115a25b8aba4ade5fa04cfb469b030eb29b941a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Jul 2013 23:33:14 +0200 -Subject: wined3d: Replace the linked lists with a ringbuffer - ---- - dlls/wined3d/cs.c | 362 ++++++++++++++++++----------------------- - dlls/wined3d/wined3d_private.h | 20 +-- - 2 files changed, 162 insertions(+), 220 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 6204e57..66c784b 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -22,20 +22,10 @@ - - WINE_DEFAULT_DEBUG_CHANNEL(d3d); - --#define WINED3D_INITIAL_CS_SIZE 4096 -- --static CRITICAL_SECTION wined3d_cs_list_mutex; --static CRITICAL_SECTION_DEBUG wined3d_cs_list_mutex_debug = --{ -- 0, 0, &wined3d_cs_list_mutex, -- {&wined3d_cs_list_mutex_debug.ProcessLocksList, -- &wined3d_cs_list_mutex_debug.ProcessLocksList}, -- 0, 0, {(DWORD_PTR)(__FILE__ ": wined3d_cs_list_mutex")} --}; --static CRITICAL_SECTION wined3d_cs_list_mutex = {&wined3d_cs_list_mutex_debug, -1, 0, 0, 0, 0}; -- - enum wined3d_cs_op - { -+ WINED3D_CS_OP_NOP, -+ WINED3D_CS_OP_SKIP, - WINED3D_CS_OP_FENCE, - WINED3D_CS_OP_PRESENT, - WINED3D_CS_OP_CLEAR, -@@ -378,99 +368,30 @@ struct wined3d_cs_resource_unmap - struct wined3d_resource *resource; - }; - --/* FIXME: The list synchronization probably isn't particularly fast. */ --static void wined3d_cs_list_enqueue(struct wined3d_cs_list *list, struct wined3d_cs_block *block) --{ -- EnterCriticalSection(&wined3d_cs_list_mutex); -- list_add_tail(&list->blocks, &block->entry); -- LeaveCriticalSection(&wined3d_cs_list_mutex); --} -- --static struct wined3d_cs_block *wined3d_cs_list_dequeue(struct wined3d_cs_list *list) --{ -- struct list *head; -- -- EnterCriticalSection(&wined3d_cs_list_mutex); -- if (!(head = list_head(&list->blocks))) -- { -- LeaveCriticalSection(&wined3d_cs_list_mutex); -- return NULL; -- } -- list_remove(head); -- LeaveCriticalSection(&wined3d_cs_list_mutex); -- -- return LIST_ENTRY(head, struct wined3d_cs_block, entry); --} -- --static struct wined3d_cs_block *wined3d_cs_list_dequeue_blocking(struct wined3d_cs_list *list) --{ -- struct wined3d_cs_block *block; -- -- /* FIXME: Use an event to wait after a couple of spins. */ -- for (;;) -- { -- if ((block = wined3d_cs_list_dequeue(list))) -- return block; -- } --} -- --static void wined3d_cs_list_init(struct wined3d_cs_list *list) --{ -- list_init(&list->blocks); --} -- --static struct wined3d_cs_block *wined3d_cs_get_thread_block(const struct wined3d_cs *cs) --{ -- return TlsGetValue(cs->tls_idx); --} -- --static void wined3d_cs_set_thread_block(const struct wined3d_cs *cs, struct wined3d_cs_block *block) -+struct wined3d_cs_skip - { -- if (!TlsSetValue(cs->tls_idx, block)) -- ERR("Failed to set thread block.\n"); --} -+ enum wined3d_cs_op opcode; -+ DWORD size; -+}; - --static void wined3d_cs_flush(struct wined3d_cs *cs) -+static void wined3d_cs_submit(struct wined3d_cs *cs, size_t size) - { -- wined3d_cs_list_enqueue(&cs->exec_list, wined3d_cs_get_thread_block(cs)); -- wined3d_cs_set_thread_block(cs, NULL); -+ LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -+ /* There is only one thread writing to queue.head, InterlockedExchange -+ * is used for the memory barrier. */ -+ InterlockedExchange(&cs->queue.head, new_val); - } - --static struct wined3d_cs_block *wined3d_cs_get_block(struct wined3d_cs *cs) -+static UINT wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data) - { -- struct wined3d_cs_block *block; -- -- if (!(block = wined3d_cs_list_dequeue(&cs->free_list))) -- { -- if (!(block = HeapAlloc(GetProcessHeap(), 0, sizeof(*block)))) -- { -- ERR("Failed to get new block.\n"); -- return NULL; -- } -- } -- -- block->pos = 0; -- -- return block; -+ return sizeof(enum wined3d_cs_op); - } - --static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) -+static UINT wined3d_cs_exec_skip(struct wined3d_cs *cs, const void *data) - { -- struct wined3d_cs_block *block = wined3d_cs_get_thread_block(cs); -- void *data; -- -- if (!block || block->pos + size > sizeof(block->data)) -- { -- if (block) -- wined3d_cs_flush(cs); -- block = wined3d_cs_get_block(cs); -- wined3d_cs_set_thread_block(cs, block); -- } -+ const struct wined3d_cs_skip *op = data; - -- data = &block->data[block->pos]; -- block->pos += size; -- -- return data; -+ return op->size; - } - - static UINT wined3d_cs_exec_fence(struct wined3d_cs *cs, const void *data) -@@ -491,14 +412,14 @@ static void wined3d_cs_emit_fence(struct wined3d_cs *cs, BOOL *signalled) - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_FENCE; - op->signalled = signalled; -+ cs->ops->submit(cs, sizeof(*op)); - } - --static void wined3d_cs_flush_and_wait(struct wined3d_cs *cs) -+static void wined3d_cs_finish(struct wined3d_cs *cs) - { - BOOL fence; - - wined3d_cs_emit_fence(cs, &fence); -- wined3d_cs_flush(cs); - - /* A busy wait should be fine, we're not supposed to have to wait very - * long. */ -@@ -556,7 +477,7 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw - - pending = InterlockedIncrement(&cs->pending_presents); - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - - while (pending > 1) - pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0); -@@ -583,8 +504,9 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * - { - struct wined3d_cs_clear *op; - unsigned int extra_rects = rect_count ? rect_count - 1 : 0; -+ size_t size = sizeof(*op) + sizeof(*op->rects) * extra_rects; - -- op = cs->ops->require_space(cs, sizeof(*op) + sizeof(*op->rects) * extra_rects); -+ op = cs->ops->require_space(cs, size); - op->opcode = WINED3D_CS_OP_CLEAR; - op->rect_count = rect_count; - if (rect_count) -@@ -594,7 +516,7 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * - op->depth = depth; - op->stencil = stencil; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, size); - } - - static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) -@@ -635,7 +557,7 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun - op->instance_count = instance_count; - op->indexed = indexed; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data) -@@ -657,7 +579,7 @@ void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query - op->predicate = predicate; - op->value = value; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) -@@ -679,7 +601,7 @@ void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_vi - op->opcode = WINED3D_CS_OP_SET_VIEWPORT; - op->viewport = *viewport; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) -@@ -700,7 +622,7 @@ void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) - op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT; - op->rect = *rect; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) -@@ -723,7 +645,7 @@ void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int v - op->view_idx = view_idx; - op->view = view; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data) -@@ -776,7 +698,7 @@ void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3 - op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW; - op->view = view; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) -@@ -797,7 +719,7 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3 - op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION; - op->declaration = declaration; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) -@@ -834,7 +756,7 @@ void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, - op->offset = offset; - op->stride = stride; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) -@@ -861,7 +783,7 @@ void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_i - op->frequency = frequency; - op->flags = flags; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) -@@ -894,7 +816,7 @@ void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, - op->buffer = buffer; - op->offset = offset; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) -@@ -926,7 +848,7 @@ void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buff - op->buffer = buffer; - op->format_id = format_id; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) -@@ -957,7 +879,7 @@ void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_sha - op->cb_idx = cb_idx; - op->buffer = buffer; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) -@@ -1032,7 +954,7 @@ void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined - op->opcode = WINED3D_CS_OP_SET_TEXTURE; - op->stage = stage; - op->texture = texture; -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) -@@ -1056,7 +978,7 @@ void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3 - op->view_idx = view_idx; - op->view = view; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) -@@ -1080,7 +1002,7 @@ void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type - op->sampler_idx = sampler_idx; - op->sampler = sampler; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) -@@ -1102,6 +1024,8 @@ void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type - op->opcode = WINED3D_CS_OP_SET_SHADER; - op->type = type; - op->shader = shader; -+ -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_vs_consts_f(struct wined3d_cs *cs, const void *data) -@@ -1137,8 +1061,9 @@ void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, - { - struct wined3d_cs_set_consts_f *op; - UINT extra_space = vector4f_count - 1; -+ size_t size = sizeof(*op) + sizeof(op->constants) * extra_space; - -- op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); -+ op = cs->ops->require_space(cs, size); - switch (type) - { - case WINED3D_SHADER_TYPE_PIXEL: -@@ -1160,7 +1085,7 @@ void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, - op->vector4f_count = vector4f_count; - memcpy(op->constants, constants, sizeof(*constants) * 4 * vector4f_count); - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, size); - } - - static UINT wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) -@@ -1182,8 +1107,8 @@ void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render - op->state = state; - op->value = value; - -- cs->ops->submit(cs); --}; -+ cs->ops->submit(cs, sizeof(*op)); -+} - - static UINT wined3d_cs_exec_set_vs_consts_b(struct wined3d_cs *cs, const void *data) - { -@@ -1216,8 +1141,9 @@ void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, - { - struct wined3d_cs_set_consts_b *op; - UINT extra_space = bool_count - 1; -+ size_t size = sizeof(*op) + sizeof(op->constants) * extra_space; - -- op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); -+ op = cs->ops->require_space(cs, size); - switch (type) - { - case WINED3D_SHADER_TYPE_PIXEL: -@@ -1239,7 +1165,7 @@ void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, - op->bool_count = bool_count; - memcpy(op->constants, constants, sizeof(op->constants) * bool_count); - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, size); - } - - static UINT wined3d_cs_exec_set_vs_consts_i(struct wined3d_cs *cs, const void *data) -@@ -1273,8 +1199,9 @@ void wined3d_cs_emit_set_consts_i(struct wined3d_cs *cs, UINT start_register, - { - struct wined3d_cs_set_consts_i *op; - UINT extra_space = vector4i_count - 1; -+ size_t size = sizeof(*op) + sizeof(op->constants) * extra_space; - -- op = cs->ops->require_space(cs, sizeof(*op) + sizeof(op->constants) * extra_space); -+ op = cs->ops->require_space(cs, size); - switch (type) - { - case WINED3D_SHADER_TYPE_PIXEL: -@@ -1296,7 +1223,7 @@ void wined3d_cs_emit_set_consts_i(struct wined3d_cs *cs, UINT start_register, - op->vector4i_count = vector4i_count; - memcpy(op->constants, constants, sizeof(op->constants) * vector4i_count); - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, size); - } - - static UINT wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) -@@ -1320,7 +1247,7 @@ void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, - op->state = state; - op->value = value; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) -@@ -1344,7 +1271,7 @@ void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, - op->state = state; - op->value = value; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) -@@ -1368,7 +1295,7 @@ void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform - op->state = state; - op->matrix = *matrix; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) -@@ -1390,7 +1317,7 @@ void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const - op->plane_idx = plane_idx; - op->plane = *plane; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data) -@@ -1468,7 +1395,7 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture - else - op->set = 0; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) -@@ -1489,7 +1416,7 @@ void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_ma - op->opcode = WINED3D_CS_OP_SET_MATERIAL; - op->material = *material; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) -@@ -1513,7 +1440,7 @@ void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_RESET_STATE; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_glfinish(struct wined3d_cs *cs, const void *data) -@@ -1539,7 +1466,7 @@ void wined3d_cs_emit_glfinish(struct wined3d_cs *cs) - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_GLFINISH; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_base_vertex_index(struct wined3d_cs *cs, const void *data) -@@ -1561,7 +1488,7 @@ void wined3d_cs_emit_set_base_vertex_index(struct wined3d_cs *cs, - op->opcode = WINED3D_CS_OP_SET_BASE_VERTEX_INDEX; - op->base_vertex_index = base_vertex_index; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_primitive_type(struct wined3d_cs *cs, const void *data) -@@ -1587,7 +1514,7 @@ void wined3d_cs_emit_set_primitive_type(struct wined3d_cs *cs, GLenum primitive_ - op->opcode = WINED3D_CS_OP_SET_PRIMITIVE_TYPE; - op->gl_primitive_type = primitive_type; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) -@@ -1644,7 +1571,7 @@ void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light - op->opcode = WINED3D_CS_OP_SET_LIGHT; - op->light = *light; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_set_light_enable(struct wined3d_cs *cs, const void *data) -@@ -1733,7 +1660,7 @@ void wined3d_cs_emit_set_light_enable(struct wined3d_cs *cs, UINT idx, BOOL enab - op->idx = idx; - op->enable = enable; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_blt(struct wined3d_cs *cs, const void *data) -@@ -1765,7 +1692,7 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf - if (fx) - op->fx = *fx; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_clear_rtv(struct wined3d_cs *cs, const void *data) -@@ -1791,7 +1718,7 @@ void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarge - op->rect = *rect; - op->color = *color; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_resource_map(struct wined3d_cs *cs, const void *data) -@@ -1815,12 +1742,14 @@ void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resourc - op->flags = flags; - op->mem = &ret; - -- cs->ops->finish(cs); -+ cs->ops->submit(cs, sizeof(*op)); - - if (flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD)) - { - FIXME("Dynamic resource map is inefficient\n"); - } -+ cs->ops->finish(cs); -+ - return ret; - } - -@@ -1842,11 +1771,13 @@ void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resour - op->opcode = WINED3D_CS_OP_RESOURCE_UNMAP; - op->resource = resource; - -- cs->ops->submit(cs); -+ cs->ops->submit(cs, sizeof(*op)); - } - - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { -+ /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -+ /* WINED3D_CS_OP_SKIP */ wined3d_cs_exec_skip, - /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, - /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, - /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, -@@ -1891,42 +1822,59 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, - }; - --static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -+static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) - { -- if (size > cs->data_size) -+ struct wined3d_cs_queue *queue = &cs->queue; -+ size_t queue_size = sizeof(queue->data) / sizeof(*queue->data); -+ -+ if (queue_size - size < queue->head) - { -- void *new_data; -+ struct wined3d_cs_skip *skip; -+ size_t nop_size = queue_size - queue->head; - -- size = max( size, cs->data_size * 2 ); -- if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size))) -- return NULL; -+ skip = wined3d_cs_mt_require_space(cs, nop_size); -+ if (nop_size < sizeof(*skip)) -+ { -+ skip->opcode = WINED3D_CS_OP_NOP; -+ } -+ else -+ { -+ skip->opcode = WINED3D_CS_OP_SKIP; -+ skip->size = nop_size; -+ } - -- cs->data_size = size; -- cs->data = new_data; -+ cs->ops->submit(cs, nop_size); -+ assert(!queue->head); - } - -- return cs->data; --} -+ while(1) -+ { -+ LONG head = queue->head; -+ LONG tail = *((volatile LONG *)&queue->tail); -+ LONG new_pos; -+ /* Empty */ -+ if (head == tail) -+ break; -+ /* Head ahead of tail, take care of wrap-around */ -+ new_pos = (head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -+ if (head > tail && (new_pos || tail)) -+ break; -+ /* Tail ahead of head, but still enough space */ -+ if (new_pos < tail && new_pos) -+ break; - --static void wined3d_cs_st_submit(struct wined3d_cs *cs) --{ -- enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)cs->data; -+ TRACE("Waiting for free space. Head %u, tail %u, want %u\n", head, tail, -+ (unsigned int) size); -+ } - -- wined3d_cs_op_handlers[opcode](cs, cs->data); -+ return &queue->data[queue->head]; - } - --static const struct wined3d_cs_ops wined3d_cs_st_ops = --{ -- wined3d_cs_st_require_space, -- wined3d_cs_st_submit, -- wined3d_cs_st_submit, --}; -- - static const struct wined3d_cs_ops wined3d_cs_mt_ops = - { - wined3d_cs_mt_require_space, -- wined3d_cs_flush, -- wined3d_cs_flush_and_wait, -+ wined3d_cs_submit, -+ wined3d_cs_finish, - }; - - /* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an -@@ -1938,9 +1886,38 @@ static void wined3d_cs_emit_stop(struct wined3d_cs *cs) - op = wined3d_cs_mt_require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_STOP; - -- wined3d_cs_flush(cs); -+ wined3d_cs_submit(cs, sizeof(*op)); -+} -+ -+static void wined3d_cs_st_submit(struct wined3d_cs *cs, size_t size) -+{ -+ enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)&cs->queue.data; -+ -+ if (opcode >= WINED3D_CS_OP_STOP) -+ { -+ ERR("Invalid opcode %#x.\n", opcode); -+ return; -+ } -+ -+ wined3d_cs_op_handlers[opcode](cs, &cs->queue.data); - } - -+static void wined3d_cs_st_finish(struct wined3d_cs *cs) -+{ -+} -+ -+static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -+{ -+ return cs->queue.data; -+} -+ -+static const struct wined3d_cs_ops wined3d_cs_st_ops = -+{ -+ wined3d_cs_st_require_space, -+ wined3d_cs_st_submit, -+ wined3d_cs_st_finish, -+}; -+ - void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, - struct wined3d_context *context, struct wined3d_surface *depth_stencil) - { -@@ -1960,31 +1937,32 @@ void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, - static DWORD WINAPI wined3d_cs_run(void *thread_param) - { - struct wined3d_cs *cs = thread_param; -+ enum wined3d_cs_op opcode; -+ LONG tail; - - TRACE("Started.\n"); - - cs->thread_id = GetCurrentThreadId(); - for (;;) - { -- struct wined3d_cs_block *block; -- UINT pos = 0; -- -- block = wined3d_cs_list_dequeue_blocking(&cs->exec_list); -- while (pos < block->pos) -+ if (*((volatile LONG *)&cs->queue.head) == cs->queue.tail) - { -- enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)&block->data[pos]; -+ continue; -+ } - -- if (opcode >= WINED3D_CS_OP_STOP) -- { -- if (opcode > WINED3D_CS_OP_STOP) -- ERR("Invalid opcode %#x.\n", opcode); -- goto done; -- } -+ tail = cs->queue.tail; -+ opcode = *(const enum wined3d_cs_op *)&cs->queue.data[tail]; - -- pos += wined3d_cs_op_handlers[opcode](cs, &block->data[pos]); -+ if (opcode >= WINED3D_CS_OP_STOP) -+ { -+ if (opcode > WINED3D_CS_OP_STOP) -+ ERR("Invalid opcode %#x.\n", opcode); -+ goto done; - } - -- wined3d_cs_list_enqueue(&cs->free_list, block); -+ tail += wined3d_cs_op_handlers[opcode](cs, &cs->queue.data[tail]); -+ tail &= (WINED3D_CS_QUEUE_SIZE - 1); -+ InterlockedExchange(&cs->queue.tail, tail); - } - - done: -@@ -2009,25 +1987,10 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) - cs->ops = &wined3d_cs_st_ops; - cs->device = device; - -- cs->data_size = WINED3D_INITIAL_CS_SIZE; -- if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size))) -- { -- goto err; -- } -- -- if ((cs->tls_idx = TlsAlloc()) == TLS_OUT_OF_INDEXES) -- { -- ERR("Failed to allocate cs TLS index, err %#x.\n", GetLastError()); -- goto err; -- } -- - if (wined3d_settings.cs_multithreaded) - { - cs->ops = &wined3d_cs_mt_ops; - -- wined3d_cs_list_init(&cs->free_list); -- wined3d_cs_list_init(&cs->exec_list); -- - if (!(cs->thread = CreateThread(NULL, 0, wined3d_cs_run, cs, 0, NULL))) - { - ERR("Failed to create wined3d command stream thread.\n"); -@@ -2039,12 +2002,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) - - err: - if (cs) -- { - state_cleanup(&cs->state); -- if (cs->tls_idx != TLS_OUT_OF_INDEXES && !TlsFree(cs->tls_idx)) -- ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); -- HeapFree(GetProcessHeap(), 0, cs->data); -- } - HeapFree(GetProcessHeap(), 0, cs); - return NULL; - } -@@ -2063,17 +2021,7 @@ void wined3d_cs_destroy(struct wined3d_cs *cs) - CloseHandle(cs->thread); - if (ret != WAIT_OBJECT_0) - ERR("Wait failed (%#x).\n", ret); -- -- /* FIXME: Cleanup the block lists on thread exit. */ --#if 0 -- wined3d_cs_list_cleanup(&cs->exec_list); -- wined3d_cs_list_cleanup(&cs->free_list); --#endif - } - -- if (!TlsFree(cs->tls_idx)) -- ERR("Failed to free cs TLS index, err %#x.\n", GetLastError()); -- -- HeapFree(GetProcessHeap(), 0, cs->data); - HeapFree(GetProcessHeap(), 0, cs); - } -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index ed4d94b..35384e1 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -31,6 +31,7 @@ - #define WINE_GLAPI - #endif - -+#include - #include - #include - #include -@@ -2584,19 +2585,17 @@ struct wined3d_cs_list - struct list blocks; - }; - --struct wined3d_cs_block -+#define WINED3D_CS_QUEUE_SIZE 0x100000 -+struct wined3d_cs_queue - { -- struct list entry; -- UINT pos; -- /* FIXME? The size is somewhat arbitrary. It's big enough for huge -- * shader constant set calls though */ -- BYTE data[sizeof(float) * 4 * 256 * 2]; -+ LONG head, tail; -+ BYTE data[WINED3D_CS_QUEUE_SIZE]; - }; - - struct wined3d_cs_ops - { - void *(*require_space)(struct wined3d_cs *cs, size_t size); -- void (*submit)(struct wined3d_cs *cs); -+ void (*submit)(struct wined3d_cs *cs, size_t size); - void (*finish)(struct wined3d_cs *cs); - }; - -@@ -2607,14 +2606,9 @@ struct wined3d_cs - struct wined3d_state state; - HANDLE thread; - DWORD thread_id; -- DWORD tls_idx; - struct wined3d_surface *onscreen_depth_stencil; - -- size_t data_size; -- void *data; -- -- struct wined3d_cs_list free_list; -- struct wined3d_cs_list exec_list; -+ struct wined3d_cs_queue queue; - - LONG pending_presents; - }; --- -2.3.5 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0076-wined3d-Don-t-preload-buffers-on-unmap.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0076-wined3d-Don-t-preload-buffers-on-unmap.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0076-wined3d-Don-t-preload-buffers-on-unmap.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0076-wined3d-Don-t-preload-buffers-on-unmap.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -From 0603f71135885ebf0666d406380385936ed5ff7b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Jul 2013 23:40:56 +0200 -Subject: wined3d: Don't preload buffers on unmap - ---- - dlls/wined3d/buffer.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 5544640..b76a07d 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -1129,10 +1129,6 @@ void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer) - buffer_clear_dirty_areas(buffer); - buffer->map_ptr = NULL; - } -- else if (buffer->flags & WINED3D_BUFFER_HASDESC) -- { -- wined3d_buffer_preload(buffer); -- } - } - - static ULONG buffer_resource_incref(struct wined3d_resource *resource) --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0076-wined3d-wined3d_-_query_issue-never-fails.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0076-wined3d-wined3d_-_query_issue-never-fails.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0076-wined3d-wined3d_-_query_issue-never-fails.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0076-wined3d-wined3d_-_query_issue-never-fails.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,116 @@ +From ea0804eca5b9d5df9eeb4a435d11ad1e6f4227b1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 18:15:00 +0200 +Subject: wined3d: wined3d_*_query_issue never fails + +--- + dlls/wined3d/query.c | 21 ++++++++------------- + dlls/wined3d/wined3d_private.h | 2 +- + 2 files changed, 9 insertions(+), 14 deletions(-) + +diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c +index e755764..3de4282 100644 +--- a/dlls/wined3d/query.c ++++ b/dlls/wined3d/query.c +@@ -292,7 +292,8 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) + { + TRACE("query %p, flags %#x.\n", query, flags); + +- return query->query_ops->query_issue(query, flags); ++ query->query_ops->query_issue(query, flags); ++ return WINED3D_OK; + } + + static void fill_query_data(void *out, unsigned int out_size, const void *result, unsigned int result_size) +@@ -435,7 +436,7 @@ enum wined3d_query_type CDECL wined3d_query_get_type(const struct wined3d_query + return query->type; + } + +-static HRESULT wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) ++static void wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) + { + TRACE("query %p, flags %#x.\n", query, flags); + +@@ -445,7 +446,7 @@ static HRESULT wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD + struct wined3d_event_query *event_query = query->extendedData; + + /* Faked event query support */ +- if (!event_query) return WINED3D_OK; ++ if (!event_query) return; + + wined3d_event_query_issue(event_query, query->device); + } +@@ -459,11 +460,9 @@ static HRESULT wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD + query->state = QUERY_BUILDING; + else + query->state = QUERY_SIGNALLED; +- +- return WINED3D_OK; + } + +-static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) ++static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) + { + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; +@@ -542,7 +541,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW + else + query->state = QUERY_SIGNALLED; + +- return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */ ++ return; + } + + static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, +@@ -605,7 +604,7 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, + return res; + } + +-static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) ++static void wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) + { + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; +@@ -639,8 +638,6 @@ static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DW + + if (flags & WINED3DISSUE_END) + query->state = QUERY_SIGNALLED; +- +- return WINED3D_OK; + } + + static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query, +@@ -669,7 +666,7 @@ static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_quer + return S_OK; + } + +-static HRESULT wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) ++static void wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) + { + TRACE("query %p, flags %#x.\n", query, flags); + +@@ -677,8 +674,6 @@ static HRESULT wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query * + query->state = QUERY_BUILDING; + if (flags & WINED3DISSUE_END) + query->state = QUERY_SIGNALLED; +- +- return WINED3D_OK; + } + + static const struct wined3d_query_ops event_query_ops = +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 59d9753..ff05a97 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2653,7 +2653,7 @@ enum query_state { + struct wined3d_query_ops + { + HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags); +- HRESULT (*query_issue)(struct wined3d_query *query, DWORD flags); ++ void (*query_issue)(struct wined3d_query *query, DWORD flags); + }; + + struct wined3d_query +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0077-wined3d-Add-query-support-to-the-command-stream.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0077-wined3d-Add-query-support-to-the-command-stream.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0077-wined3d-Add-query-support-to-the-command-stream.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0077-wined3d-Add-query-support-to-the-command-stream.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,163 @@ +From c0687b2ce9d0056bce2fc514f25baa20ab834f1e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 18:26:11 +0200 +Subject: wined3d: Add query support to the command stream + +--- + dlls/wined3d/cs.c | 73 ++++++++++++++++++++++++++++++++++++++++++ + dlls/wined3d/query.c | 8 +++-- + dlls/wined3d/wined3d_private.h | 4 +++ + 3 files changed, 83 insertions(+), 2 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index d35f114..e4d60d8 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -67,6 +67,8 @@ enum wined3d_cs_op + WINED3D_CS_OP_CLEAR_RTV, + WINED3D_CS_OP_RESOURCE_MAP, + WINED3D_CS_OP_RESOURCE_UNMAP, ++ WINED3D_CS_OP_QUERY_ISSUE, ++ WINED3D_CS_OP_QUERY_GET_DATA, + WINED3D_CS_OP_STOP, + }; + +@@ -364,6 +366,23 @@ struct wined3d_cs_skip + DWORD size; + }; + ++struct wined3d_cs_query_issue ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_query *query; ++ DWORD flags; ++}; ++ ++struct wined3d_cs_query_get_data ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_query *query; ++ void *data; ++ UINT data_size; ++ DWORD flags; ++ HRESULT *ret; ++}; ++ + static void wined3d_cs_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -1683,6 +1702,58 @@ void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resour + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_query_issue *op = data; ++ ++ op->query->query_ops->query_issue(op->query, op->flags); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) ++{ ++ struct wined3d_cs_query_issue *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_QUERY_ISSUE; ++ op->query = query; ++ op->flags = flags; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ ++static UINT wined3d_cs_exec_query_get_data(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_query_get_data *op = data; ++ struct wined3d_query *query = op->query; ++ ++ *op->ret = query->query_ops->query_get_data(query, op->data, op->data_size, op->flags); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query *query, void *data, ++ UINT data_size, DWORD flags, HRESULT *ret) ++{ ++ struct wined3d_cs_query_get_data *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_QUERY_GET_DATA; ++ op->query = query; ++ op->data = data; ++ op->data_size = data_size; ++ op->flags = flags; ++ op->ret = ret; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++ ++ if (wined3d_settings.cs_multithreaded) ++ FIXME("Query handling is not particularly fast yet\n"); ++ ++ cs->ops->finish(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -1728,6 +1799,8 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, + /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, + /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, ++ /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, ++ /* WINED3D_CS_OP_QUERY_GET_DATA */ wined3d_cs_exec_query_get_data, + }; + + static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) +diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c +index 3de4282..6436bd7 100644 +--- a/dlls/wined3d/query.c ++++ b/dlls/wined3d/query.c +@@ -275,10 +275,14 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query) + HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query, + void *data, UINT data_size, DWORD flags) + { ++ HRESULT hr; + TRACE("query %p, data %p, data_size %u, flags %#x.\n", + query, data, data_size, flags); + +- return query->query_ops->query_get_data(query, data, data_size, flags); ++ wined3d_cs_emit_query_get_data(query->device->cs, query, data, data_size, ++ flags, &hr); ++ ++ return hr; + } + + UINT CDECL wined3d_query_get_data_size(const struct wined3d_query *query) +@@ -292,7 +296,7 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) + { + TRACE("query %p, flags %#x.\n", query, flags); + +- query->query_ops->query_issue(query, flags); ++ wined3d_cs_emit_query_issue(query->device->cs, query, flags); + return WINED3D_OK; + } + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index ff05a97..6175f13 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2639,6 +2639,10 @@ void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarge + void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, + DWORD flags) DECLSPEC_HIDDEN; + void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, ++ DWORD flags) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query *query, void *data, ++ UINT data_size, DWORD flags, HRESULT *ret) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0077-wined3d-Don-t-call-glFinish-before-swapping.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0077-wined3d-Don-t-call-glFinish-before-swapping.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0077-wined3d-Don-t-call-glFinish-before-swapping.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0077-wined3d-Don-t-call-glFinish-before-swapping.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -From 808198079459086ac70236bacaacd85aa717f7ff Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Jul 2013 23:50:20 +0200 -Subject: wined3d: Don't call glFinish before swapping - -The code is probably not ready yet, so delay this patch until everything -is CSified. Right now I need it for performance testing. ---- - dlls/wined3d/swapchain.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c -index fa0c241..7ebdd1b 100644 ---- a/dlls/wined3d/swapchain.c -+++ b/dlls/wined3d/swapchain.c -@@ -531,9 +531,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT - swapchain_blit(swapchain, context, &src_rect, &dst_rect); - } - -- if (wined3d_settings.cs_multithreaded) -- gl_info->gl_ops.gl.p_glFinish(); -- else if (swapchain->num_contexts > 1) -+ if (swapchain->num_contexts > 1 && !wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFlush(); - - /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */ --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0078-wined3d-Check-our-CS-state-to-find-out-if-a-query-is.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0078-wined3d-Check-our-CS-state-to-find-out-if-a-query-is.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0078-wined3d-Check-our-CS-state-to-find-out-if-a-query-is.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0078-wined3d-Check-our-CS-state-to-find-out-if-a-query-is.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,72 @@ +From ed3e1f3c0fb3ed7d687235e0683039169d412c99 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 18:31:41 +0200 +Subject: wined3d: Check our CS state to find out if a query is done + +--- + dlls/wined3d/cs.c | 6 +++++- + dlls/wined3d/query.c | 9 +++++++++ + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index e4d60d8..ba8e840 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -1705,8 +1705,12 @@ void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resour + static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_query_issue *op = data; ++ struct wined3d_query *query = op->query; ++ ++ query->query_ops->query_issue(query, op->flags); + +- op->query->query_ops->query_issue(op->query, op->flags); ++ if (op->flags & WINED3DISSUE_END) ++ InterlockedIncrement(&query->counter_worker); + + return sizeof(*op); + } +diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c +index 6436bd7..bea03ed 100644 +--- a/dlls/wined3d/query.c ++++ b/dlls/wined3d/query.c +@@ -279,6 +279,12 @@ HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query, + TRACE("query %p, data %p, data_size %u, flags %#x.\n", + query, data, data_size, flags); + ++ if (query->counter_main != query->counter_worker) ++ { ++ TRACE("D3DISSUE_END command not submitted to GL yet\n"); ++ return S_FALSE; ++ } ++ + wined3d_cs_emit_query_get_data(query->device->cs, query, data, data_size, + flags, &hr); + +@@ -296,6 +302,9 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) + { + TRACE("query %p, flags %#x.\n", query, flags); + ++ if (flags & WINED3DISSUE_END) ++ query->counter_main++; ++ + wined3d_cs_emit_query_issue(query->device->cs, query, flags); + return WINED3D_OK; + } +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 6175f13..3fd7fa7 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2671,6 +2671,8 @@ struct wined3d_query + enum wined3d_query_type type; + DWORD data_size; + void *extendedData; ++ ++ LONG counter_main, counter_worker; + }; + + /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0078-wined3d-wined3d_-_query_issue-never-fails.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0078-wined3d-wined3d_-_query_issue-never-fails.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0078-wined3d-wined3d_-_query_issue-never-fails.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0078-wined3d-wined3d_-_query_issue-never-fails.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,116 +0,0 @@ -From ea0804eca5b9d5df9eeb4a435d11ad1e6f4227b1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 18:15:00 +0200 -Subject: wined3d: wined3d_*_query_issue never fails - ---- - dlls/wined3d/query.c | 21 ++++++++------------- - dlls/wined3d/wined3d_private.h | 2 +- - 2 files changed, 9 insertions(+), 14 deletions(-) - -diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c -index e755764..3de4282 100644 ---- a/dlls/wined3d/query.c -+++ b/dlls/wined3d/query.c -@@ -292,7 +292,8 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) - { - TRACE("query %p, flags %#x.\n", query, flags); - -- return query->query_ops->query_issue(query, flags); -+ query->query_ops->query_issue(query, flags); -+ return WINED3D_OK; - } - - static void fill_query_data(void *out, unsigned int out_size, const void *result, unsigned int result_size) -@@ -435,7 +436,7 @@ enum wined3d_query_type CDECL wined3d_query_get_type(const struct wined3d_query - return query->type; - } - --static HRESULT wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) -+static void wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) - { - TRACE("query %p, flags %#x.\n", query, flags); - -@@ -445,7 +446,7 @@ static HRESULT wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD - struct wined3d_event_query *event_query = query->extendedData; - - /* Faked event query support */ -- if (!event_query) return WINED3D_OK; -+ if (!event_query) return; - - wined3d_event_query_issue(event_query, query->device); - } -@@ -459,11 +460,9 @@ static HRESULT wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD - query->state = QUERY_BUILDING; - else - query->state = QUERY_SIGNALLED; -- -- return WINED3D_OK; - } - --static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) -+static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) - { - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -@@ -542,7 +541,7 @@ static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DW - else - query->state = QUERY_SIGNALLED; - -- return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */ -+ return; - } - - static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, -@@ -605,7 +604,7 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, - return res; - } - --static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) -+static void wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) - { - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -@@ -639,8 +638,6 @@ static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DW - - if (flags & WINED3DISSUE_END) - query->state = QUERY_SIGNALLED; -- -- return WINED3D_OK; - } - - static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query, -@@ -669,7 +666,7 @@ static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_quer - return S_OK; - } - --static HRESULT wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) -+static void wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) - { - TRACE("query %p, flags %#x.\n", query, flags); - -@@ -677,8 +674,6 @@ static HRESULT wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query * - query->state = QUERY_BUILDING; - if (flags & WINED3DISSUE_END) - query->state = QUERY_SIGNALLED; -- -- return WINED3D_OK; - } - - static const struct wined3d_query_ops event_query_ops = -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 59d9753..ff05a97 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2653,7 +2653,7 @@ enum query_state { - struct wined3d_query_ops - { - HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags); -- HRESULT (*query_issue)(struct wined3d_query *query, DWORD flags); -+ void (*query_issue)(struct wined3d_query *query, DWORD flags); - }; - - struct wined3d_query --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0079-wined3d-Add-query-support-to-the-command-stream.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0079-wined3d-Add-query-support-to-the-command-stream.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0079-wined3d-Add-query-support-to-the-command-stream.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0079-wined3d-Add-query-support-to-the-command-stream.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,163 +0,0 @@ -From c0687b2ce9d0056bce2fc514f25baa20ab834f1e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 18:26:11 +0200 -Subject: wined3d: Add query support to the command stream - ---- - dlls/wined3d/cs.c | 73 ++++++++++++++++++++++++++++++++++++++++++ - dlls/wined3d/query.c | 8 +++-- - dlls/wined3d/wined3d_private.h | 4 +++ - 3 files changed, 83 insertions(+), 2 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index d35f114..e4d60d8 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -67,6 +67,8 @@ enum wined3d_cs_op - WINED3D_CS_OP_CLEAR_RTV, - WINED3D_CS_OP_RESOURCE_MAP, - WINED3D_CS_OP_RESOURCE_UNMAP, -+ WINED3D_CS_OP_QUERY_ISSUE, -+ WINED3D_CS_OP_QUERY_GET_DATA, - WINED3D_CS_OP_STOP, - }; - -@@ -364,6 +366,23 @@ struct wined3d_cs_skip - DWORD size; - }; - -+struct wined3d_cs_query_issue -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_query *query; -+ DWORD flags; -+}; -+ -+struct wined3d_cs_query_get_data -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_query *query; -+ void *data; -+ UINT data_size; -+ DWORD flags; -+ HRESULT *ret; -+}; -+ - static void wined3d_cs_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -1683,6 +1702,58 @@ void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resour - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_query_issue *op = data; -+ -+ op->query->query_ops->query_issue(op->query, op->flags); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, DWORD flags) -+{ -+ struct wined3d_cs_query_issue *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_QUERY_ISSUE; -+ op->query = query; -+ op->flags = flags; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ -+static UINT wined3d_cs_exec_query_get_data(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_query_get_data *op = data; -+ struct wined3d_query *query = op->query; -+ -+ *op->ret = query->query_ops->query_get_data(query, op->data, op->data_size, op->flags); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query *query, void *data, -+ UINT data_size, DWORD flags, HRESULT *ret) -+{ -+ struct wined3d_cs_query_get_data *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_QUERY_GET_DATA; -+ op->query = query; -+ op->data = data; -+ op->data_size = data_size; -+ op->flags = flags; -+ op->ret = ret; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+ -+ if (wined3d_settings.cs_multithreaded) -+ FIXME("Query handling is not particularly fast yet\n"); -+ -+ cs->ops->finish(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -1728,6 +1799,8 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, - /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, - /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, -+ /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, -+ /* WINED3D_CS_OP_QUERY_GET_DATA */ wined3d_cs_exec_query_get_data, - }; - - static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) -diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c -index 3de4282..6436bd7 100644 ---- a/dlls/wined3d/query.c -+++ b/dlls/wined3d/query.c -@@ -275,10 +275,14 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query) - HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query, - void *data, UINT data_size, DWORD flags) - { -+ HRESULT hr; - TRACE("query %p, data %p, data_size %u, flags %#x.\n", - query, data, data_size, flags); - -- return query->query_ops->query_get_data(query, data, data_size, flags); -+ wined3d_cs_emit_query_get_data(query->device->cs, query, data, data_size, -+ flags, &hr); -+ -+ return hr; - } - - UINT CDECL wined3d_query_get_data_size(const struct wined3d_query *query) -@@ -292,7 +296,7 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) - { - TRACE("query %p, flags %#x.\n", query, flags); - -- query->query_ops->query_issue(query, flags); -+ wined3d_cs_emit_query_issue(query->device->cs, query, flags); - return WINED3D_OK; - } - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index ff05a97..6175f13 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2639,6 +2639,10 @@ void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarge - void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, - DWORD flags) DECLSPEC_HIDDEN; - void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *query, -+ DWORD flags) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query *query, void *data, -+ UINT data_size, DWORD flags, HRESULT *ret) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0079-wined3d-Poll-queries-automatically-in-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0079-wined3d-Poll-queries-automatically-in-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0079-wined3d-Poll-queries-automatically-in-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0079-wined3d-Poll-queries-automatically-in-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,586 @@ +From d4993de1feaab2ff73335fc976e7917a115376eb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 19:18:48 +0200 +Subject: wined3d: Poll queries automatically in the CS + +--- + dlls/wined3d/cs.c | 76 ++++++-------- + dlls/wined3d/query.c | 225 ++++++++++++++++++++++++++--------------- + dlls/wined3d/wined3d_private.h | 7 +- + 3 files changed, 180 insertions(+), 128 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index d1b4d7c..0441ca3 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -69,7 +69,6 @@ enum wined3d_cs_op + WINED3D_CS_OP_RESOURCE_MAP, + WINED3D_CS_OP_RESOURCE_UNMAP, + WINED3D_CS_OP_QUERY_ISSUE, +- WINED3D_CS_OP_QUERY_GET_DATA, + WINED3D_CS_OP_STOP, + }; + +@@ -383,16 +382,6 @@ struct wined3d_cs_query_issue + DWORD flags; + }; + +-struct wined3d_cs_query_get_data +-{ +- enum wined3d_cs_op opcode; +- struct wined3d_query *query; +- void *data; +- UINT data_size; +- DWORD flags; +- HRESULT *ret; +-}; +- + static void wined3d_cs_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -1823,8 +1812,9 @@ static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) + + query->query_ops->query_issue(query, op->flags); + +- if (op->flags & WINED3DISSUE_END) +- InterlockedIncrement(&query->counter_worker); ++ if (wined3d_settings.cs_multithreaded && op->flags & WINED3DISSUE_END ++ && list_empty(&query->poll_list_entry)) ++ list_add_tail(&cs->query_poll_list, &query->poll_list_entry); + + return sizeof(*op); + } +@@ -1841,37 +1831,6 @@ void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *qu + cs->ops->submit(cs, sizeof(*op)); + } + +-static UINT wined3d_cs_exec_query_get_data(struct wined3d_cs *cs, const void *data) +-{ +- const struct wined3d_cs_query_get_data *op = data; +- struct wined3d_query *query = op->query; +- +- *op->ret = query->query_ops->query_get_data(query, op->data, op->data_size, op->flags); +- +- return sizeof(*op); +-} +- +-void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query *query, void *data, +- UINT data_size, DWORD flags, HRESULT *ret) +-{ +- struct wined3d_cs_query_get_data *op; +- +- op = cs->ops->require_space(cs, sizeof(*op)); +- op->opcode = WINED3D_CS_OP_QUERY_GET_DATA; +- op->query = query; +- op->data = data; +- op->data_size = data_size; +- op->flags = flags; +- op->ret = ret; +- +- cs->ops->submit(cs, sizeof(*op)); +- +- if (wined3d_settings.cs_multithreaded) +- FIXME("Query handling is not particularly fast yet\n"); +- +- cs->ops->finish(cs); +-} +- + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -1919,7 +1878,6 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, + /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, + /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, +- /* WINED3D_CS_OP_QUERY_GET_DATA */ wined3d_cs_exec_query_get_data, + }; + + static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) +@@ -2034,17 +1992,45 @@ void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, + wined3d_texture_incref(cs->onscreen_depth_stencil->container); + } + ++static inline void poll_queries(struct wined3d_cs *cs) ++{ ++ struct wined3d_query *query, *cursor; ++ ++ LIST_FOR_EACH_ENTRY_SAFE(query, cursor, &cs->query_poll_list, struct wined3d_query, poll_list_entry) ++ { ++ BOOL ret; ++ ++ ret = query->query_ops->query_poll(query); ++ if (ret) ++ { ++ list_remove(&query->poll_list_entry); ++ list_init(&query->poll_list_entry); ++ InterlockedIncrement(&query->counter_retrieved); ++ } ++ } ++} ++ + static DWORD WINAPI wined3d_cs_run(void *thread_param) + { + struct wined3d_cs *cs = thread_param; + enum wined3d_cs_op opcode; + LONG tail; ++ char poll = 0; + + TRACE("Started.\n"); + ++ list_init(&cs->query_poll_list); + cs->thread_id = GetCurrentThreadId(); + for (;;) + { ++ if (poll == 10) ++ { ++ poll = 0; ++ poll_queries(cs); ++ } ++ else ++ poll++; ++ + if (*((volatile LONG *)&cs->queue.head) == cs->queue.tail) + { + continue; +diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c +index 1c6d713..d607eb5 100644 +--- a/dlls/wined3d/query.c ++++ b/dlls/wined3d/query.c +@@ -241,6 +241,15 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query) + + if (!refcount) + { ++ if (wined3d_settings.cs_multithreaded) ++ { ++ struct wined3d_device *device = query->device; ++ ++ FIXME("waiting for cs\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + /* Queries are specific to the GL context that created them. Not + * deleting the query will obviously leak it, but that's still better + * than potentially deleting a different query with the same id in this +@@ -275,20 +284,10 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query) + HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query, + void *data, UINT data_size, DWORD flags) + { +- HRESULT hr; + TRACE("query %p, data %p, data_size %u, flags %#x.\n", + query, data, data_size, flags); + +- if (query->counter_main != query->counter_worker) +- { +- TRACE("D3DISSUE_END command not submitted to GL yet\n"); +- return S_FALSE; +- } +- +- wined3d_cs_emit_query_get_data(query->device->cs, query, data, data_size, +- flags, &hr); +- +- return hr; ++ return query->query_ops->query_get_data(query, data, data_size, flags); + } + + UINT CDECL wined3d_query_get_data_size(const struct wined3d_query *query) +@@ -317,15 +316,10 @@ static void fill_query_data(void *out, unsigned int out_size, const void *result + static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, + void *data, DWORD size, DWORD flags) + { +- struct wined3d_occlusion_query *oq = query->extendedData; + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; +- struct wined3d_context *context; +- GLuint available; ++ struct wined3d_occlusion_query *oq = query->extendedData; + GLuint samples; +- HRESULT res; +- +- TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); + + if (!oq->context) + query->state = QUERY_CREATED; +@@ -339,6 +333,8 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, + return S_OK; + } + ++ TRACE("(%p) : type D3DQUERY_OCCLUSION, data %p, size %#x, flags %#x.\n", query, data, size, flags); ++ + if (query->state == QUERY_BUILDING) + { + /* Msdn says this returns an error, but our tests show that S_FALSE is returned */ +@@ -354,12 +350,37 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, + return S_OK; + } + ++ if (!wined3d_settings.cs_multithreaded) ++ { ++ if (!query->query_ops->query_poll(query)) ++ return S_FALSE; ++ } ++ else if (query->counter_main != query->counter_retrieved) ++ { ++ return S_FALSE; ++ } ++ ++ if (data) ++ fill_query_data(data, size, &oq->samples, sizeof(oq->samples)); ++ ++ return S_OK; ++} ++ ++static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query) ++{ ++ struct wined3d_occlusion_query *oq = query->extendedData; ++ struct wined3d_device *device = query->device; ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++ struct wined3d_context *context; ++ GLuint available; ++ GLuint samples; ++ BOOL ret; ++ + if (oq->context->tid != GetCurrentThreadId()) + { + FIXME("%p Wrong thread, returning 1.\n", query); +- samples = 1; +- fill_query_data(data, size, &samples, sizeof(samples)); +- return S_OK; ++ oq->samples = 1; ++ return TRUE; + } + + context = context_acquire(query->device, oq->context->current_rt); +@@ -370,68 +391,78 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, + + if (available) + { +- if (size) +- { +- GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples)); +- checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); +- TRACE("Returning %d samples.\n", samples); +- fill_query_data(data, size, &samples, sizeof(samples)); +- } +- res = S_OK; ++ GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples)); ++ checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); ++ TRACE("Returning %d samples.\n", samples); ++ oq->samples = samples; ++ ret = TRUE; + } + else + { +- res = S_FALSE; ++ ret = FALSE; + } + + context_release(context); + +- return res; ++ return ret; + } + +-static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query, +- void *data, DWORD size, DWORD flags) ++static BOOL wined3d_event_query_ops_poll(struct wined3d_query *query) + { + struct wined3d_event_query *event_query = query->extendedData; +- BOOL signaled; + enum wined3d_event_query_result ret; + +- TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); +- +- if (!data || !size) return S_OK; +- if (!event_query) +- { +- WARN("Event query not supported by GL, reporting GPU idle.\n"); +- signaled = TRUE; +- fill_query_data(data, size, &signaled, sizeof(signaled)); +- return S_OK; +- } +- + ret = wined3d_event_query_test(event_query, query->device); + switch(ret) + { + case WINED3D_EVENT_QUERY_OK: + case WINED3D_EVENT_QUERY_NOT_STARTED: +- signaled = TRUE; +- fill_query_data(data, size, &signaled, sizeof(signaled)); +- break; ++ return TRUE; + + case WINED3D_EVENT_QUERY_WAITING: +- signaled = FALSE; +- fill_query_data(data, size, &signaled, sizeof(signaled)); +- break; ++ return FALSE; + + case WINED3D_EVENT_QUERY_WRONG_THREAD: + FIXME("(%p) Wrong thread, reporting GPU idle.\n", query); +- signaled = TRUE; +- fill_query_data(data, size, &signaled, sizeof(signaled)); +- break; ++ return TRUE; + + case WINED3D_EVENT_QUERY_ERROR: + ERR("The GL event query failed, returning D3DERR_INVALIDCALL\n"); +- return WINED3DERR_INVALIDCALL; ++ return TRUE; ++ ++ default: ++ ERR("Unexpected wined3d_event_query_test result %u\n", ret); ++ return TRUE; ++ } ++} ++ ++static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query, ++ void *pData, DWORD dwSize, DWORD flags) ++{ ++ struct wined3d_event_query *event_query = query->extendedData; ++ BOOL *data = pData; ++ enum wined3d_event_query_result ret; ++ ++ TRACE("query %p, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags); ++ ++ if (!pData || !dwSize) return S_OK; ++ if (!event_query) ++ { ++ WARN("Event query not supported by GL, reporting GPU idle.\n"); ++ *data = TRUE; ++ return S_OK; + } + ++ if (!wined3d_settings.cs_multithreaded) ++ ret = query->query_ops->query_poll(query); ++ else if (query->counter_main != query->counter_retrieved) ++ ret = FALSE; ++ else ++ ret = TRUE; ++ ++ if (data) ++ fill_query_data(data, dwSize, &ret, sizeof(ret)); ++ + return S_OK; + } + +@@ -561,33 +592,57 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, + void *data, DWORD size, DWORD flags) + { + struct wined3d_timestamp_query *tq = query->extendedData; ++ ++ TRACE("(%p) : type D3DQUERY_TIMESTAMP, data %p, size %#x, flags %#x.\n", query, data, size, flags); ++ ++ if (query->state == QUERY_CREATED) ++ { ++ UINT64 zero = 0; ++ /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */ ++ TRACE("Query wasn't yet started, returning S_OK.\n"); ++ if (data) ++ fill_query_data(data, size, &zero, sizeof(zero)); ++ return S_OK; ++ } ++ ++ if (!wined3d_settings.cs_multithreaded) ++ { ++ if (!query->query_ops->query_poll(query)) ++ return S_FALSE; ++ } ++ else if (query->counter_main != query->counter_retrieved) ++ { ++ return S_FALSE; ++ } ++ ++ if (data) ++ fill_query_data(data, size, &tq->timestamp, sizeof(tq->timestamp)); ++ ++ return S_OK; ++} ++ ++static BOOL wined3d_timestamp_query_ops_poll(struct wined3d_query *query) ++{ ++ struct wined3d_timestamp_query *tq = query->extendedData; + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_context *context; + GLuint available; + GLuint64 timestamp; +- HRESULT res; ++ BOOL ret; + +- TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); +- +- if (!tq->context) +- query->state = QUERY_CREATED; +- +- if (query->state == QUERY_CREATED) ++ if (!gl_info->supported[ARB_TIMER_QUERY]) + { +- /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves. */ +- TRACE("Query wasn't yet started, returning S_OK.\n"); +- timestamp = 0; +- fill_query_data(data, size, ×tamp, sizeof(timestamp)); +- return S_OK; ++ TRACE("Faking timestamp.\n"); ++ QueryPerformanceCounter((LARGE_INTEGER *)&tq->timestamp); ++ return TRUE; + } + + if (tq->context->tid != GetCurrentThreadId()) + { + FIXME("%p Wrong thread, returning 1.\n", query); +- timestamp = 1; +- fill_query_data(data, size, ×tamp, sizeof(timestamp)); +- return S_OK; ++ tq->timestamp = 1; ++ return TRUE; + } + + context = context_acquire(query->device, tq->context->current_rt); +@@ -598,23 +653,20 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, + + if (available) + { +- if (size) +- { +- GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); +- checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); +- TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); +- fill_query_data(data, size, ×tamp, sizeof(timestamp)); +- } +- res = S_OK; ++ GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); ++ checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); ++ TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); ++ tq->timestamp = timestamp; ++ ret = TRUE; + } + else + { +- res = S_FALSE; ++ ret = FALSE; + } + + context_release(context); + +- return res; ++ return ret; + } + + static void wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) +@@ -657,15 +709,14 @@ static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_quer + void *data, DWORD size, DWORD flags) + { + TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); +- + if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT) + { + static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE}; + + if (query->state == QUERY_BUILDING) + { +- TRACE("Query is building, returning S_FALSE.\n"); +- return S_FALSE; ++ TRACE("Query is building, returning S_FALSE.\n"); ++ return S_FALSE; + } + + fill_query_data(data, size, &disjoint_data, sizeof(disjoint_data)); +@@ -679,6 +730,11 @@ static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_quer + return S_OK; + } + ++static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *query) ++{ ++ return TRUE; ++} ++ + static void wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) + { + TRACE("query %p, flags %#x.\n", query, flags); +@@ -692,24 +748,28 @@ static void wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *que + static const struct wined3d_query_ops event_query_ops = + { + wined3d_event_query_ops_get_data, ++ wined3d_event_query_ops_poll, + wined3d_event_query_ops_issue, + }; + + static const struct wined3d_query_ops occlusion_query_ops = + { + wined3d_occlusion_query_ops_get_data, ++ wined3d_occlusion_query_ops_poll, + wined3d_occlusion_query_ops_issue, + }; + + static const struct wined3d_query_ops timestamp_query_ops = + { + wined3d_timestamp_query_ops_get_data, ++ wined3d_timestamp_query_ops_poll, + wined3d_timestamp_query_ops_issue, + }; + + static const struct wined3d_query_ops timestamp_disjoint_query_ops = + { + wined3d_timestamp_disjoint_query_ops_get_data, ++ wined3d_timestamp_disjoint_query_ops_poll, + wined3d_timestamp_disjoint_query_ops_issue, + }; + +@@ -810,6 +870,7 @@ static HRESULT query_init(struct wined3d_query *query, struct wined3d_device *de + query->state = QUERY_CREATED; + query->device = device; + query->ref = 1; ++ list_init(&query->poll_list_entry); + + return WINED3D_OK; + } +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 75ca493..ec9a821 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -1112,6 +1112,7 @@ struct wined3d_occlusion_query + struct list entry; + GLuint id; + struct wined3d_context *context; ++ DWORD samples; + }; + + union wined3d_gl_query_object +@@ -1147,6 +1148,7 @@ struct wined3d_timestamp_query + struct list entry; + GLuint id; + struct wined3d_context *context; ++ UINT64 timestamp; + }; + + void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; +@@ -2675,6 +2677,7 @@ struct wined3d_cs + struct wined3d_cs_queue queue; + + LONG pending_presents; ++ struct list query_poll_list; + }; + + struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; +@@ -2770,6 +2773,7 @@ enum query_state { + struct wined3d_query_ops + { + HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags); ++ BOOL (*query_poll)(struct wined3d_query *query); + void (*query_issue)(struct wined3d_query *query, DWORD flags); + }; + +@@ -2785,7 +2789,8 @@ struct wined3d_query + DWORD data_size; + void *extendedData; + +- LONG counter_main, counter_worker; ++ LONG counter_main, counter_retrieved; ++ struct list poll_list_entry; + }; + + /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other +-- +2.6.2 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0080-wined3d-Check-our-CS-state-to-find-out-if-a-query-is.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0080-wined3d-Check-our-CS-state-to-find-out-if-a-query-is.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0080-wined3d-Check-our-CS-state-to-find-out-if-a-query-is.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0080-wined3d-Check-our-CS-state-to-find-out-if-a-query-is.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -From ed3e1f3c0fb3ed7d687235e0683039169d412c99 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 18:31:41 +0200 -Subject: wined3d: Check our CS state to find out if a query is done - ---- - dlls/wined3d/cs.c | 6 +++++- - dlls/wined3d/query.c | 9 +++++++++ - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 16 insertions(+), 1 deletion(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index e4d60d8..ba8e840 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -1705,8 +1705,12 @@ void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resour - static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_query_issue *op = data; -+ struct wined3d_query *query = op->query; -+ -+ query->query_ops->query_issue(query, op->flags); - -- op->query->query_ops->query_issue(op->query, op->flags); -+ if (op->flags & WINED3DISSUE_END) -+ InterlockedIncrement(&query->counter_worker); - - return sizeof(*op); - } -diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c -index 6436bd7..bea03ed 100644 ---- a/dlls/wined3d/query.c -+++ b/dlls/wined3d/query.c -@@ -279,6 +279,12 @@ HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query, - TRACE("query %p, data %p, data_size %u, flags %#x.\n", - query, data, data_size, flags); - -+ if (query->counter_main != query->counter_worker) -+ { -+ TRACE("D3DISSUE_END command not submitted to GL yet\n"); -+ return S_FALSE; -+ } -+ - wined3d_cs_emit_query_get_data(query->device->cs, query, data, data_size, - flags, &hr); - -@@ -296,6 +302,9 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) - { - TRACE("query %p, flags %#x.\n", query, flags); - -+ if (flags & WINED3DISSUE_END) -+ query->counter_main++; -+ - wined3d_cs_emit_query_issue(query->device->cs, query, flags); - return WINED3D_OK; - } -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 6175f13..3fd7fa7 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2671,6 +2671,8 @@ struct wined3d_query - enum wined3d_query_type type; - DWORD data_size; - void *extendedData; -+ -+ LONG counter_main, counter_worker; - }; - - /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0080-wined3d-Introduce-a-separate-queue-for-priority-comm.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0080-wined3d-Introduce-a-separate-queue-for-priority-comm.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0080-wined3d-Introduce-a-separate-queue-for-priority-comm.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0080-wined3d-Introduce-a-separate-queue-for-priority-comm.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,268 @@ +From 0a14b53f4dcb38e852db14d186d14c8526f3549a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 19:18:03 +0200 +Subject: wined3d: Introduce a separate queue for priority commands + +--- + dlls/wined3d/cs.c | 128 ++++++++++++++++++++++++++++++++++------- + dlls/wined3d/wined3d_private.h | 5 +- + 2 files changed, 110 insertions(+), 23 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 68e1ed7..a7f7694 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -372,7 +372,7 @@ struct wined3d_cs_query_issue + DWORD flags; + }; + +-static void wined3d_cs_submit(struct wined3d_cs *cs, size_t size) ++static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); + /* There is only one thread writing to queue.head, InterlockedExchange +@@ -380,6 +380,14 @@ static void wined3d_cs_submit(struct wined3d_cs *cs, size_t size) + InterlockedExchange(&cs->queue.head, new_val); + } + ++static void wined3d_cs_mt_submit_prio(struct wined3d_cs *cs, size_t size) ++{ ++ LONG new_val = (cs->prio_queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); ++ /* There is only one thread writing to queue.head, InterlockedExchange ++ * is used for the memory barrier. */ ++ InterlockedExchange(&cs->prio_queue.head, new_val); ++} ++ + static UINT wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data) + { + return sizeof(enum wined3d_cs_op); +@@ -413,15 +421,16 @@ static void wined3d_cs_emit_fence(struct wined3d_cs *cs, BOOL *signalled) + cs->ops->submit(cs, sizeof(*op)); + } + +-static void wined3d_cs_finish(struct wined3d_cs *cs) ++static void wined3d_cs_emit_fence_prio(struct wined3d_cs *cs, BOOL *signalled) + { +- BOOL fence; ++ struct wined3d_cs_fence *op; + +- wined3d_cs_emit_fence(cs, &fence); ++ *signalled = FALSE; + +- /* A busy wait should be fine, we're not supposed to have to wait very +- * long. */ +- while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); ++ op = cs->ops->require_space_prio(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_FENCE; ++ op->signalled = signalled; ++ cs->ops->submit_prio(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) +@@ -1765,9 +1774,9 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, + }; + +-static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) ++static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) + { +- struct wined3d_cs_queue *queue = &cs->queue; ++ struct wined3d_cs_queue *queue = prio ? &cs->prio_queue : &cs->queue; + size_t queue_size = sizeof(queue->data) / sizeof(*queue->data); + + if (queue_size - size < queue->head) +@@ -1775,7 +1784,7 @@ static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) + struct wined3d_cs_skip *skip; + size_t nop_size = queue_size - queue->head; + +- skip = wined3d_cs_mt_require_space(cs, nop_size); ++ skip = _wined3d_cs_mt_require_space(cs, nop_size, prio); + if (nop_size < sizeof(*skip)) + { + skip->opcode = WINED3D_CS_OP_NOP; +@@ -1786,7 +1795,11 @@ static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) + skip->size = nop_size; + } + +- cs->ops->submit(cs, nop_size); ++ if (prio) ++ cs->ops->submit_prio(cs, nop_size); ++ else ++ cs->ops->submit(cs, nop_size); ++ + assert(!queue->head); + } + +@@ -1813,12 +1826,15 @@ static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) + return &queue->data[queue->head]; + } + +-static const struct wined3d_cs_ops wined3d_cs_mt_ops = ++static inline void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) + { +- wined3d_cs_mt_require_space, +- wined3d_cs_submit, +- wined3d_cs_finish, +-}; ++ return _wined3d_cs_mt_require_space(cs, size, FALSE); ++} ++ ++static inline void *wined3d_cs_mt_require_space_prio(struct wined3d_cs *cs, size_t size) ++{ ++ return _wined3d_cs_mt_require_space(cs, size, TRUE); ++} + + /* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an + * OP itself. */ +@@ -1829,9 +1845,63 @@ static void wined3d_cs_emit_stop(struct wined3d_cs *cs) + op = wined3d_cs_mt_require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_STOP; + +- wined3d_cs_submit(cs, sizeof(*op)); ++ wined3d_cs_mt_submit(cs, sizeof(*op)); + } + ++static void wined3d_cs_mt_finish(struct wined3d_cs *cs) ++{ ++ BOOL fence; ++ ++ if (cs->thread_id == GetCurrentThreadId()) ++ { ++ static BOOL once; ++ if (!once) ++ { ++ FIXME("flush_and_wait called from cs thread\n"); ++ once = TRUE; ++ } ++ return; ++ } ++ ++ wined3d_cs_emit_fence(cs, &fence); ++ ++ /* A busy wait should be fine, we're not supposed to have to wait very ++ * long. */ ++ while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); ++} ++ ++static void wined3d_cs_mt_finish_prio(struct wined3d_cs *cs) ++{ ++ BOOL fence; ++ ++ if (cs->thread_id == GetCurrentThreadId()) ++ { ++ static BOOL once; ++ if (!once) ++ { ++ FIXME("flush_and_wait called from cs thread\n"); ++ once = TRUE; ++ } ++ return; ++ } ++ ++ wined3d_cs_emit_fence_prio(cs, &fence); ++ ++ /* A busy wait should be fine, we're not supposed to have to wait very ++ * long. */ ++ while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); ++} ++ ++static const struct wined3d_cs_ops wined3d_cs_mt_ops = ++{ ++ wined3d_cs_mt_require_space, ++ wined3d_cs_mt_require_space_prio, ++ wined3d_cs_mt_submit, ++ wined3d_cs_mt_submit_prio, ++ wined3d_cs_mt_finish, ++ wined3d_cs_mt_finish_prio, ++}; ++ + static void wined3d_cs_st_submit(struct wined3d_cs *cs, size_t size) + { + enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)&cs->queue.data; +@@ -1857,8 +1927,11 @@ static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) + static const struct wined3d_cs_ops wined3d_cs_st_ops = + { + wined3d_cs_st_require_space, ++ wined3d_cs_st_require_space, ++ wined3d_cs_st_submit, + wined3d_cs_st_submit, + wined3d_cs_st_finish, ++ wined3d_cs_st_finish, + }; + + void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, +@@ -1901,6 +1974,7 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) + enum wined3d_cs_op opcode; + LONG tail; + char poll = 0; ++ struct wined3d_cs_queue *queue; + + TRACE("Started.\n"); + +@@ -1916,13 +1990,23 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) + else + poll++; + +- if (*((volatile LONG *)&cs->queue.head) == cs->queue.tail) ++ if (*((volatile LONG *)&cs->prio_queue.head) != cs->prio_queue.tail) ++ { ++ queue = &cs->prio_queue; ++ } ++ else if (*((volatile LONG *)&cs->queue.head) != cs->queue.tail) ++ { ++ queue = &cs->queue; ++ if (*((volatile LONG *)&cs->prio_queue.head) != cs->prio_queue.tail) ++ queue = &cs->prio_queue; ++ } ++ else + { + continue; + } + +- tail = cs->queue.tail; +- opcode = *(const enum wined3d_cs_op *)&cs->queue.data[tail]; ++ tail = queue->tail; ++ opcode = *(const enum wined3d_cs_op *)&queue->data[tail]; + + if (opcode >= WINED3D_CS_OP_STOP) + { +@@ -1931,9 +2015,9 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) + goto done; + } + +- tail += wined3d_cs_op_handlers[opcode](cs, &cs->queue.data[tail]); ++ tail += wined3d_cs_op_handlers[opcode](cs, &queue->data[tail]); + tail &= (WINED3D_CS_QUEUE_SIZE - 1); +- InterlockedExchange(&cs->queue.tail, tail); ++ InterlockedExchange(&queue->tail, tail); + } + + done: +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 7bda9f0..cf01a6a 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2550,8 +2550,11 @@ struct wined3d_cs_queue + struct wined3d_cs_ops + { + void *(*require_space)(struct wined3d_cs *cs, size_t size); ++ void *(*require_space_prio)(struct wined3d_cs *cs, size_t size); + void (*submit)(struct wined3d_cs *cs, size_t size); ++ void (*submit_prio)(struct wined3d_cs *cs, size_t size); + void (*finish)(struct wined3d_cs *cs); ++ void (*finish_prio)(struct wined3d_cs *cs); + }; + + struct wined3d_cs +@@ -2563,7 +2566,7 @@ struct wined3d_cs + DWORD thread_id; + struct wined3d_surface *onscreen_depth_stencil; + +- struct wined3d_cs_queue queue; ++ struct wined3d_cs_queue queue, prio_queue; + + LONG pending_presents; + struct list query_poll_list; +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0081-wined3d-Destroy-queries-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0081-wined3d-Destroy-queries-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0081-wined3d-Destroy-queries-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0081-wined3d-Destroy-queries-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,183 @@ +From ef12b024a49a4390df02fad20938e04d5cfae35e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 21:54:45 +0200 +Subject: wined3d: Destroy queries through the CS + +--- + dlls/wined3d/cs.c | 31 ++++++++++++++++++++ + dlls/wined3d/query.c | 66 +++++++++++++++++++----------------------- + dlls/wined3d/wined3d_private.h | 3 ++ + 3 files changed, 64 insertions(+), 36 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index a7f7694..b2af05b 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -68,6 +68,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_RESOURCE_MAP, + WINED3D_CS_OP_RESOURCE_UNMAP, + WINED3D_CS_OP_QUERY_ISSUE, ++ WINED3D_CS_OP_QUERY_DESTROY, + WINED3D_CS_OP_STOP, + }; + +@@ -372,6 +373,12 @@ struct wined3d_cs_query_issue + DWORD flags; + }; + ++struct wined3d_cs_query_destroy ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_query *query; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -1726,6 +1733,29 @@ void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *qu + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_query_destroy(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_query_destroy *op = data; ++ ++ if (!list_empty(&op->query->poll_list_entry)) ++ list_remove(&op->query->poll_list_entry); ++ ++ wined3d_query_destroy(op->query); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query *query) ++{ ++ struct wined3d_cs_query_destroy *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_QUERY_DESTROY; ++ op->query = query; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -1772,6 +1802,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, + /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, + /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, ++ /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c +index 621a9d7..f377eea 100644 +--- a/dlls/wined3d/query.c ++++ b/dlls/wined3d/query.c +@@ -233,50 +233,44 @@ ULONG CDECL wined3d_query_incref(struct wined3d_query *query) + return refcount; + } + +-ULONG CDECL wined3d_query_decref(struct wined3d_query *query) ++void wined3d_query_destroy(struct wined3d_query *query) + { +- ULONG refcount = InterlockedDecrement(&query->ref); +- +- TRACE("%p decreasing refcount to %u.\n", query, refcount); ++ /* Queries are specific to the GL context that created them. Not ++ * deleting the query will obviously leak it, but that's still better ++ * than potentially deleting a different query with the same id in this ++ * context, and (still) leaking the actual query. */ ++ if (query->type == WINED3D_QUERY_TYPE_EVENT) ++ { ++ struct wined3d_event_query *event_query = query->extendedData; ++ if (event_query) wined3d_event_query_destroy(event_query); ++ } ++ else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION) ++ { ++ struct wined3d_occlusion_query *oq = query->extendedData; + +- if (!refcount) ++ if (oq->context) context_free_occlusion_query(oq); ++ HeapFree(GetProcessHeap(), 0, query->extendedData); ++ } ++ else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP) + { +- if (wined3d_settings.cs_multithreaded) +- { +- struct wined3d_device *device = query->device; ++ struct wined3d_timestamp_query *tq = query->extendedData; + +- FIXME("waiting for cs\n"); +- wined3d_cs_emit_glfinish(device->cs); +- device->cs->ops->finish(device->cs); +- } ++ if (tq->context) ++ context_free_timestamp_query(tq); ++ HeapFree(GetProcessHeap(), 0, query->extendedData); ++ } + +- /* Queries are specific to the GL context that created them. Not +- * deleting the query will obviously leak it, but that's still better +- * than potentially deleting a different query with the same id in this +- * context, and (still) leaking the actual query. */ +- if (query->type == WINED3D_QUERY_TYPE_EVENT) +- { +- struct wined3d_event_query *event_query = query->extendedData; +- if (event_query) wined3d_event_query_destroy(event_query); +- } +- else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION) +- { +- struct wined3d_occlusion_query *oq = query->extendedData; ++ HeapFree(GetProcessHeap(), 0, query); ++} + +- if (oq->context) context_free_occlusion_query(oq); +- HeapFree(GetProcessHeap(), 0, query->extendedData); +- } +- else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP) +- { +- struct wined3d_timestamp_query *tq = query->extendedData; ++ULONG CDECL wined3d_query_decref(struct wined3d_query *query) ++{ ++ ULONG refcount = InterlockedDecrement(&query->ref); + +- if (tq->context) +- context_free_timestamp_query(tq); +- HeapFree(GetProcessHeap(), 0, query->extendedData); +- } ++ TRACE("%p decreasing refcount to %u.\n", query, refcount); + +- HeapFree(GetProcessHeap(), 0, query); +- } ++ if (!refcount) ++ wined3d_cs_emit_query_destroy(query->device->cs, query); + + return refcount; + } +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index cf01a6a..28badf6 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2649,6 +2649,7 @@ void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *qu + DWORD flags) DECLSPEC_HIDDEN; + void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query *query, void *data, + UINT data_size, DWORD flags, HRESULT *ret) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query *query) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +@@ -2683,6 +2684,8 @@ struct wined3d_query + struct list poll_list_entry; + }; + ++void wined3d_query_destroy(struct wined3d_query *query) DECLSPEC_HIDDEN; ++ + /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other + * fixed function semantics as D3DCOLOR or FLOAT16 */ + enum wined3d_buffer_conversion_type +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0081-wined3d-Poll-queries-automatically-in-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0081-wined3d-Poll-queries-automatically-in-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0081-wined3d-Poll-queries-automatically-in-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0081-wined3d-Poll-queries-automatically-in-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,586 +0,0 @@ -From d4993de1feaab2ff73335fc976e7917a115376eb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 19:18:48 +0200 -Subject: wined3d: Poll queries automatically in the CS - ---- - dlls/wined3d/cs.c | 76 ++++++-------- - dlls/wined3d/query.c | 225 ++++++++++++++++++++++++++--------------- - dlls/wined3d/wined3d_private.h | 7 +- - 3 files changed, 180 insertions(+), 128 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index d1b4d7c..0441ca3 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -69,7 +69,6 @@ enum wined3d_cs_op - WINED3D_CS_OP_RESOURCE_MAP, - WINED3D_CS_OP_RESOURCE_UNMAP, - WINED3D_CS_OP_QUERY_ISSUE, -- WINED3D_CS_OP_QUERY_GET_DATA, - WINED3D_CS_OP_STOP, - }; - -@@ -383,16 +382,6 @@ struct wined3d_cs_query_issue - DWORD flags; - }; - --struct wined3d_cs_query_get_data --{ -- enum wined3d_cs_op opcode; -- struct wined3d_query *query; -- void *data; -- UINT data_size; -- DWORD flags; -- HRESULT *ret; --}; -- - static void wined3d_cs_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -1823,8 +1812,9 @@ static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) - - query->query_ops->query_issue(query, op->flags); - -- if (op->flags & WINED3DISSUE_END) -- InterlockedIncrement(&query->counter_worker); -+ if (wined3d_settings.cs_multithreaded && op->flags & WINED3DISSUE_END -+ && list_empty(&query->poll_list_entry)) -+ list_add_tail(&cs->query_poll_list, &query->poll_list_entry); - - return sizeof(*op); - } -@@ -1841,37 +1831,6 @@ void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *qu - cs->ops->submit(cs, sizeof(*op)); - } - --static UINT wined3d_cs_exec_query_get_data(struct wined3d_cs *cs, const void *data) --{ -- const struct wined3d_cs_query_get_data *op = data; -- struct wined3d_query *query = op->query; -- -- *op->ret = query->query_ops->query_get_data(query, op->data, op->data_size, op->flags); -- -- return sizeof(*op); --} -- --void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query *query, void *data, -- UINT data_size, DWORD flags, HRESULT *ret) --{ -- struct wined3d_cs_query_get_data *op; -- -- op = cs->ops->require_space(cs, sizeof(*op)); -- op->opcode = WINED3D_CS_OP_QUERY_GET_DATA; -- op->query = query; -- op->data = data; -- op->data_size = data_size; -- op->flags = flags; -- op->ret = ret; -- -- cs->ops->submit(cs, sizeof(*op)); -- -- if (wined3d_settings.cs_multithreaded) -- FIXME("Query handling is not particularly fast yet\n"); -- -- cs->ops->finish(cs); --} -- - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -1919,7 +1878,6 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, - /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, - /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, -- /* WINED3D_CS_OP_QUERY_GET_DATA */ wined3d_cs_exec_query_get_data, - }; - - static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) -@@ -2034,17 +1992,45 @@ void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, - wined3d_texture_incref(cs->onscreen_depth_stencil->container); - } - -+static inline void poll_queries(struct wined3d_cs *cs) -+{ -+ struct wined3d_query *query, *cursor; -+ -+ LIST_FOR_EACH_ENTRY_SAFE(query, cursor, &cs->query_poll_list, struct wined3d_query, poll_list_entry) -+ { -+ BOOL ret; -+ -+ ret = query->query_ops->query_poll(query); -+ if (ret) -+ { -+ list_remove(&query->poll_list_entry); -+ list_init(&query->poll_list_entry); -+ InterlockedIncrement(&query->counter_retrieved); -+ } -+ } -+} -+ - static DWORD WINAPI wined3d_cs_run(void *thread_param) - { - struct wined3d_cs *cs = thread_param; - enum wined3d_cs_op opcode; - LONG tail; -+ char poll = 0; - - TRACE("Started.\n"); - -+ list_init(&cs->query_poll_list); - cs->thread_id = GetCurrentThreadId(); - for (;;) - { -+ if (poll == 10) -+ { -+ poll = 0; -+ poll_queries(cs); -+ } -+ else -+ poll++; -+ - if (*((volatile LONG *)&cs->queue.head) == cs->queue.tail) - { - continue; -diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c -index 1c6d713..d607eb5 100644 ---- a/dlls/wined3d/query.c -+++ b/dlls/wined3d/query.c -@@ -241,6 +241,15 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query) - - if (!refcount) - { -+ if (wined3d_settings.cs_multithreaded) -+ { -+ struct wined3d_device *device = query->device; -+ -+ FIXME("waiting for cs\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - /* Queries are specific to the GL context that created them. Not - * deleting the query will obviously leak it, but that's still better - * than potentially deleting a different query with the same id in this -@@ -275,20 +284,10 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query) - HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query, - void *data, UINT data_size, DWORD flags) - { -- HRESULT hr; - TRACE("query %p, data %p, data_size %u, flags %#x.\n", - query, data, data_size, flags); - -- if (query->counter_main != query->counter_worker) -- { -- TRACE("D3DISSUE_END command not submitted to GL yet\n"); -- return S_FALSE; -- } -- -- wined3d_cs_emit_query_get_data(query->device->cs, query, data, data_size, -- flags, &hr); -- -- return hr; -+ return query->query_ops->query_get_data(query, data, data_size, flags); - } - - UINT CDECL wined3d_query_get_data_size(const struct wined3d_query *query) -@@ -317,15 +316,10 @@ static void fill_query_data(void *out, unsigned int out_size, const void *result - static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, - void *data, DWORD size, DWORD flags) - { -- struct wined3d_occlusion_query *oq = query->extendedData; - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -- struct wined3d_context *context; -- GLuint available; -+ struct wined3d_occlusion_query *oq = query->extendedData; - GLuint samples; -- HRESULT res; -- -- TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); - - if (!oq->context) - query->state = QUERY_CREATED; -@@ -339,6 +333,8 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, - return S_OK; - } - -+ TRACE("(%p) : type D3DQUERY_OCCLUSION, data %p, size %#x, flags %#x.\n", query, data, size, flags); -+ - if (query->state == QUERY_BUILDING) - { - /* Msdn says this returns an error, but our tests show that S_FALSE is returned */ -@@ -354,12 +350,37 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, - return S_OK; - } - -+ if (!wined3d_settings.cs_multithreaded) -+ { -+ if (!query->query_ops->query_poll(query)) -+ return S_FALSE; -+ } -+ else if (query->counter_main != query->counter_retrieved) -+ { -+ return S_FALSE; -+ } -+ -+ if (data) -+ fill_query_data(data, size, &oq->samples, sizeof(oq->samples)); -+ -+ return S_OK; -+} -+ -+static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query) -+{ -+ struct wined3d_occlusion_query *oq = query->extendedData; -+ struct wined3d_device *device = query->device; -+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -+ struct wined3d_context *context; -+ GLuint available; -+ GLuint samples; -+ BOOL ret; -+ - if (oq->context->tid != GetCurrentThreadId()) - { - FIXME("%p Wrong thread, returning 1.\n", query); -- samples = 1; -- fill_query_data(data, size, &samples, sizeof(samples)); -- return S_OK; -+ oq->samples = 1; -+ return TRUE; - } - - context = context_acquire(query->device, oq->context->current_rt); -@@ -370,68 +391,78 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, - - if (available) - { -- if (size) -- { -- GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples)); -- checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); -- TRACE("Returning %d samples.\n", samples); -- fill_query_data(data, size, &samples, sizeof(samples)); -- } -- res = S_OK; -+ GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples)); -+ checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); -+ TRACE("Returning %d samples.\n", samples); -+ oq->samples = samples; -+ ret = TRUE; - } - else - { -- res = S_FALSE; -+ ret = FALSE; - } - - context_release(context); - -- return res; -+ return ret; - } - --static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query, -- void *data, DWORD size, DWORD flags) -+static BOOL wined3d_event_query_ops_poll(struct wined3d_query *query) - { - struct wined3d_event_query *event_query = query->extendedData; -- BOOL signaled; - enum wined3d_event_query_result ret; - -- TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); -- -- if (!data || !size) return S_OK; -- if (!event_query) -- { -- WARN("Event query not supported by GL, reporting GPU idle.\n"); -- signaled = TRUE; -- fill_query_data(data, size, &signaled, sizeof(signaled)); -- return S_OK; -- } -- - ret = wined3d_event_query_test(event_query, query->device); - switch(ret) - { - case WINED3D_EVENT_QUERY_OK: - case WINED3D_EVENT_QUERY_NOT_STARTED: -- signaled = TRUE; -- fill_query_data(data, size, &signaled, sizeof(signaled)); -- break; -+ return TRUE; - - case WINED3D_EVENT_QUERY_WAITING: -- signaled = FALSE; -- fill_query_data(data, size, &signaled, sizeof(signaled)); -- break; -+ return FALSE; - - case WINED3D_EVENT_QUERY_WRONG_THREAD: - FIXME("(%p) Wrong thread, reporting GPU idle.\n", query); -- signaled = TRUE; -- fill_query_data(data, size, &signaled, sizeof(signaled)); -- break; -+ return TRUE; - - case WINED3D_EVENT_QUERY_ERROR: - ERR("The GL event query failed, returning D3DERR_INVALIDCALL\n"); -- return WINED3DERR_INVALIDCALL; -+ return TRUE; -+ -+ default: -+ ERR("Unexpected wined3d_event_query_test result %u\n", ret); -+ return TRUE; -+ } -+} -+ -+static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query, -+ void *pData, DWORD dwSize, DWORD flags) -+{ -+ struct wined3d_event_query *event_query = query->extendedData; -+ BOOL *data = pData; -+ enum wined3d_event_query_result ret; -+ -+ TRACE("query %p, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags); -+ -+ if (!pData || !dwSize) return S_OK; -+ if (!event_query) -+ { -+ WARN("Event query not supported by GL, reporting GPU idle.\n"); -+ *data = TRUE; -+ return S_OK; - } - -+ if (!wined3d_settings.cs_multithreaded) -+ ret = query->query_ops->query_poll(query); -+ else if (query->counter_main != query->counter_retrieved) -+ ret = FALSE; -+ else -+ ret = TRUE; -+ -+ if (data) -+ fill_query_data(data, dwSize, &ret, sizeof(ret)); -+ - return S_OK; - } - -@@ -561,33 +592,57 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, - void *data, DWORD size, DWORD flags) - { - struct wined3d_timestamp_query *tq = query->extendedData; -+ -+ TRACE("(%p) : type D3DQUERY_TIMESTAMP, data %p, size %#x, flags %#x.\n", query, data, size, flags); -+ -+ if (query->state == QUERY_CREATED) -+ { -+ UINT64 zero = 0; -+ /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */ -+ TRACE("Query wasn't yet started, returning S_OK.\n"); -+ if (data) -+ fill_query_data(data, size, &zero, sizeof(zero)); -+ return S_OK; -+ } -+ -+ if (!wined3d_settings.cs_multithreaded) -+ { -+ if (!query->query_ops->query_poll(query)) -+ return S_FALSE; -+ } -+ else if (query->counter_main != query->counter_retrieved) -+ { -+ return S_FALSE; -+ } -+ -+ if (data) -+ fill_query_data(data, size, &tq->timestamp, sizeof(tq->timestamp)); -+ -+ return S_OK; -+} -+ -+static BOOL wined3d_timestamp_query_ops_poll(struct wined3d_query *query) -+{ -+ struct wined3d_timestamp_query *tq = query->extendedData; - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_context *context; - GLuint available; - GLuint64 timestamp; -- HRESULT res; -+ BOOL ret; - -- TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); -- -- if (!tq->context) -- query->state = QUERY_CREATED; -- -- if (query->state == QUERY_CREATED) -+ if (!gl_info->supported[ARB_TIMER_QUERY]) - { -- /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves. */ -- TRACE("Query wasn't yet started, returning S_OK.\n"); -- timestamp = 0; -- fill_query_data(data, size, ×tamp, sizeof(timestamp)); -- return S_OK; -+ TRACE("Faking timestamp.\n"); -+ QueryPerformanceCounter((LARGE_INTEGER *)&tq->timestamp); -+ return TRUE; - } - - if (tq->context->tid != GetCurrentThreadId()) - { - FIXME("%p Wrong thread, returning 1.\n", query); -- timestamp = 1; -- fill_query_data(data, size, ×tamp, sizeof(timestamp)); -- return S_OK; -+ tq->timestamp = 1; -+ return TRUE; - } - - context = context_acquire(query->device, tq->context->current_rt); -@@ -598,23 +653,20 @@ static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, - - if (available) - { -- if (size) -- { -- GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); -- checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); -- TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); -- fill_query_data(data, size, ×tamp, sizeof(timestamp)); -- } -- res = S_OK; -+ GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); -+ checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); -+ TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); -+ tq->timestamp = timestamp; -+ ret = TRUE; - } - else - { -- res = S_FALSE; -+ ret = FALSE; - } - - context_release(context); - -- return res; -+ return ret; - } - - static void wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) -@@ -657,15 +709,14 @@ static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_quer - void *data, DWORD size, DWORD flags) - { - TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); -- - if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT) - { - static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE}; - - if (query->state == QUERY_BUILDING) - { -- TRACE("Query is building, returning S_FALSE.\n"); -- return S_FALSE; -+ TRACE("Query is building, returning S_FALSE.\n"); -+ return S_FALSE; - } - - fill_query_data(data, size, &disjoint_data, sizeof(disjoint_data)); -@@ -679,6 +730,11 @@ static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_quer - return S_OK; - } - -+static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *query) -+{ -+ return TRUE; -+} -+ - static void wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) - { - TRACE("query %p, flags %#x.\n", query, flags); -@@ -692,24 +748,28 @@ static void wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *que - static const struct wined3d_query_ops event_query_ops = - { - wined3d_event_query_ops_get_data, -+ wined3d_event_query_ops_poll, - wined3d_event_query_ops_issue, - }; - - static const struct wined3d_query_ops occlusion_query_ops = - { - wined3d_occlusion_query_ops_get_data, -+ wined3d_occlusion_query_ops_poll, - wined3d_occlusion_query_ops_issue, - }; - - static const struct wined3d_query_ops timestamp_query_ops = - { - wined3d_timestamp_query_ops_get_data, -+ wined3d_timestamp_query_ops_poll, - wined3d_timestamp_query_ops_issue, - }; - - static const struct wined3d_query_ops timestamp_disjoint_query_ops = - { - wined3d_timestamp_disjoint_query_ops_get_data, -+ wined3d_timestamp_disjoint_query_ops_poll, - wined3d_timestamp_disjoint_query_ops_issue, - }; - -@@ -810,6 +870,7 @@ static HRESULT query_init(struct wined3d_query *query, struct wined3d_device *de - query->state = QUERY_CREATED; - query->device = device; - query->ref = 1; -+ list_init(&query->poll_list_entry); - - return WINED3D_OK; - } -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 75ca493..ec9a821 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -1112,6 +1112,7 @@ struct wined3d_occlusion_query - struct list entry; - GLuint id; - struct wined3d_context *context; -+ DWORD samples; - }; - - union wined3d_gl_query_object -@@ -1147,6 +1148,7 @@ struct wined3d_timestamp_query - struct list entry; - GLuint id; - struct wined3d_context *context; -+ UINT64 timestamp; - }; - - void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; -@@ -2675,6 +2677,7 @@ struct wined3d_cs - struct wined3d_cs_queue queue; - - LONG pending_presents; -+ struct list query_poll_list; - }; - - struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; -@@ -2770,6 +2773,7 @@ enum query_state { - struct wined3d_query_ops - { - HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags); -+ BOOL (*query_poll)(struct wined3d_query *query); - void (*query_issue)(struct wined3d_query *query, DWORD flags); - }; - -@@ -2785,7 +2789,8 @@ struct wined3d_query - DWORD data_size; - void *extendedData; - -- LONG counter_main, counter_worker; -+ LONG counter_main, counter_retrieved; -+ struct list poll_list_entry; - }; - - /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0082-wined3d-Introduce-a-separate-queue-for-priority-comm.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0082-wined3d-Introduce-a-separate-queue-for-priority-comm.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0082-wined3d-Introduce-a-separate-queue-for-priority-comm.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0082-wined3d-Introduce-a-separate-queue-for-priority-comm.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,268 +0,0 @@ -From 0a14b53f4dcb38e852db14d186d14c8526f3549a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 19:18:03 +0200 -Subject: wined3d: Introduce a separate queue for priority commands - ---- - dlls/wined3d/cs.c | 128 ++++++++++++++++++++++++++++++++++------- - dlls/wined3d/wined3d_private.h | 5 +- - 2 files changed, 110 insertions(+), 23 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 68e1ed7..a7f7694 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -372,7 +372,7 @@ struct wined3d_cs_query_issue - DWORD flags; - }; - --static void wined3d_cs_submit(struct wined3d_cs *cs, size_t size) -+static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); - /* There is only one thread writing to queue.head, InterlockedExchange -@@ -380,6 +380,14 @@ static void wined3d_cs_submit(struct wined3d_cs *cs, size_t size) - InterlockedExchange(&cs->queue.head, new_val); - } - -+static void wined3d_cs_mt_submit_prio(struct wined3d_cs *cs, size_t size) -+{ -+ LONG new_val = (cs->prio_queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -+ /* There is only one thread writing to queue.head, InterlockedExchange -+ * is used for the memory barrier. */ -+ InterlockedExchange(&cs->prio_queue.head, new_val); -+} -+ - static UINT wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data) - { - return sizeof(enum wined3d_cs_op); -@@ -413,15 +421,16 @@ static void wined3d_cs_emit_fence(struct wined3d_cs *cs, BOOL *signalled) - cs->ops->submit(cs, sizeof(*op)); - } - --static void wined3d_cs_finish(struct wined3d_cs *cs) -+static void wined3d_cs_emit_fence_prio(struct wined3d_cs *cs, BOOL *signalled) - { -- BOOL fence; -+ struct wined3d_cs_fence *op; - -- wined3d_cs_emit_fence(cs, &fence); -+ *signalled = FALSE; - -- /* A busy wait should be fine, we're not supposed to have to wait very -- * long. */ -- while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); -+ op = cs->ops->require_space_prio(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_FENCE; -+ op->signalled = signalled; -+ cs->ops->submit_prio(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) -@@ -1765,9 +1774,9 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, - }; - --static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) -+static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) - { -- struct wined3d_cs_queue *queue = &cs->queue; -+ struct wined3d_cs_queue *queue = prio ? &cs->prio_queue : &cs->queue; - size_t queue_size = sizeof(queue->data) / sizeof(*queue->data); - - if (queue_size - size < queue->head) -@@ -1775,7 +1784,7 @@ static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) - struct wined3d_cs_skip *skip; - size_t nop_size = queue_size - queue->head; - -- skip = wined3d_cs_mt_require_space(cs, nop_size); -+ skip = _wined3d_cs_mt_require_space(cs, nop_size, prio); - if (nop_size < sizeof(*skip)) - { - skip->opcode = WINED3D_CS_OP_NOP; -@@ -1786,7 +1795,11 @@ static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) - skip->size = nop_size; - } - -- cs->ops->submit(cs, nop_size); -+ if (prio) -+ cs->ops->submit_prio(cs, nop_size); -+ else -+ cs->ops->submit(cs, nop_size); -+ - assert(!queue->head); - } - -@@ -1813,12 +1826,15 @@ static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) - return &queue->data[queue->head]; - } - --static const struct wined3d_cs_ops wined3d_cs_mt_ops = -+static inline void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) - { -- wined3d_cs_mt_require_space, -- wined3d_cs_submit, -- wined3d_cs_finish, --}; -+ return _wined3d_cs_mt_require_space(cs, size, FALSE); -+} -+ -+static inline void *wined3d_cs_mt_require_space_prio(struct wined3d_cs *cs, size_t size) -+{ -+ return _wined3d_cs_mt_require_space(cs, size, TRUE); -+} - - /* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an - * OP itself. */ -@@ -1829,9 +1845,63 @@ static void wined3d_cs_emit_stop(struct wined3d_cs *cs) - op = wined3d_cs_mt_require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_STOP; - -- wined3d_cs_submit(cs, sizeof(*op)); -+ wined3d_cs_mt_submit(cs, sizeof(*op)); - } - -+static void wined3d_cs_mt_finish(struct wined3d_cs *cs) -+{ -+ BOOL fence; -+ -+ if (cs->thread_id == GetCurrentThreadId()) -+ { -+ static BOOL once; -+ if (!once) -+ { -+ FIXME("flush_and_wait called from cs thread\n"); -+ once = TRUE; -+ } -+ return; -+ } -+ -+ wined3d_cs_emit_fence(cs, &fence); -+ -+ /* A busy wait should be fine, we're not supposed to have to wait very -+ * long. */ -+ while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); -+} -+ -+static void wined3d_cs_mt_finish_prio(struct wined3d_cs *cs) -+{ -+ BOOL fence; -+ -+ if (cs->thread_id == GetCurrentThreadId()) -+ { -+ static BOOL once; -+ if (!once) -+ { -+ FIXME("flush_and_wait called from cs thread\n"); -+ once = TRUE; -+ } -+ return; -+ } -+ -+ wined3d_cs_emit_fence_prio(cs, &fence); -+ -+ /* A busy wait should be fine, we're not supposed to have to wait very -+ * long. */ -+ while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); -+} -+ -+static const struct wined3d_cs_ops wined3d_cs_mt_ops = -+{ -+ wined3d_cs_mt_require_space, -+ wined3d_cs_mt_require_space_prio, -+ wined3d_cs_mt_submit, -+ wined3d_cs_mt_submit_prio, -+ wined3d_cs_mt_finish, -+ wined3d_cs_mt_finish_prio, -+}; -+ - static void wined3d_cs_st_submit(struct wined3d_cs *cs, size_t size) - { - enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)&cs->queue.data; -@@ -1857,8 +1927,11 @@ static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) - static const struct wined3d_cs_ops wined3d_cs_st_ops = - { - wined3d_cs_st_require_space, -+ wined3d_cs_st_require_space, -+ wined3d_cs_st_submit, - wined3d_cs_st_submit, - wined3d_cs_st_finish, -+ wined3d_cs_st_finish, - }; - - void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, -@@ -1901,6 +1974,7 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) - enum wined3d_cs_op opcode; - LONG tail; - char poll = 0; -+ struct wined3d_cs_queue *queue; - - TRACE("Started.\n"); - -@@ -1916,13 +1990,23 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) - else - poll++; - -- if (*((volatile LONG *)&cs->queue.head) == cs->queue.tail) -+ if (*((volatile LONG *)&cs->prio_queue.head) != cs->prio_queue.tail) -+ { -+ queue = &cs->prio_queue; -+ } -+ else if (*((volatile LONG *)&cs->queue.head) != cs->queue.tail) -+ { -+ queue = &cs->queue; -+ if (*((volatile LONG *)&cs->prio_queue.head) != cs->prio_queue.tail) -+ queue = &cs->prio_queue; -+ } -+ else - { - continue; - } - -- tail = cs->queue.tail; -- opcode = *(const enum wined3d_cs_op *)&cs->queue.data[tail]; -+ tail = queue->tail; -+ opcode = *(const enum wined3d_cs_op *)&queue->data[tail]; - - if (opcode >= WINED3D_CS_OP_STOP) - { -@@ -1931,9 +2015,9 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) - goto done; - } - -- tail += wined3d_cs_op_handlers[opcode](cs, &cs->queue.data[tail]); -+ tail += wined3d_cs_op_handlers[opcode](cs, &queue->data[tail]); - tail &= (WINED3D_CS_QUEUE_SIZE - 1); -- InterlockedExchange(&cs->queue.tail, tail); -+ InterlockedExchange(&queue->tail, tail); - } - - done: -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 7bda9f0..cf01a6a 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2550,8 +2550,11 @@ struct wined3d_cs_queue - struct wined3d_cs_ops - { - void *(*require_space)(struct wined3d_cs *cs, size_t size); -+ void *(*require_space_prio)(struct wined3d_cs *cs, size_t size); - void (*submit)(struct wined3d_cs *cs, size_t size); -+ void (*submit_prio)(struct wined3d_cs *cs, size_t size); - void (*finish)(struct wined3d_cs *cs); -+ void (*finish_prio)(struct wined3d_cs *cs); - }; - - struct wined3d_cs -@@ -2563,7 +2566,7 @@ struct wined3d_cs - DWORD thread_id; - struct wined3d_surface *onscreen_depth_stencil; - -- struct wined3d_cs_queue queue; -+ struct wined3d_cs_queue queue, prio_queue; - - LONG pending_presents; - struct list query_poll_list; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0082-wined3d-Separate-main-and-worker-thread-query-state.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0082-wined3d-Separate-main-and-worker-thread-query-state.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0082-wined3d-Separate-main-and-worker-thread-query-state.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0082-wined3d-Separate-main-and-worker-thread-query-state.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,138 @@ +From 1a53e5cd7279145ad9f78f2970a186f488216d6b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 24 Jul 2013 16:34:17 +0200 +Subject: wined3d: Separate main and worker thread query state + +--- + dlls/wined3d/query.c | 34 ++++++++++++---------------------- + dlls/wined3d/wined3d_private.h | 1 + + 2 files changed, 13 insertions(+), 22 deletions(-) + +diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c +index f377eea..97483a2 100644 +--- a/dlls/wined3d/query.c ++++ b/dlls/wined3d/query.c +@@ -299,6 +299,12 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) + query->counter_main++; + + wined3d_cs_emit_query_issue(query->device->cs, query, flags); ++ ++ if (flags & WINED3DISSUE_BEGIN) ++ query->state = QUERY_BUILDING; ++ else ++ query->state = QUERY_SIGNALLED; ++ + return WINED3D_OK; + } + +@@ -493,11 +499,6 @@ static void wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD fla + /* Started implicitly at device creation */ + ERR("Event query issued with START flag - what to do?\n"); + } +- +- if (flags & WINED3DISSUE_BEGIN) +- query->state = QUERY_BUILDING; +- else +- query->state = QUERY_SIGNALLED; + } + + static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) +@@ -515,7 +516,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD + /* This is allowed according to msdn and our tests. Reset the query and restart */ + if (flags & WINED3DISSUE_BEGIN) + { +- if (query->state == QUERY_BUILDING) ++ if (oq->started) + { + if (oq->context->tid != GetCurrentThreadId()) + { +@@ -544,6 +545,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD + checkGLcall("glBeginQuery()"); + + context_release(context); ++ oq->started = TRUE; + } + if (flags & WINED3DISSUE_END) + { +@@ -551,7 +553,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD + * our tests show that it returns OK. But OpenGL doesn't like it, so avoid + * generating an error + */ +- if (query->state == QUERY_BUILDING) ++ if (oq->started) + { + if (oq->context->tid != GetCurrentThreadId()) + { +@@ -567,6 +569,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD + context_release(context); + } + } ++ oq->started = FALSE; + } + } + else +@@ -574,11 +577,6 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD + FIXME("%p Occlusion queries not supported.\n", query); + } + +- if (flags & WINED3DISSUE_BEGIN) +- query->state = QUERY_BUILDING; +- else +- query->state = QUERY_SIGNALLED; +- + return; + } + +@@ -694,9 +692,6 @@ static void wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD + { + ERR("Timestamp queries not supported.\n"); + } +- +- if (flags & WINED3DISSUE_END) +- query->state = QUERY_SIGNALLED; + } + + static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query, +@@ -732,11 +727,6 @@ static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *quer + static void wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) + { + TRACE("query %p, flags %#x.\n", query, flags); +- +- if (flags & WINED3DISSUE_BEGIN) +- query->state = QUERY_BUILDING; +- if (flags & WINED3DISSUE_END) +- query->state = QUERY_SIGNALLED; + } + + static const struct wined3d_query_ops event_query_ops = +@@ -785,13 +775,13 @@ static HRESULT query_init(struct wined3d_query *query, struct wined3d_device *de + } + query->query_ops = &occlusion_query_ops; + query->data_size = sizeof(DWORD); +- query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query)); ++ query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ++ sizeof(struct wined3d_occlusion_query)); + if (!query->extendedData) + { + ERR("Failed to allocate occlusion query extended data.\n"); + return E_OUTOFMEMORY; + } +- ((struct wined3d_occlusion_query *)query->extendedData)->context = NULL; + break; + + case WINED3D_QUERY_TYPE_EVENT: +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 28badf6..ec474dd 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -1052,6 +1052,7 @@ struct wined3d_occlusion_query + GLuint id; + struct wined3d_context *context; + DWORD samples; ++ BOOL started; + }; + + union wined3d_gl_query_object +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0083-wined3d-Destroy-queries-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0083-wined3d-Destroy-queries-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0083-wined3d-Destroy-queries-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0083-wined3d-Destroy-queries-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,183 +0,0 @@ -From ef12b024a49a4390df02fad20938e04d5cfae35e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 21:54:45 +0200 -Subject: wined3d: Destroy queries through the CS - ---- - dlls/wined3d/cs.c | 31 ++++++++++++++++++++ - dlls/wined3d/query.c | 66 +++++++++++++++++++----------------------- - dlls/wined3d/wined3d_private.h | 3 ++ - 3 files changed, 64 insertions(+), 36 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index a7f7694..b2af05b 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -68,6 +68,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_RESOURCE_MAP, - WINED3D_CS_OP_RESOURCE_UNMAP, - WINED3D_CS_OP_QUERY_ISSUE, -+ WINED3D_CS_OP_QUERY_DESTROY, - WINED3D_CS_OP_STOP, - }; - -@@ -372,6 +373,12 @@ struct wined3d_cs_query_issue - DWORD flags; - }; - -+struct wined3d_cs_query_destroy -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_query *query; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -1726,6 +1733,29 @@ void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *qu - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_query_destroy(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_query_destroy *op = data; -+ -+ if (!list_empty(&op->query->poll_list_entry)) -+ list_remove(&op->query->poll_list_entry); -+ -+ wined3d_query_destroy(op->query); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query *query) -+{ -+ struct wined3d_cs_query_destroy *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_QUERY_DESTROY; -+ op->query = query; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -1772,6 +1802,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, - /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, - /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, -+ /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c -index 621a9d7..f377eea 100644 ---- a/dlls/wined3d/query.c -+++ b/dlls/wined3d/query.c -@@ -233,50 +233,44 @@ ULONG CDECL wined3d_query_incref(struct wined3d_query *query) - return refcount; - } - --ULONG CDECL wined3d_query_decref(struct wined3d_query *query) -+void wined3d_query_destroy(struct wined3d_query *query) - { -- ULONG refcount = InterlockedDecrement(&query->ref); -- -- TRACE("%p decreasing refcount to %u.\n", query, refcount); -+ /* Queries are specific to the GL context that created them. Not -+ * deleting the query will obviously leak it, but that's still better -+ * than potentially deleting a different query with the same id in this -+ * context, and (still) leaking the actual query. */ -+ if (query->type == WINED3D_QUERY_TYPE_EVENT) -+ { -+ struct wined3d_event_query *event_query = query->extendedData; -+ if (event_query) wined3d_event_query_destroy(event_query); -+ } -+ else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION) -+ { -+ struct wined3d_occlusion_query *oq = query->extendedData; - -- if (!refcount) -+ if (oq->context) context_free_occlusion_query(oq); -+ HeapFree(GetProcessHeap(), 0, query->extendedData); -+ } -+ else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP) - { -- if (wined3d_settings.cs_multithreaded) -- { -- struct wined3d_device *device = query->device; -+ struct wined3d_timestamp_query *tq = query->extendedData; - -- FIXME("waiting for cs\n"); -- wined3d_cs_emit_glfinish(device->cs); -- device->cs->ops->finish(device->cs); -- } -+ if (tq->context) -+ context_free_timestamp_query(tq); -+ HeapFree(GetProcessHeap(), 0, query->extendedData); -+ } - -- /* Queries are specific to the GL context that created them. Not -- * deleting the query will obviously leak it, but that's still better -- * than potentially deleting a different query with the same id in this -- * context, and (still) leaking the actual query. */ -- if (query->type == WINED3D_QUERY_TYPE_EVENT) -- { -- struct wined3d_event_query *event_query = query->extendedData; -- if (event_query) wined3d_event_query_destroy(event_query); -- } -- else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION) -- { -- struct wined3d_occlusion_query *oq = query->extendedData; -+ HeapFree(GetProcessHeap(), 0, query); -+} - -- if (oq->context) context_free_occlusion_query(oq); -- HeapFree(GetProcessHeap(), 0, query->extendedData); -- } -- else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP) -- { -- struct wined3d_timestamp_query *tq = query->extendedData; -+ULONG CDECL wined3d_query_decref(struct wined3d_query *query) -+{ -+ ULONG refcount = InterlockedDecrement(&query->ref); - -- if (tq->context) -- context_free_timestamp_query(tq); -- HeapFree(GetProcessHeap(), 0, query->extendedData); -- } -+ TRACE("%p decreasing refcount to %u.\n", query, refcount); - -- HeapFree(GetProcessHeap(), 0, query); -- } -+ if (!refcount) -+ wined3d_cs_emit_query_destroy(query->device->cs, query); - - return refcount; - } -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index cf01a6a..28badf6 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2649,6 +2649,7 @@ void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *qu - DWORD flags) DECLSPEC_HIDDEN; - void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query *query, void *data, - UINT data_size, DWORD flags, HRESULT *ret) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query *query) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d -@@ -2683,6 +2684,8 @@ struct wined3d_query - struct list poll_list_entry; - }; - -+void wined3d_query_destroy(struct wined3d_query *query) DECLSPEC_HIDDEN; -+ - /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other - * fixed function semantics as D3DCOLOR or FLOAT16 */ - enum wined3d_buffer_conversion_type --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0083-wined3d-Don-t-poll-queries-that-failed-to-start.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0083-wined3d-Don-t-poll-queries-that-failed-to-start.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0083-wined3d-Don-t-poll-queries-that-failed-to-start.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0083-wined3d-Don-t-poll-queries-that-failed-to-start.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,134 @@ +From 3ee3d46182ba5a4f968d2bed318a80e9380b1246 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 24 Jul 2013 17:27:35 +0200 +Subject: wined3d: Don't poll queries that failed to start + +--- + dlls/wined3d/cs.c | 5 +++-- + dlls/wined3d/query.c | 21 +++++++++++++++------ + dlls/wined3d/wined3d_private.h | 2 +- + 3 files changed, 19 insertions(+), 9 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index b2af05b..4c0695a 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -1711,10 +1711,11 @@ static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_query_issue *op = data; + struct wined3d_query *query = op->query; ++ BOOL poll; + +- query->query_ops->query_issue(query, op->flags); ++ poll = query->query_ops->query_issue(query, op->flags); + +- if (wined3d_settings.cs_multithreaded && op->flags & WINED3DISSUE_END ++ if (wined3d_settings.cs_multithreaded && poll + && list_empty(&query->poll_list_entry)) + list_add_tail(&cs->query_poll_list, &query->poll_list_entry); + +diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c +index 97483a2..a42a1bd 100644 +--- a/dlls/wined3d/query.c ++++ b/dlls/wined3d/query.c +@@ -480,7 +480,7 @@ enum wined3d_query_type CDECL wined3d_query_get_type(const struct wined3d_query + return query->type; + } + +-static void wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) ++static BOOL wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) + { + TRACE("query %p, flags %#x.\n", query, flags); + +@@ -490,21 +490,24 @@ static void wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD fla + struct wined3d_event_query *event_query = query->extendedData; + + /* Faked event query support */ +- if (!event_query) return; ++ if (!event_query) return FALSE; + + wined3d_event_query_issue(event_query, query->device); ++ return TRUE; + } + else if (flags & WINED3DISSUE_BEGIN) + { + /* Started implicitly at device creation */ + ERR("Event query issued with START flag - what to do?\n"); + } ++ return FALSE; + } + +-static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) ++static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) + { + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++ BOOL poll = FALSE; + + TRACE("query %p, flags %#x.\n", query, flags); + +@@ -570,6 +573,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD + } + } + oq->started = FALSE; ++ poll = TRUE; + } + } + else +@@ -577,7 +581,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD + FIXME("%p Occlusion queries not supported.\n", query); + } + +- return; ++ return poll; + } + + static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, +@@ -661,7 +665,7 @@ static BOOL wined3d_timestamp_query_ops_poll(struct wined3d_query *query) + return ret; + } + +-static void wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) ++static BOOL wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) + { + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; +@@ -692,6 +696,10 @@ static void wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD + { + ERR("Timestamp queries not supported.\n"); + } ++ ++ if (flags & WINED3DISSUE_END) ++ return TRUE; ++ return FALSE; + } + + static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query, +@@ -724,9 +732,10 @@ static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *quer + return TRUE; + } + +-static void wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) ++static BOOL wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) + { + TRACE("query %p, flags %#x.\n", query, flags); ++ return FALSE; + } + + static const struct wined3d_query_ops event_query_ops = +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index ec474dd..8dd9786 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2666,7 +2666,7 @@ struct wined3d_query_ops + { + HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags); + BOOL (*query_poll)(struct wined3d_query *query); +- void (*query_issue)(struct wined3d_query *query, DWORD flags); ++ BOOL (*query_issue)(struct wined3d_query *query, DWORD flags); + }; + + struct wined3d_query +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0084-wined3d-Remove-restated-queries-from-the-poll-list.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0084-wined3d-Remove-restated-queries-from-the-poll-list.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0084-wined3d-Remove-restated-queries-from-the-poll-list.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0084-wined3d-Remove-restated-queries-from-the-poll-list.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,40 @@ +From d46500650ef16a6bd292705ce9896bc8b1427d99 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 24 Jul 2013 17:50:16 +0200 +Subject: wined3d: Remove restated queries from the poll list + +--- + dlls/wined3d/cs.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 4c0695a..5c19a17 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -1715,9 +1715,20 @@ static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) + + poll = query->query_ops->query_issue(query, op->flags); + +- if (wined3d_settings.cs_multithreaded && poll +- && list_empty(&query->poll_list_entry)) +- list_add_tail(&cs->query_poll_list, &query->poll_list_entry); ++ if (wined3d_settings.cs_multithreaded) ++ { ++ if (poll && list_empty(&query->poll_list_entry)) ++ { ++ list_add_tail(&cs->query_poll_list, &query->poll_list_entry); ++ } ++ else if (!poll && !list_empty(&query->poll_list_entry)) ++ { ++ /* Can happen if occlusion queries are restarted. This discards the old ++ * result, polling it could result in a GL error */ ++ list_remove(&query->poll_list_entry); ++ list_init(&query->poll_list_entry); ++ } ++ } + + return sizeof(*op); + } +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0084-wined3d-Separate-main-and-worker-thread-query-state.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0084-wined3d-Separate-main-and-worker-thread-query-state.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0084-wined3d-Separate-main-and-worker-thread-query-state.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0084-wined3d-Separate-main-and-worker-thread-query-state.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,138 +0,0 @@ -From 1a53e5cd7279145ad9f78f2970a186f488216d6b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 24 Jul 2013 16:34:17 +0200 -Subject: wined3d: Separate main and worker thread query state - ---- - dlls/wined3d/query.c | 34 ++++++++++++---------------------- - dlls/wined3d/wined3d_private.h | 1 + - 2 files changed, 13 insertions(+), 22 deletions(-) - -diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c -index f377eea..97483a2 100644 ---- a/dlls/wined3d/query.c -+++ b/dlls/wined3d/query.c -@@ -299,6 +299,12 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags) - query->counter_main++; - - wined3d_cs_emit_query_issue(query->device->cs, query, flags); -+ -+ if (flags & WINED3DISSUE_BEGIN) -+ query->state = QUERY_BUILDING; -+ else -+ query->state = QUERY_SIGNALLED; -+ - return WINED3D_OK; - } - -@@ -493,11 +499,6 @@ static void wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD fla - /* Started implicitly at device creation */ - ERR("Event query issued with START flag - what to do?\n"); - } -- -- if (flags & WINED3DISSUE_BEGIN) -- query->state = QUERY_BUILDING; -- else -- query->state = QUERY_SIGNALLED; - } - - static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) -@@ -515,7 +516,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD - /* This is allowed according to msdn and our tests. Reset the query and restart */ - if (flags & WINED3DISSUE_BEGIN) - { -- if (query->state == QUERY_BUILDING) -+ if (oq->started) - { - if (oq->context->tid != GetCurrentThreadId()) - { -@@ -544,6 +545,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD - checkGLcall("glBeginQuery()"); - - context_release(context); -+ oq->started = TRUE; - } - if (flags & WINED3DISSUE_END) - { -@@ -551,7 +553,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD - * our tests show that it returns OK. But OpenGL doesn't like it, so avoid - * generating an error - */ -- if (query->state == QUERY_BUILDING) -+ if (oq->started) - { - if (oq->context->tid != GetCurrentThreadId()) - { -@@ -567,6 +569,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD - context_release(context); - } - } -+ oq->started = FALSE; - } - } - else -@@ -574,11 +577,6 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD - FIXME("%p Occlusion queries not supported.\n", query); - } - -- if (flags & WINED3DISSUE_BEGIN) -- query->state = QUERY_BUILDING; -- else -- query->state = QUERY_SIGNALLED; -- - return; - } - -@@ -694,9 +692,6 @@ static void wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD - { - ERR("Timestamp queries not supported.\n"); - } -- -- if (flags & WINED3DISSUE_END) -- query->state = QUERY_SIGNALLED; - } - - static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query, -@@ -732,11 +727,6 @@ static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *quer - static void wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) - { - TRACE("query %p, flags %#x.\n", query, flags); -- -- if (flags & WINED3DISSUE_BEGIN) -- query->state = QUERY_BUILDING; -- if (flags & WINED3DISSUE_END) -- query->state = QUERY_SIGNALLED; - } - - static const struct wined3d_query_ops event_query_ops = -@@ -785,13 +775,13 @@ static HRESULT query_init(struct wined3d_query *query, struct wined3d_device *de - } - query->query_ops = &occlusion_query_ops; - query->data_size = sizeof(DWORD); -- query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query)); -+ query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(struct wined3d_occlusion_query)); - if (!query->extendedData) - { - ERR("Failed to allocate occlusion query extended data.\n"); - return E_OUTOFMEMORY; - } -- ((struct wined3d_occlusion_query *)query->extendedData)->context = NULL; - break; - - case WINED3D_QUERY_TYPE_EVENT: -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 28badf6..ec474dd 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -1052,6 +1052,7 @@ struct wined3d_occlusion_query - GLuint id; - struct wined3d_context *context; - DWORD samples; -+ BOOL started; - }; - - union wined3d_gl_query_object --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0085-wined3d-Don-t-poll-queries-that-failed-to-start.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0085-wined3d-Don-t-poll-queries-that-failed-to-start.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0085-wined3d-Don-t-poll-queries-that-failed-to-start.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0085-wined3d-Don-t-poll-queries-that-failed-to-start.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -From 3ee3d46182ba5a4f968d2bed318a80e9380b1246 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 24 Jul 2013 17:27:35 +0200 -Subject: wined3d: Don't poll queries that failed to start - ---- - dlls/wined3d/cs.c | 5 +++-- - dlls/wined3d/query.c | 21 +++++++++++++++------ - dlls/wined3d/wined3d_private.h | 2 +- - 3 files changed, 19 insertions(+), 9 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index b2af05b..4c0695a 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -1711,10 +1711,11 @@ static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_query_issue *op = data; - struct wined3d_query *query = op->query; -+ BOOL poll; - -- query->query_ops->query_issue(query, op->flags); -+ poll = query->query_ops->query_issue(query, op->flags); - -- if (wined3d_settings.cs_multithreaded && op->flags & WINED3DISSUE_END -+ if (wined3d_settings.cs_multithreaded && poll - && list_empty(&query->poll_list_entry)) - list_add_tail(&cs->query_poll_list, &query->poll_list_entry); - -diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c -index 97483a2..a42a1bd 100644 ---- a/dlls/wined3d/query.c -+++ b/dlls/wined3d/query.c -@@ -480,7 +480,7 @@ enum wined3d_query_type CDECL wined3d_query_get_type(const struct wined3d_query - return query->type; - } - --static void wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) -+static BOOL wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) - { - TRACE("query %p, flags %#x.\n", query, flags); - -@@ -490,21 +490,24 @@ static void wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD fla - struct wined3d_event_query *event_query = query->extendedData; - - /* Faked event query support */ -- if (!event_query) return; -+ if (!event_query) return FALSE; - - wined3d_event_query_issue(event_query, query->device); -+ return TRUE; - } - else if (flags & WINED3DISSUE_BEGIN) - { - /* Started implicitly at device creation */ - ERR("Event query issued with START flag - what to do?\n"); - } -+ return FALSE; - } - --static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) -+static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) - { - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -+ BOOL poll = FALSE; - - TRACE("query %p, flags %#x.\n", query, flags); - -@@ -570,6 +573,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD - } - } - oq->started = FALSE; -+ poll = TRUE; - } - } - else -@@ -577,7 +581,7 @@ static void wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD - FIXME("%p Occlusion queries not supported.\n", query); - } - -- return; -+ return poll; - } - - static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, -@@ -661,7 +665,7 @@ static BOOL wined3d_timestamp_query_ops_poll(struct wined3d_query *query) - return ret; - } - --static void wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) -+static BOOL wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) - { - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -@@ -692,6 +696,10 @@ static void wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD - { - ERR("Timestamp queries not supported.\n"); - } -+ -+ if (flags & WINED3DISSUE_END) -+ return TRUE; -+ return FALSE; - } - - static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query, -@@ -724,9 +732,10 @@ static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *quer - return TRUE; - } - --static void wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) -+static BOOL wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) - { - TRACE("query %p, flags %#x.\n", query, flags); -+ return FALSE; - } - - static const struct wined3d_query_ops event_query_ops = -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index ec474dd..8dd9786 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2666,7 +2666,7 @@ struct wined3d_query_ops - { - HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags); - BOOL (*query_poll)(struct wined3d_query *query); -- void (*query_issue)(struct wined3d_query *query, DWORD flags); -+ BOOL (*query_issue)(struct wined3d_query *query, DWORD flags); - }; - - struct wined3d_query --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0085-wined3d-Don-t-reset-the-query-state-if-it-doesn-t-ha.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0085-wined3d-Don-t-reset-the-query-state-if-it-doesn-t-ha.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0085-wined3d-Don-t-reset-the-query-state-if-it-doesn-t-ha.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0085-wined3d-Don-t-reset-the-query-state-if-it-doesn-t-ha.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,31 @@ +From 681469685b22ba7fedfbc808498028b518b890a0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Mon, 5 Aug 2013 13:07:42 +0200 +Subject: wined3d: Don't reset the query state if it doesn't have a ctx + +The CS recreates occlusion queries and changes the context variable. +This leads to incorrect query results. + +TODO: Before sending, find out why the line was there in the first place +and if it is needed with the multithreaded and/or singlethreaded CS. +--- + dlls/wined3d/query.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c +index a42a1bd..39d663a 100644 +--- a/dlls/wined3d/query.c ++++ b/dlls/wined3d/query.c +@@ -321,9 +321,6 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, + struct wined3d_occlusion_query *oq = query->extendedData; + GLuint samples; + +- if (!oq->context) +- query->state = QUERY_CREATED; +- + if (query->state == QUERY_CREATED) + { + /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */ +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0086-wined3d-Put-this-into-the-query-poll-patch.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0086-wined3d-Put-this-into-the-query-poll-patch.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0086-wined3d-Put-this-into-the-query-poll-patch.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0086-wined3d-Put-this-into-the-query-poll-patch.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,52 @@ +From 5797fdf345e0af334745c957771b6a7a770eecbc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 30 Aug 2013 13:53:48 +0200 +Subject: wined3d: Put this into the query poll patch + +--- + dlls/wined3d/cs.c | 12 ++++++++++++ + dlls/wined3d/query.c | 2 +- + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 5c19a17..3540cb7 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -1728,6 +1728,18 @@ static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) + list_remove(&query->poll_list_entry); + list_init(&query->poll_list_entry); + } ++ else if (op->flags & WINED3DISSUE_END) ++ { ++ /* Can happen when an occlusion query is ended without being started, ++ * in which case we don't want to poll, but still have to counter-balance ++ * the increment of the main counter (!poll && list_empty). ++ * ++ * This can also happen if an event query is re-issued before the first ++ * fence was reached (poll && !list_empty). In this case the query is ++ * already in the list and the poll function will check the new fence. ++ * We have to counter-balance the discarded increment. */ ++ InterlockedIncrement(&query->counter_retrieved); ++ } + } + + return sizeof(*op); +diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c +index 39d663a..f33b30e 100644 +--- a/dlls/wined3d/query.c ++++ b/dlls/wined3d/query.c +@@ -567,10 +567,10 @@ static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD + checkGLcall("glEndQuery()"); + + context_release(context); ++ poll = TRUE; + } + } + oq->started = FALSE; +- poll = TRUE; + } + } + else +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0086-wined3d-Remove-restated-queries-from-the-poll-list.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0086-wined3d-Remove-restated-queries-from-the-poll-list.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0086-wined3d-Remove-restated-queries-from-the-poll-list.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0086-wined3d-Remove-restated-queries-from-the-poll-list.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -From d46500650ef16a6bd292705ce9896bc8b1427d99 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 24 Jul 2013 17:50:16 +0200 -Subject: wined3d: Remove restated queries from the poll list - ---- - dlls/wined3d/cs.c | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 4c0695a..5c19a17 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -1715,9 +1715,20 @@ static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) - - poll = query->query_ops->query_issue(query, op->flags); - -- if (wined3d_settings.cs_multithreaded && poll -- && list_empty(&query->poll_list_entry)) -- list_add_tail(&cs->query_poll_list, &query->poll_list_entry); -+ if (wined3d_settings.cs_multithreaded) -+ { -+ if (poll && list_empty(&query->poll_list_entry)) -+ { -+ list_add_tail(&cs->query_poll_list, &query->poll_list_entry); -+ } -+ else if (!poll && !list_empty(&query->poll_list_entry)) -+ { -+ /* Can happen if occlusion queries are restarted. This discards the old -+ * result, polling it could result in a GL error */ -+ list_remove(&query->poll_list_entry); -+ list_init(&query->poll_list_entry); -+ } -+ } - - return sizeof(*op); - } --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0087-wined3d-Don-t-reset-the-query-state-if-it-doesn-t-ha.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0087-wined3d-Don-t-reset-the-query-state-if-it-doesn-t-ha.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0087-wined3d-Don-t-reset-the-query-state-if-it-doesn-t-ha.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0087-wined3d-Don-t-reset-the-query-state-if-it-doesn-t-ha.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -From 681469685b22ba7fedfbc808498028b518b890a0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Mon, 5 Aug 2013 13:07:42 +0200 -Subject: wined3d: Don't reset the query state if it doesn't have a ctx - -The CS recreates occlusion queries and changes the context variable. -This leads to incorrect query results. - -TODO: Before sending, find out why the line was there in the first place -and if it is needed with the multithreaded and/or singlethreaded CS. ---- - dlls/wined3d/query.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c -index a42a1bd..39d663a 100644 ---- a/dlls/wined3d/query.c -+++ b/dlls/wined3d/query.c -@@ -321,9 +321,6 @@ static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, - struct wined3d_occlusion_query *oq = query->extendedData; - GLuint samples; - -- if (!oq->context) -- query->state = QUERY_CREATED; -- - if (query->state == QUERY_CREATED) - { - /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */ --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0087-wined3d-Send-update_surface-commands-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0087-wined3d-Send-update_surface-commands-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0087-wined3d-Send-update_surface-commands-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0087-wined3d-Send-update_surface-commands-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,128 @@ +From 961a8cb3c42a2969dd1500b4fc16adb4d47b514f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 1 Aug 2013 00:00:26 +0200 +Subject: wined3d: Send update_surface commands through the CS + +--- + dlls/wined3d/cs.c | 48 ++++++++++++++++++++++++++++++++++++++++++ + dlls/wined3d/device.c | 9 ++------ + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 52 insertions(+), 7 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 3540cb7..3264d17 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -69,6 +69,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_RESOURCE_UNMAP, + WINED3D_CS_OP_QUERY_ISSUE, + WINED3D_CS_OP_QUERY_DESTROY, ++ WINED3D_CS_OP_UPDATE_SURFACE, + WINED3D_CS_OP_STOP, + }; + +@@ -379,6 +380,15 @@ struct wined3d_cs_query_destroy + struct wined3d_query *query; + }; + ++struct wined3d_cs_update_surface ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_surface *src, *dst; ++ RECT src_rect; ++ POINT dst_point; ++ BOOL has_src_rect, has_dst_point; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -1780,6 +1790,43 @@ void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query * + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_update_surface(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_update_surface *op = data; ++ ++ surface_upload_from_surface(op->dst, op->has_dst_point ? &op->dst_point : NULL, ++ op->src, op->has_src_rect ? &op->src_rect : NULL); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surface *src, const RECT *src_rect, ++ struct wined3d_surface *dst, const POINT *dst_point) ++{ ++ struct wined3d_cs_update_surface *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_UPDATE_SURFACE; ++ op->src = src; ++ op->dst = dst; ++ op->has_src_rect = FALSE; ++ op->has_dst_point = FALSE; ++ ++ if (src_rect) ++ { ++ op->has_src_rect = TRUE; ++ op->src_rect = *src_rect; ++ } ++ ++ if (dst_point) ++ { ++ op->has_dst_point = TRUE; ++ op->dst_point = *dst_point; ++ } ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -1827,6 +1874,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, + /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, + /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, ++ /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index cd90c76..ed055f8 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -3796,14 +3796,9 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, + return WINED3DERR_INVALIDCALL; + } + +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- wined3d_cs_emit_glfinish(device->cs); +- device->cs->ops->finish(device->cs); +- } ++ wined3d_cs_emit_update_surface(device->cs, src_surface, src_rect, dst_surface, dst_point); + +- return surface_upload_from_surface(dst_surface, dst_point, src_surface, src_rect); ++ return WINED3D_OK; + } + + void CDECL wined3d_device_copy_resource(struct wined3d_device *device, +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 8dd9786..07d1613 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2651,6 +2651,8 @@ void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *qu + void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query *query, void *data, + UINT data_size, DWORD flags, HRESULT *ret) DECLSPEC_HIDDEN; + void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query *query) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surface *src, ++ const RECT *src_rect, struct wined3d_surface *dst, const POINT *dst_point) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0088-wined3d-Put-this-into-the-query-poll-patch.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0088-wined3d-Put-this-into-the-query-poll-patch.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0088-wined3d-Put-this-into-the-query-poll-patch.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0088-wined3d-Put-this-into-the-query-poll-patch.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -From 5797fdf345e0af334745c957771b6a7a770eecbc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 30 Aug 2013 13:53:48 +0200 -Subject: wined3d: Put this into the query poll patch - ---- - dlls/wined3d/cs.c | 12 ++++++++++++ - dlls/wined3d/query.c | 2 +- - 2 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 5c19a17..3540cb7 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -1728,6 +1728,18 @@ static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) - list_remove(&query->poll_list_entry); - list_init(&query->poll_list_entry); - } -+ else if (op->flags & WINED3DISSUE_END) -+ { -+ /* Can happen when an occlusion query is ended without being started, -+ * in which case we don't want to poll, but still have to counter-balance -+ * the increment of the main counter (!poll && list_empty). -+ * -+ * This can also happen if an event query is re-issued before the first -+ * fence was reached (poll && !list_empty). In this case the query is -+ * already in the list and the poll function will check the new fence. -+ * We have to counter-balance the discarded increment. */ -+ InterlockedIncrement(&query->counter_retrieved); -+ } - } - - return sizeof(*op); -diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c -index 39d663a..f33b30e 100644 ---- a/dlls/wined3d/query.c -+++ b/dlls/wined3d/query.c -@@ -567,10 +567,10 @@ static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD - checkGLcall("glEndQuery()"); - - context_release(context); -+ poll = TRUE; - } - } - oq->started = FALSE; -- poll = TRUE; - } - } - else --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0088-wined3d-Send-texture-preloads-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0088-wined3d-Send-texture-preloads-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0088-wined3d-Send-texture-preloads-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0088-wined3d-Send-texture-preloads-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,107 @@ +From dd0852f22f9a3e04e9fefae6c0a3ac4913cc390d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 1 Aug 2013 00:10:40 +0200 +Subject: wined3d: Send texture preloads through the CS + +--- + dlls/wined3d/cs.c | 32 ++++++++++++++++++++++++++++++++ + dlls/wined3d/texture.c | 6 ++---- + dlls/wined3d/wined3d_private.h | 1 + + 3 files changed, 35 insertions(+), 4 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 3264d17..78e5010 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -70,6 +70,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_QUERY_ISSUE, + WINED3D_CS_OP_QUERY_DESTROY, + WINED3D_CS_OP_UPDATE_SURFACE, ++ WINED3D_CS_OP_TEXTURE_PRELOAD, + WINED3D_CS_OP_STOP, + }; + +@@ -389,6 +390,12 @@ struct wined3d_cs_update_surface + BOOL has_src_rect, has_dst_point; + }; + ++struct wined3d_cs_texture_preload ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_texture *texture; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -1827,6 +1834,30 @@ void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surfac + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_texture_preload(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_texture_preload *op = data; ++ struct wined3d_context *context; ++ struct wined3d_texture *texture = op->texture; ++ ++ context = context_acquire(cs->device, NULL); ++ wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); ++ context_release(context); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_texture *texture) ++{ ++ struct wined3d_cs_texture_preload *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_TEXTURE_PRELOAD; ++ op->texture = texture; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -1875,6 +1906,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, + /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, + /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, ++ /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index b7891d9..ea8589a 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -569,10 +569,8 @@ void wined3d_texture_load(struct wined3d_texture *texture, + + void CDECL wined3d_texture_preload(struct wined3d_texture *texture) + { +- struct wined3d_context *context; +- context = context_acquire(texture->resource.device, NULL); +- wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); +- context_release(context); ++ const struct wined3d_device *device = texture->resource.device; ++ wined3d_cs_emit_texture_preload(device->cs, texture); + } + + void * CDECL wined3d_texture_get_parent(const struct wined3d_texture *texture) +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 07d1613..de82b46 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2653,6 +2653,7 @@ void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query + void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query *query) DECLSPEC_HIDDEN; + void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surface *src, + const RECT *src_rect, struct wined3d_surface *dst, const POINT *dst_point) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0089-wined3d-Send-update_surface-commands-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0089-wined3d-Send-update_surface-commands-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0089-wined3d-Send-update_surface-commands-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0089-wined3d-Send-update_surface-commands-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ -From 961a8cb3c42a2969dd1500b4fc16adb4d47b514f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 1 Aug 2013 00:00:26 +0200 -Subject: wined3d: Send update_surface commands through the CS - ---- - dlls/wined3d/cs.c | 48 ++++++++++++++++++++++++++++++++++++++++++ - dlls/wined3d/device.c | 9 ++------ - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 52 insertions(+), 7 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 3540cb7..3264d17 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -69,6 +69,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_RESOURCE_UNMAP, - WINED3D_CS_OP_QUERY_ISSUE, - WINED3D_CS_OP_QUERY_DESTROY, -+ WINED3D_CS_OP_UPDATE_SURFACE, - WINED3D_CS_OP_STOP, - }; - -@@ -379,6 +380,15 @@ struct wined3d_cs_query_destroy - struct wined3d_query *query; - }; - -+struct wined3d_cs_update_surface -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_surface *src, *dst; -+ RECT src_rect; -+ POINT dst_point; -+ BOOL has_src_rect, has_dst_point; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -1780,6 +1790,43 @@ void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query * - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_update_surface(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_update_surface *op = data; -+ -+ surface_upload_from_surface(op->dst, op->has_dst_point ? &op->dst_point : NULL, -+ op->src, op->has_src_rect ? &op->src_rect : NULL); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surface *src, const RECT *src_rect, -+ struct wined3d_surface *dst, const POINT *dst_point) -+{ -+ struct wined3d_cs_update_surface *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_UPDATE_SURFACE; -+ op->src = src; -+ op->dst = dst; -+ op->has_src_rect = FALSE; -+ op->has_dst_point = FALSE; -+ -+ if (src_rect) -+ { -+ op->has_src_rect = TRUE; -+ op->src_rect = *src_rect; -+ } -+ -+ if (dst_point) -+ { -+ op->has_dst_point = TRUE; -+ op->dst_point = *dst_point; -+ } -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -1827,6 +1874,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, - /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, - /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, -+ /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index cd90c76..ed055f8 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -3796,14 +3796,9 @@ HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device, - return WINED3DERR_INVALIDCALL; - } - -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- wined3d_cs_emit_glfinish(device->cs); -- device->cs->ops->finish(device->cs); -- } -+ wined3d_cs_emit_update_surface(device->cs, src_surface, src_rect, dst_surface, dst_point); - -- return surface_upload_from_surface(dst_surface, dst_point, src_surface, src_rect); -+ return WINED3D_OK; - } - - void CDECL wined3d_device_copy_resource(struct wined3d_device *device, -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 8dd9786..07d1613 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2651,6 +2651,8 @@ void wined3d_cs_emit_query_issue(struct wined3d_cs *cs, struct wined3d_query *qu - void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query *query, void *data, - UINT data_size, DWORD flags, HRESULT *ret) DECLSPEC_HIDDEN; - void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query *query) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surface *src, -+ const RECT *src_rect, struct wined3d_surface *dst, const POINT *dst_point) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0089-wined3d-Send-update_texture-calls-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0089-wined3d-Send-update_texture-calls-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0089-wined3d-Send-update_texture-calls-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0089-wined3d-Send-update_texture-calls-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,305 @@ +From 74ca9354ca44c727c7efeeee0d5f56caf19960ef Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 1 Aug 2013 00:33:48 +0200 +Subject: wined3d: Send update_texture calls through the CS + +--- + dlls/wined3d/cs.c | 33 +++++++++++ + dlls/wined3d/device.c | 125 ++++++++++++++++++++--------------------- + dlls/wined3d/wined3d_private.h | 4 ++ + 3 files changed, 98 insertions(+), 64 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 2da4249..392ef36 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -72,6 +72,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_QUERY_DESTROY, + WINED3D_CS_OP_UPDATE_SURFACE, + WINED3D_CS_OP_TEXTURE_PRELOAD, ++ WINED3D_CS_OP_UPDATE_TEXTURE, + WINED3D_CS_OP_STOP, + }; + +@@ -406,6 +407,12 @@ struct wined3d_cs_texture_preload + struct wined3d_texture *texture; + }; + ++struct wined3d_cs_update_texture ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_texture *src, *dst; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -1972,6 +1979,31 @@ void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_textu + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_update_texture(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_update_texture *op = data; ++ struct wined3d_context *context; ++ ++ context = context_acquire(cs->device, NULL); ++ device_exec_update_texture(context, op->src, op->dst); ++ context_release(context); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_texture *src, ++ struct wined3d_texture *dst) ++{ ++ struct wined3d_cs_update_texture *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_UPDATE_TEXTURE; ++ op->src = src; ++ op->dst = dst; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2022,6 +2054,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, + /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, + /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, ++ /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 4db078d..2dde4b6 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -3494,16 +3494,15 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device + } + + /* This is a helper function for UpdateTexture, there is no UpdateVolume method in D3D. */ +-static HRESULT device_update_volume(struct wined3d_device *device, ++static HRESULT device_update_volume(struct wined3d_context *context, + struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) + { + struct wined3d_const_bo_address data; + struct wined3d_map_desc src; + HRESULT hr; +- struct wined3d_context *context; + +- TRACE("device %p, src_volume %p, dst_volume %p.\n", +- device, src_volume, dst_volume); ++ TRACE("src_volume %p, dst_volume %p.\n", ++ src_volume, dst_volume); + + if (src_volume->resource.format != dst_volume->resource.format) + { +@@ -3521,8 +3520,6 @@ static HRESULT device_update_volume(struct wined3d_device *device, + if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY))) + return hr; + +- context = context_acquire(device, NULL); +- + /* Only a prepare, since we're uploading the entire volume. */ + wined3d_texture_prepare_texture(dst_volume->container, context, FALSE); + wined3d_texture_bind_and_dirtify(dst_volume->container, context, FALSE); +@@ -3532,57 +3529,20 @@ static HRESULT device_update_volume(struct wined3d_device *device, + wined3d_volume_upload_data(dst_volume, context, &data); + wined3d_resource_invalidate_location(&dst_volume->resource, ~WINED3D_LOCATION_TEXTURE_RGB); + +- context_release(context); +- + hr = wined3d_volume_unmap(src_volume); + + return hr; + } + +-HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, +- struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture) ++/* Context activation is done by the caller */ ++void device_exec_update_texture(struct wined3d_context *context, struct wined3d_texture *src_texture, ++ struct wined3d_texture *dst_texture) + { + unsigned int src_size, dst_size, src_skip_levels = 0; + unsigned int layer_count, level_count, i, j; +- enum wined3d_resource_type type; +- HRESULT hr; +- struct wined3d_context *context; +- +- TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture); +- +- /* Verify that the source and destination textures are non-NULL. */ +- if (!src_texture || !dst_texture) +- { +- WARN("Source and destination textures must be non-NULL, returning WINED3DERR_INVALIDCALL.\n"); +- return WINED3DERR_INVALIDCALL; +- } +- +- if (src_texture->resource.pool != WINED3D_POOL_SYSTEM_MEM) +- { +- WARN("Source texture not in WINED3D_POOL_SYSTEM_MEM, returning WINED3DERR_INVALIDCALL.\n"); +- return WINED3DERR_INVALIDCALL; +- } +- if (dst_texture->resource.pool != WINED3D_POOL_DEFAULT) +- { +- WARN("Destination texture not in WINED3D_POOL_DEFAULT, returning WINED3DERR_INVALIDCALL.\n"); +- return WINED3DERR_INVALIDCALL; +- } +- +- /* Verify that the source and destination textures are the same type. */ +- type = src_texture->resource.type; +- if (dst_texture->resource.type != type) +- { +- WARN("Source and destination have different types, returning WINED3DERR_INVALIDCALL.\n"); +- return WINED3DERR_INVALIDCALL; +- } ++ enum wined3d_resource_type type = src_texture->resource.type; + + layer_count = src_texture->layer_count; +- if (layer_count != dst_texture->layer_count) +- { +- WARN("Source and destination have different layer counts.\n"); +- return WINED3DERR_INVALIDCALL; +- } +- + level_count = min(wined3d_texture_get_level_count(src_texture), + wined3d_texture_get_level_count(dst_texture)); + +@@ -3599,17 +3559,8 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, + ++src_skip_levels; + } + +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- wined3d_cs_emit_glfinish(device->cs); +- device->cs->ops->finish(device->cs); +- } +- + /* Make sure that the destination texture is loaded. */ +- context = context_acquire(device, NULL); + wined3d_texture_load(dst_texture, context, FALSE); +- context_release(context); + + /* Update every surface level of the texture. */ + switch (type) +@@ -3629,11 +3580,7 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, + i * src_levels + j + src_skip_levels)); + dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, + i * dst_levels + j)); +- if (FAILED(hr = wined3d_device_update_surface(device, src_surface, NULL, dst_surface, NULL))) +- { +- WARN("Failed to update surface, hr %#x.\n", hr); +- return hr; +- } ++ surface_upload_from_surface(dst_surface, NULL, src_surface, NULL); + } + } + break; +@@ -3643,14 +3590,15 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, + { + for (i = 0; i < level_count; ++i) + { +- hr = device_update_volume(device, ++ HRESULT hr; ++ hr = device_update_volume(context, + volume_from_resource(wined3d_texture_get_sub_resource(src_texture, + i + src_skip_levels)), + volume_from_resource(wined3d_texture_get_sub_resource(dst_texture, i))); + if (FAILED(hr)) + { + WARN("Failed to update volume, hr %#x.\n", hr); +- return hr; ++ return; + } + } + break; +@@ -3658,9 +3606,58 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, + + default: + FIXME("Unsupported texture type %#x.\n", type); +- return WINED3DERR_INVALIDCALL; ++ return; ++ } ++} ++ ++HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, ++ struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture) ++{ ++ enum wined3d_resource_type type; ++ unsigned int layer_count; ++ ++ TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture); ++ ++ /* Verify that the source and destination textures are non-NULL. */ ++ if (!src_texture || !dst_texture) ++ { ++ WARN("Source and destination textures must be non-NULL, returning WINED3DERR_INVALIDCALL.\n"); ++ return WINED3DERR_INVALIDCALL; + } + ++ if (src_texture->resource.pool != WINED3D_POOL_SYSTEM_MEM) ++ { ++ WARN("Source texture not in WINED3D_POOL_SYSTEM_MEM, returning WINED3DERR_INVALIDCALL.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ if (dst_texture->resource.pool != WINED3D_POOL_DEFAULT) ++ { ++ WARN("Destination texture not in WINED3D_POOL_DEFAULT, returning WINED3DERR_INVALIDCALL.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ if (dst_texture->resource.format != src_texture->resource.format) ++ { ++ WARN("Formats do not match, returning WINED3DERR_INVALIDCALL.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ /* Verify that the source and destination textures are the same type. */ ++ type = src_texture->resource.type; ++ if (dst_texture->resource.type != type) ++ { ++ WARN("Source and destination have different types, returning WINED3DERR_INVALIDCALL.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ layer_count = src_texture->layer_count; ++ if (layer_count != dst_texture->layer_count) ++ { ++ WARN("Source and destination have different layer counts.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ wined3d_cs_emit_update_texture(device->cs, src_texture, dst_texture); ++ + return WINED3D_OK; + } + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 8985d99..e5e0336 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2212,6 +2212,8 @@ void device_resource_add(struct wined3d_device *device, struct wined3d_resource + void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; + void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) DECLSPEC_HIDDEN; ++void device_exec_update_texture(struct wined3d_context *context, struct wined3d_texture *src_texture, ++ struct wined3d_texture *dst_texture) DECLSPEC_HIDDEN; + + static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) + { +@@ -2806,6 +2808,8 @@ void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query * + void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surface *src, + const RECT *src_rect, struct wined3d_surface *dst, const POINT *dst_point) DECLSPEC_HIDDEN; + void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_texture *src, ++ struct wined3d_texture *dst) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0090-wined3d-Get-rid-of-the-surface_upload_data-glFinish.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0090-wined3d-Get-rid-of-the-surface_upload_data-glFinish.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0090-wined3d-Get-rid-of-the-surface_upload_data-glFinish.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0090-wined3d-Get-rid-of-the-surface_upload_data-glFinish.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,27 @@ +From bd911b7f7d610d7b2a4441827aef64bb24257e45 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 1 Aug 2013 01:43:35 +0200 +Subject: wined3d: Get rid of the surface_upload_data glFinish + +--- + dlls/wined3d/surface.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index c503c67..5dda903 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -1403,9 +1403,7 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w + checkGLcall("glBindBuffer"); + } + +- if (wined3d_settings.cs_multithreaded) +- gl_info->gl_ops.gl.p_glFinish(); +- else if (wined3d_settings.strict_draw_ordering) ++ if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); + + if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE) +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0090-wined3d-Send-texture-preloads-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0090-wined3d-Send-texture-preloads-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0090-wined3d-Send-texture-preloads-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0090-wined3d-Send-texture-preloads-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -From dd0852f22f9a3e04e9fefae6c0a3ac4913cc390d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 1 Aug 2013 00:10:40 +0200 -Subject: wined3d: Send texture preloads through the CS - ---- - dlls/wined3d/cs.c | 32 ++++++++++++++++++++++++++++++++ - dlls/wined3d/texture.c | 6 ++---- - dlls/wined3d/wined3d_private.h | 1 + - 3 files changed, 35 insertions(+), 4 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 3264d17..78e5010 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -70,6 +70,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_QUERY_ISSUE, - WINED3D_CS_OP_QUERY_DESTROY, - WINED3D_CS_OP_UPDATE_SURFACE, -+ WINED3D_CS_OP_TEXTURE_PRELOAD, - WINED3D_CS_OP_STOP, - }; - -@@ -389,6 +390,12 @@ struct wined3d_cs_update_surface - BOOL has_src_rect, has_dst_point; - }; - -+struct wined3d_cs_texture_preload -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_texture *texture; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -1827,6 +1834,30 @@ void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surfac - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_texture_preload(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_texture_preload *op = data; -+ struct wined3d_context *context; -+ struct wined3d_texture *texture = op->texture; -+ -+ context = context_acquire(cs->device, NULL); -+ wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); -+ context_release(context); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_texture *texture) -+{ -+ struct wined3d_cs_texture_preload *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_TEXTURE_PRELOAD; -+ op->texture = texture; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -1875,6 +1906,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, - /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, - /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, -+ /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index b7891d9..ea8589a 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -569,10 +569,8 @@ void wined3d_texture_load(struct wined3d_texture *texture, - - void CDECL wined3d_texture_preload(struct wined3d_texture *texture) - { -- struct wined3d_context *context; -- context = context_acquire(texture->resource.device, NULL); -- wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); -- context_release(context); -+ const struct wined3d_device *device = texture->resource.device; -+ wined3d_cs_emit_texture_preload(device->cs, texture); - } - - void * CDECL wined3d_texture_get_parent(const struct wined3d_texture *texture) -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 07d1613..de82b46 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2653,6 +2653,7 @@ void wined3d_cs_emit_query_get_data(struct wined3d_cs *cs, struct wined3d_query - void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query *query) DECLSPEC_HIDDEN; - void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surface *src, - const RECT *src_rect, struct wined3d_surface *dst, const POINT *dst_point) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0091-wined3d-Don-t-lock-the-src-volume-in-device_update_v.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0091-wined3d-Don-t-lock-the-src-volume-in-device_update_v.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0091-wined3d-Don-t-lock-the-src-volume-in-device_update_v.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0091-wined3d-Don-t-lock-the-src-volume-in-device_update_v.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,90 @@ +From 39991b8b55a61f725745fde7e8a2622ec6a457a0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 29 Aug 2013 22:25:14 +0200 +Subject: wined3d: Don't lock the src volume in device_update_volume + +This will attempt to wait for the CS, but this code is executed by the CS, so +it will, among other problems, break the single producer, single consumer +assumption of the work queue. + +FIXME: Maybe merge this with the previous patch or change their order. +--- + dlls/wined3d/device.c | 30 +++++++----------------------- + 1 file changed, 7 insertions(+), 23 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index e7c5bcc..e3b4217 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -3420,12 +3420,10 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device + } + + /* This is a helper function for UpdateTexture, there is no UpdateVolume method in D3D. */ +-static HRESULT device_update_volume(struct wined3d_context *context, ++static void device_update_volume(struct wined3d_context *context, + struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) + { +- struct wined3d_const_bo_address data; +- struct wined3d_map_desc src; +- HRESULT hr; ++ struct wined3d_bo_address data; + + TRACE("src_volume %p, dst_volume %p.\n", + src_volume, dst_volume); +@@ -3433,31 +3431,23 @@ static HRESULT device_update_volume(struct wined3d_context *context, + if (src_volume->resource.format != dst_volume->resource.format) + { + FIXME("Source and destination formats do not match.\n"); +- return WINED3DERR_INVALIDCALL; ++ return; + } + if (src_volume->resource.width != dst_volume->resource.width + || src_volume->resource.height != dst_volume->resource.height + || src_volume->resource.depth != dst_volume->resource.depth) + { + FIXME("Source and destination sizes do not match.\n"); +- return WINED3DERR_INVALIDCALL; ++ return; + } + +- if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY))) +- return hr; +- + /* Only a prepare, since we're uploading the entire volume. */ + wined3d_texture_prepare_texture(dst_volume->container, context, FALSE); + wined3d_texture_bind_and_dirtify(dst_volume->container, context, FALSE); + +- data.buffer_object = 0; +- data.addr = src.data; +- wined3d_volume_upload_data(dst_volume, context, &data); ++ wined3d_resource_get_memory(&src_volume->resource, src_volume->resource.map_binding, &data); ++ wined3d_volume_upload_data(dst_volume, context, wined3d_const_bo_address(&data)); + wined3d_resource_invalidate_location(&dst_volume->resource, ~WINED3D_LOCATION_TEXTURE_RGB); +- +- hr = wined3d_volume_unmap(src_volume); +- +- return hr; + } + + /* Context activation is done by the caller */ +@@ -3529,16 +3519,10 @@ void device_exec_update_texture(struct wined3d_context *context, struct wined3d_ + { + for (i = 0; i < level_count; ++i) + { +- HRESULT hr; +- hr = device_update_volume(context, ++ device_update_volume(context, + volume_from_resource(wined3d_texture_get_sub_resource(src_texture, + i + src_skip_levels)), + volume_from_resource(wined3d_texture_get_sub_resource(dst_texture, i))); +- if (FAILED(hr)) +- { +- WARN("Failed to update volume, hr %#x.\n", hr); +- return; +- } + } + break; + } +-- +2.5.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0091-wined3d-Send-surface-preloads-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0091-wined3d-Send-surface-preloads-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0091-wined3d-Send-surface-preloads-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0091-wined3d-Send-surface-preloads-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -From 2f0bb40d8d1791180b93f3d4eccbf7c3f190d19e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 1 Aug 2013 00:15:58 +0200 -Subject: wined3d: Send surface preloads through the CS - ---- - dlls/wined3d/cs.c | 31 +++++++++++++++++++++++++++++++ - dlls/wined3d/surface.c | 5 +++-- - dlls/wined3d/wined3d_private.h | 1 + - 3 files changed, 35 insertions(+), 2 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 78e5010..4834dd4 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -71,6 +71,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_QUERY_DESTROY, - WINED3D_CS_OP_UPDATE_SURFACE, - WINED3D_CS_OP_TEXTURE_PRELOAD, -+ WINED3D_CS_OP_SURFACE_PRELOAD, - WINED3D_CS_OP_STOP, - }; - -@@ -396,6 +397,12 @@ struct wined3d_cs_texture_preload - struct wined3d_texture *texture; - }; - -+struct wined3d_cs_surface_preload -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_surface *surface; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -1858,6 +1865,29 @@ void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_textu - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_surface_preload(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_surface_preload *op = data; -+ struct wined3d_context *context; -+ -+ context = context_acquire(cs->device, NULL); -+ wined3d_texture_preload(op->surface->container); -+ context_release(context); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_surface_preload(struct wined3d_cs *cs, struct wined3d_surface *surface) -+{ -+ struct wined3d_cs_surface_preload *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SURFACE_PRELOAD; -+ op->surface = surface; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -1907,6 +1937,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, - /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, - /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, -+ /* WINED3D_CS_OP_SURFACE_PRELOAD */ wined3d_cs_exec_surface_preload, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 9dadb6d..b2a5d22 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -1771,15 +1771,16 @@ ULONG CDECL wined3d_surface_decref(struct wined3d_surface *surface) - - void CDECL wined3d_surface_preload(struct wined3d_surface *surface) - { -+ const struct wined3d_device *device = surface->resource.device; - TRACE("surface %p.\n", surface); - -- if (!surface->resource.device->d3d_initialized) -+ if (!device->d3d_initialized) - { - ERR("D3D not initialized.\n"); - return; - } - -- wined3d_texture_preload(surface->container); -+ wined3d_cs_emit_surface_preload(device->cs, surface); - } - - void * CDECL wined3d_surface_get_parent(const struct wined3d_surface *surface) -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index de82b46..409f395 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2654,6 +2654,7 @@ void wined3d_cs_emit_query_destroy(struct wined3d_cs *cs, struct wined3d_query * - void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surface *src, - const RECT *src_rect, struct wined3d_surface *dst, const POINT *dst_point) DECLSPEC_HIDDEN; - void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_surface_preload(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0092-wined3d-Handle-evit_managed_resources-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0092-wined3d-Handle-evit_managed_resources-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0092-wined3d-Handle-evit_managed_resources-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0092-wined3d-Handle-evit_managed_resources-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,129 @@ +From f93c689f0844961269bd2e4f83bf242841c1e305 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 6 Aug 2013 13:50:31 +0200 +Subject: wined3d: Handle evit_managed_resources through the CS + +--- + dlls/wined3d/cs.c | 37 +++++++++++++++++++++++++++++++++++++ + dlls/wined3d/device.c | 14 +++----------- + dlls/wined3d/wined3d_private.h | 1 + + 3 files changed, 41 insertions(+), 11 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 392ef36..bbec667 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -73,6 +73,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_UPDATE_SURFACE, + WINED3D_CS_OP_TEXTURE_PRELOAD, + WINED3D_CS_OP_UPDATE_TEXTURE, ++ WINED3D_CS_OP_EVICT_RESOURCE, + WINED3D_CS_OP_STOP, + }; + +@@ -413,6 +414,12 @@ struct wined3d_cs_update_texture + struct wined3d_texture *src, *dst; + }; + ++struct wined3d_cs_evict_resource ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_resource *resource; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2004,6 +2011,35 @@ void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_textur + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_evict_resource(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_evict_resource *op = data; ++ struct wined3d_resource *resource = op->resource; ++ ++ resource->resource_ops->resource_unload(resource); ++ ++ /* FIXME: Is this necessary? Bound buffers are preloaded anyway, and in theory ++ * PreLoad should take care of invalidating the state if the VBO changes */ ++ if (resource->bind_count && resource->type == WINED3D_RTYPE_BUFFER) ++ { ++ device_invalidate_state(cs->device, STATE_STREAMSRC); ++ device_invalidate_state(cs->device, STATE_INDEXBUFFER); ++ } ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) ++{ ++ struct wined3d_cs_evict_resource *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_EVICT_RESOURCE; ++ op->resource = resource; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2055,6 +2091,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, + /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, + /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, ++ /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 4abc2c5..7f7ddbb 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -4489,13 +4489,8 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) + + TRACE("device %p.\n", device); + +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- wined3d_cs_emit_glfinish(device->cs); +- device->cs->ops->finish(device->cs); +- } +- ++ /* The resource list is manged by the main thread, iterate here and emit commands for ++ * each resource */ + LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) + { + TRACE("Checking resource %p for eviction.\n", resource); +@@ -4503,12 +4498,9 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) + if (resource->pool == WINED3D_POOL_MANAGED && !resource->map_count) + { + TRACE("Evicting %p.\n", resource); +- resource->resource_ops->resource_unload(resource); ++ wined3d_cs_emit_evict_resource(device->cs, resource); + } + } +- +- /* Invalidate stream sources, the buffer(s) may have been evicted. */ +- device_invalidate_state(device, STATE_STREAMSRC); + } + + static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index e5e0336..60ff62f 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2810,6 +2810,7 @@ void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surfac + void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; + void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_texture *src, + struct wined3d_texture *dst) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0092-wined3d-Send-update_texture-calls-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0092-wined3d-Send-update_texture-calls-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0092-wined3d-Send-update_texture-calls-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0092-wined3d-Send-update_texture-calls-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,303 +0,0 @@ -From a67a9a39ffcf23526dbabc064d02520c41a5ecdb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 1 Aug 2013 00:33:48 +0200 -Subject: wined3d: Send update_texture calls through the CS - ---- - dlls/wined3d/cs.c | 33 ++++++++++++ - dlls/wined3d/device.c | 119 +++++++++++++++++++---------------------- - dlls/wined3d/wined3d_private.h | 4 ++ - 3 files changed, 91 insertions(+), 65 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index f17a222..31f7087 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -73,6 +73,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_UPDATE_SURFACE, - WINED3D_CS_OP_TEXTURE_PRELOAD, - WINED3D_CS_OP_SURFACE_PRELOAD, -+ WINED3D_CS_OP_UPDATE_TEXTURE, - WINED3D_CS_OP_STOP, - }; - -@@ -413,6 +414,12 @@ struct wined3d_cs_surface_preload - struct wined3d_surface *surface; - }; - -+struct wined3d_cs_update_texture -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_texture *src, *dst; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2002,6 +2009,31 @@ void wined3d_cs_emit_surface_preload(struct wined3d_cs *cs, struct wined3d_surfa - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_update_texture(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_update_texture *op = data; -+ struct wined3d_context *context; -+ -+ context = context_acquire(cs->device, NULL); -+ device_exec_update_texture(context, op->src, op->dst); -+ context_release(context); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_texture *src, -+ struct wined3d_texture *dst) -+{ -+ struct wined3d_cs_update_texture *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_UPDATE_TEXTURE; -+ op->src = src; -+ op->dst = dst; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2053,6 +2085,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, - /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, - /* WINED3D_CS_OP_SURFACE_PRELOAD */ wined3d_cs_exec_surface_preload, -+ /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index d302b17..e7c5bcc 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -3420,16 +3420,15 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device - } - - /* This is a helper function for UpdateTexture, there is no UpdateVolume method in D3D. */ --static HRESULT device_update_volume(struct wined3d_device *device, -+static HRESULT device_update_volume(struct wined3d_context *context, - struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) - { - struct wined3d_const_bo_address data; - struct wined3d_map_desc src; - HRESULT hr; -- struct wined3d_context *context; - -- TRACE("device %p, src_volume %p, dst_volume %p.\n", -- device, src_volume, dst_volume); -+ TRACE("src_volume %p, dst_volume %p.\n", -+ src_volume, dst_volume); - - if (src_volume->resource.format != dst_volume->resource.format) - { -@@ -3447,8 +3446,6 @@ static HRESULT device_update_volume(struct wined3d_device *device, - if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY))) - return hr; - -- context = context_acquire(device, NULL); -- - /* Only a prepare, since we're uploading the entire volume. */ - wined3d_texture_prepare_texture(dst_volume->container, context, FALSE); - wined3d_texture_bind_and_dirtify(dst_volume->container, context, FALSE); -@@ -3458,48 +3455,17 @@ static HRESULT device_update_volume(struct wined3d_device *device, - wined3d_volume_upload_data(dst_volume, context, &data); - wined3d_resource_invalidate_location(&dst_volume->resource, ~WINED3D_LOCATION_TEXTURE_RGB); - -- context_release(context); -- - hr = wined3d_volume_unmap(src_volume); - - return hr; - } - --HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, -- struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture) -+/* Context activation is done by the caller */ -+void device_exec_update_texture(struct wined3d_context *context, struct wined3d_texture *src_texture, -+ struct wined3d_texture *dst_texture) - { -- enum wined3d_resource_type type; -+ enum wined3d_resource_type type = src_texture->resource.type; - unsigned int level_count, i, j, src_size, dst_size, src_skip_levels = 0; -- HRESULT hr; -- struct wined3d_context *context; -- -- TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture); -- -- /* Verify that the source and destination textures are non-NULL. */ -- if (!src_texture || !dst_texture) -- { -- WARN("Source and destination textures must be non-NULL, returning WINED3DERR_INVALIDCALL.\n"); -- return WINED3DERR_INVALIDCALL; -- } -- -- if (src_texture->resource.pool != WINED3D_POOL_SYSTEM_MEM) -- { -- WARN("Source texture not in WINED3D_POOL_SYSTEM_MEM, returning WINED3DERR_INVALIDCALL.\n"); -- return WINED3DERR_INVALIDCALL; -- } -- if (dst_texture->resource.pool != WINED3D_POOL_DEFAULT) -- { -- WARN("Destination texture not in WINED3D_POOL_DEFAULT, returning WINED3DERR_INVALIDCALL.\n"); -- return WINED3DERR_INVALIDCALL; -- } -- -- /* Verify that the source and destination textures are the same type. */ -- type = src_texture->resource.type; -- if (dst_texture->resource.type != type) -- { -- WARN("Source and destination have different types, returning WINED3DERR_INVALIDCALL.\n"); -- return WINED3DERR_INVALIDCALL; -- } - - level_count = min(wined3d_texture_get_level_count(src_texture), - wined3d_texture_get_level_count(dst_texture)); -@@ -3517,17 +3483,8 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, - ++src_skip_levels; - } - -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- wined3d_cs_emit_glfinish(device->cs); -- device->cs->ops->finish(device->cs); -- } -- - /* Make sure that the destination texture is loaded. */ -- context = context_acquire(device, NULL); - wined3d_texture_load(dst_texture, context, FALSE); -- context_release(context); - - /* Update every surface level of the texture. */ - switch (type) -@@ -3542,12 +3499,7 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, - src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, - i + src_skip_levels)); - dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, i)); -- hr = wined3d_device_update_surface(device, src_surface, NULL, dst_surface, NULL); -- if (FAILED(hr)) -- { -- WARN("Failed to update surface, hr %#x.\n", hr); -- return hr; -- } -+ surface_upload_from_surface(dst_surface, NULL, src_surface, NULL); - } - break; - } -@@ -3567,12 +3519,7 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, - i * src_levels + j + src_skip_levels)); - dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, - i * dst_levels + j)); -- hr = wined3d_device_update_surface(device, src_surface, NULL, dst_surface, NULL); -- if (FAILED(hr)) -- { -- WARN("Failed to update surface, hr %#x.\n", hr); -- return hr; -- } -+ surface_upload_from_surface(dst_surface, NULL, src_surface, NULL); - } - } - break; -@@ -3582,14 +3529,15 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, - { - for (i = 0; i < level_count; ++i) - { -- hr = device_update_volume(device, -+ HRESULT hr; -+ hr = device_update_volume(context, - volume_from_resource(wined3d_texture_get_sub_resource(src_texture, - i + src_skip_levels)), - volume_from_resource(wined3d_texture_get_sub_resource(dst_texture, i))); - if (FAILED(hr)) - { - WARN("Failed to update volume, hr %#x.\n", hr); -- return hr; -+ return; - } - } - break; -@@ -3597,9 +3545,50 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, - - default: - FIXME("Unsupported texture type %#x.\n", type); -- return WINED3DERR_INVALIDCALL; -+ return; -+ } -+} -+ -+HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, -+ struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture) -+{ -+ enum wined3d_resource_type type; -+ -+ TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture); -+ -+ /* Verify that the source and destination textures are non-NULL. */ -+ if (!src_texture || !dst_texture) -+ { -+ WARN("Source and destination textures must be non-NULL, returning WINED3DERR_INVALIDCALL.\n"); -+ return WINED3DERR_INVALIDCALL; - } - -+ if (src_texture->resource.pool != WINED3D_POOL_SYSTEM_MEM) -+ { -+ WARN("Source texture not in WINED3D_POOL_SYSTEM_MEM, returning WINED3DERR_INVALIDCALL.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ if (dst_texture->resource.pool != WINED3D_POOL_DEFAULT) -+ { -+ WARN("Destination texture not in WINED3D_POOL_DEFAULT, returning WINED3DERR_INVALIDCALL.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ if (dst_texture->resource.format != src_texture->resource.format) -+ { -+ WARN("Formats do not match, returning WINED3DERR_INVALIDCALL.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ /* Verify that the source and destination textures are the same type. */ -+ type = src_texture->resource.type; -+ if (dst_texture->resource.type != type) -+ { -+ WARN("Source and destination have different types, returning WINED3DERR_INVALIDCALL.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ wined3d_cs_emit_update_texture(device->cs, src_texture, dst_texture); -+ - return WINED3D_OK; - } - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 3081be5..3297c5e 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2152,6 +2152,8 @@ void device_resource_add(struct wined3d_device *device, struct wined3d_resource - void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; - void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) DECLSPEC_HIDDEN; -+void device_exec_update_texture(struct wined3d_context *context, struct wined3d_texture *src_texture, -+ struct wined3d_texture *dst_texture) DECLSPEC_HIDDEN; - - static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) - { -@@ -2744,6 +2746,8 @@ void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surfac - const RECT *src_rect, struct wined3d_surface *dst, const POINT *dst_point) DECLSPEC_HIDDEN; - void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; - void wined3d_cs_emit_surface_preload(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_texture *src, -+ struct wined3d_texture *dst) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0093-wined3d-Get-rid-of-the-surface_upload_data-glFinish.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0093-wined3d-Get-rid-of-the-surface_upload_data-glFinish.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0093-wined3d-Get-rid-of-the-surface_upload_data-glFinish.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0093-wined3d-Get-rid-of-the-surface_upload_data-glFinish.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -From bd911b7f7d610d7b2a4441827aef64bb24257e45 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 1 Aug 2013 01:43:35 +0200 -Subject: wined3d: Get rid of the surface_upload_data glFinish - ---- - dlls/wined3d/surface.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index c503c67..5dda903 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -1403,9 +1403,7 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w - checkGLcall("glBindBuffer"); - } - -- if (wined3d_settings.cs_multithreaded) -- gl_info->gl_ops.gl.p_glFinish(); -- else if (wined3d_settings.strict_draw_ordering) -+ if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); - - if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE) --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0093-wined3d-Introduce-resource-fencing.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0093-wined3d-Introduce-resource-fencing.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0093-wined3d-Introduce-resource-fencing.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0093-wined3d-Introduce-resource-fencing.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,99 @@ +From cba6a35d48886d00959d29d4fef9115a46143589 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 20 Aug 2014 18:01:36 +0200 +Subject: wined3d: Introduce resource fencing. + +FIXME: The buffer part doesn't really make sense without dynamic buffer maps. +--- + dlls/wined3d/cs.c | 19 +++++++++++++++++++ + dlls/wined3d/wined3d_private.h | 16 ++++++++++++++++ + 2 files changed, 35 insertions(+) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 11aa133..1197eef 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -575,6 +575,7 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_draw *op = data; + const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info; ++ unsigned int i; + + if (op->indexed && !gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) + { +@@ -593,6 +594,14 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) + draw_primitive(cs->device, &cs->state, op->start_idx, op->index_count, + op->start_instance, op->instance_count, op->indexed); + ++ if (op->indexed) ++ wined3d_resource_dec_fence(&cs->state.index_buffer->resource); ++ for (i = 0; i < sizeof(cs->state.streams) / sizeof(*cs->state.streams); i++) ++ { ++ if (cs->state.streams[i].buffer) ++ wined3d_resource_dec_fence(&cs->state.streams[i].buffer->resource); ++ } ++ + return sizeof(*op); + } + +@@ -600,6 +609,8 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun + UINT start_instance, UINT instance_count, BOOL indexed) + { + struct wined3d_cs_draw *op; ++ unsigned int i; ++ const struct wined3d_state *state = &cs->device->state; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_DRAW; +@@ -609,6 +620,14 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun + op->instance_count = instance_count; + op->indexed = indexed; + ++ if (indexed) ++ wined3d_resource_inc_fence(&state->index_buffer->resource); ++ for (i = 0; i < sizeof(state->streams) / sizeof(*state->streams); i++) ++ { ++ if (state->streams[i].buffer) ++ wined3d_resource_inc_fence(&state->streams[i].buffer->resource); ++ } ++ + cs->ops->submit(cs, sizeof(*op)); + } + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 570f5e3..10d0789 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2129,6 +2129,7 @@ struct wined3d_resource + GLuint buffer_object; + struct list resource_list_entry; + DWORD locations; ++ LONG access_fence; + + void *parent; + const struct wined3d_parent_ops *parent_ops; +@@ -2182,6 +2183,21 @@ void wined3d_resource_unmap_internal(struct wined3d_resource *resource) DECLSPEC + void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_validate_location(struct wined3d_resource *resource, DWORD location) DECLSPEC_HIDDEN; + ++static inline void wined3d_resource_inc_fence(struct wined3d_resource *resource) ++{ ++ InterlockedIncrement(&resource->access_fence); ++} ++ ++static inline void wined3d_resource_dec_fence(struct wined3d_resource *resource) ++{ ++ InterlockedDecrement(&resource->access_fence); ++} ++ ++static inline void wined3d_resource_wait_fence(struct wined3d_resource *resource) ++{ ++ while(InterlockedCompareExchange(&resource->access_fence, 0, 0)); ++} ++ + /* Tests show that the start address of resources is 32 byte aligned */ + #define RESOURCE_ALIGNMENT 16 + +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0094-wined3d-Don-t-lock-the-src-volume-in-device_update_v.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0094-wined3d-Don-t-lock-the-src-volume-in-device_update_v.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0094-wined3d-Don-t-lock-the-src-volume-in-device_update_v.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0094-wined3d-Don-t-lock-the-src-volume-in-device_update_v.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -From 39991b8b55a61f725745fde7e8a2622ec6a457a0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 29 Aug 2013 22:25:14 +0200 -Subject: wined3d: Don't lock the src volume in device_update_volume - -This will attempt to wait for the CS, but this code is executed by the CS, so -it will, among other problems, break the single producer, single consumer -assumption of the work queue. - -FIXME: Maybe merge this with the previous patch or change their order. ---- - dlls/wined3d/device.c | 30 +++++++----------------------- - 1 file changed, 7 insertions(+), 23 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index e7c5bcc..e3b4217 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -3420,12 +3420,10 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device - } - - /* This is a helper function for UpdateTexture, there is no UpdateVolume method in D3D. */ --static HRESULT device_update_volume(struct wined3d_context *context, -+static void device_update_volume(struct wined3d_context *context, - struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) - { -- struct wined3d_const_bo_address data; -- struct wined3d_map_desc src; -- HRESULT hr; -+ struct wined3d_bo_address data; - - TRACE("src_volume %p, dst_volume %p.\n", - src_volume, dst_volume); -@@ -3433,31 +3431,23 @@ static HRESULT device_update_volume(struct wined3d_context *context, - if (src_volume->resource.format != dst_volume->resource.format) - { - FIXME("Source and destination formats do not match.\n"); -- return WINED3DERR_INVALIDCALL; -+ return; - } - if (src_volume->resource.width != dst_volume->resource.width - || src_volume->resource.height != dst_volume->resource.height - || src_volume->resource.depth != dst_volume->resource.depth) - { - FIXME("Source and destination sizes do not match.\n"); -- return WINED3DERR_INVALIDCALL; -+ return; - } - -- if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY))) -- return hr; -- - /* Only a prepare, since we're uploading the entire volume. */ - wined3d_texture_prepare_texture(dst_volume->container, context, FALSE); - wined3d_texture_bind_and_dirtify(dst_volume->container, context, FALSE); - -- data.buffer_object = 0; -- data.addr = src.data; -- wined3d_volume_upload_data(dst_volume, context, &data); -+ wined3d_resource_get_memory(&src_volume->resource, src_volume->resource.map_binding, &data); -+ wined3d_volume_upload_data(dst_volume, context, wined3d_const_bo_address(&data)); - wined3d_resource_invalidate_location(&dst_volume->resource, ~WINED3D_LOCATION_TEXTURE_RGB); -- -- hr = wined3d_volume_unmap(src_volume); -- -- return hr; - } - - /* Context activation is done by the caller */ -@@ -3529,16 +3519,10 @@ void device_exec_update_texture(struct wined3d_context *context, struct wined3d_ - { - for (i = 0; i < level_count; ++i) - { -- HRESULT hr; -- hr = device_update_volume(context, -+ device_update_volume(context, - volume_from_resource(wined3d_texture_get_sub_resource(src_texture, - i + src_skip_levels)), - volume_from_resource(wined3d_texture_get_sub_resource(dst_texture, i))); -- if (FAILED(hr)) -- { -- WARN("Failed to update volume, hr %#x.\n", hr); -- return; -- } - } - break; - } --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0094-wined3d-Fence-update_texture-and-update_surface-call.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0094-wined3d-Fence-update_texture-and-update_surface-call.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0094-wined3d-Fence-update_texture-and-update_surface-call.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0094-wined3d-Fence-update_texture-and-update_surface-call.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,117 @@ +From a83b0e8543213b11848897ea954412ac0f06083a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 30 Aug 2013 10:41:42 +0200 +Subject: wined3d: Fence update_texture and update_surface calls + +--- + dlls/wined3d/cs.c | 26 ++++++++++++++++++++++++++ + dlls/wined3d/resource.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 1197eef..9a7e6df 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -1844,6 +1844,16 @@ static UINT wined3d_cs_exec_update_surface(struct wined3d_cs *cs, const void *da + surface_upload_from_surface(op->dst, op->has_dst_point ? &op->dst_point : NULL, + op->src, op->has_src_rect ? &op->src_rect : NULL); + ++ if (op->src->container) ++ wined3d_resource_dec_fence(&op->src->container->resource); ++ else ++ wined3d_resource_inc_fence(&op->src->resource); ++ ++ if (op->dst->container) ++ wined3d_resource_dec_fence(&op->dst->container->resource); ++ else ++ wined3d_resource_inc_fence(&op->dst->resource); ++ + return sizeof(*op); + } + +@@ -1871,6 +1881,16 @@ void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surfac + op->dst_point = *dst_point; + } + ++ if (src->container) ++ wined3d_resource_inc_fence(&src->container->resource); ++ else ++ wined3d_resource_inc_fence(&src->resource); ++ ++ if (dst->container) ++ wined3d_resource_inc_fence(&dst->container->resource); ++ else ++ wined3d_resource_inc_fence(&dst->resource); ++ + cs->ops->submit(cs, sizeof(*op)); + } + +@@ -1930,6 +1950,9 @@ static UINT wined3d_cs_exec_update_texture(struct wined3d_cs *cs, const void *da + device_exec_update_texture(context, op->src, op->dst); + context_release(context); + ++ wined3d_resource_dec_fence(&op->src->resource); ++ wined3d_resource_dec_fence(&op->dst->resource); ++ + return sizeof(*op); + } + +@@ -1943,6 +1966,9 @@ void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_textur + op->src = src; + op->dst = dst; + ++ wined3d_resource_inc_fence(&op->src->resource); ++ wined3d_resource_inc_fence(&op->dst->resource); ++ + cs->ops->submit(cs, sizeof(*op)); + } + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index af60d51..708b080 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -712,6 +712,32 @@ void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD fla + return mem; + } + ++static void wined3d_resource_sync(struct wined3d_resource *resource) ++{ ++ struct wined3d_resource *real_res = resource; ++ struct wined3d_surface *surface; ++ struct wined3d_volume *volume; ++ ++ switch (resource->type) ++ { ++ case WINED3D_RTYPE_SURFACE: ++ surface = surface_from_resource(resource); ++ if (surface->container) ++ real_res = &surface->container->resource; ++ break; ++ ++ case WINED3D_RTYPE_VOLUME: ++ volume = volume_from_resource(resource); ++ real_res = &volume->container->resource; ++ break; ++ ++ default: ++ break; ++ } ++ if (!real_res->access_fence) ++ FIXME("Waiting for CS even though resource %p is idle.\n", resource); ++} ++ + HRESULT wined3d_resource_map(struct wined3d_resource *resource, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) + { +@@ -730,6 +756,8 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, + + flags = wined3d_resource_sanitize_map_flags(resource, flags); + ++ wined3d_resource_sync(resource); ++ + base_memory = wined3d_cs_emit_resource_map(device->cs, resource, flags); + if (!base_memory) + { +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0095-wined3d-Dirtify-resources-on-unmap.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0095-wined3d-Dirtify-resources-on-unmap.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0095-wined3d-Dirtify-resources-on-unmap.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0095-wined3d-Dirtify-resources-on-unmap.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,81 @@ +From 440a516b0908c7282e89fe73a788ca461d90d81e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 26 Sep 2013 17:25:01 +0200 +Subject: wined3d: Dirtify resources on unmap + +--- + dlls/wined3d/resource.c | 7 ++++++- + dlls/wined3d/surface.c | 4 ++++ + dlls/wined3d/volume.c | 3 +++ + dlls/wined3d/wined3d_private.h | 1 + + 4 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 708b080..73011f8 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -806,7 +806,7 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, + } + + if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) +- wined3d_resource_invalidate_location(resource, ~resource->map_binding); ++ resource->unmap_dirtify = TRUE; + + resource->map_count++; + +@@ -826,6 +826,11 @@ void wined3d_resource_unmap_internal(struct wined3d_resource *resource) + wined3d_resource_release_map_ptr(resource, context); + if (context) + context_release(context); ++ ++ if (resource->unmap_dirtify) ++ wined3d_resource_invalidate_location(resource, ~resource->map_binding); ++ resource->unmap_dirtify = FALSE; ++ + } + + HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 0c3313d..e661494 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -2405,6 +2405,10 @@ HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface) + HRESULT hr; + TRACE("surface %p.\n", surface); + ++ if (surface->resource.unmap_dirtify && surface->container) ++ wined3d_texture_set_dirty(surface->container); ++ ++ + hr = wined3d_resource_unmap(&surface->resource); + if (FAILED(hr)) + return hr; +diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c +index 7ce5331..faadea1 100644 +--- a/dlls/wined3d/volume.c ++++ b/dlls/wined3d/volume.c +@@ -424,6 +424,9 @@ HRESULT CDECL wined3d_volume_unmap(struct wined3d_volume *volume) + { + HRESULT hr; + ++ if (volume->resource.unmap_dirtify) ++ wined3d_texture_set_dirty(volume->container); ++ + hr = wined3d_resource_unmap(&volume->resource); + if (hr == WINEDDERR_NOTLOCKED) + return WINED3DERR_INVALIDCALL; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index b4e5679..d670fe1 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2119,6 +2119,7 @@ struct wined3d_resource + struct list resource_list_entry; + DWORD locations; + LONG access_fence; ++ BOOL unmap_dirtify; + + void *parent; + const struct wined3d_parent_ops *parent_ops; +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0095-wined3d-Handle-evit_managed_resources-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0095-wined3d-Handle-evit_managed_resources-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0095-wined3d-Handle-evit_managed_resources-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0095-wined3d-Handle-evit_managed_resources-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,129 +0,0 @@ -From 87f659571c4214fcc73a42a1e112d6bda34950a3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 6 Aug 2013 13:50:31 +0200 -Subject: wined3d: Handle evit_managed_resources through the CS - ---- - dlls/wined3d/cs.c | 37 +++++++++++++++++++++++++++++++++++++ - dlls/wined3d/device.c | 14 +++----------- - dlls/wined3d/wined3d_private.h | 1 + - 3 files changed, 41 insertions(+), 11 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index aeba50f..11aa133 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -73,6 +73,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_TEXTURE_PRELOAD, - WINED3D_CS_OP_SURFACE_PRELOAD, - WINED3D_CS_OP_UPDATE_TEXTURE, -+ WINED3D_CS_OP_EVICT_RESOURCE, - WINED3D_CS_OP_STOP, - }; - -@@ -410,6 +411,12 @@ struct wined3d_cs_update_texture - struct wined3d_texture *src, *dst; - }; - -+struct wined3d_cs_evict_resource -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_resource *resource; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -1920,6 +1927,35 @@ void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_textur - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_evict_resource(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_evict_resource *op = data; -+ struct wined3d_resource *resource = op->resource; -+ -+ resource->resource_ops->resource_unload(resource); -+ -+ /* FIXME: Is this necessary? Bound buffers are preloaded anyway, and in theory -+ * PreLoad should take care of invalidating the state if the VBO changes */ -+ if (resource->bind_count && resource->type == WINED3D_RTYPE_BUFFER) -+ { -+ device_invalidate_state(cs->device, STATE_STREAMSRC); -+ device_invalidate_state(cs->device, STATE_INDEXBUFFER); -+ } -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) -+{ -+ struct wined3d_cs_evict_resource *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_EVICT_RESOURCE; -+ op->resource = resource; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -1971,6 +2007,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, - /* WINED3D_CS_OP_SURFACE_PRELOAD */ wined3d_cs_exec_surface_preload, - /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, -+ /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index ae7ad31..f062e84 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -4207,13 +4207,8 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) - - TRACE("device %p.\n", device); - -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- wined3d_cs_emit_glfinish(device->cs); -- device->cs->ops->finish(device->cs); -- } -- -+ /* The resource list is manged by the main thread, iterate here and emit commands for -+ * each resource */ - LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) - { - TRACE("Checking resource %p for eviction.\n", resource); -@@ -4221,12 +4216,9 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) - if (resource->pool == WINED3D_POOL_MANAGED && !resource->map_count) - { - TRACE("Evicting %p.\n", resource); -- resource->resource_ops->resource_unload(resource); -+ wined3d_cs_emit_evict_resource(device->cs, resource); - } - } -- -- /* Invalidate stream sources, the buffer(s) may have been evicted. */ -- device_invalidate_state(device, STATE_STREAMSRC); - } - - static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 25fce7f..b9eee2c 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2659,6 +2659,7 @@ void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_textu - void wined3d_cs_emit_surface_preload(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; - void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_texture *src, - struct wined3d_texture *dst) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0096-wined3d-Fence-texture-reads-in-draws.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0096-wined3d-Fence-texture-reads-in-draws.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0096-wined3d-Fence-texture-reads-in-draws.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0096-wined3d-Fence-texture-reads-in-draws.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,53 @@ +From 2d87f930869bcd32273e722a50a13a9330ce6a30 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 30 Aug 2013 22:42:33 +0200 +Subject: wined3d: Fence texture reads in draws + +This is probably stricter than necessary. GL BOs and allocated sysmem +are just staging resources. After they have been uploaded into the GL +texture, it's in theory OK to write new data buffer without interfering +with old draws. However, it is impossible to tell when if data has been +transfered into the texture because texture loads are delayed until draw +time. Specifically, it is difficult to separate two consecutive maps +from a map, draw, map sequence, where the draw hasn't been executed by +the time the second map occurs. + +The other problem is that sRGB may cause a texture load from +buffer/sysmem even though the GL texture is thought to be loaded. This +is limited to situations where sRGB textures are supported, but +sRGB_decode isn't. +--- + dlls/wined3d/cs.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 9a7e6df..0277a1e 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -601,6 +601,11 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) + if (cs->state.streams[i].buffer) + wined3d_resource_dec_fence(&cs->state.streams[i].buffer->resource); + } ++ for (i = 0; i < sizeof(cs->state.textures) / sizeof(*cs->state.textures); i++) ++ { ++ if (cs->state.textures[i]) ++ wined3d_resource_dec_fence(&cs->state.textures[i]->resource); ++ } + + return sizeof(*op); + } +@@ -627,6 +632,11 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun + if (state->streams[i].buffer) + wined3d_resource_inc_fence(&state->streams[i].buffer->resource); + } ++ for (i = 0; i < sizeof(state->textures) / sizeof(*state->textures); i++) ++ { ++ if (state->textures[i]) ++ wined3d_resource_inc_fence(&state->textures[i]->resource); ++ } + + cs->ops->submit(cs, sizeof(*op)); + } +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0096-wined3d-Introduce-resource-fencing.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0096-wined3d-Introduce-resource-fencing.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0096-wined3d-Introduce-resource-fencing.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0096-wined3d-Introduce-resource-fencing.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -From cba6a35d48886d00959d29d4fef9115a46143589 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 20 Aug 2014 18:01:36 +0200 -Subject: wined3d: Introduce resource fencing. - -FIXME: The buffer part doesn't really make sense without dynamic buffer maps. ---- - dlls/wined3d/cs.c | 19 +++++++++++++++++++ - dlls/wined3d/wined3d_private.h | 16 ++++++++++++++++ - 2 files changed, 35 insertions(+) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 11aa133..1197eef 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -575,6 +575,7 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_draw *op = data; - const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info; -+ unsigned int i; - - if (op->indexed && !gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX]) - { -@@ -593,6 +594,14 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) - draw_primitive(cs->device, &cs->state, op->start_idx, op->index_count, - op->start_instance, op->instance_count, op->indexed); - -+ if (op->indexed) -+ wined3d_resource_dec_fence(&cs->state.index_buffer->resource); -+ for (i = 0; i < sizeof(cs->state.streams) / sizeof(*cs->state.streams); i++) -+ { -+ if (cs->state.streams[i].buffer) -+ wined3d_resource_dec_fence(&cs->state.streams[i].buffer->resource); -+ } -+ - return sizeof(*op); - } - -@@ -600,6 +609,8 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun - UINT start_instance, UINT instance_count, BOOL indexed) - { - struct wined3d_cs_draw *op; -+ unsigned int i; -+ const struct wined3d_state *state = &cs->device->state; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_DRAW; -@@ -609,6 +620,14 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun - op->instance_count = instance_count; - op->indexed = indexed; - -+ if (indexed) -+ wined3d_resource_inc_fence(&state->index_buffer->resource); -+ for (i = 0; i < sizeof(state->streams) / sizeof(*state->streams); i++) -+ { -+ if (state->streams[i].buffer) -+ wined3d_resource_inc_fence(&state->streams[i].buffer->resource); -+ } -+ - cs->ops->submit(cs, sizeof(*op)); - } - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 570f5e3..10d0789 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2129,6 +2129,7 @@ struct wined3d_resource - GLuint buffer_object; - struct list resource_list_entry; - DWORD locations; -+ LONG access_fence; - - void *parent; - const struct wined3d_parent_ops *parent_ops; -@@ -2182,6 +2183,21 @@ void wined3d_resource_unmap_internal(struct wined3d_resource *resource) DECLSPEC - void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_validate_location(struct wined3d_resource *resource, DWORD location) DECLSPEC_HIDDEN; - -+static inline void wined3d_resource_inc_fence(struct wined3d_resource *resource) -+{ -+ InterlockedIncrement(&resource->access_fence); -+} -+ -+static inline void wined3d_resource_dec_fence(struct wined3d_resource *resource) -+{ -+ InterlockedDecrement(&resource->access_fence); -+} -+ -+static inline void wined3d_resource_wait_fence(struct wined3d_resource *resource) -+{ -+ while(InterlockedCompareExchange(&resource->access_fence, 0, 0)); -+} -+ - /* Tests show that the start address of resources is 32 byte aligned */ - #define RESOURCE_ALIGNMENT 16 - --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0097-wined3d-Fence-render-targets-and-depth-stencils.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0097-wined3d-Fence-render-targets-and-depth-stencils.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0097-wined3d-Fence-render-targets-and-depth-stencils.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0097-wined3d-Fence-render-targets-and-depth-stencils.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,75 @@ +From 18f06f3fccac3871c0db9d0229a137f920edfbef Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 27 Sep 2013 16:55:58 +0200 +Subject: wined3d: Fence render targets and depth stencils + +--- + dlls/wined3d/cs.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index cc73bdc..73c3dc6 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -581,6 +581,30 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * + cs->ops->submit(cs, size); + } + ++static inline BOOL wined3d_cs_colorwrite_enabled(const struct wined3d_state *state, unsigned int i) ++{ ++ switch (i) ++ { ++ case 0: ++ return !!state->render_states[WINED3D_RS_COLORWRITEENABLE]; ++ case 1: ++ return !!state->render_states[WINED3D_RS_COLORWRITEENABLE1]; ++ case 2: ++ return !!state->render_states[WINED3D_RS_COLORWRITEENABLE2]; ++ case 3: ++ return !!state->render_states[WINED3D_RS_COLORWRITEENABLE3]; ++ default: ++ ERR("Unexpected color target %u.\n", i); ++ return TRUE; ++ } ++} ++ ++static inline BOOL wined3d_cs_depth_stencil_enabled(const struct wined3d_state *state) ++{ ++ return state->render_states[WINED3D_RS_ZENABLE] ++ || state->render_states[WINED3D_RS_STENCILENABLE]; ++} ++ + static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_draw *op = data; +@@ -616,6 +640,13 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) + if (cs->state.textures[i]) + wined3d_resource_dec_fence(&cs->state.textures[i]->resource); + } ++ for (i = 0; i < gl_info->limits.buffers; i++) ++ { ++ if (cs->state.fb.render_targets[i] && wined3d_cs_colorwrite_enabled(&cs->state, i)) ++ wined3d_resource_dec_fence(cs->state.fb.render_targets[i]->resource); ++ } ++ if (cs->state.fb.depth_stencil && wined3d_cs_depth_stencil_enabled(&cs->state)) ++ wined3d_resource_dec_fence(cs->state.fb.depth_stencil->resource); + + return sizeof(*op); + } +@@ -647,6 +678,13 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun + if (state->textures[i]) + wined3d_resource_inc_fence(&state->textures[i]->resource); + } ++ for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; i++) ++ { ++ if (state->fb.render_targets[i] && wined3d_cs_colorwrite_enabled(state, i)) ++ wined3d_resource_inc_fence(state->fb.render_targets[i]->resource); ++ } ++ if (state->fb.depth_stencil && wined3d_cs_depth_stencil_enabled(state)) ++ wined3d_resource_inc_fence(state->fb.depth_stencil->resource); + + cs->ops->submit(cs, sizeof(*op)); + } +-- +2.5.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0097-wined3d-Fence-update_texture-and-update_surface-call.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0097-wined3d-Fence-update_texture-and-update_surface-call.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0097-wined3d-Fence-update_texture-and-update_surface-call.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0097-wined3d-Fence-update_texture-and-update_surface-call.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -From a83b0e8543213b11848897ea954412ac0f06083a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 30 Aug 2013 10:41:42 +0200 -Subject: wined3d: Fence update_texture and update_surface calls - ---- - dlls/wined3d/cs.c | 26 ++++++++++++++++++++++++++ - dlls/wined3d/resource.c | 28 ++++++++++++++++++++++++++++ - 2 files changed, 54 insertions(+) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 1197eef..9a7e6df 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -1844,6 +1844,16 @@ static UINT wined3d_cs_exec_update_surface(struct wined3d_cs *cs, const void *da - surface_upload_from_surface(op->dst, op->has_dst_point ? &op->dst_point : NULL, - op->src, op->has_src_rect ? &op->src_rect : NULL); - -+ if (op->src->container) -+ wined3d_resource_dec_fence(&op->src->container->resource); -+ else -+ wined3d_resource_inc_fence(&op->src->resource); -+ -+ if (op->dst->container) -+ wined3d_resource_dec_fence(&op->dst->container->resource); -+ else -+ wined3d_resource_inc_fence(&op->dst->resource); -+ - return sizeof(*op); - } - -@@ -1871,6 +1881,16 @@ void wined3d_cs_emit_update_surface(struct wined3d_cs *cs, struct wined3d_surfac - op->dst_point = *dst_point; - } - -+ if (src->container) -+ wined3d_resource_inc_fence(&src->container->resource); -+ else -+ wined3d_resource_inc_fence(&src->resource); -+ -+ if (dst->container) -+ wined3d_resource_inc_fence(&dst->container->resource); -+ else -+ wined3d_resource_inc_fence(&dst->resource); -+ - cs->ops->submit(cs, sizeof(*op)); - } - -@@ -1930,6 +1950,9 @@ static UINT wined3d_cs_exec_update_texture(struct wined3d_cs *cs, const void *da - device_exec_update_texture(context, op->src, op->dst); - context_release(context); - -+ wined3d_resource_dec_fence(&op->src->resource); -+ wined3d_resource_dec_fence(&op->dst->resource); -+ - return sizeof(*op); - } - -@@ -1943,6 +1966,9 @@ void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_textur - op->src = src; - op->dst = dst; - -+ wined3d_resource_inc_fence(&op->src->resource); -+ wined3d_resource_inc_fence(&op->dst->resource); -+ - cs->ops->submit(cs, sizeof(*op)); - } - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index af60d51..708b080 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -712,6 +712,32 @@ void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD fla - return mem; - } - -+static void wined3d_resource_sync(struct wined3d_resource *resource) -+{ -+ struct wined3d_resource *real_res = resource; -+ struct wined3d_surface *surface; -+ struct wined3d_volume *volume; -+ -+ switch (resource->type) -+ { -+ case WINED3D_RTYPE_SURFACE: -+ surface = surface_from_resource(resource); -+ if (surface->container) -+ real_res = &surface->container->resource; -+ break; -+ -+ case WINED3D_RTYPE_VOLUME: -+ volume = volume_from_resource(resource); -+ real_res = &volume->container->resource; -+ break; -+ -+ default: -+ break; -+ } -+ if (!real_res->access_fence) -+ FIXME("Waiting for CS even though resource %p is idle.\n", resource); -+} -+ - HRESULT wined3d_resource_map(struct wined3d_resource *resource, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) - { -@@ -730,6 +756,8 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, - - flags = wined3d_resource_sanitize_map_flags(resource, flags); - -+ wined3d_resource_sync(resource); -+ - base_memory = wined3d_cs_emit_resource_map(device->cs, resource, flags); - if (!base_memory) - { --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0098-wined3d-Dirtify-resources-on-unmap.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0098-wined3d-Dirtify-resources-on-unmap.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0098-wined3d-Dirtify-resources-on-unmap.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0098-wined3d-Dirtify-resources-on-unmap.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -From 440a516b0908c7282e89fe73a788ca461d90d81e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 26 Sep 2013 17:25:01 +0200 -Subject: wined3d: Dirtify resources on unmap - ---- - dlls/wined3d/resource.c | 7 ++++++- - dlls/wined3d/surface.c | 4 ++++ - dlls/wined3d/volume.c | 3 +++ - dlls/wined3d/wined3d_private.h | 1 + - 4 files changed, 14 insertions(+), 1 deletion(-) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 708b080..73011f8 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -806,7 +806,7 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, - } - - if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) -- wined3d_resource_invalidate_location(resource, ~resource->map_binding); -+ resource->unmap_dirtify = TRUE; - - resource->map_count++; - -@@ -826,6 +826,11 @@ void wined3d_resource_unmap_internal(struct wined3d_resource *resource) - wined3d_resource_release_map_ptr(resource, context); - if (context) - context_release(context); -+ -+ if (resource->unmap_dirtify) -+ wined3d_resource_invalidate_location(resource, ~resource->map_binding); -+ resource->unmap_dirtify = FALSE; -+ - } - - HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 0c3313d..e661494 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -2405,6 +2405,10 @@ HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface) - HRESULT hr; - TRACE("surface %p.\n", surface); - -+ if (surface->resource.unmap_dirtify && surface->container) -+ wined3d_texture_set_dirty(surface->container); -+ -+ - hr = wined3d_resource_unmap(&surface->resource); - if (FAILED(hr)) - return hr; -diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index 7ce5331..faadea1 100644 ---- a/dlls/wined3d/volume.c -+++ b/dlls/wined3d/volume.c -@@ -424,6 +424,9 @@ HRESULT CDECL wined3d_volume_unmap(struct wined3d_volume *volume) - { - HRESULT hr; - -+ if (volume->resource.unmap_dirtify) -+ wined3d_texture_set_dirty(volume->container); -+ - hr = wined3d_resource_unmap(&volume->resource); - if (hr == WINEDDERR_NOTLOCKED) - return WINED3DERR_INVALIDCALL; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index b4e5679..d670fe1 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2119,6 +2119,7 @@ struct wined3d_resource - struct list resource_list_entry; - DWORD locations; - LONG access_fence; -+ BOOL unmap_dirtify; - - void *parent; - const struct wined3d_parent_ops *parent_ops; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0098-wined3d-Fence-blit-operations.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0098-wined3d-Fence-blit-operations.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0098-wined3d-Fence-blit-operations.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0098-wined3d-Fence-blit-operations.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,38 @@ +From 5903d5d7db4ffbfb87d1b9616d13ea05d19dd171 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 27 Sep 2013 16:57:01 +0200 +Subject: wined3d: Fence blit operations. + +--- + dlls/wined3d/cs.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index a4b996e..5603a37 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -1709,6 +1709,10 @@ static UINT wined3d_cs_exec_blt(struct wined3d_cs *cs, const void *data) + op->src_surface, &op->src_rect, + op->flags, &op->fx, op->filter); + ++ wined3d_resource_dec_fence(&op->dst_surface->container->resource); ++ if (op->src_surface && op->src_surface != op->dst_surface) ++ wined3d_resource_dec_fence(&op->src_surface->container->resource); ++ + return sizeof(*op); + } + +@@ -1730,6 +1734,10 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf + if (fx) + op->fx = *fx; + ++ wined3d_resource_inc_fence(&dst_surface->container->resource); ++ if (src_surface && src_surface != dst_surface) ++ wined3d_resource_inc_fence(&src_surface->container->resource); ++ + cs->ops->submit(cs, sizeof(*op)); + } + +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0099-wined3d-Fence-color_fill-operations.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0099-wined3d-Fence-color_fill-operations.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0099-wined3d-Fence-color_fill-operations.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0099-wined3d-Fence-color_fill-operations.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,34 @@ +From 97f6ef9c0d1d05efc640183d3b045296bca762a0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 27 Sep 2013 16:58:13 +0200 +Subject: wined3d: Fence color_fill operations. + +--- + dlls/wined3d/cs.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 5603a37..fb92286 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -1750,6 +1750,8 @@ static UINT wined3d_cs_exec_clear_rtv(struct wined3d_cs *cs, const void *data) + + surface_color_fill(surface_from_resource(resource), &op->rect, &op->color); + ++ wined3d_resource_dec_fence(op->view->resource); ++ + return sizeof(*op); + } + +@@ -1764,6 +1766,8 @@ void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarge + op->rect = *rect; + op->color = *color; + ++ wined3d_resource_inc_fence(view->resource); ++ + cs->ops->submit(cs, sizeof(*op)); + } + +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0099-wined3d-Fence-texture-reads-in-draws.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0099-wined3d-Fence-texture-reads-in-draws.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0099-wined3d-Fence-texture-reads-in-draws.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0099-wined3d-Fence-texture-reads-in-draws.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -From 2d87f930869bcd32273e722a50a13a9330ce6a30 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 30 Aug 2013 22:42:33 +0200 -Subject: wined3d: Fence texture reads in draws - -This is probably stricter than necessary. GL BOs and allocated sysmem -are just staging resources. After they have been uploaded into the GL -texture, it's in theory OK to write new data buffer without interfering -with old draws. However, it is impossible to tell when if data has been -transfered into the texture because texture loads are delayed until draw -time. Specifically, it is difficult to separate two consecutive maps -from a map, draw, map sequence, where the draw hasn't been executed by -the time the second map occurs. - -The other problem is that sRGB may cause a texture load from -buffer/sysmem even though the GL texture is thought to be loaded. This -is limited to situations where sRGB textures are supported, but -sRGB_decode isn't. ---- - dlls/wined3d/cs.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 9a7e6df..0277a1e 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -601,6 +601,11 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) - if (cs->state.streams[i].buffer) - wined3d_resource_dec_fence(&cs->state.streams[i].buffer->resource); - } -+ for (i = 0; i < sizeof(cs->state.textures) / sizeof(*cs->state.textures); i++) -+ { -+ if (cs->state.textures[i]) -+ wined3d_resource_dec_fence(&cs->state.textures[i]->resource); -+ } - - return sizeof(*op); - } -@@ -627,6 +632,11 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun - if (state->streams[i].buffer) - wined3d_resource_inc_fence(&state->streams[i].buffer->resource); - } -+ for (i = 0; i < sizeof(state->textures) / sizeof(*state->textures); i++) -+ { -+ if (state->textures[i]) -+ wined3d_resource_inc_fence(&state->textures[i]->resource); -+ } - - cs->ops->submit(cs, sizeof(*op)); - } --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0100-wined3d-Fence-clear-calls.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0100-wined3d-Fence-clear-calls.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0100-wined3d-Fence-clear-calls.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0100-wined3d-Fence-clear-calls.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,72 @@ +From bf044ed200f71fa0d27d5b74254afb4cef8fe7ca Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 27 Sep 2013 17:04:47 +0200 +Subject: wined3d: Fence clear calls. + +--- + dlls/wined3d/cs.c | 27 +++++++++++++++++++++++++-- + 1 file changed, 25 insertions(+), 2 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 23683d0..78731a0 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -550,7 +550,7 @@ static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) + const struct wined3d_cs_clear *op = data; + struct wined3d_device *device; + RECT draw_rect; +- unsigned int extra_rects = op->rect_count ? op->rect_count - 1 : 0; ++ unsigned int extra_rects = op->rect_count ? op->rect_count - 1 : 0, i; + + device = cs->device; + wined3d_get_draw_rect(&cs->state, &draw_rect); +@@ -558,6 +558,17 @@ static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) + &cs->state.fb, op->rect_count, op->rect_count ? op->rects : NULL, &draw_rect, op->flags, + &op->color, op->depth, op->stencil); + ++ if (op->flags & WINED3DCLEAR_TARGET) ++ { ++ for (i = 0; i < device->adapter->gl_info.limits.buffers; i++) ++ { ++ if (cs->state.fb.render_targets[i]) ++ wined3d_resource_dec_fence(cs->state.fb.render_targets[i]->resource); ++ } ++ } ++ if (op->flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) ++ wined3d_resource_dec_fence(cs->state.fb.depth_stencil->resource); ++ + return sizeof(*op) + sizeof(*op->rects) * extra_rects; + } + +@@ -565,8 +576,9 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * + DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) + { + struct wined3d_cs_clear *op; +- unsigned int extra_rects = rect_count ? rect_count - 1 : 0; ++ unsigned int extra_rects = rect_count ? rect_count - 1 : 0, i; + size_t size = sizeof(*op) + sizeof(*op->rects) * extra_rects; ++ const struct wined3d_state *state = &cs->device->state; + + op = cs->ops->require_space(cs, size); + op->opcode = WINED3D_CS_OP_CLEAR; +@@ -578,6 +590,17 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * + op->depth = depth; + op->stencil = stencil; + ++ if (flags & WINED3DCLEAR_TARGET) ++ { ++ for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; i++) ++ { ++ if (state->fb.render_targets[i]) ++ wined3d_resource_inc_fence(state->fb.render_targets[i]->resource); ++ } ++ } ++ if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) ++ wined3d_resource_inc_fence(state->fb.depth_stencil->resource); ++ + cs->ops->submit(cs, size); + } + +-- +2.5.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0100-wined3d-Fence-render-targets-and-depth-stencils.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0100-wined3d-Fence-render-targets-and-depth-stencils.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0100-wined3d-Fence-render-targets-and-depth-stencils.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0100-wined3d-Fence-render-targets-and-depth-stencils.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -From 18f06f3fccac3871c0db9d0229a137f920edfbef Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 27 Sep 2013 16:55:58 +0200 -Subject: wined3d: Fence render targets and depth stencils - ---- - dlls/wined3d/cs.c | 38 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index cc73bdc..73c3dc6 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -581,6 +581,30 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * - cs->ops->submit(cs, size); - } - -+static inline BOOL wined3d_cs_colorwrite_enabled(const struct wined3d_state *state, unsigned int i) -+{ -+ switch (i) -+ { -+ case 0: -+ return !!state->render_states[WINED3D_RS_COLORWRITEENABLE]; -+ case 1: -+ return !!state->render_states[WINED3D_RS_COLORWRITEENABLE1]; -+ case 2: -+ return !!state->render_states[WINED3D_RS_COLORWRITEENABLE2]; -+ case 3: -+ return !!state->render_states[WINED3D_RS_COLORWRITEENABLE3]; -+ default: -+ ERR("Unexpected color target %u.\n", i); -+ return TRUE; -+ } -+} -+ -+static inline BOOL wined3d_cs_depth_stencil_enabled(const struct wined3d_state *state) -+{ -+ return state->render_states[WINED3D_RS_ZENABLE] -+ || state->render_states[WINED3D_RS_STENCILENABLE]; -+} -+ - static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_draw *op = data; -@@ -616,6 +640,13 @@ static UINT wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) - if (cs->state.textures[i]) - wined3d_resource_dec_fence(&cs->state.textures[i]->resource); - } -+ for (i = 0; i < gl_info->limits.buffers; i++) -+ { -+ if (cs->state.fb.render_targets[i] && wined3d_cs_colorwrite_enabled(&cs->state, i)) -+ wined3d_resource_dec_fence(cs->state.fb.render_targets[i]->resource); -+ } -+ if (cs->state.fb.depth_stencil && wined3d_cs_depth_stencil_enabled(&cs->state)) -+ wined3d_resource_dec_fence(cs->state.fb.depth_stencil->resource); - - return sizeof(*op); - } -@@ -647,6 +678,13 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun - if (state->textures[i]) - wined3d_resource_inc_fence(&state->textures[i]->resource); - } -+ for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; i++) -+ { -+ if (state->fb.render_targets[i] && wined3d_cs_colorwrite_enabled(state, i)) -+ wined3d_resource_inc_fence(state->fb.render_targets[i]->resource); -+ } -+ if (state->fb.depth_stencil && wined3d_cs_depth_stencil_enabled(state)) -+ wined3d_resource_inc_fence(state->fb.depth_stencil->resource); - - cs->ops->submit(cs, sizeof(*op)); - } --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0101-wined3d-Fence-blit-operations.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0101-wined3d-Fence-blit-operations.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0101-wined3d-Fence-blit-operations.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0101-wined3d-Fence-blit-operations.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -From 5903d5d7db4ffbfb87d1b9616d13ea05d19dd171 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 27 Sep 2013 16:57:01 +0200 -Subject: wined3d: Fence blit operations. - ---- - dlls/wined3d/cs.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index a4b996e..5603a37 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -1709,6 +1709,10 @@ static UINT wined3d_cs_exec_blt(struct wined3d_cs *cs, const void *data) - op->src_surface, &op->src_rect, - op->flags, &op->fx, op->filter); - -+ wined3d_resource_dec_fence(&op->dst_surface->container->resource); -+ if (op->src_surface && op->src_surface != op->dst_surface) -+ wined3d_resource_dec_fence(&op->src_surface->container->resource); -+ - return sizeof(*op); - } - -@@ -1730,6 +1734,10 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf - if (fx) - op->fx = *fx; - -+ wined3d_resource_inc_fence(&dst_surface->container->resource); -+ if (src_surface && src_surface != dst_surface) -+ wined3d_resource_inc_fence(&src_surface->container->resource); -+ - cs->ops->submit(cs, sizeof(*op)); - } - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0101-wined3d-Fence-present-calls.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0101-wined3d-Fence-present-calls.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0101-wined3d-Fence-present-calls.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0101-wined3d-Fence-present-calls.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,54 @@ +From e485302fbcd610c34cf3e664d3d9a588fb7f3a32 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 27 Sep 2013 17:55:35 +0200 +Subject: wined3d: Fence present calls. + +--- + dlls/wined3d/cs.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index bdb9279..45dc5ce 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -485,6 +485,7 @@ static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) + const RECT *src_rect = op->set_data & CS_PRESENT_SRC_RECT ? &op->src_rect : NULL; + const RECT *dst_rect = op->set_data & CS_PRESENT_DST_RECT ? &op->dst_rect : NULL; + const RGNDATA *dirty_region = op->set_data & CS_PRESENT_DIRTY_RGN ? &op->dirty_region : NULL; ++ unsigned int i; + + swapchain = op->swapchain; + wined3d_swapchain_set_window(swapchain, op->dst_window_override); +@@ -495,6 +496,10 @@ static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) + + InterlockedDecrement(&cs->pending_presents); + ++ wined3d_resource_dec_fence(&swapchain->front_buffer->resource); ++ for (i = 0; i < swapchain->desc.backbuffer_count; i++) ++ wined3d_resource_dec_fence(&swapchain->back_buffers[i]->resource); ++ + return sizeof(*op); + } + +@@ -504,6 +509,7 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw + { + struct wined3d_cs_present *op; + LONG pending; ++ unsigned int i; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_PRESENT; +@@ -527,6 +533,10 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw + } + op->flags = flags; + ++ wined3d_resource_inc_fence(&swapchain->front_buffer->resource); ++ for (i = 0; i < swapchain->desc.backbuffer_count; i++) ++ wined3d_resource_inc_fence(&swapchain->back_buffers[i]->resource); ++ + pending = InterlockedIncrement(&cs->pending_presents); + + cs->ops->submit(cs, sizeof(*op)); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0102-wined3d-Fence-color_fill-operations.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0102-wined3d-Fence-color_fill-operations.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0102-wined3d-Fence-color_fill-operations.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0102-wined3d-Fence-color_fill-operations.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -From 97f6ef9c0d1d05efc640183d3b045296bca762a0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 27 Sep 2013 16:58:13 +0200 -Subject: wined3d: Fence color_fill operations. - ---- - dlls/wined3d/cs.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 5603a37..fb92286 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -1750,6 +1750,8 @@ static UINT wined3d_cs_exec_clear_rtv(struct wined3d_cs *cs, const void *data) - - surface_color_fill(surface_from_resource(resource), &op->rect, &op->color); - -+ wined3d_resource_dec_fence(op->view->resource); -+ - return sizeof(*op); - } - -@@ -1764,6 +1766,8 @@ void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarge - op->rect = *rect; - op->color = *color; - -+ wined3d_resource_inc_fence(view->resource); -+ - cs->ops->submit(cs, sizeof(*op)); - } - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0102-wined3d-Make-resource-maps-and-unmaps-a-priority-com.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0102-wined3d-Make-resource-maps-and-unmaps-a-priority-com.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0102-wined3d-Make-resource-maps-and-unmaps-a-priority-com.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0102-wined3d-Make-resource-maps-and-unmaps-a-priority-com.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,80 @@ +From a14049c3703ec2f275f2ce21b45ba4bc32d6021d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 27 Sep 2013 17:58:25 +0200 +Subject: wined3d: Make resource maps and unmaps a priority command. + +--- + dlls/wined3d/cs.c | 14 +++++--------- + dlls/wined3d/resource.c | 8 ++++++-- + 2 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 45dc5ce..054c000 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -1819,19 +1819,15 @@ void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resourc + struct wined3d_cs_resource_map *op; + void *ret; + +- op = cs->ops->require_space(cs, sizeof(*op)); ++ op = cs->ops->require_space_prio(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_RESOURCE_MAP; + op->resource = resource; + op->flags = flags; + op->mem = &ret; + +- cs->ops->submit(cs, sizeof(*op)); ++ cs->ops->submit_prio(cs, sizeof(*op)); + +- if (flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD)) +- { +- FIXME("Dynamic resource map is inefficient\n"); +- } +- cs->ops->finish(cs); ++ cs->ops->finish_prio(cs); + + return ret; + } +@@ -1850,11 +1846,11 @@ void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resour + { + struct wined3d_cs_resource_unmap *op; + +- op = cs->ops->require_space(cs, sizeof(*op)); ++ op = cs->ops->require_space_prio(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_RESOURCE_UNMAP; + op->resource = resource; + +- cs->ops->submit(cs, sizeof(*op)); ++ cs->ops->submit_prio(cs, sizeof(*op)); + } + + static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 73011f8..d2407a1 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -734,8 +734,7 @@ static void wined3d_resource_sync(struct wined3d_resource *resource) + default: + break; + } +- if (!real_res->access_fence) +- FIXME("Waiting for CS even though resource %p is idle.\n", resource); ++ wined3d_resource_wait_fence(real_res); + } + + HRESULT wined3d_resource_map(struct wined3d_resource *resource, +@@ -756,6 +755,11 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, + + flags = wined3d_resource_sanitize_map_flags(resource, flags); + ++ if (flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD)) ++ { ++ FIXME("Dynamic resource map is inefficient\n"); ++ } ++ + wined3d_resource_sync(resource); + + base_memory = wined3d_cs_emit_resource_map(device->cs, resource, flags); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0103-wined3d-Dirtify-changed-textures-through-the-command.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0103-wined3d-Dirtify-changed-textures-through-the-command.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0103-wined3d-Dirtify-changed-textures-through-the-command.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0103-wined3d-Dirtify-changed-textures-through-the-command.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,176 @@ +From eb59e53d03f032fe4e04a6e7843ac06e9dddbbdd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 27 Sep 2013 18:46:19 +0200 +Subject: wined3d: Dirtify changed textures through the command stream. + +This makes sure unsynchronized maps (NOOVERWRITE /DISCARD) are reflected +in the volume's location flags at the right time. +--- + dlls/wined3d/cs.c | 31 ++++++++++++++++++++++++++++++- + dlls/wined3d/resource.c | 15 ++++++++++----- + dlls/wined3d/surface.c | 9 +++------ + dlls/wined3d/wined3d_private.h | 2 ++ + 4 files changed, 45 insertions(+), 12 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 054c000..f5c10dd 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -65,6 +65,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_SET_LIGHT_ENABLE, + WINED3D_CS_OP_BLT, + WINED3D_CS_OP_CLEAR_RTV, ++ WINED3D_CS_OP_RESOURCE_CHANGED, + WINED3D_CS_OP_RESOURCE_MAP, + WINED3D_CS_OP_RESOURCE_UNMAP, + WINED3D_CS_OP_QUERY_ISSUE, +@@ -365,6 +366,12 @@ struct wined3d_cs_resource_unmap + struct wined3d_resource *resource; + }; + ++struct wined3d_cs_resource_changed ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_resource *resource; ++}; ++ + struct wined3d_cs_skip + { + enum wined3d_cs_op opcode; +@@ -1804,6 +1811,27 @@ void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarge + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_resource_changed(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_resource_changed *op = data; ++ struct wined3d_resource *resource = op->resource; ++ ++ wined3d_resource_changed(resource); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource) ++{ ++ struct wined3d_cs_resource_changed *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_RESOURCE_CHANGED; ++ op->resource = resource; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT wined3d_cs_exec_resource_map(struct wined3d_cs *cs, const void *data) + { + const struct wined3d_cs_resource_map *op = data; +@@ -2110,11 +2138,11 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, + /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, + /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, +- /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, + /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, + /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, + /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, + /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, ++ /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, + /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, + /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, + /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, +@@ -2133,6 +2161,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, + /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, + /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, ++ /* WINED3D_CS_OP_RESOURCE_CHANGED */ wined3d_cs_exec_resource_changed, + /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, + /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, + /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index d2407a1..7cafdc6 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -830,11 +830,6 @@ void wined3d_resource_unmap_internal(struct wined3d_resource *resource) + wined3d_resource_release_map_ptr(resource, context); + if (context) + context_release(context); +- +- if (resource->unmap_dirtify) +- wined3d_resource_invalidate_location(resource, ~resource->map_binding); +- resource->unmap_dirtify = FALSE; +- + } + + HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) +@@ -849,7 +844,17 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) + } + + wined3d_cs_emit_resource_unmap(device->cs, resource); ++ ++ if (resource->unmap_dirtify) ++ wined3d_cs_emit_resource_changed(device->cs, resource); ++ resource->unmap_dirtify = FALSE; ++ + resource->map_count--; + + return WINED3D_OK; + } ++ ++void wined3d_resource_changed(struct wined3d_resource *resource) ++{ ++ wined3d_resource_invalidate_location(resource, ~resource->map_binding); ++} +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index e661494..535e21a 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -1093,6 +1093,9 @@ static void wined3d_surface_location_invalidated(struct wined3d_resource *resour + + if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + wined3d_texture_set_dirty(surface->container); ++ ++ if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) ++ surface->surface_ops->surface_frontbuffer_updated(surface); + } + + static const struct wined3d_surface_ops surface_ops = +@@ -2405,16 +2408,10 @@ HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface) + HRESULT hr; + TRACE("surface %p.\n", surface); + +- if (surface->resource.unmap_dirtify && surface->container) +- wined3d_texture_set_dirty(surface->container); +- +- + hr = wined3d_resource_unmap(&surface->resource); + if (FAILED(hr)) + return hr; + +- if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) +- surface->surface_ops->surface_frontbuffer_updated(surface); + memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); + + return hr; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index d670fe1..b9831fd 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2146,6 +2146,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * + void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; + BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++void wined3d_resource_changed(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, + const struct wined3d_box *box) DECLSPEC_HIDDEN; + void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN; +@@ -2662,6 +2663,7 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf + enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; + void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, + const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, + DWORD flags) DECLSPEC_HIDDEN; + void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0103-wined3d-Fence-clear-calls.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0103-wined3d-Fence-clear-calls.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0103-wined3d-Fence-clear-calls.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0103-wined3d-Fence-clear-calls.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -From bf044ed200f71fa0d27d5b74254afb4cef8fe7ca Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 27 Sep 2013 17:04:47 +0200 -Subject: wined3d: Fence clear calls. - ---- - dlls/wined3d/cs.c | 27 +++++++++++++++++++++++++-- - 1 file changed, 25 insertions(+), 2 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 23683d0..78731a0 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -550,7 +550,7 @@ static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) - const struct wined3d_cs_clear *op = data; - struct wined3d_device *device; - RECT draw_rect; -- unsigned int extra_rects = op->rect_count ? op->rect_count - 1 : 0; -+ unsigned int extra_rects = op->rect_count ? op->rect_count - 1 : 0, i; - - device = cs->device; - wined3d_get_draw_rect(&cs->state, &draw_rect); -@@ -558,6 +558,17 @@ static UINT wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) - &cs->state.fb, op->rect_count, op->rect_count ? op->rects : NULL, &draw_rect, op->flags, - &op->color, op->depth, op->stencil); - -+ if (op->flags & WINED3DCLEAR_TARGET) -+ { -+ for (i = 0; i < device->adapter->gl_info.limits.buffers; i++) -+ { -+ if (cs->state.fb.render_targets[i]) -+ wined3d_resource_dec_fence(cs->state.fb.render_targets[i]->resource); -+ } -+ } -+ if (op->flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) -+ wined3d_resource_dec_fence(cs->state.fb.depth_stencil->resource); -+ - return sizeof(*op) + sizeof(*op->rects) * extra_rects; - } - -@@ -565,8 +576,9 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * - DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) - { - struct wined3d_cs_clear *op; -- unsigned int extra_rects = rect_count ? rect_count - 1 : 0; -+ unsigned int extra_rects = rect_count ? rect_count - 1 : 0, i; - size_t size = sizeof(*op) + sizeof(*op->rects) * extra_rects; -+ const struct wined3d_state *state = &cs->device->state; - - op = cs->ops->require_space(cs, size); - op->opcode = WINED3D_CS_OP_CLEAR; -@@ -578,6 +590,17 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * - op->depth = depth; - op->stencil = stencil; - -+ if (flags & WINED3DCLEAR_TARGET) -+ { -+ for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; i++) -+ { -+ if (state->fb.render_targets[i]) -+ wined3d_resource_inc_fence(state->fb.render_targets[i]->resource); -+ } -+ } -+ if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) -+ wined3d_resource_inc_fence(state->fb.depth_stencil->resource); -+ - cs->ops->submit(cs, size); - } - --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0104-wined3d-Fence-present-calls.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0104-wined3d-Fence-present-calls.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0104-wined3d-Fence-present-calls.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0104-wined3d-Fence-present-calls.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -From e485302fbcd610c34cf3e664d3d9a588fb7f3a32 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 27 Sep 2013 17:55:35 +0200 -Subject: wined3d: Fence present calls. - ---- - dlls/wined3d/cs.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index bdb9279..45dc5ce 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -485,6 +485,7 @@ static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) - const RECT *src_rect = op->set_data & CS_PRESENT_SRC_RECT ? &op->src_rect : NULL; - const RECT *dst_rect = op->set_data & CS_PRESENT_DST_RECT ? &op->dst_rect : NULL; - const RGNDATA *dirty_region = op->set_data & CS_PRESENT_DIRTY_RGN ? &op->dirty_region : NULL; -+ unsigned int i; - - swapchain = op->swapchain; - wined3d_swapchain_set_window(swapchain, op->dst_window_override); -@@ -495,6 +496,10 @@ static UINT wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) - - InterlockedDecrement(&cs->pending_presents); - -+ wined3d_resource_dec_fence(&swapchain->front_buffer->resource); -+ for (i = 0; i < swapchain->desc.backbuffer_count; i++) -+ wined3d_resource_dec_fence(&swapchain->back_buffers[i]->resource); -+ - return sizeof(*op); - } - -@@ -504,6 +509,7 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw - { - struct wined3d_cs_present *op; - LONG pending; -+ unsigned int i; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_PRESENT; -@@ -527,6 +533,10 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw - } - op->flags = flags; - -+ wined3d_resource_inc_fence(&swapchain->front_buffer->resource); -+ for (i = 0; i < swapchain->desc.backbuffer_count; i++) -+ wined3d_resource_inc_fence(&swapchain->back_buffers[i]->resource); -+ - pending = InterlockedIncrement(&cs->pending_presents); - - cs->ops->submit(cs, sizeof(*op)); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0104-wined3d-Wrap-GL-BOs-in-a-structure.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0104-wined3d-Wrap-GL-BOs-in-a-structure.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0104-wined3d-Wrap-GL-BOs-in-a-structure.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0104-wined3d-Wrap-GL-BOs-in-a-structure.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,274 @@ +From c9ba533914088eba32bfa04e4318c1b18b20388e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 30 Aug 2013 17:00:35 +0200 +Subject: wined3d: Wrap GL BOs in a structure + +The idea is to use those structures for mapping through the command stream and caching +them for DISCARD maps. +--- + dlls/wined3d/device.c | 53 ++++++++++++++++++++++++++++++++++++++++++ + dlls/wined3d/resource.c | 34 +++++++++++---------------- + dlls/wined3d/surface.c | 4 ++-- + dlls/wined3d/texture.c | 2 +- + dlls/wined3d/volume.c | 6 ++--- + dlls/wined3d/wined3d_private.h | 15 +++++++++++- + 6 files changed, 86 insertions(+), 28 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 46058ef..4325e65 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -5254,3 +5254,56 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL + else + return CallWindowProcA(proc, window, message, wparam, lparam); + } ++ ++/* Context activation is done by the caller */ ++struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage, ++ GLenum type_hint, struct wined3d_context *context) ++{ ++ struct wined3d_gl_bo *ret; ++ const struct wined3d_gl_info *gl_info; ++ ++ TRACE("device %p, size %u, gl_usage %u, type_hint %u\n", device, size, gl_usage, ++ type_hint); ++ ++ ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)); ++ if(!ret) ++ return NULL; ++ ret->type_hint = type_hint; ++ ret->size = size; ++ ret->usage = gl_usage; ++ ++ gl_info = context->gl_info; ++ ++ GL_EXTCALL(glGenBuffers(1, &ret->name)); ++ if (type_hint == GL_ELEMENT_ARRAY_BUFFER) ++ context_invalidate_state(context, STATE_INDEXBUFFER); ++ GL_EXTCALL(glBindBuffer(type_hint, ret->name)); ++ GL_EXTCALL(glBufferData(type_hint, size, NULL, gl_usage)); ++ GL_EXTCALL(glBindBuffer(type_hint, 0)); ++ checkGLcall("Create buffer object"); ++ ++ TRACE("Successfully created and set up buffer %u\n", ret->name); ++ return ret; ++} ++ ++/* Context activation is done by the caller */ ++static void wined3d_device_destroy_bo(struct wined3d_device *device, const struct wined3d_context *context, ++ struct wined3d_gl_bo *bo) ++{ ++ const struct wined3d_gl_info *gl_info = context->gl_info; ++ TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name); ++ ++ GL_EXTCALL(glDeleteBuffers(1, &bo->name)); ++ checkGLcall("glDeleteBuffers"); ++ ++ HeapFree(GetProcessHeap(), 0, bo); ++} ++ ++/* Context activation is done by the caller */ ++void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, ++ const struct wined3d_context *context) ++{ ++ TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name); ++ ++ wined3d_device_destroy_bo(device, context, bo); ++} +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 3b9c609..611bfa3 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -236,12 +236,10 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * + void wined3d_resource_free_bo(struct wined3d_resource *resource) + { + struct wined3d_context *context = context_acquire(resource->device, NULL); +- const struct wined3d_gl_info *gl_info = context->gl_info; + +- TRACE("Deleting GL buffer %u belonging to resource %p.\n", resource->buffer_object, resource); +- GL_EXTCALL(glDeleteBuffers(1, &resource->buffer_object)); +- checkGLcall("glDeleteBuffers"); +- resource->buffer_object = 0; ++ wined3d_device_release_bo(resource->device, resource->buffer, context); ++ resource->buffer = NULL; ++ + context_release(context); + } + +@@ -257,7 +255,7 @@ void resource_cleanup(struct wined3d_resource *resource) + adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size); + } + +- if (resource->buffer_object) ++ if (resource->buffer) + wined3d_resource_free_bo(resource); + + wined3d_resource_free_sysmem(resource); +@@ -270,7 +268,7 @@ void resource_unload(struct wined3d_resource *resource) + if (resource->map_count) + ERR("Resource %p is being unloaded while mapped.\n", resource); + +- if (resource->buffer_object) ++ if (resource->buffer) + wined3d_resource_free_bo(resource); + + context_resource_unloaded(resource->device, +@@ -537,7 +535,7 @@ void wined3d_resource_get_memory(const struct wined3d_resource *resource, + { + if (location & WINED3D_LOCATION_BUFFER) + { +- data->buffer_object = resource->buffer_object; ++ data->buffer_object = resource->buffer->name; + data->addr = NULL; + return; + } +@@ -646,7 +644,7 @@ BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, + { + case WINED3D_LOCATION_BUFFER: + gl_info = context->gl_info; +- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer_object)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer->name)); + + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { +@@ -689,7 +687,7 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, + { + case WINED3D_LOCATION_BUFFER: + gl_info = context->gl_info; +- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer_object)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer->name)); + GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("Unmap GL buffer"); +@@ -707,20 +705,14 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, + } + + /* Context activation is done by the caller. */ +-static void wined3d_resource_prepare_bo(struct wined3d_resource *resource, const struct wined3d_context *context) ++static void wined3d_resource_prepare_bo(struct wined3d_resource *resource, struct wined3d_context *context) + { +- const struct wined3d_gl_info *gl_info = context->gl_info; +- +- if (resource->buffer_object) ++ if (resource->buffer) + return; + +- GL_EXTCALL(glGenBuffers(1, &resource->buffer_object)); +- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer_object)); +- GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, resource->size, NULL, GL_STREAM_DRAW)); +- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); +- checkGLcall("Create GL buffer"); +- +- TRACE("Created GL buffer %u for resource %p.\n", resource->buffer_object, resource); ++ resource->buffer = wined3d_device_get_bo(resource->device, resource->size, ++ GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); ++ TRACE("Created GL buffer %u for resource %p.\n", resource->buffer->name, resource); + } + + BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 40f4dab..3816f35 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -48,7 +48,7 @@ static void surface_cleanup(struct wined3d_surface *surface) + surface->resource.device->cs->ops->finish(surface->resource.device->cs); + } + +- if (surface->resource.buffer_object || surface->rb_multisample ++ if (surface->resource.buffer || surface->rb_multisample + || surface->rb_resolved || !list_empty(&surface->renderbuffers)) + { + struct wined3d_renderbuffer_entry *entry, *entry2; +@@ -3701,7 +3701,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, + /* Don't use PBOs for converted surfaces. During PBO conversion we look at + * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is + * getting called. */ +- if ((format.convert || conversion) && surface->resource.buffer_object) ++ if ((format.convert || conversion) && surface->resource.buffer) + { + TRACE("Removing the pbo attached to surface %p.\n", surface); + +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index 12796198..0fcc436 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -1586,7 +1586,7 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i + } + if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY + || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM +- || surface->resource.buffer_object)) ++ || surface->resource.buffer)) + surface->resource.map_binding = WINED3D_LOCATION_DIB; + } + +diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c +index 807e626..d93a0bd 100644 +--- a/dlls/wined3d/volume.c ++++ b/dlls/wined3d/volume.c +@@ -216,7 +216,7 @@ static void wined3d_volume_load_location(struct wined3d_resource *resource, + } + else if (volume->resource.locations & WINED3D_LOCATION_BUFFER) + { +- struct wined3d_const_bo_address data = {volume->resource.buffer_object, NULL}; ++ struct wined3d_const_bo_address data = {volume->resource.buffer->name, NULL}; + wined3d_texture_bind_and_dirtify(volume->container, context, + location == WINED3D_LOCATION_TEXTURE_SRGB); + wined3d_volume_upload_data(volume, context, &data); +@@ -267,12 +267,12 @@ static void wined3d_volume_load_location(struct wined3d_resource *resource, + break; + + case WINED3D_LOCATION_BUFFER: +- if (!volume->resource.buffer_object) ++ if (!volume->resource.buffer) + ERR("Trying to load WINED3D_LOCATION_BUFFER without setting it up first.\n"); + + if (volume->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { +- struct wined3d_bo_address data = {volume->resource.buffer_object, NULL}; ++ struct wined3d_bo_address data = {volume->resource.buffer->name, NULL}; + + if (volume->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) + wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 877dd1e..67301c8 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2120,6 +2120,14 @@ struct wined3d_state + DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; + }; + ++struct wined3d_gl_bo ++{ ++ GLuint name; ++ GLenum usage; ++ GLenum type_hint; ++ UINT size; ++}; ++ + #define WINED3D_UNMAPPED_STAGE ~0U + + /* Multithreaded flag. Removed from the public header to signal that +@@ -2229,6 +2237,11 @@ void device_invalidate_state(const struct wined3d_device *device, DWORD state) D + void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) DECLSPEC_HIDDEN; + void device_exec_update_texture(struct wined3d_context *context, struct wined3d_texture *src_texture, + struct wined3d_texture *dst_texture) DECLSPEC_HIDDEN; ++struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage, ++ GLenum type_hint, struct wined3d_context *context) DECLSPEC_HIDDEN; ++void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, ++ const struct wined3d_context *context) DECLSPEC_HIDDEN; ++ + + static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) + { +@@ -2277,7 +2290,7 @@ struct wined3d_resource + DWORD priority; + void *heap_memory, *user_memory, *bitmap_data; + UINT custom_row_pitch, custom_slice_pitch; +- GLuint buffer_object; ++ struct wined3d_gl_bo *buffer; + struct list resource_list_entry; + DWORD locations; + LONG access_fence; +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0105-wined3d-Make-resource-maps-and-unmaps-a-priority-com.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0105-wined3d-Make-resource-maps-and-unmaps-a-priority-com.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0105-wined3d-Make-resource-maps-and-unmaps-a-priority-com.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0105-wined3d-Make-resource-maps-and-unmaps-a-priority-com.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -From a14049c3703ec2f275f2ce21b45ba4bc32d6021d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 27 Sep 2013 17:58:25 +0200 -Subject: wined3d: Make resource maps and unmaps a priority command. - ---- - dlls/wined3d/cs.c | 14 +++++--------- - dlls/wined3d/resource.c | 8 ++++++-- - 2 files changed, 11 insertions(+), 11 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 45dc5ce..054c000 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -1819,19 +1819,15 @@ void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resourc - struct wined3d_cs_resource_map *op; - void *ret; - -- op = cs->ops->require_space(cs, sizeof(*op)); -+ op = cs->ops->require_space_prio(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_RESOURCE_MAP; - op->resource = resource; - op->flags = flags; - op->mem = &ret; - -- cs->ops->submit(cs, sizeof(*op)); -+ cs->ops->submit_prio(cs, sizeof(*op)); - -- if (flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD)) -- { -- FIXME("Dynamic resource map is inefficient\n"); -- } -- cs->ops->finish(cs); -+ cs->ops->finish_prio(cs); - - return ret; - } -@@ -1850,11 +1846,11 @@ void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resour - { - struct wined3d_cs_resource_unmap *op; - -- op = cs->ops->require_space(cs, sizeof(*op)); -+ op = cs->ops->require_space_prio(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_RESOURCE_UNMAP; - op->resource = resource; - -- cs->ops->submit(cs, sizeof(*op)); -+ cs->ops->submit_prio(cs, sizeof(*op)); - } - - static UINT wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data) -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 73011f8..d2407a1 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -734,8 +734,7 @@ static void wined3d_resource_sync(struct wined3d_resource *resource) - default: - break; - } -- if (!real_res->access_fence) -- FIXME("Waiting for CS even though resource %p is idle.\n", resource); -+ wined3d_resource_wait_fence(real_res); - } - - HRESULT wined3d_resource_map(struct wined3d_resource *resource, -@@ -756,6 +755,11 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, - - flags = wined3d_resource_sanitize_map_flags(resource, flags); - -+ if (flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD)) -+ { -+ FIXME("Dynamic resource map is inefficient\n"); -+ } -+ - wined3d_resource_sync(resource); - - base_memory = wined3d_cs_emit_resource_map(device->cs, resource, flags); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0105-wined3d-Separate-resource-map-and-draw-buffers.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0105-wined3d-Separate-resource-map-and-draw-buffers.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0105-wined3d-Separate-resource-map-and-draw-buffers.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0105-wined3d-Separate-resource-map-and-draw-buffers.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,69 @@ +From 93fe426cbd0d2b61997d59fbbd1e49b2615f8c0c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 30 Aug 2013 17:06:29 +0200 +Subject: wined3d: Separate resource map and draw buffers + +--- + dlls/wined3d/resource.c | 9 +++++++-- + dlls/wined3d/wined3d_private.h | 2 +- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 8fb95a1..39555ef 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -146,8 +146,12 @@ void wined3d_resource_free_bo(struct wined3d_resource *resource) + { + struct wined3d_context *context = context_acquire(resource->device, NULL); + ++ if (resource->buffer != resource->map_buffer) ++ ERR("Releasing resource buffer with buffer != map_buffer.\n"); ++ + wined3d_device_release_bo(resource->device, resource->buffer, context); + resource->buffer = NULL; ++ resource->map_buffer = NULL; + + context_release(context); + } +@@ -535,7 +539,7 @@ BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, + { + case WINED3D_LOCATION_BUFFER: + gl_info = context->gl_info; +- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer->name)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->map_buffer->name)); + + if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) + { +@@ -578,7 +582,7 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, + { + case WINED3D_LOCATION_BUFFER: + gl_info = context->gl_info; +- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer->name)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->map_buffer->name)); + GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); + GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); + checkGLcall("Unmap GL buffer"); +@@ -603,6 +607,7 @@ static void wined3d_resource_prepare_bo(struct wined3d_resource *resource, struc + + resource->buffer = wined3d_device_get_bo(resource->device, resource->size, + GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); ++ resource->map_buffer = resource->buffer; + TRACE("Created GL buffer %u for resource %p.\n", resource->buffer->name, resource); + } + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index ff64215..374dbc2 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2139,7 +2139,7 @@ struct wined3d_resource + DWORD priority; + void *heap_memory, *user_memory, *bitmap_data; + UINT custom_row_pitch, custom_slice_pitch; +- struct wined3d_gl_bo *buffer; ++ struct wined3d_gl_bo *buffer, *map_buffer; + struct list resource_list_entry; + DWORD locations; + LONG access_fence; +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0106-wined3d-Dirtify-changed-textures-through-the-command.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0106-wined3d-Dirtify-changed-textures-through-the-command.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0106-wined3d-Dirtify-changed-textures-through-the-command.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0106-wined3d-Dirtify-changed-textures-through-the-command.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,176 +0,0 @@ -From eb59e53d03f032fe4e04a6e7843ac06e9dddbbdd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 27 Sep 2013 18:46:19 +0200 -Subject: wined3d: Dirtify changed textures through the command stream. - -This makes sure unsynchronized maps (NOOVERWRITE /DISCARD) are reflected -in the volume's location flags at the right time. ---- - dlls/wined3d/cs.c | 31 ++++++++++++++++++++++++++++++- - dlls/wined3d/resource.c | 15 ++++++++++----- - dlls/wined3d/surface.c | 9 +++------ - dlls/wined3d/wined3d_private.h | 2 ++ - 4 files changed, 45 insertions(+), 12 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 054c000..f5c10dd 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -65,6 +65,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_SET_LIGHT_ENABLE, - WINED3D_CS_OP_BLT, - WINED3D_CS_OP_CLEAR_RTV, -+ WINED3D_CS_OP_RESOURCE_CHANGED, - WINED3D_CS_OP_RESOURCE_MAP, - WINED3D_CS_OP_RESOURCE_UNMAP, - WINED3D_CS_OP_QUERY_ISSUE, -@@ -365,6 +366,12 @@ struct wined3d_cs_resource_unmap - struct wined3d_resource *resource; - }; - -+struct wined3d_cs_resource_changed -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_resource *resource; -+}; -+ - struct wined3d_cs_skip - { - enum wined3d_cs_op opcode; -@@ -1804,6 +1811,27 @@ void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarge - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_resource_changed(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_resource_changed *op = data; -+ struct wined3d_resource *resource = op->resource; -+ -+ wined3d_resource_changed(resource); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource) -+{ -+ struct wined3d_cs_resource_changed *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_RESOURCE_CHANGED; -+ op->resource = resource; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT wined3d_cs_exec_resource_map(struct wined3d_cs *cs, const void *data) - { - const struct wined3d_cs_resource_map *op = data; -@@ -2110,11 +2138,11 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, - /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, - /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, -- /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, - /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, - /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, - /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, - /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, -+ /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, - /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, - /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, - /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, -@@ -2133,6 +2161,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, - /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, - /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, -+ /* WINED3D_CS_OP_RESOURCE_CHANGED */ wined3d_cs_exec_resource_changed, - /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, - /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, - /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index d2407a1..7cafdc6 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -830,11 +830,6 @@ void wined3d_resource_unmap_internal(struct wined3d_resource *resource) - wined3d_resource_release_map_ptr(resource, context); - if (context) - context_release(context); -- -- if (resource->unmap_dirtify) -- wined3d_resource_invalidate_location(resource, ~resource->map_binding); -- resource->unmap_dirtify = FALSE; -- - } - - HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) -@@ -849,7 +844,17 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) - } - - wined3d_cs_emit_resource_unmap(device->cs, resource); -+ -+ if (resource->unmap_dirtify) -+ wined3d_cs_emit_resource_changed(device->cs, resource); -+ resource->unmap_dirtify = FALSE; -+ - resource->map_count--; - - return WINED3D_OK; - } -+ -+void wined3d_resource_changed(struct wined3d_resource *resource) -+{ -+ wined3d_resource_invalidate_location(resource, ~resource->map_binding); -+} -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index e661494..535e21a 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -1093,6 +1093,9 @@ static void wined3d_surface_location_invalidated(struct wined3d_resource *resour - - if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - wined3d_texture_set_dirty(surface->container); -+ -+ if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) -+ surface->surface_ops->surface_frontbuffer_updated(surface); - } - - static const struct wined3d_surface_ops surface_ops = -@@ -2405,16 +2408,10 @@ HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface) - HRESULT hr; - TRACE("surface %p.\n", surface); - -- if (surface->resource.unmap_dirtify && surface->container) -- wined3d_texture_set_dirty(surface->container); -- -- - hr = wined3d_resource_unmap(&surface->resource); - if (FAILED(hr)) - return hr; - -- if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) -- surface->surface_ops->surface_frontbuffer_updated(surface); - memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); - - return hr; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index d670fe1..b9831fd 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2146,6 +2146,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * - void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; - BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+void wined3d_resource_changed(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, - const struct wined3d_box *box) DECLSPEC_HIDDEN; - void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -@@ -2662,6 +2663,7 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf - enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; - void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, - const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, - DWORD flags) DECLSPEC_HIDDEN; - void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0106-wined3d-Implement-DISCARD-resource-maps-with-buffers.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0106-wined3d-Implement-DISCARD-resource-maps-with-buffers.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0106-wined3d-Implement-DISCARD-resource-maps-with-buffers.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0106-wined3d-Implement-DISCARD-resource-maps-with-buffers.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,150 @@ +From eb880bc806a44d2d2d09df19a43fd1a5f7d8ecf1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 27 Sep 2013 19:06:41 +0200 +Subject: wined3d: Implement DISCARD resource maps with buffers. + +--- + dlls/wined3d/cs.c | 7 +++++-- + dlls/wined3d/resource.c | 41 ++++++++++++++++++++++++++++++++++------- + dlls/wined3d/wined3d_private.h | 6 ++++-- + 3 files changed, 43 insertions(+), 11 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index f5c10dd..d86aa59 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -370,6 +370,7 @@ struct wined3d_cs_resource_changed + { + enum wined3d_cs_op opcode; + struct wined3d_resource *resource; ++ struct wined3d_gl_bo *swap_buffer; + }; + + struct wined3d_cs_skip +@@ -1816,18 +1817,20 @@ static UINT wined3d_cs_exec_resource_changed(struct wined3d_cs *cs, const void * + const struct wined3d_cs_resource_changed *op = data; + struct wined3d_resource *resource = op->resource; + +- wined3d_resource_changed(resource); ++ wined3d_resource_changed(resource, op->swap_buffer); + + return sizeof(*op); + } + +-void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource) ++void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource, ++ struct wined3d_gl_bo *swap_buffer) + { + struct wined3d_cs_resource_changed *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_RESOURCE_CHANGED; + op->resource = resource; ++ op->swap_buffer = swap_buffer; + + cs->ops->submit(cs, sizeof(*op)); + } +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 39555ef..69dd95a 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -697,9 +697,27 @@ void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD fla + } + + if (flags & WINED3D_MAP_DISCARD) ++ { ++ switch (resource->map_binding) ++ { ++ case WINED3D_LOCATION_BUFFER: ++ resource->map_buffer = wined3d_device_get_bo(device, resource->size, ++ GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); ++ break; ++ ++ default: ++ if (resource->access_fence) ++ ERR("Location %s does not support DISCARD maps.\n", ++ wined3d_debug_location(resource->map_binding)); ++ if (resource->pool != WINED3D_POOL_DEFAULT) ++ FIXME("Discard used on %s pool resource.\n", debug_d3dpool(resource->pool)); ++ } + wined3d_resource_validate_location(resource, resource->map_binding); ++ } + else ++ { + wined3d_resource_load_location(resource, context, resource->map_binding); ++ } + + mem = wined3d_resource_get_map_ptr(resource, context, flags); + +@@ -752,12 +770,11 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, + + flags = wined3d_resource_sanitize_map_flags(resource, flags); + +- if (flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD)) +- { +- FIXME("Dynamic resource map is inefficient\n"); +- } ++ if (flags & WINED3D_MAP_NOOVERWRITE) ++ FIXME("WINED3D_MAP_NOOVERWRITE are not implemented yet.\n"); + +- wined3d_resource_sync(resource); ++ if (!(flags & WINED3D_MAP_DISCARD) || resource->map_binding != WINED3D_LOCATION_BUFFER) ++ wined3d_resource_sync(resource); + + base_memory = wined3d_cs_emit_resource_map(device->cs, resource, flags); + if (!base_memory) +@@ -843,7 +860,7 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) + wined3d_cs_emit_resource_unmap(device->cs, resource); + + if (resource->unmap_dirtify) +- wined3d_cs_emit_resource_changed(device->cs, resource); ++ wined3d_cs_emit_resource_changed(device->cs, resource, resource->map_buffer); + resource->unmap_dirtify = FALSE; + + resource->map_count--; +@@ -851,7 +868,17 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) + return WINED3D_OK; + } + +-void wined3d_resource_changed(struct wined3d_resource *resource) ++void wined3d_resource_changed(struct wined3d_resource *resource, struct wined3d_gl_bo *swap_buffer) + { ++ struct wined3d_device *device = resource->device; ++ ++ if (swap_buffer && swap_buffer != resource->buffer) ++ { ++ struct wined3d_context *context = context_acquire(device, NULL); ++ wined3d_device_release_bo(device, resource->buffer, context); ++ context_release(context); ++ resource->buffer = swap_buffer; ++ } ++ + wined3d_resource_invalidate_location(resource, ~resource->map_binding); + } +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 374dbc2..abf3ca2 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2170,7 +2170,8 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * + void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; + BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; +-void wined3d_resource_changed(struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++void wined3d_resource_changed(struct wined3d_resource *resource, ++ struct wined3d_gl_bo *swap_buffer) DECLSPEC_HIDDEN; + BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, + const struct wined3d_box *box) DECLSPEC_HIDDEN; + void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN; +@@ -2693,7 +2694,8 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf + enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; + void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, + const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; +-void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource, ++ struct wined3d_gl_bo *swap_buffer) DECLSPEC_HIDDEN; + void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, + DWORD flags) DECLSPEC_HIDDEN; + void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0107-wined3d-Implement-DISCARD-resource-maps-with-heap-me.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0107-wined3d-Implement-DISCARD-resource-maps-with-heap-me.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0107-wined3d-Implement-DISCARD-resource-maps-with-heap-me.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0107-wined3d-Implement-DISCARD-resource-maps-with-heap-me.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,258 @@ +From 589330d01be6e2555b395b0914012248b1bff069 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 27 Sep 2013 19:24:21 +0200 +Subject: wined3d: Implement DISCARD resource maps with heap memory. + +--- + dlls/wined3d/buffer.c | 1 + + dlls/wined3d/cs.c | 6 ++++-- + dlls/wined3d/resource.c | 40 +++++++++++++++++++++++++++++++++++----- + dlls/wined3d/surface.c | 3 +++ + dlls/wined3d/volume.c | 2 ++ + dlls/wined3d/wined3d_private.h | 6 +++--- + 6 files changed, 48 insertions(+), 10 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 7187114..c9b2ae7b2 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -493,6 +493,7 @@ BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *con + + if (!wined3d_resource_allocate_sysmem(&This->resource)) + ERR("Failed to allocate system memory.\n"); ++ This->resource.heap_memory = This->resource.map_heap_memory; + + if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) + context_invalidate_state(context, STATE_INDEXBUFFER); +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index d86aa59..9307246 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -371,6 +371,7 @@ struct wined3d_cs_resource_changed + enum wined3d_cs_op opcode; + struct wined3d_resource *resource; + struct wined3d_gl_bo *swap_buffer; ++ void *swap_heap_memory; + }; + + struct wined3d_cs_skip +@@ -1817,13 +1818,13 @@ static UINT wined3d_cs_exec_resource_changed(struct wined3d_cs *cs, const void * + const struct wined3d_cs_resource_changed *op = data; + struct wined3d_resource *resource = op->resource; + +- wined3d_resource_changed(resource, op->swap_buffer); ++ wined3d_resource_changed(resource, op->swap_buffer, op->swap_heap_memory); + + return sizeof(*op); + } + + void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource, +- struct wined3d_gl_bo *swap_buffer) ++ struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) + { + struct wined3d_cs_resource_changed *op; + +@@ -1831,6 +1832,7 @@ void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_reso + op->opcode = WINED3D_CS_OP_RESOURCE_CHANGED; + op->resource = resource; + op->swap_buffer = swap_buffer; ++ op->swap_heap_memory = swap_heap_memory; + + cs->ops->submit(cs, sizeof(*op)); + } +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 69dd95a..b7aa587 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -119,6 +119,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * + ERR("Failed to allocate system memory.\n"); + return E_OUTOFMEMORY; + } ++ resource->heap_memory = resource->map_heap_memory; + } + else + { +@@ -172,6 +173,7 @@ void resource_cleanup(struct wined3d_resource *resource) + wined3d_resource_free_bo(resource); + + wined3d_resource_free_sysmem(resource); ++ resource->map_heap_memory = NULL; + + device_resource_released(resource->device, resource); + } +@@ -246,7 +248,7 @@ BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) + p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; + *p = mem; + +- resource->heap_memory = ++p; ++ resource->map_heap_memory = ++p; + + return TRUE; + } +@@ -559,7 +561,7 @@ BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, + return ptr; + + case WINED3D_LOCATION_SYSMEM: +- return resource->heap_memory; ++ return resource->map_heap_memory; + + case WINED3D_LOCATION_DIB: + return resource->bitmap_data; +@@ -621,6 +623,7 @@ BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) + ERR("Failed to allocate system memory.\n"); + return FALSE; + } ++ resource->heap_memory = resource->map_heap_memory; + return TRUE; + } + +@@ -705,6 +708,10 @@ void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD fla + GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); + break; + ++ case WINED3D_LOCATION_SYSMEM: ++ wined3d_resource_allocate_sysmem(resource); ++ break; ++ + default: + if (resource->access_fence) + ERR("Location %s does not support DISCARD maps.\n", +@@ -773,7 +780,21 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, + if (flags & WINED3D_MAP_NOOVERWRITE) + FIXME("WINED3D_MAP_NOOVERWRITE are not implemented yet.\n"); + +- if (!(flags & WINED3D_MAP_DISCARD) || resource->map_binding != WINED3D_LOCATION_BUFFER) ++ if (flags & WINED3D_MAP_DISCARD) ++ { ++ switch (resource->map_binding) ++ { ++ case WINED3D_LOCATION_BUFFER: ++ case WINED3D_LOCATION_SYSMEM: ++ break; ++ ++ default: ++ FIXME("Implement discard maps with %s map binding.\n", ++ wined3d_debug_location(resource->map_binding)); ++ wined3d_resource_sync(resource); ++ } ++ } ++ else + wined3d_resource_sync(resource); + + base_memory = wined3d_cs_emit_resource_map(device->cs, resource, flags); +@@ -860,7 +881,10 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) + wined3d_cs_emit_resource_unmap(device->cs, resource); + + if (resource->unmap_dirtify) +- wined3d_cs_emit_resource_changed(device->cs, resource, resource->map_buffer); ++ { ++ wined3d_cs_emit_resource_changed(device->cs, resource, ++ resource->map_buffer, resource->map_heap_memory); ++ } + resource->unmap_dirtify = FALSE; + + resource->map_count--; +@@ -868,7 +892,8 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) + return WINED3D_OK; + } + +-void wined3d_resource_changed(struct wined3d_resource *resource, struct wined3d_gl_bo *swap_buffer) ++void wined3d_resource_changed(struct wined3d_resource *resource, struct wined3d_gl_bo *swap_buffer, ++ void *swap_heap_memory) + { + struct wined3d_device *device = resource->device; + +@@ -879,6 +904,11 @@ void wined3d_resource_changed(struct wined3d_resource *resource, struct wined3d_ + context_release(context); + resource->buffer = swap_buffer; + } ++ if (swap_heap_memory && swap_heap_memory != resource->heap_memory) ++ { ++ wined3d_resource_free_sysmem(resource); ++ resource->heap_memory = swap_heap_memory; ++ } + + wined3d_resource_invalidate_location(resource, ~resource->map_binding); + } +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 90fa582..f56bb6b 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -487,6 +487,7 @@ static void surface_evict_sysmem(struct wined3d_surface *surface) + return; + + wined3d_resource_free_sysmem(&surface->resource); ++ surface->resource.map_heap_memory = NULL; + wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); + } + +@@ -1997,6 +1998,7 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, + + surface->resource.locations = 0; + wined3d_resource_free_sysmem(&surface->resource); ++ surface->resource.map_heap_memory = NULL; + + width = texture_resource->width; + height = texture_resource->height; +@@ -5489,6 +5491,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text + if (surface->resource.map_binding == WINED3D_LOCATION_DIB) + { + wined3d_resource_free_sysmem(&surface->resource); ++ surface->resource.map_heap_memory = NULL; + wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_DIB); + wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); + } +diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c +index 28985a4..d253a17 100644 +--- a/dlls/wined3d/volume.c ++++ b/dlls/wined3d/volume.c +@@ -134,6 +134,7 @@ static void wined3d_volume_download_data(struct wined3d_volume *volume, + static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume) + { + wined3d_resource_free_sysmem(&volume->resource); ++ volume->resource.map_heap_memory = NULL; + wined3d_resource_invalidate_location(&volume->resource, WINED3D_LOCATION_SYSMEM); + } + +@@ -516,6 +517,7 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture + { + wined3d_resource_free_sysmem(&volume->resource); + volume->resource.map_binding = WINED3D_LOCATION_BUFFER; ++ volume->resource.map_heap_memory = NULL; + } + + volume->container = container; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index abf3ca2..ac4aeb3 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2137,7 +2137,7 @@ struct wined3d_resource + UINT depth; + UINT size; + DWORD priority; +- void *heap_memory, *user_memory, *bitmap_data; ++ void *heap_memory, *map_heap_memory, *user_memory, *bitmap_data; + UINT custom_row_pitch, custom_slice_pitch; + struct wined3d_gl_bo *buffer, *map_buffer; + struct list resource_list_entry; +@@ -2171,7 +2171,7 @@ void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; + BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_changed(struct wined3d_resource *resource, +- struct wined3d_gl_bo *swap_buffer) DECLSPEC_HIDDEN; ++ struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) DECLSPEC_HIDDEN; + BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, + const struct wined3d_box *box) DECLSPEC_HIDDEN; + void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN; +@@ -2695,7 +2695,7 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf + void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, + const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; + void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource, +- struct wined3d_gl_bo *swap_buffer) DECLSPEC_HIDDEN; ++ struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) DECLSPEC_HIDDEN; + void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, + DWORD flags) DECLSPEC_HIDDEN; + void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0107-wined3d-Wrap-GL-BOs-in-a-structure.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0107-wined3d-Wrap-GL-BOs-in-a-structure.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0107-wined3d-Wrap-GL-BOs-in-a-structure.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0107-wined3d-Wrap-GL-BOs-in-a-structure.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,269 +0,0 @@ -From 08092b494b98ca7ca22998b5afb4adcd6172a0fc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 30 Aug 2013 17:00:35 +0200 -Subject: wined3d: Wrap GL BOs in a structure - -The idea is to use those structures for mapping through the command stream and caching -them for DISCARD maps. ---- - dlls/wined3d/device.c | 53 ++++++++++++++++++++++++++++++++++++++++++ - dlls/wined3d/resource.c | 34 +++++++++++---------------- - dlls/wined3d/surface.c | 6 ++--- - dlls/wined3d/volume.c | 6 ++--- - dlls/wined3d/wined3d_private.h | 15 +++++++++++- - 5 files changed, 86 insertions(+), 28 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index eb0c0ba..d0fcba2 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -5139,3 +5139,56 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL - else - return CallWindowProcA(proc, window, message, wparam, lparam); - } -+ -+/* Context activation is done by the caller */ -+struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage, -+ GLenum type_hint, struct wined3d_context *context) -+{ -+ struct wined3d_gl_bo *ret; -+ const struct wined3d_gl_info *gl_info; -+ -+ TRACE("device %p, size %u, gl_usage %u, type_hint %u\n", device, size, gl_usage, -+ type_hint); -+ -+ ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)); -+ if(!ret) -+ return NULL; -+ ret->type_hint = type_hint; -+ ret->size = size; -+ ret->usage = gl_usage; -+ -+ gl_info = context->gl_info; -+ -+ GL_EXTCALL(glGenBuffers(1, &ret->name)); -+ if (type_hint == GL_ELEMENT_ARRAY_BUFFER) -+ context_invalidate_state(context, STATE_INDEXBUFFER); -+ GL_EXTCALL(glBindBuffer(type_hint, ret->name)); -+ GL_EXTCALL(glBufferData(type_hint, size, NULL, gl_usage)); -+ GL_EXTCALL(glBindBuffer(type_hint, 0)); -+ checkGLcall("Create buffer object"); -+ -+ TRACE("Successfully created and set up buffer %u\n", ret->name); -+ return ret; -+} -+ -+/* Context activation is done by the caller */ -+static void wined3d_device_destroy_bo(struct wined3d_device *device, const struct wined3d_context *context, -+ struct wined3d_gl_bo *bo) -+{ -+ const struct wined3d_gl_info *gl_info = context->gl_info; -+ TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name); -+ -+ GL_EXTCALL(glDeleteBuffers(1, &bo->name)); -+ checkGLcall("glDeleteBuffers"); -+ -+ HeapFree(GetProcessHeap(), 0, bo); -+} -+ -+/* Context activation is done by the caller */ -+void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, -+ const struct wined3d_context *context) -+{ -+ TRACE("device %p, bo %p, GL bo %u\n", device, bo, bo->name); -+ -+ wined3d_device_destroy_bo(device, context, bo); -+} -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 49ef6b9..37a2644 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -226,12 +226,10 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * - void wined3d_resource_free_bo(struct wined3d_resource *resource) - { - struct wined3d_context *context = context_acquire(resource->device, NULL); -- const struct wined3d_gl_info *gl_info = context->gl_info; - -- TRACE("Deleting GL buffer %u belonging to resource %p.\n", resource->buffer_object, resource); -- GL_EXTCALL(glDeleteBuffers(1, &resource->buffer_object)); -- checkGLcall("glDeleteBuffers"); -- resource->buffer_object = 0; -+ wined3d_device_release_bo(resource->device, resource->buffer, context); -+ resource->buffer = NULL; -+ - context_release(context); - } - -@@ -247,7 +245,7 @@ void resource_cleanup(struct wined3d_resource *resource) - adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size); - } - -- if (resource->buffer_object) -+ if (resource->buffer) - wined3d_resource_free_bo(resource); - - wined3d_resource_free_sysmem(resource); -@@ -260,7 +258,7 @@ void resource_unload(struct wined3d_resource *resource) - if (resource->map_count) - ERR("Resource %p is being unloaded while mapped.\n", resource); - -- if (resource->buffer_object) -+ if (resource->buffer) - wined3d_resource_free_bo(resource); - - context_resource_unloaded(resource->device, -@@ -511,7 +509,7 @@ void wined3d_resource_get_memory(const struct wined3d_resource *resource, - { - if (location & WINED3D_LOCATION_BUFFER) - { -- data->buffer_object = resource->buffer_object; -+ data->buffer_object = resource->buffer->name; - data->addr = NULL; - return; - } -@@ -620,7 +618,7 @@ BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, - { - case WINED3D_LOCATION_BUFFER: - gl_info = context->gl_info; -- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer_object)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer->name)); - - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) - { -@@ -663,7 +661,7 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, - { - case WINED3D_LOCATION_BUFFER: - gl_info = context->gl_info; -- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer_object)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer->name)); - GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Unmap GL buffer"); -@@ -681,20 +679,14 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, - } - - /* Context activation is done by the caller. */ --static void wined3d_resource_prepare_bo(struct wined3d_resource *resource, const struct wined3d_context *context) -+static void wined3d_resource_prepare_bo(struct wined3d_resource *resource, struct wined3d_context *context) - { -- const struct wined3d_gl_info *gl_info = context->gl_info; -- -- if (resource->buffer_object) -+ if (resource->buffer) - return; - -- GL_EXTCALL(glGenBuffers(1, &resource->buffer_object)); -- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer_object)); -- GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, resource->size, NULL, GL_STREAM_DRAW)); -- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); -- checkGLcall("Create GL buffer"); -- -- TRACE("Created GL buffer %u for resource %p.\n", resource->buffer_object, resource); -+ resource->buffer = wined3d_device_get_bo(resource->device, resource->size, -+ GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); -+ TRACE("Created GL buffer %u for resource %p.\n", resource->buffer->name, resource); - } - - BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 025e85e1..fc1fc45 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -48,7 +48,7 @@ static void surface_cleanup(struct wined3d_surface *surface) - surface->resource.device->cs->ops->finish(surface->resource.device->cs); - } - -- if (surface->resource.buffer_object || surface->rb_multisample -+ if (surface->resource.buffer || surface->rb_multisample - || surface->rb_resolved || !list_empty(&surface->renderbuffers)) - { - struct wined3d_renderbuffer_entry *entry, *entry2; -@@ -2586,7 +2586,7 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) - } - if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY - || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM -- || surface->resource.buffer_object)) -+ || surface->resource.buffer)) - surface->resource.map_binding = WINED3D_LOCATION_DIB; - } - -@@ -3905,7 +3905,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, - /* Don't use PBOs for converted surfaces. During PBO conversion we look at - * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is - * getting called. */ -- if ((format.convert || conversion) && surface->resource.buffer_object) -+ if ((format.convert || conversion) && surface->resource.buffer) - { - TRACE("Removing the pbo attached to surface %p.\n", surface); - -diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index b79f44e..ea9a047 100644 ---- a/dlls/wined3d/volume.c -+++ b/dlls/wined3d/volume.c -@@ -218,7 +218,7 @@ static void wined3d_volume_load_location(struct wined3d_resource *resource, - } - else if (volume->resource.locations & WINED3D_LOCATION_BUFFER) - { -- struct wined3d_const_bo_address data = {volume->resource.buffer_object, NULL}; -+ struct wined3d_const_bo_address data = {volume->resource.buffer->name, NULL}; - wined3d_texture_bind_and_dirtify(volume->container, context, - location == WINED3D_LOCATION_TEXTURE_SRGB); - wined3d_volume_upload_data(volume, context, &data); -@@ -269,12 +269,12 @@ static void wined3d_volume_load_location(struct wined3d_resource *resource, - break; - - case WINED3D_LOCATION_BUFFER: -- if (!volume->resource.buffer_object) -+ if (!volume->resource.buffer) - ERR("Trying to load WINED3D_LOCATION_BUFFER without setting it up first.\n"); - - if (volume->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { -- struct wined3d_bo_address data = {volume->resource.buffer_object, NULL}; -+ struct wined3d_bo_address data = {volume->resource.buffer->name, NULL}; - - if (volume->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) - wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 8a25420..9eb038e 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2048,6 +2048,14 @@ struct wined3d_state - DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; - }; - -+struct wined3d_gl_bo -+{ -+ GLuint name; -+ GLenum usage; -+ GLenum type_hint; -+ UINT size; -+}; -+ - #define WINED3D_UNMAPPED_STAGE ~0U - - /* Multithreaded flag. Removed from the public header to signal that -@@ -2154,6 +2162,11 @@ void device_invalidate_state(const struct wined3d_device *device, DWORD state) D - void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) DECLSPEC_HIDDEN; - void device_exec_update_texture(struct wined3d_context *context, struct wined3d_texture *src_texture, - struct wined3d_texture *dst_texture) DECLSPEC_HIDDEN; -+struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage, -+ GLenum type_hint, struct wined3d_context *context) DECLSPEC_HIDDEN; -+void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, -+ const struct wined3d_context *context) DECLSPEC_HIDDEN; -+ - - static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) - { -@@ -2199,7 +2212,7 @@ struct wined3d_resource - DWORD priority; - void *heap_memory, *user_memory, *bitmap_data; - UINT custom_row_pitch, custom_slice_pitch; -- GLuint buffer_object; -+ struct wined3d_gl_bo *buffer; - struct list resource_list_entry; - DWORD locations; - LONG access_fence; --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0108-wined3d-Separate-resource-map-and-draw-buffers.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0108-wined3d-Separate-resource-map-and-draw-buffers.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0108-wined3d-Separate-resource-map-and-draw-buffers.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0108-wined3d-Separate-resource-map-and-draw-buffers.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -From 93fe426cbd0d2b61997d59fbbd1e49b2615f8c0c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 30 Aug 2013 17:06:29 +0200 -Subject: wined3d: Separate resource map and draw buffers - ---- - dlls/wined3d/resource.c | 9 +++++++-- - dlls/wined3d/wined3d_private.h | 2 +- - 2 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 8fb95a1..39555ef 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -146,8 +146,12 @@ void wined3d_resource_free_bo(struct wined3d_resource *resource) - { - struct wined3d_context *context = context_acquire(resource->device, NULL); - -+ if (resource->buffer != resource->map_buffer) -+ ERR("Releasing resource buffer with buffer != map_buffer.\n"); -+ - wined3d_device_release_bo(resource->device, resource->buffer, context); - resource->buffer = NULL; -+ resource->map_buffer = NULL; - - context_release(context); - } -@@ -535,7 +539,7 @@ BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, - { - case WINED3D_LOCATION_BUFFER: - gl_info = context->gl_info; -- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer->name)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->map_buffer->name)); - - if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) - { -@@ -578,7 +582,7 @@ void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, - { - case WINED3D_LOCATION_BUFFER: - gl_info = context->gl_info; -- GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->buffer->name)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->map_buffer->name)); - GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); - GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); - checkGLcall("Unmap GL buffer"); -@@ -603,6 +607,7 @@ static void wined3d_resource_prepare_bo(struct wined3d_resource *resource, struc - - resource->buffer = wined3d_device_get_bo(resource->device, resource->size, - GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); -+ resource->map_buffer = resource->buffer; - TRACE("Created GL buffer %u for resource %p.\n", resource->buffer->name, resource); - } - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index ff64215..374dbc2 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2139,7 +2139,7 @@ struct wined3d_resource - DWORD priority; - void *heap_memory, *user_memory, *bitmap_data; - UINT custom_row_pitch, custom_slice_pitch; -- struct wined3d_gl_bo *buffer; -+ struct wined3d_gl_bo *buffer, *map_buffer; - struct list resource_list_entry; - DWORD locations; - LONG access_fence; --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0108-wined3d-Unset-some-objects-in-state_init_default.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0108-wined3d-Unset-some-objects-in-state_init_default.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0108-wined3d-Unset-some-objects-in-state_init_default.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0108-wined3d-Unset-some-objects-in-state_init_default.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,34 @@ +From 09ff7fca62f88791ece6e95f287579687418ba24 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 1 Oct 2013 21:30:07 +0200 +Subject: wined3d: Unset some objects in state_init_default. + +FIXME: Many more are needed. +FIXME2: Is this still needed? +--- + dlls/wined3d/stateblock.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c +index 606134c..690bcc7 100644 +--- a/dlls/wined3d/stateblock.c ++++ b/dlls/wined3d/stateblock.c +@@ -1339,7 +1339,15 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d + state->sampler_states[i][WINED3D_SAMP_ELEMENT_INDEX] = 0; + /* TODO: Vertex offset in the presampled displacement map. */ + state->sampler_states[i][WINED3D_SAMP_DMAP_OFFSET] = 0; ++ state->textures[i] = NULL; + } ++ ++ state->index_buffer = NULL; ++ for (i = 0; i < sizeof(state->streams) / sizeof(*state->streams); i++) ++ memset(&state->streams[i], 0, sizeof(state->streams[i])); ++ ++ state->shader[WINED3D_SHADER_TYPE_VERTEX] = NULL; ++ state->shader[WINED3D_SHADER_TYPE_PIXEL] = NULL; + } + + HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl_info, +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0109-wined3d-Don-t-request-the-frontbuffer-to-create-dumm.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0109-wined3d-Don-t-request-the-frontbuffer-to-create-dumm.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0109-wined3d-Don-t-request-the-frontbuffer-to-create-dumm.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0109-wined3d-Don-t-request-the-frontbuffer-to-create-dumm.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,26 @@ +From c7d9b4666e695ab3c3c3589337108d221665152c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 2 Oct 2013 12:36:02 +0200 +Subject: wined3d: Don't request the frontbuffer to create dummy textures. + +--- + dlls/wined3d/device.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index ea125c2..0977e12 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -991,8 +991,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, + device->swapchains[0] = swapchain; + device_init_swapchain_state(device, swapchain); + +- context = context_acquire(device, +- surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0))); ++ context = context_acquire(device, NULL); + + create_dummy_textures(device, context); + create_default_sampler(device); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0109-wined3d-Implement-DISCARD-resource-maps-with-buffers.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0109-wined3d-Implement-DISCARD-resource-maps-with-buffers.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0109-wined3d-Implement-DISCARD-resource-maps-with-buffers.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0109-wined3d-Implement-DISCARD-resource-maps-with-buffers.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,150 +0,0 @@ -From eb880bc806a44d2d2d09df19a43fd1a5f7d8ecf1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 27 Sep 2013 19:06:41 +0200 -Subject: wined3d: Implement DISCARD resource maps with buffers. - ---- - dlls/wined3d/cs.c | 7 +++++-- - dlls/wined3d/resource.c | 41 ++++++++++++++++++++++++++++++++++------- - dlls/wined3d/wined3d_private.h | 6 ++++-- - 3 files changed, 43 insertions(+), 11 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index f5c10dd..d86aa59 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -370,6 +370,7 @@ struct wined3d_cs_resource_changed - { - enum wined3d_cs_op opcode; - struct wined3d_resource *resource; -+ struct wined3d_gl_bo *swap_buffer; - }; - - struct wined3d_cs_skip -@@ -1816,18 +1817,20 @@ static UINT wined3d_cs_exec_resource_changed(struct wined3d_cs *cs, const void * - const struct wined3d_cs_resource_changed *op = data; - struct wined3d_resource *resource = op->resource; - -- wined3d_resource_changed(resource); -+ wined3d_resource_changed(resource, op->swap_buffer); - - return sizeof(*op); - } - --void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource) -+void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource, -+ struct wined3d_gl_bo *swap_buffer) - { - struct wined3d_cs_resource_changed *op; - - op = cs->ops->require_space(cs, sizeof(*op)); - op->opcode = WINED3D_CS_OP_RESOURCE_CHANGED; - op->resource = resource; -+ op->swap_buffer = swap_buffer; - - cs->ops->submit(cs, sizeof(*op)); - } -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 39555ef..69dd95a 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -697,9 +697,27 @@ void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD fla - } - - if (flags & WINED3D_MAP_DISCARD) -+ { -+ switch (resource->map_binding) -+ { -+ case WINED3D_LOCATION_BUFFER: -+ resource->map_buffer = wined3d_device_get_bo(device, resource->size, -+ GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); -+ break; -+ -+ default: -+ if (resource->access_fence) -+ ERR("Location %s does not support DISCARD maps.\n", -+ wined3d_debug_location(resource->map_binding)); -+ if (resource->pool != WINED3D_POOL_DEFAULT) -+ FIXME("Discard used on %s pool resource.\n", debug_d3dpool(resource->pool)); -+ } - wined3d_resource_validate_location(resource, resource->map_binding); -+ } - else -+ { - wined3d_resource_load_location(resource, context, resource->map_binding); -+ } - - mem = wined3d_resource_get_map_ptr(resource, context, flags); - -@@ -752,12 +770,11 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, - - flags = wined3d_resource_sanitize_map_flags(resource, flags); - -- if (flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD)) -- { -- FIXME("Dynamic resource map is inefficient\n"); -- } -+ if (flags & WINED3D_MAP_NOOVERWRITE) -+ FIXME("WINED3D_MAP_NOOVERWRITE are not implemented yet.\n"); - -- wined3d_resource_sync(resource); -+ if (!(flags & WINED3D_MAP_DISCARD) || resource->map_binding != WINED3D_LOCATION_BUFFER) -+ wined3d_resource_sync(resource); - - base_memory = wined3d_cs_emit_resource_map(device->cs, resource, flags); - if (!base_memory) -@@ -843,7 +860,7 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) - wined3d_cs_emit_resource_unmap(device->cs, resource); - - if (resource->unmap_dirtify) -- wined3d_cs_emit_resource_changed(device->cs, resource); -+ wined3d_cs_emit_resource_changed(device->cs, resource, resource->map_buffer); - resource->unmap_dirtify = FALSE; - - resource->map_count--; -@@ -851,7 +868,17 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) - return WINED3D_OK; - } - --void wined3d_resource_changed(struct wined3d_resource *resource) -+void wined3d_resource_changed(struct wined3d_resource *resource, struct wined3d_gl_bo *swap_buffer) - { -+ struct wined3d_device *device = resource->device; -+ -+ if (swap_buffer && swap_buffer != resource->buffer) -+ { -+ struct wined3d_context *context = context_acquire(device, NULL); -+ wined3d_device_release_bo(device, resource->buffer, context); -+ context_release(context); -+ resource->buffer = swap_buffer; -+ } -+ - wined3d_resource_invalidate_location(resource, ~resource->map_binding); - } -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 374dbc2..abf3ca2 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2170,7 +2170,8 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * - void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; - BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; --void wined3d_resource_changed(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+void wined3d_resource_changed(struct wined3d_resource *resource, -+ struct wined3d_gl_bo *swap_buffer) DECLSPEC_HIDDEN; - BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, - const struct wined3d_box *box) DECLSPEC_HIDDEN; - void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -@@ -2693,7 +2694,8 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf - enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; - void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, - const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; --void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource, -+ struct wined3d_gl_bo *swap_buffer) DECLSPEC_HIDDEN; - void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, - DWORD flags) DECLSPEC_HIDDEN; - void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0110-wined3d-Implement-DISCARD-resource-maps-with-heap-me.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0110-wined3d-Implement-DISCARD-resource-maps-with-heap-me.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0110-wined3d-Implement-DISCARD-resource-maps-with-heap-me.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0110-wined3d-Implement-DISCARD-resource-maps-with-heap-me.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,258 +0,0 @@ -From 589330d01be6e2555b395b0914012248b1bff069 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 27 Sep 2013 19:24:21 +0200 -Subject: wined3d: Implement DISCARD resource maps with heap memory. - ---- - dlls/wined3d/buffer.c | 1 + - dlls/wined3d/cs.c | 6 ++++-- - dlls/wined3d/resource.c | 40 +++++++++++++++++++++++++++++++++++----- - dlls/wined3d/surface.c | 3 +++ - dlls/wined3d/volume.c | 2 ++ - dlls/wined3d/wined3d_private.h | 6 +++--- - 6 files changed, 48 insertions(+), 10 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 7187114..c9b2ae7b2 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -493,6 +493,7 @@ BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *con - - if (!wined3d_resource_allocate_sysmem(&This->resource)) - ERR("Failed to allocate system memory.\n"); -+ This->resource.heap_memory = This->resource.map_heap_memory; - - if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) - context_invalidate_state(context, STATE_INDEXBUFFER); -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index d86aa59..9307246 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -371,6 +371,7 @@ struct wined3d_cs_resource_changed - enum wined3d_cs_op opcode; - struct wined3d_resource *resource; - struct wined3d_gl_bo *swap_buffer; -+ void *swap_heap_memory; - }; - - struct wined3d_cs_skip -@@ -1817,13 +1818,13 @@ static UINT wined3d_cs_exec_resource_changed(struct wined3d_cs *cs, const void * - const struct wined3d_cs_resource_changed *op = data; - struct wined3d_resource *resource = op->resource; - -- wined3d_resource_changed(resource, op->swap_buffer); -+ wined3d_resource_changed(resource, op->swap_buffer, op->swap_heap_memory); - - return sizeof(*op); - } - - void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource, -- struct wined3d_gl_bo *swap_buffer) -+ struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) - { - struct wined3d_cs_resource_changed *op; - -@@ -1831,6 +1832,7 @@ void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_reso - op->opcode = WINED3D_CS_OP_RESOURCE_CHANGED; - op->resource = resource; - op->swap_buffer = swap_buffer; -+ op->swap_heap_memory = swap_heap_memory; - - cs->ops->submit(cs, sizeof(*op)); - } -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 69dd95a..b7aa587 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -119,6 +119,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device * - ERR("Failed to allocate system memory.\n"); - return E_OUTOFMEMORY; - } -+ resource->heap_memory = resource->map_heap_memory; - } - else - { -@@ -172,6 +173,7 @@ void resource_cleanup(struct wined3d_resource *resource) - wined3d_resource_free_bo(resource); - - wined3d_resource_free_sysmem(resource); -+ resource->map_heap_memory = NULL; - - device_resource_released(resource->device, resource); - } -@@ -246,7 +248,7 @@ BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) - p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; - *p = mem; - -- resource->heap_memory = ++p; -+ resource->map_heap_memory = ++p; - - return TRUE; - } -@@ -559,7 +561,7 @@ BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, - return ptr; - - case WINED3D_LOCATION_SYSMEM: -- return resource->heap_memory; -+ return resource->map_heap_memory; - - case WINED3D_LOCATION_DIB: - return resource->bitmap_data; -@@ -621,6 +623,7 @@ BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) - ERR("Failed to allocate system memory.\n"); - return FALSE; - } -+ resource->heap_memory = resource->map_heap_memory; - return TRUE; - } - -@@ -705,6 +708,10 @@ void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD fla - GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); - break; - -+ case WINED3D_LOCATION_SYSMEM: -+ wined3d_resource_allocate_sysmem(resource); -+ break; -+ - default: - if (resource->access_fence) - ERR("Location %s does not support DISCARD maps.\n", -@@ -773,7 +780,21 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, - if (flags & WINED3D_MAP_NOOVERWRITE) - FIXME("WINED3D_MAP_NOOVERWRITE are not implemented yet.\n"); - -- if (!(flags & WINED3D_MAP_DISCARD) || resource->map_binding != WINED3D_LOCATION_BUFFER) -+ if (flags & WINED3D_MAP_DISCARD) -+ { -+ switch (resource->map_binding) -+ { -+ case WINED3D_LOCATION_BUFFER: -+ case WINED3D_LOCATION_SYSMEM: -+ break; -+ -+ default: -+ FIXME("Implement discard maps with %s map binding.\n", -+ wined3d_debug_location(resource->map_binding)); -+ wined3d_resource_sync(resource); -+ } -+ } -+ else - wined3d_resource_sync(resource); - - base_memory = wined3d_cs_emit_resource_map(device->cs, resource, flags); -@@ -860,7 +881,10 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) - wined3d_cs_emit_resource_unmap(device->cs, resource); - - if (resource->unmap_dirtify) -- wined3d_cs_emit_resource_changed(device->cs, resource, resource->map_buffer); -+ { -+ wined3d_cs_emit_resource_changed(device->cs, resource, -+ resource->map_buffer, resource->map_heap_memory); -+ } - resource->unmap_dirtify = FALSE; - - resource->map_count--; -@@ -868,7 +892,8 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) - return WINED3D_OK; - } - --void wined3d_resource_changed(struct wined3d_resource *resource, struct wined3d_gl_bo *swap_buffer) -+void wined3d_resource_changed(struct wined3d_resource *resource, struct wined3d_gl_bo *swap_buffer, -+ void *swap_heap_memory) - { - struct wined3d_device *device = resource->device; - -@@ -879,6 +904,11 @@ void wined3d_resource_changed(struct wined3d_resource *resource, struct wined3d_ - context_release(context); - resource->buffer = swap_buffer; - } -+ if (swap_heap_memory && swap_heap_memory != resource->heap_memory) -+ { -+ wined3d_resource_free_sysmem(resource); -+ resource->heap_memory = swap_heap_memory; -+ } - - wined3d_resource_invalidate_location(resource, ~resource->map_binding); - } -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 90fa582..f56bb6b 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -487,6 +487,7 @@ static void surface_evict_sysmem(struct wined3d_surface *surface) - return; - - wined3d_resource_free_sysmem(&surface->resource); -+ surface->resource.map_heap_memory = NULL; - wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); - } - -@@ -1997,6 +1998,7 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, - - surface->resource.locations = 0; - wined3d_resource_free_sysmem(&surface->resource); -+ surface->resource.map_heap_memory = NULL; - - width = texture_resource->width; - height = texture_resource->height; -@@ -5489,6 +5491,7 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text - if (surface->resource.map_binding == WINED3D_LOCATION_DIB) - { - wined3d_resource_free_sysmem(&surface->resource); -+ surface->resource.map_heap_memory = NULL; - wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_DIB); - wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); - } -diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index 28985a4..d253a17 100644 ---- a/dlls/wined3d/volume.c -+++ b/dlls/wined3d/volume.c -@@ -134,6 +134,7 @@ static void wined3d_volume_download_data(struct wined3d_volume *volume, - static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume) - { - wined3d_resource_free_sysmem(&volume->resource); -+ volume->resource.map_heap_memory = NULL; - wined3d_resource_invalidate_location(&volume->resource, WINED3D_LOCATION_SYSMEM); - } - -@@ -516,6 +517,7 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture - { - wined3d_resource_free_sysmem(&volume->resource); - volume->resource.map_binding = WINED3D_LOCATION_BUFFER; -+ volume->resource.map_heap_memory = NULL; - } - - volume->container = container; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index abf3ca2..ac4aeb3 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2137,7 +2137,7 @@ struct wined3d_resource - UINT depth; - UINT size; - DWORD priority; -- void *heap_memory, *user_memory, *bitmap_data; -+ void *heap_memory, *map_heap_memory, *user_memory, *bitmap_data; - UINT custom_row_pitch, custom_slice_pitch; - struct wined3d_gl_bo *buffer, *map_buffer; - struct list resource_list_entry; -@@ -2171,7 +2171,7 @@ void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; - BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_changed(struct wined3d_resource *resource, -- struct wined3d_gl_bo *swap_buffer) DECLSPEC_HIDDEN; -+ struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) DECLSPEC_HIDDEN; - BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, - const struct wined3d_box *box) DECLSPEC_HIDDEN; - void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -@@ -2695,7 +2695,7 @@ void wined3d_cs_emit_blt(struct wined3d_cs *cs, struct wined3d_surface *dst_surf - void wined3d_cs_emit_clear_rtv(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, - const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN; - void wined3d_cs_emit_resource_changed(struct wined3d_cs *cs, struct wined3d_resource *resource, -- struct wined3d_gl_bo *swap_buffer) DECLSPEC_HIDDEN; -+ struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) DECLSPEC_HIDDEN; - void *wined3d_cs_emit_resource_map(struct wined3d_cs *cs, struct wined3d_resource *resource, - DWORD flags) DECLSPEC_HIDDEN; - void wined3d_cs_emit_resource_unmap(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0110-wined3d-Use-double-buffered-buffers-for-multithreade.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0110-wined3d-Use-double-buffered-buffers-for-multithreade.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0110-wined3d-Use-double-buffered-buffers-for-multithreade.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0110-wined3d-Use-double-buffered-buffers-for-multithreade.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,26 @@ +From e54d3de255928108db07a5f3367213a24d8bf959 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Jul 2013 23:44:11 +0200 +Subject: wined3d: Use double-buffered buffers for multithreaded CS + +--- + dlls/wined3d/buffer.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 3ca1143..de0eaec 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -1254,6 +1254,9 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device + } + buffer->maps_size = 1; + ++ if (wined3d_settings.cs_multithreaded) ++ buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER; ++ + return WINED3D_OK; + } + +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0111-wined3d-Don-t-synchronize-NOOVERWRITE-buffer-maps.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0111-wined3d-Don-t-synchronize-NOOVERWRITE-buffer-maps.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0111-wined3d-Don-t-synchronize-NOOVERWRITE-buffer-maps.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0111-wined3d-Don-t-synchronize-NOOVERWRITE-buffer-maps.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,58 @@ +From 4dab2b426c1d4eb918dda550a547b33858617395 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 4 Jul 2013 23:49:26 +0200 +Subject: wined3d: Don't synchronize NOOVERWRITE buffer maps + +TODO: Put the patch that makes PreLoad ignore the mapped state here. +--- + dlls/wined3d/buffer.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index de0eaec..fd03fb5 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -958,13 +958,6 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + + TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags); + +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- wined3d_cs_emit_glfinish(device->cs); +- device->cs->ops->finish(device->cs); +- } +- + flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags); + /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001 multitexture + * fill rate test seems to depend on this. When we map a buffer with +@@ -995,6 +988,13 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + ++ if (wined3d_settings.cs_multithreaded) ++ { ++ FIXME("waiting for cs\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); ++ } ++ + context = context_acquire(device, NULL); + gl_info = context->gl_info; + +@@ -1056,6 +1056,12 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + buffer->flags |= WINED3D_BUFFER_SYNC; + } + ++ if (!(flags & WINED3D_MAP_NOOVERWRITE) && wined3d_settings.cs_multithreaded) ++ { ++ FIXME("waiting for cs.\n"); ++ device->cs->ops->finish(device->cs); ++ } ++ + base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.heap_memory; + *data = base + offset; + +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0111-wined3d-Unset-some-objects-in-state_init_default.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0111-wined3d-Unset-some-objects-in-state_init_default.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0111-wined3d-Unset-some-objects-in-state_init_default.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0111-wined3d-Unset-some-objects-in-state_init_default.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -From 09ff7fca62f88791ece6e95f287579687418ba24 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 1 Oct 2013 21:30:07 +0200 -Subject: wined3d: Unset some objects in state_init_default. - -FIXME: Many more are needed. -FIXME2: Is this still needed? ---- - dlls/wined3d/stateblock.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c -index 606134c..690bcc7 100644 ---- a/dlls/wined3d/stateblock.c -+++ b/dlls/wined3d/stateblock.c -@@ -1339,7 +1339,15 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d - state->sampler_states[i][WINED3D_SAMP_ELEMENT_INDEX] = 0; - /* TODO: Vertex offset in the presampled displacement map. */ - state->sampler_states[i][WINED3D_SAMP_DMAP_OFFSET] = 0; -+ state->textures[i] = NULL; - } -+ -+ state->index_buffer = NULL; -+ for (i = 0; i < sizeof(state->streams) / sizeof(*state->streams); i++) -+ memset(&state->streams[i], 0, sizeof(state->streams[i])); -+ -+ state->shader[WINED3D_SHADER_TYPE_VERTEX] = NULL; -+ state->shader[WINED3D_SHADER_TYPE_PIXEL] = NULL; - } - - HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl_info, --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0112-wined3d-Don-t-request-the-frontbuffer-to-create-dumm.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0112-wined3d-Don-t-request-the-frontbuffer-to-create-dumm.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0112-wined3d-Don-t-request-the-frontbuffer-to-create-dumm.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0112-wined3d-Don-t-request-the-frontbuffer-to-create-dumm.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -From 55240026af497ef2d4e3d8edc456e65b989bf59e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 2 Oct 2013 12:36:02 +0200 -Subject: wined3d: Don't request the frontbuffer to create dummy textures. - ---- - dlls/wined3d/device.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 6f82385..f5cb7bd 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -905,8 +905,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, - device->swapchains[0] = swapchain; - device_init_swapchain_state(device, swapchain); - -- context = context_acquire(device, -- surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0))); -+ context = context_acquire(device, NULL); - - create_dummy_textures(device, context); - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0112-wined3d-Separate-buffer-map-write-and-draw-read-memo.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0112-wined3d-Separate-buffer-map-write-and-draw-read-memo.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0112-wined3d-Separate-buffer-map-write-and-draw-read-memo.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0112-wined3d-Separate-buffer-map-write-and-draw-read-memo.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,47 @@ +From eaad769483668455de518d4bea0013ddef6d5f6a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 15:59:11 +0200 +Subject: wined3d: Separate buffer map write and draw read memory pointers + +TODO: Think about making this generic for all resources. +TODO 2: This is rather pointless on its own, merge this with the +patch that introduces this for all resources. +--- + dlls/wined3d/buffer.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index fd03fb5..2a814c6 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -191,7 +191,10 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine + if (This->flags & WINED3D_BUFFER_DOUBLEBUFFER) + buffer_invalidate_bo_range(This, 0, 0); + else ++ { + wined3d_resource_free_sysmem(&This->resource); ++ This->resource.map_heap_memory = NULL; ++ } + + return; + +@@ -1044,7 +1047,6 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + buffer_get_sysmem(buffer, context); + } + TRACE("New pointer is %p.\n", buffer->resource.heap_memory); +- buffer->map_ptr = NULL; + } + context_release(context); + } +@@ -1062,7 +1064,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + device->cs->ops->finish(device->cs); + } + +- base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.heap_memory; ++ base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.map_heap_memory; + *data = base + offset; + + TRACE("Returning memory at %p (base %p, offset %u).\n", *data, base, offset); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0113-wined3d-Accelerate-DISCARD-buffer-maps.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0113-wined3d-Accelerate-DISCARD-buffer-maps.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0113-wined3d-Accelerate-DISCARD-buffer-maps.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0113-wined3d-Accelerate-DISCARD-buffer-maps.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,139 @@ +From 46ed74a72057957b7046b45b4cdfb4b34ad4016e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 16:14:16 +0200 +Subject: wined3d: Accelerate DISCARD buffer maps + +TODO: Make this generic for all resources. +TODO2: Merge this with the patch that controlls BUFFER_DISCARD in the CS thread +TODO3: Clean up the map_mem allocation mess. +--- + dlls/wined3d/buffer.c | 15 ++++++++++++--- + dlls/wined3d/cs.c | 39 ++++++++++++++++++++++++++++++++++++++- + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 52 insertions(+), 4 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 2a814c6..5c6d36e 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -1058,10 +1058,19 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + buffer->flags |= WINED3D_BUFFER_SYNC; + } + +- if (!(flags & WINED3D_MAP_NOOVERWRITE) && wined3d_settings.cs_multithreaded) ++ if (wined3d_settings.cs_multithreaded && count == 1) + { +- FIXME("waiting for cs.\n"); +- device->cs->ops->finish(device->cs); ++ BOOL swvp = device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING; ++ if (flags & WINED3D_MAP_DISCARD && !swvp) ++ { ++ wined3d_resource_allocate_sysmem(&buffer->resource); ++ wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); ++ } ++ else if(!(flags & WINED3D_MAP_NOOVERWRITE)) ++ { ++ FIXME("waiting for cs.\n"); ++ device->cs->ops->finish(device->cs); ++ } + } + + base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.map_heap_memory; +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 9307246..341b51c 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -68,6 +68,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_RESOURCE_CHANGED, + WINED3D_CS_OP_RESOURCE_MAP, + WINED3D_CS_OP_RESOURCE_UNMAP, ++ WINED3D_CS_OP_BUFFER_SWAP_MEM, + WINED3D_CS_OP_QUERY_ISSUE, + WINED3D_CS_OP_QUERY_DESTROY, + WINED3D_CS_OP_UPDATE_SURFACE, +@@ -374,6 +375,13 @@ struct wined3d_cs_resource_changed + void *swap_heap_memory; + }; + ++struct wined3d_cs_buffer_swap_mem ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_buffer *buffer; ++ BYTE *mem; ++}; ++ + struct wined3d_cs_skip + { + enum wined3d_cs_op opcode; +@@ -2123,6 +2131,34 @@ void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resour + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_buffer_swap_mem(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_buffer_swap_mem *op = data; ++ struct wined3d_buffer *buffer = op->buffer; ++ ++ wined3d_resource_free_sysmem(&buffer->resource); ++ buffer->resource.heap_memory = op->mem; ++ ++ if (!buffer->buffer_object && buffer->resource.bind_count) ++ { ++ device_invalidate_state(cs->device, STATE_STREAMSRC); ++ device_invalidate_state(cs->device, STATE_INDEXBUFFER); ++ } ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffer *buffer, BYTE *mem) ++{ ++ struct wined3d_cs_buffer_swap_mem *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_BUFFER_SWAP_MEM; ++ op->buffer = buffer; ++ op->mem = mem; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2143,11 +2179,11 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, + /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, + /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, ++ /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, + /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, + /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, + /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, + /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, +- /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, + /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, + /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, + /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, +@@ -2169,6 +2205,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_RESOURCE_CHANGED */ wined3d_cs_exec_resource_changed, + /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, + /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, ++ /* WINED3D_CS_OP_BUFFER_SWAP_MEM */ wined3d_cs_exec_buffer_swap_mem, + /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, + /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, + /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 270162f..7d12df9 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2694,6 +2694,8 @@ void wined3d_cs_emit_surface_preload(struct wined3d_cs *cs, struct wined3d_surfa + void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_texture *src, + struct wined3d_texture *dst) DECLSPEC_HIDDEN; + void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffer *buffer, ++ BYTE *mem) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0113-wined3d-Use-double-buffered-buffers-for-multithreade.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0113-wined3d-Use-double-buffered-buffers-for-multithreade.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0113-wined3d-Use-double-buffered-buffers-for-multithreade.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0113-wined3d-Use-double-buffered-buffers-for-multithreade.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -From e54d3de255928108db07a5f3367213a24d8bf959 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Jul 2013 23:44:11 +0200 -Subject: wined3d: Use double-buffered buffers for multithreaded CS - ---- - dlls/wined3d/buffer.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 3ca1143..de0eaec 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -1254,6 +1254,9 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device - } - buffer->maps_size = 1; - -+ if (wined3d_settings.cs_multithreaded) -+ buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER; -+ - return WINED3D_OK; - } - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0114-wined3d-Accelerate-READONLY-buffer-maps.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0114-wined3d-Accelerate-READONLY-buffer-maps.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0114-wined3d-Accelerate-READONLY-buffer-maps.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0114-wined3d-Accelerate-READONLY-buffer-maps.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,29 @@ +From 14090e86e52e7fcc475ae83c3a25039a313a6d32 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 16:44:35 +0200 +Subject: wined3d: Accelerate READONLY buffer maps + +FIXME: ProcessVertices can write to buffers +--- + dlls/wined3d/buffer.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 5c6d36e..f4c0d07 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -1066,9 +1066,9 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + wined3d_resource_allocate_sysmem(&buffer->resource); + wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); + } +- else if(!(flags & WINED3D_MAP_NOOVERWRITE)) ++ else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY))) + { +- FIXME("waiting for cs.\n"); ++ FIXME("waiting for cs, flags 0x%04x.\n", flags); + device->cs->ops->finish(device->cs); + } + } +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0114-wined3d-Don-t-synchronize-NOOVERWRITE-buffer-maps.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0114-wined3d-Don-t-synchronize-NOOVERWRITE-buffer-maps.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0114-wined3d-Don-t-synchronize-NOOVERWRITE-buffer-maps.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0114-wined3d-Don-t-synchronize-NOOVERWRITE-buffer-maps.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -From 4dab2b426c1d4eb918dda550a547b33858617395 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 4 Jul 2013 23:49:26 +0200 -Subject: wined3d: Don't synchronize NOOVERWRITE buffer maps - -TODO: Put the patch that makes PreLoad ignore the mapped state here. ---- - dlls/wined3d/buffer.c | 20 +++++++++++++------- - 1 file changed, 13 insertions(+), 7 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index de0eaec..fd03fb5 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -958,13 +958,6 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - - TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags); - -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- wined3d_cs_emit_glfinish(device->cs); -- device->cs->ops->finish(device->cs); -- } -- - flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags); - /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001 multitexture - * fill rate test seems to depend on this. When we map a buffer with -@@ -995,6 +988,13 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - struct wined3d_context *context; - const struct wined3d_gl_info *gl_info; - -+ if (wined3d_settings.cs_multithreaded) -+ { -+ FIXME("waiting for cs\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); -+ } -+ - context = context_acquire(device, NULL); - gl_info = context->gl_info; - -@@ -1056,6 +1056,12 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - buffer->flags |= WINED3D_BUFFER_SYNC; - } - -+ if (!(flags & WINED3D_MAP_NOOVERWRITE) && wined3d_settings.cs_multithreaded) -+ { -+ FIXME("waiting for cs.\n"); -+ device->cs->ops->finish(device->cs); -+ } -+ - base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.heap_memory; - *data = base + offset; - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0115-wined3d-Access-the-buffer-dirty-areas-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0115-wined3d-Access-the-buffer-dirty-areas-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0115-wined3d-Access-the-buffer-dirty-areas-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0115-wined3d-Access-the-buffer-dirty-areas-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,140 @@ +From 9725eb43a6e513c68761a40b534f308c85e55086 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 17:05:12 +0200 +Subject: wined3d: Access the buffer dirty areas through the CS + +This avoids the following issues: + +1) The worker thread uploading a dirtified area before the application +unlocks the buffer and marking it clean + +2) The worker thread uploading data from the old memory and marking the +area clean although the data was written to a new block of memory. + +However, this adds more synchronization than necessary. The first +problem could be solved by moving dirtification to unmap, e.g. via a +flag in each dirty area. The second problem can be fixed by not +dirtifying in map if map_mem != resource.allocatedMemory and dirtifying +the entire buffer in buffer_swap_memory (DISCARD dirtifies the entire +buffer anyway, and this could be the reason why). + +If one of those ideas is used, access to the dirty area array needs to +be protected by locks. +--- + dlls/wined3d/buffer.c | 6 +++--- + dlls/wined3d/cs.c | 31 +++++++++++++++++++++++++++++++ + dlls/wined3d/wined3d_private.h | 3 +++ + 3 files changed, 37 insertions(+), 3 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 7d1a532..9b6ccc8 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -41,7 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); + #define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */ + #define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */ + +-static void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, UINT offset, UINT size) ++void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, UINT offset, UINT size) + { + if (!offset && !size) + goto invalidate_all; +@@ -979,9 +979,9 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + * being uploaded in that case. Two such applications are Port Royale + * and Darkstar One. */ + if (flags & WINED3D_MAP_DISCARD) +- buffer_invalidate_bo_range(buffer, 0, 0); ++ wined3d_cs_emit_buffer_invalidate_bo_range(device->cs, buffer, 0, 0); + else if (!(flags & WINED3D_MAP_READONLY)) +- buffer_invalidate_bo_range(buffer, offset, size); ++ wined3d_cs_emit_buffer_invalidate_bo_range(device->cs, buffer, offset, size); + + if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) + { +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 491ad85..bc90df2 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -70,6 +70,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_RESOURCE_MAP, + WINED3D_CS_OP_RESOURCE_UNMAP, + WINED3D_CS_OP_BUFFER_SWAP_MEM, ++ WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE, + WINED3D_CS_OP_QUERY_ISSUE, + WINED3D_CS_OP_QUERY_DESTROY, + WINED3D_CS_OP_UPDATE_SURFACE, +@@ -392,6 +393,13 @@ struct wined3d_cs_buffer_swap_mem + BYTE *mem; + }; + ++struct wined3d_cs_buffer_invalidate_bo_range ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_buffer *buffer; ++ UINT offset, size; ++}; ++ + struct wined3d_cs_skip + { + enum wined3d_cs_op opcode; +@@ -2273,6 +2281,28 @@ void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffe + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_buffer_invalidate_bo_range(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_buffer_invalidate_bo_range *op = data; ++ ++ buffer_invalidate_bo_range(op->buffer, op->offset, op->size); ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, ++ struct wined3d_buffer *buffer, UINT offset, UINT size) ++{ ++ struct wined3d_cs_buffer_invalidate_bo_range *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE; ++ op->buffer = buffer; ++ op->offset = offset; ++ op->size = size; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2321,6 +2351,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, + /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, + /* WINED3D_CS_OP_BUFFER_SWAP_MEM */ wined3d_cs_exec_buffer_swap_mem, ++ /* WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE */ wined3d_cs_exec_buffer_invalidate_bo_range, + /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, + /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, + /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index e30ae80..7d0eba9 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2813,6 +2813,8 @@ void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_textur + void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffer *buffer, + BYTE *mem) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, ++ struct wined3d_buffer *buffer, UINT offset, UINT size) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +@@ -2898,6 +2900,7 @@ void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *co + BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *context) DECLSPEC_HIDDEN; + void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, + const struct wined3d_state *state) DECLSPEC_HIDDEN; ++void buffer_invalidate_bo_range(struct wined3d_buffer *This, UINT offset, UINT size) DECLSPEC_HIDDEN; + HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, + const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN; + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0115-wined3d-Separate-buffer-map-write-and-draw-read-memo.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0115-wined3d-Separate-buffer-map-write-and-draw-read-memo.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0115-wined3d-Separate-buffer-map-write-and-draw-read-memo.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0115-wined3d-Separate-buffer-map-write-and-draw-read-memo.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -From eaad769483668455de518d4bea0013ddef6d5f6a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 15:59:11 +0200 -Subject: wined3d: Separate buffer map write and draw read memory pointers - -TODO: Think about making this generic for all resources. -TODO 2: This is rather pointless on its own, merge this with the -patch that introduces this for all resources. ---- - dlls/wined3d/buffer.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index fd03fb5..2a814c6 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -191,7 +191,10 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine - if (This->flags & WINED3D_BUFFER_DOUBLEBUFFER) - buffer_invalidate_bo_range(This, 0, 0); - else -+ { - wined3d_resource_free_sysmem(&This->resource); -+ This->resource.map_heap_memory = NULL; -+ } - - return; - -@@ -1044,7 +1047,6 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - buffer_get_sysmem(buffer, context); - } - TRACE("New pointer is %p.\n", buffer->resource.heap_memory); -- buffer->map_ptr = NULL; - } - context_release(context); - } -@@ -1062,7 +1064,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - device->cs->ops->finish(device->cs); - } - -- base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.heap_memory; -+ base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.map_heap_memory; - *data = base + offset; - - TRACE("Returning memory at %p (base %p, offset %u).\n", *data, base, offset); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0116-wined3d-Accelerate-DISCARD-buffer-maps.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0116-wined3d-Accelerate-DISCARD-buffer-maps.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0116-wined3d-Accelerate-DISCARD-buffer-maps.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0116-wined3d-Accelerate-DISCARD-buffer-maps.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,139 +0,0 @@ -From 46ed74a72057957b7046b45b4cdfb4b34ad4016e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 16:14:16 +0200 -Subject: wined3d: Accelerate DISCARD buffer maps - -TODO: Make this generic for all resources. -TODO2: Merge this with the patch that controlls BUFFER_DISCARD in the CS thread -TODO3: Clean up the map_mem allocation mess. ---- - dlls/wined3d/buffer.c | 15 ++++++++++++--- - dlls/wined3d/cs.c | 39 ++++++++++++++++++++++++++++++++++++++- - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 52 insertions(+), 4 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 2a814c6..5c6d36e 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -1058,10 +1058,19 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - buffer->flags |= WINED3D_BUFFER_SYNC; - } - -- if (!(flags & WINED3D_MAP_NOOVERWRITE) && wined3d_settings.cs_multithreaded) -+ if (wined3d_settings.cs_multithreaded && count == 1) - { -- FIXME("waiting for cs.\n"); -- device->cs->ops->finish(device->cs); -+ BOOL swvp = device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING; -+ if (flags & WINED3D_MAP_DISCARD && !swvp) -+ { -+ wined3d_resource_allocate_sysmem(&buffer->resource); -+ wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); -+ } -+ else if(!(flags & WINED3D_MAP_NOOVERWRITE)) -+ { -+ FIXME("waiting for cs.\n"); -+ device->cs->ops->finish(device->cs); -+ } - } - - base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.map_heap_memory; -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 9307246..341b51c 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -68,6 +68,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_RESOURCE_CHANGED, - WINED3D_CS_OP_RESOURCE_MAP, - WINED3D_CS_OP_RESOURCE_UNMAP, -+ WINED3D_CS_OP_BUFFER_SWAP_MEM, - WINED3D_CS_OP_QUERY_ISSUE, - WINED3D_CS_OP_QUERY_DESTROY, - WINED3D_CS_OP_UPDATE_SURFACE, -@@ -374,6 +375,13 @@ struct wined3d_cs_resource_changed - void *swap_heap_memory; - }; - -+struct wined3d_cs_buffer_swap_mem -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_buffer *buffer; -+ BYTE *mem; -+}; -+ - struct wined3d_cs_skip - { - enum wined3d_cs_op opcode; -@@ -2123,6 +2131,34 @@ void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resour - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_buffer_swap_mem(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_buffer_swap_mem *op = data; -+ struct wined3d_buffer *buffer = op->buffer; -+ -+ wined3d_resource_free_sysmem(&buffer->resource); -+ buffer->resource.heap_memory = op->mem; -+ -+ if (!buffer->buffer_object && buffer->resource.bind_count) -+ { -+ device_invalidate_state(cs->device, STATE_STREAMSRC); -+ device_invalidate_state(cs->device, STATE_INDEXBUFFER); -+ } -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffer *buffer, BYTE *mem) -+{ -+ struct wined3d_cs_buffer_swap_mem *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_BUFFER_SWAP_MEM; -+ op->buffer = buffer; -+ op->mem = mem; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2143,11 +2179,11 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, - /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, - /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, -+ /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, - /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, - /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, - /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, - /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, -- /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, - /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, - /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, - /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, -@@ -2169,6 +2205,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_RESOURCE_CHANGED */ wined3d_cs_exec_resource_changed, - /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, - /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, -+ /* WINED3D_CS_OP_BUFFER_SWAP_MEM */ wined3d_cs_exec_buffer_swap_mem, - /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, - /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, - /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 270162f..7d12df9 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2694,6 +2694,8 @@ void wined3d_cs_emit_surface_preload(struct wined3d_cs *cs, struct wined3d_surfa - void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_texture *src, - struct wined3d_texture *dst) DECLSPEC_HIDDEN; - void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffer *buffer, -+ BYTE *mem) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0116-wined3d-Ignore-buffer-resource.map_count-in-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0116-wined3d-Ignore-buffer-resource.map_count-in-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0116-wined3d-Ignore-buffer-resource.map_count-in-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0116-wined3d-Ignore-buffer-resource.map_count-in-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,58 @@ +From e7637b3b410855296289ec8ebe199b80b5a7a2b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 22:52:06 +0200 +Subject: wined3d: Ignore buffer->resource.map_count in the CS + +This fixes sporadic test failures caused by preload refusing to load +data into the GL buffer. + +It's fine to preload or create a VBO if a DISCARD or NOOVERWRITE map is +happening at the same time. A non-dynamic map will finish the CS before +incrementing map_count. +--- + dlls/wined3d/buffer.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 551cc7a..3ac45c6 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -457,7 +457,8 @@ void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *co + data->buffer_object = buffer->buffer_object; + if (!buffer->buffer_object) + { +- if ((buffer->flags & WINED3D_BUFFER_CREATEBO) && !buffer->resource.map_count) ++ if ((!buffer->resource.map_count || buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER) ++ && buffer->flags & WINED3D_BUFFER_CREATEBO) + { + buffer_create_buffer_object(buffer, context); + buffer->flags &= ~WINED3D_BUFFER_CREATEBO; +@@ -737,12 +738,6 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte + + TRACE("buffer %p.\n", buffer); + +- if (buffer->resource.map_count) +- { +- WARN("Buffer is mapped, skipping preload.\n"); +- return; +- } +- + buffer_mark_used(buffer); + + if (!buffer->buffer_object) +@@ -934,6 +929,12 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) + struct wined3d_context *context; + struct wined3d_device *device = buffer->resource.device; + ++ if (buffer->resource.map_count) ++ { ++ WARN("Buffer is mapped, skipping preload.\n"); ++ return; ++ } ++ + if (wined3d_settings.cs_multithreaded) + { + FIXME("Waiting for cs.\n"); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0117-wined3d-Accelerate-READONLY-buffer-maps.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0117-wined3d-Accelerate-READONLY-buffer-maps.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0117-wined3d-Accelerate-READONLY-buffer-maps.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0117-wined3d-Accelerate-READONLY-buffer-maps.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -From 14090e86e52e7fcc475ae83c3a25039a313a6d32 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 16:44:35 +0200 -Subject: wined3d: Accelerate READONLY buffer maps - -FIXME: ProcessVertices can write to buffers ---- - dlls/wined3d/buffer.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 5c6d36e..f4c0d07 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -1066,9 +1066,9 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - wined3d_resource_allocate_sysmem(&buffer->resource); - wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); - } -- else if(!(flags & WINED3D_MAP_NOOVERWRITE)) -+ else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY))) - { -- FIXME("waiting for cs.\n"); -+ FIXME("waiting for cs, flags 0x%04x.\n", flags); - device->cs->ops->finish(device->cs); - } - } --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0117-wined3d-Send-buffer-preloads-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0117-wined3d-Send-buffer-preloads-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0117-wined3d-Send-buffer-preloads-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0117-wined3d-Send-buffer-preloads-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,122 @@ +From f0608f8a5916eea7e342db36ffe49427e40a4b49 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sun, 7 Jul 2013 12:02:59 +0200 +Subject: wined3d: Send buffer preloads through the CS + +Think about making this a fast command. Might help if the driver +supports async data transfer, but synchronization side effects, esp. wrt +the dirty area list, have to be considered. +--- + dlls/wined3d/buffer.c | 12 +----------- + dlls/wined3d/cs.c | 31 +++++++++++++++++++++++++++++++ + dlls/wined3d/wined3d_private.h | 1 + + 3 files changed, 33 insertions(+), 11 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 3ac45c6..a09ca90 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -926,7 +926,6 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte + + void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) + { +- struct wined3d_context *context; + struct wined3d_device *device = buffer->resource.device; + + if (buffer->resource.map_count) +@@ -935,16 +934,7 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) + return; + } + +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- wined3d_cs_emit_glfinish(device->cs); +- device->cs->ops->finish(device->cs); +- } +- +- context = context_acquire(buffer->resource.device, NULL); +- buffer_internal_preload(buffer, context, NULL); +- context_release(context); ++ wined3d_cs_emit_buffer_preload(device->cs, buffer); + } + + struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer) +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 179f2e6..6b16d51 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -70,6 +70,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_RESOURCE_UNMAP, + WINED3D_CS_OP_BUFFER_SWAP_MEM, + WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE, ++ WINED3D_CS_OP_BUFFER_PRELOAD, + WINED3D_CS_OP_QUERY_ISSUE, + WINED3D_CS_OP_QUERY_DESTROY, + WINED3D_CS_OP_UPDATE_SURFACE, +@@ -442,6 +443,12 @@ struct wined3d_cs_evict_resource + struct wined3d_resource *resource; + }; + ++struct wined3d_cs_buffer_preload ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_buffer *buffer; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2189,6 +2196,29 @@ void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_buffer_preload(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_buffer_preload *op = data; ++ struct wined3d_context *context; ++ ++ context = context_acquire(cs->device, NULL); ++ buffer_internal_preload(op->buffer, context, NULL); ++ context_release(context); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer *buffer) ++{ ++ struct wined3d_cs_buffer_preload *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_BUFFER_PRELOAD; ++ op->buffer = buffer; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2237,6 +2267,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, + /* WINED3D_CS_OP_BUFFER_SWAP_MEM */ wined3d_cs_exec_buffer_swap_mem, + /* WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE */ wined3d_cs_exec_buffer_invalidate_bo_range, ++ /* WINED3D_CS_OP_BUFFER_PRELOAD */ wined3d_cs_exec_buffer_preload, + /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, + /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, + /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index c683880..4070e1d 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2698,6 +2698,7 @@ void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffe + BYTE *mem) DECLSPEC_HIDDEN; + void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, + struct wined3d_buffer *buffer, UINT offset, UINT size) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0118-wined3d-Access-the-buffer-dirty-areas-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0118-wined3d-Access-the-buffer-dirty-areas-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0118-wined3d-Access-the-buffer-dirty-areas-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0118-wined3d-Access-the-buffer-dirty-areas-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,140 +0,0 @@ -From 6d53bc01b8d6db32aab6c0d9e7b93c20f2a7af94 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 17:05:12 +0200 -Subject: wined3d: Access the buffer dirty areas through the CS - -This avoids the following issues: - -1) The worker thread uploading a dirtified area before the application -unlocks the buffer and marking it clean - -2) The worker thread uploading data from the old memory and marking the -area clean although the data was written to a new block of memory. - -However, this adds more synchronization than necessary. The first -problem could be solved by moving dirtification to unmap, e.g. via a -flag in each dirty area. The second problem can be fixed by not -dirtifying in map if map_mem != resource.allocatedMemory and dirtifying -the entire buffer in buffer_swap_memory (DISCARD dirtifies the entire -buffer anyway, and this could be the reason why). - -If one of those ideas is used, access to the dirty area array needs to -be protected by locks. ---- - dlls/wined3d/buffer.c | 6 +++--- - dlls/wined3d/cs.c | 31 +++++++++++++++++++++++++++++++ - dlls/wined3d/wined3d_private.h | 3 +++ - 3 files changed, 37 insertions(+), 3 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index c0bbfb7..df44ae0 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -41,7 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); - #define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */ - #define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */ - --static void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, UINT offset, UINT size) -+void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, UINT offset, UINT size) - { - if (!offset && !size) - goto invalidate_all; -@@ -979,9 +979,9 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - * being uploaded in that case. Two such applications are Port Royale - * and Darkstar One. */ - if (flags & WINED3D_MAP_DISCARD) -- buffer_invalidate_bo_range(buffer, 0, 0); -+ wined3d_cs_emit_buffer_invalidate_bo_range(device->cs, buffer, 0, 0); - else if (!(flags & WINED3D_MAP_READONLY)) -- buffer_invalidate_bo_range(buffer, offset, size); -+ wined3d_cs_emit_buffer_invalidate_bo_range(device->cs, buffer, offset, size); - - if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) - { -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 0a246a9..b871d92 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -70,6 +70,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_RESOURCE_MAP, - WINED3D_CS_OP_RESOURCE_UNMAP, - WINED3D_CS_OP_BUFFER_SWAP_MEM, -+ WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE, - WINED3D_CS_OP_QUERY_ISSUE, - WINED3D_CS_OP_QUERY_DESTROY, - WINED3D_CS_OP_UPDATE_SURFACE, -@@ -392,6 +393,13 @@ struct wined3d_cs_buffer_swap_mem - BYTE *mem; - }; - -+struct wined3d_cs_buffer_invalidate_bo_range -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_buffer *buffer; -+ UINT offset, size; -+}; -+ - struct wined3d_cs_skip - { - enum wined3d_cs_op opcode; -@@ -2272,6 +2280,28 @@ void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffe - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_buffer_invalidate_bo_range(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_buffer_invalidate_bo_range *op = data; -+ -+ buffer_invalidate_bo_range(op->buffer, op->offset, op->size); -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, -+ struct wined3d_buffer *buffer, UINT offset, UINT size) -+{ -+ struct wined3d_cs_buffer_invalidate_bo_range *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE; -+ op->buffer = buffer; -+ op->offset = offset; -+ op->size = size; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2320,6 +2350,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, - /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, - /* WINED3D_CS_OP_BUFFER_SWAP_MEM */ wined3d_cs_exec_buffer_swap_mem, -+ /* WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE */ wined3d_cs_exec_buffer_invalidate_bo_range, - /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, - /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, - /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index efc5d2d..801c221 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2745,6 +2745,8 @@ void wined3d_cs_emit_update_texture(struct wined3d_cs *cs, struct wined3d_textur - void wined3d_cs_emit_evict_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffer *buffer, - BYTE *mem) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, -+ struct wined3d_buffer *buffer, UINT offset, UINT size) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d -@@ -2830,6 +2832,7 @@ void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *co - BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *context) DECLSPEC_HIDDEN; - void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, - const struct wined3d_state *state) DECLSPEC_HIDDEN; -+void buffer_invalidate_bo_range(struct wined3d_buffer *This, UINT offset, UINT size) DECLSPEC_HIDDEN; - - struct wined3d_rendertarget_view - { --- -2.4.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0118-wined3d-Use-glBufferSubData-instead-of-glMapBufferRa.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0118-wined3d-Use-glBufferSubData-instead-of-glMapBufferRa.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0118-wined3d-Use-glBufferSubData-instead-of-glMapBufferRa.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0118-wined3d-Use-glBufferSubData-instead-of-glMapBufferRa.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,91 @@ +From 23c12ecbb385011837969d44bafdd50d2853eb6c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 24 Jul 2013 13:02:06 +0200 +Subject: wined3d: Use glBufferSubData instead of glMapBufferRange + +This is faster on Nvidia once we're stuck in double-buffer mode for some +reason (e.g. using threaded cs). For other cards, we want to be able to +do mapbuffer through the CS. +--- + dlls/wined3d/buffer.c | 50 ++++++-------------------------------------------- + 1 file changed, 6 insertions(+), 44 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 4fff195..5bdd6e4 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -657,43 +657,17 @@ drop_query: + /* The caller provides a GL context */ + static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info, DWORD flags) + { +- BYTE *map; + UINT start, len; + + /* This potentially invalidates the element array buffer binding, but the + * caller always takes care of this. */ + GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object)); + checkGLcall("glBindBuffer"); +- if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) +- { +- GLbitfield mapflags; +- mapflags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; +- if (flags & WINED3D_BUFFER_DISCARD) +- mapflags |= GL_MAP_INVALIDATE_BUFFER_BIT; +- else if (!(flags & WINED3D_BUFFER_SYNC)) +- mapflags |= GL_MAP_UNSYNCHRONIZED_BIT; +- map = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, +- This->resource.size, mapflags)); +- checkGLcall("glMapBufferRange"); +- } +- else +- { +- if (This->flags & WINED3D_BUFFER_APPLESYNC) +- { +- DWORD syncflags = 0; +- if (flags & WINED3D_BUFFER_DISCARD) +- syncflags |= WINED3D_MAP_DISCARD; +- else if (!(flags & WINED3D_BUFFER_SYNC)) +- syncflags |= WINED3D_MAP_NOOVERWRITE; +- buffer_sync_apple(This, syncflags, gl_info); +- } +- map = GL_EXTCALL(glMapBuffer(This->buffer_type_hint, GL_WRITE_ONLY)); +- checkGLcall("glMapBuffer"); +- } +- if (!map) ++ ++ if (flags & WINED3D_BUFFER_DISCARD) + { +- ERR("Failed to map opengl buffer\n"); +- return; ++ GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, NULL, GL_STREAM_DRAW)); ++ checkGLcall("glBufferData"); + } + + while (This->modified_areas) +@@ -702,21 +676,9 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined + start = This->maps[This->modified_areas].offset; + len = This->maps[This->modified_areas].size; + +- memcpy(map + start, (BYTE *)This->resource.heap_memory + start, len); +- +- if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) +- { +- GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len)); +- checkGLcall("glFlushMappedBufferRange"); +- } +- else if (This->flags & WINED3D_BUFFER_APPLESYNC) +- { +- GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len)); +- checkGLcall("glFlushMappedBufferRangeAPPLE"); +- } ++ GL_EXTCALL(glBufferSubData(This->buffer_type_hint, start, len, (BYTE *)This->resource.heap_memory + start)); ++ checkGLcall("glBufferSubData"); + } +- GL_EXTCALL(glUnmapBuffer(This->buffer_type_hint)); +- checkGLcall("glUnmapBuffer"); + } + + static void buffer_mark_used(struct wined3d_buffer *buffer) +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0119-wined3d-Ignore-buffer-resource.map_count-in-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0119-wined3d-Ignore-buffer-resource.map_count-in-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0119-wined3d-Ignore-buffer-resource.map_count-in-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0119-wined3d-Ignore-buffer-resource.map_count-in-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -From e7637b3b410855296289ec8ebe199b80b5a7a2b0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 22:52:06 +0200 -Subject: wined3d: Ignore buffer->resource.map_count in the CS - -This fixes sporadic test failures caused by preload refusing to load -data into the GL buffer. - -It's fine to preload or create a VBO if a DISCARD or NOOVERWRITE map is -happening at the same time. A non-dynamic map will finish the CS before -incrementing map_count. ---- - dlls/wined3d/buffer.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 551cc7a..3ac45c6 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -457,7 +457,8 @@ void buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_context *co - data->buffer_object = buffer->buffer_object; - if (!buffer->buffer_object) - { -- if ((buffer->flags & WINED3D_BUFFER_CREATEBO) && !buffer->resource.map_count) -+ if ((!buffer->resource.map_count || buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER) -+ && buffer->flags & WINED3D_BUFFER_CREATEBO) - { - buffer_create_buffer_object(buffer, context); - buffer->flags &= ~WINED3D_BUFFER_CREATEBO; -@@ -737,12 +738,6 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte - - TRACE("buffer %p.\n", buffer); - -- if (buffer->resource.map_count) -- { -- WARN("Buffer is mapped, skipping preload.\n"); -- return; -- } -- - buffer_mark_used(buffer); - - if (!buffer->buffer_object) -@@ -934,6 +929,12 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) - struct wined3d_context *context; - struct wined3d_device *device = buffer->resource.device; - -+ if (buffer->resource.map_count) -+ { -+ WARN("Buffer is mapped, skipping preload.\n"); -+ return; -+ } -+ - if (wined3d_settings.cs_multithreaded) - { - FIXME("Waiting for cs.\n"); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0119-wined3d-Separate-GL-buffer-discard-control-from-igno.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0119-wined3d-Separate-GL-buffer-discard-control-from-igno.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0119-wined3d-Separate-GL-buffer-discard-control-from-igno.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0119-wined3d-Separate-GL-buffer-discard-control-from-igno.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,135 @@ +From cb3001744c90910e2a44caa6bb05eb0c5a685efd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 30 Jul 2013 22:17:10 +0200 +Subject: wined3d: Separate GL buffer discard control from ignoring + MAP_DISCARD. + +Ignoring WINED3D_MAP_DISCARD is controlled purely in the main thread, +whereas the other one is controlled in the worker thread. Store them in +separate fields for synchronization purposes. + +There are some problems left: +* buffer->flags is still accessed by both threads without sync. +* CSMT=off has a separate codepath that is untested. +--- + dlls/wined3d/buffer.c | 25 +++++++++++++++++++------ + dlls/wined3d/cs.c | 9 +++++++-- + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 28 insertions(+), 8 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 3945549..2421eb3 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -32,7 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); + #define WINED3D_BUFFER_HASDESC 0x01 /* A vertex description has been found. */ + #define WINED3D_BUFFER_CREATEBO 0x02 /* Create a buffer object for this buffer. */ + #define WINED3D_BUFFER_DOUBLEBUFFER 0x04 /* Keep both a buffer object and a system memory copy for this buffer. */ +-#define WINED3D_BUFFER_DISCARD 0x08 /* A DISCARD lock has occurred since the last preload. */ ++#define WINED3D_BUFFER_DISCARD 0x08 /* The next PreLoad may discard the buffer contents. */ + #define WINED3D_BUFFER_SYNC 0x10 /* There has been at least one synchronized map since the last preload. */ + #define WINED3D_BUFFER_APPLESYNC 0x20 /* Using sync as in GL_APPLE_flush_buffer_range. */ + +@@ -921,7 +921,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + * previous contents of the buffer. The r600g driver only does this when + * the buffer is currently in use, while the proprietary NVIDIA driver + * appears to do this unconditionally. */ +- if (buffer->flags & WINED3D_BUFFER_DISCARD) ++ if (buffer->ignore_discard) + flags &= ~WINED3D_MAP_DISCARD; + count = ++buffer->resource.map_count; + +@@ -1004,10 +1004,15 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + context_release(context); + } + } +- +- if (flags & WINED3D_MAP_DISCARD) +- buffer->flags |= WINED3D_BUFFER_DISCARD; +- else if (!(flags & WINED3D_MAP_NOOVERWRITE)) ++ else if(!wined3d_settings.cs_multithreaded) ++ { ++ if (flags & WINED3D_MAP_DISCARD) ++ { ++ buffer->flags |= WINED3D_BUFFER_DISCARD; ++ buffer->ignore_discard = TRUE; ++ } ++ } ++ if (!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD))) + buffer->flags |= WINED3D_BUFFER_SYNC; + } + +@@ -1016,6 +1021,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + BOOL swvp = device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING; + if (flags & WINED3D_MAP_DISCARD && !swvp) + { ++ buffer->ignore_discard = TRUE; + wined3d_resource_allocate_sysmem(&buffer->resource); + wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); + } +@@ -1399,3 +1405,10 @@ HRESULT CDECL wined3d_buffer_create_ib(struct wined3d_device *device, UINT size, + + return WINED3D_OK; + } ++ ++void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) ++{ ++ wined3d_resource_free_sysmem(&buffer->resource); ++ buffer->resource.heap_memory = mem; ++ buffer->flags |= WINED3D_BUFFER_DISCARD; ++} +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index ee76ef0..5eb8803 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -732,11 +732,17 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun + op->indexed = indexed; + + if (indexed) ++ { + wined3d_resource_inc_fence(&state->index_buffer->resource); ++ state->index_buffer->ignore_discard = FALSE; ++ } + for (i = 0; i < sizeof(state->streams) / sizeof(*state->streams); i++) + { + if (state->streams[i].buffer) ++ { + wined3d_resource_inc_fence(&state->streams[i].buffer->resource); ++ state->streams[i].buffer->ignore_discard = FALSE; ++ } + } + for (i = 0; i < sizeof(state->textures) / sizeof(*state->textures); i++) + { +@@ -2265,8 +2271,7 @@ static UINT wined3d_cs_exec_buffer_swap_mem(struct wined3d_cs *cs, const void *d + const struct wined3d_cs_buffer_swap_mem *op = data; + struct wined3d_buffer *buffer = op->buffer; + +- wined3d_resource_free_sysmem(&buffer->resource); +- buffer->resource.heap_memory = op->mem; ++ buffer_swap_mem(buffer, op->mem); + + if (!buffer->buffer_object && buffer->resource.bind_count) + { +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 27a534a..c79b6a9 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2877,6 +2877,7 @@ struct wined3d_buffer + GLenum buffer_object_usage; + GLenum buffer_type_hint; + DWORD flags; ++ BOOL ignore_discard; + void *map_ptr; + + struct wined3d_map_range *maps; +@@ -2902,6 +2903,7 @@ BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *con + void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, + const struct wined3d_state *state) DECLSPEC_HIDDEN; + void buffer_invalidate_bo_range(struct wined3d_buffer *This, UINT offset, UINT size) DECLSPEC_HIDDEN; ++void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) DECLSPEC_HIDDEN; + HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, + const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN; + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0120-wined3d-Create-buffers-before-mapping-them.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0120-wined3d-Create-buffers-before-mapping-them.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0120-wined3d-Create-buffers-before-mapping-them.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0120-wined3d-Create-buffers-before-mapping-them.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,66 @@ +From 26b18d0685e6c3bc9d00cc9eba3359c8c671bdd9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 29 Aug 2013 17:35:53 +0200 +Subject: wined3d: Create buffers before mapping them. + +--- + dlls/wined3d/buffer.c | 26 +++++++++++++++++++++++++- + 1 file changed, 25 insertions(+), 1 deletion(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 5d71e9c..bd788c4 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -185,6 +185,8 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine + ERR("glBufferData failed with error %s (%#x)\n", debug_glerror(error), error); + goto fail; + } ++ if (wined3d_settings.strict_draw_ordering || wined3d_settings.cs_multithreaded) ++ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + + This->buffer_object_usage = gl_usage; + +@@ -911,9 +913,32 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + LONG count; + BYTE *base; + struct wined3d_device *device = buffer->resource.device; ++ struct wined3d_context *context; + + TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags); + ++ /* FIXME: There is a race condition with the same code in ++ * buffer_internal_preload and buffer_get_memory. ++ * ++ * This deals with a race condition concering buffer creation and buffer maps. ++ * If a VBO is created by the worker thread while the buffer is mapped, outdated ++ * data may be uploaded, and the BO range is not properly invaliated. Keep in ++ * mind that a broken application might draw from a buffer before mapping it. ++ * ++ * Don't try to solve this by going back to always invalidating changed areas. ++ * This won't work if we ever want to support glMapBufferRange mapping with ++ * GL_ARB_buffer_storage in the CS. ++ * ++ * Also keep in mind that UnLoad can destroy the VBO, so simply creating it ++ * on buffer creation won't work either. */ ++ if (buffer->flags & WINED3D_BUFFER_CREATEBO) ++ { ++ context = context_acquire(device, NULL); ++ buffer_create_buffer_object(buffer, context); ++ context_release(context); ++ buffer->flags &= ~WINED3D_BUFFER_CREATEBO; ++ } ++ + flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags); + /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001 multitexture + * fill rate test seems to depend on this. When we map a buffer with +@@ -941,7 +966,6 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + if (count == 1) + { + struct wined3d_device *device = buffer->resource.device; +- struct wined3d_context *context; + const struct wined3d_gl_info *gl_info; + + if (wined3d_settings.cs_multithreaded) +-- +2.5.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0120-wined3d-Send-buffer-preloads-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0120-wined3d-Send-buffer-preloads-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0120-wined3d-Send-buffer-preloads-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0120-wined3d-Send-buffer-preloads-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,122 +0,0 @@ -From f0608f8a5916eea7e342db36ffe49427e40a4b49 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sun, 7 Jul 2013 12:02:59 +0200 -Subject: wined3d: Send buffer preloads through the CS - -Think about making this a fast command. Might help if the driver -supports async data transfer, but synchronization side effects, esp. wrt -the dirty area list, have to be considered. ---- - dlls/wined3d/buffer.c | 12 +----------- - dlls/wined3d/cs.c | 31 +++++++++++++++++++++++++++++++ - dlls/wined3d/wined3d_private.h | 1 + - 3 files changed, 33 insertions(+), 11 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 3ac45c6..a09ca90 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -926,7 +926,6 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte - - void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) - { -- struct wined3d_context *context; - struct wined3d_device *device = buffer->resource.device; - - if (buffer->resource.map_count) -@@ -935,16 +934,7 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) - return; - } - -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- wined3d_cs_emit_glfinish(device->cs); -- device->cs->ops->finish(device->cs); -- } -- -- context = context_acquire(buffer->resource.device, NULL); -- buffer_internal_preload(buffer, context, NULL); -- context_release(context); -+ wined3d_cs_emit_buffer_preload(device->cs, buffer); - } - - struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer) -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 179f2e6..6b16d51 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -70,6 +70,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_RESOURCE_UNMAP, - WINED3D_CS_OP_BUFFER_SWAP_MEM, - WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE, -+ WINED3D_CS_OP_BUFFER_PRELOAD, - WINED3D_CS_OP_QUERY_ISSUE, - WINED3D_CS_OP_QUERY_DESTROY, - WINED3D_CS_OP_UPDATE_SURFACE, -@@ -442,6 +443,12 @@ struct wined3d_cs_evict_resource - struct wined3d_resource *resource; - }; - -+struct wined3d_cs_buffer_preload -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_buffer *buffer; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2189,6 +2196,29 @@ void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_buffer_preload(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_buffer_preload *op = data; -+ struct wined3d_context *context; -+ -+ context = context_acquire(cs->device, NULL); -+ buffer_internal_preload(op->buffer, context, NULL); -+ context_release(context); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer *buffer) -+{ -+ struct wined3d_cs_buffer_preload *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_BUFFER_PRELOAD; -+ op->buffer = buffer; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2237,6 +2267,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, - /* WINED3D_CS_OP_BUFFER_SWAP_MEM */ wined3d_cs_exec_buffer_swap_mem, - /* WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE */ wined3d_cs_exec_buffer_invalidate_bo_range, -+ /* WINED3D_CS_OP_BUFFER_PRELOAD */ wined3d_cs_exec_buffer_preload, - /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, - /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, - /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index c683880..4070e1d 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2698,6 +2698,7 @@ void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffe - BYTE *mem) DECLSPEC_HIDDEN; - void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, - struct wined3d_buffer *buffer, UINT offset, UINT size) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0121-wined3d-Destroy-views-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0121-wined3d-Destroy-views-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0121-wined3d-Destroy-views-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0121-wined3d-Destroy-views-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,173 @@ +From eef628fde30bac893e13569c49213893a46583cb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 21 Aug 2014 22:47:58 +0200 +Subject: wined3d: Destroy views through the CS. + +Move this ahead. This has caused sporadic test failures ever since blits were moved to the CS. + +Also contains an ugly hack for ffp_blit_depth_fill. +--- + dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ + dlls/wined3d/surface.c | 4 ++-- + dlls/wined3d/view.c | 29 ++++++++++++++++++++++++++++- + dlls/wined3d/wined3d_private.h | 4 ++++ + 4 files changed, 62 insertions(+), 3 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index b489506..a5df7a7 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -78,6 +78,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_TEXTURE_PRELOAD, + WINED3D_CS_OP_UPDATE_TEXTURE, + WINED3D_CS_OP_EVICT_RESOURCE, ++ WINED3D_CS_OP_VIEW_DESTROY, + WINED3D_CS_OP_STOP, + }; + +@@ -452,6 +453,12 @@ struct wined3d_cs_buffer_preload + struct wined3d_buffer *buffer; + }; + ++struct wined3d_cs_view_destroy ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_rendertarget_view *view; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2308,6 +2315,26 @@ void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_view_destroy(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_view_destroy *op = data; ++ ++ wined3d_rendertarget_view_destroy(op->view); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) ++{ ++ struct wined3d_cs_view_destroy *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_VIEW_DESTROY; ++ op->view = view; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2364,6 +2391,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, + /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, + /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, ++ /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index b1db403..9f89468 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -939,7 +939,7 @@ static HRESULT wined3d_surface_depth_fill(struct wined3d_surface *surface, const + } + + hr = blitter->depth_fill(device, view, rect, depth); +- wined3d_rendertarget_view_decref(view); ++ wined3d_rendertarget_view_decref_worker(view); + + return hr; + } +@@ -3207,7 +3207,7 @@ HRESULT surface_color_fill(struct wined3d_surface *s, const RECT *rect, const st + } + + hr = blitter->color_fill(device, view, rect, color); +- wined3d_rendertarget_view_decref(view); ++ wined3d_rendertarget_view_decref_worker(view); + + return hr; + } +diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c +index 8d4f7fd..e4694af 100644 +--- a/dlls/wined3d/view.c ++++ b/dlls/wined3d/view.c +@@ -33,6 +33,11 @@ ULONG CDECL wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *v + return refcount; + } + ++void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) ++{ ++ HeapFree(GetProcessHeap(), 0, view); ++} ++ + ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view) + { + ULONG refcount = InterlockedDecrement(&view->refcount); +@@ -41,11 +46,33 @@ ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *v + + if (!refcount) + { ++ struct wined3d_device *device = view->resource->device; ++ + /* Call wined3d_object_destroyed() before releasing the resource, + * since releasing the resource may end up destroying the parent. */ + view->parent_ops->wined3d_object_destroyed(view->parent); + wined3d_resource_decref(view->resource); +- HeapFree(GetProcessHeap(), 0, view); ++ wined3d_cs_emit_view_destroy(device->cs, view); ++ } ++ ++ return refcount; ++} ++ ++/* Ugly hack for ffp_blit_depth_fill that allows destroying a view from inside the ++ * worker thread. */ ++ULONG wined3d_rendertarget_view_decref_worker(struct wined3d_rendertarget_view *view) ++{ ++ ULONG refcount = InterlockedDecrement(&view->refcount); ++ ++ TRACE("%p decreasing refcount to %u.\n", view, refcount); ++ ++ if (!refcount) ++ { ++ /* Call wined3d_object_destroyed() before releasing the resource, ++ * since releasing the resource may end up destroying the parent. */ ++ view->parent_ops->wined3d_object_destroyed(view->parent); ++ wined3d_resource_decref(view->resource); ++ wined3d_rendertarget_view_destroy(view); + } + + return refcount; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index c9578bd..9c70257 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2902,6 +2902,7 @@ void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffe + void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, + struct wined3d_buffer *buffer, UINT offset, UINT size) DECLSPEC_HIDDEN; + void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +@@ -3027,6 +3028,9 @@ static inline struct wined3d_surface *wined3d_rendertarget_view_get_surface( + return surface_from_resource(resource); + } + ++ULONG wined3d_rendertarget_view_decref_worker(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; ++void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; ++ + struct wined3d_shader_resource_view + { + LONG refcount; +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0121-wined3d-Use-glBufferSubData-instead-of-glMapBufferRa.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0121-wined3d-Use-glBufferSubData-instead-of-glMapBufferRa.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0121-wined3d-Use-glBufferSubData-instead-of-glMapBufferRa.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0121-wined3d-Use-glBufferSubData-instead-of-glMapBufferRa.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -From 8d084548850a169be0ef5863e7c8fe2ebce83c36 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 24 Jul 2013 13:02:06 +0200 -Subject: wined3d: Use glBufferSubData instead of glMapBufferRange - -This is faster on Nvidia once we're stuck in double-buffer mode for some -reason (e.g. using threaded cs). For other cards, we want to be able to -do mapbuffer through the CS. ---- - dlls/wined3d/buffer.c | 50 ++++++-------------------------------------------- - 1 file changed, 6 insertions(+), 44 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 12ef20f..04e38cb 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -657,43 +657,17 @@ drop_query: - /* The caller provides a GL context */ - static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info, DWORD flags) - { -- BYTE *map; - UINT start = 0, len = 0; - - /* This potentially invalidates the element array buffer binding, but the - * caller always takes care of this. */ - GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object)); - checkGLcall("glBindBuffer"); -- if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) -- { -- GLbitfield mapflags; -- mapflags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; -- if (flags & WINED3D_BUFFER_DISCARD) -- mapflags |= GL_MAP_INVALIDATE_BUFFER_BIT; -- else if (!(flags & WINED3D_BUFFER_SYNC)) -- mapflags |= GL_MAP_UNSYNCHRONIZED_BIT; -- map = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, -- This->resource.size, mapflags)); -- checkGLcall("glMapBufferRange"); -- } -- else -- { -- if (This->flags & WINED3D_BUFFER_APPLESYNC) -- { -- DWORD syncflags = 0; -- if (flags & WINED3D_BUFFER_DISCARD) -- syncflags |= WINED3D_MAP_DISCARD; -- else if (!(flags & WINED3D_BUFFER_SYNC)) -- syncflags |= WINED3D_MAP_NOOVERWRITE; -- buffer_sync_apple(This, syncflags, gl_info); -- } -- map = GL_EXTCALL(glMapBuffer(This->buffer_type_hint, GL_WRITE_ONLY)); -- checkGLcall("glMapBuffer"); -- } -- if (!map) -+ -+ if (flags & WINED3D_BUFFER_DISCARD) - { -- ERR("Failed to map opengl buffer\n"); -- return; -+ GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, NULL, GL_STREAM_DRAW)); -+ checkGLcall("glBufferData"); - } - - while (This->modified_areas) -@@ -702,21 +676,9 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined - start = This->maps[This->modified_areas].offset; - len = This->maps[This->modified_areas].size; - -- memcpy(map + start, (BYTE *)This->resource.heap_memory + start, len); -- -- if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) -- { -- GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len)); -- checkGLcall("glFlushMappedBufferRange"); -- } -- else if (This->flags & WINED3D_BUFFER_APPLESYNC) -- { -- GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len)); -- checkGLcall("glFlushMappedBufferRangeAPPLE"); -- } -+ GL_EXTCALL(glBufferSubData(This->buffer_type_hint, start, len, (BYTE *)This->resource.heap_memory + start)); -+ checkGLcall("glBufferSubData"); - } -- GL_EXTCALL(glUnmapBuffer(This->buffer_type_hint)); -- checkGLcall("glUnmapBuffer"); - } - - static void buffer_mark_used(struct wined3d_buffer *buffer) --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0122-wined3d-Remove-another-glFinish.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0122-wined3d-Remove-another-glFinish.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0122-wined3d-Remove-another-glFinish.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0122-wined3d-Remove-another-glFinish.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,28 @@ +From 8a0e110ba10657b84aa33a1cd51fe46128062d4d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sat, 6 Jul 2013 22:08:39 +0200 +Subject: wined3d: Remove another glFinish + +I don't think this is needed any more. +--- + dlls/wined3d/surface.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 43f68c6..1d777e2 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -825,9 +825,7 @@ static void surface_blt_fbo(const struct wined3d_device *device, + dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, GL_COLOR_BUFFER_BIT, gl_filter); + checkGLcall("glBlitFramebuffer()"); + +- if (wined3d_settings.cs_multithreaded) +- gl_info->gl_ops.gl.p_glFinish(); +- else if (wined3d_settings.strict_draw_ordering ++ if (wined3d_settings.strict_draw_ordering + || (dst_location == WINED3D_LOCATION_DRAWABLE + && dst_surface->container->swapchain->front_buffer == dst_surface->container)) + gl_info->gl_ops.gl.p_glFlush(); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0122-wined3d-Separate-GL-buffer-discard-control-from-igno.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0122-wined3d-Separate-GL-buffer-discard-control-from-igno.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0122-wined3d-Separate-GL-buffer-discard-control-from-igno.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0122-wined3d-Separate-GL-buffer-discard-control-from-igno.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,135 +0,0 @@ -From fd33771329457adaba5a2fb8006991e7ad756ec7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 30 Jul 2013 22:17:10 +0200 -Subject: wined3d: Separate GL buffer discard control from ignoring - MAP_DISCARD. - -Ignoring WINED3D_MAP_DISCARD is controlled purely in the main thread, -whereas the other one is controlled in the worker thread. Store them in -separate fields for synchronization purposes. - -There are some problems left: -* buffer->flags is still accessed by both threads without sync. -* CSMT=off has a separate codepath that is untested. ---- - dlls/wined3d/buffer.c | 25 +++++++++++++++++++------ - dlls/wined3d/cs.c | 9 +++++++-- - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 28 insertions(+), 8 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 675dbec..8b09aee 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -32,7 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); - #define WINED3D_BUFFER_HASDESC 0x01 /* A vertex description has been found. */ - #define WINED3D_BUFFER_CREATEBO 0x02 /* Create a buffer object for this buffer. */ - #define WINED3D_BUFFER_DOUBLEBUFFER 0x04 /* Keep both a buffer object and a system memory copy for this buffer. */ --#define WINED3D_BUFFER_DISCARD 0x08 /* A DISCARD lock has occurred since the last preload. */ -+#define WINED3D_BUFFER_DISCARD 0x08 /* The next PreLoad may discard the buffer contents. */ - #define WINED3D_BUFFER_SYNC 0x10 /* There has been at least one synchronized map since the last preload. */ - #define WINED3D_BUFFER_APPLESYNC 0x20 /* Using sync as in GL_APPLE_flush_buffer_range. */ - -@@ -921,7 +921,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - * previous contents of the buffer. The r600g driver only does this when - * the buffer is currently in use, while the proprietary NVIDIA driver - * appears to do this unconditionally. */ -- if (buffer->flags & WINED3D_BUFFER_DISCARD) -+ if (buffer->ignore_discard) - flags &= ~WINED3D_MAP_DISCARD; - count = ++buffer->resource.map_count; - -@@ -1004,10 +1004,15 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - context_release(context); - } - } -- -- if (flags & WINED3D_MAP_DISCARD) -- buffer->flags |= WINED3D_BUFFER_DISCARD; -- else if (!(flags & WINED3D_MAP_NOOVERWRITE)) -+ else if(!wined3d_settings.cs_multithreaded) -+ { -+ if (flags & WINED3D_MAP_DISCARD) -+ { -+ buffer->flags |= WINED3D_BUFFER_DISCARD; -+ buffer->ignore_discard = TRUE; -+ } -+ } -+ if (!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD))) - buffer->flags |= WINED3D_BUFFER_SYNC; - } - -@@ -1016,6 +1021,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - BOOL swvp = device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING; - if (flags & WINED3D_MAP_DISCARD && !swvp) - { -+ buffer->ignore_discard = TRUE; - wined3d_resource_allocate_sysmem(&buffer->resource); - wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); - } -@@ -1332,3 +1338,10 @@ HRESULT CDECL wined3d_buffer_create_ib(struct wined3d_device *device, UINT size, - - return WINED3D_OK; - } -+ -+void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) -+{ -+ wined3d_resource_free_sysmem(&buffer->resource); -+ buffer->resource.heap_memory = mem; -+ buffer->flags |= WINED3D_BUFFER_DISCARD; -+} -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 6b16d51..4b9af57 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -722,11 +722,17 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun - op->indexed = indexed; - - if (indexed) -+ { - wined3d_resource_inc_fence(&state->index_buffer->resource); -+ state->index_buffer->ignore_discard = FALSE; -+ } - for (i = 0; i < sizeof(state->streams) / sizeof(*state->streams); i++) - { - if (state->streams[i].buffer) -+ { - wined3d_resource_inc_fence(&state->streams[i].buffer->resource); -+ state->streams[i].buffer->ignore_discard = FALSE; -+ } - } - for (i = 0; i < sizeof(state->textures) / sizeof(*state->textures); i++) - { -@@ -2151,8 +2157,7 @@ static UINT wined3d_cs_exec_buffer_swap_mem(struct wined3d_cs *cs, const void *d - const struct wined3d_cs_buffer_swap_mem *op = data; - struct wined3d_buffer *buffer = op->buffer; - -- wined3d_resource_free_sysmem(&buffer->resource); -- buffer->resource.heap_memory = op->mem; -+ buffer_swap_mem(buffer, op->mem); - - if (!buffer->buffer_object && buffer->resource.bind_count) - { -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 4070e1d..0f88961 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2760,6 +2760,7 @@ struct wined3d_buffer - GLenum buffer_object_usage; - GLenum buffer_type_hint; - DWORD flags; -+ BOOL ignore_discard; - void *map_ptr; - - struct wined3d_map_range *maps; -@@ -2785,6 +2786,7 @@ BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *con - void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, - const struct wined3d_state *state) DECLSPEC_HIDDEN; - void buffer_invalidate_bo_range(struct wined3d_buffer *This, UINT offset, UINT size) DECLSPEC_HIDDEN; -+void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) DECLSPEC_HIDDEN; - - struct wined3d_rendertarget_view - { --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0123-wined3d-Create-buffers-before-mapping-them.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0123-wined3d-Create-buffers-before-mapping-them.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0123-wined3d-Create-buffers-before-mapping-them.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0123-wined3d-Create-buffers-before-mapping-them.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -From 26b18d0685e6c3bc9d00cc9eba3359c8c671bdd9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 29 Aug 2013 17:35:53 +0200 -Subject: wined3d: Create buffers before mapping them. - ---- - dlls/wined3d/buffer.c | 26 +++++++++++++++++++++++++- - 1 file changed, 25 insertions(+), 1 deletion(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 5d71e9c..bd788c4 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -185,6 +185,8 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine - ERR("glBufferData failed with error %s (%#x)\n", debug_glerror(error), error); - goto fail; - } -+ if (wined3d_settings.strict_draw_ordering || wined3d_settings.cs_multithreaded) -+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - This->buffer_object_usage = gl_usage; - -@@ -911,9 +913,32 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - LONG count; - BYTE *base; - struct wined3d_device *device = buffer->resource.device; -+ struct wined3d_context *context; - - TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags); - -+ /* FIXME: There is a race condition with the same code in -+ * buffer_internal_preload and buffer_get_memory. -+ * -+ * This deals with a race condition concering buffer creation and buffer maps. -+ * If a VBO is created by the worker thread while the buffer is mapped, outdated -+ * data may be uploaded, and the BO range is not properly invaliated. Keep in -+ * mind that a broken application might draw from a buffer before mapping it. -+ * -+ * Don't try to solve this by going back to always invalidating changed areas. -+ * This won't work if we ever want to support glMapBufferRange mapping with -+ * GL_ARB_buffer_storage in the CS. -+ * -+ * Also keep in mind that UnLoad can destroy the VBO, so simply creating it -+ * on buffer creation won't work either. */ -+ if (buffer->flags & WINED3D_BUFFER_CREATEBO) -+ { -+ context = context_acquire(device, NULL); -+ buffer_create_buffer_object(buffer, context); -+ context_release(context); -+ buffer->flags &= ~WINED3D_BUFFER_CREATEBO; -+ } -+ - flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags); - /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001 multitexture - * fill rate test seems to depend on this. When we map a buffer with -@@ -941,7 +966,6 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - if (count == 1) - { - struct wined3d_device *device = buffer->resource.device; -- struct wined3d_context *context; - const struct wined3d_gl_info *gl_info; - - if (wined3d_settings.cs_multithreaded) --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0123-wined3d-Destroy-vertex-declarations-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0123-wined3d-Destroy-vertex-declarations-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0123-wined3d-Destroy-vertex-declarations-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0123-wined3d-Destroy-vertex-declarations-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,131 @@ +From a26808a39c226fc0f168336becc97ed512029d52 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 31 Jul 2013 23:06:27 +0200 +Subject: wined3d: Destroy vertex declarations through the CS + +--- + dlls/wined3d/cs.c | 29 +++++++++++++++++++++++++++++ + dlls/wined3d/vertexdeclaration.c | 15 ++++++++------- + dlls/wined3d/wined3d_private.h | 4 ++++ + 3 files changed, 41 insertions(+), 7 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 8e48c55..38063d7 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -79,6 +79,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_UPDATE_TEXTURE, + WINED3D_CS_OP_EVICT_RESOURCE, + WINED3D_CS_OP_VIEW_DESTROY, ++ WINED3D_CS_OP_VDECL_DESTROY, + WINED3D_CS_OP_STOP, + }; + +@@ -456,6 +457,12 @@ struct wined3d_cs_view_destroy + struct wined3d_rendertarget_view *view; + }; + ++struct wined3d_cs_vertex_declaration_destroy ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_vertex_declaration *declaration; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2251,6 +2258,27 @@ void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_renderta + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_vertex_declaration_destroy(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_vertex_declaration_destroy *op = data; ++ ++ wined3d_vertex_declaration_destroy(op->declaration); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, ++ struct wined3d_vertex_declaration *declaration) ++{ ++ struct wined3d_cs_vertex_declaration_destroy *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_VDECL_DESTROY; ++ op->declaration = declaration; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2308,6 +2336,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, + /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, + /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, ++ /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c +index 3f4d5e4..fc7a110 100644 +--- a/dlls/wined3d/vertexdeclaration.c ++++ b/dlls/wined3d/vertexdeclaration.c +@@ -48,6 +48,12 @@ ULONG CDECL wined3d_vertex_declaration_incref(struct wined3d_vertex_declaration + return refcount; + } + ++void wined3d_vertex_declaration_destroy(struct wined3d_vertex_declaration *declaration) ++{ ++ HeapFree(GetProcessHeap(), 0, declaration->elements); ++ HeapFree(GetProcessHeap(), 0, declaration); ++} ++ + ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration *declaration) + { + ULONG refcount = InterlockedDecrement(&declaration->ref); +@@ -56,14 +62,9 @@ ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration + + if (!refcount) + { +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- declaration->device->cs->ops->finish(declaration->device->cs); +- } +- HeapFree(GetProcessHeap(), 0, declaration->elements); ++ const struct wined3d_device *device = declaration->device; + declaration->parent_ops->wined3d_object_destroyed(declaration->parent); +- HeapFree(GetProcessHeap(), 0, declaration); ++ wined3d_cs_emit_vertex_declaration_destroy(device->cs, declaration); + } + + return refcount; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 7d68448..5d3393c 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2499,6 +2499,8 @@ struct wined3d_vertex_declaration + BOOL half_float_conv_needed; + }; + ++void wined3d_vertex_declaration_destroy(struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; ++ + struct wined3d_saved_states + { + DWORD transform[(HIGHEST_TRANSFORMSTATE >> 5) + 1]; +@@ -2700,6 +2702,8 @@ void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, + struct wined3d_buffer *buffer, UINT offset, UINT size) DECLSPEC_HIDDEN; + void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; + void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, ++ struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0124-wined3d-Destroy-shaders-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0124-wined3d-Destroy-shaders-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0124-wined3d-Destroy-shaders-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0124-wined3d-Destroy-shaders-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,126 @@ +From c75e1fc10eb6a040ef2736cee8262e4200366905 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 31 Jul 2013 23:18:28 +0200 +Subject: wined3d: Destroy shaders through the CS + +--- + dlls/wined3d/cs.c | 29 +++++++++++++++++++++++++++++ + dlls/wined3d/shader.c | 12 ++++-------- + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 35 insertions(+), 8 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index f088200..c745460 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -81,6 +81,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_EVICT_RESOURCE, + WINED3D_CS_OP_VIEW_DESTROY, + WINED3D_CS_OP_VDECL_DESTROY, ++ WINED3D_CS_OP_SHADER_CLEANUP, + WINED3D_CS_OP_STOP, + }; + +@@ -473,6 +474,12 @@ struct wined3d_cs_vertex_declaration_destroy + struct wined3d_vertex_declaration *declaration; + }; + ++struct wined3d_cs_shader_cleanup ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_shader *shader; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2392,6 +2399,27 @@ void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_shader_cleanup(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_shader_cleanup *op = data; ++ ++ shader_cleanup(op->shader); ++ HeapFree(GetProcessHeap(), 0, op->shader); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader *shader) ++{ ++ struct wined3d_cs_shader_cleanup *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SHADER_CLEANUP; ++ op->shader = shader; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2451,6 +2479,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, + /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, + /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, ++ /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c +index ec2a269..04e217e 100644 +--- a/dlls/wined3d/shader.c ++++ b/dlls/wined3d/shader.c +@@ -1859,7 +1859,7 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe + } + } + +-static void shader_cleanup(struct wined3d_shader *shader) ++void shader_cleanup(struct wined3d_shader *shader) + { + HeapFree(GetProcessHeap(), 0, shader->output_signature.elements); + HeapFree(GetProcessHeap(), 0, shader->input_signature.elements); +@@ -2115,14 +2115,10 @@ ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader) + + if (!refcount) + { +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- shader->device->cs->ops->finish(shader->device->cs); +- } +- shader_cleanup(shader); ++ const struct wined3d_device *device = shader->device; ++ + shader->parent_ops->wined3d_object_destroyed(shader->parent); +- HeapFree(GetProcessHeap(), 0, shader); ++ wined3d_cs_emit_shader_cleanup(device->cs, shader); + } + + return refcount; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index a2f2044..545c97e 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2751,6 +2751,7 @@ void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer + void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; + void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, + struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader *shader) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +@@ -3153,6 +3154,7 @@ unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_map + void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, + const struct wined3d_shader_reg_maps *reg_maps, const DWORD *byte_code, void *backend_ctx) DECLSPEC_HIDDEN; + BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage) DECLSPEC_HIDDEN; ++void shader_cleanup(struct wined3d_shader *shader) DECLSPEC_HIDDEN; + + static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg) + { +-- +2.3.5 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0124-wined3d-Destroy-views-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0124-wined3d-Destroy-views-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0124-wined3d-Destroy-views-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0124-wined3d-Destroy-views-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,173 +0,0 @@ -From a31fb6ca1b9379028340024e2bd7e97e894b0532 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 21 Aug 2014 22:47:58 +0200 -Subject: wined3d: Destroy views through the CS. - -Move this ahead. This has caused sporadic test failures ever since blits were moved to the CS. - -Also contains an ugly hack for ffp_blit_depth_fill. ---- - dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ - dlls/wined3d/surface.c | 4 ++-- - dlls/wined3d/view.c | 29 ++++++++++++++++++++++++++++- - dlls/wined3d/wined3d_private.h | 4 ++++ - 4 files changed, 62 insertions(+), 3 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 4b9af57..8e48c55 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -78,6 +78,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_SURFACE_PRELOAD, - WINED3D_CS_OP_UPDATE_TEXTURE, - WINED3D_CS_OP_EVICT_RESOURCE, -+ WINED3D_CS_OP_VIEW_DESTROY, - WINED3D_CS_OP_STOP, - }; - -@@ -449,6 +450,12 @@ struct wined3d_cs_buffer_preload - struct wined3d_buffer *buffer; - }; - -+struct wined3d_cs_view_destroy -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_rendertarget_view *view; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2224,6 +2231,26 @@ void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_view_destroy(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_view_destroy *op = data; -+ -+ wined3d_rendertarget_view_destroy(op->view); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) -+{ -+ struct wined3d_cs_view_destroy *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_VIEW_DESTROY; -+ op->view = view; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2280,6 +2307,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SURFACE_PRELOAD */ wined3d_cs_exec_surface_preload, - /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, - /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, -+ /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 73160ff..43f68c6 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -4140,7 +4140,7 @@ static HRESULT ffp_blit_color_fill(struct wined3d_device *device, struct wined3d - } - - device_clear_render_targets(device, 1, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0); -- wined3d_rendertarget_view_decref(view); -+ wined3d_rendertarget_view_decref_worker(view); - - return WINED3D_OK; - } -@@ -4160,7 +4160,7 @@ static HRESULT ffp_blit_depth_fill(struct wined3d_device *device, struct wined3d - } - - device_clear_render_targets(device, 0, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_ZBUFFER, 0, depth, 0); -- wined3d_rendertarget_view_decref(fb.depth_stencil); -+ wined3d_rendertarget_view_decref_worker(fb.depth_stencil); - - return WINED3D_OK; - } -diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c -index 9cda64d..56eb7b3 100644 ---- a/dlls/wined3d/view.c -+++ b/dlls/wined3d/view.c -@@ -33,6 +33,11 @@ ULONG CDECL wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *v - return refcount; - } - -+void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) -+{ -+ HeapFree(GetProcessHeap(), 0, view); -+} -+ - ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view) - { - ULONG refcount = InterlockedDecrement(&view->refcount); -@@ -41,11 +46,33 @@ ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *v - - if (!refcount) - { -+ struct wined3d_device *device = view->resource->device; -+ - /* Call wined3d_object_destroyed() before releasing the resource, - * since releasing the resource may end up destroying the parent. */ - view->parent_ops->wined3d_object_destroyed(view->parent); - wined3d_resource_decref(view->resource); -- HeapFree(GetProcessHeap(), 0, view); -+ wined3d_cs_emit_view_destroy(device->cs, view); -+ } -+ -+ return refcount; -+} -+ -+/* Ugly hack for ffp_blit_depth_fill that allows destroying a view from inside the -+ * worker thread. */ -+ULONG wined3d_rendertarget_view_decref_worker(struct wined3d_rendertarget_view *view) -+{ -+ ULONG refcount = InterlockedDecrement(&view->refcount); -+ -+ TRACE("%p decreasing refcount to %u.\n", view, refcount); -+ -+ if (!refcount) -+ { -+ /* Call wined3d_object_destroyed() before releasing the resource, -+ * since releasing the resource may end up destroying the parent. */ -+ view->parent_ops->wined3d_object_destroyed(view->parent); -+ wined3d_resource_decref(view->resource); -+ wined3d_rendertarget_view_destroy(view); - } - - return refcount; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 0f88961..7d68448 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2699,6 +2699,7 @@ void wined3d_cs_emit_buffer_swap_mem(struct wined3d_cs *cs, struct wined3d_buffe - void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, - struct wined3d_buffer *buffer, UINT offset, UINT size) DECLSPEC_HIDDEN; - void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d -@@ -2824,6 +2825,9 @@ static inline struct wined3d_surface *wined3d_rendertarget_view_get_surface( - return surface_from_resource(resource); - } - -+ULONG wined3d_rendertarget_view_decref_worker(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; -+void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; -+ - struct wined3d_shader_resource_view - { - LONG refcount; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0125-wined3d-Create-VBOs-through-the-command-stream.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0125-wined3d-Create-VBOs-through-the-command-stream.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0125-wined3d-Create-VBOs-through-the-command-stream.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0125-wined3d-Create-VBOs-through-the-command-stream.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,133 @@ +From 66a6fe6a092a4fa661e5baab52bbb2c1d7c661de Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 2 Oct 2013 21:47:08 +0200 +Subject: wined3d: Create VBOs through the command stream. + +A stop-gap solution to make fglrx happier until buffers are updated. +--- + dlls/wined3d/buffer.c | 8 ++------ + dlls/wined3d/cs.c | 32 ++++++++++++++++++++++++++++++++ + dlls/wined3d/wined3d_private.h | 3 +++ + 3 files changed, 37 insertions(+), 6 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 8f86a5b..a937b90 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -117,7 +117,7 @@ static void delete_gl_buffer(struct wined3d_buffer *This, const struct wined3d_g + } + + /* Context activation is done by the caller. */ +-static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) ++void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) + { + GLenum gl_usage = GL_STATIC_DRAW_ARB; + GLenum error; +@@ -185,8 +185,6 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine + ERR("glBufferData failed with error %s (%#x)\n", debug_glerror(error), error); + goto fail; + } +- if (wined3d_settings.strict_draw_ordering || wined3d_settings.cs_multithreaded) +- gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + + This->buffer_object_usage = gl_usage; + +@@ -933,9 +931,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + * on buffer creation won't work either. */ + if (buffer->flags & WINED3D_BUFFER_CREATEBO) + { +- context = context_acquire(device, NULL); +- buffer_create_buffer_object(buffer, context); +- context_release(context); ++ wined3d_cs_emit_create_vbo(device->cs, buffer); + buffer->flags &= ~WINED3D_BUFFER_CREATEBO; + } + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 59b9a9c..33a3b05 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -82,6 +82,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_VIEW_DESTROY, + WINED3D_CS_OP_VDECL_DESTROY, + WINED3D_CS_OP_SHADER_CLEANUP, ++ WINED3D_CS_OP_CREATE_VBO, + WINED3D_CS_OP_STOP, + }; + +@@ -480,6 +481,12 @@ struct wined3d_cs_shader_cleanup + struct wined3d_shader *shader; + }; + ++struct wined3d_cs_create_vbo ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_buffer *buffer; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2421,6 +2428,30 @@ void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_create_vbo(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_create_vbo *op = data; ++ struct wined3d_context *context = context_acquire(cs->device, NULL); ++ ++ buffer_create_buffer_object(op->buffer, context); ++ ++ context_release(context); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *buffer) ++{ ++ struct wined3d_cs_create_vbo *op; ++ ++ op = cs->ops->require_space_prio(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_CREATE_VBO; ++ op->buffer = buffer; ++ ++ cs->ops->submit_prio(cs, sizeof(*op)); ++ cs->ops->finish_prio(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2481,6 +2512,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, + /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, + /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, ++ /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 9eb3c3a..4d5710a 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2822,6 +2822,7 @@ void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_renderta + void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, + struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; + void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader *shader) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +@@ -2910,6 +2911,8 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte + const struct wined3d_state *state) DECLSPEC_HIDDEN; + void buffer_invalidate_bo_range(struct wined3d_buffer *This, UINT offset, UINT size) DECLSPEC_HIDDEN; + void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) DECLSPEC_HIDDEN; ++void buffer_create_buffer_object(struct wined3d_buffer *This, ++ struct wined3d_context *context) DECLSPEC_HIDDEN; + HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, + const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN; + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0125-wined3d-Remove-another-glFinish.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0125-wined3d-Remove-another-glFinish.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0125-wined3d-Remove-another-glFinish.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0125-wined3d-Remove-another-glFinish.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -From 8a0e110ba10657b84aa33a1cd51fe46128062d4d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sat, 6 Jul 2013 22:08:39 +0200 -Subject: wined3d: Remove another glFinish - -I don't think this is needed any more. ---- - dlls/wined3d/surface.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 43f68c6..1d777e2 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -825,9 +825,7 @@ static void surface_blt_fbo(const struct wined3d_device *device, - dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, GL_COLOR_BUFFER_BIT, gl_filter); - checkGLcall("glBlitFramebuffer()"); - -- if (wined3d_settings.cs_multithreaded) -- gl_info->gl_ops.gl.p_glFinish(); -- else if (wined3d_settings.strict_draw_ordering -+ if (wined3d_settings.strict_draw_ordering - || (dst_location == WINED3D_LOCATION_DRAWABLE - && dst_surface->container->swapchain->front_buffer == dst_surface->container)) - gl_info->gl_ops.gl.p_glFlush(); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0126-wined3d-Clean-up-resource-data-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0126-wined3d-Clean-up-resource-data-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0126-wined3d-Clean-up-resource-data-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0126-wined3d-Clean-up-resource-data-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,211 @@ +From 9109cd39e2867e3e9061d1720bde4598111b3d3b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 2 Oct 2013 22:38:51 +0200 +Subject: wined3d: Clean up resource data through the CS. + +--- + dlls/wined3d/buffer.c | 3 +++ + dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ + dlls/wined3d/resource.c | 15 ++++++++++----- + dlls/wined3d/surface.c | 5 +++++ + dlls/wined3d/texture.c | 4 ++++ + dlls/wined3d/volume.c | 3 +++ + dlls/wined3d/wined3d_private.h | 3 +++ + 7 files changed, 56 insertions(+), 5 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index fc65d3a..d968dcb 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -570,6 +570,9 @@ ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) + } + + resource_cleanup(&buffer->resource); ++ if (wined3d_settings.cs_multithreaded) ++ buffer->resource.device->cs->ops->finish(buffer->resource.device->cs); ++ + buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent); + HeapFree(GetProcessHeap(), 0, buffer->maps); + HeapFree(GetProcessHeap(), 0, buffer); +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index c00d1d3..6edd5e3 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -82,6 +82,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_VDECL_DESTROY, + WINED3D_CS_OP_SHADER_CLEANUP, + WINED3D_CS_OP_CREATE_VBO, ++ WINED3D_CS_OP_RESOURCE_CLEANUP, + WINED3D_CS_OP_STOP, + }; + +@@ -477,6 +478,12 @@ struct wined3d_cs_create_vbo + struct wined3d_buffer *buffer; + }; + ++struct wined3d_cs_resource_cleanup ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_resource *resource; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2338,6 +2345,26 @@ void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *bu + cs->ops->finish_prio(cs); + } + ++static UINT wined3d_cs_exec_resource_cleanup(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_resource_cleanup *op = data; ++ ++ wined3d_resource_cleanup_cs(op->resource); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, struct wined3d_resource *resource) ++{ ++ struct wined3d_cs_resource_cleanup *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_RESOURCE_CLEANUP; ++ op->resource = resource; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2398,6 +2425,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, + /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, + /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, ++ /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index ef0b213..dd21986 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -157,6 +157,15 @@ void wined3d_resource_free_bo(struct wined3d_resource *resource) + context_release(context); + } + ++void wined3d_resource_cleanup_cs(struct wined3d_resource *resource) ++{ ++ if (resource->buffer) ++ wined3d_resource_free_bo(resource); ++ ++ wined3d_resource_free_sysmem(resource); ++ resource->map_heap_memory = NULL; ++} ++ + void resource_cleanup(struct wined3d_resource *resource) + { + const struct wined3d *d3d = resource->device->wined3d; +@@ -169,11 +178,7 @@ void resource_cleanup(struct wined3d_resource *resource) + adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size); + } + +- if (resource->buffer) +- wined3d_resource_free_bo(resource); +- +- wined3d_resource_free_sysmem(resource); +- resource->map_heap_memory = NULL; ++ wined3d_cs_emit_resource_cleanup(resource->device->cs, resource); + + device_resource_released(resource->device, resource); + } +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 1d777e2..4a1cf30 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -101,9 +101,12 @@ static void surface_cleanup(struct wined3d_surface *surface) + + void wined3d_surface_destroy(struct wined3d_surface *surface) + { ++ struct wined3d_device *device = surface->resource.device; + TRACE("surface %p.\n", surface); + + surface_cleanup(surface); ++ if (wined3d_settings.cs_multithreaded) ++ device->cs->ops->finish(device->cs); + surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent); + HeapFree(GetProcessHeap(), 0, surface); + } +@@ -5321,6 +5324,8 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text + { + ERR("Private setup failed, hr %#x.\n", hr); + surface_cleanup(surface); ++ if (wined3d_settings.cs_multithreaded) ++ surface->resource.device->cs->ops->finish(surface->resource.device->cs); + return hr; + } + +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index ea8589a..f7988e5 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -74,6 +74,8 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc + { + ERR("Failed to allocate sub-resource array.\n"); + resource_cleanup(&texture->resource); ++ if (wined3d_settings.cs_multithreaded) ++ texture->resource.device->cs->ops->finish(texture->resource.device->cs); + return E_OUTOFMEMORY; + } + +@@ -153,6 +155,8 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture) + wined3d_texture_unload_gl_texture(texture); + HeapFree(GetProcessHeap(), 0, texture->sub_resources); + resource_cleanup(&texture->resource); ++ if (wined3d_settings.cs_multithreaded) ++ texture->resource.device->cs->ops->finish(texture->resource.device->cs); + } + + void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) +diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c +index 34b72d1..218118d 100644 +--- a/dlls/wined3d/volume.c ++++ b/dlls/wined3d/volume.c +@@ -291,9 +291,12 @@ void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context * + + void wined3d_volume_destroy(struct wined3d_volume *volume) + { ++ struct wined3d_device *device = volume->resource.device; + TRACE("volume %p.\n", volume); + + resource_cleanup(&volume->resource); ++ if (wined3d_settings.cs_multithreaded) ++ device->cs->ops->finish(device->cs); + volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent); + HeapFree(GetProcessHeap(), 0, volume); + } +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 74e059c..f4c269c 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2163,6 +2163,7 @@ void wined3d_resource_changed(struct wined3d_resource *resource, + struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) DECLSPEC_HIDDEN; + BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, + const struct wined3d_box *box) DECLSPEC_HIDDEN; ++void wined3d_resource_cleanup_cs(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, +@@ -2706,6 +2707,8 @@ void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, + struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; + void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader *shader) DECLSPEC_HIDDEN; + void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, ++ struct wined3d_resource *resource) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0126-wined3d-Destroy-vertex-declarations-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0126-wined3d-Destroy-vertex-declarations-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0126-wined3d-Destroy-vertex-declarations-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0126-wined3d-Destroy-vertex-declarations-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -From a26808a39c226fc0f168336becc97ed512029d52 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 31 Jul 2013 23:06:27 +0200 -Subject: wined3d: Destroy vertex declarations through the CS - ---- - dlls/wined3d/cs.c | 29 +++++++++++++++++++++++++++++ - dlls/wined3d/vertexdeclaration.c | 15 ++++++++------- - dlls/wined3d/wined3d_private.h | 4 ++++ - 3 files changed, 41 insertions(+), 7 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 8e48c55..38063d7 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -79,6 +79,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_UPDATE_TEXTURE, - WINED3D_CS_OP_EVICT_RESOURCE, - WINED3D_CS_OP_VIEW_DESTROY, -+ WINED3D_CS_OP_VDECL_DESTROY, - WINED3D_CS_OP_STOP, - }; - -@@ -456,6 +457,12 @@ struct wined3d_cs_view_destroy - struct wined3d_rendertarget_view *view; - }; - -+struct wined3d_cs_vertex_declaration_destroy -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_vertex_declaration *declaration; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2251,6 +2258,27 @@ void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_renderta - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_vertex_declaration_destroy(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_vertex_declaration_destroy *op = data; -+ -+ wined3d_vertex_declaration_destroy(op->declaration); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, -+ struct wined3d_vertex_declaration *declaration) -+{ -+ struct wined3d_cs_vertex_declaration_destroy *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_VDECL_DESTROY; -+ op->declaration = declaration; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2308,6 +2336,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, - /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, - /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, -+ /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c -index 3f4d5e4..fc7a110 100644 ---- a/dlls/wined3d/vertexdeclaration.c -+++ b/dlls/wined3d/vertexdeclaration.c -@@ -48,6 +48,12 @@ ULONG CDECL wined3d_vertex_declaration_incref(struct wined3d_vertex_declaration - return refcount; - } - -+void wined3d_vertex_declaration_destroy(struct wined3d_vertex_declaration *declaration) -+{ -+ HeapFree(GetProcessHeap(), 0, declaration->elements); -+ HeapFree(GetProcessHeap(), 0, declaration); -+} -+ - ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration *declaration) - { - ULONG refcount = InterlockedDecrement(&declaration->ref); -@@ -56,14 +62,9 @@ ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration - - if (!refcount) - { -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- declaration->device->cs->ops->finish(declaration->device->cs); -- } -- HeapFree(GetProcessHeap(), 0, declaration->elements); -+ const struct wined3d_device *device = declaration->device; - declaration->parent_ops->wined3d_object_destroyed(declaration->parent); -- HeapFree(GetProcessHeap(), 0, declaration); -+ wined3d_cs_emit_vertex_declaration_destroy(device->cs, declaration); - } - - return refcount; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 7d68448..5d3393c 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2499,6 +2499,8 @@ struct wined3d_vertex_declaration - BOOL half_float_conv_needed; - }; - -+void wined3d_vertex_declaration_destroy(struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; -+ - struct wined3d_saved_states - { - DWORD transform[(HIGHEST_TRANSFORMSTATE >> 5) + 1]; -@@ -2700,6 +2702,8 @@ void wined3d_cs_emit_buffer_invalidate_bo_range(struct wined3d_cs *cs, - struct wined3d_buffer *buffer, UINT offset, UINT size) DECLSPEC_HIDDEN; - void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; - void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, -+ struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0127-wined3d-Clean-up-buffer-resource-data-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0127-wined3d-Clean-up-buffer-resource-data-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0127-wined3d-Clean-up-buffer-resource-data-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0127-wined3d-Clean-up-buffer-resource-data-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,156 @@ +From 1ddba156e6aa9f96e9e05b18b1324183884a2596 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 2 Oct 2013 22:50:08 +0200 +Subject: wined3d: Clean up buffer resource data through the CS. + +--- + dlls/wined3d/buffer.c | 39 ++++++++++++++++++++------------------- + dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 50 insertions(+), 19 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index e248ca9..12a1ca0 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -545,37 +545,38 @@ static void buffer_unload(struct wined3d_resource *resource) + resource_unload(resource); + } + ++void wined3d_buffer_cleanup_cs(struct wined3d_buffer *buffer) ++{ ++ struct wined3d_context *context; ++ struct wined3d_device *device = buffer->resource.device; ++ ++ if (buffer->buffer_object) ++ { ++ context = context_acquire(device, NULL); ++ delete_gl_buffer(buffer, context->gl_info); ++ context_release(context); ++ ++ HeapFree(GetProcessHeap(), 0, buffer->conversion_map); ++ } ++ ++ HeapFree(GetProcessHeap(), 0, buffer->maps); ++ HeapFree(GetProcessHeap(), 0, buffer); ++} ++ + ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) + { + ULONG refcount = InterlockedDecrement(&buffer->resource.ref); +- struct wined3d_context *context; + + TRACE("%p decreasing refcount to %u.\n", buffer, refcount); + + if (!refcount) + { +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- buffer->resource.device->cs->ops->finish(buffer->resource.device->cs); +- } +- +- if (buffer->buffer_object) +- { +- context = context_acquire(buffer->resource.device, NULL); +- delete_gl_buffer(buffer, context->gl_info); +- context_release(context); +- +- HeapFree(GetProcessHeap(), 0, buffer->conversion_map); +- } ++ struct wined3d_device *device = buffer->resource.device; + + resource_cleanup(&buffer->resource); +- if (wined3d_settings.cs_multithreaded) +- buffer->resource.device->cs->ops->finish(buffer->resource.device->cs); + + buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent); +- HeapFree(GetProcessHeap(), 0, buffer->maps); +- HeapFree(GetProcessHeap(), 0, buffer); ++ wined3d_cs_emit_buffer_cleanup(device->cs, buffer); + } + + return refcount; +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 4a42ca3..f64c43d 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -84,6 +84,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_SHADER_CLEANUP, + WINED3D_CS_OP_CREATE_VBO, + WINED3D_CS_OP_RESOURCE_CLEANUP, ++ WINED3D_CS_OP_BUFFER_CLEANUP, + WINED3D_CS_OP_STOP, + }; + +@@ -494,6 +495,12 @@ struct wined3d_cs_resource_cleanup + struct wined3d_resource *resource; + }; + ++struct wined3d_cs_buffer_cleanup ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_buffer *buffer; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2479,6 +2486,26 @@ void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, struct wined3d_reso + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_buffer_cleanup(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_buffer_cleanup *op = data; ++ ++ wined3d_buffer_cleanup_cs(op->buffer); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) ++{ ++ struct wined3d_cs_buffer_cleanup *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_BUFFER_CLEANUP; ++ op->buffer = buffer; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2541,6 +2568,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, + /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, + /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, ++ /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index e80859a..83c94c5 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2826,6 +2826,7 @@ void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader + void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; + void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, + struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +@@ -2916,6 +2917,7 @@ void buffer_invalidate_bo_range(struct wined3d_buffer *This, UINT offset, UINT s + void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) DECLSPEC_HIDDEN; + void buffer_create_buffer_object(struct wined3d_buffer *This, + struct wined3d_context *context) DECLSPEC_HIDDEN; ++void wined3d_buffer_cleanup_cs(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; + HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, + const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN; + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0127-wined3d-Destroy-shaders-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0127-wined3d-Destroy-shaders-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0127-wined3d-Destroy-shaders-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0127-wined3d-Destroy-shaders-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -From c75e1fc10eb6a040ef2736cee8262e4200366905 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 31 Jul 2013 23:18:28 +0200 -Subject: wined3d: Destroy shaders through the CS - ---- - dlls/wined3d/cs.c | 29 +++++++++++++++++++++++++++++ - dlls/wined3d/shader.c | 12 ++++-------- - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 35 insertions(+), 8 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index f088200..c745460 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -81,6 +81,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_EVICT_RESOURCE, - WINED3D_CS_OP_VIEW_DESTROY, - WINED3D_CS_OP_VDECL_DESTROY, -+ WINED3D_CS_OP_SHADER_CLEANUP, - WINED3D_CS_OP_STOP, - }; - -@@ -473,6 +474,12 @@ struct wined3d_cs_vertex_declaration_destroy - struct wined3d_vertex_declaration *declaration; - }; - -+struct wined3d_cs_shader_cleanup -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_shader *shader; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2392,6 +2399,27 @@ void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_shader_cleanup(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_shader_cleanup *op = data; -+ -+ shader_cleanup(op->shader); -+ HeapFree(GetProcessHeap(), 0, op->shader); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader *shader) -+{ -+ struct wined3d_cs_shader_cleanup *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SHADER_CLEANUP; -+ op->shader = shader; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2451,6 +2479,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, - /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, - /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, -+ /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c -index ec2a269..04e217e 100644 ---- a/dlls/wined3d/shader.c -+++ b/dlls/wined3d/shader.c -@@ -1859,7 +1859,7 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe - } - } - --static void shader_cleanup(struct wined3d_shader *shader) -+void shader_cleanup(struct wined3d_shader *shader) - { - HeapFree(GetProcessHeap(), 0, shader->output_signature.elements); - HeapFree(GetProcessHeap(), 0, shader->input_signature.elements); -@@ -2115,14 +2115,10 @@ ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader) - - if (!refcount) - { -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- shader->device->cs->ops->finish(shader->device->cs); -- } -- shader_cleanup(shader); -+ const struct wined3d_device *device = shader->device; -+ - shader->parent_ops->wined3d_object_destroyed(shader->parent); -- HeapFree(GetProcessHeap(), 0, shader); -+ wined3d_cs_emit_shader_cleanup(device->cs, shader); - } - - return refcount; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index a2f2044..545c97e 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2751,6 +2751,7 @@ void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer - void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; - void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, - struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader *shader) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d -@@ -3153,6 +3154,7 @@ unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_map - void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, - const struct wined3d_shader_reg_maps *reg_maps, const DWORD *byte_code, void *backend_ctx) DECLSPEC_HIDDEN; - BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage) DECLSPEC_HIDDEN; -+void shader_cleanup(struct wined3d_shader *shader) DECLSPEC_HIDDEN; - - static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg) - { --- -2.3.5 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0128-wined3d-Clean-up-volume-resource-data-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0128-wined3d-Clean-up-volume-resource-data-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0128-wined3d-Clean-up-volume-resource-data-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0128-wined3d-Clean-up-volume-resource-data-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,122 @@ +From 40087b5024636170ee3bc5c4ed3436898a97e21c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 2 Oct 2013 22:54:57 +0200 +Subject: wined3d: Clean up volume resource data through the CS. + +--- + dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ + dlls/wined3d/volume.c | 9 ++++++--- + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 36 insertions(+), 3 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 54b6d1a..18b556d 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -85,6 +85,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_CREATE_VBO, + WINED3D_CS_OP_RESOURCE_CLEANUP, + WINED3D_CS_OP_BUFFER_CLEANUP, ++ WINED3D_CS_OP_VOLUME_CLEANUP, + WINED3D_CS_OP_STOP, + }; + +@@ -501,6 +502,12 @@ struct wined3d_cs_buffer_cleanup + struct wined3d_buffer *buffer; + }; + ++struct wined3d_cs_volume_cleanup ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_volume *volume; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2506,6 +2513,26 @@ void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_volume_cleanup(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_volume_cleanup *op = data; ++ ++ wined3d_volume_cleanup_cs(op->volume); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) ++{ ++ struct wined3d_cs_volume_cleanup *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_VOLUME_CLEANUP; ++ op->volume = volume; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2569,6 +2596,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, + /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, + /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, ++ /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c +index 15c80ce..eb0341a 100644 +--- a/dlls/wined3d/volume.c ++++ b/dlls/wined3d/volume.c +@@ -313,10 +313,8 @@ void wined3d_volume_destroy(struct wined3d_volume *volume) + TRACE("volume %p.\n", volume); + + resource_cleanup(&volume->resource); +- if (wined3d_settings.cs_multithreaded) +- device->cs->ops->finish(device->cs); + volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent); +- HeapFree(GetProcessHeap(), 0, volume); ++ wined3d_cs_emit_volume_cleanup(device->cs, volume); + } + + static void volume_unload(struct wined3d_resource *resource) +@@ -425,6 +423,11 @@ static ULONG volume_resource_incref(struct wined3d_resource *resource) + return wined3d_texture_incref(volume->container); + } + ++void wined3d_volume_cleanup_cs(struct wined3d_volume *volume) ++{ ++ HeapFree(GetProcessHeap(), 0, volume); ++} ++ + static ULONG volume_resource_decref(struct wined3d_resource *resource) + { + struct wined3d_volume *volume = volume_from_resource(resource); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index f4cc159..04a403a 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2435,6 +2435,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, + HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) DECLSPEC_HIDDEN; + void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, + const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; ++void wined3d_volume_cleanup_cs(struct wined3d_volume *volume) DECLSPEC_HIDDEN; + + struct wined3d_surface_dib + { +@@ -2809,6 +2810,7 @@ void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *bu + void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, + struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.6.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0128-wined3d-Create-VBOs-through-the-command-stream.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0128-wined3d-Create-VBOs-through-the-command-stream.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0128-wined3d-Create-VBOs-through-the-command-stream.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0128-wined3d-Create-VBOs-through-the-command-stream.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,133 +0,0 @@ -From 60ebba02de794f88fea7b31406493de579ce01e3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 2 Oct 2013 21:47:08 +0200 -Subject: wined3d: Create VBOs through the command stream. - -A stop-gap solution to make fglrx happier until buffers are updated. ---- - dlls/wined3d/buffer.c | 8 ++------ - dlls/wined3d/cs.c | 32 ++++++++++++++++++++++++++++++++ - dlls/wined3d/wined3d_private.h | 3 +++ - 3 files changed, 37 insertions(+), 6 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 5ebe487..7c3dc17 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -117,7 +117,7 @@ static void delete_gl_buffer(struct wined3d_buffer *This, const struct wined3d_g - } - - /* Context activation is done by the caller. */ --static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) -+void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) - { - GLenum gl_usage = GL_STATIC_DRAW_ARB; - GLenum error; -@@ -185,8 +185,6 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wine - ERR("glBufferData failed with error %s (%#x)\n", debug_glerror(error), error); - goto fail; - } -- if (wined3d_settings.strict_draw_ordering || wined3d_settings.cs_multithreaded) -- gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - This->buffer_object_usage = gl_usage; - -@@ -933,9 +931,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - * on buffer creation won't work either. */ - if (buffer->flags & WINED3D_BUFFER_CREATEBO) - { -- context = context_acquire(device, NULL); -- buffer_create_buffer_object(buffer, context); -- context_release(context); -+ wined3d_cs_emit_create_vbo(device->cs, buffer); - buffer->flags &= ~WINED3D_BUFFER_CREATEBO; - } - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 21d5b74..c00d1d3 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -81,6 +81,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_VIEW_DESTROY, - WINED3D_CS_OP_VDECL_DESTROY, - WINED3D_CS_OP_SHADER_CLEANUP, -+ WINED3D_CS_OP_CREATE_VBO, - WINED3D_CS_OP_STOP, - }; - -@@ -470,6 +471,12 @@ struct wined3d_cs_shader_cleanup - struct wined3d_shader *shader; - }; - -+struct wined3d_cs_create_vbo -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_buffer *buffer; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2307,6 +2314,30 @@ void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_create_vbo(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_create_vbo *op = data; -+ struct wined3d_context *context = context_acquire(cs->device, NULL); -+ -+ buffer_create_buffer_object(op->buffer, context); -+ -+ context_release(context); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *buffer) -+{ -+ struct wined3d_cs_create_vbo *op; -+ -+ op = cs->ops->require_space_prio(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_CREATE_VBO; -+ op->buffer = buffer; -+ -+ cs->ops->submit_prio(cs, sizeof(*op)); -+ cs->ops->finish_prio(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2366,6 +2397,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, - /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, - /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, -+ /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 2cdc6e9..63b8ece 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2722,6 +2722,7 @@ void wined3d_cs_emit_view_destroy(struct wined3d_cs *cs, struct wined3d_renderta - void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, - struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; - void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader *shader) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d -@@ -2810,6 +2811,8 @@ void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_conte - const struct wined3d_state *state) DECLSPEC_HIDDEN; - void buffer_invalidate_bo_range(struct wined3d_buffer *This, UINT offset, UINT size) DECLSPEC_HIDDEN; - void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) DECLSPEC_HIDDEN; -+void buffer_create_buffer_object(struct wined3d_buffer *This, -+ struct wined3d_context *context) DECLSPEC_HIDDEN; - - struct wined3d_rendertarget_view - { --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0129-wined3d-Clean-up-resource-data-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0129-wined3d-Clean-up-resource-data-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0129-wined3d-Clean-up-resource-data-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0129-wined3d-Clean-up-resource-data-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,211 +0,0 @@ -From 9109cd39e2867e3e9061d1720bde4598111b3d3b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 2 Oct 2013 22:38:51 +0200 -Subject: wined3d: Clean up resource data through the CS. - ---- - dlls/wined3d/buffer.c | 3 +++ - dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ - dlls/wined3d/resource.c | 15 ++++++++++----- - dlls/wined3d/surface.c | 5 +++++ - dlls/wined3d/texture.c | 4 ++++ - dlls/wined3d/volume.c | 3 +++ - dlls/wined3d/wined3d_private.h | 3 +++ - 7 files changed, 56 insertions(+), 5 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index fc65d3a..d968dcb 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -570,6 +570,9 @@ ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) - } - - resource_cleanup(&buffer->resource); -+ if (wined3d_settings.cs_multithreaded) -+ buffer->resource.device->cs->ops->finish(buffer->resource.device->cs); -+ - buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent); - HeapFree(GetProcessHeap(), 0, buffer->maps); - HeapFree(GetProcessHeap(), 0, buffer); -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index c00d1d3..6edd5e3 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -82,6 +82,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_VDECL_DESTROY, - WINED3D_CS_OP_SHADER_CLEANUP, - WINED3D_CS_OP_CREATE_VBO, -+ WINED3D_CS_OP_RESOURCE_CLEANUP, - WINED3D_CS_OP_STOP, - }; - -@@ -477,6 +478,12 @@ struct wined3d_cs_create_vbo - struct wined3d_buffer *buffer; - }; - -+struct wined3d_cs_resource_cleanup -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_resource *resource; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2338,6 +2345,26 @@ void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *bu - cs->ops->finish_prio(cs); - } - -+static UINT wined3d_cs_exec_resource_cleanup(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_resource_cleanup *op = data; -+ -+ wined3d_resource_cleanup_cs(op->resource); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, struct wined3d_resource *resource) -+{ -+ struct wined3d_cs_resource_cleanup *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_RESOURCE_CLEANUP; -+ op->resource = resource; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2398,6 +2425,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, - /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, - /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, -+ /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index ef0b213..dd21986 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -157,6 +157,15 @@ void wined3d_resource_free_bo(struct wined3d_resource *resource) - context_release(context); - } - -+void wined3d_resource_cleanup_cs(struct wined3d_resource *resource) -+{ -+ if (resource->buffer) -+ wined3d_resource_free_bo(resource); -+ -+ wined3d_resource_free_sysmem(resource); -+ resource->map_heap_memory = NULL; -+} -+ - void resource_cleanup(struct wined3d_resource *resource) - { - const struct wined3d *d3d = resource->device->wined3d; -@@ -169,11 +178,7 @@ void resource_cleanup(struct wined3d_resource *resource) - adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size); - } - -- if (resource->buffer) -- wined3d_resource_free_bo(resource); -- -- wined3d_resource_free_sysmem(resource); -- resource->map_heap_memory = NULL; -+ wined3d_cs_emit_resource_cleanup(resource->device->cs, resource); - - device_resource_released(resource->device, resource); - } -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 1d777e2..4a1cf30 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -101,9 +101,12 @@ static void surface_cleanup(struct wined3d_surface *surface) - - void wined3d_surface_destroy(struct wined3d_surface *surface) - { -+ struct wined3d_device *device = surface->resource.device; - TRACE("surface %p.\n", surface); - - surface_cleanup(surface); -+ if (wined3d_settings.cs_multithreaded) -+ device->cs->ops->finish(device->cs); - surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent); - HeapFree(GetProcessHeap(), 0, surface); - } -@@ -5321,6 +5324,8 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text - { - ERR("Private setup failed, hr %#x.\n", hr); - surface_cleanup(surface); -+ if (wined3d_settings.cs_multithreaded) -+ surface->resource.device->cs->ops->finish(surface->resource.device->cs); - return hr; - } - -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index ea8589a..f7988e5 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -74,6 +74,8 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc - { - ERR("Failed to allocate sub-resource array.\n"); - resource_cleanup(&texture->resource); -+ if (wined3d_settings.cs_multithreaded) -+ texture->resource.device->cs->ops->finish(texture->resource.device->cs); - return E_OUTOFMEMORY; - } - -@@ -153,6 +155,8 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture) - wined3d_texture_unload_gl_texture(texture); - HeapFree(GetProcessHeap(), 0, texture->sub_resources); - resource_cleanup(&texture->resource); -+ if (wined3d_settings.cs_multithreaded) -+ texture->resource.device->cs->ops->finish(texture->resource.device->cs); - } - - void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) -diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index 34b72d1..218118d 100644 ---- a/dlls/wined3d/volume.c -+++ b/dlls/wined3d/volume.c -@@ -291,9 +291,12 @@ void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context * - - void wined3d_volume_destroy(struct wined3d_volume *volume) - { -+ struct wined3d_device *device = volume->resource.device; - TRACE("volume %p.\n", volume); - - resource_cleanup(&volume->resource); -+ if (wined3d_settings.cs_multithreaded) -+ device->cs->ops->finish(device->cs); - volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent); - HeapFree(GetProcessHeap(), 0, volume); - } -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 74e059c..f4c269c 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2163,6 +2163,7 @@ void wined3d_resource_changed(struct wined3d_resource *resource, - struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) DECLSPEC_HIDDEN; - BOOL wined3d_resource_check_block_align(const struct wined3d_resource *resource, - const struct wined3d_box *box) DECLSPEC_HIDDEN; -+void wined3d_resource_cleanup_cs(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_free_bo(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - BYTE *wined3d_resource_get_map_ptr(const struct wined3d_resource *resource, -@@ -2706,6 +2707,8 @@ void wined3d_cs_emit_vertex_declaration_destroy(struct wined3d_cs *cs, - struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; - void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader *shader) DECLSPEC_HIDDEN; - void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, -+ struct wined3d_resource *resource) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0129-wined3d-Clean-up-surfaces-through-the-cs.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0129-wined3d-Clean-up-surfaces-through-the-cs.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0129-wined3d-Clean-up-surfaces-through-the-cs.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0129-wined3d-Clean-up-surfaces-through-the-cs.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,178 @@ +From 0fd12af6067cbe8aa8800098a602d808978d14ac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sun, 6 Oct 2013 16:12:24 +0200 +Subject: wined3d: Clean up surfaces through the cs. + +--- + dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ + dlls/wined3d/surface.c | 37 ++++++++++++++++--------------------- + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 46 insertions(+), 21 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 18b556d..91b76f5 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -86,6 +86,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_RESOURCE_CLEANUP, + WINED3D_CS_OP_BUFFER_CLEANUP, + WINED3D_CS_OP_VOLUME_CLEANUP, ++ WINED3D_CS_OP_SURFACE_CLEANUP, + WINED3D_CS_OP_STOP, + }; + +@@ -508,6 +509,12 @@ struct wined3d_cs_volume_cleanup + struct wined3d_volume *volume; + }; + ++struct wined3d_cs_surface_cleanup ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_surface *surface; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2533,6 +2540,26 @@ void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_surface_cleanup(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_surface_cleanup *op = data; ++ ++ wined3d_surface_cleanup_cs(op->surface); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) ++{ ++ struct wined3d_cs_surface_cleanup *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SURFACE_CLEANUP; ++ op->surface = surface; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2597,6 +2624,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, + /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, + /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, ++ /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index c607072..e0164f1 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -36,20 +36,10 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); + + #define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */ + +-static void surface_cleanup(struct wined3d_surface *surface) +-{ +- struct wined3d_surface *overlay, *cur; +- +- TRACE("surface %p.\n", surface); +- +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- surface->resource.device->cs->ops->finish(surface->resource.device->cs); +- } + +- if (surface->resource.buffer || surface->rb_multisample +- || surface->rb_resolved || !list_empty(&surface->renderbuffers)) ++void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) ++{ ++ if (surface->rb_multisample || surface->rb_resolved || !list_empty(&surface->renderbuffers)) + { + struct wined3d_renderbuffer_entry *entry, *entry2; + const struct wined3d_gl_info *gl_info; +@@ -87,6 +77,16 @@ static void surface_cleanup(struct wined3d_surface *surface) + surface->resource.bitmap_data = NULL; + } + ++ TRACE("Destroyed surface %p.\n", surface); ++ HeapFree(GetProcessHeap(), 0, surface); ++} ++ ++static void surface_cleanup(struct wined3d_surface *surface) ++{ ++ struct wined3d_surface *overlay, *cur; ++ ++ TRACE("surface %p.\n", surface); ++ + if (surface->overlay_dest) + list_remove(&surface->overlay_entry); + +@@ -97,18 +97,15 @@ static void surface_cleanup(struct wined3d_surface *surface) + } + + resource_cleanup(&surface->resource); ++ wined3d_cs_emit_surface_cleanup(surface->resource.device->cs, surface); + } + + void wined3d_surface_destroy(struct wined3d_surface *surface) + { +- struct wined3d_device *device = surface->resource.device; + TRACE("surface %p.\n", surface); + +- surface_cleanup(surface); +- if (wined3d_settings.cs_multithreaded) +- device->cs->ops->finish(device->cs); + surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent); +- HeapFree(GetProcessHeap(), 0, surface); ++ surface_cleanup(surface); + } + + void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context, +@@ -5360,8 +5357,6 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text + { + ERR("Private setup failed, hr %#x.\n", hr); + surface_cleanup(surface); +- if (wined3d_settings.cs_multithreaded) +- surface->resource.device->cs->ops->finish(surface->resource.device->cs); + return hr; + } + +@@ -5404,7 +5399,7 @@ HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct w + if (FAILED(hr = surface_init(object, container, desc, target, level, layer, flags))) + { + WARN("Failed to initialize surface, returning %#x.\n", hr); +- HeapFree(GetProcessHeap(), 0, object); ++ /* The command stream takes care of freeing the memory. */ + return hr; + } + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 96102af..cbc3fa9 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2537,6 +2537,7 @@ void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect_ + struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, + const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; + BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) DECLSPEC_HIDDEN; ++void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; + + void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, + const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; +@@ -2800,6 +2801,7 @@ void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, + struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; + void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.6.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0130-wined3d-Clean-up-buffer-resource-data-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0130-wined3d-Clean-up-buffer-resource-data-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0130-wined3d-Clean-up-buffer-resource-data-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0130-wined3d-Clean-up-buffer-resource-data-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -From 6462e66d6d2229b1755e7689e2b01eee97696676 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 2 Oct 2013 22:50:08 +0200 -Subject: wined3d: Clean up buffer resource data through the CS. - ---- - dlls/wined3d/buffer.c | 39 ++++++++++++++++++++------------------- - dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 50 insertions(+), 19 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index d968dcb..15ed760 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -545,37 +545,38 @@ static void buffer_unload(struct wined3d_resource *resource) - resource_unload(resource); - } - -+void wined3d_buffer_cleanup_cs(struct wined3d_buffer *buffer) -+{ -+ struct wined3d_context *context; -+ struct wined3d_device *device = buffer->resource.device; -+ -+ if (buffer->buffer_object) -+ { -+ context = context_acquire(device, NULL); -+ delete_gl_buffer(buffer, context->gl_info); -+ context_release(context); -+ -+ HeapFree(GetProcessHeap(), 0, buffer->conversion_map); -+ } -+ -+ HeapFree(GetProcessHeap(), 0, buffer->maps); -+ HeapFree(GetProcessHeap(), 0, buffer); -+} -+ - ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) - { - ULONG refcount = InterlockedDecrement(&buffer->resource.ref); -- struct wined3d_context *context; - - TRACE("%p decreasing refcount to %u.\n", buffer, refcount); - - if (!refcount) - { -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- buffer->resource.device->cs->ops->finish(buffer->resource.device->cs); -- } -- -- if (buffer->buffer_object) -- { -- context = context_acquire(buffer->resource.device, NULL); -- delete_gl_buffer(buffer, context->gl_info); -- context_release(context); -- -- HeapFree(GetProcessHeap(), 0, buffer->conversion_map); -- } -+ struct wined3d_device *device = buffer->resource.device; - - resource_cleanup(&buffer->resource); -- if (wined3d_settings.cs_multithreaded) -- buffer->resource.device->cs->ops->finish(buffer->resource.device->cs); - - buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent); -- HeapFree(GetProcessHeap(), 0, buffer->maps); -- HeapFree(GetProcessHeap(), 0, buffer); -+ wined3d_cs_emit_buffer_cleanup(device->cs, buffer); - } - - return refcount; -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 6edd5e3..40cd85d 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -83,6 +83,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_SHADER_CLEANUP, - WINED3D_CS_OP_CREATE_VBO, - WINED3D_CS_OP_RESOURCE_CLEANUP, -+ WINED3D_CS_OP_BUFFER_CLEANUP, - WINED3D_CS_OP_STOP, - }; - -@@ -484,6 +485,12 @@ struct wined3d_cs_resource_cleanup - struct wined3d_resource *resource; - }; - -+struct wined3d_cs_buffer_cleanup -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_buffer *buffer; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2365,6 +2372,26 @@ void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, struct wined3d_reso - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_buffer_cleanup(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_buffer_cleanup *op = data; -+ -+ wined3d_buffer_cleanup_cs(op->buffer); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) -+{ -+ struct wined3d_cs_buffer_cleanup *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_BUFFER_CLEANUP; -+ op->buffer = buffer; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2426,6 +2453,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, - /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, - /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, -+ /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index f4c269c..76c0708 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2709,6 +2709,7 @@ void wined3d_cs_emit_shader_cleanup(struct wined3d_cs *cs, struct wined3d_shader - void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; - void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, - struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d -@@ -2799,6 +2800,7 @@ void buffer_invalidate_bo_range(struct wined3d_buffer *This, UINT offset, UINT s - void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) DECLSPEC_HIDDEN; - void buffer_create_buffer_object(struct wined3d_buffer *This, - struct wined3d_context *context) DECLSPEC_HIDDEN; -+void wined3d_buffer_cleanup_cs(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; - - struct wined3d_rendertarget_view - { --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0130-wined3d-Clean-up-texture-resources-through-the-cs.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0130-wined3d-Clean-up-texture-resources-through-the-cs.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0130-wined3d-Clean-up-texture-resources-through-the-cs.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0130-wined3d-Clean-up-texture-resources-through-the-cs.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,245 @@ +From 422533270db1400ad7a8a0d4bfd5fa74ed2f8424 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sun, 6 Oct 2013 16:20:32 +0200 +Subject: wined3d: Clean up texture resources through the cs. + +--- + dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ + dlls/wined3d/texture.c | 33 +++++++++++++++++++++++++-------- + dlls/wined3d/wined3d_private.h | 2 ++ + 3 files changed, 55 insertions(+), 8 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 1c7b3c7..4f7e49f 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -86,6 +86,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_BUFFER_CLEANUP, + WINED3D_CS_OP_VOLUME_CLEANUP, + WINED3D_CS_OP_SURFACE_CLEANUP, ++ WINED3D_CS_OP_TEXTURE_CLEANUP, + WINED3D_CS_OP_STOP, + }; + +@@ -508,6 +509,12 @@ struct wined3d_cs_surface_cleanup + struct wined3d_surface *surface; + }; + ++struct wined3d_cs_texture_cleanup ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_texture *texture; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2530,6 +2537,26 @@ void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surfa + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_texture_cleanup(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_texture_cleanup *op = data; ++ ++ wined3d_texture_cleanup_cs(op->texture); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_texture *texture) ++{ ++ struct wined3d_cs_texture_cleanup *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_TEXTURE_CLEANUP; ++ op->texture = texture; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2594,6 +2621,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, + /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, + /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, ++ /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index 0e9b6ea..18fc976 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -114,17 +114,26 @@ static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture) + resource_unload(&texture->resource); + } + ++void wined3d_texture_cleanup_cs(struct wined3d_texture *texture) ++{ ++ wined3d_texture_unload_gl_texture(texture); ++ HeapFree(GetProcessHeap(), 0, texture->sub_resources); ++ HeapFree(GetProcessHeap(), 0, texture); ++} ++ + static void wined3d_texture_cleanup(struct wined3d_texture *texture) + { + UINT sub_count = texture->level_count * texture->layer_count; + UINT i; ++ struct wined3d_device *device = texture->resource.device; + + TRACE("texture %p.\n", texture); + ++ /* Because sub_resource_cleanup interferes with GL resources */ + if (wined3d_settings.cs_multithreaded) + { + FIXME("Waiting for cs.\n"); +- texture->resource.device->cs->ops->finish(texture->resource.device->cs); ++ device->cs->ops->finish(device->cs); + } + + for (i = 0; i < sub_count; ++i) +@@ -135,11 +144,8 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture) + texture->texture_ops->texture_sub_resource_cleanup(sub_resource); + } + +- wined3d_texture_unload_gl_texture(texture); +- HeapFree(GetProcessHeap(), 0, texture->sub_resources); + resource_cleanup(&texture->resource); +- if (wined3d_settings.cs_multithreaded) +- texture->resource.device->cs->ops->finish(texture->resource.device->cs); ++ wined3d_cs_emit_texture_cleanup(device->cs, texture); + } + + void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) +@@ -423,9 +429,10 @@ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) + + if (!refcount) + { ++ void *parent = texture->resource.parent; ++ const struct wined3d_parent_ops *parent_ops = texture->resource.parent_ops; + wined3d_texture_cleanup(texture); +- texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent); +- HeapFree(GetProcessHeap(), 0, texture); ++ parent_ops->wined3d_object_destroyed(parent); + } + + return refcount; +@@ -990,6 +997,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 + if (WINED3DFMT_UNKNOWN >= desc->format) + { + WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); ++ HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; + } + +@@ -1020,6 +1028,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 + else + { + WARN("Attempted to create a mipmapped/cube NPOT texture without unconditional NPOT support.\n"); ++ HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; + } + } +@@ -1032,12 +1041,14 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 + if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) + { + WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n"); ++ HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; + } + + if (level_count != 1) + { + WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); ++ HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; + } + } +@@ -1046,6 +1057,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 + flags, device, parent, parent_ops, &texture2d_resource_ops))) + { + WARN("Failed to initialize texture, returning %#x.\n", hr); ++ HeapFree(GetProcessHeap(), 0, texture); + return hr; + } + +@@ -1248,12 +1260,14 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct + if (WINED3DFMT_UNKNOWN >= desc->format) + { + WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); ++ HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; + } + + if (!gl_info->supported[EXT_TEXTURE3D]) + { + WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture); ++ HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; + } + +@@ -1263,12 +1277,14 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct + if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) + { + WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); ++ HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; + } + + if (levels != 1) + { + WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); ++ HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; + } + } +@@ -1296,6 +1312,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct + { + WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n", + desc->width, desc->height, desc->depth); ++ HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; + } + } +@@ -1305,6 +1322,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct + 0, device, parent, parent_ops, &texture3d_resource_ops))) + { + WARN("Failed to initialize texture, returning %#x.\n", hr); ++ HeapFree(GetProcessHeap(), 0, texture); + return hr; + } + +@@ -1424,7 +1442,6 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct + if (FAILED(hr)) + { + WARN("Failed to initialize texture, returning %#x.\n", hr); +- HeapFree(GetProcessHeap(), 0, object); + return hr; + } + +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 7a1b9aa..2da4a16 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2484,6 +2484,7 @@ static inline struct gl_texture *wined3d_texture_get_gl_texture(struct wined3d_t + + void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, + const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; ++void wined3d_texture_cleanup_cs(struct wined3d_texture *texture) DECLSPEC_HIDDEN; + void wined3d_texture_bind(struct wined3d_texture *texture, + struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; + void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, +@@ -2917,6 +2918,7 @@ void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, + void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; + void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) DECLSPEC_HIDDEN; + void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0131-wined3d-Clean-up-volume-resource-data-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0131-wined3d-Clean-up-volume-resource-data-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0131-wined3d-Clean-up-volume-resource-data-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0131-wined3d-Clean-up-volume-resource-data-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,122 +0,0 @@ -From 40087b5024636170ee3bc5c4ed3436898a97e21c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 2 Oct 2013 22:54:57 +0200 -Subject: wined3d: Clean up volume resource data through the CS. - ---- - dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ - dlls/wined3d/volume.c | 9 ++++++--- - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 36 insertions(+), 3 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 54b6d1a..18b556d 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -85,6 +85,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_CREATE_VBO, - WINED3D_CS_OP_RESOURCE_CLEANUP, - WINED3D_CS_OP_BUFFER_CLEANUP, -+ WINED3D_CS_OP_VOLUME_CLEANUP, - WINED3D_CS_OP_STOP, - }; - -@@ -501,6 +502,12 @@ struct wined3d_cs_buffer_cleanup - struct wined3d_buffer *buffer; - }; - -+struct wined3d_cs_volume_cleanup -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_volume *volume; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2506,6 +2513,26 @@ void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_volume_cleanup(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_volume_cleanup *op = data; -+ -+ wined3d_volume_cleanup_cs(op->volume); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) -+{ -+ struct wined3d_cs_volume_cleanup *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_VOLUME_CLEANUP; -+ op->volume = volume; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2569,6 +2596,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, - /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, - /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, -+ /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c -index 15c80ce..eb0341a 100644 ---- a/dlls/wined3d/volume.c -+++ b/dlls/wined3d/volume.c -@@ -313,10 +313,8 @@ void wined3d_volume_destroy(struct wined3d_volume *volume) - TRACE("volume %p.\n", volume); - - resource_cleanup(&volume->resource); -- if (wined3d_settings.cs_multithreaded) -- device->cs->ops->finish(device->cs); - volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent); -- HeapFree(GetProcessHeap(), 0, volume); -+ wined3d_cs_emit_volume_cleanup(device->cs, volume); - } - - static void volume_unload(struct wined3d_resource *resource) -@@ -425,6 +423,11 @@ static ULONG volume_resource_incref(struct wined3d_resource *resource) - return wined3d_texture_incref(volume->container); - } - -+void wined3d_volume_cleanup_cs(struct wined3d_volume *volume) -+{ -+ HeapFree(GetProcessHeap(), 0, volume); -+} -+ - static ULONG volume_resource_decref(struct wined3d_resource *resource) - { - struct wined3d_volume *volume = volume_from_resource(resource); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index f4cc159..04a403a 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2435,6 +2435,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume, - HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) DECLSPEC_HIDDEN; - void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, - const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; -+void wined3d_volume_cleanup_cs(struct wined3d_volume *volume) DECLSPEC_HIDDEN; - - struct wined3d_surface_dib - { -@@ -2809,6 +2810,7 @@ void wined3d_cs_emit_create_vbo(struct wined3d_cs *cs, struct wined3d_buffer *bu - void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, - struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.6.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0131-wined3d-Unload-resources-through-the-CS-in-uninit_3d.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0131-wined3d-Unload-resources-through-the-CS-in-uninit_3d.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0131-wined3d-Unload-resources-through-the-CS-in-uninit_3d.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0131-wined3d-Unload-resources-through-the-CS-in-uninit_3d.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,29 @@ +From a0e7463e86758e478993d59c339f590283e3532b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 2 Oct 2013 23:28:56 +0200 +Subject: wined3d: Unload resources through the CS in uninit_3d. + +--- + dlls/wined3d/device.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index e0e2c82..1d7d733 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -1066,9 +1066,10 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) + LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) + { + TRACE("Unloading resource %p.\n", resource); +- +- resource->resource_ops->resource_unload(resource); ++ wined3d_cs_emit_evict_resource(device->cs, resource); + } ++ if (wined3d_settings.cs_multithreaded) ++ device->cs->ops->finish(device->cs); + + wine_rb_clear(&device->samplers, device_free_sampler, NULL); + +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0132-wined3d-Clean-up-surfaces-through-the-cs.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0132-wined3d-Clean-up-surfaces-through-the-cs.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0132-wined3d-Clean-up-surfaces-through-the-cs.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0132-wined3d-Clean-up-surfaces-through-the-cs.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ -From 0fd12af6067cbe8aa8800098a602d808978d14ac Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sun, 6 Oct 2013 16:12:24 +0200 -Subject: wined3d: Clean up surfaces through the cs. - ---- - dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ - dlls/wined3d/surface.c | 37 ++++++++++++++++--------------------- - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 46 insertions(+), 21 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 18b556d..91b76f5 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -86,6 +86,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_RESOURCE_CLEANUP, - WINED3D_CS_OP_BUFFER_CLEANUP, - WINED3D_CS_OP_VOLUME_CLEANUP, -+ WINED3D_CS_OP_SURFACE_CLEANUP, - WINED3D_CS_OP_STOP, - }; - -@@ -508,6 +509,12 @@ struct wined3d_cs_volume_cleanup - struct wined3d_volume *volume; - }; - -+struct wined3d_cs_surface_cleanup -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_surface *surface; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2533,6 +2540,26 @@ void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_surface_cleanup(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_surface_cleanup *op = data; -+ -+ wined3d_surface_cleanup_cs(op->surface); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) -+{ -+ struct wined3d_cs_surface_cleanup *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SURFACE_CLEANUP; -+ op->surface = surface; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2597,6 +2624,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, - /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, - /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, -+ /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index c607072..e0164f1 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -36,20 +36,10 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); - - #define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */ - --static void surface_cleanup(struct wined3d_surface *surface) --{ -- struct wined3d_surface *overlay, *cur; -- -- TRACE("surface %p.\n", surface); -- -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- surface->resource.device->cs->ops->finish(surface->resource.device->cs); -- } - -- if (surface->resource.buffer || surface->rb_multisample -- || surface->rb_resolved || !list_empty(&surface->renderbuffers)) -+void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) -+{ -+ if (surface->rb_multisample || surface->rb_resolved || !list_empty(&surface->renderbuffers)) - { - struct wined3d_renderbuffer_entry *entry, *entry2; - const struct wined3d_gl_info *gl_info; -@@ -87,6 +77,16 @@ static void surface_cleanup(struct wined3d_surface *surface) - surface->resource.bitmap_data = NULL; - } - -+ TRACE("Destroyed surface %p.\n", surface); -+ HeapFree(GetProcessHeap(), 0, surface); -+} -+ -+static void surface_cleanup(struct wined3d_surface *surface) -+{ -+ struct wined3d_surface *overlay, *cur; -+ -+ TRACE("surface %p.\n", surface); -+ - if (surface->overlay_dest) - list_remove(&surface->overlay_entry); - -@@ -97,18 +97,15 @@ static void surface_cleanup(struct wined3d_surface *surface) - } - - resource_cleanup(&surface->resource); -+ wined3d_cs_emit_surface_cleanup(surface->resource.device->cs, surface); - } - - void wined3d_surface_destroy(struct wined3d_surface *surface) - { -- struct wined3d_device *device = surface->resource.device; - TRACE("surface %p.\n", surface); - -- surface_cleanup(surface); -- if (wined3d_settings.cs_multithreaded) -- device->cs->ops->finish(device->cs); - surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent); -- HeapFree(GetProcessHeap(), 0, surface); -+ surface_cleanup(surface); - } - - void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context, -@@ -5360,8 +5357,6 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text - { - ERR("Private setup failed, hr %#x.\n", hr); - surface_cleanup(surface); -- if (wined3d_settings.cs_multithreaded) -- surface->resource.device->cs->ops->finish(surface->resource.device->cs); - return hr; - } - -@@ -5404,7 +5399,7 @@ HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct w - if (FAILED(hr = surface_init(object, container, desc, target, level, layer, flags))) - { - WARN("Failed to initialize surface, returning %#x.\n", hr); -- HeapFree(GetProcessHeap(), 0, object); -+ /* The command stream takes care of freeing the memory. */ - return hr; - } - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 96102af..cbc3fa9 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2537,6 +2537,7 @@ void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect_ - struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, - const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; - BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) DECLSPEC_HIDDEN; -+void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; - - void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, - const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -@@ -2800,6 +2801,7 @@ void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, - struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; - void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.6.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0132-wined3d-Unload-resources-through-the-CS-in-device_re.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0132-wined3d-Unload-resources-through-the-CS-in-device_re.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0132-wined3d-Unload-resources-through-the-CS-in-device_re.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0132-wined3d-Unload-resources-through-the-CS-in-device_re.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,44 @@ +From d2b010c4c1c08d71ed6e2e4257db236535c20deb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 2 Oct 2013 23:40:20 +0200 +Subject: wined3d: Unload resources through the CS in device_reset. + +--- + dlls/wined3d/device.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 28819af..2410547 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -4228,21 +4228,23 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d + struct wined3d_context *context; + struct wined3d_shader *shader; + +- context = context_acquire(device, NULL); +- gl_info = context->gl_info; +- + LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) + { + TRACE("Unloading resource %p.\n", resource); + +- resource->resource_ops->resource_unload(resource); ++ wined3d_cs_emit_evict_resource(device->cs, resource); + } ++ if (wined3d_settings.cs_multithreaded) ++ device->cs->ops->finish(device->cs); + + LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry) + { + device->shader_backend->shader_destroy(shader); + } + ++ context = context_acquire(device, NULL); ++ gl_info = context->gl_info; ++ + if (device->depth_blt_texture) + { + gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->depth_blt_texture); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0133-wined3d-Clean-up-texture-resources-through-the-cs.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0133-wined3d-Clean-up-texture-resources-through-the-cs.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0133-wined3d-Clean-up-texture-resources-through-the-cs.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0133-wined3d-Clean-up-texture-resources-through-the-cs.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,284 +0,0 @@ -From 99c21f03b539568231b746938b4b0cb5ba664720 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sun, 6 Oct 2013 16:20:32 +0200 -Subject: wined3d: Clean up texture resources through the cs. - ---- - dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ - dlls/wined3d/texture.c | 38 ++++++++++++++++++++++++++++++-------- - dlls/wined3d/wined3d_private.h | 2 ++ - 3 files changed, 60 insertions(+), 8 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 91b76f5..ba8d19e 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -87,6 +87,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_BUFFER_CLEANUP, - WINED3D_CS_OP_VOLUME_CLEANUP, - WINED3D_CS_OP_SURFACE_CLEANUP, -+ WINED3D_CS_OP_TEXTURE_CLEANUP, - WINED3D_CS_OP_STOP, - }; - -@@ -515,6 +516,12 @@ struct wined3d_cs_surface_cleanup - struct wined3d_surface *surface; - }; - -+struct wined3d_cs_texture_cleanup -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_texture *texture; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2560,6 +2567,26 @@ void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surfa - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_texture_cleanup(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_texture_cleanup *op = data; -+ -+ wined3d_texture_cleanup_cs(op->texture); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_texture *texture) -+{ -+ struct wined3d_cs_texture_cleanup *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_TEXTURE_CLEANUP; -+ op->texture = texture; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2625,6 +2652,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, - /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, - /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, -+ /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 61ef22e..85abaa4 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -114,17 +114,26 @@ static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture) - resource_unload(&texture->resource); - } - -+void wined3d_texture_cleanup_cs(struct wined3d_texture *texture) -+{ -+ wined3d_texture_unload_gl_texture(texture); -+ HeapFree(GetProcessHeap(), 0, texture->sub_resources); -+ HeapFree(GetProcessHeap(), 0, texture); -+} -+ - static void wined3d_texture_cleanup(struct wined3d_texture *texture) - { - UINT sub_count = texture->level_count * texture->layer_count; - UINT i; -+ struct wined3d_device *device = texture->resource.device; - - TRACE("texture %p.\n", texture); - -+ /* Because sub_resource_cleanup interferes with GL resources */ - if (wined3d_settings.cs_multithreaded) - { - FIXME("Waiting for cs.\n"); -- texture->resource.device->cs->ops->finish(texture->resource.device->cs); -+ device->cs->ops->finish(device->cs); - } - - for (i = 0; i < sub_count; ++i) -@@ -135,11 +144,8 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture) - texture->texture_ops->texture_sub_resource_cleanup(sub_resource); - } - -- wined3d_texture_unload_gl_texture(texture); -- HeapFree(GetProcessHeap(), 0, texture->sub_resources); - resource_cleanup(&texture->resource); -- if (wined3d_settings.cs_multithreaded) -- texture->resource.device->cs->ops->finish(texture->resource.device->cs); -+ wined3d_cs_emit_texture_cleanup(device->cs, texture); - } - - void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) -@@ -423,9 +429,10 @@ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) - - if (!refcount) - { -+ void *parent = texture->resource.parent; -+ const struct wined3d_parent_ops *parent_ops = texture->resource.parent_ops; - wined3d_texture_cleanup(texture); -- texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent); -- HeapFree(GetProcessHeap(), 0, texture); -+ parent_ops->wined3d_object_destroyed(parent); - } - - return refcount; -@@ -1028,6 +1035,7 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi - if (WINED3DFMT_UNKNOWN >= desc->format) - { - WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - -@@ -1037,12 +1045,14 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi - if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - - if (levels != 1) - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - } -@@ -1063,6 +1073,7 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi - else - { - WARN("Attempted to create a NPOT cube texture (edge length %u) without GL support.\n", desc->width); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - } -@@ -1072,6 +1083,7 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi - surface_flags, device, parent, parent_ops, &texture2d_resource_ops))) - { - WARN("Failed to initialize texture, returning %#x\n", hr); -+ HeapFree(GetProcessHeap(), 0, texture); - return hr; - } - -@@ -1134,6 +1146,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 - if (WINED3DFMT_UNKNOWN >= desc->format) - { - WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - -@@ -1164,6 +1177,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 - else - { - WARN("Attempted to create a mipmapped NPOT texture without unconditional NPOT support.\n"); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - } -@@ -1176,12 +1190,14 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 - if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n"); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - - if (levels != 1) - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - } -@@ -1190,6 +1206,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 - surface_flags, device, parent, parent_ops, &texture2d_resource_ops))) - { - WARN("Failed to initialize texture, returning %#x.\n", hr); -+ HeapFree(GetProcessHeap(), 0, texture); - return hr; - } - -@@ -1392,12 +1409,14 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct - if (WINED3DFMT_UNKNOWN >= desc->format) - { - WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - - if (!gl_info->supported[EXT_TEXTURE3D]) - { - WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - -@@ -1407,12 +1426,14 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct - if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - - if (levels != 1) - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - } -@@ -1440,6 +1461,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct - { - WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n", - desc->width, desc->height, desc->depth); -+ HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } - } -@@ -1449,6 +1471,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct - 0, device, parent, parent_ops, &texture3d_resource_ops))) - { - WARN("Failed to initialize texture, returning %#x.\n", hr); -+ HeapFree(GetProcessHeap(), 0, texture); - return hr; - } - -@@ -1549,7 +1572,6 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct - if (FAILED(hr)) - { - WARN("Failed to initialize texture, returning %#x.\n", hr); -- HeapFree(GetProcessHeap(), 0, object); - return hr; - } - -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 55b057c..e5baaa4 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2393,6 +2393,7 @@ static inline struct gl_texture *wined3d_texture_get_gl_texture(struct wined3d_t - - void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, - const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; -+void wined3d_texture_cleanup_cs(struct wined3d_texture *texture) DECLSPEC_HIDDEN; - void wined3d_texture_bind(struct wined3d_texture *texture, - struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; - void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, -@@ -2827,6 +2828,7 @@ void wined3d_cs_emit_resource_cleanup(struct wined3d_cs *cs, - void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; - void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) DECLSPEC_HIDDEN; - void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0133-wined3d-Don-t-glFinish-after-a-depth-buffer-blit.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0133-wined3d-Don-t-glFinish-after-a-depth-buffer-blit.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0133-wined3d-Don-t-glFinish-after-a-depth-buffer-blit.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0133-wined3d-Don-t-glFinish-after-a-depth-buffer-blit.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,27 @@ +From 81f901210e683ac2a2193957849497031f424545 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 3 Oct 2013 17:39:08 +0200 +Subject: wined3d: Don't glFinish after a depth buffer blit. + +--- + dlls/wined3d/surface.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 4d8bd1c..3c5489f 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -694,9 +694,7 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, + dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, gl_mask, GL_NEAREST); + checkGLcall("glBlitFramebuffer()"); + +- if (wined3d_settings.cs_multithreaded) +- gl_info->gl_ops.gl.p_glFinish(); +- else if (wined3d_settings.strict_draw_ordering) ++ if (wined3d_settings.strict_draw_ordering) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + + context_release(context); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0134-wined3d-Remove-software-cursor-support.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0134-wined3d-Remove-software-cursor-support.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0134-wined3d-Remove-software-cursor-support.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0134-wined3d-Remove-software-cursor-support.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,180 @@ +From 5630b5ff775157526358b39aa01da3d3d3ed2a5e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 3 Oct 2013 19:23:24 +0200 +Subject: wined3d: Remove software cursor support. + +This has been broken since quite some time and only serves to crash fglrx by acquiring a context +in the main thread. + +FIXME: Make sure wined3d_device_show_cursor returns the correct value if a software cursor is set. +--- + dlls/wined3d/device.c | 64 ------------------------------------------ + dlls/wined3d/swapchain.c | 29 ------------------- + dlls/wined3d/wined3d_private.h | 1 - + 3 files changed, 94 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 7b7d5c9..d521cca 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -1119,8 +1119,6 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) + + if (device->logo_texture) + wined3d_texture_decref(device->logo_texture); +- if (device->cursor_texture) +- wined3d_texture_decref(device->cursor_texture); + + /* Release the buffers (with sanity checks). + * FIXME: Move this move into a separate patch. I think the idea +@@ -4259,48 +4257,6 @@ void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, + wined3d_rendertarget_view_decref(prev); + } + +-static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined3d_device *device, +- struct wined3d_surface *cursor_image) +-{ +- struct wined3d_sub_resource_data data; +- struct wined3d_resource_desc desc; +- struct wined3d_map_desc map_desc; +- struct wined3d_texture *texture; +- HRESULT hr; +- +- if (FAILED(wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_READONLY))) +- { +- ERR("Failed to map source surface.\n"); +- return NULL; +- } +- +- data.data = map_desc.data; +- data.row_pitch = map_desc.row_pitch; +- data.slice_pitch = map_desc.slice_pitch; +- +- desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; +- desc.format = WINED3DFMT_B8G8R8A8_UNORM; +- desc.multisample_type = WINED3D_MULTISAMPLE_NONE; +- desc.multisample_quality = 0; +- desc.usage = WINED3DUSAGE_DYNAMIC; +- desc.pool = WINED3D_POOL_DEFAULT; +- desc.width = cursor_image->resource.width; +- desc.height = cursor_image->resource.height; +- desc.depth = 1; +- desc.size = 0; +- +- hr = wined3d_texture_create(device, &desc, 1, WINED3D_TEXTURE_CREATE_MAPPABLE, +- &data, NULL, &wined3d_null_parent_ops, &texture); +- wined3d_surface_unmap(cursor_image); +- if (FAILED(hr)) +- { +- ERR("Failed to create cursor texture.\n"); +- return NULL; +- } +- +- return texture; +-} +- + HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device, + UINT x_hotspot, UINT y_hotspot, struct wined3d_texture *texture, unsigned int sub_resource_idx) + { +@@ -4319,12 +4275,6 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device + + cursor_image = surface_from_resource(sub_resource); + +- if (device->cursor_texture) +- { +- wined3d_texture_decref(device->cursor_texture); +- device->cursor_texture = NULL; +- } +- + if (cursor_image->resource.format->id != WINED3DFMT_B8G8R8A8_UNORM) + { + WARN("Surface %p has an invalid format %s.\n", +@@ -4352,11 +4302,6 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device + * release it after setting the cursor image. Windows doesn't + * addref the set surface, so we can't do this either without + * creating circular refcount dependencies. */ +- if (!(device->cursor_texture = wined3d_device_create_cursor_texture(device, cursor_image))) +- { +- ERR("Failed to create cursor texture.\n"); +- return WINED3DERR_INVALIDCALL; +- } + + if (cursor_image->resource.width == 32 && cursor_image->resource.height == 32) + { +@@ -4461,10 +4406,6 @@ BOOL CDECL wined3d_device_show_cursor(struct wined3d_device *device, BOOL show) + else + SetCursor(NULL); + } +- else if (device->cursor_texture) +- { +- device->bCursorVisible = show; +- } + + return oldVisible; + } +@@ -4621,11 +4562,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + wined3d_texture_decref(device->logo_texture); + device->logo_texture = NULL; + } +- if (device->cursor_texture) +- { +- wined3d_texture_decref(device->cursor_texture); +- device->cursor_texture = NULL; +- } + } + + if (device->state.fb.render_targets) +diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c +index 6a1363e..5d2b17d 100644 +--- a/dlls/wined3d/swapchain.c ++++ b/dlls/wined3d/swapchain.c +@@ -455,35 +455,6 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT + NULL, WINED3D_TEXF_POINT); + } + +- if (swapchain->device->bCursorVisible && swapchain->device->cursor_texture +- && !swapchain->device->hardwareCursor) +- { +- struct wined3d_surface *cursor = surface_from_resource( +- wined3d_texture_get_sub_resource(swapchain->device->cursor_texture, 0)); +- RECT destRect = +- { +- swapchain->device->xScreenSpace - swapchain->device->xHotSpot, +- swapchain->device->yScreenSpace - swapchain->device->yHotSpot, +- swapchain->device->xScreenSpace + swapchain->device->cursorWidth - swapchain->device->xHotSpot, +- swapchain->device->yScreenSpace + swapchain->device->cursorHeight - swapchain->device->yHotSpot, +- }; +- RECT src_rect = +- { +- 0, 0, +- swapchain->device->cursor_texture->resource.width, +- swapchain->device->cursor_texture->resource.height +- }; +- const RECT clip_rect = {0, 0, back_buffer->resource.width, back_buffer->resource.height}; +- +- TRACE("Rendering the software cursor.\n"); +- +- if (swapchain->desc.windowed) +- MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&destRect, 2); +- if (wined3d_clip_blit(&clip_rect, &destRect, &src_rect)) +- wined3d_surface_blt(back_buffer, &destRect, cursor, &src_rect, WINEDDBLT_ALPHATEST, +- NULL, WINED3D_TEXF_POINT); +- } +- + TRACE("Presenting HDC %p.\n", context->hdc); + + render_to_fbo = swapchain->render_to_fbo; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index d45d35f..6a57cc9 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2165,7 +2165,6 @@ struct wined3d_device + UINT xScreenSpace; + UINT yScreenSpace; + UINT cursorWidth, cursorHeight; +- struct wined3d_texture *cursor_texture; + HCURSOR hardwareCursor; + + /* The Wine logo texture */ +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0134-wined3d-Unload-resources-through-the-CS-in-uninit_3d.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0134-wined3d-Unload-resources-through-the-CS-in-uninit_3d.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0134-wined3d-Unload-resources-through-the-CS-in-uninit_3d.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0134-wined3d-Unload-resources-through-the-CS-in-uninit_3d.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -From a0e7463e86758e478993d59c339f590283e3532b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 2 Oct 2013 23:28:56 +0200 -Subject: wined3d: Unload resources through the CS in uninit_3d. - ---- - dlls/wined3d/device.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index e0e2c82..1d7d733 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -1066,9 +1066,10 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) - LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) - { - TRACE("Unloading resource %p.\n", resource); -- -- resource->resource_ops->resource_unload(resource); -+ wined3d_cs_emit_evict_resource(device->cs, resource); - } -+ if (wined3d_settings.cs_multithreaded) -+ device->cs->ops->finish(device->cs); - - wine_rb_clear(&device->samplers, device_free_sampler, NULL); - --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0135-wined3d-Create-dummy-textures-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0135-wined3d-Create-dummy-textures-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0135-wined3d-Create-dummy-textures-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0135-wined3d-Create-dummy-textures-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,172 @@ +From e95849bf089a6b93c67e1927a646a4e8bb35a243 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 10 Oct 2013 16:29:42 +0200 +Subject: wined3d: Create dummy textures through the CS. + +Hacky version. Just good enough to see if the double context during init is what makes fglrx +crash. +--- + dlls/wined3d/cs.c | 30 ++++++++++++++++++++++++++++++ + dlls/wined3d/device.c | 19 +++++++------------ + dlls/wined3d/wined3d_private.h | 4 +++- + 3 files changed, 40 insertions(+), 13 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index bd83689..383c9a5 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -88,6 +88,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_VOLUME_CLEANUP, + WINED3D_CS_OP_SURFACE_CLEANUP, + WINED3D_CS_OP_TEXTURE_CLEANUP, ++ WINED3D_CS_OP_CREATE_DUMMY_TEXTURES, + WINED3D_CS_OP_STOP, + }; + +@@ -522,6 +523,11 @@ struct wined3d_cs_texture_cleanup + struct wined3d_texture *texture; + }; + ++struct wined3d_cs_create_dummy_textures ++{ ++ enum wined3d_cs_op opcode; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2587,6 +2593,29 @@ void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_textu + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_create_dummy_textures(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_create_dummy_textures *op = data; ++ struct wined3d_context *context = context_acquire(cs->device, NULL); ++ ++ device_create_dummy_textures(cs->device, context); ++ device_create_default_sampler(cs->device); ++ ++ context_release(context); ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) ++{ ++ struct wined3d_cs_create_dummy_textures *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_CREATE_DUMMY_TEXTURES; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++ cs->ops->finish(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2653,6 +2682,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, + /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, + /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, ++ /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 1b0226a..df19923 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -651,7 +651,7 @@ out: + } + + /* Context activation is done by the caller. */ +-static void create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) ++void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) + { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + unsigned int i, j, count; +@@ -758,7 +758,7 @@ static void destroy_dummy_textures(struct wined3d_device *device, const struct w + } + + /* Context activation is done by the caller. */ +-static void create_default_sampler(struct wined3d_device *device) ++void device_create_default_sampler(struct wined3d_device *device) + { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + +@@ -940,7 +940,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, + { + static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f}; + struct wined3d_swapchain *swapchain = NULL; +- struct wined3d_context *context; + DWORD clear_flags = 0; + HRESULT hr; + +@@ -991,10 +990,8 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, + device->swapchains[0] = swapchain; + device_init_swapchain_state(device, swapchain); + +- context = context_acquire(device, NULL); +- +- create_dummy_textures(device, context); +- create_default_sampler(device); ++ /* also calls create_default_sampler */ ++ wined3d_cs_emit_create_dummy_textures(device->cs); + + device->contexts[0]->last_was_rhw = 0; + +@@ -1006,7 +1003,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, + + case ORM_BACKBUFFER: + { +- if (context_get_current()->aux_buffers > 0) ++ if (device->contexts[0]->aux_buffers > 0) + { + TRACE("Using auxiliary buffer for offscreen rendering\n"); + device->offscreenBuffer = GL_AUX0; +@@ -1022,8 +1019,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, + + TRACE("All defaults now set up, leaving 3D init.\n"); + +- context_release(context); +- + /* Clear the screen */ + if (swapchain->back_buffers && swapchain->back_buffers[0]) + clear_flags |= WINED3DCLEAR_TARGET; +@@ -4504,8 +4499,8 @@ static HRESULT create_primary_opengl_context(struct wined3d_device *device, stru + + swapchain->context[0] = context; + swapchain->num_contexts = 1; +- create_dummy_textures(device, context); +- create_default_sampler(device); ++ device_create_dummy_textures(device, context); ++ device_create_default_sampler(device); + context_release(context); + + return WINED3D_OK; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index d187c0a..f9ffece 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2198,7 +2198,8 @@ struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT + GLenum type_hint, struct wined3d_context *context) DECLSPEC_HIDDEN; + void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, + const struct wined3d_context *context) DECLSPEC_HIDDEN; +- ++void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; ++void device_create_default_sampler(struct wined3d_device *device); + + static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) + { +@@ -2837,6 +2838,7 @@ void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer + void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) DECLSPEC_HIDDEN; + void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; + void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0135-wined3d-Unload-resources-through-the-CS-in-device_re.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0135-wined3d-Unload-resources-through-the-CS-in-device_re.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0135-wined3d-Unload-resources-through-the-CS-in-device_re.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0135-wined3d-Unload-resources-through-the-CS-in-device_re.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -From d2b010c4c1c08d71ed6e2e4257db236535c20deb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 2 Oct 2013 23:40:20 +0200 -Subject: wined3d: Unload resources through the CS in device_reset. - ---- - dlls/wined3d/device.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 28819af..2410547 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -4228,21 +4228,23 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d - struct wined3d_context *context; - struct wined3d_shader *shader; - -- context = context_acquire(device, NULL); -- gl_info = context->gl_info; -- - LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) - { - TRACE("Unloading resource %p.\n", resource); - -- resource->resource_ops->resource_unload(resource); -+ wined3d_cs_emit_evict_resource(device->cs, resource); - } -+ if (wined3d_settings.cs_multithreaded) -+ device->cs->ops->finish(device->cs); - - LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry) - { - device->shader_backend->shader_destroy(shader); - } - -+ context = context_acquire(device, NULL); -+ gl_info = context->gl_info; -+ - if (device->depth_blt_texture) - { - gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->depth_blt_texture); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0136-wined3d-Create-the-initial-context-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0136-wined3d-Create-the-initial-context-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0136-wined3d-Create-the-initial-context-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0136-wined3d-Create-the-initial-context-through-the-CS.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,240 @@ +From 070101f77c342c4eeb49e01d3cc9ca9eaa63fe24 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 10 Oct 2013 16:43:19 +0200 +Subject: wined3d: Create the initial context through the CS. + +Very hacky. +--- + dlls/wined3d/cs.c | 34 ++++++++++++ + dlls/wined3d/swapchain.c | 118 +++++++++++++++++++++++------------------ + dlls/wined3d/wined3d_private.h | 4 ++ + 3 files changed, 103 insertions(+), 53 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 7dc847b..c78ac12 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -89,6 +89,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_SURFACE_CLEANUP, + WINED3D_CS_OP_TEXTURE_CLEANUP, + WINED3D_CS_OP_CREATE_DUMMY_TEXTURES, ++ WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT, + WINED3D_CS_OP_STOP, + }; + +@@ -528,6 +529,13 @@ struct wined3d_cs_create_dummy_textures + enum wined3d_cs_op opcode; + }; + ++struct wined3d_cs_create_swapchain_context ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_swapchain *swapchain; ++ HRESULT *ret; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2615,6 +2623,31 @@ void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) + cs->ops->finish(cs); + } + ++static UINT wined3d_cs_exec_create_swapchain_context(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_create_swapchain_context *op = data; ++ ++ *op->ret = swapchain_create_context_cs(cs->device, op->swapchain); ++ ++ return sizeof(*op); ++} ++ ++HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain) ++{ ++ HRESULT ret; ++ struct wined3d_cs_create_swapchain_context *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT; ++ op->swapchain = swapchain; ++ op->ret = &ret; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++ cs->ops->finish(cs); ++ ++ return ret; ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2682,6 +2715,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, + /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, + /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, ++ /* WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT */ wined3d_cs_exec_create_swapchain_context, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c +index efe6987..71e5df6 100644 +--- a/dlls/wined3d/swapchain.c ++++ b/dlls/wined3d/swapchain.c +@@ -723,6 +723,69 @@ static void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain) + swapchain->render_to_fbo = TRUE; + } + ++HRESULT swapchain_create_context_cs(struct wined3d_device *device, struct wined3d_swapchain *swapchain) ++{ ++ const struct wined3d_adapter *adapter = device->adapter; ++ unsigned int i; ++ static const enum wined3d_format_id formats[] = ++ { ++ WINED3DFMT_D24_UNORM_S8_UINT, ++ WINED3DFMT_D32_UNORM, ++ WINED3DFMT_R24_UNORM_X8_TYPELESS, ++ WINED3DFMT_D16_UNORM, ++ WINED3DFMT_S1_UINT_D15_UNORM ++ }; ++ struct wined3d_surface *front_buffer; ++ const struct wined3d_gl_info *gl_info = &adapter->gl_info; ++ ++ swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); ++ if (!swapchain->context) ++ { ++ ERR("Failed to create the context array.\n"); ++ return E_OUTOFMEMORY; ++ } ++ swapchain->num_contexts = 1; ++ ++ /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. ++ * You are able to add a depth + stencil surface at a later stage when you need it. ++ * In order to support this properly in WineD3D we need the ability to recreate the opengl context and ++ * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new ++ * context, need torecreate shaders, textures and other resources. ++ * ++ * The context manager already takes care of the state problem and for the other tasks code from Reset ++ * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. ++ * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the ++ * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this ++ * issue needs to be fixed. */ ++ front_buffer = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); ++ for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) ++ { ++ swapchain->ds_format = wined3d_get_format(gl_info, formats[i]); ++ swapchain->context[0] = context_create(swapchain, front_buffer, swapchain->ds_format); ++ if (swapchain->context[0]) break; ++ TRACE("Depth stencil format %s is not supported, trying next format\n", ++ debug_d3dformat(formats[i])); ++ } ++ ++ if (!swapchain->context[0]) ++ { ++ WARN("Failed to create context.\n"); ++ HeapFree(GetProcessHeap(), 0, swapchain->context); ++ swapchain->context = NULL; ++ return WINED3DERR_NOTAVAILABLE; ++ } ++ ++ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO ++ && (!swapchain->desc.enable_auto_depth_stencil ++ || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) ++ { ++ FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); ++ } ++ context_release(swapchain->context[0]); ++ ++ return WINED3D_OK; ++} ++ + static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, + struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) + { +@@ -840,60 +903,9 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 + + if (!(device->wined3d->flags & WINED3D_NO3D)) + { +- static const enum wined3d_format_id formats[] = +- { +- WINED3DFMT_D24_UNORM_S8_UINT, +- WINED3DFMT_D32_UNORM, +- WINED3DFMT_R24_UNORM_X8_TYPELESS, +- WINED3DFMT_D16_UNORM, +- WINED3DFMT_S1_UINT_D15_UNORM +- }; +- +- const struct wined3d_gl_info *gl_info = &adapter->gl_info; +- +- swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); +- if (!swapchain->context) +- { +- ERR("Failed to create the context array.\n"); +- hr = E_OUTOFMEMORY; ++ hr = wined3d_cs_emit_create_swapchain_context(device->cs, swapchain); ++ if (FAILED(hr)) + goto err; +- } +- swapchain->num_contexts = 1; +- +- /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. +- * You are able to add a depth + stencil surface at a later stage when you need it. +- * In order to support this properly in WineD3D we need the ability to recreate the opengl context and +- * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new +- * context, need torecreate shaders, textures and other resources. +- * +- * The context manager already takes care of the state problem and for the other tasks code from Reset +- * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. +- * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the +- * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this +- * issue needs to be fixed. */ +- for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) +- { +- swapchain->ds_format = wined3d_get_format(gl_info, formats[i]); +- swapchain->context[0] = context_create(swapchain, front_buffer, swapchain->ds_format); +- if (swapchain->context[0]) break; +- TRACE("Depth stencil format %s is not supported, trying next format\n", +- debug_d3dformat(formats[i])); +- } +- +- if (!swapchain->context[0]) +- { +- WARN("Failed to create context.\n"); +- hr = WINED3DERR_NOTAVAILABLE; +- goto err; +- } +- +- if (wined3d_settings.offscreen_rendering_mode != ORM_FBO +- && (!desc->enable_auto_depth_stencil +- || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) +- { +- FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); +- } +- context_release(swapchain->context[0]); + } + + if (swapchain->desc.backbuffer_count > 0) +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index df99c6f..4f2e652 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2804,6 +2804,8 @@ void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume + void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; + void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; + void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) DECLSPEC_HIDDEN; ++HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, ++ struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +@@ -2988,6 +2990,8 @@ struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchai + void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; ++HRESULT swapchain_create_context_cs(struct wined3d_device *device, ++ struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + + /***************************************************************************** + * Utility function prototypes +-- +2.5.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0136-wined3d-Don-t-glFinish-after-a-depth-buffer-blit.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0136-wined3d-Don-t-glFinish-after-a-depth-buffer-blit.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0136-wined3d-Don-t-glFinish-after-a-depth-buffer-blit.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0136-wined3d-Don-t-glFinish-after-a-depth-buffer-blit.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -From 81f901210e683ac2a2193957849497031f424545 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 3 Oct 2013 17:39:08 +0200 -Subject: wined3d: Don't glFinish after a depth buffer blit. - ---- - dlls/wined3d/surface.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 4d8bd1c..3c5489f 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -694,9 +694,7 @@ static void surface_depth_blt_fbo(const struct wined3d_device *device, - dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, gl_mask, GL_NEAREST); - checkGLcall("glBlitFramebuffer()"); - -- if (wined3d_settings.cs_multithreaded) -- gl_info->gl_ops.gl.p_glFinish(); -- else if (wined3d_settings.strict_draw_ordering) -+ if (wined3d_settings.strict_draw_ordering) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - - context_release(context); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0137-wined3d-Recreate-ctx-and-dummy-textures-through-the-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0137-wined3d-Recreate-ctx-and-dummy-textures-through-the-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0137-wined3d-Recreate-ctx-and-dummy-textures-through-the-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0137-wined3d-Recreate-ctx-and-dummy-textures-through-the-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,63 @@ +From 031a0b58fd0d26fabae25fd1ad9f0030f8e58290 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 10 Oct 2013 18:40:04 +0200 +Subject: wined3d: Recreate ctx and dummy textures through the CS after resets. + +--- + dlls/wined3d/device.c | 27 ++++----------------------- + 1 file changed, 4 insertions(+), 23 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index df19923..fe0a014 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -4457,8 +4457,6 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d + + static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain) + { +- struct wined3d_context *context; +- struct wined3d_surface *target; + HRESULT hr; + + if (FAILED(hr = device->shader_backend->shader_alloc_private(device, +@@ -4475,33 +4473,16 @@ static HRESULT create_primary_opengl_context(struct wined3d_device *device, stru + return hr; + } + +- /* Recreate the primary swapchain's context */ +- swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); +- if (!swapchain->context) +- { +- ERR("Failed to allocate memory for swapchain context array.\n"); +- device->blitter->free_private(device); +- device->shader_backend->shader_free_private(device); +- return E_OUTOFMEMORY; +- } +- +- target = swapchain->back_buffers +- ? surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)) +- : surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); +- if (!(context = context_create(swapchain, target, swapchain->ds_format))) ++ hr = wined3d_cs_emit_create_swapchain_context(device->cs, swapchain); ++ if (FAILED(hr)) + { + WARN("Failed to create context.\n"); + device->blitter->free_private(device); + device->shader_backend->shader_free_private(device); +- HeapFree(GetProcessHeap(), 0, swapchain->context); +- return E_FAIL; ++ return hr; + } + +- swapchain->context[0] = context; +- swapchain->num_contexts = 1; +- device_create_dummy_textures(device, context); +- device_create_default_sampler(device); +- context_release(context); ++ wined3d_cs_emit_create_dummy_textures(device->cs); + + return WINED3D_OK; + } +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0137-wined3d-Remove-software-cursor-support.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0137-wined3d-Remove-software-cursor-support.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0137-wined3d-Remove-software-cursor-support.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0137-wined3d-Remove-software-cursor-support.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,180 +0,0 @@ -From 649e5b815399a26eb4f3ace31d604310771a9eac Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 3 Oct 2013 19:23:24 +0200 -Subject: wined3d: Remove software cursor support. - -This has been broken since quite some time and only serves to crash fglrx by acquiring a context -in the main thread. - -FIXME: Make sure wined3d_device_show_cursor returns the correct value if a software cursor is set. ---- - dlls/wined3d/device.c | 64 ------------------------------------------ - dlls/wined3d/swapchain.c | 29 ------------------- - dlls/wined3d/wined3d_private.h | 1 - - 3 files changed, 94 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 70fb2cb..e9ef79f 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -1073,8 +1073,6 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) - - if (device->logo_texture) - wined3d_texture_decref(device->logo_texture); -- if (device->cursor_texture) -- wined3d_texture_decref(device->cursor_texture); - - /* Release the buffers (with sanity checks). - * FIXME: Move this move into a separate patch. I think the idea -@@ -4181,48 +4179,6 @@ void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, - wined3d_rendertarget_view_decref(prev); - } - --static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined3d_device *device, -- struct wined3d_surface *cursor_image) --{ -- struct wined3d_sub_resource_data data; -- struct wined3d_resource_desc desc; -- struct wined3d_map_desc map_desc; -- struct wined3d_texture *texture; -- HRESULT hr; -- -- if (FAILED(wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_READONLY))) -- { -- ERR("Failed to map source surface.\n"); -- return NULL; -- } -- -- data.data = map_desc.data; -- data.row_pitch = map_desc.row_pitch; -- data.slice_pitch = map_desc.slice_pitch; -- -- desc.resource_type = WINED3D_RTYPE_TEXTURE; -- desc.format = WINED3DFMT_B8G8R8A8_UNORM; -- desc.multisample_type = WINED3D_MULTISAMPLE_NONE; -- desc.multisample_quality = 0; -- desc.usage = WINED3DUSAGE_DYNAMIC; -- desc.pool = WINED3D_POOL_DEFAULT; -- desc.width = cursor_image->resource.width; -- desc.height = cursor_image->resource.height; -- desc.depth = 1; -- desc.size = 0; -- -- hr = wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE, -- &data, NULL, &wined3d_null_parent_ops, &texture); -- wined3d_surface_unmap(cursor_image); -- if (FAILED(hr)) -- { -- ERR("Failed to create cursor texture.\n"); -- return NULL; -- } -- -- return texture; --} -- - HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device, - UINT x_hotspot, UINT y_hotspot, struct wined3d_texture *texture, unsigned int sub_resource_idx) - { -@@ -4241,12 +4197,6 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device - - cursor_image = surface_from_resource(sub_resource); - -- if (device->cursor_texture) -- { -- wined3d_texture_decref(device->cursor_texture); -- device->cursor_texture = NULL; -- } -- - if (cursor_image->resource.format->id != WINED3DFMT_B8G8R8A8_UNORM) - { - WARN("Surface %p has an invalid format %s.\n", -@@ -4274,11 +4224,6 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device - * release it after setting the cursor image. Windows doesn't - * addref the set surface, so we can't do this either without - * creating circular refcount dependencies. */ -- if (!(device->cursor_texture = wined3d_device_create_cursor_texture(device, cursor_image))) -- { -- ERR("Failed to create cursor texture.\n"); -- return WINED3DERR_INVALIDCALL; -- } - - if (cursor_image->resource.width == 32 && cursor_image->resource.height == 32) - { -@@ -4383,10 +4328,6 @@ BOOL CDECL wined3d_device_show_cursor(struct wined3d_device *device, BOOL show) - else - SetCursor(NULL); - } -- else if (device->cursor_texture) -- { -- device->bCursorVisible = show; -- } - - return oldVisible; - } -@@ -4541,11 +4482,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - wined3d_texture_decref(device->logo_texture); - device->logo_texture = NULL; - } -- if (device->cursor_texture) -- { -- wined3d_texture_decref(device->cursor_texture); -- device->cursor_texture = NULL; -- } - } - - if (device->state.fb.render_targets) -diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c -index 77eb532..d0c7c54 100644 ---- a/dlls/wined3d/swapchain.c -+++ b/dlls/wined3d/swapchain.c -@@ -455,35 +455,6 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT - NULL, WINED3D_TEXF_POINT); - } - -- if (swapchain->device->bCursorVisible && swapchain->device->cursor_texture -- && !swapchain->device->hardwareCursor) -- { -- struct wined3d_surface *cursor = surface_from_resource( -- wined3d_texture_get_sub_resource(swapchain->device->cursor_texture, 0)); -- RECT destRect = -- { -- swapchain->device->xScreenSpace - swapchain->device->xHotSpot, -- swapchain->device->yScreenSpace - swapchain->device->yHotSpot, -- swapchain->device->xScreenSpace + swapchain->device->cursorWidth - swapchain->device->xHotSpot, -- swapchain->device->yScreenSpace + swapchain->device->cursorHeight - swapchain->device->yHotSpot, -- }; -- RECT src_rect = -- { -- 0, 0, -- swapchain->device->cursor_texture->resource.width, -- swapchain->device->cursor_texture->resource.height -- }; -- const RECT clip_rect = {0, 0, back_buffer->resource.width, back_buffer->resource.height}; -- -- TRACE("Rendering the software cursor.\n"); -- -- if (swapchain->desc.windowed) -- MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&destRect, 2); -- if (wined3d_clip_blit(&clip_rect, &destRect, &src_rect)) -- wined3d_surface_blt(back_buffer, &destRect, cursor, &src_rect, WINEDDBLT_ALPHATEST, -- NULL, WINED3D_TEXF_POINT); -- } -- - TRACE("Presenting HDC %p.\n", context->hdc); - - render_to_fbo = swapchain->render_to_fbo; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 9450bdc..27a4a87 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2151,7 +2151,6 @@ struct wined3d_device - UINT xScreenSpace; - UINT yScreenSpace; - UINT cursorWidth, cursorHeight; -- struct wined3d_texture *cursor_texture; - HCURSOR hardwareCursor; - - /* The Wine logo texture */ --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0138-wined3d-Create-dummy-textures-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0138-wined3d-Create-dummy-textures-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0138-wined3d-Create-dummy-textures-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0138-wined3d-Create-dummy-textures-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -From c91b5281332e1879e25088efeee24bc1a337ca30 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 10 Oct 2013 16:29:42 +0200 -Subject: wined3d: Create dummy textures through the CS. - -Hacky version. Just good enough to see if the double context during init is what makes fglrx -crash. ---- - dlls/wined3d/cs.c | 29 +++++++++++++++++++++++++++++ - dlls/wined3d/device.c | 13 ++++--------- - dlls/wined3d/wined3d_private.h | 3 ++- - 3 files changed, 35 insertions(+), 10 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 5e4aa53..fb1d1aa 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -87,6 +87,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_VOLUME_CLEANUP, - WINED3D_CS_OP_SURFACE_CLEANUP, - WINED3D_CS_OP_TEXTURE_CLEANUP, -+ WINED3D_CS_OP_CREATE_DUMMY_TEXTURES, - WINED3D_CS_OP_STOP, - }; - -@@ -512,6 +513,11 @@ struct wined3d_cs_texture_cleanup - struct wined3d_texture *texture; - }; - -+struct wined3d_cs_create_dummy_textures -+{ -+ enum wined3d_cs_op opcode; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2473,6 +2479,28 @@ void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_textu - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_create_dummy_textures(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_create_dummy_textures *op = data; -+ struct wined3d_context *context = context_acquire(cs->device, NULL); -+ -+ device_create_dummy_textures(cs->device, context); -+ -+ context_release(context); -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) -+{ -+ struct wined3d_cs_create_dummy_textures *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_CREATE_DUMMY_TEXTURES; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+ cs->ops->finish(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2538,6 +2566,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, - /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, - /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, -+ /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index b3f75ba..28b1c81 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -608,7 +608,7 @@ out: - } - - /* Context activation is done by the caller. */ --static void create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) -+void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) - { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - unsigned int i, j, count; -@@ -854,7 +854,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, - { - static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f}; - struct wined3d_swapchain *swapchain = NULL; -- struct wined3d_context *context; - DWORD clear_flags = 0; - HRESULT hr; - -@@ -905,9 +904,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, - device->swapchains[0] = swapchain; - device_init_swapchain_state(device, swapchain); - -- context = context_acquire(device, NULL); -- -- create_dummy_textures(device, context); -+ wined3d_cs_emit_create_dummy_textures(device->cs); - - device->contexts[0]->last_was_rhw = 0; - -@@ -919,7 +916,7 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, - - case ORM_BACKBUFFER: - { -- if (context_get_current()->aux_buffers > 0) -+ if (device->contexts[0]->aux_buffers > 0) - { - TRACE("Using auxiliary buffer for offscreen rendering\n"); - device->offscreenBuffer = GL_AUX0; -@@ -935,8 +932,6 @@ HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device, - - TRACE("All defaults now set up, leaving 3D init.\n"); - -- context_release(context); -- - /* Clear the screen */ - if (swapchain->back_buffers && swapchain->back_buffers[0]) - clear_flags |= WINED3DCLEAR_TARGET; -@@ -4236,7 +4231,7 @@ static HRESULT create_primary_opengl_context(struct wined3d_device *device, stru - - swapchain->context[0] = context; - swapchain->num_contexts = 1; -- create_dummy_textures(device, context); -+ device_create_dummy_textures(device, context); - context_release(context); - - return WINED3D_OK; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 2f8cab4..a4e1886 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2076,7 +2076,7 @@ struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT - GLenum type_hint, struct wined3d_context *context) DECLSPEC_HIDDEN; - void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, - const struct wined3d_context *context) DECLSPEC_HIDDEN; -- -+void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; - - static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) - { -@@ -2715,6 +2715,7 @@ void wined3d_cs_emit_buffer_cleanup(struct wined3d_cs *cs, struct wined3d_buffer - void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume *volume) DECLSPEC_HIDDEN; - void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; - void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0138-wined3d-Ignore-WINED3D_MAP_NO_DIRTY_UPDATE-in-resour.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0138-wined3d-Ignore-WINED3D_MAP_NO_DIRTY_UPDATE-in-resour.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0138-wined3d-Ignore-WINED3D_MAP_NO_DIRTY_UPDATE-in-resour.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0138-wined3d-Ignore-WINED3D_MAP_NO_DIRTY_UPDATE-in-resour.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,37 @@ +From 00632c0c269b313ecf484bf7aff6d61666d27ff9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 10 Oct 2013 19:18:06 +0200 +Subject: wined3d: Ignore WINED3D_MAP_NO_DIRTY_UPDATE in resource_map. + +TODO: This flag and add_dirty_rect need tests. + +The primary purpose of this patch is to fix a memory leak in World of +Warcraft. WoW uses WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_DISCARD on +sysmem surfaces. A new block of memory is allocated, but never assigned +to heap_mem because wined3d_cs_emit_resource_changed is not called. + +The bigger picture is that we don't know how this flag and AddDirtyRect +/ AddDirtyBox are supposed to work. Msdn mentions some interaction with +update_surface and update_texture, but personally I think it is more +likely that this functionality is used to update separate rectangles in +a texture, similar to what can be achieved by mapping a buffer twice. +--- + dlls/wined3d/resource.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index dd21986..805c6da 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -849,7 +849,7 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, + } + } + +- if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) ++ if (!(flags & WINED3D_MAP_READONLY)) + resource->unmap_dirtify = TRUE; + + resource->map_count++; +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0139-wined3d-Create-the-initial-context-through-the-CS.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0139-wined3d-Create-the-initial-context-through-the-CS.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0139-wined3d-Create-the-initial-context-through-the-CS.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0139-wined3d-Create-the-initial-context-through-the-CS.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,240 +0,0 @@ -From 070101f77c342c4eeb49e01d3cc9ca9eaa63fe24 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 10 Oct 2013 16:43:19 +0200 -Subject: wined3d: Create the initial context through the CS. - -Very hacky. ---- - dlls/wined3d/cs.c | 34 ++++++++++++ - dlls/wined3d/swapchain.c | 118 +++++++++++++++++++++++------------------ - dlls/wined3d/wined3d_private.h | 4 ++ - 3 files changed, 103 insertions(+), 53 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 7dc847b..c78ac12 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -89,6 +89,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_SURFACE_CLEANUP, - WINED3D_CS_OP_TEXTURE_CLEANUP, - WINED3D_CS_OP_CREATE_DUMMY_TEXTURES, -+ WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT, - WINED3D_CS_OP_STOP, - }; - -@@ -528,6 +529,13 @@ struct wined3d_cs_create_dummy_textures - enum wined3d_cs_op opcode; - }; - -+struct wined3d_cs_create_swapchain_context -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_swapchain *swapchain; -+ HRESULT *ret; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2615,6 +2623,31 @@ void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) - cs->ops->finish(cs); - } - -+static UINT wined3d_cs_exec_create_swapchain_context(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_create_swapchain_context *op = data; -+ -+ *op->ret = swapchain_create_context_cs(cs->device, op->swapchain); -+ -+ return sizeof(*op); -+} -+ -+HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain) -+{ -+ HRESULT ret; -+ struct wined3d_cs_create_swapchain_context *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT; -+ op->swapchain = swapchain; -+ op->ret = &ret; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+ cs->ops->finish(cs); -+ -+ return ret; -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2682,6 +2715,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, - /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, - /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, -+ /* WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT */ wined3d_cs_exec_create_swapchain_context, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c -index efe6987..71e5df6 100644 ---- a/dlls/wined3d/swapchain.c -+++ b/dlls/wined3d/swapchain.c -@@ -723,6 +723,69 @@ static void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain) - swapchain->render_to_fbo = TRUE; - } - -+HRESULT swapchain_create_context_cs(struct wined3d_device *device, struct wined3d_swapchain *swapchain) -+{ -+ const struct wined3d_adapter *adapter = device->adapter; -+ unsigned int i; -+ static const enum wined3d_format_id formats[] = -+ { -+ WINED3DFMT_D24_UNORM_S8_UINT, -+ WINED3DFMT_D32_UNORM, -+ WINED3DFMT_R24_UNORM_X8_TYPELESS, -+ WINED3DFMT_D16_UNORM, -+ WINED3DFMT_S1_UINT_D15_UNORM -+ }; -+ struct wined3d_surface *front_buffer; -+ const struct wined3d_gl_info *gl_info = &adapter->gl_info; -+ -+ swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); -+ if (!swapchain->context) -+ { -+ ERR("Failed to create the context array.\n"); -+ return E_OUTOFMEMORY; -+ } -+ swapchain->num_contexts = 1; -+ -+ /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. -+ * You are able to add a depth + stencil surface at a later stage when you need it. -+ * In order to support this properly in WineD3D we need the ability to recreate the opengl context and -+ * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new -+ * context, need torecreate shaders, textures and other resources. -+ * -+ * The context manager already takes care of the state problem and for the other tasks code from Reset -+ * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. -+ * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the -+ * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this -+ * issue needs to be fixed. */ -+ front_buffer = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); -+ for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) -+ { -+ swapchain->ds_format = wined3d_get_format(gl_info, formats[i]); -+ swapchain->context[0] = context_create(swapchain, front_buffer, swapchain->ds_format); -+ if (swapchain->context[0]) break; -+ TRACE("Depth stencil format %s is not supported, trying next format\n", -+ debug_d3dformat(formats[i])); -+ } -+ -+ if (!swapchain->context[0]) -+ { -+ WARN("Failed to create context.\n"); -+ HeapFree(GetProcessHeap(), 0, swapchain->context); -+ swapchain->context = NULL; -+ return WINED3DERR_NOTAVAILABLE; -+ } -+ -+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO -+ && (!swapchain->desc.enable_auto_depth_stencil -+ || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) -+ { -+ FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); -+ } -+ context_release(swapchain->context[0]); -+ -+ return WINED3D_OK; -+} -+ - static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, - struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) - { -@@ -840,60 +903,9 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 - - if (!(device->wined3d->flags & WINED3D_NO3D)) - { -- static const enum wined3d_format_id formats[] = -- { -- WINED3DFMT_D24_UNORM_S8_UINT, -- WINED3DFMT_D32_UNORM, -- WINED3DFMT_R24_UNORM_X8_TYPELESS, -- WINED3DFMT_D16_UNORM, -- WINED3DFMT_S1_UINT_D15_UNORM -- }; -- -- const struct wined3d_gl_info *gl_info = &adapter->gl_info; -- -- swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); -- if (!swapchain->context) -- { -- ERR("Failed to create the context array.\n"); -- hr = E_OUTOFMEMORY; -+ hr = wined3d_cs_emit_create_swapchain_context(device->cs, swapchain); -+ if (FAILED(hr)) - goto err; -- } -- swapchain->num_contexts = 1; -- -- /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. -- * You are able to add a depth + stencil surface at a later stage when you need it. -- * In order to support this properly in WineD3D we need the ability to recreate the opengl context and -- * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new -- * context, need torecreate shaders, textures and other resources. -- * -- * The context manager already takes care of the state problem and for the other tasks code from Reset -- * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. -- * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the -- * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this -- * issue needs to be fixed. */ -- for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) -- { -- swapchain->ds_format = wined3d_get_format(gl_info, formats[i]); -- swapchain->context[0] = context_create(swapchain, front_buffer, swapchain->ds_format); -- if (swapchain->context[0]) break; -- TRACE("Depth stencil format %s is not supported, trying next format\n", -- debug_d3dformat(formats[i])); -- } -- -- if (!swapchain->context[0]) -- { -- WARN("Failed to create context.\n"); -- hr = WINED3DERR_NOTAVAILABLE; -- goto err; -- } -- -- if (wined3d_settings.offscreen_rendering_mode != ORM_FBO -- && (!desc->enable_auto_depth_stencil -- || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) -- { -- FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); -- } -- context_release(swapchain->context[0]); - } - - if (swapchain->desc.backbuffer_count > 0) -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index df99c6f..4f2e652 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2804,6 +2804,8 @@ void wined3d_cs_emit_volume_cleanup(struct wined3d_cs *cs, struct wined3d_volume - void wined3d_cs_emit_surface_cleanup(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; - void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_texture *texture) DECLSPEC_HIDDEN; - void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) DECLSPEC_HIDDEN; -+HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, -+ struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d -@@ -2988,6 +2990,8 @@ struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchai - void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; - HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; - void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -+HRESULT swapchain_create_context_cs(struct wined3d_device *device, -+ struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; - - /***************************************************************************** - * Utility function prototypes --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0139-wined3d-Delete-GL-contexts-through-the-CS-in-reset.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0139-wined3d-Delete-GL-contexts-through-the-CS-in-reset.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0139-wined3d-Delete-GL-contexts-through-the-CS-in-reset.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0139-wined3d-Delete-GL-contexts-through-the-CS-in-reset.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,147 @@ +From e97fb065249c11f83234e5d8b713112725fc3039 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 11 Oct 2013 10:11:13 +0200 +Subject: wined3d: Delete GL contexts through the CS in reset. + +Let's see if this fixes the remaining fglrx crashes... +--- + dlls/wined3d/cs.c | 29 +++++++++++++++++++++++++++++ + dlls/wined3d/device.c | 26 +++++++++++++++----------- + dlls/wined3d/wined3d_private.h | 4 ++++ + 3 files changed, 48 insertions(+), 11 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index b0b86ae..b30bb4e 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -90,6 +90,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_TEXTURE_CLEANUP, + WINED3D_CS_OP_CREATE_DUMMY_TEXTURES, + WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT, ++ WINED3D_CS_OP_DELETE_GL_CONTEXTS, + WINED3D_CS_OP_STOP, + }; + +@@ -536,6 +537,12 @@ struct wined3d_cs_create_swapchain_context + HRESULT *ret; + }; + ++struct wined3d_cs_delete_gl_contexts ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_swapchain *swapchain; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2649,6 +2656,27 @@ HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, struct w + return ret; + } + ++static UINT wined3d_cs_exec_delete_gl_contexts(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_delete_gl_contexts *op = data; ++ ++ device_delete_opengl_contexts_cs(cs->device, op->swapchain); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain) ++{ ++ struct wined3d_cs_delete_gl_contexts *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_DELETE_GL_CONTEXTS; ++ op->swapchain = swapchain; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++ cs->ops->finish(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2717,6 +2745,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, + /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, + /* WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT */ wined3d_cs_exec_create_swapchain_context, ++ /* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 525b61b..039b645 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -4409,22 +4409,12 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) + } + } + +-static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) ++void device_delete_opengl_contexts_cs(struct wined3d_device *device, struct wined3d_swapchain *swapchain) + { +- struct wined3d_resource *resource, *cursor; + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + struct wined3d_shader *shader; + +- LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) +- { +- TRACE("Unloading resource %p.\n", resource); +- +- wined3d_cs_emit_evict_resource(device->cs, resource); +- } +- if (wined3d_settings.cs_multithreaded) +- device->cs->ops->finish(device->cs); +- + LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry) + { + device->shader_backend->shader_destroy(shader); +@@ -4454,6 +4444,20 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d + swapchain->context = NULL; + } + ++static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) ++{ ++ struct wined3d_resource *resource, *cursor; ++ ++ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) ++ { ++ TRACE("Unloading resource %p.\n", resource); ++ ++ wined3d_cs_emit_evict_resource(device->cs, resource); ++ } ++ ++ wined3d_cs_emit_delete_opengl_contexts(device->cs, swapchain); ++} ++ + static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain) + { + HRESULT hr; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index d5b939c..9f509e5 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2200,6 +2200,8 @@ void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_ + const struct wined3d_context *context) DECLSPEC_HIDDEN; + void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; + void device_create_default_sampler(struct wined3d_device *device); ++void device_delete_opengl_contexts_cs(struct wined3d_device *device, ++ struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + + static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) + { +@@ -2841,6 +2843,8 @@ void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_textu + void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) DECLSPEC_HIDDEN; + HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, + struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, ++ struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0140-wined3d-Delete-GL-contexts-through-the-CS-in-uninit_.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0140-wined3d-Delete-GL-contexts-through-the-CS-in-uninit_.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0140-wined3d-Delete-GL-contexts-through-the-CS-in-uninit_.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0140-wined3d-Delete-GL-contexts-through-the-CS-in-uninit_.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,80 @@ +From fd1de8f949ff49edbaff899af7e3a6ce83b99521 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 11 Oct 2013 10:17:42 +0200 +Subject: wined3d: Delete GL contexts through the CS in uninit_3d. + +--- + dlls/wined3d/device.c | 33 +++------------------------------ + 1 file changed, 3 insertions(+), 30 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 800944b..8941632 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -1091,8 +1091,6 @@ static void device_free_sampler(struct wine_rb_entry *entry, void *context) + HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) + { + struct wined3d_resource *resource, *cursor; +- const struct wined3d_gl_info *gl_info; +- struct wined3d_context *context; + struct wined3d_surface *surface; + UINT i; + +@@ -1104,12 +1102,6 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) + if (wined3d_settings.cs_multithreaded) + device->cs->ops->finish(device->cs); + +- /* I don't think that the interface guarantees that the device is destroyed from the same thread +- * it was created. Thus make sure a context is active for the glDelete* calls +- */ +- context = context_acquire(device, NULL); +- gl_info = context->gl_info; +- + if (device->logo_texture) + wined3d_texture_decref(device->logo_texture); + +@@ -1139,31 +1131,11 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) + TRACE("Unloading resource %p.\n", resource); + wined3d_cs_emit_evict_resource(device->cs, resource); + } +- if (wined3d_settings.cs_multithreaded) +- device->cs->ops->finish(device->cs); + + wine_rb_clear(&device->samplers, device_free_sampler, NULL); + +- /* Destroy the depth blt resources, they will be invalid after the reset. Also free shader +- * private data, it might contain opengl pointers +- */ +- if (device->depth_blt_texture) +- { +- gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->depth_blt_texture); +- device->depth_blt_texture = 0; +- } +- +- /* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */ +- device->blitter->free_private(device); +- device->shader_backend->shader_free_private(device); +- destroy_dummy_textures(device, gl_info); +- destroy_default_sampler(device); +- +- /* Release the context again as soon as possible. In particular, +- * releasing the render target views below may release the last reference +- * to the swapchain associated with this context, which in turn will +- * destroy the context. */ +- context_release(context); ++ /* FIXME: Is this in the right place??? */ ++ wined3d_cs_emit_delete_opengl_contexts(device->cs, device->swapchains[0]); + + if (device->back_buffer_view) + { +@@ -4443,6 +4415,7 @@ void device_delete_opengl_contexts_cs(struct wined3d_device *device, struct wine + + HeapFree(GetProcessHeap(), 0, swapchain->context); + swapchain->context = NULL; ++ swapchain->num_contexts = 0; + } + + static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0140-wined3d-Recreate-ctx-and-dummy-textures-through-the-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0140-wined3d-Recreate-ctx-and-dummy-textures-through-the-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0140-wined3d-Recreate-ctx-and-dummy-textures-through-the-.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0140-wined3d-Recreate-ctx-and-dummy-textures-through-the-.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -From bc64eef6fb48de707d8d19cb604e748e207742e4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 10 Oct 2013 18:40:04 +0200 -Subject: wined3d: Recreate ctx and dummy textures through the CS after resets. - ---- - dlls/wined3d/device.c | 26 ++++---------------------- - 1 file changed, 4 insertions(+), 22 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 28b1c81..a113e21 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -4189,8 +4189,6 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d - - static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain) - { -- struct wined3d_context *context; -- struct wined3d_surface *target; - HRESULT hr; - - if (FAILED(hr = device->shader_backend->shader_alloc_private(device, -@@ -4207,32 +4205,16 @@ static HRESULT create_primary_opengl_context(struct wined3d_device *device, stru - return hr; - } - -- /* Recreate the primary swapchain's context */ -- swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); -- if (!swapchain->context) -- { -- ERR("Failed to allocate memory for swapchain context array.\n"); -- device->blitter->free_private(device); -- device->shader_backend->shader_free_private(device); -- return E_OUTOFMEMORY; -- } -- -- target = swapchain->back_buffers -- ? surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)) -- : surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); -- if (!(context = context_create(swapchain, target, swapchain->ds_format))) -+ hr = wined3d_cs_emit_create_swapchain_context(device->cs, swapchain); -+ if (FAILED(hr)) - { - WARN("Failed to create context.\n"); - device->blitter->free_private(device); - device->shader_backend->shader_free_private(device); -- HeapFree(GetProcessHeap(), 0, swapchain->context); -- return E_FAIL; -+ return hr; - } - -- swapchain->context[0] = context; -- swapchain->num_contexts = 1; -- device_create_dummy_textures(device, context); -- context_release(context); -+ wined3d_cs_emit_create_dummy_textures(device->cs); - - return WINED3D_OK; - } --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0141-wined3d-Ignore-WINED3D_MAP_NO_DIRTY_UPDATE-in-resour.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0141-wined3d-Ignore-WINED3D_MAP_NO_DIRTY_UPDATE-in-resour.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0141-wined3d-Ignore-WINED3D_MAP_NO_DIRTY_UPDATE-in-resour.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0141-wined3d-Ignore-WINED3D_MAP_NO_DIRTY_UPDATE-in-resour.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -From 00632c0c269b313ecf484bf7aff6d61666d27ff9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 10 Oct 2013 19:18:06 +0200 -Subject: wined3d: Ignore WINED3D_MAP_NO_DIRTY_UPDATE in resource_map. - -TODO: This flag and add_dirty_rect need tests. - -The primary purpose of this patch is to fix a memory leak in World of -Warcraft. WoW uses WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_DISCARD on -sysmem surfaces. A new block of memory is allocated, but never assigned -to heap_mem because wined3d_cs_emit_resource_changed is not called. - -The bigger picture is that we don't know how this flag and AddDirtyRect -/ AddDirtyBox are supposed to work. Msdn mentions some interaction with -update_surface and update_texture, but personally I think it is more -likely that this functionality is used to update separate rectangles in -a texture, similar to what can be achieved by mapping a buffer twice. ---- - dlls/wined3d/resource.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index dd21986..805c6da 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -849,7 +849,7 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, - } - } - -- if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) -+ if (!(flags & WINED3D_MAP_READONLY)) - resource->unmap_dirtify = TRUE; - - resource->map_count++; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0141-wined3d-Invoke-surface_unload-through-the-CS-in-wine.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0141-wined3d-Invoke-surface_unload-through-the-CS-in-wine.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0141-wined3d-Invoke-surface_unload-through-the-CS-in-wine.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0141-wined3d-Invoke-surface_unload-through-the-CS-in-wine.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,31 @@ +From 210ed15c0132830fe2a6b4bf422fdc794982cf9c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 11 Oct 2013 12:09:37 +0200 +Subject: wined3d: Invoke surface_unload through the CS in + wined3d_surface_update_desc. + +This fixes another case where we use a GL context in the main thread and +crash fglrx in doing so. +--- + dlls/wined3d/texture.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index f055d5e..09ac38f 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -769,7 +769,10 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT + } + + if (device->d3d_initialized) +- texture->resource.resource_ops->resource_unload(&texture->resource); ++ { ++ wined3d_cs_emit_evict_resource(device->cs, &surface->resource); ++ device->cs->ops->finish(device->cs); ++ } + + texture->resource.format = format; + texture->resource.multisample_type = multisample_type; +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0142-wined3d-Delete-GL-contexts-through-the-CS-in-reset.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0142-wined3d-Delete-GL-contexts-through-the-CS-in-reset.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0142-wined3d-Delete-GL-contexts-through-the-CS-in-reset.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0142-wined3d-Delete-GL-contexts-through-the-CS-in-reset.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -From 2fa4aafc16726b74a32cfcfae23d68749545114f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 11 Oct 2013 10:11:13 +0200 -Subject: wined3d: Delete GL contexts through the CS in reset. - -Let's see if this fixes the remaining fglrx crashes... ---- - dlls/wined3d/cs.c | 29 +++++++++++++++++++++++++++++ - dlls/wined3d/device.c | 26 +++++++++++++++----------- - dlls/wined3d/wined3d_private.h | 4 ++++ - 3 files changed, 48 insertions(+), 11 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 3662432..489fad0 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -89,6 +89,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_TEXTURE_CLEANUP, - WINED3D_CS_OP_CREATE_DUMMY_TEXTURES, - WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT, -+ WINED3D_CS_OP_DELETE_GL_CONTEXTS, - WINED3D_CS_OP_STOP, - }; - -@@ -526,6 +527,12 @@ struct wined3d_cs_create_swapchain_context - HRESULT *ret; - }; - -+struct wined3d_cs_delete_gl_contexts -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_swapchain *swapchain; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2534,6 +2541,27 @@ HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, struct w - return ret; - } - -+static UINT wined3d_cs_exec_delete_gl_contexts(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_delete_gl_contexts *op = data; -+ -+ device_delete_opengl_contexts_cs(cs->device, op->swapchain); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain) -+{ -+ struct wined3d_cs_delete_gl_contexts *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_DELETE_GL_CONTEXTS; -+ op->swapchain = swapchain; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+ cs->ops->finish(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2601,6 +2629,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, - /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, - /* WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT */ wined3d_cs_exec_create_swapchain_context, -+ /* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index a113e21..b96f20f 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -4142,22 +4142,12 @@ void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device) - } - } - --static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) -+void device_delete_opengl_contexts_cs(struct wined3d_device *device, struct wined3d_swapchain *swapchain) - { -- struct wined3d_resource *resource, *cursor; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - struct wined3d_shader *shader; - -- LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) -- { -- TRACE("Unloading resource %p.\n", resource); -- -- wined3d_cs_emit_evict_resource(device->cs, resource); -- } -- if (wined3d_settings.cs_multithreaded) -- device->cs->ops->finish(device->cs); -- - LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry) - { - device->shader_backend->shader_destroy(shader); -@@ -4187,6 +4177,20 @@ static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d - swapchain->context = NULL; - } - -+static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) -+{ -+ struct wined3d_resource *resource, *cursor; -+ -+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) -+ { -+ TRACE("Unloading resource %p.\n", resource); -+ -+ wined3d_cs_emit_evict_resource(device->cs, resource); -+ } -+ -+ wined3d_cs_emit_delete_opengl_contexts(device->cs, swapchain); -+} -+ - static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain) - { - HRESULT hr; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index ab38f0e..2f7dd75 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2077,6 +2077,8 @@ struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT - void wined3d_device_release_bo(struct wined3d_device *device, struct wined3d_gl_bo *bo, - const struct wined3d_context *context) DECLSPEC_HIDDEN; - void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; -+void device_delete_opengl_contexts_cs(struct wined3d_device *device, -+ struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; - - static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) - { -@@ -2718,6 +2720,8 @@ void wined3d_cs_emit_texture_cleanup(struct wined3d_cs *cs, struct wined3d_textu - void wined3d_cs_emit_create_dummy_textures(struct wined3d_cs *cs) DECLSPEC_HIDDEN; - HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, - struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, -+ struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0142-wined3d-Use-an-event-to-block-the-worker-thread-when.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0142-wined3d-Use-an-event-to-block-the-worker-thread-when.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0142-wined3d-Use-an-event-to-block-the-worker-thread-when.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0142-wined3d-Use-an-event-to-block-the-worker-thread-when.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,177 @@ +From e18809d8ea1a9d47a592c91d3bfb703a5df08ac2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 24 Oct 2013 18:56:13 +0200 +Subject: wined3d: Use an event to block the worker thread when it is idle. + +I could not find a canonical implementation for this. Suggestions are +welcome. + +The main goal was to avoid SetEvent / WaitForSingleObject / ResetEvent +calls at all costs. They go straight to wineserver, bringing it to 25% +CPU time and cutting framerates in half. Hence the extra BOOL to tell +cs_submit when to set the event. + +Finding the correct spin count is tricky. The value I set is high enough +to prevent 3DMark2001 car chase high detail from waiting. This benchmark +maps a lot of in-use managed buffers and thus waits for the CS. But what +the ideal number is depends a lot on the game and CPU. + +A better heuristic is needed. E.g. we could tell the worker thread when +the main thread is waiting for a resource to become idle and avoid +waiting for the event in that case. We may have to use POSIX +synchronization primitives for efficiency. On the other hand, the +current implementation probably still spins way too much for an +application that throttles the framerate to 30 fps by waiting in its own +code. So it is probably only good enough for Microsoft Powerpoint. + +We should also think about blocking the main thread with events if it is +waiting for the worker thread when waiting for resources, the swap +counter or space in the command Stream. This should preserve power when +vsync is turned on. +--- + dlls/wined3d/cs.c | 51 +++++++++++++++++++++++++++++++++++++++--- + dlls/wined3d/wined3d_private.h | 5 +++++ + 2 files changed, 53 insertions(+), 3 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 489fad0..8cbca6c 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -539,6 +539,9 @@ static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + /* There is only one thread writing to queue.head, InterlockedExchange + * is used for the memory barrier. */ + InterlockedExchange(&cs->queue.head, new_val); ++ ++ if (InterlockedCompareExchange(&cs->waiting_for_event, FALSE, TRUE)) ++ SetEvent(cs->event); + } + + static void wined3d_cs_mt_submit_prio(struct wined3d_cs *cs, size_t size) +@@ -547,6 +550,9 @@ static void wined3d_cs_mt_submit_prio(struct wined3d_cs *cs, size_t size) + /* There is only one thread writing to queue.head, InterlockedExchange + * is used for the memory barrier. */ + InterlockedExchange(&cs->prio_queue.head, new_val); ++ ++ if (InterlockedCompareExchange(&cs->waiting_for_event, FALSE, TRUE)) ++ SetEvent(cs->event); + } + + static UINT wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data) +@@ -2826,6 +2832,34 @@ static inline void poll_queries(struct wined3d_cs *cs) + } + } + ++static inline BOOL queue_is_empty(const struct wined3d_cs_queue *queue) ++{ ++ return *((volatile LONG *)&queue->head) == queue->tail; ++} ++ ++static void wined3d_cs_wait_event(struct wined3d_cs *cs) ++{ ++ InterlockedExchange(&cs->waiting_for_event, TRUE); ++ ++ /* The main thread might enqueue a finish command and block on it ++ * after the worker thread decided to enter wined3d_cs_wait_event ++ * and before waiting_for_event was set to TRUE. Check again if ++ * the queues are empty */ ++ if (!queue_is_empty(&cs->prio_queue) || !queue_is_empty(&cs->queue)) ++ { ++ /* The main thread might have signalled the event, or be in the process ++ * of doing so. Wait for the event to reset it. ResetEvent is not good ++ * because the main thread might be beween the waiting_for_event reset ++ * and SignalEvent call. */ ++ if (!InterlockedCompareExchange(&cs->waiting_for_event, FALSE, FALSE)) ++ WaitForSingleObject(cs->event, INFINITE); ++ } ++ else ++ { ++ WaitForSingleObject(cs->event, INFINITE); ++ } ++} ++ + static DWORD WINAPI wined3d_cs_run(void *thread_param) + { + struct wined3d_cs *cs = thread_param; +@@ -2833,6 +2867,7 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) + LONG tail; + char poll = 0; + struct wined3d_cs_queue *queue; ++ unsigned int spin_count = 0; + + TRACE("Started.\n"); + +@@ -2848,21 +2883,27 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) + else + poll++; + +- if (*((volatile LONG *)&cs->prio_queue.head) != cs->prio_queue.tail) ++ if (!queue_is_empty(&cs->prio_queue)) + { + queue = &cs->prio_queue; + } +- else if (*((volatile LONG *)&cs->queue.head) != cs->queue.tail) ++ else if (!queue_is_empty(&cs->queue)) + { + queue = &cs->queue; +- if (*((volatile LONG *)&cs->prio_queue.head) != cs->prio_queue.tail) ++ if (!queue_is_empty(&cs->prio_queue)) + queue = &cs->prio_queue; + } + else + { ++ spin_count++; ++ if (spin_count >= WINED3D_CS_SPIN_COUNT && list_empty(&cs->query_poll_list)) ++ wined3d_cs_wait_event(cs); ++ + continue; + } + ++ spin_count = 0; ++ + tail = queue->tail; + opcode = *(const enum wined3d_cs_op *)&queue->data[tail]; + +@@ -2904,6 +2945,8 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) + { + cs->ops = &wined3d_cs_mt_ops; + ++ cs->event = CreateEventW(NULL, FALSE, FALSE, NULL); ++ + if (!(cs->thread = CreateThread(NULL, 0, wined3d_cs_run, cs, 0, NULL))) + { + ERR("Failed to create wined3d command stream thread.\n"); +@@ -2934,6 +2977,8 @@ void wined3d_cs_destroy(struct wined3d_cs *cs) + CloseHandle(cs->thread); + if (ret != WAIT_OBJECT_0) + ERR("Wait failed (%#x).\n", ret); ++ if (!CloseHandle(cs->event)) ++ ERR("Closing event failed.\n"); + } + + HeapFree(GetProcessHeap(), 0, cs); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 2f7dd75..63b67da 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2583,6 +2583,8 @@ struct wined3d_cs_list + }; + + #define WINED3D_CS_QUEUE_SIZE 0x100000 ++#define WINED3D_CS_SPIN_COUNT 10000000 ++ + struct wined3d_cs_queue + { + LONG head, tail; +@@ -2612,6 +2614,9 @@ struct wined3d_cs + + LONG pending_presents; + struct list query_poll_list; ++ ++ HANDLE event; ++ BOOL waiting_for_event; + }; + + struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0143-wined3d-Delete-GL-contexts-through-the-CS-in-uninit_.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0143-wined3d-Delete-GL-contexts-through-the-CS-in-uninit_.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0143-wined3d-Delete-GL-contexts-through-the-CS-in-uninit_.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0143-wined3d-Delete-GL-contexts-through-the-CS-in-uninit_.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,79 +0,0 @@ -From b596845e64e0d1f5d0674508066409f8eb88bed1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 11 Oct 2013 10:17:42 +0200 -Subject: wined3d: Delete GL contexts through the CS in uninit_3d. - ---- - dlls/wined3d/device.c | 32 +++----------------------------- - 1 file changed, 3 insertions(+), 29 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 15868f2..d20d3b1 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -1013,8 +1013,6 @@ static void device_free_sampler(struct wine_rb_entry *entry, void *context) - HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) - { - struct wined3d_resource *resource, *cursor; -- const struct wined3d_gl_info *gl_info; -- struct wined3d_context *context; - struct wined3d_surface *surface; - UINT i; - -@@ -1026,12 +1024,6 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) - if (wined3d_settings.cs_multithreaded) - device->cs->ops->finish(device->cs); - -- /* I don't think that the interface guarantees that the device is destroyed from the same thread -- * it was created. Thus make sure a context is active for the glDelete* calls -- */ -- context = context_acquire(device, NULL); -- gl_info = context->gl_info; -- - if (device->logo_texture) - wined3d_texture_decref(device->logo_texture); - -@@ -1061,30 +1053,11 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) - TRACE("Unloading resource %p.\n", resource); - wined3d_cs_emit_evict_resource(device->cs, resource); - } -- if (wined3d_settings.cs_multithreaded) -- device->cs->ops->finish(device->cs); - - wine_rb_clear(&device->samplers, device_free_sampler, NULL); - -- /* Destroy the depth blt resources, they will be invalid after the reset. Also free shader -- * private data, it might contain opengl pointers -- */ -- if (device->depth_blt_texture) -- { -- gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->depth_blt_texture); -- device->depth_blt_texture = 0; -- } -- -- /* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */ -- device->blitter->free_private(device); -- device->shader_backend->shader_free_private(device); -- destroy_dummy_textures(device, gl_info); -- -- /* Release the context again as soon as possible. In particular, -- * releasing the render target views below may release the last reference -- * to the swapchain associated with this context, which in turn will -- * destroy the context. */ -- context_release(context); -+ /* FIXME: Is this in the right place??? */ -+ wined3d_cs_emit_delete_opengl_contexts(device->cs, device->swapchains[0]); - - if (device->back_buffer_view) - { -@@ -4366,6 +4339,7 @@ void device_delete_opengl_contexts_cs(struct wined3d_device *device, struct wine - - HeapFree(GetProcessHeap(), 0, swapchain->context); - swapchain->context = NULL; -+ swapchain->num_contexts = 0; - } - - static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0143-wined3d-Fence-preload-operations.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0143-wined3d-Fence-preload-operations.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0143-wined3d-Fence-preload-operations.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0143-wined3d-Fence-preload-operations.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,71 @@ +From c1bf11e5e355915f1ac6e1e9cdfaf3b5a7309167 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 24 Oct 2013 22:38:26 +0200 +Subject: wined3d: Fence preload operations. + +Otherwise texture data might get lost, thanks to surface/volume_evict_sysmem: + +1) preload(texture) +2) map(texture) + -> Loads sysmem / sets it with discard map. +3) unmap(texture) + -> enqueues a resource_changed operation +4) preload is executed. + -> Uploads data written in 3. Discards sysmem. Questionable if + DISCARD was passed, but without it, no harm done. + -> texture is only up to date location. +5) resource_changed executed. + -> Discards texture. + +And data is lost. This patch prevents that by stalling the map until the +PreLoad is done. + +What's left open is finding out why anyone (I'm looking at you EVE +online) preloads a texture right before mapping it... +--- + dlls/wined3d/cs.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index a542270..0318315 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -2252,6 +2252,8 @@ static UINT wined3d_cs_exec_texture_preload(struct wined3d_cs *cs, const void *d + wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); + context_release(context); + ++ wined3d_resource_dec_fence(&texture->resource); ++ + return sizeof(*op); + } + +@@ -2263,6 +2265,8 @@ void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_textu + op->opcode = WINED3D_CS_OP_TEXTURE_PRELOAD; + op->texture = texture; + ++ wined3d_resource_inc_fence(&texture->resource); ++ + cs->ops->submit(cs, sizeof(*op)); + } + +@@ -2384,6 +2388,8 @@ static UINT wined3d_cs_exec_buffer_preload(struct wined3d_cs *cs, const void *da + buffer_internal_preload(op->buffer, context, NULL); + context_release(context); + ++ wined3d_resource_dec_fence(&op->buffer->resource); ++ + return sizeof(*op); + } + +@@ -2395,6 +2401,8 @@ void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer + op->opcode = WINED3D_CS_OP_BUFFER_PRELOAD; + op->buffer = buffer; + ++ wined3d_resource_inc_fence(&buffer->resource); ++ + cs->ops->submit(cs, sizeof(*op)); + } + +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0144-d3d8-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0144-d3d8-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0144-d3d8-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0144-d3d8-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,26 @@ +From c8083ad9f76ddba995df169c8b2f3486e81bbe02 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 20 Nov 2013 18:04:50 +0100 +Subject: d3d8/tests: D3DLOCK_NO_DIRTY_UPDATE on managed textures is + temporarily broken. + +--- + dlls/d3d8/tests/visual.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c +index a8a771e..9535b69 100644 +--- a/dlls/d3d8/tests/visual.c ++++ b/dlls/d3d8/tests/visual.c +@@ -4998,7 +4998,7 @@ static void add_dirty_rect_test(void) + fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE); + add_dirty_rect_test_draw(device); + color = getPixelColor(device, 320, 240); +- ok(color_match(color, 0x00ff0000, 1), ++ todo_wine ok(color_match(color, 0x00ff0000, 1), + "Expected color 0x00ff0000, got 0x%08x.\n", color); + hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL); + ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0144-wined3d-Invoke-surface_unload-through-the-CS-in-wine.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0144-wined3d-Invoke-surface_unload-through-the-CS-in-wine.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0144-wined3d-Invoke-surface_unload-through-the-CS-in-wine.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0144-wined3d-Invoke-surface_unload-through-the-CS-in-wine.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -From 210ed15c0132830fe2a6b4bf422fdc794982cf9c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 11 Oct 2013 12:09:37 +0200 -Subject: wined3d: Invoke surface_unload through the CS in - wined3d_surface_update_desc. - -This fixes another case where we use a GL context in the main thread and -crash fglrx in doing so. ---- - dlls/wined3d/texture.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index f055d5e..09ac38f 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -769,7 +769,10 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT - } - - if (device->d3d_initialized) -- texture->resource.resource_ops->resource_unload(&texture->resource); -+ { -+ wined3d_cs_emit_evict_resource(device->cs, &surface->resource); -+ device->cs->ops->finish(device->cs); -+ } - - texture->resource.format = format; - texture->resource.multisample_type = multisample_type; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0145-d3d9-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0145-d3d9-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0145-d3d9-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0145-d3d9-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,26 @@ +From 1bdcaa3e831f627806a00a07fb92ef28502c4f7a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 20 Nov 2013 18:06:02 +0100 +Subject: d3d9/tests: D3DLOCK_NO_DIRTY_UPDATE on managed textures is + temporarily broken. + +--- + dlls/d3d9/tests/visual.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c +index d1aa3d4..6b28d14 100644 +--- a/dlls/d3d9/tests/visual.c ++++ b/dlls/d3d9/tests/visual.c +@@ -16457,7 +16457,7 @@ static void add_dirty_rect_test(void) + fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE); + add_dirty_rect_test_draw(device); + color = getPixelColor(device, 320, 240); +- ok(color_match(color, 0x00ff0000, 1), ++ todo_wine ok(color_match(color, 0x00ff0000, 1), + "Expected color 0x00ff0000, got 0x%08x.\n", color); + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0145-wined3d-Use-an-event-to-block-the-worker-thread-when.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0145-wined3d-Use-an-event-to-block-the-worker-thread-when.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0145-wined3d-Use-an-event-to-block-the-worker-thread-when.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0145-wined3d-Use-an-event-to-block-the-worker-thread-when.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,177 +0,0 @@ -From e18809d8ea1a9d47a592c91d3bfb703a5df08ac2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 24 Oct 2013 18:56:13 +0200 -Subject: wined3d: Use an event to block the worker thread when it is idle. - -I could not find a canonical implementation for this. Suggestions are -welcome. - -The main goal was to avoid SetEvent / WaitForSingleObject / ResetEvent -calls at all costs. They go straight to wineserver, bringing it to 25% -CPU time and cutting framerates in half. Hence the extra BOOL to tell -cs_submit when to set the event. - -Finding the correct spin count is tricky. The value I set is high enough -to prevent 3DMark2001 car chase high detail from waiting. This benchmark -maps a lot of in-use managed buffers and thus waits for the CS. But what -the ideal number is depends a lot on the game and CPU. - -A better heuristic is needed. E.g. we could tell the worker thread when -the main thread is waiting for a resource to become idle and avoid -waiting for the event in that case. We may have to use POSIX -synchronization primitives for efficiency. On the other hand, the -current implementation probably still spins way too much for an -application that throttles the framerate to 30 fps by waiting in its own -code. So it is probably only good enough for Microsoft Powerpoint. - -We should also think about blocking the main thread with events if it is -waiting for the worker thread when waiting for resources, the swap -counter or space in the command Stream. This should preserve power when -vsync is turned on. ---- - dlls/wined3d/cs.c | 51 +++++++++++++++++++++++++++++++++++++++--- - dlls/wined3d/wined3d_private.h | 5 +++++ - 2 files changed, 53 insertions(+), 3 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 489fad0..8cbca6c 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -539,6 +539,9 @@ static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - /* There is only one thread writing to queue.head, InterlockedExchange - * is used for the memory barrier. */ - InterlockedExchange(&cs->queue.head, new_val); -+ -+ if (InterlockedCompareExchange(&cs->waiting_for_event, FALSE, TRUE)) -+ SetEvent(cs->event); - } - - static void wined3d_cs_mt_submit_prio(struct wined3d_cs *cs, size_t size) -@@ -547,6 +550,9 @@ static void wined3d_cs_mt_submit_prio(struct wined3d_cs *cs, size_t size) - /* There is only one thread writing to queue.head, InterlockedExchange - * is used for the memory barrier. */ - InterlockedExchange(&cs->prio_queue.head, new_val); -+ -+ if (InterlockedCompareExchange(&cs->waiting_for_event, FALSE, TRUE)) -+ SetEvent(cs->event); - } - - static UINT wined3d_cs_exec_nop(struct wined3d_cs *cs, const void *data) -@@ -2826,6 +2832,34 @@ static inline void poll_queries(struct wined3d_cs *cs) - } - } - -+static inline BOOL queue_is_empty(const struct wined3d_cs_queue *queue) -+{ -+ return *((volatile LONG *)&queue->head) == queue->tail; -+} -+ -+static void wined3d_cs_wait_event(struct wined3d_cs *cs) -+{ -+ InterlockedExchange(&cs->waiting_for_event, TRUE); -+ -+ /* The main thread might enqueue a finish command and block on it -+ * after the worker thread decided to enter wined3d_cs_wait_event -+ * and before waiting_for_event was set to TRUE. Check again if -+ * the queues are empty */ -+ if (!queue_is_empty(&cs->prio_queue) || !queue_is_empty(&cs->queue)) -+ { -+ /* The main thread might have signalled the event, or be in the process -+ * of doing so. Wait for the event to reset it. ResetEvent is not good -+ * because the main thread might be beween the waiting_for_event reset -+ * and SignalEvent call. */ -+ if (!InterlockedCompareExchange(&cs->waiting_for_event, FALSE, FALSE)) -+ WaitForSingleObject(cs->event, INFINITE); -+ } -+ else -+ { -+ WaitForSingleObject(cs->event, INFINITE); -+ } -+} -+ - static DWORD WINAPI wined3d_cs_run(void *thread_param) - { - struct wined3d_cs *cs = thread_param; -@@ -2833,6 +2867,7 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) - LONG tail; - char poll = 0; - struct wined3d_cs_queue *queue; -+ unsigned int spin_count = 0; - - TRACE("Started.\n"); - -@@ -2848,21 +2883,27 @@ static DWORD WINAPI wined3d_cs_run(void *thread_param) - else - poll++; - -- if (*((volatile LONG *)&cs->prio_queue.head) != cs->prio_queue.tail) -+ if (!queue_is_empty(&cs->prio_queue)) - { - queue = &cs->prio_queue; - } -- else if (*((volatile LONG *)&cs->queue.head) != cs->queue.tail) -+ else if (!queue_is_empty(&cs->queue)) - { - queue = &cs->queue; -- if (*((volatile LONG *)&cs->prio_queue.head) != cs->prio_queue.tail) -+ if (!queue_is_empty(&cs->prio_queue)) - queue = &cs->prio_queue; - } - else - { -+ spin_count++; -+ if (spin_count >= WINED3D_CS_SPIN_COUNT && list_empty(&cs->query_poll_list)) -+ wined3d_cs_wait_event(cs); -+ - continue; - } - -+ spin_count = 0; -+ - tail = queue->tail; - opcode = *(const enum wined3d_cs_op *)&queue->data[tail]; - -@@ -2904,6 +2945,8 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) - { - cs->ops = &wined3d_cs_mt_ops; - -+ cs->event = CreateEventW(NULL, FALSE, FALSE, NULL); -+ - if (!(cs->thread = CreateThread(NULL, 0, wined3d_cs_run, cs, 0, NULL))) - { - ERR("Failed to create wined3d command stream thread.\n"); -@@ -2934,6 +2977,8 @@ void wined3d_cs_destroy(struct wined3d_cs *cs) - CloseHandle(cs->thread); - if (ret != WAIT_OBJECT_0) - ERR("Wait failed (%#x).\n", ret); -+ if (!CloseHandle(cs->event)) -+ ERR("Closing event failed.\n"); - } - - HeapFree(GetProcessHeap(), 0, cs); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 2f7dd75..63b67da 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2583,6 +2583,8 @@ struct wined3d_cs_list - }; - - #define WINED3D_CS_QUEUE_SIZE 0x100000 -+#define WINED3D_CS_SPIN_COUNT 10000000 -+ - struct wined3d_cs_queue - { - LONG head, tail; -@@ -2612,6 +2614,9 @@ struct wined3d_cs - - LONG pending_presents; - struct list query_poll_list; -+ -+ HANDLE event; -+ BOOL waiting_for_event; - }; - - struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0146-wined3d-Completely-reset-the-state-on-reset.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0146-wined3d-Completely-reset-the-state-on-reset.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0146-wined3d-Completely-reset-the-state-on-reset.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0146-wined3d-Completely-reset-the-state-on-reset.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,24 @@ +From eb14a8f5c8dc07cda57b588e11f4b3381a340dcb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 10 Jan 2014 17:57:03 +0100 +Subject: wined3d: Completely reset the state on reset. + +--- + dlls/wined3d/device.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 278bbdc..62b0625 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -4531,6 +4531,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + } + wined3d_cs_emit_reset_state(device->cs); + state_cleanup(&device->state); ++ memset(&device->state, 0, sizeof(device->state)); + + if (device->d3d_initialized) + delete_opengl_contexts(device, swapchain); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0146-wined3d-Fence-preload-operations.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0146-wined3d-Fence-preload-operations.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0146-wined3d-Fence-preload-operations.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0146-wined3d-Fence-preload-operations.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -From 4a770e26268a89e0f211b42dfdd857f3180bb73e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 24 Oct 2013 22:38:26 +0200 -Subject: wined3d: Fence preload operations. - -Otherwise texture data might get lost, thanks to surface/volume_evict_sysmem: - -1) preload(texture) -2) map(texture) - -> Loads sysmem / sets it with discard map. -3) unmap(texture) - -> enqueues a resource_changed operation -4) preload is executed. - -> Uploads data written in 3. Discards sysmem. Questionable if - DISCARD was passed, but without it, no harm done. - -> texture is only up to date location. -5) resource_changed executed. - -> Discards texture. - -And data is lost. This patch prevents that by stalling the map until the -PreLoad is done. - -What's left open is finding out why anyone (I'm looking at you EVE -online) preloads a texture right before mapping it... ---- - dlls/wined3d/cs.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 8cbca6c..b152a0d 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -2145,6 +2145,8 @@ static UINT wined3d_cs_exec_texture_preload(struct wined3d_cs *cs, const void *d - wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); - context_release(context); - -+ wined3d_resource_dec_fence(&texture->resource); -+ - return sizeof(*op); - } - -@@ -2156,6 +2158,8 @@ void wined3d_cs_emit_texture_preload(struct wined3d_cs *cs, struct wined3d_textu - op->opcode = WINED3D_CS_OP_TEXTURE_PRELOAD; - op->texture = texture; - -+ wined3d_resource_inc_fence(&texture->resource); -+ - cs->ops->submit(cs, sizeof(*op)); - } - -@@ -2168,6 +2172,8 @@ static UINT wined3d_cs_exec_surface_preload(struct wined3d_cs *cs, const void *d - wined3d_texture_preload(op->surface->container); - context_release(context); - -+ wined3d_resource_dec_fence(&op->surface->container->resource); -+ - return sizeof(*op); - } - -@@ -2179,6 +2185,8 @@ void wined3d_cs_emit_surface_preload(struct wined3d_cs *cs, struct wined3d_surfa - op->opcode = WINED3D_CS_OP_SURFACE_PRELOAD; - op->surface = surface; - -+ wined3d_resource_inc_fence(&op->surface->container->resource); -+ - cs->ops->submit(cs, sizeof(*op)); - } - -@@ -2300,6 +2308,8 @@ static UINT wined3d_cs_exec_buffer_preload(struct wined3d_cs *cs, const void *da - buffer_internal_preload(op->buffer, context, NULL); - context_release(context); - -+ wined3d_resource_dec_fence(&op->buffer->resource); -+ - return sizeof(*op); - } - -@@ -2311,6 +2321,8 @@ void wined3d_cs_emit_buffer_preload(struct wined3d_cs *cs, struct wined3d_buffer - op->opcode = WINED3D_CS_OP_BUFFER_PRELOAD; - op->buffer = buffer; - -+ wined3d_resource_inc_fence(&buffer->resource); -+ - cs->ops->submit(cs, sizeof(*op)); - } - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0147-d3d8-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0147-d3d8-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0147-d3d8-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0147-d3d8-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -From c8083ad9f76ddba995df169c8b2f3486e81bbe02 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 20 Nov 2013 18:04:50 +0100 -Subject: d3d8/tests: D3DLOCK_NO_DIRTY_UPDATE on managed textures is - temporarily broken. - ---- - dlls/d3d8/tests/visual.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c -index a8a771e..9535b69 100644 ---- a/dlls/d3d8/tests/visual.c -+++ b/dlls/d3d8/tests/visual.c -@@ -4998,7 +4998,7 @@ static void add_dirty_rect_test(void) - fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE); - add_dirty_rect_test_draw(device); - color = getPixelColor(device, 320, 240); -- ok(color_match(color, 0x00ff0000, 1), -+ todo_wine ok(color_match(color, 0x00ff0000, 1), - "Expected color 0x00ff0000, got 0x%08x.\n", color); - hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL); - ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0147-wined3d-Send-getdc-and-releasedc-through-the-command.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0147-wined3d-Send-getdc-and-releasedc-through-the-command.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0147-wined3d-Send-getdc-and-releasedc-through-the-command.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0147-wined3d-Send-getdc-and-releasedc-through-the-command.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,302 @@ +From f51b464c3100bfdea3de7e6dde646f97e09fccb6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Sun, 16 Mar 2014 14:13:42 +0100 +Subject: wined3d: Send getdc and releasedc through the command stream. + +As with the palette patch just a cheap workaround for a context +activation bug I just regret that I didn't describe more verbously +earlier. I forgot what it was about exactly and can't be bothered to +investigate atm. +--- + dlls/wined3d/cs.c | 58 ++++++++++++++++++++++++++++++++++++++++ + dlls/wined3d/surface.c | 56 +++++++++++++++++++++++++++++++++++++++ + dlls/wined3d/texture.c | 60 +++--------------------------------------- + dlls/wined3d/wined3d_private.h | 4 +++ + 4 files changed, 121 insertions(+), 57 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 0aab83b..c135ece 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -90,6 +90,8 @@ enum wined3d_cs_op + WINED3D_CS_OP_CREATE_DUMMY_TEXTURES, + WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT, + WINED3D_CS_OP_DELETE_GL_CONTEXTS, ++ WINED3D_CS_OP_GETDC, ++ WINED3D_CS_OP_RELEASEDC, + WINED3D_CS_OP_STOP, + }; + +@@ -536,6 +538,18 @@ struct wined3d_cs_delete_gl_contexts + struct wined3d_swapchain *swapchain; + }; + ++struct wined3d_cs_getdc ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_surface *surface; ++}; ++ ++struct wined3d_cs_releasedc ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_surface *surface; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2661,6 +2675,48 @@ void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, struct wined3 + cs->ops->finish(cs); + } + ++static UINT wined3d_cs_exec_getdc(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_getdc *op = data; ++ ++ wined3d_surface_getdc_cs(op->surface); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) ++{ ++ struct wined3d_cs_getdc *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_GETDC; ++ op->surface = surface; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++ cs->ops->finish(cs); ++} ++ ++static UINT wined3d_cs_exec_releasedc(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_releasedc *op = data; ++ ++ wined3d_surface_releasedc_cs(op->surface); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) ++{ ++ struct wined3d_cs_releasedc *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_RELEASEDC; ++ op->surface = surface; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++ cs->ops->finish(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2729,6 +2785,8 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, + /* WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT */ wined3d_cs_exec_create_swapchain_context, + /* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts, ++ /* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc, ++ /* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 822f36f..d70e310 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -2456,6 +2456,62 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, + return wined3d_resource_map(&surface->resource, map_desc, box, flags); + } + ++void wined3d_surface_getdc_cs(struct wined3d_surface *surface) ++{ ++ HRESULT hr; ++ struct wined3d_device *device = surface->resource.device; ++ struct wined3d_context *context = NULL; ++ ++ if (device->d3d_initialized) ++ context = context_acquire(device, NULL); ++ ++ /* Create a DIB section if there isn't a dc yet. */ ++ if (!surface->hDC) ++ { ++ if (FAILED(hr = surface_create_dib_section(surface))) ++ { ++ if (context) ++ context_release(context); ++ return; ++ } ++ if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY ++ || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM ++ || surface->resource.buffer)) ++ surface->resource.map_binding = WINED3D_LOCATION_DIB; ++ } ++ ++ wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_DIB); ++ wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_DIB); ++ ++ if (context) ++ context_release(context); ++} ++ ++void wined3d_surface_releasedc_cs(struct wined3d_surface *surface) ++{ ++ if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM ++ && surface->resource.map_binding != WINED3D_LOCATION_DIB)) ++ { ++ /* The game Salammbo modifies the surface contents without mapping the surface between ++ * a GetDC/ReleaseDC operation and flipping the surface. If the DIB remains the active ++ * copy and is copied to the screen, this update, which draws the mouse pointer, is lost. ++ * Do not only copy the DIB to the map location, but also make sure the map location is ++ * copied back to the DIB in the next getdc call. ++ * ++ * The same consideration applies to user memory surfaces. */ ++ struct wined3d_device *device = surface->resource.device; ++ struct wined3d_context *context = NULL; ++ ++ if (device->d3d_initialized) ++ context = context_acquire(device, NULL); ++ ++ wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); ++ wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_DIB); ++ if (context) ++ context_release(context); ++ } ++} ++ + static void read_from_framebuffer(struct wined3d_surface *surface, + struct wined3d_context *old_ctx, DWORD dst_location) + { +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index d17a6e1..a9dbf42 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -1561,10 +1561,8 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct + HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc) + { + struct wined3d_device *device = texture->resource.device; +- struct wined3d_context *context = NULL; + struct wined3d_resource *sub_resource; + struct wined3d_surface *surface; +- HRESULT hr; + + TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc); + +@@ -1585,14 +1583,6 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i + return WINED3DERR_INVALIDCALL; + } + +- if (wined3d_settings.cs_multithreaded) +- { +- struct wined3d_device *device = surface->resource.device; +- FIXME("Waiting for cs.\n"); +- wined3d_cs_emit_glfinish(device->cs); +- device->cs->ops->finish(device->cs); +- } +- + /* Give more detailed info for ddraw. */ + if (surface->flags & SFLAG_DCINUSE) + return WINEDDERR_DCALREADYCREATED; +@@ -1601,43 +1591,18 @@ HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned i + if (surface->resource.map_count) + return WINED3DERR_INVALIDCALL; + +- if (device->d3d_initialized) +- context = context_acquire(device, NULL); +- +- /* Create a DIB section if there isn't a dc yet. */ +- if (!surface->hDC) +- { +- if (FAILED(hr = surface_create_dib_section(surface))) +- { +- if (context) +- context_release(context); +- return WINED3DERR_INVALIDCALL; +- } +- if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY +- || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM +- || surface->resource.buffer)) +- surface->resource.map_binding = WINED3D_LOCATION_DIB; +- } +- +- wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_DIB); +- wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_DIB); +- +- if (context) +- context_release(context); +- + surface->flags |= SFLAG_DCINUSE; + surface->resource.map_count++; +- ++ wined3d_cs_emit_getdc(device->cs, surface); + *dc = surface->hDC; + TRACE("Returning dc %p.\n", *dc); + +- return WINED3D_OK; ++ return *dc ? WINED3D_OK : WINED3DERR_INVALIDCALL; + } + + HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc) + { + struct wined3d_device *device = texture->resource.device; +- struct wined3d_context *context = NULL; + struct wined3d_resource *sub_resource; + struct wined3d_surface *surface; + +@@ -1667,26 +1632,7 @@ HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsign + surface->resource.map_count--; + surface->flags &= ~SFLAG_DCINUSE; + +- if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY +- || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM +- && surface->resource.map_binding != WINED3D_LOCATION_DIB)) +- { +- /* The game Salammbo modifies the surface contents without mapping the surface between +- * a GetDC/ReleaseDC operation and flipping the surface. If the DIB remains the active +- * copy and is copied to the screen, this update, which draws the mouse pointer, is lost. +- * Do not only copy the DIB to the map location, but also make sure the map location is +- * copied back to the DIB in the next getdc call. +- * +- * The same consideration applies to user memory surfaces. */ +- +- if (device->d3d_initialized) +- context = context_acquire(device, NULL); +- +- wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); +- wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_DIB); +- if (context) +- context_release(context); +- } ++ wined3d_cs_emit_releasedc(device->cs, surface); + + return WINED3D_OK; + } +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 5bb6a21..0e0e3fe 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2623,6 +2623,8 @@ void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect_ + const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; + BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) DECLSPEC_HIDDEN; + void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; ++void wined3d_surface_getdc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; ++void wined3d_surface_releasedc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; + + void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, + const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; +@@ -2895,6 +2897,8 @@ HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, + struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, + struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0148-d3d9-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0148-d3d9-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0148-d3d9-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0148-d3d9-tests-D3DLOCK_NO_DIRTY_UPDATE-on-managed-textur.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -From 1bdcaa3e831f627806a00a07fb92ef28502c4f7a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 20 Nov 2013 18:06:02 +0100 -Subject: d3d9/tests: D3DLOCK_NO_DIRTY_UPDATE on managed textures is - temporarily broken. - ---- - dlls/d3d9/tests/visual.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c -index d1aa3d4..6b28d14 100644 ---- a/dlls/d3d9/tests/visual.c -+++ b/dlls/d3d9/tests/visual.c -@@ -16457,7 +16457,7 @@ static void add_dirty_rect_test(void) - fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE); - add_dirty_rect_test_draw(device); - color = getPixelColor(device, 320, 240); -- ok(color_match(color, 0x00ff0000, 1), -+ todo_wine ok(color_match(color, 0x00ff0000, 1), - "Expected color 0x00ff0000, got 0x%08x.\n", color); - hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); - ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0148-wined3d-Set-map_heap_memory-NULL-when-allocating-a-P.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0148-wined3d-Set-map_heap_memory-NULL-when-allocating-a-P.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0148-wined3d-Set-map_heap_memory-NULL-when-allocating-a-P.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0148-wined3d-Set-map_heap_memory-NULL-when-allocating-a-P.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,31 @@ +From 80c6dcd25ef96df6885a55cdd23900ae55f30bab Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 5 Jun 2014 13:07:27 +0200 +Subject: wined3d: Set map_heap_memory = NULL when allocating a PBO. + +Otherwise the next unmap will re-assign it with the resource_changed +message. Freeing the actual memory and setting the read pointer to 0 is +the task of the worker thread. + +Wined3d_resource_prepare_bo is only called if the map binding is +LOCATION_BUFFER, and map_heap_memory is only used if the map binding is +LOCATION_SYSMEM. +--- + dlls/wined3d/resource.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 671ab50..1dff0ed 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -616,6 +616,7 @@ static void wined3d_resource_prepare_bo(struct wined3d_resource *resource, struc + GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); + resource->map_buffer = resource->buffer; + TRACE("Created GL buffer %u for resource %p.\n", resource->buffer->name, resource); ++ resource->map_heap_memory = NULL; + } + + BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0149-wined3d-Completely-reset-the-state-on-reset.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0149-wined3d-Completely-reset-the-state-on-reset.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0149-wined3d-Completely-reset-the-state-on-reset.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0149-wined3d-Completely-reset-the-state-on-reset.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -From eb14a8f5c8dc07cda57b588e11f4b3381a340dcb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 10 Jan 2014 17:57:03 +0100 -Subject: wined3d: Completely reset the state on reset. - ---- - dlls/wined3d/device.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 278bbdc..62b0625 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -4531,6 +4531,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - } - wined3d_cs_emit_reset_state(device->cs); - state_cleanup(&device->state); -+ memset(&device->state, 0, sizeof(device->state)); - - if (device->d3d_initialized) - delete_opengl_contexts(device, swapchain); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0149-wined3d-Wait-only-for-the-buffer-to-be-idle.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0149-wined3d-Wait-only-for-the-buffer-to-be-idle.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0149-wined3d-Wait-only-for-the-buffer-to-be-idle.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0149-wined3d-Wait-only-for-the-buffer-to-be-idle.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,27 @@ +From 82ec316a058cc2e1894fb64eee1249ff663f112e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 22 Aug 2014 15:52:50 +0200 +Subject: wined3d: Wait only for the buffer to be idle. + +This got lost somewhere during the patch reordering. +--- + dlls/wined3d/buffer.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 15ed760..c0f96e3 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -1051,8 +1051,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + } + else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY))) + { +- FIXME("waiting for cs, flags 0x%04x.\n", flags); +- device->cs->ops->finish(device->cs); ++ wined3d_resource_wait_fence(&buffer->resource); + } + } + +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0150-wined3d-Add-a-comment-about-worker-thread-lag.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0150-wined3d-Add-a-comment-about-worker-thread-lag.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0150-wined3d-Add-a-comment-about-worker-thread-lag.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0150-wined3d-Add-a-comment-about-worker-thread-lag.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,31 @@ +From 7cfd19b8d052ed99f3060d5cab1349ec33e162ad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Mon, 25 Aug 2014 19:57:42 +0200 +Subject: wined3d: Add a comment about worker thread lag. + +--- + dlls/wined3d/cs.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 44930c1..9b890ae 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -677,6 +677,14 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw + + cs->ops->submit(cs, sizeof(*op)); + ++ /* D3D10 documentation suggests that Windows allows the game to run ++ * 3 frames ahead of the GPU. Increasing this above 1 causes uneven ++ * animation in some games, most notably StarCraft II. The framerates ++ * don't show this problem. The issue is more noticable with vsync ++ * on, but also happens with vsync off. ++ * ++ * In Counter-Strike: Source a frame difference of 3 causes noticable ++ * input delay that makes the game unplayable. */ + while (pending > 1) + pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0); + } +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0150-wined3d-Send-getdc-and-releasedc-through-the-command.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0150-wined3d-Send-getdc-and-releasedc-through-the-command.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0150-wined3d-Send-getdc-and-releasedc-through-the-command.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0150-wined3d-Send-getdc-and-releasedc-through-the-command.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,274 +0,0 @@ -From 660da782e4f462082b582638dab578af11c65b5f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Sun, 16 Mar 2014 14:13:42 +0100 -Subject: wined3d: Send getdc and releasedc through the command stream. - -As with the palette patch just a cheap workaround for a context -activation bug I just regret that I didn't describe more verbously -earlier. I forgot what it was about exactly and can't be bothered to -investigate atm. ---- - dlls/wined3d/cs.c | 58 +++++++++++++++++++++++++ - dlls/wined3d/surface.c | 96 +++++++++++++++++++++--------------------- - dlls/wined3d/wined3d_private.h | 4 ++ - 3 files changed, 110 insertions(+), 48 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 56e5e1c..63040f6 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -91,6 +91,8 @@ enum wined3d_cs_op - WINED3D_CS_OP_CREATE_DUMMY_TEXTURES, - WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT, - WINED3D_CS_OP_DELETE_GL_CONTEXTS, -+ WINED3D_CS_OP_GETDC, -+ WINED3D_CS_OP_RELEASEDC, - WINED3D_CS_OP_STOP, - }; - -@@ -543,6 +545,18 @@ struct wined3d_cs_delete_gl_contexts - struct wined3d_swapchain *swapchain; - }; - -+struct wined3d_cs_getdc -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_surface *surface; -+}; -+ -+struct wined3d_cs_releasedc -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_surface *surface; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2694,6 +2708,48 @@ void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, struct wined3 - cs->ops->finish(cs); - } - -+static UINT wined3d_cs_exec_getdc(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_getdc *op = data; -+ -+ wined3d_surface_getdc_cs(op->surface); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) -+{ -+ struct wined3d_cs_getdc *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_GETDC; -+ op->surface = surface; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+ cs->ops->finish(cs); -+} -+ -+static UINT wined3d_cs_exec_releasedc(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_releasedc *op = data; -+ -+ wined3d_surface_releasedc_cs(op->surface); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) -+{ -+ struct wined3d_cs_releasedc *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_RELEASEDC; -+ op->surface = surface; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+ cs->ops->finish(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2763,6 +2819,8 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, - /* WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT */ wined3d_cs_exec_create_swapchain_context, - /* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts, -+ /* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc, -+ /* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index f35f56e..3d42543 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -2497,48 +2497,23 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, - return wined3d_resource_map(&surface->resource, map_desc, box, flags); - } - --HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) -+void wined3d_surface_getdc_cs(struct wined3d_surface *surface) - { -- HRESULT hr; - struct wined3d_device *device = surface->resource.device; - struct wined3d_context *context = NULL; - -- TRACE("surface %p, dc %p.\n", surface, dc); -- -- if (!(surface->container->resource.format_flags & WINED3DFMT_FLAG_GETDC)) -- { -- WARN("Cannot use GetDC on a %s surface.\n", debug_d3dformat(surface->resource.format->id)); -- return WINED3DERR_INVALIDCALL; -- } -- -- if (wined3d_settings.cs_multithreaded) -- { -- struct wined3d_device *device = surface->resource.device; -- FIXME("Waiting for cs.\n"); -- wined3d_cs_emit_glfinish(device->cs); -- device->cs->ops->finish(device->cs); -- } -- -- /* Give more detailed info for ddraw. */ -- if (surface->flags & SFLAG_DCINUSE) -- return WINEDDERR_DCALREADYCREATED; -- -- /* Can't GetDC if the surface is locked. */ -- if (surface->resource.map_count) -- return WINED3DERR_INVALIDCALL; -- - if (device->d3d_initialized) - context = context_acquire(surface->resource.device, NULL); - - /* Create a DIB section if there isn't a dc yet. */ - if (!surface->hDC) - { -- hr = surface_create_dib_section(surface); -+ HRESULT hr = surface_create_dib_section(surface); - if (FAILED(hr)) - { - if (context) - context_release(context); -- return WINED3DERR_INVALIDCALL; -+ return; - } - if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY - || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM -@@ -2551,35 +2526,40 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) - - if (context) - context_release(context); -- -- surface->flags |= SFLAG_DCINUSE; -- surface->resource.map_count++; -- -- *dc = surface->hDC; -- TRACE("Returning dc %p.\n", *dc); -- -- return WINED3D_OK; - } - --HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) -+HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) - { -- TRACE("surface %p, dc %p.\n", surface, dc); -+ struct wined3d_device *device = surface->resource.device; - -- if (!(surface->flags & SFLAG_DCINUSE)) -- return WINEDDERR_NODC; -+ TRACE("surface %p, dc %p.\n", surface, dc); - -- if (surface->hDC != dc) -+ if (!(surface->container->resource.format_flags & WINED3DFMT_FLAG_GETDC)) - { -- WARN("Application tries to release invalid DC %p, surface DC is %p.\n", -- dc, surface->hDC); -- return WINEDDERR_NODC; -+ WARN("Cannot use GetDC on a %s surface.\n", debug_d3dformat(surface->resource.format->id)); -+ return WINED3DERR_INVALIDCALL; - } - -- surface->resource.map_count--; -- surface->flags &= ~SFLAG_DCINUSE; -+ /* Give more detailed info for ddraw. */ -+ if (surface->flags & SFLAG_DCINUSE) -+ return WINEDDERR_DCALREADYCREATED; -+ -+ /* Can't GetDC if the surface is locked. */ -+ if (surface->resource.map_count) -+ return WINED3DERR_INVALIDCALL; -+ -+ surface->flags |= SFLAG_DCINUSE; -+ surface->resource.map_count++; -+ wined3d_cs_emit_getdc(device->cs, surface); -+ *dc = surface->hDC; -+ TRACE("Returning dc %p.\n", *dc); -+ -+ return *dc ? WINED3D_OK : WINED3DERR_INVALIDCALL; -+} - -- if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY -- || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM -+void wined3d_surface_releasedc_cs(struct wined3d_surface *surface) -+{ -+ if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM - && surface->resource.map_binding != WINED3D_LOCATION_DIB)) - { - /* The game Salammbo modifies the surface contents without mapping the surface between -@@ -2600,6 +2580,26 @@ HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) - if (context) - context_release(context); - } -+} -+ -+HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) -+{ -+ TRACE("surface %p, dc %p.\n", surface, dc); -+ -+ if (!(surface->flags & SFLAG_DCINUSE)) -+ return WINEDDERR_NODC; -+ -+ if (surface->hDC != dc) -+ { -+ WARN("Application tries to release invalid DC %p, surface DC is %p.\n", -+ dc, surface->hDC); -+ return WINEDDERR_NODC; -+ } -+ -+ surface->resource.map_count--; -+ surface->flags &= ~SFLAG_DCINUSE; -+ -+ wined3d_cs_emit_releasedc(surface->resource.device->cs, surface); - - return WINED3D_OK; - } -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 7307746..d68bb48 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2540,6 +2540,8 @@ void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect_ - const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; - BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) DECLSPEC_HIDDEN; - void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -+void wined3d_surface_getdc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -+void wined3d_surface_releasedc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; - - void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, - const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -@@ -2815,6 +2817,8 @@ HRESULT wined3d_cs_emit_create_swapchain_context(struct wined3d_cs *cs, - struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; - void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, - struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.6.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0151-wined3d-Remove-the-texture-destroy-glFinish.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0151-wined3d-Remove-the-texture-destroy-glFinish.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0151-wined3d-Remove-the-texture-destroy-glFinish.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0151-wined3d-Remove-the-texture-destroy-glFinish.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,32 @@ +From c064211d94884f2c131c5496e60f591511c5462d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 28 Aug 2014 15:02:12 +0200 +Subject: wined3d: Remove the texture destroy glFinish. + +This should work now that surface_decref is essentially gone and the +container is never unset. +--- + dlls/wined3d/texture.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +index 09ac38f..6f78292 100644 +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -146,13 +146,6 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture) + + TRACE("texture %p.\n", texture); + +- /* Because sub_resource_cleanup interferes with GL resources */ +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- device->cs->ops->finish(device->cs); +- } +- + for (i = 0; i < sub_count; ++i) + { + struct wined3d_resource *sub_resource = texture->sub_resources[i]; +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0151-wined3d-Set-map_heap_memory-NULL-when-allocating-a-P.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0151-wined3d-Set-map_heap_memory-NULL-when-allocating-a-P.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0151-wined3d-Set-map_heap_memory-NULL-when-allocating-a-P.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0151-wined3d-Set-map_heap_memory-NULL-when-allocating-a-P.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -From 80c6dcd25ef96df6885a55cdd23900ae55f30bab Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 5 Jun 2014 13:07:27 +0200 -Subject: wined3d: Set map_heap_memory = NULL when allocating a PBO. - -Otherwise the next unmap will re-assign it with the resource_changed -message. Freeing the actual memory and setting the read pointer to 0 is -the task of the worker thread. - -Wined3d_resource_prepare_bo is only called if the map binding is -LOCATION_BUFFER, and map_heap_memory is only used if the map binding is -LOCATION_SYSMEM. ---- - dlls/wined3d/resource.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 671ab50..1dff0ed 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -616,6 +616,7 @@ static void wined3d_resource_prepare_bo(struct wined3d_resource *resource, struc - GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context); - resource->map_buffer = resource->buffer; - TRACE("Created GL buffer %u for resource %p.\n", resource->buffer->name, resource); -+ resource->map_heap_memory = NULL; - } - - BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0152-wined3d-Move-FBO-destruction-into-the-worker-thread.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0152-wined3d-Move-FBO-destruction-into-the-worker-thread.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0152-wined3d-Move-FBO-destruction-into-the-worker-thread.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0152-wined3d-Move-FBO-destruction-into-the-worker-thread.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,40 @@ +From 05b16589d0f658e929eaafb416d4b19bd88bb47d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 28 Aug 2014 16:09:45 +0200 +Subject: wined3d: Move FBO destruction into the worker thread. + +This protects the context array against races. +--- + dlls/wined3d/device.c | 2 -- + dlls/wined3d/resource.c | 2 ++ + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 62b0625..b5ce2c3 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -4638,8 +4638,6 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso + + TRACE("device %p, resource %p, type %s.\n", device, resource, debug_d3dresourcetype(type)); + +- context_resource_released(device, resource, type); +- + switch (type) + { + case WINED3D_RTYPE_SURFACE: +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index 8069160..cd60356 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -159,6 +159,8 @@ void wined3d_resource_free_bo(struct wined3d_resource *resource) + + void wined3d_resource_cleanup_cs(struct wined3d_resource *resource) + { ++ context_resource_released(resource->device, resource, resource->type); ++ + if (resource->buffer) + wined3d_resource_free_bo(resource); + +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0152-wined3d-Wait-only-for-the-buffer-to-be-idle.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0152-wined3d-Wait-only-for-the-buffer-to-be-idle.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0152-wined3d-Wait-only-for-the-buffer-to-be-idle.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0152-wined3d-Wait-only-for-the-buffer-to-be-idle.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -From 82ec316a058cc2e1894fb64eee1249ff663f112e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 22 Aug 2014 15:52:50 +0200 -Subject: wined3d: Wait only for the buffer to be idle. - -This got lost somewhere during the patch reordering. ---- - dlls/wined3d/buffer.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 15ed760..c0f96e3 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -1051,8 +1051,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - } - else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY))) - { -- FIXME("waiting for cs, flags 0x%04x.\n", flags); -- device->cs->ops->finish(device->cs); -+ wined3d_resource_wait_fence(&buffer->resource); - } - } - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0153-wined3d-Add-a-comment-about-worker-thread-lag.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0153-wined3d-Add-a-comment-about-worker-thread-lag.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0153-wined3d-Add-a-comment-about-worker-thread-lag.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0153-wined3d-Add-a-comment-about-worker-thread-lag.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -From 7cfd19b8d052ed99f3060d5cab1349ec33e162ad Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Mon, 25 Aug 2014 19:57:42 +0200 -Subject: wined3d: Add a comment about worker thread lag. - ---- - dlls/wined3d/cs.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 44930c1..9b890ae 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -677,6 +677,14 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw - - cs->ops->submit(cs, sizeof(*op)); - -+ /* D3D10 documentation suggests that Windows allows the game to run -+ * 3 frames ahead of the GPU. Increasing this above 1 causes uneven -+ * animation in some games, most notably StarCraft II. The framerates -+ * don't show this problem. The issue is more noticable with vsync -+ * on, but also happens with vsync off. -+ * -+ * In Counter-Strike: Source a frame difference of 3 causes noticable -+ * input delay that makes the game unplayable. */ - while (pending > 1) - pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0); - } --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0153-wined3d-Don-t-incref-decref-textures-in-color-depth-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0153-wined3d-Don-t-incref-decref-textures-in-color-depth-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0153-wined3d-Don-t-incref-decref-textures-in-color-depth-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0153-wined3d-Don-t-incref-decref-textures-in-color-depth-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,160 @@ +From 9ceff8564c938a798238a8ff91ab75ad2659eb32 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 28 Aug 2014 16:10:09 +0200 +Subject: wined3d: Don't incref / decref textures in color / depth fill blits. + +See comment in the code. The solution is not particularly nice. A better +approach may be to handle them in ddraw, where we have a permanent view +for the surface. +--- + dlls/wined3d/surface.c | 59 +++++++++++++++++++++--------------------- + dlls/wined3d/view.c | 20 -------------- + dlls/wined3d/wined3d_private.h | 1 - + 3 files changed, 30 insertions(+), 50 deletions(-) + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index bff8df5..aa844fc 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -911,8 +911,8 @@ static HRESULT wined3d_surface_depth_fill(struct wined3d_surface *surface, const + { + struct wined3d_resource *resource = &surface->container->resource; + struct wined3d_device *device = resource->device; +- struct wined3d_rendertarget_view_desc view_desc; +- struct wined3d_rendertarget_view *view; ++ struct wined3d_rendertarget_view view; ++ struct wined3d_texture *texture = surface->container; + const struct blit_shader *blitter; + HRESULT hr; + +@@ -923,19 +923,17 @@ static HRESULT wined3d_surface_depth_fill(struct wined3d_surface *surface, const + return WINED3DERR_INVALIDCALL; + } + +- view_desc.format_id = resource->format->id; +- view_desc.u.texture.level_idx = surface->texture_level; +- view_desc.u.texture.layer_idx = surface->texture_layer; +- view_desc.u.texture.layer_count = 1; +- if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, +- resource, NULL, &wined3d_null_parent_ops, &view))) +- { +- ERR("Failed to create rendertarget view, hr %#x.\n", hr); +- return hr; +- } ++ view.resource = &surface->container->resource; ++ view.parent = NULL; ++ view.parent_ops = &wined3d_null_parent_ops; ++ view.format = surface->resource.format; ++ view.buffer_offset = 0; ++ view.width = surface->resource.width; ++ view.height = surface->resource.height; ++ view.depth = 1; ++ view.sub_resource_idx = surface->texture_layer * texture->level_count + surface->texture_level; + +- hr = blitter->depth_fill(device, view, rect, depth); +- wined3d_rendertarget_view_decref_worker(view); ++ hr = blitter->depth_fill(device, &view, rect, depth); + + return hr; + } +@@ -3235,8 +3233,8 @@ HRESULT surface_color_fill(struct wined3d_surface *s, const RECT *rect, const st + { + struct wined3d_resource *resource = &s->container->resource; + struct wined3d_device *device = resource->device; +- struct wined3d_rendertarget_view_desc view_desc; +- struct wined3d_rendertarget_view *view; ++ struct wined3d_rendertarget_view view; ++ struct wined3d_texture *texture = s->container; + const struct blit_shader *blitter; + HRESULT hr; + +@@ -3247,19 +3245,22 @@ HRESULT surface_color_fill(struct wined3d_surface *s, const RECT *rect, const st + return WINED3DERR_INVALIDCALL; + } + +- view_desc.format_id = resource->format->id; +- view_desc.u.texture.level_idx = s->texture_level; +- view_desc.u.texture.layer_idx = s->texture_layer; +- view_desc.u.texture.layer_count = 1; +- if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, +- resource, NULL, &wined3d_null_parent_ops, &view))) +- { +- ERR("Failed to create rendertarget view, hr %#x.\n", hr); +- return hr; +- } ++ /* Can't incref / decref the resource here. This is executed inside the worker ++ * thread. Playing with the refcount here makes the worker thread visible to ++ * the client lib. Problems occur when the worker thread happens to hold the ++ * last reference and the resource destruction callbacks are called from the ++ * wrong thread. */ ++ view.resource = &texture->resource; ++ view.parent = NULL; ++ view.parent_ops = &wined3d_null_parent_ops; ++ view.format = s->resource.format; ++ view.buffer_offset = 0; ++ view.width = s->resource.width; ++ view.height = s->resource.height; ++ view.depth = 1; ++ view.sub_resource_idx = s->texture_layer * texture->level_count + s->texture_level; + +- hr = blitter->color_fill(device, view, rect, color); +- wined3d_rendertarget_view_decref_worker(view); ++ hr = blitter->color_fill(device, &view, rect, color); + + return hr; + } +@@ -4056,7 +4057,7 @@ static HRESULT ffp_blit_color_fill(struct wined3d_device *device, struct wined3d + const RECT *rect, const struct wined3d_color *color) + { + const RECT draw_rect = {0, 0, view->width, view->height}; +- struct wined3d_fb_state fb = {&view, NULL}; ++ struct wined3d_fb_state fb = {&view, NULL, 1}; + + device_clear_render_targets(device, 1, &fb, 1, rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0); + +diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c +index e4694af..f2134f4 100644 +--- a/dlls/wined3d/view.c ++++ b/dlls/wined3d/view.c +@@ -58,26 +58,6 @@ ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *v + return refcount; + } + +-/* Ugly hack for ffp_blit_depth_fill that allows destroying a view from inside the +- * worker thread. */ +-ULONG wined3d_rendertarget_view_decref_worker(struct wined3d_rendertarget_view *view) +-{ +- ULONG refcount = InterlockedDecrement(&view->refcount); +- +- TRACE("%p decreasing refcount to %u.\n", view, refcount); +- +- if (!refcount) +- { +- /* Call wined3d_object_destroyed() before releasing the resource, +- * since releasing the resource may end up destroying the parent. */ +- view->parent_ops->wined3d_object_destroyed(view->parent); +- wined3d_resource_decref(view->resource); +- wined3d_rendertarget_view_destroy(view); +- } +- +- return refcount; +-} +- + void * CDECL wined3d_rendertarget_view_get_parent(const struct wined3d_rendertarget_view *view) + { + TRACE("view %p.\n", view); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 929e7c7..0e0c8fa 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -3063,7 +3063,6 @@ static inline struct wined3d_surface *wined3d_rendertarget_view_get_surface( + return surface_from_resource(resource); + } + +-ULONG wined3d_rendertarget_view_decref_worker(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; + void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; + + struct wined3d_shader_resource_view +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0154-wined3d-Remove-the-texture-destroy-glFinish.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0154-wined3d-Remove-the-texture-destroy-glFinish.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0154-wined3d-Remove-the-texture-destroy-glFinish.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0154-wined3d-Remove-the-texture-destroy-glFinish.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -From c064211d94884f2c131c5496e60f591511c5462d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 28 Aug 2014 15:02:12 +0200 -Subject: wined3d: Remove the texture destroy glFinish. - -This should work now that surface_decref is essentially gone and the -container is never unset. ---- - dlls/wined3d/texture.c | 7 ------- - 1 file changed, 7 deletions(-) - -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c -index 09ac38f..6f78292 100644 ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -146,13 +146,6 @@ static void wined3d_texture_cleanup(struct wined3d_texture *texture) - - TRACE("texture %p.\n", texture); - -- /* Because sub_resource_cleanup interferes with GL resources */ -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- device->cs->ops->finish(device->cs); -- } -- - for (i = 0; i < sub_count; ++i) - { - struct wined3d_resource *sub_resource = texture->sub_resources[i]; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0154-Winex11-complain-about-glfinish.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0154-Winex11-complain-about-glfinish.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0154-Winex11-complain-about-glfinish.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0154-Winex11-complain-about-glfinish.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,32 @@ +From 7af302e360179e2ef395c66327876b276f30fe9f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 29 Aug 2014 12:12:11 +0200 +Subject: Winex11: complain about glfinish + +--- + dlls/winex11.drv/opengl.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c +index 3d0bd24..069dcc5 100644 +--- a/dlls/winex11.drv/opengl.c ++++ b/dlls/winex11.drv/opengl.c +@@ -1962,6 +1962,7 @@ static void wglFinish(void) + escape.code = X11DRV_FLUSH_GL_DRAWABLE; + escape.gl_drawable = 0; + ++ ERR("glFinish\n"); + if ((gl = get_gl_drawable( WindowFromDC( ctx->hdc ), 0 ))) + { + switch (gl->type) +@@ -1987,6 +1988,7 @@ static void wglFlush(void) + escape.code = X11DRV_FLUSH_GL_DRAWABLE; + escape.gl_drawable = 0; + ++ ERR("glFlush\n"); + if ((gl = get_gl_drawable( WindowFromDC( ctx->hdc ), 0 ))) + { + switch (gl->type) +-- +2.6.2 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0155-wined3d-Make-sure-the-new-window-is-set-up-before-se.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0155-wined3d-Make-sure-the-new-window-is-set-up-before-se.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0155-wined3d-Make-sure-the-new-window-is-set-up-before-se.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0155-wined3d-Make-sure-the-new-window-is-set-up-before-se.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,69 @@ +From 003aabc11ecba217dbf01cd479a9b4b9a9ec4464 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 29 Aug 2014 14:46:19 +0200 +Subject: wined3d: Make sure the new window is set up before setting up a + context. + +--- + dlls/wined3d/device.c | 31 +++++++++++++++++++++---------- + 1 file changed, 21 insertions(+), 10 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 1f02518..f5bc02a 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -4570,6 +4570,27 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + } + } + ++ /* Free implicit resources and wait for the command stream before modifying ++ * swapchain parameters. After modifying the swapchain parameters a new GL ++ * context may be acquired by the worker thread. This causes problems in the ++ * d3d8/9 test that passes a hidden window as the new device window. ++ * SetPixelFormat will call SetWindowPos inside the X11 driver, which sends ++ * a message to the window to query the icon. Since the worker thread is ++ * not the thread that created the window and the d3d8 test does not run ++ * an event loop this deadlocks. Set up the window first from the main thread ++ * before calling SetPixelFormat from the worker thread to avoid this. */ ++ if (device->auto_depth_stencil_view) ++ { ++ wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); ++ device->auto_depth_stencil_view = NULL; ++ } ++ if (device->back_buffer_view) ++ { ++ wined3d_rendertarget_view_decref(device->back_buffer_view); ++ device->back_buffer_view = NULL; ++ } ++ device->cs->ops->finish(device->cs); ++ + TRACE("New params:\n"); + TRACE("backbuffer_width %u\n", swapchain_desc->backbuffer_width); + TRACE("backbuffer_height %u\n", swapchain_desc->backbuffer_height); +@@ -4696,11 +4717,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + swapchain_desc->multisample_type, swapchain_desc->multisample_quality))) + return hr; + +- if (device->auto_depth_stencil_view) +- { +- wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); +- device->auto_depth_stencil_view = NULL; +- } + if (swapchain->desc.enable_auto_depth_stencil) + { + struct wined3d_resource_desc texture_desc; +@@ -4742,11 +4758,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + wined3d_device_set_depth_stencil_view(device, device->auto_depth_stencil_view); + } + +- if (device->back_buffer_view) +- { +- wined3d_rendertarget_view_decref(device->back_buffer_view); +- device->back_buffer_view = NULL; +- } + if (swapchain->desc.backbuffer_count) + { + view_desc.format_id = swapchain_desc->backbuffer_format; +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0155-wined3d-Move-FBO-destruction-into-the-worker-thread.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0155-wined3d-Move-FBO-destruction-into-the-worker-thread.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0155-wined3d-Move-FBO-destruction-into-the-worker-thread.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0155-wined3d-Move-FBO-destruction-into-the-worker-thread.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -From 05b16589d0f658e929eaafb416d4b19bd88bb47d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 28 Aug 2014 16:09:45 +0200 -Subject: wined3d: Move FBO destruction into the worker thread. - -This protects the context array against races. ---- - dlls/wined3d/device.c | 2 -- - dlls/wined3d/resource.c | 2 ++ - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 62b0625..b5ce2c3 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -4638,8 +4638,6 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso - - TRACE("device %p, resource %p, type %s.\n", device, resource, debug_d3dresourcetype(type)); - -- context_resource_released(device, resource, type); -- - switch (type) - { - case WINED3D_RTYPE_SURFACE: -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index 8069160..cd60356 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -159,6 +159,8 @@ void wined3d_resource_free_bo(struct wined3d_resource *resource) - - void wined3d_resource_cleanup_cs(struct wined3d_resource *resource) - { -+ context_resource_released(resource->device, resource, resource->type); -+ - if (resource->buffer) - wined3d_resource_free_bo(resource); - --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0156-wined3d-Don-t-incref-decref-textures-in-color-depth-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0156-wined3d-Don-t-incref-decref-textures-in-color-depth-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0156-wined3d-Don-t-incref-decref-textures-in-color-depth-.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0156-wined3d-Don-t-incref-decref-textures-in-color-depth-.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -From 54eb3e212afc243fef25a46017ae3d822014f336 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 28 Aug 2014 16:10:09 +0200 -Subject: wined3d: Don't incref / decref textures in color / depth fill blits. - -See comment in the code. The solution is not particularly nice. A better -approach may be to handle them in ddraw, where we have a permanent view -for the surface. ---- - dlls/wined3d/surface.c | 52 +++++++++++++++++++++++++----------------- - dlls/wined3d/view.c | 20 ---------------- - dlls/wined3d/wined3d_private.h | 1 - - 3 files changed, 31 insertions(+), 42 deletions(-) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 1ccbe35..82485f3 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -4124,19 +4124,26 @@ static HRESULT ffp_blit_color_fill(struct wined3d_device *device, struct wined3d - const RECT *dst_rect, const struct wined3d_color *color) - { - const RECT draw_rect = {0, 0, dst_surface->resource.width, dst_surface->resource.height}; -- struct wined3d_rendertarget_view *view; -- struct wined3d_fb_state fb = {&view, NULL}; -- HRESULT hr; -- -- if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(dst_surface, -- NULL, &wined3d_null_parent_ops, &view))) -- { -- ERR("Failed to create rendertarget view, hr %#x.\n", hr); -- return hr; -- } -+ struct wined3d_rendertarget_view view, *view_ptr = &view; -+ struct wined3d_fb_state fb = {&view_ptr, NULL, 1}; -+ struct wined3d_texture *texture = dst_surface->container; -+ -+ /* Can't incref / decref the resource here. This is executed inside the worker -+ * thread. Playing with the refcount here makes the worker thread visible to -+ * the client lib. Problems occur when the worker thread happens to hold the -+ * last reference and the resource destruction callbacks are called from the -+ * wrong thread. */ -+ view.resource = &texture->resource; -+ view.parent = NULL; -+ view.parent_ops = &wined3d_null_parent_ops; -+ view.format = dst_surface->resource.format; -+ view.buffer_offset = 0; -+ view.width = dst_surface->resource.width; -+ view.height = dst_surface->resource.height; -+ view.depth = 1; -+ view.sub_resource_idx = dst_surface->texture_layer * texture->level_count + dst_surface->texture_level; - - device_clear_render_targets(device, 1, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0); -- wined3d_rendertarget_view_decref_worker(view); - - return WINED3D_OK; - } -@@ -4145,18 +4152,21 @@ static HRESULT ffp_blit_depth_fill(struct wined3d_device *device, struct wined3d - const RECT *dst_rect, float depth) - { - const RECT draw_rect = {0, 0, dst_surface->resource.width, dst_surface->resource.height}; -- struct wined3d_fb_state fb = {NULL, NULL}; -- HRESULT hr; -- -- if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(dst_surface, -- NULL, &wined3d_null_parent_ops, &fb.depth_stencil))) -- { -- ERR("Failed to create rendertarget view, hr %#x.\n", hr); -- return hr; -- } -+ struct wined3d_rendertarget_view view; -+ struct wined3d_fb_state fb = {NULL, &view}; -+ struct wined3d_texture *texture = dst_surface->container; -+ -+ view.resource = &dst_surface->container->resource; -+ view.parent = NULL; -+ view.parent_ops = &wined3d_null_parent_ops; -+ view.format = dst_surface->resource.format; -+ view.buffer_offset = 0; -+ view.width = dst_surface->resource.width; -+ view.height = dst_surface->resource.height; -+ view.depth = 1; -+ view.sub_resource_idx = dst_surface->texture_layer * texture->level_count + dst_surface->texture_level; - - device_clear_render_targets(device, 0, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_ZBUFFER, 0, depth, 0); -- wined3d_rendertarget_view_decref_worker(fb.depth_stencil); - - return WINED3D_OK; - } -diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c -index 56eb7b3..870f1df 100644 ---- a/dlls/wined3d/view.c -+++ b/dlls/wined3d/view.c -@@ -58,26 +58,6 @@ ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *v - return refcount; - } - --/* Ugly hack for ffp_blit_depth_fill that allows destroying a view from inside the -- * worker thread. */ --ULONG wined3d_rendertarget_view_decref_worker(struct wined3d_rendertarget_view *view) --{ -- ULONG refcount = InterlockedDecrement(&view->refcount); -- -- TRACE("%p decreasing refcount to %u.\n", view, refcount); -- -- if (!refcount) -- { -- /* Call wined3d_object_destroyed() before releasing the resource, -- * since releasing the resource may end up destroying the parent. */ -- view->parent_ops->wined3d_object_destroyed(view->parent); -- wined3d_resource_decref(view->resource); -- wined3d_rendertarget_view_destroy(view); -- } -- -- return refcount; --} -- - void * CDECL wined3d_rendertarget_view_get_parent(const struct wined3d_rendertarget_view *view) - { - TRACE("view %p.\n", view); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 3abd0a8..88329e5 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2859,7 +2859,6 @@ static inline struct wined3d_surface *wined3d_rendertarget_view_get_surface( - return surface_from_resource(resource); - } - --ULONG wined3d_rendertarget_view_decref_worker(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; - void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; - - struct wined3d_shader_resource_view --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0156-wined3d-Remove-the-device_reset-CS-sync-fixme.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0156-wined3d-Remove-the-device_reset-CS-sync-fixme.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0156-wined3d-Remove-the-device_reset-CS-sync-fixme.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0156-wined3d-Remove-the-device_reset-CS-sync-fixme.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,31 @@ +From 87ccefcb423dc16c82c5324fba63a6f30a7c8126 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 29 Aug 2014 14:46:55 +0200 +Subject: wined3d: Remove the device_reset CS sync fixme. + +--- + dlls/wined3d/device.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index f79db11..18cecac 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -4402,12 +4402,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, + TRACE("device %p, swapchain_desc %p, mode %p, callback %p, reset_state %#x.\n", + device, swapchain_desc, mode, callback, reset_state); + +- if (wined3d_settings.cs_multithreaded) +- { +- FIXME("Waiting for cs.\n"); +- wined3d_cs_emit_glfinish(device->cs); +- device->cs->ops->finish(device->cs); +- } ++ wined3d_cs_emit_glfinish(device->cs); ++ device->cs->ops->finish(device->cs); + + if (!(swapchain = wined3d_device_get_swapchain(device, 0))) + { +-- +2.5.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0157-wined3d-Put-GL_APPLE_flush_buffer_range-syncing-back.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0157-wined3d-Put-GL_APPLE_flush_buffer_range-syncing-back.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0157-wined3d-Put-GL_APPLE_flush_buffer_range-syncing-back.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0157-wined3d-Put-GL_APPLE_flush_buffer_range-syncing-back.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,52 @@ +From 86347e81d7f9b1cf0c231833b5cbba783c0acbd9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 29 Aug 2014 18:52:22 +0200 +Subject: wined3d: Put GL_APPLE_flush_buffer_range syncing back in place. + +--- + dlls/wined3d/buffer.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index e1ba423..d2da303 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -673,6 +673,12 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined + GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, NULL, GL_STREAM_DRAW)); + checkGLcall("glBufferData"); + } ++ else if (flags & WINED3D_BUFFER_SYNC && This->flags & WINED3D_BUFFER_APPLESYNC) ++ { ++ /* OSX doesn't do non-blocking asynchonous glBufferSubData like Linux drivers do, so we want to set ++ * GL_BUFFER_FLUSHING_UNMAP_APPLE to GL_FALSE. This means we have to do synchonization ourselves. */ ++ buffer_sync_apple(This, 0, gl_info); ++ } + + while (This->modified_areas) + { +@@ -1035,9 +1041,9 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + buffer->flags |= WINED3D_BUFFER_DISCARD; + buffer->ignore_discard = TRUE; + } ++ else if (!(flags & WINED3D_MAP_NOOVERWRITE)) ++ buffer->flags |= WINED3D_BUFFER_SYNC; + } +- if (!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD))) +- buffer->flags |= WINED3D_BUFFER_SYNC; + } + + if (wined3d_settings.cs_multithreaded && count == 1) +@@ -1052,6 +1058,10 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY))) + { + wined3d_resource_wait_fence(&buffer->resource); ++ /* Writing to the (otherwise worker thread controlled) ++ * flags field is OK here since the wait_fence call made ++ * sure the buffer is idle. */ ++ buffer->flags |= WINED3D_BUFFER_SYNC; + } + } + +-- +2.2.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0157-Winex11-complain-about-glfinish.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0157-Winex11-complain-about-glfinish.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0157-Winex11-complain-about-glfinish.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0157-Winex11-complain-about-glfinish.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -From 7af302e360179e2ef395c66327876b276f30fe9f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 29 Aug 2014 12:12:11 +0200 -Subject: Winex11: complain about glfinish - ---- - dlls/winex11.drv/opengl.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c -index 3d0bd24..069dcc5 100644 ---- a/dlls/winex11.drv/opengl.c -+++ b/dlls/winex11.drv/opengl.c -@@ -1962,6 +1962,7 @@ static void wglFinish(void) - escape.code = X11DRV_FLUSH_GL_DRAWABLE; - escape.gl_drawable = 0; - -+ ERR("glFinish\n"); - if ((gl = get_gl_drawable( WindowFromDC( ctx->hdc ), 0 ))) - { - switch (gl->type) -@@ -1987,6 +1988,7 @@ static void wglFlush(void) - escape.code = X11DRV_FLUSH_GL_DRAWABLE; - escape.gl_drawable = 0; - -+ ERR("glFlush\n"); - if ((gl = get_gl_drawable( WindowFromDC( ctx->hdc ), 0 ))) - { - switch (gl->type) --- -2.6.2 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0158-wined3d-Make-sure-the-new-window-is-set-up-before-se.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0158-wined3d-Make-sure-the-new-window-is-set-up-before-se.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0158-wined3d-Make-sure-the-new-window-is-set-up-before-se.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0158-wined3d-Make-sure-the-new-window-is-set-up-before-se.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -From cc06aee370abd3cb1d9cd3ff52a8859c7810fcd7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 29 Aug 2014 14:46:19 +0200 -Subject: wined3d: Make sure the new window is set up before setting up a - context. - ---- - dlls/wined3d/device.c | 31 +++++++++++++++++++++---------- - 1 file changed, 21 insertions(+), 10 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 0173d18..3ae0091 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -4454,6 +4454,27 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - } - } - -+ /* Free implicit resources and wait for the command stream before modifying -+ * swapchain parameters. After modifying the swapchain parameters a new GL -+ * context may be acquired by the worker thread. This causes problems in the -+ * d3d8/9 test that passes a hidden window as the new device window. -+ * SetPixelFormat will call SetWindowPos inside the X11 driver, which sends -+ * a message to the window to query the icon. Since the worker thread is -+ * not the thread that created the window and the d3d8 test does not run -+ * an event loop this deadlocks. Set up the window first from the main thread -+ * before calling SetPixelFormat from the worker thread to avoid this. */ -+ if (device->auto_depth_stencil_view) -+ { -+ wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); -+ device->auto_depth_stencil_view = NULL; -+ } -+ if (device->back_buffer_view) -+ { -+ wined3d_rendertarget_view_decref(device->back_buffer_view); -+ device->back_buffer_view = NULL; -+ } -+ device->cs->ops->finish(device->cs); -+ - TRACE("New params:\n"); - TRACE("backbuffer_width %u\n", swapchain_desc->backbuffer_width); - TRACE("backbuffer_height %u\n", swapchain_desc->backbuffer_height); -@@ -4580,11 +4601,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - swapchain_desc->multisample_type, swapchain_desc->multisample_quality))) - return hr; - -- if (device->auto_depth_stencil_view) -- { -- wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); -- device->auto_depth_stencil_view = NULL; -- } - if (swapchain->desc.enable_auto_depth_stencil) - { - struct wined3d_resource_desc texture_desc; -@@ -4627,11 +4643,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - wined3d_device_set_depth_stencil_view(device, device->auto_depth_stencil_view); - } - -- if (device->back_buffer_view) -- { -- wined3d_rendertarget_view_decref(device->back_buffer_view); -- device->back_buffer_view = NULL; -- } - if (swapchain->desc.backbuffer_count && FAILED(hr = wined3d_rendertarget_view_create_from_surface( - surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)), - NULL, &wined3d_null_parent_ops, &device->back_buffer_view))) --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0158-wined3d-Wait-for-the-resource-to-be-idle-when-destro.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0158-wined3d-Wait-for-the-resource-to-be-idle-when-destro.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0158-wined3d-Wait-for-the-resource-to-be-idle-when-destro.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0158-wined3d-Wait-for-the-resource-to-be-idle-when-destro.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,41 @@ +From ba0d7248f185c8d6024f0d92b8c87b2d7153317c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Wed, 3 Sep 2014 20:20:39 +0200 +Subject: wined3d: Wait for the resource to be idle when destroying user memory + surfaces. + +--- + dlls/wined3d/surface.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 82485f3..3557c00 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -84,6 +84,8 @@ void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) + static void surface_cleanup(struct wined3d_surface *surface) + { + struct wined3d_surface *overlay, *cur; ++ struct wined3d_cs *cs = surface->resource.device->cs; ++ BOOL user_mem = surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY; + + TRACE("surface %p.\n", surface); + +@@ -97,7 +99,13 @@ static void surface_cleanup(struct wined3d_surface *surface) + } + + resource_cleanup(&surface->resource); +- wined3d_cs_emit_surface_cleanup(surface->resource.device->cs, surface); ++ wined3d_cs_emit_surface_cleanup(cs, surface); ++ ++ /* Wait for the CS to finish operations on this surface when user memory was in use. ++ * The application is allowed to free the memory after texture / surface destruction ++ * returns. */ ++ if (user_mem) ++ wined3d_resource_wait_fence(&surface->container->resource); + } + + void wined3d_surface_destroy(struct wined3d_surface *surface) +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0159-wined3d-Don-t-sync-on-redundant-discard-calls.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0159-wined3d-Don-t-sync-on-redundant-discard-calls.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0159-wined3d-Don-t-sync-on-redundant-discard-calls.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0159-wined3d-Don-t-sync-on-redundant-discard-calls.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,25 @@ +From 4e89934c223fd43aab2679042c7c808c8200aa68 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Mon, 8 Sep 2014 14:53:57 +0200 +Subject: wined3d: Don't sync on redundant discard calls. + +--- + dlls/wined3d/buffer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index d743f0a..1081247 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -1055,7 +1055,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + wined3d_resource_allocate_sysmem(&buffer->resource); + wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); + } +- else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY))) ++ else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY)) && !buffer->ignore_discard) + { + wined3d_resource_wait_fence(&buffer->resource); + /* Writing to the (otherwise worker thread controlled) +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0159-wined3d-Remove-the-device_reset-CS-sync-fixme.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0159-wined3d-Remove-the-device_reset-CS-sync-fixme.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0159-wined3d-Remove-the-device_reset-CS-sync-fixme.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0159-wined3d-Remove-the-device_reset-CS-sync-fixme.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -From 87ccefcb423dc16c82c5324fba63a6f30a7c8126 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 29 Aug 2014 14:46:55 +0200 -Subject: wined3d: Remove the device_reset CS sync fixme. - ---- - dlls/wined3d/device.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index f79db11..18cecac 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -4402,12 +4402,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, - TRACE("device %p, swapchain_desc %p, mode %p, callback %p, reset_state %#x.\n", - device, swapchain_desc, mode, callback, reset_state); - -- if (wined3d_settings.cs_multithreaded) -- { -- FIXME("Waiting for cs.\n"); -- wined3d_cs_emit_glfinish(device->cs); -- device->cs->ops->finish(device->cs); -- } -+ wined3d_cs_emit_glfinish(device->cs); -+ device->cs->ops->finish(device->cs); - - if (!(swapchain = wined3d_device_get_swapchain(device, 0))) - { --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0160-wined3d-Don-t-discard-new-buffers.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0160-wined3d-Don-t-discard-new-buffers.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0160-wined3d-Don-t-discard-new-buffers.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0160-wined3d-Don-t-discard-new-buffers.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,24 @@ +From 6f08171470d477868721be4e6a1f1178856340d4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Mon, 8 Sep 2014 14:57:37 +0200 +Subject: wined3d: Don't discard new buffers. + +--- + dlls/wined3d/buffer.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 1081247..e6e56bb 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -1196,6 +1196,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device + return hr; + } + buffer->buffer_type_hint = bind_hint; ++ buffer->ignore_discard = TRUE; + + TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage, + debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory, buffer); +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0160-wined3d-Put-GL_APPLE_flush_buffer_range-syncing-back.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0160-wined3d-Put-GL_APPLE_flush_buffer_range-syncing-back.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0160-wined3d-Put-GL_APPLE_flush_buffer_range-syncing-back.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0160-wined3d-Put-GL_APPLE_flush_buffer_range-syncing-back.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -From 86347e81d7f9b1cf0c231833b5cbba783c0acbd9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 29 Aug 2014 18:52:22 +0200 -Subject: wined3d: Put GL_APPLE_flush_buffer_range syncing back in place. - ---- - dlls/wined3d/buffer.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index e1ba423..d2da303 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -673,6 +673,12 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined - GL_EXTCALL(glBufferData(This->buffer_type_hint, This->resource.size, NULL, GL_STREAM_DRAW)); - checkGLcall("glBufferData"); - } -+ else if (flags & WINED3D_BUFFER_SYNC && This->flags & WINED3D_BUFFER_APPLESYNC) -+ { -+ /* OSX doesn't do non-blocking asynchonous glBufferSubData like Linux drivers do, so we want to set -+ * GL_BUFFER_FLUSHING_UNMAP_APPLE to GL_FALSE. This means we have to do synchonization ourselves. */ -+ buffer_sync_apple(This, 0, gl_info); -+ } - - while (This->modified_areas) - { -@@ -1035,9 +1041,9 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - buffer->flags |= WINED3D_BUFFER_DISCARD; - buffer->ignore_discard = TRUE; - } -+ else if (!(flags & WINED3D_MAP_NOOVERWRITE)) -+ buffer->flags |= WINED3D_BUFFER_SYNC; - } -- if (!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_DISCARD))) -- buffer->flags |= WINED3D_BUFFER_SYNC; - } - - if (wined3d_settings.cs_multithreaded && count == 1) -@@ -1052,6 +1058,10 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY))) - { - wined3d_resource_wait_fence(&buffer->resource); -+ /* Writing to the (otherwise worker thread controlled) -+ * flags field is OK here since the wait_fence call made -+ * sure the buffer is idle. */ -+ buffer->flags |= WINED3D_BUFFER_SYNC; - } - } - --- -2.2.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0161-wined3d-Don-t-try-to-sync-VBOs-manually-on-OSX-with-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0161-wined3d-Don-t-try-to-sync-VBOs-manually-on-OSX-with-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0161-wined3d-Don-t-try-to-sync-VBOs-manually-on-OSX-with-.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0161-wined3d-Don-t-try-to-sync-VBOs-manually-on-OSX-with-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,52 @@ +From 180d8cf49a4f4481b08e373e8c8a75c116094e63 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Mon, 8 Sep 2014 15:09:44 +0200 +Subject: wined3d: Don't try to sync VBOs manually on OSX with CSMT. + +This fixes a performance regression in some games caused by +aaf4849718c3c3a763c460a24a51dd6c6b55524a. + +GL_ARB_sync and GL_APPLE_fence seem to be fairly slow on OSX. Putting the +buffer back into synchonized mode and synchronizing all future uploads +is about twice as fast. This was benchmarked with 3DMark2001. Gunpoint, +another game that depends on synchronized dynamic buffer maps, feels +smoother, although the lack of a benchmark mode makes testing this difficult. + +This assumes that if a game maps a dynamic buffer without NOOVERWRITE or +DISCARD once it will always do so. I have not seen a game yet that mixes +async and sync maps. If the game mixes them, the wined3d-side CS will still +update the buffer asynchronously. Only the worker thread -> GL copy is +synchronized, as it used to be for all buffers in cx13. + +This patch only changes the double-buffered (used for CSMT) codepath. Making +the same change to the glMapBuffer codepath improves 3DMark2001 performance +as well, but the difference is much smaller. I will leave the manual sync +code in place until we have a game that clearly profits from this change. +--- + dlls/wined3d/buffer.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index e6e56bb..b33dd5a 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -676,8 +676,14 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined + else if (flags & WINED3D_BUFFER_SYNC && This->flags & WINED3D_BUFFER_APPLESYNC) + { + /* OSX doesn't do non-blocking asynchonous glBufferSubData like Linux drivers do, so we want to set +- * GL_BUFFER_FLUSHING_UNMAP_APPLE to GL_FALSE. This means we have to do synchonization ourselves. */ +- buffer_sync_apple(This, 0, gl_info); ++ * GL_BUFFER_SERIALIZED_MODIFY_APPLE to GL_FALSE. Unfortunately ARB_sync and APPLE_fence are pretty ++ * slow on OSX. Putting the buffer back into synchronized mode for future maps is a lot faster. ++ * (GeForce 650M, Mavericks). The difference between ARB_sync and normal buffer operation is small ++ * in the glMapBuffer codepath without CSMT. */ ++ glFinish(); ++ GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)); ++ checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)"); ++ This->flags &= ~WINED3D_BUFFER_APPLESYNC; + } + + while (This->modified_areas) +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0161-wined3d-Wait-for-the-resource-to-be-idle-when-destro.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0161-wined3d-Wait-for-the-resource-to-be-idle-when-destro.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0161-wined3d-Wait-for-the-resource-to-be-idle-when-destro.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0161-wined3d-Wait-for-the-resource-to-be-idle-when-destro.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -From ba0d7248f185c8d6024f0d92b8c87b2d7153317c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Wed, 3 Sep 2014 20:20:39 +0200 -Subject: wined3d: Wait for the resource to be idle when destroying user memory - surfaces. - ---- - dlls/wined3d/surface.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 82485f3..3557c00 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -84,6 +84,8 @@ void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) - static void surface_cleanup(struct wined3d_surface *surface) - { - struct wined3d_surface *overlay, *cur; -+ struct wined3d_cs *cs = surface->resource.device->cs; -+ BOOL user_mem = surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY; - - TRACE("surface %p.\n", surface); - -@@ -97,7 +99,13 @@ static void surface_cleanup(struct wined3d_surface *surface) - } - - resource_cleanup(&surface->resource); -- wined3d_cs_emit_surface_cleanup(surface->resource.device->cs, surface); -+ wined3d_cs_emit_surface_cleanup(cs, surface); -+ -+ /* Wait for the CS to finish operations on this surface when user memory was in use. -+ * The application is allowed to free the memory after texture / surface destruction -+ * returns. */ -+ if (user_mem) -+ wined3d_resource_wait_fence(&surface->container->resource); - } - - void wined3d_surface_destroy(struct wined3d_surface *surface) --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0162-wined3d-Don-t-sync-on-redundant-discard-calls.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0162-wined3d-Don-t-sync-on-redundant-discard-calls.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0162-wined3d-Don-t-sync-on-redundant-discard-calls.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0162-wined3d-Don-t-sync-on-redundant-discard-calls.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -From 4e89934c223fd43aab2679042c7c808c8200aa68 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Mon, 8 Sep 2014 14:53:57 +0200 -Subject: wined3d: Don't sync on redundant discard calls. - ---- - dlls/wined3d/buffer.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index d743f0a..1081247 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -1055,7 +1055,7 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - wined3d_resource_allocate_sysmem(&buffer->resource); - wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); - } -- else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY))) -+ else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY)) && !buffer->ignore_discard) - { - wined3d_resource_wait_fence(&buffer->resource); - /* Writing to the (otherwise worker thread controlled) --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0162-wined3d-Render-target-lock-hack.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0162-wined3d-Render-target-lock-hack.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0162-wined3d-Render-target-lock-hack.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0162-wined3d-Render-target-lock-hack.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,86 @@ +From 8b94a2168e87d63b4def608b239fc4cc4b1075d3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Tue, 23 Sep 2014 22:18:56 +0200 +Subject: wined3d: Render target lock hack + +--- + dlls/wined3d/resource.c | 17 +++++++++++++++++ + dlls/wined3d/wined3d_main.c | 7 +++++++ + dlls/wined3d/wined3d_private.h | 1 + + 3 files changed, 25 insertions(+) + +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index dd58302..5bc7d9a 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -887,6 +887,17 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, + TRACE("resource %p, map_desc %p, box %s, flags %#x.\n", + resource, map_desc, debug_box(box), flags); + ++ if (resource->usage & WINED3DUSAGE_RENDERTARGET && wined3d_settings.ignore_rt_map) ++ { ++ WARN("Ignoring render target map, only finishing CS.\n"); ++ wined3d_cs_emit_glfinish(device->cs); ++ map_desc->row_pitch = 0; ++ map_desc->slice_pitch = 0; ++ map_desc->data = NULL; ++ device->cs->ops->finish(device->cs); ++ return WINED3D_OK; ++ } ++ + if (resource->map_count) + { + WARN("Volume is already mapped.\n"); +@@ -986,6 +997,12 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) + struct wined3d_device *device = resource->device; + TRACE("resource %p.\n", resource); + ++ if (resource->usage & WINED3DUSAGE_RENDERTARGET && wined3d_settings.ignore_rt_map) ++ { ++ WARN("Ignoring render target unmap.\n"); ++ return WINED3D_OK; ++ } ++ + if (!resource->map_count) + { + WARN("Trying to unlock an unlocked resource %p.\n", resource); +diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c +index 7b4fc40..0bc1120 100644 +--- a/dlls/wined3d/wined3d_main.c ++++ b/dlls/wined3d/wined3d_main.c +@@ -87,6 +87,7 @@ struct wined3d_settings wined3d_settings = + ~0U, /* No PS shader model limit by default. */ + FALSE, /* 3D support enabled by default. */ + FALSE, /* No multithreaded CS by default. */ ++ FALSE, /* Do not ignore render target maps. */ + }; + + struct wined3d * CDECL wined3d_create(DWORD flags) +@@ -321,6 +322,12 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) + TRACE("Enabling multithreaded command stream.\n"); + wined3d_settings.cs_multithreaded = TRUE; + } ++ if (!get_config_key(hkey, appkey, "ignore_rt_map", buffer, size) ++ && !strcmp(buffer,"enabled")) ++ { ++ TRACE("Ignoring render target maps.\n"); ++ wined3d_settings.ignore_rt_map = TRUE; ++ } + } + + if (appkey) RegCloseKey( appkey ); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 9a1c94d..d0453f1 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -296,6 +296,7 @@ struct wined3d_settings + unsigned int max_sm_ps; + BOOL no_3d; + BOOL cs_multithreaded; ++ BOOL ignore_rt_map; + }; + + extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN; +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0163-wined3d-Avoid-calling-wined3d_surface_blt-from-surfa.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0163-wined3d-Avoid-calling-wined3d_surface_blt-from-surfa.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0163-wined3d-Avoid-calling-wined3d_surface_blt-from-surfa.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0163-wined3d-Avoid-calling-wined3d_surface_blt-from-surfa.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,42 @@ +From a2aa05486b1b77425b94657483334a1dd5763048 Mon Sep 17 00:00:00 2001 +From: Matteo Bruni +Date: Fri, 12 Sep 2014 19:03:05 +0200 +Subject: wined3d: Avoid calling wined3d_surface_blt() from + surface_upload_from_surface(). + +--- + dlls/wined3d/surface.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index 3557c00..9ab0738 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -37,6 +37,10 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); + #define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */ + + ++static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, ++ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, ++ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter); ++ + void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) + { + if (surface->rb_multisample || surface->rb_resolved || !list_empty(&surface->renderbuffers)) +@@ -1522,9 +1526,11 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P + return WINED3DERR_INVALIDCALL; + } + +- /* Use wined3d_surface_blt() instead of uploading directly if we need conversion. */ ++ /* Use surface_cpu_blt() instead of uploading directly if we need ++ * conversion. Avoid calling wined3d_surface_blt() since that goes ++ * through the CS. */ + if (dst_format->convert || wined3d_format_get_color_key_conversion(dst_surface->container, FALSE)) +- return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT); ++ return surface_cpu_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT); + + context = context_acquire(dst_surface->resource.device, NULL); + gl_info = context->gl_info; +-- +2.1.3 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0163-wined3d-Don-t-discard-new-buffers.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0163-wined3d-Don-t-discard-new-buffers.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0163-wined3d-Don-t-discard-new-buffers.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0163-wined3d-Don-t-discard-new-buffers.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -From 6f08171470d477868721be4e6a1f1178856340d4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Mon, 8 Sep 2014 14:57:37 +0200 -Subject: wined3d: Don't discard new buffers. - ---- - dlls/wined3d/buffer.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 1081247..e6e56bb 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -1196,6 +1196,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device - return hr; - } - buffer->buffer_type_hint = bind_hint; -+ buffer->ignore_discard = TRUE; - - TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage, - debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory, buffer); --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0164-wined3d-Don-t-try-to-sync-VBOs-manually-on-OSX-with-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0164-wined3d-Don-t-try-to-sync-VBOs-manually-on-OSX-with-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0164-wined3d-Don-t-try-to-sync-VBOs-manually-on-OSX-with-.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0164-wined3d-Don-t-try-to-sync-VBOs-manually-on-OSX-with-.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -From 180d8cf49a4f4481b08e373e8c8a75c116094e63 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Mon, 8 Sep 2014 15:09:44 +0200 -Subject: wined3d: Don't try to sync VBOs manually on OSX with CSMT. - -This fixes a performance regression in some games caused by -aaf4849718c3c3a763c460a24a51dd6c6b55524a. - -GL_ARB_sync and GL_APPLE_fence seem to be fairly slow on OSX. Putting the -buffer back into synchonized mode and synchronizing all future uploads -is about twice as fast. This was benchmarked with 3DMark2001. Gunpoint, -another game that depends on synchronized dynamic buffer maps, feels -smoother, although the lack of a benchmark mode makes testing this difficult. - -This assumes that if a game maps a dynamic buffer without NOOVERWRITE or -DISCARD once it will always do so. I have not seen a game yet that mixes -async and sync maps. If the game mixes them, the wined3d-side CS will still -update the buffer asynchronously. Only the worker thread -> GL copy is -synchronized, as it used to be for all buffers in cx13. - -This patch only changes the double-buffered (used for CSMT) codepath. Making -the same change to the glMapBuffer codepath improves 3DMark2001 performance -as well, but the difference is much smaller. I will leave the manual sync -code in place until we have a game that clearly profits from this change. ---- - dlls/wined3d/buffer.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index e6e56bb..b33dd5a 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -676,8 +676,14 @@ static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined - else if (flags & WINED3D_BUFFER_SYNC && This->flags & WINED3D_BUFFER_APPLESYNC) - { - /* OSX doesn't do non-blocking asynchonous glBufferSubData like Linux drivers do, so we want to set -- * GL_BUFFER_FLUSHING_UNMAP_APPLE to GL_FALSE. This means we have to do synchonization ourselves. */ -- buffer_sync_apple(This, 0, gl_info); -+ * GL_BUFFER_SERIALIZED_MODIFY_APPLE to GL_FALSE. Unfortunately ARB_sync and APPLE_fence are pretty -+ * slow on OSX. Putting the buffer back into synchronized mode for future maps is a lot faster. -+ * (GeForce 650M, Mavericks). The difference between ARB_sync and normal buffer operation is small -+ * in the glMapBuffer codepath without CSMT. */ -+ glFinish(); -+ GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)); -+ checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)"); -+ This->flags &= ~WINED3D_BUFFER_APPLESYNC; - } - - while (This->modified_areas) --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0164-wined3d-Only-discard-buffers-that-are-in-use.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0164-wined3d-Only-discard-buffers-that-are-in-use.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0164-wined3d-Only-discard-buffers-that-are-in-use.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0164-wined3d-Only-discard-buffers-that-are-in-use.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,33 @@ +From b5d14c60d7533217f9ea6b96c2fafc14eb9870cc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 16 Jan 2015 19:19:05 +0100 +Subject: wined3d: Only discard buffers that are in use. + +No need to mess around with memory if it is idle. +--- + dlls/wined3d/buffer.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index f5bd06d..6995264 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -1057,9 +1057,12 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN + BOOL swvp = device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING; + if (flags & WINED3D_MAP_DISCARD && !swvp) + { +- buffer->ignore_discard = TRUE; +- wined3d_resource_allocate_sysmem(&buffer->resource); +- wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); ++ if (buffer->resource.access_fence) ++ { ++ buffer->ignore_discard = TRUE; ++ wined3d_resource_allocate_sysmem(&buffer->resource); ++ wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); ++ } + } + else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY)) && !buffer->ignore_discard) + { +-- +2.5.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0165-wined3d-Destroy-samplers-through-the-command-stream.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0165-wined3d-Destroy-samplers-through-the-command-stream.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0165-wined3d-Destroy-samplers-through-the-command-stream.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0165-wined3d-Destroy-samplers-through-the-command-stream.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,135 @@ +From 94db69addfe7d9049300393410664dee39f695f4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Thu, 27 Aug 2015 23:43:08 +0200 +Subject: wined3d: Destroy samplers through the command stream. + +--- + dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ + dlls/wined3d/sampler.c | 21 +++++++++++++-------- + dlls/wined3d/wined3d_private.h | 3 +++ + 3 files changed, 44 insertions(+), 8 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index e89e053..01c4ba3 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -93,6 +93,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_DELETE_GL_CONTEXTS, + WINED3D_CS_OP_GETDC, + WINED3D_CS_OP_RELEASEDC, ++ WINED3D_CS_OP_SAMPLER_DESTROY, + WINED3D_CS_OP_STOP, + }; + +@@ -557,6 +558,12 @@ struct wined3d_cs_releasedc + struct wined3d_surface *surface; + }; + ++struct wined3d_cs_sampler_destroy ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_sampler *sampler; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2758,6 +2765,26 @@ void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *su + cs->ops->finish(cs); + } + ++static UINT wined3d_cs_exec_sampler_destroy(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_sampler_destroy *op = data; ++ ++ wined3d_sampler_destroy(op->sampler); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler) ++{ ++ struct wined3d_cs_sampler_destroy *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SAMPLER_DESTROY; ++ op->sampler = sampler; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2829,6 +2856,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts, + /* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc, + /* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc, ++ /* WINED3D_CS_OP_SAMPLER_DESTROY */ wined3d_cs_exec_sampler_destroy, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c +index ffa1155..81bdb51 100644 +--- a/dlls/wined3d/sampler.c ++++ b/dlls/wined3d/sampler.c +@@ -33,22 +33,27 @@ ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler) + return refcount; + } + ++void wined3d_sampler_destroy(struct wined3d_sampler *sampler) ++{ ++ struct wined3d_context *context = context_acquire(sampler->device, NULL); ++ const struct wined3d_gl_info *gl_info = context->gl_info; ++ ++ GL_EXTCALL(glDeleteSamplers(1, &sampler->name)); ++ context_release(context); ++ ++ HeapFree(GetProcessHeap(), 0, sampler); ++} ++ + ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler) + { + ULONG refcount = InterlockedDecrement(&sampler->refcount); +- const struct wined3d_gl_info *gl_info; +- struct wined3d_context *context; + + TRACE("%p decreasing refcount to %u.\n", sampler, refcount); + + if (!refcount) + { +- context = context_acquire(sampler->device, NULL); +- gl_info = context->gl_info; +- GL_EXTCALL(glDeleteSamplers(1, &sampler->name)); +- context_release(context); +- +- HeapFree(GetProcessHeap(), 0, sampler); ++ struct wined3d_device *device = sampler->device; ++ wined3d_cs_emit_sampler_destroy(device->cs, sampler); + } + + return refcount; +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index 0adce02..9f4c9e1 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2566,6 +2566,8 @@ struct wined3d_sampler + GLuint name; + }; + ++void wined3d_sampler_destroy(struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; ++ + struct wined3d_vertex_declaration_element + { + const struct wined3d_format *format; +@@ -2821,6 +2823,7 @@ void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, + struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; + void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.5.1 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0165-wined3d-Render-target-lock-hack.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0165-wined3d-Render-target-lock-hack.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0165-wined3d-Render-target-lock-hack.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0165-wined3d-Render-target-lock-hack.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -From f23d42ca6a96a3d257fc57dbae8d5ebd3620e4b7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Tue, 23 Sep 2014 22:18:56 +0200 -Subject: wined3d: Render target lock hack - ---- - dlls/wined3d/resource.c | 17 +++++++++++++++++ - dlls/wined3d/wined3d_main.c | 7 +++++++ - dlls/wined3d/wined3d_private.h | 1 + - 3 files changed, 25 insertions(+) - -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c -index cd60356..dc36dd5 100644 ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -777,6 +777,17 @@ HRESULT wined3d_resource_map(struct wined3d_resource *resource, - TRACE("resource %p, map_desc %p, box %p, flags %#x.\n", - resource, map_desc, box, flags); - -+ if (resource->usage & WINED3DUSAGE_RENDERTARGET && wined3d_settings.ignore_rt_map) -+ { -+ WARN("Ignoring render target map, only finishing CS.\n"); -+ wined3d_cs_emit_glfinish(device->cs); -+ map_desc->row_pitch = 0; -+ map_desc->slice_pitch = 0; -+ map_desc->data = NULL; -+ device->cs->ops->finish(device->cs); -+ return WINED3D_OK; -+ } -+ - if (resource->map_count) - { - WARN("Volume is already mapped.\n"); -@@ -880,6 +891,12 @@ HRESULT wined3d_resource_unmap(struct wined3d_resource *resource) - struct wined3d_device *device = resource->device; - TRACE("resource %p.\n", resource); - -+ if (resource->usage & WINED3DUSAGE_RENDERTARGET && wined3d_settings.ignore_rt_map) -+ { -+ WARN("Ignoring render target unmap.\n"); -+ return WINED3D_OK; -+ } -+ - if (!resource->map_count) - { - WARN("Trying to unlock an unlocked resource %p.\n", resource); -diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c -index e6dc444..a1e4e6c 100644 ---- a/dlls/wined3d/wined3d_main.c -+++ b/dlls/wined3d/wined3d_main.c -@@ -86,6 +86,7 @@ struct wined3d_settings wined3d_settings = - ~0U, /* No PS shader model limit by default. */ - FALSE, /* 3D support enabled by default. */ - FALSE, /* No multithreaded CS by default. */ -+ FALSE, /* Do not ignore render target maps. */ - }; - - struct wined3d * CDECL wined3d_create(DWORD flags) -@@ -311,6 +312,12 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) - TRACE("Enabling multithreaded command stream.\n"); - wined3d_settings.cs_multithreaded = TRUE; - } -+ if (!get_config_key(hkey, appkey, "ignore_rt_map", buffer, size) -+ && !strcmp(buffer,"enabled")) -+ { -+ TRACE("Ignoring render target maps.\n"); -+ wined3d_settings.ignore_rt_map = TRUE; -+ } - } - - if (appkey) RegCloseKey( appkey ); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 88329e5..dd06525 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -281,6 +281,7 @@ struct wined3d_settings - unsigned int max_sm_ps; - BOOL no_3d; - BOOL cs_multithreaded; -+ BOOL ignore_rt_map; - }; - - extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0166-wined3d-Avoid-calling-wined3d_surface_blt-from-surfa.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0166-wined3d-Avoid-calling-wined3d_surface_blt-from-surfa.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0166-wined3d-Avoid-calling-wined3d_surface_blt-from-surfa.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0166-wined3d-Avoid-calling-wined3d_surface_blt-from-surfa.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -From a2aa05486b1b77425b94657483334a1dd5763048 Mon Sep 17 00:00:00 2001 -From: Matteo Bruni -Date: Fri, 12 Sep 2014 19:03:05 +0200 -Subject: wined3d: Avoid calling wined3d_surface_blt() from - surface_upload_from_surface(). - ---- - dlls/wined3d/surface.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index 3557c00..9ab0738 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -37,6 +37,10 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); - #define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */ - - -+static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, -+ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, -+ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter); -+ - void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) - { - if (surface->rb_multisample || surface->rb_resolved || !list_empty(&surface->renderbuffers)) -@@ -1522,9 +1526,11 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P - return WINED3DERR_INVALIDCALL; - } - -- /* Use wined3d_surface_blt() instead of uploading directly if we need conversion. */ -+ /* Use surface_cpu_blt() instead of uploading directly if we need -+ * conversion. Avoid calling wined3d_surface_blt() since that goes -+ * through the CS. */ - if (dst_format->convert || wined3d_format_get_color_key_conversion(dst_surface->container, FALSE)) -- return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT); -+ return surface_cpu_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT); - - context = context_acquire(dst_surface->resource.device, NULL); - gl_info = context->gl_info; --- -2.1.3 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0166-wined3d-Hack-to-reject-unsupported-color-fills.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0166-wined3d-Hack-to-reject-unsupported-color-fills.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0166-wined3d-Hack-to-reject-unsupported-color-fills.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0166-wined3d-Hack-to-reject-unsupported-color-fills.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,31 @@ +From 190f220b618f92af812a06ea75d1a7cf93ef6194 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 28 Aug 2015 00:01:39 +0200 +Subject: wined3d: Hack to reject unsupported color fills. + +--- + dlls/wined3d/surface.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +index bf1f1cf..0a460cf 100644 +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -5220,6 +5220,14 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC + } + } + ++ /* FIXME: We should select the blitter in the main thread, that way we can return an error if the blit ++ * is unsupported without duplicating all the checks... */ ++ if (flags & WINEDDBLT_COLORFILL && (dst_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)) ++ { ++ WARN("Block color fill, returning WINED3DERR_INVALIDCALL\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ + if (!fx || !(fx->dwDDFX)) + flags &= ~WINEDDBLT_DDFX; + +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0167-wined3d-Alloc-the-buffer-map-array-before-mapping-th.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0167-wined3d-Alloc-the-buffer-map-array-before-mapping-th.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0167-wined3d-Alloc-the-buffer-map-array-before-mapping-th.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0167-wined3d-Alloc-the-buffer-map-array-before-mapping-th.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,56 @@ +From b0f13fef660a46a781b1dd849996049ebe514242 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 28 Aug 2015 01:13:32 +0200 +Subject: wined3d: Alloc the buffer map array before mapping the buffer. + +FIXME: This needs to go into whatever patch creates the VBO on first map. +--- + dlls/wined3d/buffer.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +index 0c3dc56..531eb39 100644 +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -1317,27 +1317,28 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device + buffer->flags |= WINED3D_BUFFER_CREATEBO; + } + ++ buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)); ++ if (!buffer->maps) ++ { ++ ERR("Out of memory\n"); ++ buffer_unload(&buffer->resource); ++ resource_cleanup(&buffer->resource); ++ return E_OUTOFMEMORY; ++ } ++ buffer->maps_size = 1; ++ + if (data) + { + if (FAILED(hr = wined3d_buffer_upload_data(buffer, NULL, data->data))) + { + ERR("Failed to upload data, hr %#x.\n", hr); ++ HeapFree(GetProcessHeap(), 0, buffer->maps); + buffer_unload(&buffer->resource); + resource_cleanup(&buffer->resource); + return hr; + } + } + +- buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)); +- if (!buffer->maps) +- { +- ERR("Out of memory\n"); +- buffer_unload(&buffer->resource); +- resource_cleanup(&buffer->resource); +- return E_OUTOFMEMORY; +- } +- buffer->maps_size = 1; +- + if (wined3d_settings.cs_multithreaded) + buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER; + +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0167-wined3d-Only-discard-buffers-that-are-in-use.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0167-wined3d-Only-discard-buffers-that-are-in-use.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0167-wined3d-Only-discard-buffers-that-are-in-use.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0167-wined3d-Only-discard-buffers-that-are-in-use.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -From b5d14c60d7533217f9ea6b96c2fafc14eb9870cc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 16 Jan 2015 19:19:05 +0100 -Subject: wined3d: Only discard buffers that are in use. - -No need to mess around with memory if it is idle. ---- - dlls/wined3d/buffer.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index f5bd06d..6995264 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -1057,9 +1057,12 @@ HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UIN - BOOL swvp = device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING; - if (flags & WINED3D_MAP_DISCARD && !swvp) - { -- buffer->ignore_discard = TRUE; -- wined3d_resource_allocate_sysmem(&buffer->resource); -- wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); -+ if (buffer->resource.access_fence) -+ { -+ buffer->ignore_discard = TRUE; -+ wined3d_resource_allocate_sysmem(&buffer->resource); -+ wined3d_cs_emit_buffer_swap_mem(device->cs, buffer, buffer->resource.map_heap_memory); -+ } - } - else if(!(flags & (WINED3D_MAP_NOOVERWRITE | WINED3D_MAP_READONLY)) && !buffer->ignore_discard) - { --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0168-wined3d-Destroy-samplers-through-the-command-stream.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0168-wined3d-Destroy-samplers-through-the-command-stream.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0168-wined3d-Destroy-samplers-through-the-command-stream.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0168-wined3d-Destroy-samplers-through-the-command-stream.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,135 +0,0 @@ -From 94db69addfe7d9049300393410664dee39f695f4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Thu, 27 Aug 2015 23:43:08 +0200 -Subject: wined3d: Destroy samplers through the command stream. - ---- - dlls/wined3d/cs.c | 28 ++++++++++++++++++++++++++++ - dlls/wined3d/sampler.c | 21 +++++++++++++-------- - dlls/wined3d/wined3d_private.h | 3 +++ - 3 files changed, 44 insertions(+), 8 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index e89e053..01c4ba3 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -93,6 +93,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_DELETE_GL_CONTEXTS, - WINED3D_CS_OP_GETDC, - WINED3D_CS_OP_RELEASEDC, -+ WINED3D_CS_OP_SAMPLER_DESTROY, - WINED3D_CS_OP_STOP, - }; - -@@ -557,6 +558,12 @@ struct wined3d_cs_releasedc - struct wined3d_surface *surface; - }; - -+struct wined3d_cs_sampler_destroy -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_sampler *sampler; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2758,6 +2765,26 @@ void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *su - cs->ops->finish(cs); - } - -+static UINT wined3d_cs_exec_sampler_destroy(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_sampler_destroy *op = data; -+ -+ wined3d_sampler_destroy(op->sampler); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler) -+{ -+ struct wined3d_cs_sampler_destroy *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SAMPLER_DESTROY; -+ op->sampler = sampler; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2829,6 +2856,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts, - /* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc, - /* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc, -+ /* WINED3D_CS_OP_SAMPLER_DESTROY */ wined3d_cs_exec_sampler_destroy, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c -index ffa1155..81bdb51 100644 ---- a/dlls/wined3d/sampler.c -+++ b/dlls/wined3d/sampler.c -@@ -33,22 +33,27 @@ ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler) - return refcount; - } - -+void wined3d_sampler_destroy(struct wined3d_sampler *sampler) -+{ -+ struct wined3d_context *context = context_acquire(sampler->device, NULL); -+ const struct wined3d_gl_info *gl_info = context->gl_info; -+ -+ GL_EXTCALL(glDeleteSamplers(1, &sampler->name)); -+ context_release(context); -+ -+ HeapFree(GetProcessHeap(), 0, sampler); -+} -+ - ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler) - { - ULONG refcount = InterlockedDecrement(&sampler->refcount); -- const struct wined3d_gl_info *gl_info; -- struct wined3d_context *context; - - TRACE("%p decreasing refcount to %u.\n", sampler, refcount); - - if (!refcount) - { -- context = context_acquire(sampler->device, NULL); -- gl_info = context->gl_info; -- GL_EXTCALL(glDeleteSamplers(1, &sampler->name)); -- context_release(context); -- -- HeapFree(GetProcessHeap(), 0, sampler); -+ struct wined3d_device *device = sampler->device; -+ wined3d_cs_emit_sampler_destroy(device->cs, sampler); - } - - return refcount; -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 0adce02..9f4c9e1 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2566,6 +2566,8 @@ struct wined3d_sampler - GLuint name; - }; - -+void wined3d_sampler_destroy(struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; -+ - struct wined3d_vertex_declaration_element - { - const struct wined3d_format *format; -@@ -2821,6 +2823,7 @@ void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, - struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; - void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; - void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0168-wined3d-Send-update_sub_resource-calls-through-the-c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0168-wined3d-Send-update_sub_resource-calls-through-the-c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0168-wined3d-Send-update_sub_resource-calls-through-the-c.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0168-wined3d-Send-update_sub_resource-calls-through-the-c.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,223 @@ +From ccca792636064c789f2f5b8f9b333f6591f275a8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20D=C3=B6singer?= +Date: Fri, 4 Sep 2015 15:22:49 +0200 +Subject: wined3d: Send update_sub_resource calls through the command stream. + +--- + dlls/wined3d/cs.c | 91 ++++++++++++++++++++++++++++++++++++++++++ + dlls/wined3d/device.c | 43 +------------------- + dlls/wined3d/wined3d_private.h | 3 ++ + 3 files changed, 95 insertions(+), 42 deletions(-) + +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +index 707f00d..e99a54d 100644 +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -93,6 +93,7 @@ enum wined3d_cs_op + WINED3D_CS_OP_GETDC, + WINED3D_CS_OP_RELEASEDC, + WINED3D_CS_OP_SAMPLER_DESTROY, ++ WINED3D_CS_OP_UPDATE_SUB_RESOURCE, + WINED3D_CS_OP_STOP, + }; + +@@ -557,6 +558,15 @@ struct wined3d_cs_sampler_destroy + struct wined3d_sampler *sampler; + }; + ++struct wined3d_cs_update_sub_resource ++{ ++ enum wined3d_cs_op opcode; ++ struct wined3d_resource *resource; ++ unsigned int sub_resource_idx, row_pitch, depth_pitch; ++ const struct wined3d_box *box; ++ const void *data; ++}; ++ + static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) + { + LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +@@ -2752,6 +2762,86 @@ void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampl + cs->ops->submit(cs, sizeof(*op)); + } + ++static UINT wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_update_sub_resource *op = data; ++ ++ struct wined3d_resource *sub_resource; ++ const struct wined3d_gl_info *gl_info; ++ struct wined3d_const_bo_address addr; ++ struct wined3d_context *context; ++ struct wined3d_texture *texture; ++ struct wined3d_surface *surface; ++ POINT dst_point; ++ RECT src_rect; ++ ++ texture = wined3d_texture_from_resource(op->resource); ++ sub_resource = wined3d_texture_get_sub_resource(texture, op->sub_resource_idx); ++ surface = surface_from_resource(sub_resource); ++ ++ src_rect.left = 0; ++ src_rect.top = 0; ++ if (op->box) ++ { ++ src_rect.right = op->box->right - op->box->left; ++ src_rect.bottom = op->box->bottom - op->box->top; ++ dst_point.x = op->box->left; ++ dst_point.y = op->box->top; ++ } ++ else ++ { ++ src_rect.right = sub_resource->width; ++ src_rect.bottom = sub_resource->height; ++ dst_point.x = 0; ++ dst_point.y = 0; ++ } ++ ++ addr.buffer_object = 0; ++ addr.addr = op->data; ++ ++ context = context_acquire(cs->device, NULL); ++ gl_info = context->gl_info; ++ ++ /* Only load the surface for partial updates. */ ++ if (!dst_point.x && !dst_point.y && src_rect.right == sub_resource->width ++ && src_rect.bottom == sub_resource->height) ++ wined3d_texture_prepare_texture(texture, context, FALSE); ++ else ++ wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); ++ wined3d_texture_bind_and_dirtify(texture, context, FALSE); ++ ++ wined3d_surface_upload_data(surface, gl_info, op->resource->format, ++ &src_rect, op->row_pitch, &dst_point, FALSE, &addr); ++ ++ context_release(context); ++ ++ wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_TEXTURE_RGB); ++ wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); ++ ++ return sizeof(*op); ++} ++ ++void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, ++ unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, ++ unsigned int depth_pitch) ++{ ++ struct wined3d_cs_update_sub_resource *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; ++ op->resource = resource; ++ op->sub_resource_idx = sub_resource_idx; ++ op->box = box; ++ op->data = data; ++ op->row_pitch = row_pitch; ++ op->depth_pitch = depth_pitch; ++ ++ cs->ops->submit(cs, sizeof(*op)); ++ /* The data pointer may go away, need to wait until the data is read. Copying the data may be faster. ++ * Don't forget to copy box as well in this case. */ ++ cs->ops->finish(cs); ++} ++ + static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = + { + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, +@@ -2823,6 +2913,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc, + /* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc, + /* WINED3D_CS_OP_SAMPLER_DESTROY */ wined3d_cs_exec_sampler_destroy, ++ /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource, + }; + + static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +index 6602fc3..a46f944 100644 +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -4019,13 +4019,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str + unsigned int depth_pitch) + { + struct wined3d_resource *sub_resource; +- const struct wined3d_gl_info *gl_info; +- struct wined3d_const_bo_address addr; +- struct wined3d_context *context; + struct wined3d_texture *texture; +- struct wined3d_surface *surface; +- POINT dst_point; +- RECT src_rect; + + TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u.\n", + device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch); +@@ -4059,10 +4053,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str + WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); + return; + } +- surface = surface_from_resource(sub_resource); + +- src_rect.left = 0; +- src_rect.top = 0; + if (box) + { + if (box->left >= box->right || box->right > sub_resource->width +@@ -4072,41 +4063,9 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str + WARN("Invalid box %s specified.\n", debug_box(box)); + return; + } +- +- src_rect.right = box->right - box->left; +- src_rect.bottom = box->bottom - box->top; +- dst_point.x = box->left; +- dst_point.y = box->top; + } +- else +- { +- src_rect.right = sub_resource->width; +- src_rect.bottom = sub_resource->height; +- dst_point.x = 0; +- dst_point.y = 0; +- } +- +- addr.buffer_object = 0; +- addr.addr = data; +- +- context = context_acquire(resource->device, NULL); +- gl_info = context->gl_info; +- +- /* Only load the surface for partial updates. */ +- if (!dst_point.x && !dst_point.y && src_rect.right == sub_resource->width +- && src_rect.bottom == sub_resource->height) +- wined3d_texture_prepare_texture(texture, context, FALSE); +- else +- wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); +- wined3d_texture_bind_and_dirtify(texture, context, FALSE); +- +- wined3d_surface_upload_data(surface, gl_info, resource->format, +- &src_rect, row_pitch, &dst_point, FALSE, &addr); +- +- context_release(context); + +- wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_TEXTURE_RGB); +- wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); ++ wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); + } + + HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device, +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +index f73c482..3789c55 100644 +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -2939,6 +2939,9 @@ void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, + void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; + void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; + void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; ++void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, ++ unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, ++ unsigned int depth_pitch) DECLSPEC_HIDDEN; + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0169-wined3d-Hack-to-reject-unsupported-color-fills.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0169-wined3d-Hack-to-reject-unsupported-color-fills.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0169-wined3d-Hack-to-reject-unsupported-color-fills.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0169-wined3d-Hack-to-reject-unsupported-color-fills.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -From e366ff98587ac212a25fd28f9f26f18ca5f30382 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 28 Aug 2015 00:01:39 +0200 -Subject: wined3d: Hack to reject unsupported color fills. - ---- - dlls/wined3d/surface.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c -index e318bf106..f815b65 100644 ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -5302,6 +5302,14 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC - memset(&src_rect, 0, sizeof(src_rect)); - } - -+ /* FIXME: We should select the blitter in the main thread, that way we can return an error if the blit -+ * is unsupported without duplicating all the checks... */ -+ if (flags & WINEDDBLT_COLORFILL && (dst_surface->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)) -+ { -+ WARN("Block color fill, returning WINED3DERR_INVALIDCALL\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ - if (!fx || !(fx->dwDDFX)) - flags &= ~WINEDDBLT_DDFX; - --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0170-wined3d-Alloc-the-buffer-map-array-before-mapping-th.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0170-wined3d-Alloc-the-buffer-map-array-before-mapping-th.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0170-wined3d-Alloc-the-buffer-map-array-before-mapping-th.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0170-wined3d-Alloc-the-buffer-map-array-before-mapping-th.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -From 3f00564e2ed6f37b857d0724dea00646285c747c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 28 Aug 2015 01:13:32 +0200 -Subject: wined3d: Alloc the buffer map array before mapping the buffer. - -FIXME: This needs to go into whatever patch creates the VBO on first map. ---- - dlls/wined3d/buffer.c | 21 +++++++++++---------- - 1 file changed, 11 insertions(+), 10 deletions(-) - -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c -index 6995264..753e38c 100644 ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -1250,6 +1250,16 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device - buffer->flags |= WINED3D_BUFFER_CREATEBO; - } - -+ buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)); -+ if (!buffer->maps) -+ { -+ ERR("Out of memory\n"); -+ buffer_unload(&buffer->resource); -+ resource_cleanup(&buffer->resource); -+ return E_OUTOFMEMORY; -+ } -+ buffer->maps_size = 1; -+ - if (data) - { - BYTE *ptr; -@@ -1258,6 +1268,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device - if (FAILED(hr)) - { - ERR("Failed to map buffer, hr %#x\n", hr); -+ HeapFree(GetProcessHeap(), 0, buffer->maps); - buffer_unload(&buffer->resource); - resource_cleanup(&buffer->resource); - return hr; -@@ -1268,16 +1279,6 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device - wined3d_buffer_unmap(buffer); - } - -- buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)); -- if (!buffer->maps) -- { -- ERR("Out of memory\n"); -- buffer_unload(&buffer->resource); -- resource_cleanup(&buffer->resource); -- return E_OUTOFMEMORY; -- } -- buffer->maps_size = 1; -- - if (wined3d_settings.cs_multithreaded) - buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER; - --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0171-wined3d-Send-update_sub_resource-calls-through-the-c.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0171-wined3d-Send-update_sub_resource-calls-through-the-c.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/0171-wined3d-Send-update_sub_resource-calls-through-the-c.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/0171-wined3d-Send-update_sub_resource-calls-through-the-c.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,223 +0,0 @@ -From 6e0637c6122e1cb792ae028ab60d45b91fb4d3a2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20D=C3=B6singer?= -Date: Fri, 4 Sep 2015 15:22:49 +0200 -Subject: wined3d: Send update_sub_resource calls through the command stream. - ---- - dlls/wined3d/cs.c | 91 ++++++++++++++++++++++++++++++++++++++++++ - dlls/wined3d/device.c | 43 +------------------- - dlls/wined3d/wined3d_private.h | 3 ++ - 3 files changed, 95 insertions(+), 42 deletions(-) - -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index 01c4ba3..277291b 100644 ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -94,6 +94,7 @@ enum wined3d_cs_op - WINED3D_CS_OP_GETDC, - WINED3D_CS_OP_RELEASEDC, - WINED3D_CS_OP_SAMPLER_DESTROY, -+ WINED3D_CS_OP_UPDATE_SUB_RESOURCE, - WINED3D_CS_OP_STOP, - }; - -@@ -564,6 +565,15 @@ struct wined3d_cs_sampler_destroy - struct wined3d_sampler *sampler; - }; - -+struct wined3d_cs_update_sub_resource -+{ -+ enum wined3d_cs_op opcode; -+ struct wined3d_resource *resource; -+ unsigned int sub_resource_idx, row_pitch, depth_pitch; -+ const struct wined3d_box *box; -+ const void *data; -+}; -+ - static void wined3d_cs_mt_submit(struct wined3d_cs *cs, size_t size) - { - LONG new_val = (cs->queue.head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -@@ -2785,6 +2795,86 @@ void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampl - cs->ops->submit(cs, sizeof(*op)); - } - -+static UINT wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_update_sub_resource *op = data; -+ -+ struct wined3d_resource *sub_resource; -+ const struct wined3d_gl_info *gl_info; -+ struct wined3d_const_bo_address addr; -+ struct wined3d_context *context; -+ struct wined3d_texture *texture; -+ struct wined3d_surface *surface; -+ POINT dst_point; -+ RECT src_rect; -+ -+ texture = wined3d_texture_from_resource(op->resource); -+ sub_resource = wined3d_texture_get_sub_resource(texture, op->sub_resource_idx); -+ surface = surface_from_resource(sub_resource); -+ -+ src_rect.left = 0; -+ src_rect.top = 0; -+ if (op->box) -+ { -+ src_rect.right = op->box->right - op->box->left; -+ src_rect.bottom = op->box->bottom - op->box->top; -+ dst_point.x = op->box->left; -+ dst_point.y = op->box->top; -+ } -+ else -+ { -+ src_rect.right = sub_resource->width; -+ src_rect.bottom = sub_resource->height; -+ dst_point.x = 0; -+ dst_point.y = 0; -+ } -+ -+ addr.buffer_object = 0; -+ addr.addr = op->data; -+ -+ context = context_acquire(cs->device, NULL); -+ gl_info = context->gl_info; -+ -+ /* Only load the surface for partial updates. */ -+ if (!dst_point.x && !dst_point.y && src_rect.right == sub_resource->width -+ && src_rect.bottom == sub_resource->height) -+ wined3d_texture_prepare_texture(texture, context, FALSE); -+ else -+ wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); -+ wined3d_texture_bind_and_dirtify(texture, context, FALSE); -+ -+ wined3d_surface_upload_data(surface, gl_info, op->resource->format, -+ &src_rect, op->row_pitch, &dst_point, FALSE, &addr); -+ -+ context_release(context); -+ -+ wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_TEXTURE_RGB); -+ wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); -+ -+ return sizeof(*op); -+} -+ -+void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, -+ unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, -+ unsigned int depth_pitch) -+{ -+ struct wined3d_cs_update_sub_resource *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; -+ op->resource = resource; -+ op->sub_resource_idx = sub_resource_idx; -+ op->box = box; -+ op->data = data; -+ op->row_pitch = row_pitch; -+ op->depth_pitch = depth_pitch; -+ -+ cs->ops->submit(cs, sizeof(*op)); -+ /* The data pointer may go away, need to wait until the data is read. Copying the data may be faster. -+ * Don't forget to copy box as well in this case. */ -+ cs->ops->finish(cs); -+} -+ - static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = - { - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, -@@ -2857,6 +2947,7 @@ static UINT (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc, - /* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc, - /* WINED3D_CS_OP_SAMPLER_DESTROY */ wined3d_cs_exec_sampler_destroy, -+ /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource, - }; - - static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index a6766e5..93498d8 100644 ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -3934,13 +3934,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str - unsigned int depth_pitch) - { - struct wined3d_resource *sub_resource; -- const struct wined3d_gl_info *gl_info; -- struct wined3d_const_bo_address addr; -- struct wined3d_context *context; - struct wined3d_texture *texture; -- struct wined3d_surface *surface; -- POINT dst_point; -- RECT src_rect; - - TRACE("device %p, resource %p, sub_resource_idx %u, box %p, data %p, row_pitch %u, depth_pitch %u.\n", - device, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); -@@ -3957,10 +3951,7 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str - WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); - return; - } -- surface = surface_from_resource(sub_resource); - -- src_rect.left = 0; -- src_rect.top = 0; - if (box) - { - if (box->left >= box->right || box->right > sub_resource->width -@@ -3970,41 +3961,9 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str - box->left, box->top, box->front, box->right, box->bottom, box->back); - return; - } -- -- src_rect.right = box->right - box->left; -- src_rect.bottom = box->bottom - box->top; -- dst_point.x = box->left; -- dst_point.y = box->top; - } -- else -- { -- src_rect.right = sub_resource->width; -- src_rect.bottom = sub_resource->height; -- dst_point.x = 0; -- dst_point.y = 0; -- } -- -- addr.buffer_object = 0; -- addr.addr = data; -- -- context = context_acquire(resource->device, NULL); -- gl_info = context->gl_info; -- -- /* Only load the surface for partial updates. */ -- if (!dst_point.x && !dst_point.y && src_rect.right == sub_resource->width -- && src_rect.bottom == sub_resource->height) -- wined3d_texture_prepare_texture(texture, context, FALSE); -- else -- wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); -- wined3d_texture_bind_and_dirtify(texture, context, FALSE); -- -- wined3d_surface_upload_data(surface, gl_info, resource->format, -- &src_rect, row_pitch, &dst_point, FALSE, &addr); -- -- context_release(context); - -- wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_TEXTURE_RGB); -- wined3d_resource_invalidate_location(&surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); -+ wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); - } - - HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device, -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 9125336..d9dd839 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -2823,6 +2823,9 @@ void wined3d_cs_emit_delete_opengl_contexts(struct wined3d_cs *cs, - void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; - void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; - void wined3d_cs_emit_sampler_destroy(struct wined3d_cs *cs, struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; -+void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, -+ unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, -+ unsigned int depth_pitch) DECLSPEC_HIDDEN; - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d --- -2.5.1 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/9999-IfDefined.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/9999-IfDefined.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-CSMT_Main/9999-IfDefined.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-CSMT_Main/9999-IfDefined.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,9872 +1,9708 @@ From: Wine Staging Team Subject: Autogenerated #ifdef patch for wined3d-CSMT_Main. -diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c ---- a/dlls/wined3d/swapchain.c -+++ b/dlls/wined3d/swapchain.c -@@ -320,7 +320,11 @@ - if (backbuffer->resource.multisample_type) - { - location = WINED3D_LOCATION_RB_RESOLVED; +diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c +--- a/dlls/d3d8/tests/visual.c ++++ b/dlls/d3d8/tests/visual.c +@@ -5480,7 +5480,11 @@ + fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE); + add_dirty_rect_test_draw(device); + color = getPixelColor(device, 320, 240); +#if defined(STAGING_CSMT) - wined3d_resource_load_location(&backbuffer->resource, context, location); + todo_wine ok(color_match(color, 0x00ff0000, 1), +#else /* STAGING_CSMT */ -+ surface_load_location(backbuffer, context, location); ++ ok(color_match(color, 0x00ff0000, 1), +#endif /* STAGING_CSMT */ - } - - context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, backbuffer, NULL, location); -@@ -428,11 +432,19 @@ - } - - static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in, + "Expected color 0x00ff0000, got 0x%08x.\n", color); + hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL); + ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr); +diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c +--- a/dlls/d3d9/tests/visual.c ++++ b/dlls/d3d9/tests/visual.c +@@ -1339,7 +1339,11 @@ + * result on Wine. + * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0}, + * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */ +#if defined(STAGING_CSMT) - const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags, - struct wined3d_surface *depth_stencil) - { - struct wined3d_surface *back_buffer = surface_from_resource( - wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); + {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS, 0}, +#else /* STAGING_CSMT */ -+ const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags) -+{ -+ struct wined3d_surface *back_buffer = surface_from_resource( -+ wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); -+ const struct wined3d_fb_state *fb = &swapchain->device->fb; ++ {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS | TODO_FILL_RETURN, 0}, +#endif /* STAGING_CSMT */ - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - struct wined3d_surface *front; -@@ -460,6 +472,37 @@ - NULL, WINED3D_TEXF_POINT); - } - -+#if !defined(STAGING_CSMT) -+ if (swapchain->device->bCursorVisible && swapchain->device->cursor_texture -+ && !swapchain->device->hardwareCursor) -+ { -+ struct wined3d_surface *cursor = surface_from_resource( -+ wined3d_texture_get_sub_resource(swapchain->device->cursor_texture, 0)); -+ RECT destRect = -+ { -+ swapchain->device->xScreenSpace - swapchain->device->xHotSpot, -+ swapchain->device->yScreenSpace - swapchain->device->yHotSpot, -+ swapchain->device->xScreenSpace + swapchain->device->cursorWidth - swapchain->device->xHotSpot, -+ swapchain->device->yScreenSpace + swapchain->device->cursorHeight - swapchain->device->yHotSpot, -+ }; -+ RECT src_rect = -+ { -+ 0, 0, -+ swapchain->device->cursor_texture->resource.width, -+ swapchain->device->cursor_texture->resource.height -+ }; -+ const RECT clip_rect = {0, 0, back_buffer->resource.width, back_buffer->resource.height}; -+ -+ TRACE("Rendering the software cursor.\n"); -+ -+ if (swapchain->desc.windowed) -+ MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&destRect, 2); -+ if (wined3d_clip_blit(&clip_rect, &destRect, &src_rect)) -+ wined3d_surface_blt(back_buffer, &destRect, cursor, &src_rect, WINEDDBLT_ALPHATEST, -+ NULL, WINED3D_TEXF_POINT); -+ } -+ + /* Vendor-specific formats like ATI2N are a non-issue here since they're not + * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET + * when created as texture. */ +@@ -17630,7 +17634,11 @@ + fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE); + add_dirty_rect_test_draw(device); + color = getPixelColor(device, 320, 240); ++#if defined(STAGING_CSMT) + todo_wine ok(color_match(color, 0x00ff0000, 1), ++#else /* STAGING_CSMT */ ++ ok(color_match(color, 0x00ff0000, 1), +#endif /* STAGING_CSMT */ - TRACE("Presenting HDC %p.\n", context->hdc); - - render_to_fbo = swapchain->render_to_fbo; -@@ -501,6 +544,7 @@ - */ - if (!swapchain->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO) + "Expected color 0x00ff0000, got 0x%08x.\n", color); + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr); +diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c +--- a/dlls/wined3d/arb_program_shader.c ++++ b/dlls/wined3d/arb_program_shader.c +@@ -684,7 +684,11 @@ { + const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; + const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog; +#if defined(STAGING_CSMT) - wined3d_resource_load_location(&back_buffer->resource, context, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_resource_invalidate_location(&back_buffer->resource, WINED3D_LOCATION_DRAWABLE); - swapchain->render_to_fbo = TRUE; -@@ -509,6 +553,16 @@ - else - { - wined3d_resource_load_location(&back_buffer->resource, context, back_buffer->container->resource.draw_binding); + UINT rt_height = state->fb.render_targets[0]->height; +#else /* STAGING_CSMT */ -+ surface_load_location(back_buffer, context, WINED3D_LOCATION_TEXTURE_RGB); -+ surface_invalidate_location(back_buffer, WINED3D_LOCATION_DRAWABLE); -+ swapchain->render_to_fbo = TRUE; -+ swapchain_update_draw_bindings(swapchain); -+ } -+ else -+ { -+ surface_load_location(back_buffer, context, back_buffer->container->resource.draw_binding); ++ UINT rt_height = state->fb->render_targets[0]->height; +#endif /* STAGING_CSMT */ - } - - if (swapchain->render_to_fbo) -@@ -521,8 +575,13 @@ - swapchain_blit(swapchain, context, &src_rect, &dst_rect); - } + /* Load DirectX 9 float constants for pixel shader */ + priv->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, +@@ -4712,7 +4716,11 @@ + } + else + { +#if defined(STAGING_CSMT) - if (swapchain->num_contexts > 1 && !wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFlush(); + UINT rt_height = state->fb.render_targets[0]->height; +#else /* STAGING_CSMT */ -+ if (swapchain->num_contexts > 1) -+ gl_info->gl_ops.gl.p_glFinish(); ++ UINT rt_height = state->fb->render_targets[0]->height; +#endif /* STAGING_CSMT */ + shader_arb_ps_local_constants(compiled, context, state, rt_height); + } - /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */ - gl_info->gl_ops.wgl.p_wglSwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */ -@@ -546,6 +605,7 @@ +@@ -7873,7 +7881,11 @@ - front = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); + /* Now load the surface */ + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO ++#if defined(STAGING_CSMT) + && (src_surface->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) ++#else /* STAGING_CSMT */ ++ && (src_surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) ++#endif /* STAGING_CSMT */ + == WINED3D_LOCATION_DRAWABLE + && !wined3d_resource_is_offscreen(&src_surface->container->resource)) + { +@@ -7911,6 +7923,7 @@ + /* Leave the opengl state valid for blitting */ + arbfp_blit_unset(context->gl_info); +#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&front->resource, WINED3D_LOCATION_DRAWABLE); - wined3d_resource_invalidate_location(&front->resource, ~WINED3D_LOCATION_DRAWABLE); - switch (swapchain->desc.swap_effect) -@@ -574,6 +634,31 @@ - { - wined3d_texture_decref(swapchain->device->cs->onscreen_depth_stencil->container); - swapchain->device->cs->onscreen_depth_stencil = NULL; + if (wined3d_settings.cs_multithreaded) + context->gl_info->gl_ops.gl.p_glFinish(); + else if (wined3d_settings.strict_draw_ordering +@@ -7922,6 +7935,17 @@ + + wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); + wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding); +#else /* STAGING_CSMT */ -+ surface_validate_location(front, WINED3D_LOCATION_DRAWABLE); -+ surface_invalidate_location(front, ~WINED3D_LOCATION_DRAWABLE); -+ /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM -+ * and INTEXTURE copies can keep their old content if they have any defined content. -+ * If the swapeffect is COPY, the content remains the same. -+ * -+ * The FLIP swap effect is not implemented yet. We could mark WINED3D_LOCATION_DRAWABLE -+ * up to date and hope WGL flipped front and back buffers and read this data into -+ * the FBO. Don't bother about this for now. */ ++ if (wined3d_settings.strict_draw_ordering ++ || (dst_surface->container->swapchain ++ && (dst_surface->container->swapchain->front_buffer == dst_surface->container))) ++ context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + -+ if (fb->depth_stencil) -+ { -+ struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(fb->depth_stencil); ++ context_release(context); + -+ if (ds && (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL -+ || ds->flags & SFLAG_DISCARD)) -+ { -+ surface_modify_ds_location(ds, WINED3D_LOCATION_DISCARDED, -+ fb->depth_stencil->width, fb->depth_stencil->height); -+ if (ds == swapchain->device->onscreen_depth_stencil) -+ { -+ wined3d_texture_decref(swapchain->device->onscreen_depth_stencil->container); -+ swapchain->device->onscreen_depth_stencil = NULL; ++ surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); ++ surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); +#endif /* STAGING_CSMT */ - } - } - } -@@ -606,7 +691,11 @@ - - TRACE("Copying surface %p to screen.\n", front); + } + static HRESULT arbfp_blit_color_fill(struct wined3d_device *device, struct wined3d_rendertarget_view *view, +diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c +--- a/dlls/wined3d/buffer.c ++++ b/dlls/wined3d/buffer.c +@@ -32,6 +32,7 @@ + #define WINED3D_BUFFER_HASDESC 0x01 /* A vertex description has been found. */ + #define WINED3D_BUFFER_CREATEBO 0x02 /* Create a buffer object for this buffer. */ + #define WINED3D_BUFFER_DOUBLEBUFFER 0x04 /* Keep both a buffer object and a system memory copy for this buffer. */ +#if defined(STAGING_CSMT) - wined3d_resource_load_location(&front->resource, NULL, WINED3D_LOCATION_DIB); + #define WINED3D_BUFFER_DISCARD 0x08 /* The next PreLoad may discard the buffer contents. */ + #define WINED3D_BUFFER_SYNC 0x10 /* There has been at least one synchronized map since the last preload. */ + #define WINED3D_BUFFER_APPLESYNC 0x20 /* Using sync as in GL_APPLE_flush_buffer_range. */ +@@ -42,6 +43,19 @@ + #define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */ + + void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, UINT offset, UINT size) +#else /* STAGING_CSMT */ -+ surface_load_location(front, NULL, WINED3D_LOCATION_DIB); ++#define WINED3D_BUFFER_FLUSH 0x08 /* Manual unmap flushing. */ ++#define WINED3D_BUFFER_DISCARD 0x10 /* A DISCARD lock has occurred since the last preload. */ ++#define WINED3D_BUFFER_SYNC 0x20 /* There has been at least one synchronized map since the last preload. */ ++#define WINED3D_BUFFER_APPLESYNC 0x40 /* Using sync as in GL_APPLE_flush_buffer_range. */ ++ ++#define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */ ++#define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */ ++#define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */ ++#define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */ ++ ++static void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, UINT offset, UINT size) +#endif /* STAGING_CSMT */ - - src_dc = front->hDC; - window = swapchain->win_handle; -@@ -634,8 +723,12 @@ + { + if (!offset && !size) + goto invalidate_all; +@@ -117,7 +131,11 @@ } - static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in, + /* Context activation is done by the caller. */ +#if defined(STAGING_CSMT) - const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags, - struct wined3d_surface *depth_stencil) + void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) +#else /* STAGING_CSMT */ -+ const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags) ++static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) +#endif /* STAGING_CSMT */ { - struct wined3d_surface *front, *back; - -@@ -662,9 +755,15 @@ - { - void *tmp; - + GLenum gl_usage = GL_STATIC_DRAW_ARB; + GLenum error; +@@ -166,6 +184,10 @@ + { + GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); + checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)"); ++#if !defined(STAGING_CSMT) ++ This->flags |= WINED3D_BUFFER_FLUSH; ++ ++#endif /* STAGING_CSMT */ + GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); + checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)"); + This->flags |= WINED3D_BUFFER_APPLESYNC; +@@ -191,10 +213,14 @@ + if (This->flags & WINED3D_BUFFER_DOUBLEBUFFER) + buffer_invalidate_bo_range(This, 0, 0); + else +#if defined(STAGING_CSMT) - tmp = front->resource.bitmap_data; - front->resource.bitmap_data = back->resource.bitmap_data; - back->resource.bitmap_data = tmp; + { + wined3d_resource_free_sysmem(&This->resource); + This->resource.map_heap_memory = NULL; + } +#else /* STAGING_CSMT */ -+ tmp = front->dib.bitmap_data; -+ front->dib.bitmap_data = back->dib.bitmap_data; -+ back->dib.bitmap_data = tmp; ++ wined3d_resource_free_sysmem(&This->resource); +#endif /* STAGING_CSMT */ - if (front->resource.heap_memory) - ERR("GDI Surface %p has heap memory allocated.\n", front); -@@ -735,6 +834,7 @@ - swapchain->render_to_fbo = TRUE; - } + return; -+#if defined(STAGING_CSMT) - HRESULT swapchain_create_context_cs(struct wined3d_device *device, struct wined3d_swapchain *swapchain) +@@ -423,6 +449,7 @@ { - const struct wined3d_adapter *adapter = device->adapter; -@@ -798,6 +898,7 @@ - return WINED3D_OK; - } + DWORD src_color = *dst_color; ++#if defined(STAGING_CSMT) + /* Color conversion like in draw_strided_slow. watch out for little endianity + * If we want that stuff to work on big endian machines too we have to consider more things + * +@@ -431,6 +458,16 @@ + * 0x0000ff00: Green mask + * 0x000000ff: Red mask + */ ++#else /* STAGING_CSMT */ ++ /* Color conversion like in drawStridedSlow. watch out for little endianity ++ * If we want that stuff to work on big endian machines too we have to consider more things ++ * ++ * 0xff000000: Alpha mask ++ * 0x00ff0000: Blue mask ++ * 0x0000ff00: Green mask ++ * 0x000000ff: Red mask ++ */ +#endif /* STAGING_CSMT */ - static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, - struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) - { -@@ -888,8 +989,13 @@ - front_buffer = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); - if (!(device->wined3d->flags & WINED3D_NO3D)) + *dst_color = 0; + *dst_color |= (src_color & 0xff00ff00u); /* Alpha Green */ + *dst_color |= (src_color & 0x00ff0000u) >> 16; /* Red */ +@@ -457,8 +494,12 @@ + data->buffer_object = buffer->buffer_object; + if (!buffer->buffer_object) { +#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&front_buffer->resource, WINED3D_LOCATION_DRAWABLE); - wined3d_resource_invalidate_location(&front_buffer->resource, ~WINED3D_LOCATION_DRAWABLE); + if ((!buffer->resource.map_count || buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER) + && buffer->flags & WINED3D_BUFFER_CREATEBO) +#else /* STAGING_CSMT */ -+ surface_validate_location(front_buffer, WINED3D_LOCATION_DRAWABLE); -+ surface_invalidate_location(front_buffer, ~WINED3D_LOCATION_DRAWABLE); ++ if ((buffer->flags & WINED3D_BUFFER_CREATEBO) && !buffer->resource.map_count) +#endif /* STAGING_CSMT */ - } + { + buffer_create_buffer_object(buffer, context); + buffer->flags &= ~WINED3D_BUFFER_CREATEBO; +@@ -497,7 +538,9 @@ - /* MSDN says we're only allowed a single fullscreen swapchain per device, -@@ -915,9 +1021,66 @@ + if (!wined3d_resource_allocate_sysmem(&This->resource)) + ERR("Failed to allocate system memory.\n"); ++#if defined(STAGING_CSMT) + This->resource.heap_memory = This->resource.map_heap_memory; ++#endif /* STAGING_CSMT */ + + if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) + context_invalidate_state(context, STATE_INDEXBUFFER); +@@ -545,6 +588,7 @@ + resource_unload(resource); + } - if (!(device->wined3d->flags & WINED3D_NO3D)) - { +#if defined(STAGING_CSMT) - hr = wined3d_cs_emit_create_swapchain_context(device->cs, swapchain); - if (FAILED(hr)) - goto err; + void wined3d_buffer_cleanup_cs(struct wined3d_buffer *buffer) + { + struct wined3d_context *context; +@@ -577,6 +621,30 @@ + + buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent); + wined3d_cs_emit_buffer_cleanup(device->cs, buffer); +#else /* STAGING_CSMT */ -+ static const enum wined3d_format_id formats[] = -+ { -+ WINED3DFMT_D24_UNORM_S8_UINT, -+ WINED3DFMT_D32_UNORM, -+ WINED3DFMT_R24_UNORM_X8_TYPELESS, -+ WINED3DFMT_D16_UNORM, -+ WINED3DFMT_S1_UINT_D15_UNORM -+ }; ++ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) ++{ ++ ULONG refcount = InterlockedDecrement(&buffer->resource.ref); ++ struct wined3d_context *context; + -+ const struct wined3d_gl_info *gl_info = &adapter->gl_info; ++ TRACE("%p decreasing refcount to %u.\n", buffer, refcount); + -+ swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); -+ if (!swapchain->context) ++ if (!refcount) ++ { ++ if (buffer->buffer_object) + { -+ ERR("Failed to create the context array.\n"); -+ hr = E_OUTOFMEMORY; -+ goto err; -+ } -+ swapchain->num_contexts = 1; ++ context = context_acquire(buffer->resource.device, NULL); ++ delete_gl_buffer(buffer, context->gl_info); ++ context_release(context); + -+ /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. -+ * You are able to add a depth + stencil surface at a later stage when you need it. -+ * In order to support this properly in WineD3D we need the ability to recreate the opengl context and -+ * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new -+ * context, need torecreate shaders, textures and other resources. -+ * -+ * The context manager already takes care of the state problem and for the other tasks code from Reset -+ * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. -+ * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the -+ * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this -+ * issue needs to be fixed. */ -+ for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) -+ { -+ swapchain->ds_format = wined3d_get_format(gl_info, formats[i]); -+ swapchain->context[0] = context_create(swapchain, front_buffer, swapchain->ds_format); -+ if (swapchain->context[0]) break; -+ TRACE("Depth stencil format %s is not supported, trying next format\n", -+ debug_d3dformat(formats[i])); ++ HeapFree(GetProcessHeap(), 0, buffer->conversion_map); + } + -+ if (!swapchain->context[0]) -+ { -+ WARN("Failed to create context.\n"); -+ hr = WINED3DERR_NOTAVAILABLE; -+ goto err; -+ } ++ resource_cleanup(&buffer->resource); ++ buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent); ++ HeapFree(GetProcessHeap(), 0, buffer->maps); ++ HeapFree(GetProcessHeap(), 0, buffer); ++#endif /* STAGING_CSMT */ + } + + return refcount; +@@ -661,6 +729,7 @@ + /* The caller provides a GL context */ + static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info, DWORD flags) + { ++#if defined(STAGING_CSMT) + UINT start, len; + + /* This potentially invalidates the element array buffer binding, but the +@@ -684,6 +753,45 @@ + GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)); + checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)"); + This->flags &= ~WINED3D_BUFFER_APPLESYNC; ++#else /* STAGING_CSMT */ ++ BYTE *map; ++ UINT start, len; + -+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO -+ && (!desc->enable_auto_depth_stencil -+ || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) ++ /* This potentially invalidates the element array buffer binding, but the ++ * caller always takes care of this. */ ++ GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object)); ++ checkGLcall("glBindBuffer"); ++ if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) ++ { ++ GLbitfield mapflags; ++ mapflags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; ++ if (flags & WINED3D_BUFFER_DISCARD) ++ mapflags |= GL_MAP_INVALIDATE_BUFFER_BIT; ++ else if (!(flags & WINED3D_BUFFER_SYNC)) ++ mapflags |= GL_MAP_UNSYNCHRONIZED_BIT; ++ map = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, ++ This->resource.size, mapflags)); ++ checkGLcall("glMapBufferRange"); ++ } ++ else ++ { ++ if (This->flags & WINED3D_BUFFER_APPLESYNC) + { -+ FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); ++ DWORD syncflags = 0; ++ if (flags & WINED3D_BUFFER_DISCARD) ++ syncflags |= WINED3D_MAP_DISCARD; ++ else if (!(flags & WINED3D_BUFFER_SYNC)) ++ syncflags |= WINED3D_MAP_NOOVERWRITE; ++ buffer_sync_apple(This, syncflags, gl_info); + } -+ context_release(swapchain->context[0]); ++ map = GL_EXTCALL(glMapBuffer(This->buffer_type_hint, GL_WRITE_ONLY)); ++ checkGLcall("glMapBuffer"); ++ } ++ if (!map) ++ { ++ ERR("Failed to map opengl buffer\n"); ++ return; +#endif /* STAGING_CSMT */ } - if (swapchain->desc.backbuffer_count > 0) -diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c ---- a/dlls/wined3d/state.c -+++ b/dlls/wined3d/state.c -@@ -105,7 +105,11 @@ - const struct wined3d_gl_info *gl_info = context->gl_info; + while (This->modified_areas) +@@ -692,12 +800,33 @@ + start = This->maps[This->modified_areas].offset; + len = This->maps[This->modified_areas].size; - /* No z test without depth stencil buffers */ +#if defined(STAGING_CSMT) - if (!state->fb.depth_stencil) -+#else /* STAGING_CSMT */ -+ if (!state->fb->depth_stencil) -+#endif /* STAGING_CSMT */ - { - TRACE("No Z buffer - disabling depth test\n"); - zenable = WINED3D_ZB_FALSE; -@@ -370,8 +374,13 @@ + GL_EXTCALL(glBufferSubData(This->buffer_type_hint, start, len, (BYTE *)This->resource.heap_memory + start)); + checkGLcall("glBufferSubData"); + } + } - static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) - { -+#if defined(STAGING_CSMT) - const struct wined3d_format *rt_format = state->fb.render_targets[0]->format; - unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; + static void buffer_mark_used(struct wined3d_buffer *buffer) +#else /* STAGING_CSMT */ -+ const struct wined3d_format *rt_format = state->fb->render_targets[0]->format; -+ unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; -+#endif /* STAGING_CSMT */ - const struct wined3d_gl_info *gl_info = context->gl_info; - GLenum srcBlend, dstBlend; - enum wined3d_blend d3d_blend; -@@ -816,7 +825,11 @@ - GLint depthFail_ccw; ++ memcpy(map + start, (BYTE *)This->resource.heap_memory + start, len); ++ ++ if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) ++ { ++ GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len)); ++ checkGLcall("glFlushMappedBufferRange"); ++ } ++ else if (This->flags & WINED3D_BUFFER_FLUSH) ++ { ++ GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len)); ++ checkGLcall("glFlushMappedBufferRangeAPPLE"); ++ } ++ } ++ GL_EXTCALL(glUnmapBuffer(This->buffer_type_hint)); ++ checkGLcall("glUnmapBuffer"); ++} ++ ++void buffer_mark_used(struct wined3d_buffer *buffer) ++#endif /* STAGING_CSMT */ + { + buffer->flags &= ~(WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); + } +@@ -716,6 +845,14 @@ - /* No stencil test without a stencil buffer. */ -+#if defined(STAGING_CSMT) - if (!state->fb.depth_stencil) -+#else /* STAGING_CSMT */ -+ if (!state->fb->depth_stencil) + TRACE("buffer %p.\n", buffer); + ++#if !defined(STAGING_CSMT) ++ if (buffer->resource.map_count) ++ { ++ WARN("Buffer is mapped, skipping preload.\n"); ++ return; ++ } ++ +#endif /* STAGING_CSMT */ - { - gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST); - checkGLcall("glDisable GL_STENCIL_TEST"); -@@ -912,7 +925,11 @@ + buffer_mark_used(buffer); - static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + if (!buffer->buffer_object) +@@ -904,6 +1041,7 @@ + + void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) { +#if defined(STAGING_CSMT) - DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; + struct wined3d_device *device = buffer->resource.device; + + if (buffer->resource.map_count) +@@ -913,6 +1051,12 @@ + } + + wined3d_cs_emit_buffer_preload(device->cs, buffer); +#else /* STAGING_CSMT */ -+ DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; ++ struct wined3d_context *context; ++ context = context_acquire(buffer->resource.device, NULL); ++ buffer_internal_preload(buffer, context, NULL); ++ context_release(context); +#endif /* STAGING_CSMT */ - const struct wined3d_gl_info *gl_info = context->gl_info; - - GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); -@@ -926,7 +943,11 @@ + } - static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer) +@@ -926,6 +1070,7 @@ { + LONG count; + BYTE *base; +#if defined(STAGING_CSMT) - DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; + struct wined3d_device *device = buffer->resource.device; + struct wined3d_context *context; + +@@ -950,6 +1095,10 @@ + wined3d_cs_emit_create_vbo(device->cs, buffer); + buffer->flags &= ~WINED3D_BUFFER_CREATEBO; + } +#else /* STAGING_CSMT */ -+ DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; ++ ++ TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags); +#endif /* STAGING_CSMT */ - const struct wined3d_gl_info *gl_info = context->gl_info; - - gl_info->gl_ops.gl.p_glStencilMask(mask); -@@ -1128,10 +1149,17 @@ - /* drop through */ - case WINED3D_FOG_NONE: + flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags); + /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001 multitexture +@@ -958,7 +1107,11 @@ + * previous contents of the buffer. The r600g driver only does this when + * the buffer is currently in use, while the proprietary NVIDIA driver + * appears to do this unconditionally. */ +#if defined(STAGING_CSMT) - /* Both are none? According to msdn the alpha channel of the specular - * color contains a fog factor. Set it in draw_strided_slow. - * Same happens with Vertexfog on transformed vertices - */ + if (buffer->ignore_discard) +#else /* STAGING_CSMT */ -+ /* Both are none? According to msdn the alpha channel of the specular -+ * color contains a fog factor. Set it in drawStridedSlow. -+ * Same happens with Vertexfog on transformed vertices -+ */ ++ if (buffer->flags & WINED3D_BUFFER_DISCARD) +#endif /* STAGING_CSMT */ - new_source = FOGSOURCE_COORD; - gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR); - checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)"); -@@ -1653,7 +1681,11 @@ - if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS] - || state->render_states[WINED3D_RS_DEPTHBIAS]) - { + flags &= ~WINED3D_MAP_DISCARD; + count = ++buffer->resource.map_count; + +@@ -969,6 +1122,7 @@ + * being uploaded in that case. Two such applications are Port Royale + * and Darkstar One. */ + if (flags & WINED3D_MAP_DISCARD) +#if defined(STAGING_CSMT) - const struct wined3d_rendertarget_view *depth = state->fb.depth_stencil; + wined3d_cs_emit_buffer_invalidate_bo_range(device->cs, buffer, 0, 0); + else if (!(flags & WINED3D_MAP_READONLY)) + wined3d_cs_emit_buffer_invalidate_bo_range(device->cs, buffer, offset, size); +@@ -986,6 +1140,19 @@ + wined3d_cs_emit_glfinish(device->cs); + device->cs->ops->finish(device->cs); + } +#else /* STAGING_CSMT */ -+ const struct wined3d_rendertarget_view *depth = state->fb->depth_stencil; ++ buffer_invalidate_bo_range(buffer, 0, 0); ++ else if (!(flags & WINED3D_MAP_READONLY)) ++ buffer_invalidate_bo_range(buffer, offset, size); ++ ++ if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) ++ { ++ if (count == 1) ++ { ++ struct wined3d_device *device = buffer->resource.device; ++ struct wined3d_context *context; ++ const struct wined3d_gl_info *gl_info; +#endif /* STAGING_CSMT */ - float scale; - union -@@ -4190,9 +4222,15 @@ + context = context_acquire(device, NULL); + gl_info = context->gl_info; +@@ -1036,6 +1203,7 @@ + buffer_get_sysmem(buffer, context); + } + TRACE("New pointer is %p.\n", buffer->resource.heap_memory); ++#if defined(STAGING_CSMT) } + context_release(context); } - } else { -+#if defined(STAGING_CSMT) - /* TODO: support blends in draw_strided_slow - * No need to write a FIXME here, this is done after the general vertex decl decoding - */ +@@ -1075,6 +1243,21 @@ + } + + base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.map_heap_memory; +#else /* STAGING_CSMT */ -+ /* TODO: support blends in drawStridedSlow -+ * No need to write a FIXME here, this is done after the general vertex decl decoding -+ */ ++ buffer->map_ptr = NULL; ++ } ++ context_release(context); ++ } ++ } ++ ++ if (flags & WINED3D_MAP_DISCARD) ++ buffer->flags |= WINED3D_BUFFER_DISCARD; ++ else if (!(flags & WINED3D_MAP_NOOVERWRITE)) ++ buffer->flags |= WINED3D_BUFFER_SYNC; ++ } ++ ++ base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.heap_memory; +#endif /* STAGING_CSMT */ - WARN("unsupported blending in openGl\n"); - } - } -@@ -4546,7 +4584,11 @@ + *data = base + offset; - static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) - { + TRACE("Returning memory at %p (base %p, offset %u).\n", *data, base, offset); +@@ -1128,7 +1311,11 @@ + checkGLcall("glFlushMappedBufferRange"); + } + } +#if defined(STAGING_CSMT) - const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; + else if (buffer->flags & WINED3D_BUFFER_APPLESYNC) +#else /* STAGING_CSMT */ -+ const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; ++ else if (buffer->flags & WINED3D_BUFFER_FLUSH) +#endif /* STAGING_CSMT */ - const struct wined3d_gl_info *gl_info = context->gl_info; - struct wined3d_viewport vp = state->viewport; + { + for (i = 0; i < buffer->modified_areas; ++i) + { +@@ -1139,6 +1326,7 @@ + } -@@ -4724,7 +4766,11 @@ - } - else - { + GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint)); +#if defined(STAGING_CSMT) - const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; + if (wined3d_settings.cs_multithreaded) + gl_info->gl_ops.gl.p_glFinish(); + else if (wined3d_settings.strict_draw_ordering) +@@ -1147,6 +1335,18 @@ + + buffer_clear_dirty_areas(buffer); + buffer->map_ptr = NULL; +#else /* STAGING_CSMT */ -+ const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; ++ if (wined3d_settings.strict_draw_ordering) ++ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ ++ context_release(context); ++ ++ buffer_clear_dirty_areas(buffer); ++ buffer->map_ptr = NULL; ++ } ++ else if (buffer->flags & WINED3D_BUFFER_HASDESC) ++ { ++ wined3d_buffer_preload(buffer); +#endif /* STAGING_CSMT */ - UINT height; - UINT width; + } + } -@@ -4788,7 +4834,11 @@ +@@ -1225,6 +1425,7 @@ + return WINED3D_OK; + } - void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) ++#if defined(STAGING_CSMT) + static void wined3d_buffer_location_invalidated(struct wined3d_resource *resource, DWORD location) { + ERR("Not yet implemented.\n"); +@@ -1237,6 +1438,7 @@ + ERR("Not yet implemented.\n"); + } + ++#endif /* STAGING_CSMT */ + static const struct wined3d_resource_ops buffer_resource_ops = + { + buffer_resource_incref, +@@ -1244,8 +1446,10 @@ + buffer_unload, + buffer_resource_sub_resource_map, + buffer_resource_sub_resource_unmap, +#if defined(STAGING_CSMT) - unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; -+#else /* STAGING_CSMT */ -+ unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; + wined3d_buffer_location_invalidated, + wined3d_buffer_load_location, +#endif /* STAGING_CSMT */ - const struct wined3d_gl_info *gl_info = context->gl_info; + }; - TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); -diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c ---- a/dlls/d3d8/tests/visual.c -+++ b/dlls/d3d8/tests/visual.c -@@ -5480,7 +5480,11 @@ - fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE); - add_dirty_rect_test_draw(device); - color = getPixelColor(device, 320, 240); + static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device *device, +@@ -1277,7 +1481,9 @@ + return hr; + } + buffer->buffer_type_hint = bind_hint; +#if defined(STAGING_CSMT) - todo_wine ok(color_match(color, 0x00ff0000, 1), + buffer->ignore_discard = TRUE; ++#endif /* STAGING_CSMT */ + + TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage, + debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory, buffer); +@@ -1293,6 +1499,7 @@ + + dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE]; + ++#if defined(STAGING_CSMT) + /* Observations show that draw_strided_slow is faster on dynamic VBs than converting + + * drawStridedFast (half-life 2 and others). + * +@@ -1300,6 +1507,15 @@ + * show that draw_strided_slow is faster than converting + uploading + drawStridedFast. + * Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers. + */ +#else /* STAGING_CSMT */ -+ ok(color_match(color, 0x00ff0000, 1), ++ /* Observations show that drawStridedSlow is faster on dynamic VBs than converting + ++ * drawStridedFast (half-life 2 and others). ++ * ++ * Basically converting the vertices in the buffer is quite expensive, and observations ++ * show that drawStridedSlow is faster than converting + uploading + drawStridedFast. ++ * Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers. ++ */ +#endif /* STAGING_CSMT */ - "Expected color 0x00ff0000, got 0x%08x.\n", color); - hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL); - ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr); -diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c ---- a/dlls/wined3d/volume.c -+++ b/dlls/wined3d/volume.c -@@ -40,6 +40,32 @@ - return TRUE; - } + if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT]) + { + TRACE("Not creating a vbo because GL_ARB_vertex_buffer is not supported\n"); +@@ -1317,6 +1533,7 @@ + buffer->flags |= WINED3D_BUFFER_CREATEBO; + } -+#if !defined(STAGING_CSMT) -+void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch) -+{ -+ const struct wined3d_format *format = volume->resource.format; -+ -+ if (volume->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) ++#if defined(STAGING_CSMT) + buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)); + if (!buffer->maps) + { +@@ -1341,6 +1558,28 @@ + + if (wined3d_settings.cs_multithreaded) + buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER; ++#else /* STAGING_CSMT */ ++ if (data) + { -+ /* Since compressed formats are block based, pitch means the amount of -+ * bytes to the next row of block rather than the next row of pixels. */ -+ UINT row_block_count = (volume->resource.width + format->block_width - 1) / format->block_width; -+ UINT slice_block_count = (volume->resource.height + format->block_height - 1) / format->block_height; -+ *row_pitch = row_block_count * format->block_byte_count; -+ *slice_pitch = *row_pitch * slice_block_count; ++ if (FAILED(hr = wined3d_buffer_upload_data(buffer, NULL, data->data))) ++ { ++ ERR("Failed to upload data, hr %#x.\n", hr); ++ buffer_unload(&buffer->resource); ++ resource_cleanup(&buffer->resource); ++ return hr; ++ } + } -+ else ++ ++ buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)); ++ if (!buffer->maps) + { -+ unsigned char alignment = volume->resource.device->surface_alignment; -+ *row_pitch = format->byte_count * volume->resource.width; /* Bytes / row */ -+ *row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1); -+ *slice_pitch = *row_pitch * volume->resource.height; ++ ERR("Out of memory\n"); ++ buffer_unload(&buffer->resource); ++ resource_cleanup(&buffer->resource); ++ return E_OUTOFMEMORY; + } -+ -+ TRACE("Returning row pitch %u, slice pitch %u.\n", *row_pitch, *slice_pitch); -+} -+ ++ buffer->maps_size = 1; +#endif /* STAGING_CSMT */ - /* This call just uploads data, the caller is responsible for binding the - * correct texture. */ - /* Context activation is done by the caller. */ -@@ -71,7 +97,11 @@ - dst_row_pitch = width * format->conv_byte_count; - dst_slice_pitch = dst_row_pitch * height; + return WINED3D_OK; + } +@@ -1449,6 +1688,7 @@ + + return WINED3D_OK; + } +#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(&volume->resource, &src_row_pitch, &src_slice_pitch); -+#else /* STAGING_CSMT */ -+ wined3d_volume_get_pitch(volume, &src_row_pitch, &src_slice_pitch); -+#endif /* STAGING_CSMT */ - converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth); - format->convert(data->addr, converted_mem, src_row_pitch, src_slice_pitch, -@@ -99,6 +129,22 @@ - HeapFree(GetProcessHeap(), 0, converted_mem); + void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) + { +@@ -1456,3 +1696,4 @@ + buffer->resource.heap_memory = mem; + buffer->flags |= WINED3D_BUFFER_DISCARD; } ++#endif /* STAGING_CSMT */ +diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c +--- a/dlls/wined3d/context.c ++++ b/dlls/wined3d/context.c +@@ -1453,6 +1453,7 @@ + goto out; + } + ++#if defined(STAGING_CSMT) + ret->current_fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(*ret->current_fb.render_targets) * gl_info->limits.buffers); + ret->current_fb.rt_size = gl_info->limits.buffers; +@@ -1461,6 +1462,7 @@ + if (device->context_count) + ret->offscreenBuffer = device->contexts[0]->offscreenBuffer; -+#if !defined(STAGING_CSMT) -+void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) -+{ -+ TRACE("Volume %p, setting %s.\n", volume, wined3d_debug_location(location)); -+ volume->locations |= location; -+ TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations)); -+} -+ -+void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) -+{ -+ TRACE("Volume %p, clearing %s.\n", volume, wined3d_debug_location(location)); -+ volume->locations &= ~location; -+ TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations)); -+} -+ +#endif /* STAGING_CSMT */ - /* Context activation is done by the caller. */ - static void wined3d_volume_download_data(struct wined3d_volume *volume, - const struct wined3d_context *context, const struct wined3d_bo_address *data) -@@ -134,8 +180,33 @@ - static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume) - { - wined3d_resource_free_sysmem(&volume->resource); + /* Initialize the texture unit mapping to a 1:1 mapping */ + for (s = 0; s < MAX_COMBINED_SAMPLERS; ++s) + { +@@ -1785,7 +1787,9 @@ + if (hdc) wined3d_release_dc(swapchain->win_handle, hdc); + device->shader_backend->shader_free_context_data(ret); + device->adapter->fragment_pipe->free_context_data(ret); +#if defined(STAGING_CSMT) - volume->resource.map_heap_memory = NULL; - wined3d_resource_invalidate_location(&volume->resource, WINED3D_LOCATION_SYSMEM); + HeapFree(GetProcessHeap(), 0, ret->current_fb.render_targets); ++#endif /* STAGING_CSMT */ + HeapFree(GetProcessHeap(), 0, ret->free_event_queries); + HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries); + HeapFree(GetProcessHeap(), 0, ret->free_timestamp_queries); +@@ -1820,7 +1824,9 @@ + + device->shader_backend->shader_free_context_data(context); + device->adapter->fragment_pipe->free_context_data(context); ++#if defined(STAGING_CSMT) + HeapFree(GetProcessHeap(), 0, context->current_fb.render_targets); ++#endif /* STAGING_CSMT */ + HeapFree(GetProcessHeap(), 0, context->draw_buffers); + HeapFree(GetProcessHeap(), 0, context->blit_targets); + device_context_remove(device, context); +@@ -2240,6 +2246,7 @@ + WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n"); + + /* The currently active context is the necessary context to access the swapchain's onscreen buffers */ ++#if defined(STAGING_CSMT) + wined3d_resource_load_location(&context->current_rt->resource, context, WINED3D_LOCATION_TEXTURE_RGB); + swapchain->render_to_fbo = TRUE; + swapchain_update_draw_bindings(swapchain); +@@ -2254,6 +2261,22 @@ + return context_generate_rt_mask_from_surface(rt); + else + return context_generate_rt_mask(context->offscreenBuffer); +#else /* STAGING_CSMT */ -+ wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_SYSMEM); ++ surface_load_location(context->current_rt, context, WINED3D_LOCATION_TEXTURE_RGB); ++ swapchain->render_to_fbo = TRUE; ++ swapchain_update_draw_bindings(swapchain); ++ context_set_render_offscreen(context, TRUE); +} + -+static DWORD volume_access_from_location(DWORD location) ++static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_device *device, const struct wined3d_surface *rt) +{ -+ switch (location) -+ { -+ case WINED3D_LOCATION_DISCARDED: -+ return 0; -+ -+ case WINED3D_LOCATION_SYSMEM: -+ return WINED3D_RESOURCE_ACCESS_CPU; -+ -+ case WINED3D_LOCATION_BUFFER: -+ case WINED3D_LOCATION_TEXTURE_RGB: -+ case WINED3D_LOCATION_TEXTURE_SRGB: -+ return WINED3D_RESOURCE_ACCESS_GPU; -+ -+ default: -+ FIXME("Unhandled location %#x.\n", location); -+ return 0; -+ } ++ if (!rt || rt->resource.format->id == WINED3DFMT_NULL) ++ return 0; ++ else if (rt->container->swapchain) ++ return context_generate_rt_mask_from_surface(rt); ++ else ++ return context_generate_rt_mask(device->offscreenBuffer); +#endif /* STAGING_CSMT */ } /* Context activation is done by the caller. */ -@@ -177,6 +248,7 @@ - - return TRUE; - } +@@ -2285,7 +2308,11 @@ + } + else + { +#if defined(STAGING_CSMT) - - /* Context activation is done by the caller. */ - static void wined3d_volume_load_location(struct wined3d_resource *resource, -@@ -187,6 +259,22 @@ - - TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location), - wined3d_debug_location(volume->resource.locations)); + rt_mask = context_generate_rt_mask_no_fbo(context, rt); +#else /* STAGING_CSMT */ -+/* Context activation is done by the caller. */ -+static void wined3d_volume_load_location(struct wined3d_volume *volume, -+ struct wined3d_context *context, DWORD location) -+{ -+ DWORD required_access = volume_access_from_location(location); -+ -+ TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location), -+ wined3d_debug_location(volume->locations)); -+ -+ if ((volume->locations & location) == location) -+ { -+ TRACE("Location(s) already up to date.\n"); -+ return; -+ } ++ rt_mask = context_generate_rt_mask_no_fbo(device, rt); +#endif /* STAGING_CSMT */ + } - if ((volume->resource.access_flags & required_access) != required_access) - { -@@ -205,6 +293,7 @@ - && !(volume->container->flags & WINED3D_TEXTURE_SRGB_ALLOCATED))) - ERR("Trying to load (s)RGB texture without prior allocation.\n"); + cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; +@@ -2332,7 +2359,11 @@ + DWORD rt_mask = 0, *cur_mask; + UINT i; +#if defined(STAGING_CSMT) - if (volume->resource.locations & WINED3D_LOCATION_DISCARDED) - { - TRACE("Volume previously discarded, nothing to do.\n"); -@@ -238,6 +327,41 @@ - return; - } - wined3d_resource_validate_location(&volume->resource, location); + if (isStateDirty(context, STATE_FRAMEBUFFER) || !wined3d_fb_equal(fb, &context->current_fb) +#else /* STAGING_CSMT */ -+ if (volume->locations & WINED3D_LOCATION_DISCARDED) -+ { -+ TRACE("Volume previously discarded, nothing to do.\n"); -+ wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); -+ } -+ else if (volume->locations & WINED3D_LOCATION_SYSMEM) -+ { -+ struct wined3d_const_bo_address data = {0, volume->resource.heap_memory}; -+ wined3d_texture_bind_and_dirtify(volume->container, context, -+ location == WINED3D_LOCATION_TEXTURE_SRGB); -+ wined3d_volume_upload_data(volume, context, &data); -+ } -+ else if (volume->locations & WINED3D_LOCATION_BUFFER) -+ { -+ struct wined3d_const_bo_address data = {volume->pbo, NULL}; -+ wined3d_texture_bind_and_dirtify(volume->container, context, -+ location == WINED3D_LOCATION_TEXTURE_SRGB); -+ wined3d_volume_upload_data(volume, context, &data); -+ } -+ else if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) -+ { -+ wined3d_volume_srgb_transfer(volume, context, TRUE); -+ } -+ else if (volume->locations & WINED3D_LOCATION_TEXTURE_SRGB) -+ { -+ wined3d_volume_srgb_transfer(volume, context, FALSE); -+ } -+ else -+ { -+ FIXME("Implement texture loading from %s.\n", wined3d_debug_location(volume->locations)); -+ return; -+ } -+ wined3d_volume_validate_location(volume, location); ++ if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != &device->fb +#endif /* STAGING_CSMT */ - - if (wined3d_volume_can_evict(volume)) - wined3d_volume_evict_sysmem(volume); -@@ -248,11 +372,24 @@ - if (!volume->resource.heap_memory) - ERR("Trying to load WINED3D_LOCATION_SYSMEM without setting it up first.\n"); - + || rt_count != context->gl_info->limits.buffers) + { + if (!context_validate_rt_config(rt_count, rts, dsv)) +@@ -2374,11 +2405,17 @@ + } + else + { +#if defined(STAGING_CSMT) - if (volume->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) - { - struct wined3d_bo_address data = {0, volume->resource.heap_memory}; + rt_mask = context_generate_rt_mask_no_fbo(context, + rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); + } - if (volume->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) + wined3d_fb_copy(&context->current_fb, fb); +#else /* STAGING_CSMT */ -+ if (volume->locations & WINED3D_LOCATION_DISCARDED) -+ { -+ TRACE("Volume previously discarded, nothing to do.\n"); -+ wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); -+ } -+ else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) -+ { -+ struct wined3d_bo_address data = {0, volume->resource.heap_memory}; -+ -+ if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) ++ rt_mask = context_generate_rt_mask_no_fbo(device, ++ rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); ++ } +#endif /* STAGING_CSMT */ - wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); - else - wined3d_texture_bind_and_dirtify(volume->container, context, TRUE); -@@ -263,6 +400,7 @@ - else - { - FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", + } + else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO + && (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))) +@@ -2391,7 +2428,11 @@ + } + else + { +#if defined(STAGING_CSMT) - wined3d_debug_location(volume->resource.locations)); - return; - } -@@ -278,6 +416,28 @@ - struct wined3d_bo_address data = {volume->resource.buffer->name, NULL}; + rt_mask = context_generate_rt_mask_no_fbo(context, ++#else /* STAGING_CSMT */ ++ rt_mask = context_generate_rt_mask_no_fbo(device, ++#endif /* STAGING_CSMT */ + rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); + } - if (volume->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) +@@ -2434,6 +2475,7 @@ + return TRUE; + } + ++#if defined(STAGING_CSMT) + static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_state *state) + { + struct wined3d_rendertarget_view **rts = state->fb.render_targets; +@@ -2443,6 +2485,18 @@ + + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) + return context_generate_rt_mask_no_fbo(context, wined3d_rendertarget_view_get_surface(rts[0])); +#else /* STAGING_CSMT */ -+ wined3d_debug_location(volume->locations)); -+ return; -+ } -+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM); -+ break; -+ -+ case WINED3D_LOCATION_BUFFER: -+ if (!volume->pbo) -+ ERR("Trying to load WINED3D_LOCATION_BUFFER without setting it up first.\n"); -+ -+ if (volume->locations & WINED3D_LOCATION_DISCARDED) -+ { -+ TRACE("Volume previously discarded, nothing to do.\n"); -+ wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); -+ } -+ else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) -+ { -+ struct wined3d_bo_address data = {volume->pbo, NULL}; ++static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_device *device) ++{ ++ const struct wined3d_state *state = &device->state; ++ struct wined3d_rendertarget_view **rts = state->fb->render_targets; ++ struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; ++ DWORD rt_mask, rt_mask_bits; ++ unsigned int i; + -+ if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) ++ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) ++ return context_generate_rt_mask_no_fbo(device, wined3d_rendertarget_view_get_surface(rts[0])); +#endif /* STAGING_CSMT */ - wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); - else - wined3d_texture_bind_and_dirtify(volume->container, context, TRUE); -@@ -287,6 +447,7 @@ - else - { - FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", + else if (!context->render_offscreen) + return context_generate_rt_mask_from_surface(wined3d_rendertarget_view_get_surface(rts[0])); + +@@ -2465,8 +2519,14 @@ + /* Context activation is done by the caller. */ + void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { +#if defined(STAGING_CSMT) - wined3d_debug_location(volume->resource.locations)); - return; - } -@@ -296,6 +457,17 @@ - default: - FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), - wined3d_debug_location(volume->resource.locations)); + const struct wined3d_fb_state *fb = &state->fb; + DWORD rt_mask = find_draw_buffers_mask(context, state); +#else /* STAGING_CSMT */ -+ wined3d_debug_location(volume->locations)); -+ return; -+ } -+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER); -+ break; -+ -+ default: -+ FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), -+ wined3d_debug_location(volume->locations)); ++ const struct wined3d_device *device = context->swapchain->device; ++ const struct wined3d_fb_state *fb = state->fb; ++ DWORD rt_mask = find_draw_buffers_mask(context, device); +#endif /* STAGING_CSMT */ + DWORD *cur_mask; + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) +@@ -2497,8 +2557,10 @@ + context_apply_draw_buffers(context, rt_mask); + *cur_mask = rt_mask; } ++#if defined(STAGING_CSMT) + + wined3d_fb_copy(&context->current_fb, &state->fb); ++#endif /* STAGING_CSMT */ } -@@ -303,6 +475,7 @@ - void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) + static void context_map_stage(struct wined3d_context *context, DWORD stage, DWORD unit) +@@ -2745,12 +2807,22 @@ + /* Context activation is done by the caller. */ + void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - wined3d_texture_prepare_texture(volume->container, context, srgb_mode); +#if defined(STAGING_CSMT) - wined3d_resource_load_location(&volume->resource, context, - srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB); - } -@@ -315,6 +488,51 @@ - resource_cleanup(&volume->resource); - volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent); - wined3d_cs_emit_volume_cleanup(device->cs, volume); + DWORD rt_mask, *cur_mask; + + if (isStateDirty(context, STATE_FRAMEBUFFER)) return; + + cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; + rt_mask = find_draw_buffers_mask(context, state); +#else /* STAGING_CSMT */ -+ wined3d_volume_load_location(volume, context, -+ srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB); -+} -+ -+/* Context activation is done by the caller. */ -+static void wined3d_volume_prepare_pbo(struct wined3d_volume *volume, struct wined3d_context *context) -+{ -+ const struct wined3d_gl_info *gl_info = context->gl_info; -+ -+ if (volume->pbo) -+ return; -+ -+ GL_EXTCALL(glGenBuffers(1, &volume->pbo)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo)); -+ GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, volume->resource.size, NULL, GL_STREAM_DRAW)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); -+ checkGLcall("Create PBO"); -+ -+ TRACE("Created PBO %u for volume %p.\n", volume->pbo, volume); -+} -+ -+static void wined3d_volume_free_pbo(struct wined3d_volume *volume) -+{ -+ struct wined3d_context *context = context_acquire(volume->resource.device, NULL); -+ const struct wined3d_gl_info *gl_info = context->gl_info; -+ -+ TRACE("Deleting PBO %u belonging to volume %p.\n", volume->pbo, volume); -+ GL_EXTCALL(glDeleteBuffers(1, &volume->pbo)); -+ checkGLcall("glDeleteBuffers"); -+ volume->pbo = 0; -+ context_release(context); -+} -+ -+void wined3d_volume_destroy(struct wined3d_volume *volume) -+{ -+ TRACE("volume %p.\n", volume); ++ const struct wined3d_device *device = context->swapchain->device; ++ DWORD rt_mask, *cur_mask; + -+ if (volume->pbo) -+ wined3d_volume_free_pbo(volume); ++ if (isStateDirty(context, STATE_FRAMEBUFFER)) return; + -+ resource_cleanup(&volume->resource); -+ volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent); -+ HeapFree(GetProcessHeap(), 0, volume); ++ cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; ++ rt_mask = find_draw_buffers_mask(context, device); ++#endif /* STAGING_CSMT */ + if (rt_mask != *cur_mask) + { + context_apply_draw_buffers(context, rt_mask); +@@ -2952,7 +3024,11 @@ + { + if (state->vertex_declaration->half_float_conv_needed && !stream_info->all_vbo) + { ++#if defined(STAGING_CSMT) + TRACE("Using draw_strided_slow with vertex shaders for FLOAT16 conversion.\n"); ++#else /* STAGING_CSMT */ ++ TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion.\n"); +#endif /* STAGING_CSMT */ + context->use_immediate_mode_draw = TRUE; + } + else +@@ -3137,11 +3213,19 @@ } - static void volume_unload(struct wined3d_resource *resource) -@@ -328,6 +546,7 @@ - - TRACE("texture %p.\n", resource); - + /* Context activation is done by the caller. */ +#if defined(STAGING_CSMT) - if (wined3d_resource_prepare_system_memory(&volume->resource)) - { - context = context_acquire(device, NULL); -@@ -340,6 +559,29 @@ - ERR("Out of memory when unloading volume %p.\n", volume); - wined3d_resource_validate_location(&volume->resource, WINED3D_LOCATION_DISCARDED); - wined3d_resource_invalidate_location(&volume->resource, ~WINED3D_LOCATION_DISCARDED); + BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, + const struct wined3d_state *state) + { + const struct StateEntry *state_table = context->state_table; + const struct wined3d_fb_state *fb = &state->fb; +#else /* STAGING_CSMT */ -+ if (volume_prepare_system_memory(volume)) -+ { -+ context = context_acquire(device, NULL); -+ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM); -+ context_release(context); -+ wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_SYSMEM); -+ } -+ else -+ { -+ ERR("Out of memory when unloading volume %p.\n", volume); -+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_DISCARDED); -+ wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_DISCARDED); -+ } -+ -+ if (volume->pbo) -+ { -+ /* Should not happen because only dynamic default pool volumes -+ * have a buffer, and those are not evicted by device_evit_managed_resources -+ * and must be freed before a non-ex device reset. */ -+ ERR("Unloading a volume with a buffer\n"); -+ wined3d_volume_free_pbo(volume); ++BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) ++{ ++ const struct wined3d_state *state = &device->state; ++ const struct StateEntry *state_table = context->state_table; ++ const struct wined3d_fb_state *fb = state->fb; ++#endif /* STAGING_CSMT */ + unsigned int i; + WORD map; + +@@ -3174,12 +3258,17 @@ + for (i = 0, map = context->stream_info.use_map; map; map >>= 1, ++i) + { + if (map & 1) ++#if defined(STAGING_CSMT) + buffer_internal_preload(state->streams[context->stream_info.elements[i].stream_idx].buffer, + context, state); + } + /* PreLoad may kick buffers out of vram. */ + if (isStateDirty(context, STATE_STREAMSRC)) + context_update_stream_info(context, state); ++#else /* STAGING_CSMT */ ++ buffer_mark_used(state->streams[context->stream_info.elements[i].stream_idx].buffer); ++ } ++#endif /* STAGING_CSMT */ + } + if (state->index_buffer) + { +@@ -3274,7 +3363,11 @@ + if (texture->texture_srgb.name) + wined3d_texture_load(texture, context, TRUE); + wined3d_texture_load(texture, context, FALSE); ++#if defined(STAGING_CSMT) + wined3d_resource_invalidate_location(&context->current_rt->resource, WINED3D_LOCATION_DRAWABLE); ++#else /* STAGING_CSMT */ ++ surface_invalidate_location(context->current_rt, WINED3D_LOCATION_DRAWABLE); +#endif /* STAGING_CSMT */ + } } - /* The texture name is managed by the container. */ -@@ -348,6 +590,36 @@ - resource_unload(resource); - } +diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c +--- a/dlls/wined3d/cs.c ++++ b/dlls/wined3d/cs.c +@@ -22,11 +22,18 @@ -+#if !defined(STAGING_CSMT) -+static BOOL volume_check_block_align(const struct wined3d_volume *volume, -+ const struct wined3d_box *box) -+{ -+ UINT width_mask, height_mask; -+ const struct wined3d_format *format = volume->resource.format; -+ -+ if (!box) -+ return TRUE; -+ -+ /* This assumes power of two block sizes, but NPOT block sizes would be -+ * silly anyway. -+ * -+ * This also assumes that the format's block depth is 1. */ -+ width_mask = format->block_width - 1; -+ height_mask = format->block_height - 1; + WINE_DEFAULT_DEBUG_CHANNEL(d3d); + ++#if defined(STAGING_CSMT) + enum wined3d_cs_op + { + WINED3D_CS_OP_NOP, + WINED3D_CS_OP_SKIP, + WINED3D_CS_OP_FENCE, ++#else /* STAGING_CSMT */ ++#define WINED3D_INITIAL_CS_SIZE 4096 + -+ if (box->left & width_mask) -+ return FALSE; -+ if (box->top & height_mask) -+ return FALSE; -+ if (box->right & width_mask && box->right != volume->resource.width) -+ return FALSE; -+ if (box->bottom & height_mask && box->bottom != volume->resource.height) -+ return FALSE; ++enum wined3d_cs_op ++{ ++#endif /* STAGING_CSMT */ + WINED3D_CS_OP_PRESENT, + WINED3D_CS_OP_CLEAR, + WINED3D_CS_OP_DRAW, +@@ -53,6 +60,7 @@ + WINED3D_CS_OP_SET_COLOR_KEY, + WINED3D_CS_OP_SET_MATERIAL, + WINED3D_CS_OP_RESET_STATE, ++#if defined(STAGING_CSMT) + WINED3D_CS_OP_SET_VS_CONSTS_F, + WINED3D_CS_OP_SET_VS_CONSTS_B, + WINED3D_CS_OP_SET_VS_CONSTS_I, +@@ -132,6 +140,30 @@ + float depth; + DWORD stencil; + RECT rects[1]; ++#else /* STAGING_CSMT */ ++}; + -+ return TRUE; -+} ++struct wined3d_cs_present ++{ ++ enum wined3d_cs_op opcode; ++ HWND dst_window_override; ++ struct wined3d_swapchain *swapchain; ++ const RECT *src_rect; ++ const RECT *dst_rect; ++ const RGNDATA *dirty_region; ++ DWORD flags; ++}; + ++struct wined3d_cs_clear ++{ ++ enum wined3d_cs_op opcode; ++ DWORD rect_count; ++ const RECT *rects; ++ DWORD flags; ++ const struct wined3d_color *color; ++ float depth; ++ DWORD stencil; +#endif /* STAGING_CSMT */ - static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *volume, - const struct wined3d_box *box) - { -@@ -373,6 +645,7 @@ - HRESULT wined3d_volume_map(struct wined3d_volume *volume, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) + }; + + struct wined3d_cs_draw +@@ -154,6 +186,7 @@ + struct wined3d_cs_set_viewport { + enum wined3d_cs_op opcode; +#if defined(STAGING_CSMT) - HRESULT hr; - const struct wined3d_format *format = volume->resource.format; - const unsigned int fmt_flags = volume->container->resource.format_flags; -@@ -413,6 +686,177 @@ - if (hr == WINEDDERR_NOTLOCKED) - return WINED3DERR_INVALIDCALL; - return hr; + struct wined3d_viewport viewport; + }; + +@@ -161,6 +194,15 @@ + { + enum wined3d_cs_op opcode; + RECT rect; +#else /* STAGING_CSMT */ -+ struct wined3d_device *device = volume->resource.device; -+ struct wined3d_context *context; -+ const struct wined3d_gl_info *gl_info; -+ BYTE *base_memory; -+ const struct wined3d_format *format = volume->resource.format; -+ const unsigned int fmt_flags = volume->container->resource.format_flags; -+ -+ TRACE("volume %p, map_desc %p, box %p, flags %#x.\n", -+ volume, map_desc, box, flags); -+ -+ map_desc->data = NULL; -+ if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) -+ { -+ WARN("Volume %p is not CPU accessible.\n", volume); -+ return WINED3DERR_INVALIDCALL; -+ } -+ if (volume->resource.map_count) -+ { -+ WARN("Volume is already mapped.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ if (!wined3d_volume_check_box_dimensions(volume, box)) -+ { -+ WARN("Map box is invalid.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !volume_check_block_align(volume, box)) -+ { -+ WARN("Map box is misaligned for %ux%u blocks.\n", -+ format->block_width, format->block_height); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags); -+ -+ if (volume->resource.map_binding == WINED3D_LOCATION_BUFFER) -+ { -+ context = context_acquire(device, NULL); -+ gl_info = context->gl_info; -+ -+ wined3d_volume_prepare_pbo(volume, context); -+ if (flags & WINED3D_MAP_DISCARD) -+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER); -+ else -+ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER); -+ -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo)); -+ -+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) -+ { -+ GLbitfield mapflags = wined3d_resource_gl_map_flags(flags); -+ mapflags &= ~GL_MAP_FLUSH_EXPLICIT_BIT; -+ base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, -+ 0, volume->resource.size, mapflags)); -+ } -+ else -+ { -+ GLenum access = wined3d_resource_gl_legacy_map_flags(flags); -+ base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access)); -+ } ++ const struct wined3d_viewport *viewport; ++}; + -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); -+ checkGLcall("Map PBO"); ++struct wined3d_cs_set_scissor_rect ++{ ++ enum wined3d_cs_op opcode; ++ const RECT *rect; ++#endif /* STAGING_CSMT */ + }; + + struct wined3d_cs_set_rendertarget_view +@@ -288,6 +330,7 @@ + { + enum wined3d_cs_op opcode; + enum wined3d_transform_state state; ++#if defined(STAGING_CSMT) + struct wined3d_matrix matrix; + }; + +@@ -302,6 +345,22 @@ + { + enum wined3d_cs_op opcode; + struct wined3d_material material; ++#else /* STAGING_CSMT */ ++ const struct wined3d_matrix *matrix; ++}; + -+ context_release(context); -+ } -+ else -+ { -+ if (!volume_prepare_system_memory(volume)) -+ { -+ WARN("Out of memory.\n"); -+ map_desc->data = NULL; -+ return E_OUTOFMEMORY; -+ } ++struct wined3d_cs_set_clip_plane ++{ ++ enum wined3d_cs_op opcode; ++ UINT plane_idx; ++ const struct wined3d_vec4 *plane; ++}; + -+ if (flags & WINED3D_MAP_DISCARD) -+ { -+ wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM); -+ } -+ else if (!(volume->locations & WINED3D_LOCATION_SYSMEM)) -+ { -+ context = context_acquire(device, NULL); -+ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM); -+ context_release(context); -+ } -+ base_memory = volume->resource.heap_memory; -+ } -+ -+ TRACE("Base memory pointer %p.\n", base_memory); -+ -+ if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) -+ { -+ map_desc->row_pitch = volume->resource.width * format->byte_count; -+ map_desc->slice_pitch = map_desc->row_pitch * volume->resource.height; -+ } -+ else -+ { -+ wined3d_volume_get_pitch(volume, &map_desc->row_pitch, &map_desc->slice_pitch); -+ } -+ -+ if (!box) -+ { -+ TRACE("No box supplied - all is ok\n"); -+ map_desc->data = base_memory; -+ } -+ else -+ { -+ TRACE("Lock Box (%p) = l %u, t %u, r %u, b %u, fr %u, ba %u\n", -+ box, box->left, box->top, box->right, box->bottom, box->front, box->back); -+ -+ if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) -+ { -+ /* Compressed textures are block based, so calculate the offset of -+ * the block that contains the top-left pixel of the locked rectangle. */ -+ map_desc->data = base_memory -+ + (box->front * map_desc->slice_pitch) -+ + ((box->top / format->block_height) * map_desc->row_pitch) -+ + ((box->left / format->block_width) * format->block_byte_count); -+ } -+ else -+ { -+ map_desc->data = base_memory -+ + (map_desc->slice_pitch * box->front) -+ + (map_desc->row_pitch * box->top) -+ + (box->left * volume->resource.format->byte_count); -+ } -+ } -+ -+ if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) -+ { -+ wined3d_texture_set_dirty(volume->container); -+ wined3d_volume_invalidate_location(volume, ~volume->resource.map_binding); -+ } -+ -+ volume->resource.map_count++; -+ -+ TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n", -+ map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); -+ -+ return WINED3D_OK; -+} -+ -+HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) ++struct wined3d_cs_set_material +{ -+ TRACE("volume %p.\n", volume); -+ -+ if (!volume->resource.map_count) -+ { -+ WARN("Trying to unlock an unlocked volume %p.\n", volume); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ if (volume->resource.map_binding == WINED3D_LOCATION_BUFFER) -+ { -+ struct wined3d_device *device = volume->resource.device; -+ struct wined3d_context *context = context_acquire(device, NULL); -+ const struct wined3d_gl_info *gl_info = context->gl_info; -+ -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo)); -+ GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); -+ checkGLcall("Unmap PBO"); -+ -+ context_release(context); -+ } -+ -+ volume->resource.map_count--; -+ -+ return WINED3D_OK; ++ enum wined3d_cs_op opcode; ++ const struct wined3d_material *material; +#endif /* STAGING_CSMT */ - } + }; - static ULONG volume_resource_incref(struct wined3d_resource *resource) -@@ -423,11 +867,13 @@ - return wined3d_texture_incref(volume->container); - } + struct wined3d_cs_reset_state +@@ -309,6 +368,7 @@ + enum wined3d_cs_op opcode; + }; +#if defined(STAGING_CSMT) - void wined3d_volume_cleanup_cs(struct wined3d_volume *volume) + struct wined3d_cs_set_consts_f { - HeapFree(GetProcessHeap(), 0, volume); - } - -+#endif /* STAGING_CSMT */ - static ULONG volume_resource_decref(struct wined3d_resource *resource) + enum wined3d_cs_op opcode; +@@ -2847,197 +2907,971 @@ + /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, + /* WINED3D_CS_OP_SKIP */ wined3d_cs_exec_skip, + /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, +- /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, +- /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, +- /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, +- /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication, +- /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport, +- /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect, +- /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, +- /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, +- /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, +- /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, +- /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, +- /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output, +- /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, +- /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, +- /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, +- /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, +- /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, +- /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, +- /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, +- /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, +- /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, +- /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, +- /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, +- /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, +- /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, +- /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, +- /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, +- /* WINED3D_CS_OP_SET_VS_CONSTS_B */ wined3d_cs_exec_set_vs_consts_b, +- /* WINED3D_CS_OP_SET_VS_CONSTS_I */ wined3d_cs_exec_set_vs_consts_i, +- /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, +- /* WINED3D_CS_OP_SET_PS_CONSTS_B */ wined3d_cs_exec_set_ps_consts_b, +- /* WINED3D_CS_OP_SET_PS_CONSTS_I */ wined3d_cs_exec_set_ps_consts_i, +- /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, +- /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, +- /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, +- /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, +- /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, +- /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, +- /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, +- /* WINED3D_CS_OP_RESOURCE_CHANGED */ wined3d_cs_exec_resource_changed, +- /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, +- /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, +- /* WINED3D_CS_OP_BUFFER_SWAP_MEM */ wined3d_cs_exec_buffer_swap_mem, +- /* WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE */ wined3d_cs_exec_buffer_invalidate_bo_range, +- /* WINED3D_CS_OP_BUFFER_PRELOAD */ wined3d_cs_exec_buffer_preload, +- /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, +- /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, +- /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, +- /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, +- /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, +- /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, +- /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, +- /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, +- /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, +- /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, +- /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, +- /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, +- /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, +- /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, +- /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, +- /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, +- /* WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT */ wined3d_cs_exec_create_swapchain_context, +- /* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts, +- /* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc, +- /* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc, +- /* WINED3D_CS_OP_SAMPLER_DESTROY */ wined3d_cs_exec_sampler_destroy, +- /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource, +-}; +- +-static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) ++#else /* STAGING_CSMT */ ++static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) { - struct wined3d_volume *volume = volume_from_resource(resource); -@@ -449,6 +895,7 @@ - return WINED3DERR_INVALIDCALL; - } +- struct wined3d_cs_queue *queue = prio ? &cs->prio_queue : &cs->queue; +- size_t queue_size = sizeof(queue->data) / sizeof(*queue->data); ++ const struct wined3d_cs_present *op = data; ++ struct wined3d_swapchain *swapchain; -+#if defined(STAGING_CSMT) - static void wined3d_volume_location_invalidated(struct wined3d_resource *resource, DWORD location) - { - struct wined3d_volume *volume = volume_from_resource(resource); -@@ -457,6 +904,7 @@ - wined3d_texture_set_dirty(volume->container); - } +- if (queue_size - size < queue->head) +- { +- struct wined3d_cs_skip *skip; +- size_t nop_size = queue_size - queue->head; ++ swapchain = op->swapchain; ++ wined3d_swapchain_set_window(swapchain, op->dst_window_override); -+#endif /* STAGING_CSMT */ - static const struct wined3d_resource_ops volume_resource_ops = - { - volume_resource_incref, -@@ -464,8 +912,10 @@ - volume_unload, - volume_resource_sub_resource_map, - volume_resource_sub_resource_unmap, -+#if defined(STAGING_CSMT) - wined3d_volume_location_invalidated, - wined3d_volume_load_location, -+#endif /* STAGING_CSMT */ - }; +- skip = _wined3d_cs_mt_require_space(cs, nop_size, prio); +- if (nop_size < sizeof(*skip)) +- { +- skip->opcode = WINED3D_CS_OP_NOP; +- } +- else +- { +- skip->opcode = WINED3D_CS_OP_SKIP; +- skip->size = nop_size; +- } ++ swapchain->swapchain_ops->swapchain_present(swapchain, ++ op->src_rect, op->dst_rect, op->dirty_region, op->flags); ++} - static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture *container, -@@ -497,7 +947,11 @@ - } +- if (prio) +- cs->ops->submit_prio(cs, nop_size); +- else +- cs->ops->submit(cs, nop_size); ++void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, ++ const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, ++ const RGNDATA *dirty_region, DWORD flags) ++{ ++ struct wined3d_cs_present *op; - volume->texture_level = level; -+#if defined(STAGING_CSMT) - volume->resource.locations = WINED3D_LOCATION_DISCARDED; -+#else /* STAGING_CSMT */ -+ volume->locations = WINED3D_LOCATION_DISCARDED; -+#endif /* STAGING_CSMT */ +- assert(!queue->head); +- } ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_PRESENT; ++ op->dst_window_override = dst_window_override; ++ op->swapchain = swapchain; ++ op->src_rect = src_rect; ++ op->dst_rect = dst_rect; ++ op->dirty_region = dirty_region; ++ op->flags = flags; - if (desc->pool == WINED3D_POOL_DEFAULT && desc->usage & WINED3DUSAGE_DYNAMIC - && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] -@@ -505,7 +959,9 @@ - { - wined3d_resource_free_sysmem(&volume->resource); - volume->resource.map_binding = WINED3D_LOCATION_BUFFER; -+#if defined(STAGING_CSMT) - volume->resource.map_heap_memory = NULL; -+#endif /* STAGING_CSMT */ - } - - volume->container = container; -diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c ---- a/dlls/wined3d/utils.c -+++ b/dlls/wined3d/utils.c -@@ -3733,7 +3733,11 @@ - float y_offset = context->render_offscreen - ? (center_offset - (2.0f * y) - h) / h - : (center_offset - (2.0f * y) - h) / -h; -+#if defined(STAGING_CSMT) - enum wined3d_depth_buffer_type zenable = state->fb.depth_stencil ? -+#else /* STAGING_CSMT */ -+ enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ? -+#endif /* STAGING_CSMT */ - state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; - float z_scale = zenable ? 2.0f : 0.0f; - float z_offset = zenable ? -1.0f : 0.0f; -@@ -3856,6 +3860,7 @@ - /* case WINED3D_TTFF_COUNT1: Won't ever get here. */ - case WINED3D_TTFF_COUNT2: - mat._13 = mat._23 = mat._33 = mat._43 = 0.0f; -+#if defined(STAGING_CSMT) - /* OpenGL divides the first 3 vertex coord by the 4th by default, - * which is essentially the same as D3DTTFF_PROJECTED. Make sure that - * the 4th coord evaluates to 1.0 to eliminate that. -@@ -3868,6 +3873,20 @@ - * A more serious problem occurs if the app passes 4 coordinates in, and the - * 4th is != 1.0(opengl default). This would have to be fixed in draw_strided_slow - * or a replacement shader. */ -+#else /* STAGING_CSMT */ -+ /* OpenGL divides the first 3 vertex coord by the 4th by default, -+ * which is essentially the same as D3DTTFF_PROJECTED. Make sure that -+ * the 4th coord evaluates to 1.0 to eliminate that. -+ * -+ * If the fixed function pipeline is used, the 4th value remains unused, -+ * so there is no danger in doing this. With vertex shaders we have a -+ * problem. Should an app hit that problem, the code here would have to -+ * check for pixel shaders, and the shader has to undo the default gl divide. -+ * -+ * A more serious problem occurs if the app passes 4 coordinates in, and the -+ * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow -+ * or a replacement shader. */ -+#endif /* STAGING_CSMT */ - default: - mat._14 = mat._24 = mat._34 = 0.0f; mat._44 = 1.0f; - } -@@ -4325,7 +4344,11 @@ - unsigned int i; - DWORD ttff; - DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; -+#if defined(STAGING_CSMT) - unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; -+#else /* STAGING_CSMT */ -+ unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; -+#endif /* STAGING_CSMT */ - const struct wined3d_gl_info *gl_info = context->gl_info; - const struct wined3d_d3d_info *d3d_info = context->d3d_info; - -diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c ---- a/dlls/wined3d/wined3d_main.c -+++ b/dlls/wined3d/wined3d_main.c -@@ -87,8 +87,10 @@ - ~0U, /* No GS shader model limit by default. */ - ~0U, /* No PS shader model limit by default. */ - FALSE, /* 3D support enabled by default. */ -+#if defined(STAGING_CSMT) - TRUE, /* Multithreaded CS by default. */ - FALSE, /* Do not ignore render target maps. */ -+#endif /* STAGING_CSMT */ - }; - - struct wined3d * CDECL wined3d_create(DWORD flags) -@@ -328,6 +330,7 @@ - TRACE("Disabling 3D support.\n"); - wined3d_settings.no_3d = TRUE; - } -+#if defined(STAGING_CSMT) - if (!get_config_key(hkey, appkey, "CSMT", buffer, size) - && !strcmp(buffer,"disabled")) - { -@@ -344,6 +347,9 @@ - - FIXME_(winediag)("Experimental wined3d CSMT feature is currently %s.\n", - wined3d_settings.cs_multithreaded ? "enabled" : "disabled"); -+#else /* STAGING_CSMT */ -+ } -+#endif /* STAGING_CSMT */ - - if (appkey) RegCloseKey( appkey ); - if (hkey) RegCloseKey( hkey ); -diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c ---- a/dlls/wined3d/arb_program_shader.c -+++ b/dlls/wined3d/arb_program_shader.c -@@ -684,7 +684,11 @@ - { - const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; - const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog; -+#if defined(STAGING_CSMT) - UINT rt_height = state->fb.render_targets[0]->height; -+#else /* STAGING_CSMT */ -+ UINT rt_height = state->fb->render_targets[0]->height; -+#endif /* STAGING_CSMT */ - - /* Load DirectX 9 float constants for pixel shader */ - priv->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, -@@ -4712,7 +4716,11 @@ - } - else - { -+#if defined(STAGING_CSMT) - UINT rt_height = state->fb.render_targets[0]->height; -+#else /* STAGING_CSMT */ -+ UINT rt_height = state->fb->render_targets[0]->height; -+#endif /* STAGING_CSMT */ - shader_arb_ps_local_constants(compiled, context, state, rt_height); - } - -@@ -7844,7 +7852,11 @@ +- while(1) +- { +- LONG head = queue->head; +- LONG tail = *((volatile LONG *)&queue->tail); +- LONG new_pos; +- /* Empty */ +- if (head == tail) +- break; +- /* Head ahead of tail, take care of wrap-around */ +- new_pos = (head + size) & (WINED3D_CS_QUEUE_SIZE - 1); +- if (head > tail && (new_pos || tail)) +- break; +- /* Tail ahead of head, but still enough space */ +- if (new_pos < tail && new_pos) +- break; ++ cs->ops->submit(cs); ++} - /* Now load the surface */ - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO -+#if defined(STAGING_CSMT) - && (src_surface->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) -+#else /* STAGING_CSMT */ -+ && (src_surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_DRAWABLE)) -+#endif /* STAGING_CSMT */ - == WINED3D_LOCATION_DRAWABLE - && !wined3d_resource_is_offscreen(&src_surface->container->resource)) - { -@@ -7882,6 +7894,7 @@ - /* Leave the opengl state valid for blitting */ - arbfp_blit_unset(context->gl_info); +- TRACE("Waiting for free space. Head %u, tail %u, want %u\n", head, tail, +- (unsigned int) size); +- } ++static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_clear *op = data; ++ struct wined3d_device *device; ++ RECT draw_rect; -+#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - context->gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering -@@ -7893,6 +7906,17 @@ +- return &queue->data[queue->head]; ++ device = cs->device; ++ wined3d_get_draw_rect(&device->state, &draw_rect); ++ device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, ++ &device->fb, op->rect_count, op->rects, &draw_rect, op->flags, ++ op->color, op->depth, op->stencil); + } - wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); - wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding); -+#else /* STAGING_CSMT */ -+ if (wined3d_settings.strict_draw_ordering -+ || (dst_surface->container->swapchain -+ && (dst_surface->container->swapchain->front_buffer == dst_surface->container))) -+ context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ +-static inline void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) ++void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, ++ DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) + { +- return _wined3d_cs_mt_require_space(cs, size, FALSE); ++ struct wined3d_cs_clear *op; + -+ context_release(context); ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_CLEAR; ++ op->rect_count = rect_count; ++ op->rects = rects; ++ op->flags = flags; ++ op->color = color; ++ op->depth = depth; ++ op->stencil = stencil; + -+ surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); -+ surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); -+#endif /* STAGING_CSMT */ ++ cs->ops->submit(cs); } - static HRESULT arbfp_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface, -diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c ---- a/dlls/wined3d/view.c -+++ b/dlls/wined3d/view.c -@@ -33,11 +33,13 @@ - return refcount; +-static inline void *wined3d_cs_mt_require_space_prio(struct wined3d_cs *cs, size_t size) ++static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) + { +- return _wined3d_cs_mt_require_space(cs, size, TRUE); ++ const struct wined3d_cs_draw *op = data; ++ ++ draw_primitive(cs->device, op->start_idx, op->index_count, ++ op->start_instance, op->instance_count, op->indexed); } -+#if defined(STAGING_CSMT) - void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) +-/* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an +- * OP itself. */ +-static void wined3d_cs_emit_stop(struct wined3d_cs *cs) ++void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count, ++ UINT start_instance, UINT instance_count, BOOL indexed) { - HeapFree(GetProcessHeap(), 0, view); +- struct wined3d_cs_stop *op; ++ struct wined3d_cs_draw *op; + +- op = wined3d_cs_mt_require_space(cs, sizeof(*op)); +- op->opcode = WINED3D_CS_OP_STOP; ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_DRAW; ++ op->start_idx = start_idx; ++ op->index_count = index_count; ++ op->start_instance = start_instance; ++ op->instance_count = instance_count; ++ op->indexed = indexed; + +- wined3d_cs_mt_submit(cs, sizeof(*op)); ++ cs->ops->submit(cs); } -+#endif /* STAGING_CSMT */ - ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view) +-static void wined3d_cs_mt_finish(struct wined3d_cs *cs) ++static void wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data) { - ULONG refcount = InterlockedDecrement(&view->refcount); -@@ -46,6 +48,7 @@ +- BOOL fence; +- +- if (cs->thread_id == GetCurrentThreadId()) +- { +- static BOOL once; +- if (!once) +- { +- FIXME("flush_and_wait called from cs thread\n"); +- once = TRUE; +- } +- return; +- } +- +- wined3d_cs_emit_fence(cs, &fence); ++ const struct wined3d_cs_set_predication *op = data; - if (!refcount) - { -+#if defined(STAGING_CSMT) - struct wined3d_device *device = view->resource->device; +- /* A busy wait should be fine, we're not supposed to have to wait very +- * long. */ +- while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); ++ cs->state.predicate = op->predicate; ++ cs->state.predicate_value = op->value; + } - /* Call wined3d_object_destroyed() before releasing the resource, -@@ -53,6 +56,13 @@ - view->parent_ops->wined3d_object_destroyed(view->parent); - wined3d_resource_decref(view->resource); - wined3d_cs_emit_view_destroy(device->cs, view); -+#else /* STAGING_CSMT */ -+ /* Call wined3d_object_destroyed() before releasing the resource, -+ * since releasing the resource may end up destroying the parent. */ -+ view->parent_ops->wined3d_object_destroyed(view->parent); -+ wined3d_resource_decref(view->resource); -+ HeapFree(GetProcessHeap(), 0, view); -+#endif /* STAGING_CSMT */ - } - - return refcount; -diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c ---- a/dlls/wined3d/context.c -+++ b/dlls/wined3d/context.c -@@ -1453,6 +1453,7 @@ - goto out; - } - -+#if defined(STAGING_CSMT) - ret->current_fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(*ret->current_fb.render_targets) * gl_info->limits.buffers); - ret->current_fb.rt_size = gl_info->limits.buffers; -@@ -1461,6 +1462,7 @@ - if (device->context_count) - ret->offscreenBuffer = device->contexts[0]->offscreenBuffer; - -+#endif /* STAGING_CSMT */ - /* Initialize the texture unit mapping to a 1:1 mapping */ - for (s = 0; s < MAX_COMBINED_SAMPLERS; ++s) - { -@@ -1784,7 +1786,9 @@ - out: - device->shader_backend->shader_free_context_data(ret); - device->adapter->fragment_pipe->free_context_data(ret); -+#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, ret->current_fb.render_targets); -+#endif /* STAGING_CSMT */ - HeapFree(GetProcessHeap(), 0, ret->free_event_queries); - HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries); - HeapFree(GetProcessHeap(), 0, ret->free_timestamp_queries); -@@ -1819,7 +1823,9 @@ +-static void wined3d_cs_mt_finish_prio(struct wined3d_cs *cs) ++void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value) + { +- BOOL fence; ++ struct wined3d_cs_set_predication *op; - device->shader_backend->shader_free_context_data(context); - device->adapter->fragment_pipe->free_context_data(context); -+#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, context->current_fb.render_targets); -+#endif /* STAGING_CSMT */ - HeapFree(GetProcessHeap(), 0, context->draw_buffers); - HeapFree(GetProcessHeap(), 0, context->blit_targets); - device_context_remove(device, context); -@@ -2239,6 +2245,7 @@ - WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n"); +- if (cs->thread_id == GetCurrentThreadId()) +- { +- static BOOL once; +- if (!once) +- { +- FIXME("flush_and_wait called from cs thread\n"); +- once = TRUE; +- } +- return; +- } ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_PREDICATION; ++ op->predicate = predicate; ++ op->value = value; - /* The currently active context is the necessary context to access the swapchain's onscreen buffers */ -+#if defined(STAGING_CSMT) - wined3d_resource_load_location(&context->current_rt->resource, context, WINED3D_LOCATION_TEXTURE_RGB); - swapchain->render_to_fbo = TRUE; - swapchain_update_draw_bindings(swapchain); -@@ -2253,6 +2260,22 @@ - return context_generate_rt_mask_from_surface(rt); - else - return context_generate_rt_mask(context->offscreenBuffer); -+#else /* STAGING_CSMT */ -+ surface_load_location(context->current_rt, context, WINED3D_LOCATION_TEXTURE_RGB); -+ swapchain->render_to_fbo = TRUE; -+ swapchain_update_draw_bindings(swapchain); -+ context_set_render_offscreen(context, TRUE); +- wined3d_cs_emit_fence_prio(cs, &fence); ++ cs->ops->submit(cs); +} -+ -+static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_device *device, const struct wined3d_surface *rt) -+{ -+ if (!rt || rt->resource.format->id == WINED3DFMT_NULL) -+ return 0; -+ else if (rt->container->swapchain) -+ return context_generate_rt_mask_from_surface(rt); -+ else -+ return context_generate_rt_mask(device->offscreenBuffer); -+#endif /* STAGING_CSMT */ - } - - /* Context activation is done by the caller. */ -@@ -2284,7 +2307,11 @@ - } - else - { -+#if defined(STAGING_CSMT) - rt_mask = context_generate_rt_mask_no_fbo(context, rt); -+#else /* STAGING_CSMT */ -+ rt_mask = context_generate_rt_mask_no_fbo(device, rt); -+#endif /* STAGING_CSMT */ - } - - cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; -@@ -2331,7 +2358,11 @@ - DWORD rt_mask = 0, *cur_mask; - UINT i; - -+#if defined(STAGING_CSMT) - if (isStateDirty(context, STATE_FRAMEBUFFER) || !wined3d_fb_equal(fb, &context->current_fb) -+#else /* STAGING_CSMT */ -+ if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != &device->fb -+#endif /* STAGING_CSMT */ - || rt_count != context->gl_info->limits.buffers) - { - if (!context_validate_rt_config(rt_count, rts, dsv)) -@@ -2373,11 +2404,17 @@ - } - else - { -+#if defined(STAGING_CSMT) - rt_mask = context_generate_rt_mask_no_fbo(context, - rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); - } - - wined3d_fb_copy(&context->current_fb, fb); -+#else /* STAGING_CSMT */ -+ rt_mask = context_generate_rt_mask_no_fbo(device, -+ rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); -+ } -+#endif /* STAGING_CSMT */ - } - else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO - && (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))) -@@ -2390,7 +2427,11 @@ - } - else - { -+#if defined(STAGING_CSMT) - rt_mask = context_generate_rt_mask_no_fbo(context, -+#else /* STAGING_CSMT */ -+ rt_mask = context_generate_rt_mask_no_fbo(device, -+#endif /* STAGING_CSMT */ - rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); - } - -@@ -2433,6 +2474,7 @@ - return TRUE; - } - -+#if defined(STAGING_CSMT) - static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_state *state) - { - struct wined3d_rendertarget_view **rts = state->fb.render_targets; -@@ -2442,6 +2484,18 @@ - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) - return context_generate_rt_mask_no_fbo(context, wined3d_rendertarget_view_get_surface(rts[0])); -+#else /* STAGING_CSMT */ -+static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_device *device) +- /* A busy wait should be fine, we're not supposed to have to wait very +- * long. */ +- while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); ++static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) +{ -+ const struct wined3d_state *state = &device->state; -+ struct wined3d_rendertarget_view **rts = state->fb->render_targets; -+ struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL]; -+ DWORD rt_mask, rt_mask_bits; -+ unsigned int i; ++ const struct wined3d_cs_set_viewport *op = data; + -+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) -+ return context_generate_rt_mask_no_fbo(device, wined3d_rendertarget_view_get_surface(rts[0])); -+#endif /* STAGING_CSMT */ - else if (!context->render_offscreen) - return context_generate_rt_mask_from_surface(wined3d_rendertarget_view_get_surface(rts[0])); - -@@ -2464,8 +2518,14 @@ - /* Context activation is done by the caller. */ - void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) - { -+#if defined(STAGING_CSMT) - const struct wined3d_fb_state *fb = &state->fb; - DWORD rt_mask = find_draw_buffers_mask(context, state); -+#else /* STAGING_CSMT */ -+ const struct wined3d_device *device = context->swapchain->device; -+ const struct wined3d_fb_state *fb = state->fb; -+ DWORD rt_mask = find_draw_buffers_mask(context, device); -+#endif /* STAGING_CSMT */ - DWORD *cur_mask; - - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) -@@ -2496,8 +2556,10 @@ - context_apply_draw_buffers(context, rt_mask); - *cur_mask = rt_mask; - } -+#if defined(STAGING_CSMT) - - wined3d_fb_copy(&context->current_fb, &state->fb); -+#endif /* STAGING_CSMT */ ++ cs->state.viewport = *op->viewport; ++ device_invalidate_state(cs->device, STATE_VIEWPORT); } - static void context_map_stage(struct wined3d_context *context, DWORD stage, DWORD unit) -@@ -2744,12 +2806,22 @@ - /* Context activation is done by the caller. */ - void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +-static const struct wined3d_cs_ops wined3d_cs_mt_ops = ++void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) { -+#if defined(STAGING_CSMT) - DWORD rt_mask, *cur_mask; - - if (isStateDirty(context, STATE_FRAMEBUFFER)) return; - - cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; - rt_mask = find_draw_buffers_mask(context, state); -+#else /* STAGING_CSMT */ -+ const struct wined3d_device *device = context->swapchain->device; -+ DWORD rt_mask, *cur_mask; +- wined3d_cs_mt_require_space, +- wined3d_cs_mt_require_space_prio, ++ struct wined3d_cs_set_viewport *op; + -+ if (isStateDirty(context, STATE_FRAMEBUFFER)) return; ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_VIEWPORT; ++ op->viewport = viewport; + -+ cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; -+ rt_mask = find_draw_buffers_mask(context, device); -+#endif /* STAGING_CSMT */ - if (rt_mask != *cur_mask) - { - context_apply_draw_buffers(context, rt_mask); -@@ -2951,7 +3023,11 @@ - { - if (state->vertex_declaration->half_float_conv_needed && !stream_info->all_vbo) - { -+#if defined(STAGING_CSMT) - TRACE("Using draw_strided_slow with vertex shaders for FLOAT16 conversion.\n"); -+#else /* STAGING_CSMT */ -+ TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion.\n"); -+#endif /* STAGING_CSMT */ - context->use_immediate_mode_draw = TRUE; - } - else -@@ -3126,11 +3202,19 @@ - } - - /* Context activation is done by the caller. */ -+#if defined(STAGING_CSMT) - BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, - const struct wined3d_state *state) - { - const struct StateEntry *state_table = context->state_table; - const struct wined3d_fb_state *fb = &state->fb; -+#else /* STAGING_CSMT */ -+BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) ++ cs->ops->submit(cs); ++} ++ ++static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) +{ -+ const struct wined3d_state *state = &device->state; -+ const struct StateEntry *state_table = context->state_table; -+ const struct wined3d_fb_state *fb = state->fb; -+#endif /* STAGING_CSMT */ - unsigned int i; - WORD map; - -@@ -3163,12 +3247,17 @@ - for (i = 0, map = context->stream_info.use_map; map; map >>= 1, ++i) - { - if (map & 1) -+#if defined(STAGING_CSMT) - buffer_internal_preload(state->streams[context->stream_info.elements[i].stream_idx].buffer, - context, state); - } - /* PreLoad may kick buffers out of vram. */ - if (isStateDirty(context, STATE_STREAMSRC)) - context_update_stream_info(context, state); -+#else /* STAGING_CSMT */ -+ buffer_mark_used(state->streams[context->stream_info.elements[i].stream_idx].buffer); ++ const struct wined3d_cs_set_scissor_rect *op = data; ++ ++ cs->state.scissor_rect = *op->rect; ++ device_invalidate_state(cs->device, STATE_SCISSORRECT); ++} ++ ++void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) ++{ ++ struct wined3d_cs_set_scissor_rect *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT; ++ op->rect = rect; ++ ++ cs->ops->submit(cs); ++} ++ ++static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_rendertarget_view *op = data; ++ ++ cs->state.fb->render_targets[op->view_idx] = op->view; ++ device_invalidate_state(cs->device, STATE_FRAMEBUFFER); ++} ++ ++void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx, ++ struct wined3d_rendertarget_view *view) ++{ ++ struct wined3d_cs_set_rendertarget_view *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW; ++ op->view_idx = view_idx; ++ op->view = view; ++ ++ cs->ops->submit(cs); ++} ++ ++static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_depth_stencil_view *op = data; ++ struct wined3d_device *device = cs->device; ++ struct wined3d_rendertarget_view *prev; ++ ++ if ((prev = cs->state.fb->depth_stencil)) ++ { ++ struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev); ++ ++ if (prev_surface && (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL ++ || prev_surface->flags & SFLAG_DISCARD)) ++ { ++ surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height); ++ if (prev_surface == device->onscreen_depth_stencil) ++ { ++ wined3d_texture_decref(device->onscreen_depth_stencil->container); ++ device->onscreen_depth_stencil = NULL; ++ } + } -+#endif /* STAGING_CSMT */ - } - if (state->index_buffer) - { -@@ -3263,7 +3352,11 @@ - if (texture->texture_srgb.name) - wined3d_texture_load(texture, context, TRUE); - wined3d_texture_load(texture, context, FALSE); -+#if defined(STAGING_CSMT) - wined3d_resource_invalidate_location(&context->current_rt->resource, WINED3D_LOCATION_DRAWABLE); -+#else /* STAGING_CSMT */ -+ surface_invalidate_location(context->current_rt, WINED3D_LOCATION_DRAWABLE); -+#endif /* STAGING_CSMT */ - } - } - -diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c ---- a/dlls/wined3d/stateblock.c -+++ b/dlls/wined3d/stateblock.c -@@ -464,7 +464,9 @@ - struct wined3d_texture *texture; - struct wined3d_buffer *buffer; - struct wined3d_shader *shader; -+#if defined(STAGING_CSMT) - struct wined3d_rendertarget_view *view; -+#endif /* STAGING_CSMT */ - unsigned int i, j; - - if ((decl = state->vertex_declaration)) -@@ -541,6 +543,7 @@ - } - } - } -+#if defined(STAGING_CSMT) - - if (state->fb.depth_stencil) - { -@@ -566,6 +569,7 @@ - } - } - } -+#endif /* STAGING_CSMT */ - } - - void state_cleanup(struct wined3d_state *state) -@@ -593,7 +597,9 @@ - - HeapFree(GetProcessHeap(), 0, state->vs_consts_f); - HeapFree(GetProcessHeap(), 0, state->ps_consts_f); -+#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, state->fb.render_targets); -+#endif /* STAGING_CSMT */ - } - - ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock) -@@ -1075,8 +1081,13 @@ - gl_primitive_type = stateblock->state.gl_primitive_type; - prev = device->update_state->gl_primitive_type; - device->update_state->gl_primitive_type = gl_primitive_type; -+#if defined(STAGING_CSMT) - if (gl_primitive_type != prev) - wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type); -+#else /* STAGING_CSMT */ -+ if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS)) -+ device_invalidate_state(device, STATE_POINT_ENABLE); -+#endif /* STAGING_CSMT */ - } - - if (stateblock->changed.indices) -@@ -1334,6 +1345,7 @@ - state->sampler_states[i][WINED3D_SAMP_ELEMENT_INDEX] = 0; - /* TODO: Vertex offset in the presampled displacement map. */ - state->sampler_states[i][WINED3D_SAMP_DMAP_OFFSET] = 0; -+#if defined(STAGING_CSMT) - state->textures[i] = NULL; - } - -@@ -1351,6 +1363,19 @@ - unsigned int i; - - state->flags = flags; -+#else /* STAGING_CSMT */ + } ++ ++ cs->fb.depth_stencil = op->view; ++ ++ if (!prev != !op->view) ++ { ++ /* Swapping NULL / non NULL depth stencil affects the depth and tests */ ++ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE)); ++ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE)); ++ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK)); ++ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); ++ } ++ else if (prev && (prev->format_flags & WINED3DFMT_FLAG_FLOAT) ++ != (op->view->format_flags & WINED3DFMT_FLAG_FLOAT)) ++ { ++ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); ++ } ++ ++ device_invalidate_state(device, STATE_FRAMEBUFFER); +} + -+HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, -+ const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, -+ DWORD flags) ++void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) +{ -+ unsigned int i; ++ struct wined3d_cs_set_depth_stencil_view *op; + -+ state->flags = flags; -+ state->fb = fb; -+#endif /* STAGING_CSMT */ - - for (i = 0; i < LIGHTMAP_SIZE; i++) - { -@@ -1368,6 +1393,7 @@ - return E_OUTOFMEMORY; - } - -+#if defined(STAGING_CSMT) - if (!(state->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(*state->fb.render_targets) * gl_info->limits.buffers))) - { -@@ -1377,6 +1403,7 @@ - } - state->fb.rt_size = gl_info->limits.buffers; - -+#endif /* STAGING_CSMT */ - if (flags & WINED3D_STATE_INIT_DEFAULT) - state_init_default(state, gl_info); - -@@ -1387,6 +1414,7 @@ - struct wined3d_device *device, enum wined3d_stateblock_type type) - { - HRESULT hr; -+#if defined(STAGING_CSMT) - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; - -@@ -1394,6 +1422,14 @@ - stateblock->device = device; - - if (FAILED(hr = state_init(&stateblock->state, gl_info, d3d_info, 0))) -+#else /* STAGING_CSMT */ -+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW; ++ op->view = view; + -+ stateblock->ref = 1; -+ stateblock->device = device; ++ cs->ops->submit(cs); ++} + -+ if (FAILED(hr = state_init(&stateblock->state, NULL, &device->adapter->gl_info, d3d_info, 0))) -+#endif /* STAGING_CSMT */ - return hr; - - if (FAILED(hr = stateblock_allocate_shader_constants(stateblock))) -diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c ---- a/dlls/d3d9/tests/visual.c -+++ b/dlls/d3d9/tests/visual.c -@@ -1339,7 +1339,11 @@ - * result on Wine. - * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0}, - * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */ -+#if defined(STAGING_CSMT) - {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS, 0}, -+#else /* STAGING_CSMT */ -+ {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS | TODO_FILL_RETURN, 0}, -+#endif /* STAGING_CSMT */ - /* Vendor-specific formats like ATI2N are a non-issue here since they're not - * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET - * when created as texture. */ -@@ -17630,7 +17634,11 @@ - fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE); - add_dirty_rect_test_draw(device); - color = getPixelColor(device, 320, 240); -+#if defined(STAGING_CSMT) - todo_wine ok(color_match(color, 0x00ff0000, 1), -+#else /* STAGING_CSMT */ -+ ok(color_match(color, 0x00ff0000, 1), -+#endif /* STAGING_CSMT */ - "Expected color 0x00ff0000, got 0x%08x.\n", color); - hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); - ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -1,3 +1,4 @@ -+#if defined(STAGING_CSMT) - /* - * Direct3D wine internal private include file - * -@@ -21,6 +22,31 @@ - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ -+#else /* STAGING_CSMT */ -+/* -+ * Direct3D wine internal private include file -+ * -+ * Copyright 2002-2003 The wine-d3d team -+ * Copyright 2002-2003 Raphael Junqueira -+ * Copyright 2002-2003, 2004 Jason Edmeades -+ * Copyright 2005 Oliver Stieber -+ * Copyright 2006-2011, 2013 Stefan Dösinger for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+#endif /* STAGING_CSMT */ - - #ifndef __WINE_WINED3D_PRIVATE_H - #define __WINE_WINED3D_PRIVATE_H -@@ -31,7 +57,9 @@ - #define WINE_GLAPI - #endif - -+#if defined(STAGING_CSMT) - #include -+#endif /* STAGING_CSMT */ - #include - #include - #include -@@ -284,8 +312,10 @@ - unsigned int max_sm_gs; - unsigned int max_sm_ps; - BOOL no_3d; -+#if defined(STAGING_CSMT) - BOOL cs_multithreaded; - BOOL ignore_rt_map; -+#endif /* STAGING_CSMT */ - }; - - extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN; -@@ -1026,9 +1056,14 @@ - WORD use_map; /* MAX_ATTRIBS, 16 */ - }; - -+#if defined(STAGING_CSMT) - void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, - UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count, - BOOL indexed) DECLSPEC_HIDDEN; -+#else /* STAGING_CSMT */ -+void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count, -+ UINT start_instance, UINT instance_count, BOOL indexed) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; - - #define eps 1e-8f -@@ -1116,8 +1151,10 @@ - struct list entry; - GLuint id; - struct wined3d_context *context; -+#if defined(STAGING_CSMT) - DWORD samples; - BOOL started; -+#endif /* STAGING_CSMT */ - }; - - union wined3d_gl_query_object -@@ -1153,6 +1190,7 @@ - struct list entry; - GLuint id; - struct wined3d_context *context; -+#if defined(STAGING_CSMT) - UINT64 timestamp; - }; - -@@ -1188,6 +1226,12 @@ - for (i = 0; i < min(dst->rt_size, src->rt_size); i++) - dst->render_targets[i] = src->render_targets[i]; - } -+#else /* STAGING_CSMT */ -+}; ++static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_vertex_declaration *op = data; + -+void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; -+void context_free_timestamp_query(struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - - struct wined3d_context - { -@@ -1203,7 +1247,9 @@ - DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */ - DWORD numDirtyEntries; - DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ -+#if defined(STAGING_CSMT) - struct wined3d_fb_state current_fb; -+#endif /* STAGING_CSMT */ - - struct wined3d_swapchain *swapchain; - struct wined3d_surface *current_rt; -@@ -1300,8 +1346,17 @@ - GLfloat fog_coord_value; - GLfloat color[4], fogstart, fogend, fogcolor[4]; - GLuint dummy_arbfp_prog; -+#if defined(STAGING_CSMT) - - GLenum offscreenBuffer; -+#else /* STAGING_CSMT */ -+}; ++ cs->state.vertex_declaration = op->declaration; ++ device_invalidate_state(cs->device, STATE_VDECL); ++} + -+struct wined3d_fb_state ++void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration) +{ -+ struct wined3d_rendertarget_view **render_targets; -+ struct wined3d_rendertarget_view *depth_stencil; -+#endif /* STAGING_CSMT */ - }; - - typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id); -@@ -1444,8 +1499,12 @@ - void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN; - BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_device *device, - UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN; -+#if defined(STAGING_CSMT) - BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, - const struct wined3d_state *state) DECLSPEC_HIDDEN; -+#else /* STAGING_CSMT */ -+BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, - struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN; - void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, -@@ -2028,7 +2087,11 @@ - struct wined3d_state - { - DWORD flags; -+#if defined(STAGING_CSMT) - struct wined3d_fb_state fb; -+#else /* STAGING_CSMT */ -+ const struct wined3d_fb_state *fb; -+#endif /* STAGING_CSMT */ - - struct wined3d_vertex_declaration *vertex_declaration; - struct wined3d_stream_output stream_output[MAX_STREAM_OUT]; -@@ -2073,6 +2136,7 @@ - DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; - }; - -+#if defined(STAGING_CSMT) - struct wined3d_gl_bo - { - GLuint name; -@@ -2081,6 +2145,7 @@ - UINT size; - }; - -+#endif /* STAGING_CSMT */ - #define WINED3D_UNMAPPED_STAGE ~0U - - /* Multithreaded flag. Removed from the public header to signal that -@@ -2136,11 +2201,23 @@ - struct wined3d_rendertarget_view *back_buffer_view; - struct wined3d_swapchain **swapchains; - UINT swapchain_count; -+#if defined(STAGING_CSMT) - struct wined3d_rendertarget_view *auto_depth_stencil_view; - - struct list resources; /* a linked list to track resources created by the device */ - struct list shaders; /* a linked list to track shaders (pixel and vertex) */ - struct wine_rb_tree samplers; -+#else /* STAGING_CSMT */ ++ struct wined3d_cs_set_vertex_declaration *op; + -+ struct list resources; /* a linked list to track resources created by the device */ -+ struct list shaders; /* a linked list to track shaders (pixel and vertex) */ -+ struct wine_rb_tree samplers; ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION; ++ op->declaration = declaration; + -+ /* Render Target Support */ -+ struct wined3d_fb_state fb; -+ struct wined3d_surface *onscreen_depth_stencil; -+ struct wined3d_rendertarget_view *auto_depth_stencil_view; -+#endif /* STAGING_CSMT */ - - /* For rendering to a texture using glCopyTexImage */ - GLuint depth_blt_texture; -@@ -2151,6 +2228,9 @@ - UINT xScreenSpace; - UINT yScreenSpace; - UINT cursorWidth, cursorHeight; -+#if !defined(STAGING_CSMT) -+ struct wined3d_texture *cursor_texture; -+#endif /* STAGING_CSMT */ - HCURSOR hardwareCursor; - - /* The Wine logo texture */ -@@ -2182,6 +2262,7 @@ - UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN; - void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+#if defined(STAGING_CSMT) - void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; - void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) DECLSPEC_HIDDEN; - void device_exec_update_texture(struct wined3d_context *context, struct wined3d_texture *src_texture, -@@ -2193,6 +2274,11 @@ - void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; - void device_delete_opengl_contexts_cs(struct wined3d_device *device, - struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -+#else /* STAGING_CSMT */ -+void device_switch_onscreen_ds(struct wined3d_device *device, struct wined3d_context *context, -+ struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; -+void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - - static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) - { -@@ -2212,9 +2298,11 @@ - HRESULT (*resource_sub_resource_map)(struct wined3d_resource *resource, unsigned int sub_resource_idx, - struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); - HRESULT (*resource_sub_resource_unmap)(struct wined3d_resource *resource, unsigned int sub_resource_idx); -+#if defined(STAGING_CSMT) - void (*resource_location_invalidated)(struct wined3d_resource *resource, DWORD location); - void (*resource_load_location)(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location); -+#endif /* STAGING_CSMT */ - }; - - struct wined3d_resource -@@ -2239,6 +2327,7 @@ - UINT depth; - UINT size; - DWORD priority; -+#if defined(STAGING_CSMT) - void *heap_memory, *map_heap_memory, *user_memory, *bitmap_data; - UINT custom_row_pitch, custom_slice_pitch; - struct wined3d_gl_bo *buffer, *map_buffer; -@@ -2246,6 +2335,10 @@ - DWORD locations; - LONG access_fence; - BOOL unmap_dirtify; -+#else /* STAGING_CSMT */ -+ void *heap_memory; -+ struct list resource_list_entry; -+#endif /* STAGING_CSMT */ - - void *parent; - const struct wined3d_parent_ops *parent_ops; -@@ -2270,6 +2363,7 @@ - void *parent, const struct wined3d_parent_ops *parent_ops, - const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN; - void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+#if defined(STAGING_CSMT) - DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; - BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; - void wined3d_resource_changed(struct wined3d_resource *resource, -@@ -2318,6 +2412,15 @@ - { - while(InterlockedCompareExchange(&resource->access_fence, 0, 0)); - } -+#else /* STAGING_CSMT */ -+BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; -+GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; -+BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; -+void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - - /* Tests show that the start address of resources is 32 byte aligned */ - #define RESOURCE_ALIGNMENT 16 -@@ -2402,7 +2505,9 @@ - - void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, - const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; -+#if defined(STAGING_CSMT) - void wined3d_texture_cleanup_cs(struct wined3d_texture *texture) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - void wined3d_texture_bind(struct wined3d_texture *texture, - struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; - void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, -@@ -2436,9 +2541,16 @@ - struct wined3d_resource resource; - struct wined3d_texture *container; - -+#if defined(STAGING_CSMT) - DWORD flags; - GLint texture_level; - DWORD download_count; -+#else /* STAGING_CSMT */ -+ DWORD flags, locations; -+ GLint texture_level; -+ DWORD download_count; -+ GLuint pbo; -+#endif /* STAGING_CSMT */ - }; - - static inline struct wined3d_volume *volume_from_resource(struct wined3d_resource *resource) -@@ -2446,6 +2558,7 @@ - return CONTAINING_RECORD(resource, struct wined3d_volume, resource); - } - -+#if defined(STAGING_CSMT) - HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, - unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN; - void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN; -@@ -2461,6 +2574,27 @@ - struct wined3d_surface_dib - { - HBITMAP DIBsection; -+#else /* STAGING_CSMT */ -+BOOL volume_prepare_system_memory(struct wined3d_volume *volume) DECLSPEC_HIDDEN; -+HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, -+ unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN; -+void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN; -+void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch) DECLSPEC_HIDDEN; -+void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, -+ BOOL srgb_mode) DECLSPEC_HIDDEN; -+void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; -+HRESULT wined3d_volume_map(struct wined3d_volume *volume, -+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; -+void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; -+HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) DECLSPEC_HIDDEN; -+void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, -+ const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; ++ cs->ops->submit(cs); ++} + -+struct wined3d_surface_dib ++static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) +{ -+ HBITMAP DIBsection; -+ void *bitmap_data; -+#endif /* STAGING_CSMT */ - UINT bitmap_size; - }; - -@@ -2486,7 +2620,11 @@ - struct wined3d_surface_ops - { - HRESULT (*surface_private_setup)(struct wined3d_surface *surface); -+#if defined(STAGING_CSMT) - void (*surface_frontbuffer_updated)(struct wined3d_surface *surface); -+#else /* STAGING_CSMT */ -+ void (*surface_unmap)(struct wined3d_surface *surface); -+#endif /* STAGING_CSMT */ - }; - - struct wined3d_surface -@@ -2494,12 +2632,26 @@ - struct wined3d_resource resource; - const struct wined3d_surface_ops *surface_ops; - struct wined3d_texture *container; -+#if defined(STAGING_CSMT) - - DWORD flags; - - UINT pow2Width; - UINT pow2Height; - -+#else /* STAGING_CSMT */ -+ void *user_memory; -+ DWORD locations; ++ const struct wined3d_cs_set_stream_source *op = data; ++ struct wined3d_stream_state *stream; ++ struct wined3d_buffer *prev; + -+ DWORD flags; ++ stream = &cs->state.streams[op->stream_idx]; ++ prev = stream->buffer; ++ stream->buffer = op->buffer; ++ stream->offset = op->offset; ++ stream->stride = op->stride; + -+ UINT pitch; -+ UINT pow2Width; -+ UINT pow2Height; ++ if (op->buffer) ++ InterlockedIncrement(&op->buffer->resource.bind_count); ++ if (prev) ++ InterlockedDecrement(&prev->resource.bind_count); + -+ /* PBO */ -+ GLuint pbo; -+#endif /* STAGING_CSMT */ - GLuint rb_multisample; - GLuint rb_resolved; - GLenum texture_target; -@@ -2543,11 +2695,22 @@ - GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) DECLSPEC_HIDDEN; - void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context, - unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN; -+#if defined(STAGING_CSMT) - void surface_load(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; - void surface_load_ds_location(struct wined3d_surface *surface, - struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; - void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, - struct wined3d_context *context) DECLSPEC_HIDDEN; -+#else /* STAGING_CSMT */ -+void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN; -+void surface_load(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; -+void surface_load_ds_location(struct wined3d_surface *surface, -+ struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -+void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, -+ struct wined3d_context *context) DECLSPEC_HIDDEN; -+HRESULT surface_load_location(struct wined3d_surface *surface, -+ struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; - void wined3d_surface_prepare(struct wined3d_surface *surface, struct wined3d_context *context, - DWORD location) DECLSPEC_HIDDEN; -@@ -2559,6 +2722,7 @@ - const struct wined3d_gl_info *gl_info, void *mem, unsigned int pitch) DECLSPEC_HIDDEN; - HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, - struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN; -+#if defined(STAGING_CSMT) - HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, - GLenum target, unsigned int level, unsigned int layer, DWORD flags, - struct wined3d_surface **surface) DECLSPEC_HIDDEN; -@@ -2573,6 +2737,17 @@ - void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; - void wined3d_surface_getdc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; - void wined3d_surface_releasedc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -+#else /* STAGING_CSMT */ -+void surface_validate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN; -+HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, -+ GLenum target, unsigned int level, unsigned int layer, DWORD flags, -+ struct wined3d_surface **surface) DECLSPEC_HIDDEN; -+void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -+void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN; -+void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, -+ const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, -+ BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - - void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, - const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; -@@ -2594,8 +2769,10 @@ - GLuint name; - }; - -+#if defined(STAGING_CSMT) - void wined3d_sampler_destroy(struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; - -+#endif /* STAGING_CSMT */ - struct wined3d_vertex_declaration_element - { - const struct wined3d_format *format; -@@ -2624,8 +2801,10 @@ - BOOL half_float_conv_needed; - }; - -+#if defined(STAGING_CSMT) - void wined3d_vertex_declaration_destroy(struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; - -+#endif /* STAGING_CSMT */ - struct wined3d_saved_states - { - DWORD transform[(HIGHEST_TRANSFORMSTATE >> 5) + 1]; -@@ -2693,6 +2872,7 @@ - void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN; - - void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; -+#if defined(STAGING_CSMT) - HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl_info, - const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; - void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; -@@ -2743,6 +2923,32 @@ - void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN; - void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, struct wined3d_context *context, - struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; -+#else /* STAGING_CSMT */ -+HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, -+ const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, -+ DWORD flags) DECLSPEC_HIDDEN; -+void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; ++ device_invalidate_state(cs->device, STATE_STREAMSRC); ++} + -+struct wined3d_cs_ops ++void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, ++ struct wined3d_buffer *buffer, UINT offset, UINT stride) +{ -+ void *(*require_space)(struct wined3d_cs *cs, size_t size); -+ void (*submit)(struct wined3d_cs *cs); -+}; ++ struct wined3d_cs_set_stream_source *op; + -+struct wined3d_cs ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE; ++ op->stream_idx = stream_idx; ++ op->buffer = buffer; ++ op->offset = offset; ++ op->stride = stride; ++ ++ cs->ops->submit(cs); ++} ++ ++static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) +{ -+ const struct wined3d_cs_ops *ops; -+ struct wined3d_device *device; -+ struct wined3d_fb_state fb; -+ struct wined3d_state state; ++ const struct wined3d_cs_set_stream_source_freq *op = data; ++ struct wined3d_stream_state *stream; + -+ size_t data_size; -+ void *data; -+}; ++ stream = &cs->state.streams[op->stream_idx]; ++ stream->frequency = op->frequency; ++ stream->flags = op->flags; + -+struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; -+void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - - void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, - DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; -@@ -2792,6 +2998,7 @@ - void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, - struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; -+#if defined(STAGING_CSMT) - void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, - UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; - void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, -@@ -2855,6 +3062,7 @@ - void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, - unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, - unsigned int depth_pitch) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - - /* Direct3D terminology with little modifications. We do not have an issued state - * because only the driver knows about it, but we have a created state because d3d -@@ -2869,8 +3077,12 @@ - struct wined3d_query_ops - { - HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags); -+#if defined(STAGING_CSMT) - BOOL (*query_poll)(struct wined3d_query *query); - BOOL (*query_issue)(struct wined3d_query *query, DWORD flags); -+#else /* STAGING_CSMT */ -+ HRESULT (*query_issue)(struct wined3d_query *query, DWORD flags); -+#endif /* STAGING_CSMT */ - }; - - struct wined3d_query -@@ -2884,12 +3096,16 @@ - enum wined3d_query_type type; - DWORD data_size; - void *extendedData; -+#if defined(STAGING_CSMT) - - LONG counter_main, counter_retrieved; - struct list poll_list_entry; - }; - - void wined3d_query_destroy(struct wined3d_query *query) DECLSPEC_HIDDEN; -+#else /* STAGING_CSMT */ -+}; -+#endif /* STAGING_CSMT */ - - /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other - * fixed function semantics as D3DCOLOR or FLOAT16 */ -@@ -2916,7 +3132,9 @@ - GLenum buffer_object_usage; - GLenum buffer_type_hint; - DWORD flags; -+#if defined(STAGING_CSMT) - BOOL ignore_discard; -+#endif /* STAGING_CSMT */ - void *map_ptr; - - struct wined3d_map_range *maps; -@@ -2941,11 +3159,15 @@ - BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *context) DECLSPEC_HIDDEN; - void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, - const struct wined3d_state *state) DECLSPEC_HIDDEN; -+#if defined(STAGING_CSMT) - void buffer_invalidate_bo_range(struct wined3d_buffer *This, UINT offset, UINT size) DECLSPEC_HIDDEN; - void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) DECLSPEC_HIDDEN; - void buffer_create_buffer_object(struct wined3d_buffer *This, - struct wined3d_context *context) DECLSPEC_HIDDEN; - void wined3d_buffer_cleanup_cs(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; -+#else /* STAGING_CSMT */ -+void buffer_mark_used(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - - struct wined3d_rendertarget_view - { -@@ -2984,8 +3206,10 @@ - return surface_from_resource(resource); - } - -+#if defined(STAGING_CSMT) - void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; - -+#endif /* STAGING_CSMT */ - struct wined3d_shader_resource_view - { - LONG refcount; -@@ -2998,8 +3222,12 @@ - struct wined3d_swapchain_ops - { - void (*swapchain_present)(struct wined3d_swapchain *swapchain, const RECT *src_rect, -+#if defined(STAGING_CSMT) - const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags, - struct wined3d_surface *depth_stencil); -+#else /* STAGING_CSMT */ -+ const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags); -+#endif /* STAGING_CSMT */ - }; - - struct wined3d_swapchain -@@ -3038,8 +3266,10 @@ - void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; - HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; - void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -+#if defined(STAGING_CSMT) - HRESULT swapchain_create_context_cs(struct wined3d_device *device, - struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - - /***************************************************************************** - * Utility function prototypes -@@ -3242,7 +3472,9 @@ - void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, - const struct wined3d_shader_reg_maps *reg_maps, const DWORD *byte_code, void *backend_ctx) DECLSPEC_HIDDEN; - BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage) DECLSPEC_HIDDEN; -+#if defined(STAGING_CSMT) - void shader_cleanup(struct wined3d_shader *shader) DECLSPEC_HIDDEN; -+#endif /* STAGING_CSMT */ - - static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg) - { -diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c ---- a/dlls/wined3d/vertexdeclaration.c -+++ b/dlls/wined3d/vertexdeclaration.c -@@ -50,12 +50,14 @@ - return refcount; - } - -+#if defined(STAGING_CSMT) - void wined3d_vertex_declaration_destroy(struct wined3d_vertex_declaration *declaration) - { - HeapFree(GetProcessHeap(), 0, declaration->elements); - HeapFree(GetProcessHeap(), 0, declaration); - } - -+#endif /* STAGING_CSMT */ - ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration *declaration) - { - ULONG refcount = InterlockedDecrement(&declaration->ref); -@@ -64,9 +66,15 @@ - - if (!refcount) - { -+#if defined(STAGING_CSMT) - const struct wined3d_device *device = declaration->device; - declaration->parent_ops->wined3d_object_destroyed(declaration->parent); - wined3d_cs_emit_vertex_declaration_destroy(device->cs, declaration); -+#else /* STAGING_CSMT */ -+ HeapFree(GetProcessHeap(), 0, declaration->elements); -+ declaration->parent_ops->wined3d_object_destroyed(declaration->parent); -+ HeapFree(GetProcessHeap(), 0, declaration); -+#endif /* STAGING_CSMT */ - } - - return refcount; -diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c ---- a/dlls/winex11.drv/opengl.c -+++ b/dlls/winex11.drv/opengl.c -@@ -1980,7 +1980,9 @@ - escape.code = X11DRV_FLUSH_GL_DRAWABLE; - escape.gl_drawable = 0; - -+#if defined(STAGING_CSMT) - ERR("glFinish\n"); -+#endif /* STAGING_CSMT */ - if ((gl = get_gl_drawable( WindowFromDC( ctx->hdc ), 0 ))) - { - switch (gl->type) -@@ -2006,7 +2008,9 @@ - escape.code = X11DRV_FLUSH_GL_DRAWABLE; - escape.gl_drawable = 0; - -+#if defined(STAGING_CSMT) - ERR("glFlush\n"); -+#endif /* STAGING_CSMT */ - if ((gl = get_gl_drawable( WindowFromDC( ctx->hdc ), 0 ))) - { - switch (gl->type) -diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c ---- a/dlls/wined3d/query.c -+++ b/dlls/wined3d/query.c -@@ -233,6 +233,7 @@ - return refcount; - } - -+#if defined(STAGING_CSMT) - void wined3d_query_destroy(struct wined3d_query *query) - { - /* Queries are specific to the GL context that created them. Not -@@ -263,6 +264,7 @@ - HeapFree(GetProcessHeap(), 0, query); - } - -+#endif /* STAGING_CSMT */ - ULONG CDECL wined3d_query_decref(struct wined3d_query *query) - { - ULONG refcount = InterlockedDecrement(&query->ref); -@@ -270,7 +272,38 @@ - TRACE("%p decreasing refcount to %u.\n", query, refcount); - - if (!refcount) -+#if defined(STAGING_CSMT) - wined3d_cs_emit_query_destroy(query->device->cs, query); -+#else /* STAGING_CSMT */ -+ { -+ /* Queries are specific to the GL context that created them. Not -+ * deleting the query will obviously leak it, but that's still better -+ * than potentially deleting a different query with the same id in this -+ * context, and (still) leaking the actual query. */ -+ if (query->type == WINED3D_QUERY_TYPE_EVENT) -+ { -+ struct wined3d_event_query *event_query = query->extendedData; -+ if (event_query) wined3d_event_query_destroy(event_query); -+ } -+ else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION) -+ { -+ struct wined3d_occlusion_query *oq = query->extendedData; ++ device_invalidate_state(cs->device, STATE_STREAMSRC); ++} + -+ if (oq->context) context_free_occlusion_query(oq); -+ HeapFree(GetProcessHeap(), 0, query->extendedData); -+ } -+ else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP) -+ { -+ struct wined3d_timestamp_query *tq = query->extendedData; ++void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags) ++{ ++ struct wined3d_cs_set_stream_source_freq *op; + -+ if (tq->context) -+ context_free_timestamp_query(tq); -+ HeapFree(GetProcessHeap(), 0, query->extendedData); -+ } ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ; ++ op->stream_idx = stream_idx; ++ op->frequency = frequency; ++ op->flags = flags; + -+ HeapFree(GetProcessHeap(), 0, query); -+ } -+#endif /* STAGING_CSMT */ - - return refcount; - } -@@ -295,6 +328,7 @@ - { - TRACE("query %p, flags %#x.\n", query, flags); - -+#if defined(STAGING_CSMT) - if (flags & WINED3DISSUE_END) - query->counter_main++; - -@@ -306,6 +340,9 @@ - query->state = QUERY_SIGNALLED; - - return WINED3D_OK; -+#else /* STAGING_CSMT */ -+ return query->query_ops->query_issue(query, flags); -+#endif /* STAGING_CSMT */ - } - - static void fill_query_data(void *out, unsigned int out_size, const void *result, unsigned int result_size) -@@ -316,10 +353,25 @@ - static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, - void *data, DWORD size, DWORD flags) - { -+#if defined(STAGING_CSMT) - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - struct wined3d_occlusion_query *oq = query->extendedData; - GLuint samples; -+#else /* STAGING_CSMT */ -+ struct wined3d_occlusion_query *oq = query->extendedData; -+ struct wined3d_device *device = query->device; -+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -+ struct wined3d_context *context; -+ GLuint available; -+ GLuint samples; -+ HRESULT res; ++ cs->ops->submit(cs); ++} + -+ TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); ++static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_stream_output *op = data; ++ struct wined3d_stream_output *stream; ++ struct wined3d_buffer *prev; + -+ if (!oq->context) -+ query->state = QUERY_CREATED; -+#endif /* STAGING_CSMT */ - - if (query->state == QUERY_CREATED) - { -@@ -330,8 +382,10 @@ - return S_OK; - } - -+#if defined(STAGING_CSMT) - TRACE("(%p) : type D3DQUERY_OCCLUSION, data %p, size %#x, flags %#x.\n", query, data, size, flags); - -+#endif /* STAGING_CSMT */ - if (query->state == QUERY_BUILDING) - { - /* Msdn says this returns an error, but our tests show that S_FALSE is returned */ -@@ -347,6 +401,7 @@ - return S_OK; - } - -+#if defined(STAGING_CSMT) - if (!wined3d_settings.cs_multithreaded) - { - if (!query->query_ops->query_poll(query)) -@@ -378,6 +433,14 @@ - FIXME("%p Wrong thread, returning 1.\n", query); - oq->samples = 1; - return TRUE; -+#else /* STAGING_CSMT */ -+ if (oq->context->tid != GetCurrentThreadId()) -+ { -+ FIXME("%p Wrong thread, returning 1.\n", query); -+ samples = 1; -+ fill_query_data(data, size, &samples, sizeof(samples)); -+ return S_OK; -+#endif /* STAGING_CSMT */ - } - - context = context_acquire(query->device, oq->context->current_rt); -@@ -388,6 +451,7 @@ - - if (available) - { -+#if defined(STAGING_CSMT) - GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples)); - checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); - TRACE("Returning %d samples.\n", samples); -@@ -459,6 +523,69 @@ - - if (data) - fill_query_data(data, dwSize, &ret, sizeof(ret)); -+#else /* STAGING_CSMT */ -+ if (size) -+ { -+ GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples)); -+ checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); -+ TRACE("Returning %d samples.\n", samples); -+ fill_query_data(data, size, &samples, sizeof(samples)); -+ } -+ res = S_OK; -+ } -+ else -+ { -+ res = S_FALSE; -+ } -+ -+ context_release(context); ++ stream = &cs->state.stream_output[op->stream_idx]; ++ prev = stream->buffer; ++ stream->buffer = op->buffer; ++ stream->offset = op->offset; + -+ return res; ++ if (op->buffer) ++ InterlockedIncrement(&op->buffer->resource.bind_count); ++ if (prev) ++ InterlockedDecrement(&prev->resource.bind_count); +} + -+static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query, -+ void *data, DWORD size, DWORD flags) ++void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, ++ struct wined3d_buffer *buffer, UINT offset) +{ -+ struct wined3d_event_query *event_query = query->extendedData; -+ BOOL signaled; -+ enum wined3d_event_query_result ret; ++ struct wined3d_cs_set_stream_output *op; + -+ TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT; ++ op->stream_idx = stream_idx; ++ op->buffer = buffer; ++ op->offset = offset; + -+ if (!data || !size) return S_OK; -+ if (!event_query) -+ { -+ WARN("Event query not supported by GL, reporting GPU idle.\n"); -+ signaled = TRUE; -+ fill_query_data(data, size, &signaled, sizeof(signaled)); -+ return S_OK; -+ } ++ cs->ops->submit(cs); ++} + -+ ret = wined3d_event_query_test(event_query, query->device); -+ switch(ret) -+ { -+ case WINED3D_EVENT_QUERY_OK: -+ case WINED3D_EVENT_QUERY_NOT_STARTED: -+ signaled = TRUE; -+ fill_query_data(data, size, &signaled, sizeof(signaled)); -+ break; ++static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_index_buffer *op = data; ++ struct wined3d_buffer *prev; + -+ case WINED3D_EVENT_QUERY_WAITING: -+ signaled = FALSE; -+ fill_query_data(data, size, &signaled, sizeof(signaled)); -+ break; ++ prev = cs->state.index_buffer; ++ cs->state.index_buffer = op->buffer; ++ cs->state.index_format = op->format_id; + -+ case WINED3D_EVENT_QUERY_WRONG_THREAD: -+ FIXME("(%p) Wrong thread, reporting GPU idle.\n", query); -+ signaled = TRUE; -+ fill_query_data(data, size, &signaled, sizeof(signaled)); -+ break; ++ if (op->buffer) ++ InterlockedIncrement(&op->buffer->resource.bind_count); ++ if (prev) ++ InterlockedDecrement(&prev->resource.bind_count); + -+ case WINED3D_EVENT_QUERY_ERROR: -+ ERR("The GL event query failed, returning D3DERR_INVALIDCALL\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+#endif /* STAGING_CSMT */ - - return S_OK; - } -@@ -477,7 +604,11 @@ - return query->type; - } - -+#if defined(STAGING_CSMT) - static BOOL wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) -+#else /* STAGING_CSMT */ -+static HRESULT wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) -+#endif /* STAGING_CSMT */ - { - TRACE("query %p, flags %#x.\n", query, flags); - -@@ -487,6 +618,7 @@ - struct wined3d_event_query *event_query = query->extendedData; - - /* Faked event query support */ -+#if defined(STAGING_CSMT) - if (!event_query) return FALSE; - - wined3d_event_query_issue(event_query, query->device); -@@ -505,6 +637,30 @@ - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - BOOL poll = FALSE; -+#else /* STAGING_CSMT */ -+ if (!event_query) return WINED3D_OK; ++ device_invalidate_state(cs->device, STATE_INDEXBUFFER); ++} + -+ wined3d_event_query_issue(event_query, query->device); -+ } -+ else if (flags & WINED3DISSUE_BEGIN) -+ { -+ /* Started implicitly at device creation */ -+ ERR("Event query issued with START flag - what to do?\n"); -+ } ++void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, ++ enum wined3d_format_id format_id) ++{ ++ struct wined3d_cs_set_index_buffer *op; + -+ if (flags & WINED3DISSUE_BEGIN) -+ query->state = QUERY_BUILDING; -+ else -+ query->state = QUERY_SIGNALLED; ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER; ++ op->buffer = buffer; ++ op->format_id = format_id; + -+ return WINED3D_OK; ++ cs->ops->submit(cs); +} + -+static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) ++static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) +{ -+ struct wined3d_device *device = query->device; -+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -+#endif /* STAGING_CSMT */ - - TRACE("query %p, flags %#x.\n", query, flags); - -@@ -516,7 +672,11 @@ - /* This is allowed according to msdn and our tests. Reset the query and restart */ - if (flags & WINED3DISSUE_BEGIN) - { -+#if defined(STAGING_CSMT) - if (oq->started) -+#else /* STAGING_CSMT */ -+ if (query->state == QUERY_BUILDING) -+#endif /* STAGING_CSMT */ - { - if (oq->context->tid != GetCurrentThreadId()) - { -@@ -545,7 +705,9 @@ - checkGLcall("glBeginQuery()"); - - context_release(context); -+#if defined(STAGING_CSMT) - oq->started = TRUE; -+#endif /* STAGING_CSMT */ - } - if (flags & WINED3DISSUE_END) - { -@@ -553,7 +715,11 @@ - * our tests show that it returns OK. But OpenGL doesn't like it, so avoid - * generating an error - */ -+#if defined(STAGING_CSMT) - if (oq->started) -+#else /* STAGING_CSMT */ -+ if (query->state == QUERY_BUILDING) -+#endif /* STAGING_CSMT */ - { - if (oq->context->tid != GetCurrentThreadId()) - { -@@ -567,10 +733,15 @@ - checkGLcall("glEndQuery()"); - - context_release(context); -+#if defined(STAGING_CSMT) - poll = TRUE; - } - } - oq->started = FALSE; -+#else /* STAGING_CSMT */ -+ } -+ } -+#endif /* STAGING_CSMT */ - } - } - else -@@ -578,6 +749,7 @@ - FIXME("%p Occlusion queries not supported.\n", query); - } - -+#if defined(STAGING_CSMT) - return poll; - } - -@@ -636,6 +808,47 @@ - FIXME("%p Wrong thread, returning 1.\n", query); - tq->timestamp = 1; - return TRUE; -+#else /* STAGING_CSMT */ -+ if (flags & WINED3DISSUE_BEGIN) -+ query->state = QUERY_BUILDING; -+ else -+ query->state = QUERY_SIGNALLED; ++ const struct wined3d_cs_set_constant_buffer *op = data; ++ struct wined3d_buffer *prev; + -+ return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */ -+} ++ prev = cs->state.cb[op->type][op->cb_idx]; ++ cs->state.cb[op->type][op->cb_idx] = op->buffer; + -+static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, -+ void *data, DWORD size, DWORD flags) ++ if (op->buffer) ++ InterlockedIncrement(&op->buffer->resource.bind_count); ++ if (prev) ++ InterlockedDecrement(&prev->resource.bind_count); ++ ++ device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type)); ++} ++ ++void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, ++ UINT cb_idx, struct wined3d_buffer *buffer) +{ -+ struct wined3d_timestamp_query *tq = query->extendedData; -+ struct wined3d_device *device = query->device; -+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -+ struct wined3d_context *context; -+ GLuint available; -+ GLuint64 timestamp; -+ HRESULT res; ++ struct wined3d_cs_set_constant_buffer *op; + -+ TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER; ++ op->type = type; ++ op->cb_idx = cb_idx; ++ op->buffer = buffer; + -+ if (!tq->context) -+ query->state = QUERY_CREATED; ++ cs->ops->submit(cs); ++} + -+ if (query->state == QUERY_CREATED) -+ { -+ /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves. */ -+ TRACE("Query wasn't yet started, returning S_OK.\n"); -+ timestamp = 0; -+ fill_query_data(data, size, ×tamp, sizeof(timestamp)); -+ return S_OK; -+ } ++static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; ++ const struct wined3d_cs_set_texture *op = data; ++ struct wined3d_texture *prev; ++ BOOL old_use_color_key = FALSE, new_use_color_key = FALSE; + -+ if (tq->context->tid != GetCurrentThreadId()) ++ prev = cs->state.textures[op->stage]; ++ cs->state.textures[op->stage] = op->texture; ++ ++ if (op->texture) + { -+ FIXME("%p Wrong thread, returning 1.\n", query); -+ timestamp = 1; -+ fill_query_data(data, size, ×tamp, sizeof(timestamp)); -+ return S_OK; -+#endif /* STAGING_CSMT */ - } - - context = context_acquire(query->device, tq->context->current_rt); -@@ -646,6 +859,7 @@ - - if (available) - { -+#if defined(STAGING_CSMT) - GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); - checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); - TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); -@@ -663,6 +877,28 @@ - } - - static BOOL wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) -+#else /* STAGING_CSMT */ -+ if (size) ++ const struct wined3d_format *new_format = op->texture->resource.format; ++ const struct wined3d_format *old_format = prev ? prev->resource.format : NULL; ++ unsigned int old_fmt_flags = prev ? prev->resource.format_flags : 0; ++ unsigned int new_fmt_flags = op->texture->resource.format_flags; ++ ++ if (InterlockedIncrement(&op->texture->resource.bind_count) == 1) ++ op->texture->sampler = op->stage; ++ ++ if (!prev || op->texture->target != prev->target ++ || !is_same_fixup(new_format->color_fixup, old_format->color_fixup) ++ || (new_fmt_flags & WINED3DFMT_FLAG_SHADOW) != (old_fmt_flags & WINED3DFMT_FLAG_SHADOW)) ++ device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); ++ ++ if (!prev && op->stage < d3d_info->limits.ffp_blend_stages) + { -+ GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); -+ checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); -+ TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); -+ fill_query_data(data, size, ×tamp, sizeof(timestamp)); ++ /* The source arguments for color and alpha ops have different ++ * meanings when a NULL texture is bound, so the COLOR_OP and ++ * ALPHA_OP have to be dirtified. */ ++ device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP)); ++ device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP)); + } -+ res = S_OK; ++ ++ if (!op->stage && op->texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) ++ new_use_color_key = TRUE; + } -+ else ++ ++ if (prev) + { -+ res = S_FALSE; ++ if (InterlockedDecrement(&prev->resource.bind_count) && prev->sampler == op->stage) ++ { ++ unsigned int i; ++ ++ /* Search for other stages the texture is bound to. Shouldn't ++ * happen if applications bind textures to a single stage only. */ ++ TRACE("Searching for other stages the texture is bound to.\n"); ++ for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) ++ { ++ if (cs->state.textures[i] == prev) ++ { ++ TRACE("Texture is also bound to stage %u.\n", i); ++ prev->sampler = i; ++ break; ++ } ++ } ++ } ++ ++ if (!op->texture && op->stage < d3d_info->limits.ffp_blend_stages) ++ { ++ device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP)); ++ device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP)); ++ } ++ ++ if (!op->stage && prev->async.color_key_flags & WINED3D_CKEY_SRC_BLT) ++ old_use_color_key = TRUE; + } + -+ context_release(context); ++ device_invalidate_state(cs->device, STATE_SAMPLER(op->stage)); + -+ return res; ++ if (new_use_color_key != old_use_color_key) ++ device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE)); ++ ++ if (new_use_color_key) ++ device_invalidate_state(cs->device, STATE_COLOR_KEY); +} + -+static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) -+#endif /* STAGING_CSMT */ - { - struct wined3d_device *device = query->device; - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -@@ -695,6 +931,7 @@ - } - - if (flags & WINED3DISSUE_END) -+#if defined(STAGING_CSMT) - return TRUE; - return FALSE; - } -@@ -711,6 +948,26 @@ - { - TRACE("Query is building, returning S_FALSE.\n"); - return S_FALSE; -+#else /* STAGING_CSMT */ -+ query->state = QUERY_SIGNALLED; ++void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture) ++{ ++ struct wined3d_cs_set_texture *op; + -+ return WINED3D_OK; ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_TEXTURE; ++ op->stage = stage; ++ op->texture = texture; ++ ++ cs->ops->submit(cs); +} + -+static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query, -+ void *data, DWORD size, DWORD flags) ++static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) +{ -+ TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); ++ const struct wined3d_cs_set_shader_resource_view *op = data; + -+ if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT) -+ { -+ static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE}; ++ cs->state.shader_resource_view[op->type][op->view_idx] = op->view; ++ device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); ++} + -+ if (query->state == QUERY_BUILDING) -+ { -+ TRACE("Query is building, returning S_FALSE.\n"); -+ return S_FALSE; -+#endif /* STAGING_CSMT */ - } - - fill_query_data(data, size, &disjoint_data, sizeof(disjoint_data)); -@@ -724,6 +981,7 @@ - return S_OK; - } - -+#if defined(STAGING_CSMT) - static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *query) - { - return TRUE; -@@ -760,6 +1018,41 @@ - { - wined3d_timestamp_disjoint_query_ops_get_data, - wined3d_timestamp_disjoint_query_ops_poll, -+#else /* STAGING_CSMT */ -+static HRESULT wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) ++void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type, ++ UINT view_idx, struct wined3d_shader_resource_view *view) +{ -+ TRACE("query %p, flags %#x.\n", query, flags); ++ struct wined3d_cs_set_shader_resource_view *op; + -+ if (flags & WINED3DISSUE_BEGIN) -+ query->state = QUERY_BUILDING; -+ if (flags & WINED3DISSUE_END) -+ query->state = QUERY_SIGNALLED; ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW; ++ op->type = type; ++ op->view_idx = view_idx; ++ op->view = view; + -+ return WINED3D_OK; ++ cs->ops->submit(cs); +} + -+static const struct wined3d_query_ops event_query_ops = ++static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) +{ -+ wined3d_event_query_ops_get_data, -+ wined3d_event_query_ops_issue, -+}; ++ const struct wined3d_cs_set_sampler *op = data; + -+static const struct wined3d_query_ops occlusion_query_ops = ++ cs->state.sampler[op->type][op->sampler_idx] = op->sampler; ++ device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); ++} ++ ++void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type, ++ UINT sampler_idx, struct wined3d_sampler *sampler) +{ -+ wined3d_occlusion_query_ops_get_data, -+ wined3d_occlusion_query_ops_issue, -+}; ++ struct wined3d_cs_set_sampler *op; + -+static const struct wined3d_query_ops timestamp_query_ops = ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_SAMPLER; ++ op->type = type; ++ op->sampler_idx = sampler_idx; ++ op->sampler = sampler; ++ ++ cs->ops->submit(cs); ++} ++ ++static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) +{ -+ wined3d_timestamp_query_ops_get_data, -+ wined3d_timestamp_query_ops_issue, -+}; ++ const struct wined3d_cs_set_shader *op = data; + -+static const struct wined3d_query_ops timestamp_disjoint_query_ops = ++ cs->state.shader[op->type] = op->shader; ++ device_invalidate_state(cs->device, STATE_SHADER(op->type)); ++ device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); ++} ++ ++void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) +{ -+ wined3d_timestamp_disjoint_query_ops_get_data, -+#endif /* STAGING_CSMT */ - wined3d_timestamp_disjoint_query_ops_issue, - }; - -@@ -781,6 +1074,7 @@ - } - query->query_ops = &occlusion_query_ops; - query->data_size = sizeof(DWORD); -+#if defined(STAGING_CSMT) - query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(struct wined3d_occlusion_query)); - if (!query->extendedData) -@@ -788,6 +1082,15 @@ - ERR("Failed to allocate occlusion query extended data.\n"); - return E_OUTOFMEMORY; - } -+#else /* STAGING_CSMT */ -+ query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query)); -+ if (!query->extendedData) -+ { -+ ERR("Failed to allocate occlusion query extended data.\n"); -+ return E_OUTOFMEMORY; -+ } -+ ((struct wined3d_occlusion_query *)query->extendedData)->context = NULL; -+#endif /* STAGING_CSMT */ - break; - - case WINED3D_QUERY_TYPE_EVENT: -@@ -860,7 +1163,9 @@ - query->state = QUERY_CREATED; - query->device = device; - query->ref = 1; -+#if defined(STAGING_CSMT) - list_init(&query->poll_list_entry); -+#endif /* STAGING_CSMT */ - - return WINED3D_OK; - } -diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c ---- a/dlls/wined3d/drawprim.c -+++ b/dlls/wined3d/drawprim.c -@@ -36,7 +36,11 @@ - #include - - /* Context activation is done by the caller. */ -+#if defined(STAGING_CSMT) - static void draw_strided_fast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, -+#else /* STAGING_CSMT */ -+static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, -+#endif /* STAGING_CSMT */ - const void *idx_data, UINT start_idx, INT base_vertex_index, UINT start_instance, UINT instance_count) - { - if (idx_size) -@@ -95,7 +99,11 @@ - */ - - /* Context activation is done by the caller. */ -+#if defined(STAGING_CSMT) - static void draw_strided_slow(const struct wined3d_state *state, struct wined3d_context *context, -+#else /* STAGING_CSMT */ -+static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_context *context, -+#endif /* STAGING_CSMT */ - const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType, - const void *idxData, UINT idxSize, UINT startIdx) - { -@@ -103,6 +111,9 @@ - const WORD *pIdxBufS = NULL; - const DWORD *pIdxBufL = NULL; - UINT vx_index; -+#if !defined(STAGING_CSMT) -+ const struct wined3d_state *state = &device->state; -+#endif /* STAGING_CSMT */ - LONG SkipnStrides = startIdx; - BOOL pixelShader = use_ps(state); - BOOL specular_fog = FALSE; -@@ -452,7 +463,11 @@ - } - - /* Context activation is done by the caller. */ -+#if defined(STAGING_CSMT) - static void draw_strided_slow_vs(struct wined3d_context *context, const struct wined3d_state *state, -+#else /* STAGING_CSMT */ -+static void drawStridedSlowVs(struct wined3d_context *context, const struct wined3d_state *state, -+#endif /* STAGING_CSMT */ - const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, - const void *idxData, UINT idxSize, UINT startIdx) - { -@@ -509,7 +524,11 @@ - } - - /* Context activation is done by the caller. */ -+#if defined(STAGING_CSMT) - static void draw_strided_instanced(struct wined3d_context *context, const struct wined3d_state *state, -+#else /* STAGING_CSMT */ -+static void drawStridedInstanced(struct wined3d_context *context, const struct wined3d_state *state, -+#endif /* STAGING_CSMT */ - const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, - const void *idxData, UINT idxSize, UINT startIdx, UINT base_vertex_index, UINT instance_count) - { -@@ -594,10 +613,17 @@ - } - - /* Routine common to the draw primitive and draw indexed primitive routines */ -+#if defined(STAGING_CSMT) - void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, - UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count, - BOOL indexed) - { -+#else /* STAGING_CSMT */ -+void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count, -+ UINT start_instance, UINT instance_count, BOOL indexed) ++ struct wined3d_cs_set_shader *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_SHADER; ++ op->type = type; ++ op->shader = shader; ++ ++ cs->ops->submit(cs); ++} ++ ++static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) +{ -+ const struct wined3d_state *state = &device->state; -+#endif /* STAGING_CSMT */ - const struct wined3d_stream_info *stream_info; - struct wined3d_event_query *ib_query = NULL; - struct wined3d_stream_info si_emulated; -@@ -610,7 +636,11 @@ - - if (!index_count) return; - -+#if defined(STAGING_CSMT) - context = context_acquire(device, wined3d_rendertarget_view_get_surface(state->fb.render_targets[0])); -+#else /* STAGING_CSMT */ -+ context = context_acquire(device, wined3d_rendertarget_view_get_surface(device->fb.render_targets[0])); -+#endif /* STAGING_CSMT */ - if (!context->valid) - { - context_release(context); -@@ -621,6 +651,7 @@ - - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) - { -+#if defined(STAGING_CSMT) - struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(state->fb.render_targets[i]); - if (target && target->resource.format->id != WINED3DFMT_NULL) - { -@@ -628,6 +659,15 @@ - { - wined3d_resource_load_location(&target->resource, context, target->container->resource.draw_binding); - wined3d_resource_invalidate_location(&target->resource, ~target->container->resource.draw_binding); -+#else /* STAGING_CSMT */ -+ struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]); -+ if (target && target->resource.format->id != WINED3DFMT_NULL) -+ { -+ if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) -+ { -+ surface_load_location(target, context, target->container->resource.draw_binding); -+ surface_invalidate_location(target, ~target->container->resource.draw_binding); -+#endif /* STAGING_CSMT */ - } - else - { -@@ -636,6 +676,7 @@ - } - } - -+#if defined(STAGING_CSMT) - if (state->fb.depth_stencil) - { - /* Note that this depends on the context_acquire() call above to set -@@ -655,6 +696,27 @@ - wined3d_cs_switch_onscreen_ds(device->cs, context, ds); - - if (ds->resource.locations & location) -+#else /* STAGING_CSMT */ -+ if (device->fb.depth_stencil) -+ { -+ /* Note that this depends on the context_acquire() call above to set -+ * context->render_offscreen properly. We don't currently take the -+ * Z-compare function into account, but we could skip loading the -+ * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note -+ * that we never copy the stencil data.*/ -+ DWORD location = context->render_offscreen ? device->fb.depth_stencil->resource->draw_binding -+ : WINED3D_LOCATION_DRAWABLE; -+ struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil); ++ const struct wined3d_cs_set_render_state *op = data; + -+ if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) -+ { -+ RECT current_rect, draw_rect, r; ++ cs->state.render_states[op->state] = op->value; ++ device_invalidate_state(cs->device, STATE_RENDER(op->state)); ++} + -+ if (!context->render_offscreen && ds != device->onscreen_depth_stencil) -+ device_switch_onscreen_ds(device, context, ds); ++void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value) ++{ ++ struct wined3d_cs_set_render_state *op; + -+ if (ds->locations & location) -+#endif /* STAGING_CSMT */ - SetRect(¤t_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy); - else - SetRectEmpty(¤t_rect); -@@ -671,6 +733,7 @@ - wined3d_surface_prepare(ds, context, location); - } - -+#if defined(STAGING_CSMT) - if (!context_apply_draw_state(context, device, state)) - { - context_release(context); -@@ -681,6 +744,18 @@ - if (state->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE]) - { - struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil); -+#else /* STAGING_CSMT */ -+ if (!context_apply_draw_state(context, device)) -+ { -+ context_release(context); -+ WARN("Unable to apply draw state, skipping draw.\n"); -+ return; -+ } ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_RENDER_STATE; ++ op->state = state; ++ op->value = value; + -+ if (device->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE]) -+ { -+ struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil); -+#endif /* STAGING_CSMT */ - DWORD location = context->render_offscreen ? ds->container->resource.draw_binding : WINED3D_LOCATION_DRAWABLE; - - surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); -@@ -763,6 +838,7 @@ - else - WARN_(d3d_perf)("Using immediate mode with vertex shaders for half float emulation.\n"); - -+#if defined(STAGING_CSMT) - draw_strided_slow_vs(context, state, stream_info, index_count, - state->gl_primitive_type, idx_data, idx_size, start_idx); - } -@@ -785,6 +861,30 @@ - else - { - draw_strided_fast(gl_info, state->gl_primitive_type, index_count, idx_size, idx_data, -+#else /* STAGING_CSMT */ -+ drawStridedSlowVs(context, state, stream_info, index_count, -+ state->gl_primitive_type, idx_data, idx_size, start_idx); -+ } -+ else -+ { -+ if (context->d3d_info->ffp_generic_attributes) -+ drawStridedSlowVs(context, state, stream_info, index_count, -+ state->gl_primitive_type, idx_data, idx_size, start_idx); -+ else -+ drawStridedSlow(device, context, stream_info, index_count, -+ state->gl_primitive_type, idx_data, idx_size, start_idx); -+ } -+ } -+ else if (!gl_info->supported[ARB_INSTANCED_ARRAYS] && instance_count) -+ { -+ /* Instancing emulation by mixing immediate mode and arrays. */ -+ drawStridedInstanced(context, state, stream_info, index_count, state->gl_primitive_type, -+ idx_data, idx_size, start_idx, state->base_vertex_index, instance_count); -+ } -+ else -+ { -+ drawStridedFast(gl_info, state->gl_primitive_type, index_count, idx_size, idx_data, -+#endif /* STAGING_CSMT */ - start_idx, state->base_vertex_index, start_instance, instance_count); - } - -diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c ---- a/dlls/wined3d/device.c -+++ b/dlls/wined3d/device.c -@@ -198,6 +198,24 @@ - device->contexts = new_array; - } - -+#if !defined(STAGING_CSMT) -+void device_switch_onscreen_ds(struct wined3d_device *device, -+ struct wined3d_context *context, struct wined3d_surface *depth_stencil) ++ cs->ops->submit(cs); ++} ++ ++static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) +{ -+ if (device->onscreen_depth_stencil) -+ { -+ surface_load_ds_location(device->onscreen_depth_stencil, context, WINED3D_LOCATION_TEXTURE_RGB); ++ const struct wined3d_cs_set_texture_state *op = data; + -+ surface_modify_ds_location(device->onscreen_depth_stencil, WINED3D_LOCATION_TEXTURE_RGB, -+ device->onscreen_depth_stencil->ds_current_size.cx, -+ device->onscreen_depth_stencil->ds_current_size.cy); -+ wined3d_texture_decref(device->onscreen_depth_stencil->container); -+ } -+ device->onscreen_depth_stencil = depth_stencil; -+ wined3d_texture_incref(device->onscreen_depth_stencil->container); ++ cs->state.texture_states[op->stage][op->state] = op->value; ++ device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state)); +} + -+#endif /* STAGING_CSMT */ - static BOOL is_full_clear(const struct wined3d_surface *target, const RECT *draw_rect, const RECT *clear_rect) - { - /* partial draw rect */ -@@ -220,7 +238,11 @@ - { - RECT current_rect, r; - -+#if defined(STAGING_CSMT) - if (ds->resource.locations & WINED3D_LOCATION_DISCARDED) -+#else /* STAGING_CSMT */ -+ if (ds->locations & WINED3D_LOCATION_DISCARDED) -+#endif /* STAGING_CSMT */ - { - /* Depth buffer was discarded, make it entirely current in its new location since - * there is no other place where we would get data anyway. */ -@@ -228,7 +250,11 @@ - return; - } - -+#if defined(STAGING_CSMT) - if (ds->resource.locations & location) -+#else /* STAGING_CSMT */ -+ if (ds->locations & location) -+#endif /* STAGING_CSMT */ - SetRect(¤t_rect, 0, 0, - ds->ds_current_size.cx, - ds->ds_current_size.cy); -@@ -308,7 +334,11 @@ - if (rt && rt->resource.format->id != WINED3DFMT_NULL) - { - if (flags & WINED3DCLEAR_TARGET && !is_full_clear(target, draw_rect, clear_rect)) -+#if defined(STAGING_CSMT) - wined3d_resource_load_location(&rt->resource, context, rt->container->resource.draw_binding); -+#else /* STAGING_CSMT */ -+ surface_load_location(rt, context, rt->container->resource.draw_binding); -+#endif /* STAGING_CSMT */ - else - wined3d_surface_prepare(rt, context, rt->container->resource.draw_binding); - } -@@ -333,8 +363,13 @@ - { - DWORD location = render_offscreen ? fb->depth_stencil->resource->draw_binding : WINED3D_LOCATION_DRAWABLE; - -+#if defined(STAGING_CSMT) - if (!render_offscreen && depth_stencil != device->cs->onscreen_depth_stencil) - wined3d_cs_switch_onscreen_ds(device->cs, context, depth_stencil); -+#else /* STAGING_CSMT */ -+ if (!render_offscreen && depth_stencil != device->onscreen_depth_stencil) -+ device_switch_onscreen_ds(device, context, depth_stencil); -+#endif /* STAGING_CSMT */ - prepare_ds_clear(depth_stencil, context, location, - draw_rect, rect_count, clear_rect, &ds_rect); - } -@@ -382,8 +417,13 @@ - - if (rt) - { -+#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&rt->resource, rt->container->resource.draw_binding); - wined3d_resource_invalidate_location(&rt->resource, ~rt->container->resource.draw_binding); -+#else /* STAGING_CSMT */ -+ surface_validate_location(rt, rt->container->resource.draw_binding); -+ surface_invalidate_location(rt, ~rt->container->resource.draw_binding); -+#endif /* STAGING_CSMT */ - } - } - -@@ -651,7 +691,11 @@ - } - - /* Context activation is done by the caller. */ -+#if defined(STAGING_CSMT) - void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) -+#else /* STAGING_CSMT */ -+static void create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) -+#endif /* STAGING_CSMT */ - { - const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; - unsigned int i, j, count; -@@ -878,7 +922,11 @@ - BOOL ds_enable = !!swapchain->desc.enable_auto_depth_stencil; - unsigned int i; - -+#if defined(STAGING_CSMT) - if (device->state.fb.render_targets) -+#else /* STAGING_CSMT */ -+ if (device->fb.render_targets) -+#endif /* STAGING_CSMT */ - { - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) - { -@@ -896,7 +944,13 @@ - struct wined3d_swapchain_desc *swapchain_desc) - { - static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f}; -+#if defined(STAGING_CSMT) - struct wined3d_swapchain *swapchain = NULL; -+#else /* STAGING_CSMT */ -+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -+ struct wined3d_swapchain *swapchain = NULL; -+ struct wined3d_context *context; -+#endif /* STAGING_CSMT */ - DWORD clear_flags = 0; - HRESULT hr; - -@@ -907,6 +961,11 @@ - if (device->wined3d->flags & WINED3D_NO3D) - return WINED3DERR_INVALIDCALL; - -+#if !defined(STAGING_CSMT) -+ device->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(*device->fb.render_targets) * gl_info->limits.buffers); -+ -+#endif /* STAGING_CSMT */ - if (FAILED(hr = device->shader_backend->shader_alloc_private(device, - device->adapter->vertex_pipe, device->adapter->fragment_pipe))) - { -@@ -947,7 +1006,14 @@ - device->swapchains[0] = swapchain; - device_init_swapchain_state(device, swapchain); - -+#if defined(STAGING_CSMT) - wined3d_cs_emit_create_dummy_textures(device->cs); -+#else /* STAGING_CSMT */ -+ context = context_acquire(device, -+ surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0))); ++void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, ++ enum wined3d_texture_stage_state state, DWORD value) ++{ ++ struct wined3d_cs_set_texture_state *op; + -+ create_dummy_textures(device, context); -+#endif /* STAGING_CSMT */ - - device->contexts[0]->last_was_rhw = 0; - -@@ -959,7 +1025,11 @@ - - case ORM_BACKBUFFER: - { -+#if defined(STAGING_CSMT) - if (device->contexts[0]->aux_buffers > 0) -+#else /* STAGING_CSMT */ -+ if (context_get_current()->aux_buffers > 0) -+#endif /* STAGING_CSMT */ - { - TRACE("Using auxiliary buffer for offscreen rendering\n"); - device->offscreenBuffer = GL_AUX0; -@@ -971,9 +1041,16 @@ - } - } - } -+#if defined(STAGING_CSMT) - device->contexts[0]->offscreenBuffer = device->offscreenBuffer; - - TRACE("All defaults now set up, leaving 3D init.\n"); -+#else /* STAGING_CSMT */ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_TEXTURE_STATE; ++ op->stage = stage; ++ op->state = state; ++ op->value = value; + -+ TRACE("All defaults now set up, leaving 3D init.\n"); ++ cs->ops->submit(cs); ++} + -+ context_release(context); -+#endif /* STAGING_CSMT */ - - /* Clear the screen */ - if (swapchain->back_buffers && swapchain->back_buffers[0]) -@@ -990,6 +1067,9 @@ - return WINED3D_OK; - - err_out: -+#if !defined(STAGING_CSMT) -+ HeapFree(GetProcessHeap(), 0, device->fb.render_targets); -+#endif /* STAGING_CSMT */ - HeapFree(GetProcessHeap(), 0, device->swapchains); - device->swapchain_count = 0; - if (device->back_buffer_view) -@@ -1047,6 +1127,10 @@ - HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) - { - struct wined3d_resource *resource, *cursor; -+#if !defined(STAGING_CSMT) -+ const struct wined3d_gl_info *gl_info; -+ struct wined3d_context *context; -+#endif /* STAGING_CSMT */ - struct wined3d_surface *surface; - UINT i; - -@@ -1055,6 +1139,7 @@ - if (!device->d3d_initialized) - return WINED3DERR_INVALIDCALL; - -+#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - device->cs->ops->finish(device->cs); - -@@ -1093,6 +1178,82 @@ - /* FIXME: Is this in the right place??? */ - wined3d_cs_emit_delete_opengl_contexts(device->cs, device->swapchains[0]); - -+#else /* STAGING_CSMT */ -+ /* I don't think that the interface guarantees that the device is destroyed from the same thread -+ * it was created. Thus make sure a context is active for the glDelete* calls -+ */ -+ context = context_acquire(device, NULL); -+ gl_info = context->gl_info; ++static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_sampler_state *op = data; + -+ if (device->logo_texture) -+ wined3d_texture_decref(device->logo_texture); -+ if (device->cursor_texture) -+ wined3d_texture_decref(device->cursor_texture); ++ cs->state.sampler_states[op->sampler_idx][op->state] = op->value; ++ device_invalidate_state(cs->device, STATE_SAMPLER(op->sampler_idx)); ++} + -+ state_unbind_resources(&device->state); ++void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, ++ enum wined3d_sampler_state state, DWORD value) ++{ ++ struct wined3d_cs_set_sampler_state *op; + -+ /* Unload resources */ -+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) -+ { -+ TRACE("Unloading resource %p.\n", resource); ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_SAMPLER_STATE; ++ op->sampler_idx = sampler_idx; ++ op->state = state; ++ op->value = value; + -+ resource->resource_ops->resource_unload(resource); -+ } ++ cs->ops->submit(cs); ++} + -+ wine_rb_clear(&device->samplers, device_free_sampler, NULL); ++static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_transform *op = data; + -+ /* Destroy the depth blt resources, they will be invalid after the reset. Also free shader -+ * private data, it might contain opengl pointers -+ */ -+ if (device->depth_blt_texture) -+ { -+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->depth_blt_texture); -+ device->depth_blt_texture = 0; -+ } ++ cs->state.transforms[op->state] = *op->matrix; ++ if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices)) ++ device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); ++} + -+ /* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */ -+ device->blitter->free_private(device); -+ device->shader_backend->shader_free_private(device); -+ destroy_dummy_textures(device, gl_info); ++void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state, ++ const struct wined3d_matrix *matrix) ++{ ++ struct wined3d_cs_set_transform *op; + -+ /* Release the context again as soon as possible. In particular, -+ * releasing the render target views below may release the last reference -+ * to the swapchain associated with this context, which in turn will -+ * destroy the context. */ -+ context_release(context); ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_TRANSFORM; ++ op->state = state; ++ op->matrix = matrix; + -+ /* Release the buffers (with sanity checks)*/ -+ if (device->onscreen_depth_stencil) -+ { -+ surface = device->onscreen_depth_stencil; -+ device->onscreen_depth_stencil = NULL; -+ wined3d_texture_decref(surface->container); -+ } ++ cs->ops->submit(cs); ++} + -+ if (device->fb.depth_stencil) -+ { -+ struct wined3d_rendertarget_view *view = device->fb.depth_stencil; ++static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_clip_plane *op = data; + -+ TRACE("Releasing depth/stencil view %p.\n", view); ++ cs->state.clip_planes[op->plane_idx] = *op->plane; ++ device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx)); ++} + -+ device->fb.depth_stencil = NULL; -+ wined3d_rendertarget_view_decref(view); -+ } ++void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane) ++{ ++ struct wined3d_cs_set_clip_plane *op; + -+ if (device->auto_depth_stencil_view) ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE; ++ op->plane_idx = plane_idx; ++ op->plane = plane; ++ ++ cs->ops->submit(cs); ++} ++ ++static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_color_key *op = data; ++ struct wined3d_texture *texture = op->texture; ++ ++ if (op->set) + { -+ struct wined3d_rendertarget_view *view = device->auto_depth_stencil_view; ++ switch (op->flags) ++ { ++ case WINED3D_CKEY_DST_BLT: ++ texture->async.dst_blt_color_key = op->color_key; ++ texture->async.color_key_flags |= WINED3D_CKEY_DST_BLT; ++ break; + -+ device->auto_depth_stencil_view = NULL; -+ if (wined3d_rendertarget_view_decref(view)) -+ ERR("Something's still holding the auto depth/stencil view (%p).\n", view); -+ } ++ case WINED3D_CKEY_DST_OVERLAY: ++ texture->async.dst_overlay_color_key = op->color_key; ++ texture->async.color_key_flags |= WINED3D_CKEY_DST_OVERLAY; ++ break; + -+ for (i = 0; i < gl_info->limits.buffers; ++i) ++ case WINED3D_CKEY_SRC_BLT: ++ if (texture == cs->state.textures[0]) ++ { ++ device_invalidate_state(cs->device, STATE_COLOR_KEY); ++ if (!(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)) ++ device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE)); ++ } ++ ++ texture->async.src_blt_color_key = op->color_key; ++ texture->async.color_key_flags |= WINED3D_CKEY_SRC_BLT; ++ break; ++ ++ case WINED3D_CKEY_SRC_OVERLAY: ++ texture->async.src_overlay_color_key = op->color_key; ++ texture->async.color_key_flags |= WINED3D_CKEY_SRC_OVERLAY; ++ break; ++ } ++ } ++ else + { -+ wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); ++ switch (op->flags) ++ { ++ case WINED3D_CKEY_DST_BLT: ++ texture->async.color_key_flags &= ~WINED3D_CKEY_DST_BLT; ++ break; ++ ++ case WINED3D_CKEY_DST_OVERLAY: ++ texture->async.color_key_flags &= ~WINED3D_CKEY_DST_OVERLAY; ++ break; ++ ++ case WINED3D_CKEY_SRC_BLT: ++ if (texture == cs->state.textures[0] && texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) ++ device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE)); ++ ++ texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_BLT; ++ break; ++ ++ case WINED3D_CKEY_SRC_OVERLAY: ++ texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_OVERLAY; ++ break; ++ } + } -+#endif /* STAGING_CSMT */ - if (device->back_buffer_view) - { - wined3d_rendertarget_view_decref(device->back_buffer_view); -@@ -1110,6 +1271,11 @@ - device->swapchains = NULL; - device->swapchain_count = 0; - -+#if !defined(STAGING_CSMT) -+ HeapFree(GetProcessHeap(), 0, device->fb.render_targets); -+ device->fb.render_targets = NULL; ++} + -+#endif /* STAGING_CSMT */ - device->d3d_initialized = FALSE; - - return WINED3D_OK; -@@ -1496,6 +1662,16 @@ - TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", - light->range, light->falloff, light->theta, light->phi); - -+#if !defined(STAGING_CSMT) -+ /* Update the live definitions if the light is currently assigned a glIndex. */ -+ if (object->glIndex != -1 && !device->recording) ++void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture, ++ WORD flags, const struct wined3d_color_key *color_key) ++{ ++ struct wined3d_cs_set_color_key *op; ++ ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_COLOR_KEY; ++ op->texture = texture; ++ op->flags = flags; ++ if (color_key) + { -+ if (object->OriginalParms.type != light->type) -+ device_invalidate_state(device, STATE_LIGHT_TYPE); -+ device_invalidate_state(device, STATE_ACTIVELIGHT(object->glIndex)); ++ op->color_key = *color_key; ++ op->set = 1; + } ++ else ++ op->set = 0; + -+#endif /* STAGING_CSMT */ - /* Save away the information. */ - object->OriginalParms = *light; - -@@ -1575,9 +1751,11 @@ - FIXME("Unrecognized light type %#x.\n", light->type); - } - -+#if defined(STAGING_CSMT) - if (!device->recording) - wined3d_cs_emit_set_light(device->cs, object); - -+#endif /* STAGING_CSMT */ - return WINED3D_OK; - } - -@@ -1650,6 +1828,14 @@ - { - if (light_info->glIndex != -1) - { -+#if !defined(STAGING_CSMT) -+ if (!device->recording) -+ { -+ device_invalidate_state(device, STATE_LIGHT_TYPE); -+ device_invalidate_state(device, STATE_ACTIVELIGHT(light_info->glIndex)); -+ } ++ cs->ops->submit(cs); ++} + -+#endif /* STAGING_CSMT */ - device->update_state->lights[light_info->glIndex] = NULL; - light_info->glIndex = -1; - } -@@ -1691,11 +1877,23 @@ - WARN("Too many concurrently active lights\n"); - return WINED3D_OK; - } -+#if defined(STAGING_CSMT) - } - } - - if (!device->recording) - wined3d_cs_emit_set_light_enable(device->cs, light_idx, enable); -+#else /* STAGING_CSMT */ ++static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) ++{ ++ const struct wined3d_cs_set_material *op = data; + -+ /* i == light_info->glIndex */ -+ if (!device->recording) -+ { -+ device_invalidate_state(device, STATE_LIGHT_TYPE); -+ device_invalidate_state(device, STATE_ACTIVELIGHT(i)); -+ } -+ } -+ } -+#endif /* STAGING_CSMT */ - - return WINED3D_OK; - } -@@ -1870,9 +2068,11 @@ - TRACE("device %p, base_index %d.\n", device, base_index); - - device->update_state->base_vertex_index = base_index; -+#if defined(STAGING_CSMT) - - if (!device->recording) - wined3d_cs_emit_set_base_vertex_index(device->cs, base_index); -+#endif /* STAGING_CSMT */ - } - - INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *device) -@@ -1917,7 +2117,11 @@ - || !(texture->resource.format_flags & WINED3DFMT_FLAG_DEPTH)) - return; - surface = surface_from_resource(texture->sub_resources[0]); -+#if defined(STAGING_CSMT) - if (!(depth_stencil = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil))) -+#else /* STAGING_CSMT */ -+ if (!(depth_stencil = wined3d_rendertarget_view_get_surface(state->fb->depth_stencil))) -+#endif /* STAGING_CSMT */ - return; - - wined3d_surface_blt(surface, NULL, depth_stencil, NULL, 0, NULL, WINED3D_TEXF_POINT); -@@ -2237,7 +2441,11 @@ - return device->state.sampler[WINED3D_SHADER_TYPE_VERTEX][idx]; - } - -+#if defined(STAGING_CSMT) - void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) -+#else /* STAGING_CSMT */ -+static void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) -+#endif /* STAGING_CSMT */ - { - UINT i; - -@@ -2270,8 +2478,12 @@ - } - else - { -+#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_b(device->cs, start_register, constants, - bool_count, WINED3D_SHADER_TYPE_VERTEX); -+#else /* STAGING_CSMT */ -+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_B); -+#endif /* STAGING_CSMT */ - } - - return WINED3D_OK; -@@ -2318,8 +2530,12 @@ - } - else - { -+#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_i(device->cs, start_register, constants, - vector4i_count, WINED3D_SHADER_TYPE_VERTEX); -+#else /* STAGING_CSMT */ -+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_I); -+#endif /* STAGING_CSMT */ - } - - return WINED3D_OK; -@@ -2370,8 +2586,13 @@ - memset(device->recording->changed.vertexShaderConstantsF + start_register, 1, - sizeof(*device->recording->changed.vertexShaderConstantsF) * vector4f_count); - else -+#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_f(device->cs, start_register, constants, vector4f_count, - WINED3D_SHADER_TYPE_VERTEX); -+#else /* STAGING_CSMT */ -+ device->shader_backend->shader_update_float_vertex_constants(device, start_register, vector4f_count); ++ cs->state.material = *op->material; ++ device_invalidate_state(cs->device, STATE_MATERIAL); ++} + -+#endif /* STAGING_CSMT */ - - return WINED3D_OK; - } -@@ -2506,8 +2727,12 @@ - } - else - { -+#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_b(device->cs, start_register, constants, - bool_count, WINED3D_SHADER_TYPE_PIXEL); -+#else /* STAGING_CSMT */ -+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_B); -+#endif /* STAGING_CSMT */ - } - - return WINED3D_OK; -@@ -2554,8 +2779,12 @@ - } - else - { -+#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_i(device->cs, start_register, constants, - vector4i_count, WINED3D_SHADER_TYPE_PIXEL); -+#else /* STAGING_CSMT */ -+ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_I); -+#endif /* STAGING_CSMT */ - } - - return WINED3D_OK; -@@ -2607,8 +2836,12 @@ - memset(device->recording->changed.pixelShaderConstantsF + start_register, 1, - sizeof(*device->recording->changed.pixelShaderConstantsF) * vector4f_count); - else -+#if defined(STAGING_CSMT) - wined3d_cs_emit_set_consts_f(device->cs, start_register, constants, vector4f_count, - WINED3D_SHADER_TYPE_PIXEL); -+#else /* STAGING_CSMT */ -+ device->shader_backend->shader_update_float_pixel_constants(device, start_register, vector4f_count); -+#endif /* STAGING_CSMT */ - - return WINED3D_OK; - } -@@ -2768,6 +3001,7 @@ - return hr; - } - -+#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - { - FIXME("Waiting for cs.\n"); -@@ -2775,6 +3009,7 @@ - device->cs->ops->finish(device->cs); - } - -+#endif /* STAGING_CSMT */ - wined3d_device_get_transform(device, WINED3D_TS_VIEW, &view_mat); - wined3d_device_get_transform(device, WINED3D_TS_PROJECTION, &proj_mat); - wined3d_device_get_transform(device, WINED3D_TS_WORLD_MATRIX(0), &world_mat); -@@ -3260,6 +3495,10 @@ - - HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) - { -+#if !defined(STAGING_CSMT) -+ struct wined3d_context *context; ++void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material) ++{ ++ struct wined3d_cs_set_material *op; + -+#endif /* STAGING_CSMT */ - TRACE("device %p.\n", device); - - if (!device->inScene) -@@ -3268,6 +3507,15 @@ - return WINED3DERR_INVALIDCALL; - } - -+#if !defined(STAGING_CSMT) -+ context = context_acquire(device, NULL); -+ /* We only have to do this if we need to read the, swapbuffers performs a flush for us */ -+ context->gl_info->gl_ops.gl.p_glFlush(); -+ /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever -+ * fails. */ -+ context_release(context); ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_SET_MATERIAL; ++ op->material = material; + -+#endif /* STAGING_CSMT */ - device->inScene = FALSE; - return WINED3D_OK; - } -@@ -3275,8 +3523,10 @@ - HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, - const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) - { -+#if defined(STAGING_CSMT) - const struct wined3d_fb_state *fb = &device->state.fb; - -+#endif /* STAGING_CSMT */ - TRACE("device %p, rect_count %u, rects %p, flags %#x, color {%.8e, %.8e, %.8e, %.8e}, depth %.8e, stencil %u.\n", - device, rect_count, rects, flags, color->r, color->g, color->b, color->a, depth, stencil); - -@@ -3285,12 +3535,19 @@ - WARN("Rects is %p, but rect_count is 0, ignoring clear\n", rects); - return WINED3D_OK; - } -+#if defined(STAGING_CSMT) - if (rect_count && !rects) - rect_count = 0; - - if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) - { - struct wined3d_rendertarget_view *ds = fb->depth_stencil; -+#else /* STAGING_CSMT */ ++ cs->ops->submit(cs); ++} + -+ if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) -+ { -+ struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; -+#endif /* STAGING_CSMT */ - if (!ds) - { - WARN("Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL\n"); -@@ -3299,8 +3556,13 @@ - } - else if (flags & WINED3DCLEAR_TARGET) - { -+#if defined(STAGING_CSMT) - if (ds->width < fb->render_targets[0]->width - || ds->height < fb->render_targets[0]->height) -+#else /* STAGING_CSMT */ -+ if (ds->width < device->fb.render_targets[0]->width -+ || ds->height < device->fb.render_targets[0]->height) -+#endif /* STAGING_CSMT */ - { - WARN("Silently ignoring depth and target clear with mismatching sizes\n"); - return WINED3D_OK; -@@ -3346,6 +3608,9 @@ - enum wined3d_primitive_type primitive_type) - { - GLenum gl_primitive_type, prev; -+#if !defined(STAGING_CSMT) ++static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) ++{ ++ struct wined3d_adapter *adapter = cs->device->adapter; ++ HRESULT hr; + -+#endif /* STAGING_CSMT */ - TRACE("device %p, primitive_type %s\n", device, debug_d3dprimitivetype(primitive_type)); - - gl_primitive_type = gl_primitive_type_from_d3d(primitive_type); -@@ -3353,8 +3618,13 @@ - device->update_state->gl_primitive_type = gl_primitive_type; - if (device->recording) - device->recording->changed.primitive_type = TRUE; -+#if defined(STAGING_CSMT) - else if (gl_primitive_type != prev) - wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type); -+#else /* STAGING_CSMT */ -+ else if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS)) -+ device_invalidate_state(device, STATE_POINT_ENABLE); -+#endif /* STAGING_CSMT */ - } - - void CDECL wined3d_device_get_primitive_type(const struct wined3d_device *device, -@@ -3377,6 +3647,14 @@ - return WINED3DERR_INVALIDCALL; - } - -+#if !defined(STAGING_CSMT) -+ if (device->state.load_base_vertex_index) -+ { -+ device->state.load_base_vertex_index = 0; -+ device_invalidate_state(device, STATE_BASEVERTEXINDEX); -+ } ++ state_cleanup(&cs->state); ++ memset(&cs->state, 0, sizeof(cs->state)); ++ if (FAILED(hr = state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info, ++ WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) ++ ERR("Failed to initialize CS state, hr %#x.\n", hr); ++} + -+#endif /* STAGING_CSMT */ - wined3d_cs_emit_draw(device->cs, start_vertex, vertex_count, 0, 0, FALSE); - - return WINED3D_OK; -@@ -3393,6 +3671,10 @@ - - HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count) - { -+#if !defined(STAGING_CSMT) -+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) ++{ ++ struct wined3d_cs_reset_state *op; + -+#endif /* STAGING_CSMT */ - TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count); - - if (!device->state.index_buffer) -@@ -3411,6 +3693,15 @@ - return WINED3DERR_INVALIDCALL; - } - -+#if !defined(STAGING_CSMT) -+ if (!gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] && -+ device->state.load_base_vertex_index != device->state.base_vertex_index) -+ { -+ device->state.load_base_vertex_index = device->state.base_vertex_index; -+ device_invalidate_state(device, STATE_BASEVERTEXINDEX); -+ } ++ op = cs->ops->require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_RESET_STATE; ++ ++ cs->ops->submit(cs); ++} + ++static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = ++{ +#endif /* STAGING_CSMT */ - wined3d_cs_emit_draw(device->cs, start_idx, index_count, 0, 0, TRUE); - - return WINED3D_OK; -@@ -3426,6 +3717,7 @@ - } - - /* This is a helper function for UpdateTexture, there is no UpdateVolume method in D3D. */ -+#if defined(STAGING_CSMT) - static void device_update_volume(struct wined3d_context *context, - struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) - { -@@ -3462,6 +3754,88 @@ - { - enum wined3d_resource_type type = src_texture->resource.type; - unsigned int level_count, i, j, src_size, dst_size, src_skip_levels = 0; -+#else /* STAGING_CSMT */ -+static HRESULT device_update_volume(struct wined3d_device *device, -+ struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) -+{ -+ struct wined3d_const_bo_address data; -+ struct wined3d_map_desc src; -+ HRESULT hr; -+ struct wined3d_context *context; ++ /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, ++ /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, ++ /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, ++ /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication, ++ /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport, ++ /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect, ++ /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, ++ /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, ++ /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, ++ /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, ++ /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, ++ /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output, ++ /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, ++ /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, ++ /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, ++ /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, ++ /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, ++ /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, ++ /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, ++ /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, ++ /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, ++ /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, ++ /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, ++ /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, ++ /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, ++ /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, ++#if defined(STAGING_CSMT) ++ /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, ++ /* WINED3D_CS_OP_SET_VS_CONSTS_B */ wined3d_cs_exec_set_vs_consts_b, ++ /* WINED3D_CS_OP_SET_VS_CONSTS_I */ wined3d_cs_exec_set_vs_consts_i, ++ /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, ++ /* WINED3D_CS_OP_SET_PS_CONSTS_B */ wined3d_cs_exec_set_ps_consts_b, ++ /* WINED3D_CS_OP_SET_PS_CONSTS_I */ wined3d_cs_exec_set_ps_consts_i, ++ /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, ++ /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, ++ /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, ++ /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, ++ /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, ++ /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, ++ /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, ++ /* WINED3D_CS_OP_RESOURCE_CHANGED */ wined3d_cs_exec_resource_changed, ++ /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, ++ /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, ++ /* WINED3D_CS_OP_BUFFER_SWAP_MEM */ wined3d_cs_exec_buffer_swap_mem, ++ /* WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE */ wined3d_cs_exec_buffer_invalidate_bo_range, ++ /* WINED3D_CS_OP_BUFFER_PRELOAD */ wined3d_cs_exec_buffer_preload, ++ /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, ++ /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, ++ /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, ++ /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, ++ /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, ++ /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, ++ /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, ++ /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, ++ /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, ++ /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, ++ /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, ++ /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, ++ /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, ++ /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, ++ /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, ++ /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, ++ /* WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT */ wined3d_cs_exec_create_swapchain_context, ++ /* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts, ++ /* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc, ++ /* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc, ++ /* WINED3D_CS_OP_SAMPLER_DESTROY */ wined3d_cs_exec_sampler_destroy, ++ /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource, ++}; + -+ TRACE("device %p, src_volume %p, dst_volume %p.\n", -+ device, src_volume, dst_volume); ++static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) ++{ ++ struct wined3d_cs_queue *queue = prio ? &cs->prio_queue : &cs->queue; ++ size_t queue_size = sizeof(queue->data) / sizeof(*queue->data); + -+ if (src_volume->resource.format != dst_volume->resource.format) ++ if (queue_size - size < queue->head) + { -+ FIXME("Source and destination formats do not match.\n"); -+ return WINED3DERR_INVALIDCALL; ++ struct wined3d_cs_skip *skip; ++ size_t nop_size = queue_size - queue->head; ++ ++ skip = _wined3d_cs_mt_require_space(cs, nop_size, prio); ++ if (nop_size < sizeof(*skip)) ++ { ++ skip->opcode = WINED3D_CS_OP_NOP; ++ } ++ else ++ { ++ skip->opcode = WINED3D_CS_OP_SKIP; ++ skip->size = nop_size; ++ } ++ ++ if (prio) ++ cs->ops->submit_prio(cs, nop_size); ++ else ++ cs->ops->submit(cs, nop_size); ++ ++ assert(!queue->head); + } -+ if (src_volume->resource.width != dst_volume->resource.width -+ || src_volume->resource.height != dst_volume->resource.height -+ || src_volume->resource.depth != dst_volume->resource.depth) ++ ++ while(1) + { -+ FIXME("Source and destination sizes do not match.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } ++ LONG head = queue->head; ++ LONG tail = *((volatile LONG *)&queue->tail); ++ LONG new_pos; ++ /* Empty */ ++ if (head == tail) ++ break; ++ /* Head ahead of tail, take care of wrap-around */ ++ new_pos = (head + size) & (WINED3D_CS_QUEUE_SIZE - 1); ++ if (head > tail && (new_pos || tail)) ++ break; ++ /* Tail ahead of head, but still enough space */ ++ if (new_pos < tail && new_pos) ++ break; + -+ if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY))) -+ return hr; ++ TRACE("Waiting for free space. Head %u, tail %u, want %u\n", head, tail, ++ (unsigned int) size); ++ } + -+ context = context_acquire(device, NULL); ++ return &queue->data[queue->head]; ++} + -+ /* Only a prepare, since we're uploading the entire volume. */ -+ wined3d_texture_prepare_texture(dst_volume->container, context, FALSE); -+ wined3d_texture_bind_and_dirtify(dst_volume->container, context, FALSE); ++static inline void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) ++{ ++ return _wined3d_cs_mt_require_space(cs, size, FALSE); ++} + -+ data.buffer_object = 0; -+ data.addr = src.data; -+ wined3d_volume_upload_data(dst_volume, context, &data); -+ wined3d_volume_invalidate_location(dst_volume, ~WINED3D_LOCATION_TEXTURE_RGB); ++static inline void *wined3d_cs_mt_require_space_prio(struct wined3d_cs *cs, size_t size) ++{ ++ return _wined3d_cs_mt_require_space(cs, size, TRUE); ++} + -+ context_release(context); ++/* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an ++ * OP itself. */ ++static void wined3d_cs_emit_stop(struct wined3d_cs *cs) ++{ ++ struct wined3d_cs_stop *op; + -+ hr = wined3d_volume_unmap(src_volume); ++ op = wined3d_cs_mt_require_space(cs, sizeof(*op)); ++ op->opcode = WINED3D_CS_OP_STOP; + -+ return hr; ++ wined3d_cs_mt_submit(cs, sizeof(*op)); +} + -+HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, -+ struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture) ++static void wined3d_cs_mt_finish(struct wined3d_cs *cs) +{ -+ enum wined3d_resource_type type; -+ unsigned int level_count, i, j, src_size, dst_size, src_skip_levels = 0; -+ HRESULT hr; -+ struct wined3d_context *context; -+ -+ TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture); ++ BOOL fence; + -+ /* Verify that the source and destination textures are non-NULL. */ -+ if (!src_texture || !dst_texture) ++ if (cs->thread_id == GetCurrentThreadId()) + { -+ WARN("Source and destination textures must be non-NULL, returning WINED3DERR_INVALIDCALL.\n"); -+ return WINED3DERR_INVALIDCALL; ++ static BOOL once; ++ if (!once) ++ { ++ FIXME("flush_and_wait called from cs thread\n"); ++ once = TRUE; ++ } ++ return; + } + -+ if (src_texture->resource.pool != WINED3D_POOL_SYSTEM_MEM) -+ { -+ WARN("Source texture not in WINED3D_POOL_SYSTEM_MEM, returning WINED3DERR_INVALIDCALL.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ if (dst_texture->resource.pool != WINED3D_POOL_DEFAULT) -+ { -+ WARN("Destination texture not in WINED3D_POOL_DEFAULT, returning WINED3DERR_INVALIDCALL.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } ++ wined3d_cs_emit_fence(cs, &fence); + -+ /* Verify that the source and destination textures are the same type. */ -+ type = src_texture->resource.type; -+ if (dst_texture->resource.type != type) ++ /* A busy wait should be fine, we're not supposed to have to wait very ++ * long. */ ++ while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); ++} ++ ++static void wined3d_cs_mt_finish_prio(struct wined3d_cs *cs) ++{ ++ BOOL fence; ++ ++ if (cs->thread_id == GetCurrentThreadId()) + { -+ WARN("Source and destination have different types, returning WINED3DERR_INVALIDCALL.\n"); -+ return WINED3DERR_INVALIDCALL; ++ static BOOL once; ++ if (!once) ++ { ++ FIXME("flush_and_wait called from cs thread\n"); ++ once = TRUE; ++ } ++ return; + } -+#endif /* STAGING_CSMT */ - - level_count = min(wined3d_texture_get_level_count(src_texture), - wined3d_texture_get_level_count(dst_texture)); -@@ -3480,7 +3854,13 @@ ++ ++ wined3d_cs_emit_fence_prio(cs, &fence); ++ ++ /* A busy wait should be fine, we're not supposed to have to wait very ++ * long. */ ++ while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); ++} ++ ++static const struct wined3d_cs_ops wined3d_cs_mt_ops = ++{ ++ wined3d_cs_mt_require_space, ++ wined3d_cs_mt_require_space_prio, + wined3d_cs_mt_submit, + wined3d_cs_mt_submit_prio, + wined3d_cs_mt_finish, +@@ -3259,5 +4093,80 @@ + ERR("Closing event failed.\n"); } - /* Make sure that the destination texture is loaded. */ -+#if defined(STAGING_CSMT) -+ wined3d_texture_load(dst_texture, context, FALSE); -+#else /* STAGING_CSMT */ -+ context = context_acquire(device, NULL); - wined3d_texture_load(dst_texture, context, FALSE); -+ context_release(context); -+#endif /* STAGING_CSMT */ - - /* Update every surface level of the texture. */ - switch (type) -@@ -3495,7 +3875,16 @@ - src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, - i + src_skip_levels)); - dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, i)); -+#if defined(STAGING_CSMT) - surface_upload_from_surface(dst_surface, NULL, src_surface, NULL); +#else /* STAGING_CSMT */ -+ hr = wined3d_device_update_surface(device, src_surface, NULL, dst_surface, NULL); -+ if (FAILED(hr)) -+ { -+ WARN("Failed to update surface, hr %#x.\n", hr); -+ return hr; -+ } -+#endif /* STAGING_CSMT */ - } - break; - } -@@ -3515,7 +3904,16 @@ - i * src_levels + j + src_skip_levels)); - dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, - i * dst_levels + j)); -+#if defined(STAGING_CSMT) - surface_upload_from_surface(dst_surface, NULL, src_surface, NULL); -+#else /* STAGING_CSMT */ -+ hr = wined3d_device_update_surface(device, src_surface, NULL, dst_surface, NULL); -+ if (FAILED(hr)) -+ { -+ WARN("Failed to update surface, hr %#x.\n", hr); -+ return hr; -+ } ++}; ++ ++static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) ++{ ++ if (size > cs->data_size) ++ { ++ void *new_data; ++ ++ size = max( size, cs->data_size * 2 ); ++ if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size))) ++ return NULL; ++ ++ cs->data_size = size; ++ cs->data = new_data; ++ } ++ ++ return cs->data; ++} ++ ++static void wined3d_cs_st_submit(struct wined3d_cs *cs) ++{ ++ enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)cs->data; ++ ++ wined3d_cs_op_handlers[opcode](cs, cs->data); ++} ++ ++static const struct wined3d_cs_ops wined3d_cs_st_ops = ++{ ++ wined3d_cs_st_require_space, ++ wined3d_cs_st_submit, ++}; ++ ++struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) ++{ ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++ struct wined3d_cs *cs; ++ ++ if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs)))) ++ return NULL; ++ ++ if (!(cs->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ++ sizeof(*cs->fb.render_targets) * gl_info->limits.buffers))) ++ { ++ HeapFree(GetProcessHeap(), 0, cs); ++ return NULL; ++ } ++ ++ if (FAILED(state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info, ++ WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) ++ { ++ HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); ++ HeapFree(GetProcessHeap(), 0, cs); ++ return NULL; ++ } ++ ++ cs->ops = &wined3d_cs_st_ops; ++ cs->device = device; ++ ++ cs->data_size = WINED3D_INITIAL_CS_SIZE; ++ if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size))) ++ { ++ HeapFree(GetProcessHeap(), 0, cs); ++ return NULL; ++ } ++ ++ return cs; ++} ++ ++void wined3d_cs_destroy(struct wined3d_cs *cs) ++{ ++ state_cleanup(&cs->state); ++ HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); ++ HeapFree(GetProcessHeap(), 0, cs->data); +#endif /* STAGING_CSMT */ - } - } - break; -@@ -3525,6 +3923,7 @@ - { - for (i = 0; i < level_count; ++i) - { -+#if defined(STAGING_CSMT) - device_update_volume(context, - volume_from_resource(wined3d_texture_get_sub_resource(src_texture, - i + src_skip_levels)), -@@ -3578,6 +3977,25 @@ - } + HeapFree(GetProcessHeap(), 0, cs); + } +diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c +--- a/dlls/wined3d/device.c ++++ b/dlls/wined3d/device.c +@@ -198,6 +198,24 @@ + device->contexts = new_array; + } - wined3d_cs_emit_update_texture(device->cs, src_texture, dst_texture); -+#else /* STAGING_CSMT */ -+ hr = device_update_volume(device, -+ volume_from_resource(wined3d_texture_get_sub_resource(src_texture, -+ i + src_skip_levels)), -+ volume_from_resource(wined3d_texture_get_sub_resource(dst_texture, i))); -+ if (FAILED(hr)) -+ { -+ WARN("Failed to update volume, hr %#x.\n", hr); -+ return hr; -+ } -+ } -+ break; -+ } ++#if !defined(STAGING_CSMT) ++void device_switch_onscreen_ds(struct wined3d_device *device, ++ struct wined3d_context *context, struct wined3d_surface *depth_stencil) ++{ ++ if (device->onscreen_depth_stencil) ++ { ++ surface_load_ds_location(device->onscreen_depth_stencil, context, WINED3D_LOCATION_TEXTURE_RGB); + -+ default: -+ FIXME("Unsupported texture type %#x.\n", type); -+ return WINED3DERR_INVALIDCALL; ++ surface_modify_ds_location(device->onscreen_depth_stencil, WINED3D_LOCATION_TEXTURE_RGB, ++ device->onscreen_depth_stencil->ds_current_size.cx, ++ device->onscreen_depth_stencil->ds_current_size.cy); ++ wined3d_texture_decref(device->onscreen_depth_stencil->container); + } ++ device->onscreen_depth_stencil = depth_stencil; ++ wined3d_texture_incref(device->onscreen_depth_stencil->container); ++} ++ +#endif /* STAGING_CSMT */ + static BOOL is_full_clear(const struct wined3d_surface *target, const RECT *draw_rect, const RECT *clear_rect) + { + /* partial draw rect */ +@@ -220,7 +238,11 @@ + { + RECT current_rect, r; - return WINED3D_OK; - } -@@ -3627,8 +4045,13 @@ - if (state->render_states[WINED3D_RS_ZENABLE] || state->render_states[WINED3D_RS_ZWRITEENABLE] - || state->render_states[WINED3D_RS_STENCILENABLE]) - { +#if defined(STAGING_CSMT) - struct wined3d_rendertarget_view *rt = state->fb.render_targets[0]; - struct wined3d_rendertarget_view *ds = state->fb.depth_stencil; + if (ds->resource.locations & WINED3D_LOCATION_DISCARDED) +#else /* STAGING_CSMT */ -+ struct wined3d_rendertarget_view *rt = device->fb.render_targets[0]; -+ struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; ++ if (ds->locations & WINED3D_LOCATION_DISCARDED) +#endif /* STAGING_CSMT */ + { + /* Depth buffer was discarded, make it entirely current in its new location since + * there is no other place where we would get data anyway. */ +@@ -228,7 +250,11 @@ + return; + } - if (ds && rt && (ds->width < rt->width || ds->height < rt->height)) ++#if defined(STAGING_CSMT) + if (ds->resource.locations & location) ++#else /* STAGING_CSMT */ ++ if (ds->locations & location) ++#endif /* STAGING_CSMT */ + SetRect(¤t_rect, 0, 0, + ds->ds_current_size.cx, + ds->ds_current_size.cy); +@@ -308,7 +334,11 @@ + if (rt && rt->resource.format->id != WINED3DFMT_NULL) { -@@ -3727,6 +4150,7 @@ - struct wined3d_surface *src_surface, const RECT *src_rect, - struct wined3d_surface *dst_surface, const POINT *dst_point) - { + if (flags & WINED3DCLEAR_TARGET && !is_full_clear(target, draw_rect, clear_rect)) +#if defined(STAGING_CSMT) - const struct wined3d_format *src_format = src_surface->resource.format; - const struct wined3d_format *dst_format = dst_surface->resource.format; - UINT update_w, update_h; -@@ -3734,6 +4158,7 @@ - RECT r, dst_rect; - POINT p; + wined3d_resource_load_location(&rt->resource, context, rt->container->resource.draw_binding); ++#else /* STAGING_CSMT */ ++ surface_load_location(rt, context, rt->container->resource.draw_binding); ++#endif /* STAGING_CSMT */ + else + wined3d_surface_prepare(rt, context, rt->container->resource.draw_binding); + } +@@ -333,8 +363,13 @@ + { + DWORD location = render_offscreen ? fb->depth_stencil->resource->draw_binding : WINED3D_LOCATION_DRAWABLE; ++#if defined(STAGING_CSMT) + if (!render_offscreen && depth_stencil != device->cs->onscreen_depth_stencil) + wined3d_cs_switch_onscreen_ds(device->cs, context, depth_stencil); ++#else /* STAGING_CSMT */ ++ if (!render_offscreen && depth_stencil != device->onscreen_depth_stencil) ++ device_switch_onscreen_ds(device, context, depth_stencil); +#endif /* STAGING_CSMT */ - TRACE("device %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s.\n", - device, src_surface, wine_dbgstr_rect(src_rect), - dst_surface, wine_dbgstr_point(dst_point)); -@@ -3745,6 +4170,7 @@ - return WINED3DERR_INVALIDCALL; + prepare_ds_clear(depth_stencil, context, location, + draw_rect, rect_count, clear_rect, &ds_rect); } +@@ -382,8 +417,13 @@ + if (rt) + { +#if defined(STAGING_CSMT) - if (src_format->id != dst_format->id) - { - WARN("Source and destination surfaces should have the same format.\n"); -@@ -3809,6 +4235,9 @@ - wined3d_cs_emit_update_surface(device->cs, src_surface, src_rect, dst_surface, dst_point); - - return WINED3D_OK; + wined3d_resource_validate_location(&rt->resource, rt->container->resource.draw_binding); + wined3d_resource_invalidate_location(&rt->resource, ~rt->container->resource.draw_binding); +#else /* STAGING_CSMT */ -+ return surface_upload_from_surface(dst_surface, dst_point, src_surface, src_rect); ++ surface_validate_location(rt, rt->container->resource.draw_binding); ++ surface_invalidate_location(rt, ~rt->container->resource.draw_binding); +#endif /* STAGING_CSMT */ + } + } + +@@ -651,7 +691,11 @@ } - void CDECL wined3d_device_copy_resource(struct wined3d_device *device, -@@ -3963,7 +4392,17 @@ - unsigned int depth_pitch) - { - struct wined3d_resource *sub_resource; + /* Context activation is done by the caller. */ +#if defined(STAGING_CSMT) -+ struct wined3d_texture *texture; + void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) +#else /* STAGING_CSMT */ -+ const struct wined3d_gl_info *gl_info; -+ struct wined3d_const_bo_address addr; -+ struct wined3d_context *context; - struct wined3d_texture *texture; -+ struct wined3d_surface *surface; -+ POINT dst_point; -+ RECT src_rect; ++static void create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) +#endif /* STAGING_CSMT */ + { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + unsigned int i, j, count; +@@ -758,7 +802,11 @@ + } - TRACE("device %p, resource %p, sub_resource_idx %u, box %p, data %p, row_pitch %u, depth_pitch %u.\n", - device, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); -@@ -3980,7 +4419,14 @@ - WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); - return; - } + /* Context activation is done by the caller. */ +#if defined(STAGING_CSMT) -+ + void device_create_default_sampler(struct wined3d_device *device) +#else /* STAGING_CSMT */ -+ surface = surface_from_resource(sub_resource); ++static void create_default_sampler(struct wined3d_device *device) ++#endif /* STAGING_CSMT */ + { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -+ src_rect.left = 0; -+ src_rect.top = 0; +@@ -923,7 +971,11 @@ + BOOL ds_enable = !!swapchain->desc.enable_auto_depth_stencil; + unsigned int i; + ++#if defined(STAGING_CSMT) + if (device->state.fb.render_targets) ++#else /* STAGING_CSMT */ ++ if (device->fb.render_targets) +#endif /* STAGING_CSMT */ - if (box) { - if (box->left >= box->right || box->right > sub_resource->width -@@ -3990,9 +4436,47 @@ - box->left, box->top, box->front, box->right, box->bottom, box->back); - return; - } + for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + { +@@ -941,7 +993,13 @@ + struct wined3d_swapchain_desc *swapchain_desc) + { + static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f}; +#if defined(STAGING_CSMT) - } - - wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); + struct wined3d_swapchain *swapchain = NULL; +#else /* STAGING_CSMT */ -+ -+ src_rect.right = box->right - box->left; -+ src_rect.bottom = box->bottom - box->top; -+ dst_point.x = box->left; -+ dst_point.y = box->top; -+ } -+ else -+ { -+ src_rect.right = sub_resource->width; -+ src_rect.bottom = sub_resource->height; -+ dst_point.x = 0; -+ dst_point.y = 0; -+ } -+ -+ addr.buffer_object = 0; -+ addr.addr = data; -+ -+ context = context_acquire(resource->device, NULL); -+ gl_info = context->gl_info; -+ -+ /* Only load the surface for partial updates. */ -+ if (!dst_point.x && !dst_point.y && src_rect.right == sub_resource->width -+ && src_rect.bottom == sub_resource->height) -+ wined3d_texture_prepare_texture(texture, context, FALSE); -+ else -+ surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB); -+ wined3d_texture_bind_and_dirtify(texture, context, FALSE); -+ -+ wined3d_surface_upload_data(surface, gl_info, resource->format, -+ &src_rect, row_pitch, &dst_point, FALSE, &addr); -+ -+ context_release(context); -+ -+ surface_validate_location(surface, WINED3D_LOCATION_TEXTURE_RGB); -+ surface_invalidate_location(surface, ~WINED3D_LOCATION_TEXTURE_RGB); ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++ struct wined3d_swapchain *swapchain = NULL; ++ struct wined3d_context *context; +#endif /* STAGING_CSMT */ - } + DWORD clear_flags = 0; + HRESULT hr; - HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device, -@@ -4023,8 +4507,14 @@ - rect = &r; - } +@@ -952,6 +1010,11 @@ + if (device->wined3d->flags & WINED3D_NO3D) + return WINED3DERR_INVALIDCALL; -+#if defined(STAGING_CSMT) - wined3d_cs_emit_clear_rtv(device->cs, view, rect, color); - return WINED3D_OK; -+#else /* STAGING_CSMT */ -+ resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), view->sub_resource_idx); ++#if !defined(STAGING_CSMT) ++ device->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ++ sizeof(*device->fb.render_targets) * gl_info->limits.buffers); + -+ return surface_color_fill(surface_from_resource(resource), rect, color); +#endif /* STAGING_CSMT */ - } - - struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(const struct wined3d_device *device, -@@ -4038,6 +4528,7 @@ - return NULL; - } + if (FAILED(hr = device->shader_backend->shader_alloc_private(device, + device->adapter->vertex_pipe, device->adapter->fragment_pipe))) + { +@@ -1000,8 +1063,16 @@ + device->swapchains[0] = swapchain; + device_init_swapchain_state(device, swapchain); +#if defined(STAGING_CSMT) - return device->state.fb.render_targets[view_idx]; - } - -@@ -4053,6 +4544,22 @@ - { - struct wined3d_rendertarget_view *prev; - struct wined3d_fb_state *fb = &device->state.fb; + /* also calls create_default_sampler */ + wined3d_cs_emit_create_dummy_textures(device->cs); +#else /* STAGING_CSMT */ -+ return device->fb.render_targets[view_idx]; -+} -+ -+struct wined3d_rendertarget_view * CDECL wined3d_device_get_depth_stencil_view(const struct wined3d_device *device) -+{ -+ TRACE("device %p.\n", device); -+ -+ return device->fb.depth_stencil; -+} ++ context = context_acquire(device, ++ surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0))); + -+HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device, -+ unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport) -+{ -+ struct wined3d_rendertarget_view *prev; ++ create_dummy_textures(device, context); ++ create_default_sampler(device); +#endif /* STAGING_CSMT */ - TRACE("device %p, view_idx %u, view %p, set_viewport %#x.\n", - device, view_idx, view, set_viewport); -@@ -4092,6 +4599,7 @@ - } + device->contexts[0]->last_was_rhw = 0; +@@ -1013,7 +1084,11 @@ + case ORM_BACKBUFFER: + { +#if defined(STAGING_CSMT) - prev = fb->render_targets[view_idx]; - if (view == prev) - return WINED3D_OK; -@@ -4099,6 +4607,15 @@ - if (view) - wined3d_rendertarget_view_incref(view); - fb->render_targets[view_idx] = view; + if (device->contexts[0]->aux_buffers > 0) ++#else /* STAGING_CSMT */ ++ if (context_get_current()->aux_buffers > 0) ++#endif /* STAGING_CSMT */ + { + TRACE("Using auxiliary buffer for offscreen rendering\n"); + device->offscreenBuffer = GL_AUX0; +@@ -1025,9 +1100,16 @@ + } + } + } ++#if defined(STAGING_CSMT) + device->contexts[0]->offscreenBuffer = device->offscreenBuffer; + + TRACE("All defaults now set up, leaving 3D init.\n"); +#else /* STAGING_CSMT */ -+ prev = device->fb.render_targets[view_idx]; -+ if (view == prev) -+ return WINED3D_OK; + -+ if (view) -+ wined3d_rendertarget_view_incref(view); -+ device->fb.render_targets[view_idx] = view; ++ TRACE("All defaults now set up, leaving 3D init.\n"); ++ ++ context_release(context); +#endif /* STAGING_CSMT */ - wined3d_cs_emit_set_rendertarget_view(device->cs, view_idx, view); - /* Release after the assignment, to prevent device_resource_released() - * from seeing the surface as still in use. */ -@@ -4110,6 +4627,7 @@ - void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view) + /* Clear the screen */ + if (swapchain->back_buffers && swapchain->back_buffers[0]) +@@ -1044,6 +1126,9 @@ + return WINED3D_OK; + + err_out: ++#if !defined(STAGING_CSMT) ++ HeapFree(GetProcessHeap(), 0, device->fb.render_targets); ++#endif /* STAGING_CSMT */ + HeapFree(GetProcessHeap(), 0, device->swapchains); + device->swapchain_count = 0; + if (device->back_buffer_view) +@@ -1101,6 +1186,10 @@ + HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) { + struct wined3d_resource *resource, *cursor; ++#if !defined(STAGING_CSMT) ++ const struct wined3d_gl_info *gl_info; ++ struct wined3d_context *context; ++#endif /* STAGING_CSMT */ + struct wined3d_surface *surface; + UINT i; + +@@ -1109,6 +1198,7 @@ + if (!device->d3d_initialized) + return WINED3DERR_INVALIDCALL; + +#if defined(STAGING_CSMT) - struct wined3d_fb_state *fb = &device->state.fb; - struct wined3d_rendertarget_view *prev; + if (wined3d_settings.cs_multithreaded) + device->cs->ops->finish(device->cs); + +@@ -1147,6 +1237,83 @@ + /* FIXME: Is this in the right place??? */ + wined3d_cs_emit_delete_opengl_contexts(device->cs, device->swapchains[0]); -@@ -4127,6 +4645,66 @@ - wined3d_cs_emit_set_depth_stencil_view(device->cs, view); - if (prev) - wined3d_rendertarget_view_decref(prev); +#else /* STAGING_CSMT */ -+ struct wined3d_rendertarget_view *prev; ++ /* I don't think that the interface guarantees that the device is destroyed from the same thread ++ * it was created. Thus make sure a context is active for the glDelete* calls ++ */ ++ context = context_acquire(device, NULL); ++ gl_info = context->gl_info; + -+ TRACE("device %p, view %p.\n", device, view); ++ if (device->logo_texture) ++ wined3d_texture_decref(device->logo_texture); ++ if (device->cursor_texture) ++ wined3d_texture_decref(device->cursor_texture); + -+ prev = device->fb.depth_stencil; -+ if (prev == view) ++ state_unbind_resources(&device->state); ++ ++ /* Unload resources */ ++ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) + { -+ TRACE("Trying to do a NOP SetRenderTarget operation.\n"); -+ return; -+ } ++ TRACE("Unloading resource %p.\n", resource); + -+ if ((device->fb.depth_stencil = view)) -+ wined3d_rendertarget_view_incref(view); -+ wined3d_cs_emit_set_depth_stencil_view(device->cs, view); -+ if (prev) -+ wined3d_rendertarget_view_decref(prev); -+} ++ resource->resource_ops->resource_unload(resource); ++ } + -+static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined3d_device *device, -+ struct wined3d_surface *cursor_image) -+{ -+ struct wined3d_sub_resource_data data; -+ struct wined3d_resource_desc desc; -+ struct wined3d_map_desc map_desc; -+ struct wined3d_texture *texture; -+ HRESULT hr; ++ wine_rb_clear(&device->samplers, device_free_sampler, NULL); + -+ if (FAILED(wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_READONLY))) ++ /* Destroy the depth blt resources, they will be invalid after the reset. Also free shader ++ * private data, it might contain opengl pointers ++ */ ++ if (device->depth_blt_texture) + { -+ ERR("Failed to map source surface.\n"); -+ return NULL; ++ gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->depth_blt_texture); ++ device->depth_blt_texture = 0; + } + -+ data.data = map_desc.data; -+ data.row_pitch = map_desc.row_pitch; -+ data.slice_pitch = map_desc.slice_pitch; ++ /* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */ ++ device->blitter->free_private(device); ++ device->shader_backend->shader_free_private(device); ++ destroy_dummy_textures(device, gl_info); ++ destroy_default_sampler(device); + -+ desc.resource_type = WINED3D_RTYPE_TEXTURE; -+ desc.format = WINED3DFMT_B8G8R8A8_UNORM; -+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE; -+ desc.multisample_quality = 0; -+ desc.usage = WINED3DUSAGE_DYNAMIC; -+ desc.pool = WINED3D_POOL_DEFAULT; -+ desc.width = cursor_image->resource.width; -+ desc.height = cursor_image->resource.height; -+ desc.depth = 1; -+ desc.size = 0; ++ /* Release the context again as soon as possible. In particular, ++ * releasing the render target views below may release the last reference ++ * to the swapchain associated with this context, which in turn will ++ * destroy the context. */ ++ context_release(context); + -+ hr = wined3d_texture_create(device, &desc, 1, WINED3D_SURFACE_MAPPABLE, -+ &data, NULL, &wined3d_null_parent_ops, &texture); -+ wined3d_surface_unmap(cursor_image); -+ if (FAILED(hr)) ++ /* Release the buffers (with sanity checks)*/ ++ if (device->onscreen_depth_stencil) + { -+ ERR("Failed to create cursor texture.\n"); -+ return NULL; ++ surface = device->onscreen_depth_stencil; ++ device->onscreen_depth_stencil = NULL; ++ wined3d_texture_decref(surface->container); + } + -+ return texture; -+#endif /* STAGING_CSMT */ - } - - HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device, -@@ -4147,6 +4725,14 @@ - - cursor_image = surface_from_resource(sub_resource); - -+#if !defined(STAGING_CSMT) -+ if (device->cursor_texture) ++ if (device->fb.depth_stencil) + { -+ wined3d_texture_decref(device->cursor_texture); -+ device->cursor_texture = NULL; ++ struct wined3d_rendertarget_view *view = device->fb.depth_stencil; ++ ++ TRACE("Releasing depth/stencil view %p.\n", view); ++ ++ device->fb.depth_stencil = NULL; ++ wined3d_rendertarget_view_decref(view); ++ } ++ ++ if (device->auto_depth_stencil_view) ++ { ++ struct wined3d_rendertarget_view *view = device->auto_depth_stencil_view; ++ ++ device->auto_depth_stencil_view = NULL; ++ if (wined3d_rendertarget_view_decref(view)) ++ ERR("Something's still holding the auto depth/stencil view (%p).\n", view); + } + ++ for (i = 0; i < gl_info->limits.buffers; ++i) ++ { ++ wined3d_device_set_rendertarget_view(device, i, NULL, FALSE); ++ } +#endif /* STAGING_CSMT */ - if (cursor_image->resource.format->id != WINED3DFMT_B8G8R8A8_UNORM) + if (device->back_buffer_view) { - WARN("Surface %p has an invalid format %s.\n", -@@ -4174,6 +4760,13 @@ - * release it after setting the cursor image. Windows doesn't - * addref the set surface, so we can't do this either without - * creating circular refcount dependencies. */ + wined3d_rendertarget_view_decref(device->back_buffer_view); +@@ -1164,6 +1331,11 @@ + device->swapchains = NULL; + device->swapchain_count = 0; + +#if !defined(STAGING_CSMT) -+ if (!(device->cursor_texture = wined3d_device_create_cursor_texture(device, cursor_image))) -+ { -+ ERR("Failed to create cursor texture.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } ++ HeapFree(GetProcessHeap(), 0, device->fb.render_targets); ++ device->fb.render_targets = NULL; ++ +#endif /* STAGING_CSMT */ + device->d3d_initialized = FALSE; + + return WINED3D_OK; +@@ -1550,6 +1722,16 @@ + TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", + light->range, light->falloff, light->theta, light->phi); - if (cursor_image->resource.width == 32 && cursor_image->resource.height == 32) - { -@@ -4278,6 +4871,12 @@ - else - SetCursor(NULL); - } +#if !defined(STAGING_CSMT) -+ else if (device->cursor_texture) ++ /* Update the live definitions if the light is currently assigned a glIndex. */ ++ if (object->glIndex != -1 && !device->recording) + { -+ device->bCursorVisible = show; ++ if (object->OriginalParms.type != light->type) ++ device_invalidate_state(device, STATE_LIGHT_TYPE); ++ device_invalidate_state(device, STATE_ACTIVELIGHT(object->glIndex)); + } ++ +#endif /* STAGING_CSMT */ + /* Save away the information. */ + object->OriginalParms = *light; - return oldVisible; - } -@@ -4288,8 +4887,10 @@ - - TRACE("device %p.\n", device); +@@ -1629,9 +1811,11 @@ + FIXME("Unrecognized light type %#x.\n", light->type); + } +#if defined(STAGING_CSMT) - /* The resource list is manged by the main thread, iterate here and emit commands for - * each resource */ + if (!device->recording) + wined3d_cs_emit_set_light(device->cs, object); + +#endif /* STAGING_CSMT */ - LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) + return WINED3D_OK; + } + +@@ -1704,6 +1888,14 @@ { - TRACE("Checking resource %p for eviction.\n", resource); -@@ -4297,6 +4898,7 @@ - if (resource->pool == WINED3D_POOL_MANAGED && !resource->map_count) + if (light_info->glIndex != -1) { - TRACE("Evicting %p.\n", resource); ++#if !defined(STAGING_CSMT) ++ if (!device->recording) ++ { ++ device_invalidate_state(device, STATE_LIGHT_TYPE); ++ device_invalidate_state(device, STATE_ACTIVELIGHT(light_info->glIndex)); ++ } ++ ++#endif /* STAGING_CSMT */ + device->update_state->lights[light_info->glIndex] = NULL; + light_info->glIndex = -1; + } +@@ -1745,11 +1937,23 @@ + WARN("Too many concurrently active lights\n"); + return WINED3D_OK; + } +#if defined(STAGING_CSMT) - wined3d_cs_emit_evict_resource(device->cs, resource); } } -@@ -4315,6 +4917,37 @@ - context = context_acquire(device, NULL); - gl_info = context->gl_info; + if (!device->recording) + wined3d_cs_emit_set_light_enable(device->cs, light_idx, enable); +#else /* STAGING_CSMT */ -+ resource->resource_ops->resource_unload(resource); -+ } -+ } -+ -+ /* Invalidate stream sources, the buffer(s) may have been evicted. */ -+ device_invalidate_state(device, STATE_STREAMSRC); -+} -+ -+static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) -+{ -+ struct wined3d_resource *resource, *cursor; -+ const struct wined3d_gl_info *gl_info; -+ struct wined3d_context *context; -+ struct wined3d_shader *shader; -+ -+ context = context_acquire(device, NULL); -+ gl_info = context->gl_info; -+ -+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) -+ { -+ TRACE("Unloading resource %p.\n", resource); -+ -+ resource->resource_ops->resource_unload(resource); -+ } + -+ LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry) -+ { -+ device->shader_backend->shader_destroy(shader); ++ /* i == light_info->glIndex */ ++ if (!device->recording) ++ { ++ device_invalidate_state(device, STATE_LIGHT_TYPE); ++ device_invalidate_state(device, STATE_ACTIVELIGHT(i)); ++ } ++ } + } +#endif /* STAGING_CSMT */ - if (device->depth_blt_texture) - { -@@ -4335,6 +4968,7 @@ + return WINED3D_OK; + } +@@ -1924,9 +2128,11 @@ + TRACE("device %p, base_index %d.\n", device, base_index); - HeapFree(GetProcessHeap(), 0, swapchain->context); - swapchain->context = NULL; + device->update_state->base_vertex_index = base_index; +#if defined(STAGING_CSMT) - swapchain->num_contexts = 0; + + if (!device->recording) + wined3d_cs_emit_set_base_vertex_index(device->cs, base_index); ++#endif /* STAGING_CSMT */ } -@@ -4354,6 +4988,14 @@ + INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *device) +@@ -1972,7 +2178,11 @@ + || !(texture->resource.format_flags & WINED3DFMT_FLAG_DEPTH)) + return; + surface = surface_from_resource(texture->sub_resources[0]); ++#if defined(STAGING_CSMT) + if (!(depth_stencil = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil))) ++#else /* STAGING_CSMT */ ++ if (!(depth_stencil = wined3d_rendertarget_view_get_surface(state->fb->depth_stencil))) ++#endif /* STAGING_CSMT */ + return; - static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain) - { + SetRect(&dst_rect, 0, 0, surface->resource.width, surface->resource.height); +@@ -2301,7 +2511,11 @@ + return device->state.sampler[WINED3D_SHADER_TYPE_VERTEX][idx]; + } + ++#if defined(STAGING_CSMT) + void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) +#else /* STAGING_CSMT */ -+} -+ -+static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain) -+{ -+ struct wined3d_context *context; -+ struct wined3d_surface *target; ++static void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) +#endif /* STAGING_CSMT */ - HRESULT hr; + { + UINT i; - if (FAILED(hr = device->shader_backend->shader_alloc_private(device, -@@ -4370,6 +5012,7 @@ - return hr; +@@ -2334,8 +2548,12 @@ } - + else + { +#if defined(STAGING_CSMT) - hr = wined3d_cs_emit_create_swapchain_context(device->cs, swapchain); - if (FAILED(hr)) + wined3d_cs_emit_set_consts_b(device->cs, start_register, constants, + bool_count, WINED3D_SHADER_TYPE_VERTEX); ++#else /* STAGING_CSMT */ ++ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_B); ++#endif /* STAGING_CSMT */ + } + + return WINED3D_OK; +@@ -2382,8 +2600,12 @@ + } + else { -@@ -4380,6 +5023,34 @@ ++#if defined(STAGING_CSMT) + wined3d_cs_emit_set_consts_i(device->cs, start_register, constants, + vector4i_count, WINED3D_SHADER_TYPE_VERTEX); ++#else /* STAGING_CSMT */ ++ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_I); ++#endif /* STAGING_CSMT */ } - wined3d_cs_emit_create_dummy_textures(device->cs); + return WINED3D_OK; +@@ -2434,8 +2656,13 @@ + memset(device->recording->changed.vertexShaderConstantsF + start_register, 1, + sizeof(*device->recording->changed.vertexShaderConstantsF) * vector4f_count); + else ++#if defined(STAGING_CSMT) + wined3d_cs_emit_set_consts_f(device->cs, start_register, constants, vector4f_count, + WINED3D_SHADER_TYPE_VERTEX); +#else /* STAGING_CSMT */ -+ /* Recreate the primary swapchain's context */ -+ swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); -+ if (!swapchain->context) -+ { -+ ERR("Failed to allocate memory for swapchain context array.\n"); -+ device->blitter->free_private(device); -+ device->shader_backend->shader_free_private(device); -+ return E_OUTOFMEMORY; -+ } -+ -+ target = swapchain->back_buffers -+ ? surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)) -+ : surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); -+ if (!(context = context_create(swapchain, target, swapchain->ds_format))) -+ { -+ WARN("Failed to create context.\n"); -+ device->blitter->free_private(device); -+ device->shader_backend->shader_free_private(device); -+ HeapFree(GetProcessHeap(), 0, swapchain->context); -+ return E_FAIL; -+ } ++ device->shader_backend->shader_update_float_vertex_constants(device, start_register, vector4f_count); + -+ swapchain->context[0] = context; -+ swapchain->num_contexts = 1; -+ create_dummy_textures(device, context); -+ context_release(context); +#endif /* STAGING_CSMT */ return WINED3D_OK; } -@@ -4398,9 +5069,11 @@ - TRACE("device %p, swapchain_desc %p, mode %p, callback %p, reset_state %#x.\n", - device, swapchain_desc, mode, callback, reset_state); - -+#if defined(STAGING_CSMT) - wined3d_cs_emit_glfinish(device->cs); - device->cs->ops->finish(device->cs); - -+#endif /* STAGING_CSMT */ - if (!(swapchain = wined3d_device_get_swapchain(device, 0))) +@@ -2570,8 +2797,12 @@ + } + else { - ERR("Failed to get the first implicit swapchain.\n"); -@@ -4415,9 +5088,21 @@ - wined3d_texture_decref(device->logo_texture); - device->logo_texture = NULL; - } +#if defined(STAGING_CSMT) + wined3d_cs_emit_set_consts_b(device->cs, start_register, constants, + bool_count, WINED3D_SHADER_TYPE_PIXEL); ++#else /* STAGING_CSMT */ ++ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_B); ++#endif /* STAGING_CSMT */ } - if (device->state.fb.render_targets) -+#else /* STAGING_CSMT */ -+ if (device->cursor_texture) -+ { -+ wined3d_texture_decref(device->cursor_texture); -+ device->cursor_texture = NULL; -+ } -+ state_unbind_resources(&device->state); -+ } -+ -+ if (device->fb.render_targets) -+#endif /* STAGING_CSMT */ + return WINED3D_OK; +@@ -2618,8 +2849,12 @@ + } + else { - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) - { -@@ -4426,6 +5111,7 @@ ++#if defined(STAGING_CSMT) + wined3d_cs_emit_set_consts_i(device->cs, start_register, constants, + vector4i_count, WINED3D_SHADER_TYPE_PIXEL); ++#else /* STAGING_CSMT */ ++ device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_I); ++#endif /* STAGING_CSMT */ } - wined3d_device_set_depth_stencil_view(device, NULL); + return WINED3D_OK; +@@ -2671,8 +2906,12 @@ + memset(device->recording->changed.pixelShaderConstantsF + start_register, 1, + sizeof(*device->recording->changed.pixelShaderConstantsF) * vector4f_count); + else +#if defined(STAGING_CSMT) - if (reset_state) - { - state_unbind_resources(&device->state); -@@ -4435,6 +5121,12 @@ - { - wined3d_texture_decref(device->cs->onscreen_depth_stencil->container); - device->cs->onscreen_depth_stencil = NULL; + wined3d_cs_emit_set_consts_f(device->cs, start_register, constants, vector4f_count, + WINED3D_SHADER_TYPE_PIXEL); +#else /* STAGING_CSMT */ -+ if (device->onscreen_depth_stencil) -+ { -+ wined3d_texture_decref(device->onscreen_depth_stencil->container); -+ device->onscreen_depth_stencil = NULL; ++ device->shader_backend->shader_update_float_pixel_constants(device, start_register, vector4f_count); +#endif /* STAGING_CSMT */ - } - if (reset_state) -@@ -4447,6 +5139,7 @@ - } + return WINED3D_OK; + } +@@ -2832,6 +3071,7 @@ + return hr; } +#if defined(STAGING_CSMT) - /* Free implicit resources and wait for the command stream before modifying - * swapchain parameters. After modifying the swapchain parameters a new GL - * context may be acquired by the worker thread. This causes problems in the -@@ -4468,6 +5161,7 @@ + if (wined3d_settings.cs_multithreaded) + { + FIXME("Waiting for cs.\n"); +@@ -2839,6 +3079,7 @@ + device->cs->ops->finish(device->cs); } - device->cs->ops->finish(device->cs); +#endif /* STAGING_CSMT */ - TRACE("New params:\n"); - TRACE("backbuffer_width %u\n", swapchain_desc->backbuffer_width); - TRACE("backbuffer_height %u\n", swapchain_desc->backbuffer_height); -@@ -4594,6 +5288,13 @@ - swapchain_desc->multisample_type, swapchain_desc->multisample_quality))) - return hr; + wined3d_device_get_transform(device, WINED3D_TS_VIEW, &view_mat); + wined3d_device_get_transform(device, WINED3D_TS_PROJECTION, &proj_mat); + wined3d_device_get_transform(device, WINED3D_TS_WORLD_MATRIX(0), &world_mat); +@@ -3324,6 +3565,10 @@ + HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device) + { +#if !defined(STAGING_CSMT) -+ if (device->auto_depth_stencil_view) -+ { -+ wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); -+ device->auto_depth_stencil_view = NULL; -+ } ++ struct wined3d_context *context; ++ +#endif /* STAGING_CSMT */ - if (swapchain->desc.enable_auto_depth_stencil) - { - struct wined3d_resource_desc texture_desc; -@@ -4636,6 +5337,13 @@ - wined3d_device_set_depth_stencil_view(device, device->auto_depth_stencil_view); + TRACE("device %p.\n", device); + + if (!device->inScene) +@@ -3332,6 +3577,15 @@ + return WINED3DERR_INVALIDCALL; } +#if !defined(STAGING_CSMT) -+ if (device->back_buffer_view) -+ { -+ wined3d_rendertarget_view_decref(device->back_buffer_view); -+ device->back_buffer_view = NULL; -+ } ++ context = context_acquire(device, NULL); ++ /* We only have to do this if we need to read the, swapbuffers performs a flush for us */ ++ context->gl_info->gl_ops.gl.p_glFlush(); ++ /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever ++ * fails. */ ++ context_release(context); ++ +#endif /* STAGING_CSMT */ - if (swapchain->desc.backbuffer_count && FAILED(hr = wined3d_rendertarget_view_create_from_surface( - surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)), - NULL, &wined3d_null_parent_ops, &device->back_buffer_view))) -@@ -4656,12 +5364,20 @@ - } - wined3d_cs_emit_reset_state(device->cs); - state_cleanup(&device->state); + device->inScene = FALSE; + return WINED3D_OK; + } +@@ -3339,8 +3593,10 @@ + HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, + const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) + { +#if defined(STAGING_CSMT) - memset(&device->state, 0, sizeof(device->state)); - - if (device->d3d_initialized) - delete_opengl_contexts(device, swapchain); + const struct wined3d_fb_state *fb = &device->state.fb; - if (FAILED(hr = state_init(&device->state, &device->adapter->gl_info, -+#else /* STAGING_CSMT */ -+ -+ if (device->d3d_initialized) -+ delete_opengl_contexts(device, swapchain); -+ -+ if (FAILED(hr = state_init(&device->state, &device->fb, &device->adapter->gl_info, +#endif /* STAGING_CSMT */ - &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) - ERR("Failed to initialize device state, hr %#x.\n", hr); - device->update_state = &device->state; -@@ -4670,6 +5386,7 @@ + TRACE("device %p, rect_count %u, rects %p, flags %#x, color {%.8e, %.8e, %.8e, %.8e}, depth %.8e, stencil %u.\n", + device, rect_count, rects, flags, color->r, color->g, color->b, color->a, depth, stencil); + +@@ -3349,12 +3605,19 @@ + WARN("Rects is %p, but rect_count is 0, ignoring clear\n", rects); + return WINED3D_OK; } - else if (device->back_buffer_view) - { +#if defined(STAGING_CSMT) - struct wined3d_state *state = &device->state; + if (rect_count && !rects) + rect_count = 0; - wined3d_device_set_rendertarget_view(device, 0, device->back_buffer_view, FALSE); -@@ -4685,6 +5402,24 @@ - state->scissor_rect.left = 0; - state->scissor_rect.right = swapchain->desc.backbuffer_width; - state->scissor_rect.bottom = swapchain->desc.backbuffer_height; + if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) + { + struct wined3d_rendertarget_view *ds = fb->depth_stencil; +#else /* STAGING_CSMT */ -+ struct wined3d_rendertarget_view *view = device->back_buffer_view; -+ struct wined3d_state *state = &device->state; -+ -+ wined3d_device_set_rendertarget_view(device, 0, view, FALSE); + -+ /* Note the min_z / max_z is not reset. */ -+ state->viewport.x = 0; -+ state->viewport.y = 0; -+ state->viewport.width = view->width; -+ state->viewport.height = view->height; -+ wined3d_cs_emit_set_viewport(device->cs, &state->viewport); ++ if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) ++ { ++ struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; ++#endif /* STAGING_CSMT */ + if (!ds) + { + WARN("Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL\n"); +@@ -3363,8 +3626,13 @@ + } + else if (flags & WINED3DCLEAR_TARGET) + { ++#if defined(STAGING_CSMT) + if (ds->width < fb->render_targets[0]->width + || ds->height < fb->render_targets[0]->height) ++#else /* STAGING_CSMT */ ++ if (ds->width < device->fb.render_targets[0]->width ++ || ds->height < device->fb.render_targets[0]->height) ++#endif /* STAGING_CSMT */ + { + WARN("Silently ignoring depth and target clear with mismatching sizes\n"); + return WINED3D_OK; +@@ -3410,6 +3678,9 @@ + enum wined3d_primitive_type primitive_type) + { + GLenum gl_primitive_type, prev; ++#if !defined(STAGING_CSMT) + -+ state->scissor_rect.top = 0; -+ state->scissor_rect.left = 0; -+ state->scissor_rect.right = view->width; -+ state->scissor_rect.bottom = view->height; +#endif /* STAGING_CSMT */ - wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); - } + TRACE("device %p, primitive_type %s\n", device, debug_d3dprimitivetype(primitive_type)); -@@ -4760,6 +5495,10 @@ + gl_primitive_type = gl_primitive_type_from_d3d(primitive_type); +@@ -3417,8 +3688,13 @@ + device->update_state->gl_primitive_type = gl_primitive_type; + if (device->recording) + device->recording->changed.primitive_type = TRUE; ++#if defined(STAGING_CSMT) + else if (gl_primitive_type != prev) + wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type); ++#else /* STAGING_CSMT */ ++ else if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS)) ++ device_invalidate_state(device, STATE_POINT_ENABLE); ++#endif /* STAGING_CSMT */ + } - TRACE("device %p, resource %p, type %s.\n", device, resource, debug_d3dresourcetype(type)); + void CDECL wined3d_device_get_primitive_type(const struct wined3d_device *device, +@@ -3441,6 +3717,14 @@ + return WINED3DERR_INVALIDCALL; + } +#if !defined(STAGING_CSMT) -+ context_resource_released(device, resource, type); ++ if (device->state.load_base_vertex_index) ++ { ++ device->state.load_base_vertex_index = 0; ++ device_invalidate_state(device, STATE_BASEVERTEXINDEX); ++ } + +#endif /* STAGING_CSMT */ - switch (type) - { - case WINED3D_RTYPE_SURFACE: -@@ -4770,6 +5509,7 @@ + wined3d_cs_emit_draw(device->cs, start_vertex, vertex_count, 0, 0, FALSE); - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) - { -+#if defined(STAGING_CSMT) - if (wined3d_rendertarget_view_get_surface(device->state.fb.render_targets[i]) == surface) - { - ERR("Surface %p is still in use as render target %u.\n", surface, i); -@@ -4781,6 +5521,19 @@ - { - ERR("Surface %p is still in use as depth/stencil buffer.\n", surface); - device->state.fb.depth_stencil = NULL; -+#else /* STAGING_CSMT */ -+ if (wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]) == surface) -+ { -+ ERR("Surface %p is still in use as render target %u.\n", surface, i); -+ device->fb.render_targets[i] = NULL; -+ } -+ } + return WINED3D_OK; +@@ -3457,6 +3741,10 @@ + + HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count) + { ++#if !defined(STAGING_CSMT) ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + -+ if (wined3d_rendertarget_view_get_surface(device->fb.depth_stencil) == surface) -+ { -+ ERR("Surface %p is still in use as depth/stencil buffer.\n", surface); -+ device->fb.depth_stencil = NULL; +#endif /* STAGING_CSMT */ - } - } - break; -@@ -4943,7 +5696,11 @@ + TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count); - device->blitter = adapter->blitter; + if (!device->state.index_buffer) +@@ -3475,6 +3763,15 @@ + return WINED3DERR_INVALIDCALL; + } -+#if defined(STAGING_CSMT) - if (FAILED(hr = state_init(&device->state, &adapter->gl_info, -+#else /* STAGING_CSMT */ -+ if (FAILED(hr = state_init(&device->state, &device->fb, &adapter->gl_info, ++#if !defined(STAGING_CSMT) ++ if (!gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] && ++ device->state.load_base_vertex_index != device->state.base_vertex_index) ++ { ++ device->state.load_base_vertex_index = device->state.base_vertex_index; ++ device_invalidate_state(device, STATE_BASEVERTEXINDEX); ++ } ++ +#endif /* STAGING_CSMT */ - &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) - { - ERR("Failed to initialize device state, hr %#x.\n", hr); -@@ -5042,6 +5799,7 @@ - else - return CallWindowProcA(proc, window, message, wparam, lparam); + wined3d_cs_emit_draw(device->cs, start_idx, index_count, 0, 0, TRUE); + + return WINED3D_OK; +@@ -3490,6 +3787,7 @@ } + + /* This is a helper function for UpdateTexture, there is no UpdateVolume method in D3D. */ +#if defined(STAGING_CSMT) + static void device_update_volume(struct wined3d_context *context, + struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) + { +@@ -3529,6 +3827,97 @@ + enum wined3d_resource_type type = src_texture->resource.type; - /* Context activation is done by the caller */ - struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage, -@@ -5095,3 +5853,4 @@ - - wined3d_device_destroy_bo(device, context, bo); - } + layer_count = src_texture->layer_count; ++#else /* STAGING_CSMT */ ++static HRESULT device_update_volume(struct wined3d_device *device, ++ struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume) ++{ ++ struct wined3d_const_bo_address data; ++ struct wined3d_map_desc src; ++ HRESULT hr; ++ struct wined3d_context *context; ++ ++ TRACE("device %p, src_volume %p, dst_volume %p.\n", ++ device, src_volume, dst_volume); ++ ++ if (src_volume->resource.format != dst_volume->resource.format) ++ { ++ FIXME("Source and destination formats do not match.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ if (src_volume->resource.width != dst_volume->resource.width ++ || src_volume->resource.height != dst_volume->resource.height ++ || src_volume->resource.depth != dst_volume->resource.depth) ++ { ++ FIXME("Source and destination sizes do not match.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY))) ++ return hr; ++ ++ context = context_acquire(device, NULL); ++ ++ /* Only a prepare, since we're uploading the entire volume. */ ++ wined3d_texture_prepare_texture(dst_volume->container, context, FALSE); ++ wined3d_texture_bind_and_dirtify(dst_volume->container, context, FALSE); ++ ++ data.buffer_object = 0; ++ data.addr = src.data; ++ wined3d_volume_upload_data(dst_volume, context, &data); ++ wined3d_volume_invalidate_location(dst_volume, ~WINED3D_LOCATION_TEXTURE_RGB); ++ ++ context_release(context); ++ ++ hr = wined3d_volume_unmap(src_volume); ++ ++ return hr; ++} ++ ++HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, ++ struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture) ++{ ++ unsigned int src_size, dst_size, src_skip_levels = 0; ++ unsigned int layer_count, level_count, i, j; ++ enum wined3d_resource_type type; ++ HRESULT hr; ++ struct wined3d_context *context; ++ ++ TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture); ++ ++ /* Verify that the source and destination textures are non-NULL. */ ++ if (!src_texture || !dst_texture) ++ { ++ WARN("Source and destination textures must be non-NULL, returning WINED3DERR_INVALIDCALL.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ if (src_texture->resource.pool != WINED3D_POOL_SYSTEM_MEM) ++ { ++ WARN("Source texture not in WINED3D_POOL_SYSTEM_MEM, returning WINED3DERR_INVALIDCALL.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ if (dst_texture->resource.pool != WINED3D_POOL_DEFAULT) ++ { ++ WARN("Destination texture not in WINED3D_POOL_DEFAULT, returning WINED3DERR_INVALIDCALL.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ /* Verify that the source and destination textures are the same type. */ ++ type = src_texture->resource.type; ++ if (dst_texture->resource.type != type) ++ { ++ WARN("Source and destination have different types, returning WINED3DERR_INVALIDCALL.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ ++ layer_count = src_texture->layer_count; ++ if (layer_count != dst_texture->layer_count) ++ { ++ WARN("Source and destination have different layer counts.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ +#endif /* STAGING_CSMT */ -diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c ---- a/dlls/wined3d/glsl_shader.c -+++ b/dlls/wined3d/glsl_shader.c -@@ -1622,9 +1622,17 @@ - const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv) - { - const struct wined3d_shader_version *version = ®_maps->shader_version; + level_count = min(wined3d_texture_get_level_count(src_texture), + wined3d_texture_get_level_count(dst_texture)); + +@@ -3546,7 +3935,13 @@ + } + + /* Make sure that the destination texture is loaded. */ +#if defined(STAGING_CSMT) - const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; - const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; - const struct wined3d_gl_info *gl_info = context->gl_info; ++ wined3d_texture_load(dst_texture, context, FALSE); +#else /* STAGING_CSMT */ -+ const struct wined3d_state *state = &shader->device->state; -+ const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; -+ const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; -+ const struct wined3d_gl_info *gl_info = context->gl_info; -+ const struct wined3d_fb_state *fb = &shader->device->fb; ++ context = context_acquire(device, NULL); + wined3d_texture_load(dst_texture, context, FALSE); ++ context_release(context); +#endif /* STAGING_CSMT */ - unsigned int i, extra_constants_needed = 0; - const struct wined3d_shader_lconst *lconst; - const char *prefix; -@@ -1904,7 +1912,11 @@ - { - UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input); + /* Update every surface level of the texture. */ + switch (type) +@@ -3566,7 +3961,15 @@ + i * src_levels + j + src_skip_levels)); + dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, + i * dst_levels + j)); +#if defined(STAGING_CSMT) - if (ps_args->vp_mode == vertexshader) + surface_upload_from_surface(dst_surface, NULL, src_surface, NULL); +#else /* STAGING_CSMT */ -+ if (use_vs(state)) ++ if (FAILED(hr = wined3d_device_update_surface(device, src_surface, NULL, dst_surface, NULL))) ++ { ++ WARN("Failed to update surface, hr %#x.\n", hr); ++ return hr; ++ } +#endif /* STAGING_CSMT */ - declare_in_varying(gl_info, buffer, FALSE, "vec4 %s_link[%u];\n", prefix, in_count); - shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); - } -@@ -1945,6 +1957,7 @@ + } } - else + break; +@@ -3576,6 +3979,7 @@ + { + for (i = 0; i < level_count; ++i) { +#if defined(STAGING_CSMT) - /* This happens because we do not have proper tracking of the - * constant registers that are actually used, only the max - * limit of the shader version. -@@ -1953,6 +1966,23 @@ - * it and just create the uniform. - */ - FIXME("Cannot find a free uniform for vpos correction params\n"); + device_update_volume(context, + volume_from_resource(wined3d_texture_get_sub_resource(src_texture, + i + src_skip_levels)), +@@ -3637,6 +4041,25 @@ + } + + wined3d_cs_emit_update_texture(device->cs, src_texture, dst_texture); +#else /* STAGING_CSMT */ -+ float ycorrection[] = ++ hr = device_update_volume(device, ++ volume_from_resource(wined3d_texture_get_sub_resource(src_texture, ++ i + src_skip_levels)), ++ volume_from_resource(wined3d_texture_get_sub_resource(dst_texture, i))); ++ if (FAILED(hr)) + { -+ context->render_offscreen ? 0.0f : fb->render_targets[0]->height, -+ context->render_offscreen ? 1.0f : -1.0f, -+ 0.0f, -+ 0.0f, -+ }; ++ WARN("Failed to update volume, hr %#x.\n", hr); ++ return hr; ++ } ++ } ++ break; ++ } + -+ /* This happens because we do not have proper tracking of the -+ * constant registers that are actually used, only the max -+ * limit of the shader version. */ -+ FIXME("Cannot find a free uniform for vpos correction params\n"); -+ shader_addline(buffer, "const vec4 ycorrection = "); -+ shader_glsl_append_imm_vec4(buffer, ycorrection); -+ shader_addline(buffer, ";\n"); ++ default: ++ FIXME("Unsupported texture type %#x.\n", type); ++ return WINED3DERR_INVALIDCALL; ++ } +#endif /* STAGING_CSMT */ - } - shader_addline(buffer, "vec4 vpos;\n"); - } -diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c ---- a/dlls/wined3d/cs.c -+++ b/dlls/wined3d/cs.c -@@ -22,11 +22,18 @@ - - WINE_DEFAULT_DEBUG_CHANNEL(d3d); + return WINED3D_OK; + } +@@ -3686,8 +4109,13 @@ + if (state->render_states[WINED3D_RS_ZENABLE] || state->render_states[WINED3D_RS_ZWRITEENABLE] + || state->render_states[WINED3D_RS_STENCILENABLE]) + { +#if defined(STAGING_CSMT) - enum wined3d_cs_op - { - WINED3D_CS_OP_NOP, - WINED3D_CS_OP_SKIP, - WINED3D_CS_OP_FENCE, -+#else /* STAGING_CSMT */ -+#define WINED3D_INITIAL_CS_SIZE 4096 -+ -+enum wined3d_cs_op -+{ -+#endif /* STAGING_CSMT */ - WINED3D_CS_OP_PRESENT, - WINED3D_CS_OP_CLEAR, - WINED3D_CS_OP_DRAW, -@@ -53,6 +60,7 @@ - WINED3D_CS_OP_SET_COLOR_KEY, - WINED3D_CS_OP_SET_MATERIAL, - WINED3D_CS_OP_RESET_STATE, -+#if defined(STAGING_CSMT) - WINED3D_CS_OP_SET_VS_CONSTS_F, - WINED3D_CS_OP_SET_VS_CONSTS_B, - WINED3D_CS_OP_SET_VS_CONSTS_I, -@@ -133,6 +141,30 @@ - float depth; - DWORD stencil; - RECT rects[1]; + struct wined3d_rendertarget_view *rt = state->fb.render_targets[0]; + struct wined3d_rendertarget_view *ds = state->fb.depth_stencil; +#else /* STAGING_CSMT */ -+}; -+ -+struct wined3d_cs_present -+{ -+ enum wined3d_cs_op opcode; -+ HWND dst_window_override; -+ struct wined3d_swapchain *swapchain; -+ const RECT *src_rect; -+ const RECT *dst_rect; -+ const RGNDATA *dirty_region; -+ DWORD flags; -+}; -+ -+struct wined3d_cs_clear -+{ -+ enum wined3d_cs_op opcode; -+ DWORD rect_count; -+ const RECT *rects; -+ DWORD flags; -+ const struct wined3d_color *color; -+ float depth; -+ DWORD stencil; ++ struct wined3d_rendertarget_view *rt = device->fb.render_targets[0]; ++ struct wined3d_rendertarget_view *ds = device->fb.depth_stencil; +#endif /* STAGING_CSMT */ - }; - struct wined3d_cs_draw -@@ -155,6 +187,7 @@ - struct wined3d_cs_set_viewport + if (ds && rt && (ds->width < rt->width || ds->height < rt->height)) + { +@@ -3786,6 +4214,7 @@ + struct wined3d_surface *src_surface, const RECT *src_rect, + struct wined3d_surface *dst_surface, const POINT *dst_point) { - enum wined3d_cs_op opcode; +#if defined(STAGING_CSMT) - struct wined3d_viewport viewport; - }; - -@@ -162,6 +195,15 @@ - { - enum wined3d_cs_op opcode; - RECT rect; + const struct wined3d_format *src_format = src_surface->resource.format; + const struct wined3d_format *dst_format = dst_surface->resource.format; + UINT update_w, update_h; +@@ -3793,6 +4222,7 @@ + RECT r, dst_rect; + POINT p; + ++#endif /* STAGING_CSMT */ + TRACE("device %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s.\n", + device, src_surface, wine_dbgstr_rect(src_rect), + dst_surface, wine_dbgstr_point(dst_point)); +@@ -3804,6 +4234,7 @@ + return WINED3DERR_INVALIDCALL; + } + ++#if defined(STAGING_CSMT) + if (src_format->id != dst_format->id) + { + WARN("Source and destination surfaces should have the same format.\n"); +@@ -3868,6 +4299,9 @@ + wined3d_cs_emit_update_surface(device->cs, src_surface, src_rect, dst_surface, dst_point); + + return WINED3D_OK; +#else /* STAGING_CSMT */ -+ const struct wined3d_viewport *viewport; -+}; -+ -+struct wined3d_cs_set_scissor_rect -+{ -+ enum wined3d_cs_op opcode; -+ const RECT *rect; ++ return surface_upload_from_surface(dst_surface, dst_point, src_surface, src_rect); +#endif /* STAGING_CSMT */ - }; + } - struct wined3d_cs_set_rendertarget_view -@@ -289,6 +331,7 @@ + void CDECL wined3d_device_copy_resource(struct wined3d_device *device, +@@ -4042,7 +4476,17 @@ + unsigned int depth_pitch) { - enum wined3d_cs_op opcode; - enum wined3d_transform_state state; + struct wined3d_resource *sub_resource; +#if defined(STAGING_CSMT) - struct wined3d_matrix matrix; - }; + struct wined3d_texture *texture; ++#else /* STAGING_CSMT */ ++ const struct wined3d_gl_info *gl_info; ++ struct wined3d_const_bo_address addr; ++ struct wined3d_context *context; ++ struct wined3d_texture *texture; ++ struct wined3d_surface *surface; ++ POINT dst_point; ++ RECT src_rect; ++#endif /* STAGING_CSMT */ -@@ -303,6 +346,22 @@ - { - enum wined3d_cs_op opcode; - struct wined3d_material material; + TRACE("device %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, depth_pitch %u.\n", + device, resource, sub_resource_idx, debug_box(box), data, row_pitch, depth_pitch); +@@ -4076,7 +4520,14 @@ + WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx); + return; + } ++#if defined(STAGING_CSMT) ++ ++#else /* STAGING_CSMT */ ++ surface = surface_from_resource(sub_resource); + ++ src_rect.left = 0; ++ src_rect.top = 0; ++#endif /* STAGING_CSMT */ + if (box) + { + if (box->left >= box->right || box->right > sub_resource->width +@@ -4086,9 +4537,47 @@ + WARN("Invalid box %s specified.\n", debug_box(box)); + return; + } ++#if defined(STAGING_CSMT) + } + + wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); +#else /* STAGING_CSMT */ -+ const struct wined3d_matrix *matrix; -+}; + -+struct wined3d_cs_set_clip_plane -+{ -+ enum wined3d_cs_op opcode; -+ UINT plane_idx; -+ const struct wined3d_vec4 *plane; -+}; ++ src_rect.right = box->right - box->left; ++ src_rect.bottom = box->bottom - box->top; ++ dst_point.x = box->left; ++ dst_point.y = box->top; ++ } ++ else ++ { ++ src_rect.right = sub_resource->width; ++ src_rect.bottom = sub_resource->height; ++ dst_point.x = 0; ++ dst_point.y = 0; ++ } + -+struct wined3d_cs_set_material -+{ -+ enum wined3d_cs_op opcode; -+ const struct wined3d_material *material; ++ addr.buffer_object = 0; ++ addr.addr = data; ++ ++ context = context_acquire(resource->device, NULL); ++ gl_info = context->gl_info; ++ ++ /* Only load the surface for partial updates. */ ++ if (!dst_point.x && !dst_point.y && src_rect.right == sub_resource->width ++ && src_rect.bottom == sub_resource->height) ++ wined3d_texture_prepare_texture(texture, context, FALSE); ++ else ++ surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB); ++ wined3d_texture_bind_and_dirtify(texture, context, FALSE); ++ ++ wined3d_surface_upload_data(surface, gl_info, resource->format, ++ &src_rect, row_pitch, &dst_point, FALSE, &addr); ++ ++ context_release(context); ++ ++ surface_validate_location(surface, WINED3D_LOCATION_TEXTURE_RGB); ++ surface_invalidate_location(surface, ~WINED3D_LOCATION_TEXTURE_RGB); +#endif /* STAGING_CSMT */ - }; + } - struct wined3d_cs_reset_state -@@ -310,6 +369,7 @@ - enum wined3d_cs_op opcode; - }; + HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device, +@@ -4119,8 +4608,14 @@ + rect = &r; + } +#if defined(STAGING_CSMT) - struct wined3d_cs_set_consts_f - { - enum wined3d_cs_op opcode; -@@ -2880,197 +2940,971 @@ - /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, - /* WINED3D_CS_OP_SKIP */ wined3d_cs_exec_skip, - /* WINED3D_CS_OP_FENCE */ wined3d_cs_exec_fence, -- /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, -- /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, -- /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, -- /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication, -- /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport, -- /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect, -- /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, -- /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, -- /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, -- /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, -- /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, -- /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output, -- /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, -- /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, -- /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, -- /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, -- /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, -- /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, -- /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, -- /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, -- /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, -- /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, -- /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, -- /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, -- /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, -- /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, -- /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, -- /* WINED3D_CS_OP_SET_VS_CONSTS_B */ wined3d_cs_exec_set_vs_consts_b, -- /* WINED3D_CS_OP_SET_VS_CONSTS_I */ wined3d_cs_exec_set_vs_consts_i, -- /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, -- /* WINED3D_CS_OP_SET_PS_CONSTS_B */ wined3d_cs_exec_set_ps_consts_b, -- /* WINED3D_CS_OP_SET_PS_CONSTS_I */ wined3d_cs_exec_set_ps_consts_i, -- /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, -- /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, -- /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, -- /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, -- /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, -- /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, -- /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, -- /* WINED3D_CS_OP_RESOURCE_CHANGED */ wined3d_cs_exec_resource_changed, -- /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, -- /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, -- /* WINED3D_CS_OP_BUFFER_SWAP_MEM */ wined3d_cs_exec_buffer_swap_mem, -- /* WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE */ wined3d_cs_exec_buffer_invalidate_bo_range, -- /* WINED3D_CS_OP_BUFFER_PRELOAD */ wined3d_cs_exec_buffer_preload, -- /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, -- /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, -- /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, -- /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, -- /* WINED3D_CS_OP_SURFACE_PRELOAD */ wined3d_cs_exec_surface_preload, -- /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, -- /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, -- /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, -- /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, -- /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, -- /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, -- /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, -- /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, -- /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, -- /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, -- /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, -- /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, -- /* WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT */ wined3d_cs_exec_create_swapchain_context, -- /* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts, -- /* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc, -- /* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc, -- /* WINED3D_CS_OP_SAMPLER_DESTROY */ wined3d_cs_exec_sampler_destroy, -- /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource, --}; -- --static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) + wined3d_cs_emit_clear_rtv(device->cs, view, rect, color); + return WINED3D_OK; +#else /* STAGING_CSMT */ -+static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) - { -- struct wined3d_cs_queue *queue = prio ? &cs->prio_queue : &cs->queue; -- size_t queue_size = sizeof(queue->data) / sizeof(*queue->data); -+ const struct wined3d_cs_present *op = data; -+ struct wined3d_swapchain *swapchain; ++ resource = wined3d_texture_get_sub_resource(wined3d_texture_from_resource(resource), view->sub_resource_idx); ++ ++ return surface_color_fill(surface_from_resource(resource), rect, color); ++#endif /* STAGING_CSMT */ + } -- if (queue_size - size < queue->head) -- { -- struct wined3d_cs_skip *skip; -- size_t nop_size = queue_size - queue->head; -+ swapchain = op->swapchain; -+ wined3d_swapchain_set_window(swapchain, op->dst_window_override); + struct wined3d_rendertarget_view * CDECL wined3d_device_get_rendertarget_view(const struct wined3d_device *device, +@@ -4134,6 +4629,7 @@ + return NULL; + } -- skip = _wined3d_cs_mt_require_space(cs, nop_size, prio); -- if (nop_size < sizeof(*skip)) -- { -- skip->opcode = WINED3D_CS_OP_NOP; -- } -- else -- { -- skip->opcode = WINED3D_CS_OP_SKIP; -- skip->size = nop_size; -- } -+ swapchain->swapchain_ops->swapchain_present(swapchain, -+ op->src_rect, op->dst_rect, op->dirty_region, op->flags); -+} ++#if defined(STAGING_CSMT) + return device->state.fb.render_targets[view_idx]; + } -- if (prio) -- cs->ops->submit_prio(cs, nop_size); -- else -- cs->ops->submit(cs, nop_size); -+void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, -+ const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, -+ const RGNDATA *dirty_region, DWORD flags) +@@ -4149,6 +4645,22 @@ + { + struct wined3d_rendertarget_view *prev; + struct wined3d_fb_state *fb = &device->state.fb; ++#else /* STAGING_CSMT */ ++ return device->fb.render_targets[view_idx]; ++} ++ ++struct wined3d_rendertarget_view * CDECL wined3d_device_get_depth_stencil_view(const struct wined3d_device *device) +{ -+ struct wined3d_cs_present *op; - -- assert(!queue->head); -- } -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_PRESENT; -+ op->dst_window_override = dst_window_override; -+ op->swapchain = swapchain; -+ op->src_rect = src_rect; -+ op->dst_rect = dst_rect; -+ op->dirty_region = dirty_region; -+ op->flags = flags; - -- while(1) -- { -- LONG head = queue->head; -- LONG tail = *((volatile LONG *)&queue->tail); -- LONG new_pos; -- /* Empty */ -- if (head == tail) -- break; -- /* Head ahead of tail, take care of wrap-around */ -- new_pos = (head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -- if (head > tail && (new_pos || tail)) -- break; -- /* Tail ahead of head, but still enough space */ -- if (new_pos < tail && new_pos) -- break; -+ cs->ops->submit(cs); ++ TRACE("device %p.\n", device); ++ ++ return device->fb.depth_stencil; +} - -- TRACE("Waiting for free space. Head %u, tail %u, want %u\n", head, tail, -- (unsigned int) size); -- } -+static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) ++ ++HRESULT CDECL wined3d_device_set_rendertarget_view(struct wined3d_device *device, ++ unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport) +{ -+ const struct wined3d_cs_clear *op = data; -+ struct wined3d_device *device; -+ RECT draw_rect; ++ struct wined3d_rendertarget_view *prev; ++#endif /* STAGING_CSMT */ -- return &queue->data[queue->head]; -+ device = cs->device; -+ wined3d_get_draw_rect(&device->state, &draw_rect); -+ device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, -+ &device->fb, op->rect_count, op->rects, &draw_rect, op->flags, -+ op->color, op->depth, op->stencil); - } + TRACE("device %p, view_idx %u, view %p, set_viewport %#x.\n", + device, view_idx, view, set_viewport); +@@ -4188,6 +4700,7 @@ + } --static inline void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) -+void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, -+ DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) - { -- return _wined3d_cs_mt_require_space(cs, size, FALSE); -+ struct wined3d_cs_clear *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_CLEAR; -+ op->rect_count = rect_count; -+ op->rects = rects; -+ op->flags = flags; -+ op->color = color; -+ op->depth = depth; -+ op->stencil = stencil; -+ -+ cs->ops->submit(cs); - } --static inline void *wined3d_cs_mt_require_space_prio(struct wined3d_cs *cs, size_t size) -+static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) - { -- return _wined3d_cs_mt_require_space(cs, size, TRUE); -+ const struct wined3d_cs_draw *op = data; ++#if defined(STAGING_CSMT) + prev = fb->render_targets[view_idx]; + if (view == prev) + return WINED3D_OK; +@@ -4195,6 +4708,15 @@ + if (view) + wined3d_rendertarget_view_incref(view); + fb->render_targets[view_idx] = view; ++#else /* STAGING_CSMT */ ++ prev = device->fb.render_targets[view_idx]; ++ if (view == prev) ++ return WINED3D_OK; + -+ draw_primitive(cs->device, op->start_idx, op->index_count, -+ op->start_instance, op->instance_count, op->indexed); - } - --/* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an -- * OP itself. */ --static void wined3d_cs_emit_stop(struct wined3d_cs *cs) -+void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_count, -+ UINT start_instance, UINT instance_count, BOOL indexed) - { -- struct wined3d_cs_stop *op; -+ struct wined3d_cs_draw *op; - -- op = wined3d_cs_mt_require_space(cs, sizeof(*op)); -- op->opcode = WINED3D_CS_OP_STOP; -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_DRAW; -+ op->start_idx = start_idx; -+ op->index_count = index_count; -+ op->start_instance = start_instance; -+ op->instance_count = instance_count; -+ op->indexed = indexed; - -- wined3d_cs_mt_submit(cs, sizeof(*op)); -+ cs->ops->submit(cs); - } - --static void wined3d_cs_mt_finish(struct wined3d_cs *cs) -+static void wined3d_cs_exec_set_predication(struct wined3d_cs *cs, const void *data) - { -- BOOL fence; -- -- if (cs->thread_id == GetCurrentThreadId()) -- { -- static BOOL once; -- if (!once) -- { -- FIXME("flush_and_wait called from cs thread\n"); -- once = TRUE; -- } -- return; -- } -- -- wined3d_cs_emit_fence(cs, &fence); -+ const struct wined3d_cs_set_predication *op = data; - -- /* A busy wait should be fine, we're not supposed to have to wait very -- * long. */ -- while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); -+ cs->state.predicate = op->predicate; -+ cs->state.predicate_value = op->value; - } ++ if (view) ++ wined3d_rendertarget_view_incref(view); ++ device->fb.render_targets[view_idx] = view; ++#endif /* STAGING_CSMT */ + wined3d_cs_emit_set_rendertarget_view(device->cs, view_idx, view); + /* Release after the assignment, to prevent device_resource_released() + * from seeing the surface as still in use. */ +@@ -4206,6 +4728,7 @@ --static void wined3d_cs_mt_finish_prio(struct wined3d_cs *cs) -+void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value) + void CDECL wined3d_device_set_depth_stencil_view(struct wined3d_device *device, struct wined3d_rendertarget_view *view) { -- BOOL fence; -+ struct wined3d_cs_set_predication *op; - -- if (cs->thread_id == GetCurrentThreadId()) -- { -- static BOOL once; -- if (!once) -- { -- FIXME("flush_and_wait called from cs thread\n"); -- once = TRUE; -- } -- return; -- } -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_PREDICATION; -+ op->predicate = predicate; -+ op->value = value; - -- wined3d_cs_emit_fence_prio(cs, &fence); -+ cs->ops->submit(cs); -+} ++#if defined(STAGING_CSMT) + struct wined3d_fb_state *fb = &device->state.fb; + struct wined3d_rendertarget_view *prev; -- /* A busy wait should be fine, we're not supposed to have to wait very -- * long. */ -- while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); -+static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_viewport *op = data; +@@ -4223,6 +4746,66 @@ + wined3d_cs_emit_set_depth_stencil_view(device->cs, view); + if (prev) + wined3d_rendertarget_view_decref(prev); ++#else /* STAGING_CSMT */ ++ struct wined3d_rendertarget_view *prev; + -+ cs->state.viewport = *op->viewport; -+ device_invalidate_state(cs->device, STATE_VIEWPORT); - } - --static const struct wined3d_cs_ops wined3d_cs_mt_ops = -+void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) - { -- wined3d_cs_mt_require_space, -+ struct wined3d_cs_set_viewport *op; ++ TRACE("device %p, view %p.\n", device, view); + -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_VIEWPORT; -+ op->viewport = viewport; ++ prev = device->fb.depth_stencil; ++ if (prev == view) ++ { ++ TRACE("Trying to do a NOP SetRenderTarget operation.\n"); ++ return; ++ } + -+ cs->ops->submit(cs); ++ if ((device->fb.depth_stencil = view)) ++ wined3d_rendertarget_view_incref(view); ++ wined3d_cs_emit_set_depth_stencil_view(device->cs, view); ++ if (prev) ++ wined3d_rendertarget_view_decref(prev); +} + -+static void wined3d_cs_exec_set_scissor_rect(struct wined3d_cs *cs, const void *data) ++static struct wined3d_texture *wined3d_device_create_cursor_texture(struct wined3d_device *device, ++ struct wined3d_surface *cursor_image) +{ -+ const struct wined3d_cs_set_scissor_rect *op = data; ++ struct wined3d_sub_resource_data data; ++ struct wined3d_resource_desc desc; ++ struct wined3d_map_desc map_desc; ++ struct wined3d_texture *texture; ++ HRESULT hr; + -+ cs->state.scissor_rect = *op->rect; -+ device_invalidate_state(cs->device, STATE_SCISSORRECT); -+} ++ if (FAILED(wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_READONLY))) ++ { ++ ERR("Failed to map source surface.\n"); ++ return NULL; ++ } + -+void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) -+{ -+ struct wined3d_cs_set_scissor_rect *op; ++ data.data = map_desc.data; ++ data.row_pitch = map_desc.row_pitch; ++ data.slice_pitch = map_desc.slice_pitch; + -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_SCISSOR_RECT; -+ op->rect = rect; ++ desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; ++ desc.format = WINED3DFMT_B8G8R8A8_UNORM; ++ desc.multisample_type = WINED3D_MULTISAMPLE_NONE; ++ desc.multisample_quality = 0; ++ desc.usage = WINED3DUSAGE_DYNAMIC; ++ desc.pool = WINED3D_POOL_DEFAULT; ++ desc.width = cursor_image->resource.width; ++ desc.height = cursor_image->resource.height; ++ desc.depth = 1; ++ desc.size = 0; + -+ cs->ops->submit(cs); -+} ++ hr = wined3d_texture_create(device, &desc, 1, WINED3D_TEXTURE_CREATE_MAPPABLE, ++ &data, NULL, &wined3d_null_parent_ops, &texture); ++ wined3d_surface_unmap(cursor_image); ++ if (FAILED(hr)) ++ { ++ ERR("Failed to create cursor texture.\n"); ++ return NULL; ++ } + -+static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_rendertarget_view *op = data; -+ -+ cs->state.fb->render_targets[op->view_idx] = op->view; -+ device_invalidate_state(cs->device, STATE_FRAMEBUFFER); -+} -+ -+void wined3d_cs_emit_set_rendertarget_view(struct wined3d_cs *cs, unsigned int view_idx, -+ struct wined3d_rendertarget_view *view) -+{ -+ struct wined3d_cs_set_rendertarget_view *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW; -+ op->view_idx = view_idx; -+ op->view = view; -+ -+ cs->ops->submit(cs); -+} -+ -+static void wined3d_cs_exec_set_depth_stencil_view(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_depth_stencil_view *op = data; -+ struct wined3d_device *device = cs->device; -+ struct wined3d_rendertarget_view *prev; -+ -+ if ((prev = cs->state.fb->depth_stencil)) ++ return texture; ++#endif /* STAGING_CSMT */ + } + + HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device, +@@ -4243,6 +4826,14 @@ + + cursor_image = surface_from_resource(sub_resource); + ++#if !defined(STAGING_CSMT) ++ if (device->cursor_texture) + { -+ struct wined3d_surface *prev_surface = wined3d_rendertarget_view_get_surface(prev); -+ -+ if (prev_surface && (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL -+ || prev_surface->flags & SFLAG_DISCARD)) -+ { -+ surface_modify_ds_location(prev_surface, WINED3D_LOCATION_DISCARDED, prev->width, prev->height); -+ if (prev_surface == device->onscreen_depth_stencil) -+ { -+ wined3d_texture_decref(device->onscreen_depth_stencil->container); -+ device->onscreen_depth_stencil = NULL; -+ } -+ } ++ wined3d_texture_decref(device->cursor_texture); ++ device->cursor_texture = NULL; + } + -+ cs->fb.depth_stencil = op->view; -+ -+ if (!prev != !op->view) ++#endif /* STAGING_CSMT */ + if (cursor_image->resource.format->id != WINED3DFMT_B8G8R8A8_UNORM) + { + WARN("Surface %p has an invalid format %s.\n", +@@ -4270,6 +4861,13 @@ + * release it after setting the cursor image. Windows doesn't + * addref the set surface, so we can't do this either without + * creating circular refcount dependencies. */ ++#if !defined(STAGING_CSMT) ++ if (!(device->cursor_texture = wined3d_device_create_cursor_texture(device, cursor_image))) + { -+ /* Swapping NULL / non NULL depth stencil affects the depth and tests */ -+ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE)); -+ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE)); -+ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK)); -+ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); ++ ERR("Failed to create cursor texture.\n"); ++ return WINED3DERR_INVALIDCALL; + } -+ else if (prev && (prev->format_flags & WINED3DFMT_FLAG_FLOAT) -+ != (op->view->format_flags & WINED3DFMT_FLAG_FLOAT)) ++#endif /* STAGING_CSMT */ + + if (cursor_image->resource.width == 32 && cursor_image->resource.height == 32) + { +@@ -4374,6 +4972,12 @@ + else + SetCursor(NULL); + } ++#if !defined(STAGING_CSMT) ++ else if (device->cursor_texture) + { -+ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS)); ++ device->bCursorVisible = show; ++ } ++#endif /* STAGING_CSMT */ + + return oldVisible; + } +@@ -4384,8 +4988,10 @@ + + TRACE("device %p.\n", device); + ++#if defined(STAGING_CSMT) + /* The resource list is manged by the main thread, iterate here and emit commands for + * each resource */ ++#endif /* STAGING_CSMT */ + LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) + { + TRACE("Checking resource %p for eviction.\n", resource); +@@ -4393,6 +4999,7 @@ + if (resource->pool == WINED3D_POOL_MANAGED && !resource->map_count) + { + TRACE("Evicting %p.\n", resource); ++#if defined(STAGING_CSMT) + wined3d_cs_emit_evict_resource(device->cs, resource); + } + } +@@ -4411,6 +5018,37 @@ + + context = context_acquire(device, NULL); + gl_info = context->gl_info; ++#else /* STAGING_CSMT */ ++ resource->resource_ops->resource_unload(resource); ++ } + } + -+ device_invalidate_state(device, STATE_FRAMEBUFFER); -+} -+ -+void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) -+{ -+ struct wined3d_cs_set_depth_stencil_view *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW; -+ op->view = view; -+ -+ cs->ops->submit(cs); ++ /* Invalidate stream sources, the buffer(s) may have been evicted. */ ++ device_invalidate_state(device, STATE_STREAMSRC); +} + -+static void wined3d_cs_exec_set_vertex_declaration(struct wined3d_cs *cs, const void *data) ++static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain) +{ -+ const struct wined3d_cs_set_vertex_declaration *op = data; ++ struct wined3d_resource *resource, *cursor; ++ const struct wined3d_gl_info *gl_info; ++ struct wined3d_context *context; ++ struct wined3d_shader *shader; + -+ cs->state.vertex_declaration = op->declaration; -+ device_invalidate_state(cs->device, STATE_VDECL); -+} ++ context = context_acquire(device, NULL); ++ gl_info = context->gl_info; + -+void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration) -+{ -+ struct wined3d_cs_set_vertex_declaration *op; ++ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) ++ { ++ TRACE("Unloading resource %p.\n", resource); + -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_VERTEX_DECLARATION; -+ op->declaration = declaration; ++ resource->resource_ops->resource_unload(resource); ++ } + -+ cs->ops->submit(cs); ++ LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry) ++ { ++ device->shader_backend->shader_destroy(shader); ++ } ++#endif /* STAGING_CSMT */ + + if (device->depth_blt_texture) + { +@@ -4432,6 +5070,7 @@ + + HeapFree(GetProcessHeap(), 0, swapchain->context); + swapchain->context = NULL; ++#if defined(STAGING_CSMT) + swapchain->num_contexts = 0; + } + +@@ -4451,6 +5090,14 @@ + + static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain) + { ++#else /* STAGING_CSMT */ +} + -+static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) ++static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain) +{ -+ const struct wined3d_cs_set_stream_source *op = data; -+ struct wined3d_stream_state *stream; -+ struct wined3d_buffer *prev; -+ -+ stream = &cs->state.streams[op->stream_idx]; -+ prev = stream->buffer; -+ stream->buffer = op->buffer; -+ stream->offset = op->offset; -+ stream->stride = op->stride; ++ struct wined3d_context *context; ++ struct wined3d_surface *target; ++#endif /* STAGING_CSMT */ + HRESULT hr; + + if (FAILED(hr = device->shader_backend->shader_alloc_private(device, +@@ -4467,6 +5114,7 @@ + return hr; + } + ++#if defined(STAGING_CSMT) + hr = wined3d_cs_emit_create_swapchain_context(device->cs, swapchain); + if (FAILED(hr)) + { +@@ -4477,6 +5125,35 @@ + } + + wined3d_cs_emit_create_dummy_textures(device->cs); ++#else /* STAGING_CSMT */ ++ /* Recreate the primary swapchain's context */ ++ swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); ++ if (!swapchain->context) ++ { ++ ERR("Failed to allocate memory for swapchain context array.\n"); ++ device->blitter->free_private(device); ++ device->shader_backend->shader_free_private(device); ++ return E_OUTOFMEMORY; ++ } + -+ if (op->buffer) -+ InterlockedIncrement(&op->buffer->resource.bind_count); -+ if (prev) -+ InterlockedDecrement(&prev->resource.bind_count); ++ target = swapchain->back_buffers ++ ? surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)) ++ : surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); ++ if (!(context = context_create(swapchain, target, swapchain->ds_format))) ++ { ++ WARN("Failed to create context.\n"); ++ device->blitter->free_private(device); ++ device->shader_backend->shader_free_private(device); ++ HeapFree(GetProcessHeap(), 0, swapchain->context); ++ return E_FAIL; ++ } + -+ device_invalidate_state(cs->device, STATE_STREAMSRC); -+} ++ swapchain->context[0] = context; ++ swapchain->num_contexts = 1; ++ create_dummy_textures(device, context); ++ create_default_sampler(device); ++ context_release(context); ++#endif /* STAGING_CSMT */ + + return WINED3D_OK; + } +@@ -4496,9 +5173,11 @@ + TRACE("device %p, swapchain_desc %p, mode %p, callback %p, reset_state %#x.\n", + device, swapchain_desc, mode, callback, reset_state); + ++#if defined(STAGING_CSMT) + wined3d_cs_emit_glfinish(device->cs); + device->cs->ops->finish(device->cs); + ++#endif /* STAGING_CSMT */ + if (!(swapchain = wined3d_device_get_swapchain(device, 0))) + { + ERR("Failed to get the first implicit swapchain.\n"); +@@ -4513,9 +5192,21 @@ + wined3d_texture_decref(device->logo_texture); + device->logo_texture = NULL; + } ++#if defined(STAGING_CSMT) + } + + if (device->state.fb.render_targets) ++#else /* STAGING_CSMT */ ++ if (device->cursor_texture) ++ { ++ wined3d_texture_decref(device->cursor_texture); ++ device->cursor_texture = NULL; ++ } ++ state_unbind_resources(&device->state); ++ } + -+void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, -+ struct wined3d_buffer *buffer, UINT offset, UINT stride) -+{ -+ struct wined3d_cs_set_stream_source *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE; -+ op->stream_idx = stream_idx; -+ op->buffer = buffer; -+ op->offset = offset; -+ op->stride = stride; -+ -+ cs->ops->submit(cs); -+} -+ -+static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_stream_source_freq *op = data; -+ struct wined3d_stream_state *stream; -+ -+ stream = &cs->state.streams[op->stream_idx]; -+ stream->frequency = op->frequency; -+ stream->flags = op->flags; -+ -+ device_invalidate_state(cs->device, STATE_STREAMSRC); -+} -+ -+void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags) -+{ -+ struct wined3d_cs_set_stream_source_freq *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ; -+ op->stream_idx = stream_idx; -+ op->frequency = frequency; -+ op->flags = flags; -+ -+ cs->ops->submit(cs); -+} -+ -+static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_stream_output *op = data; -+ struct wined3d_stream_output *stream; -+ struct wined3d_buffer *prev; -+ -+ stream = &cs->state.stream_output[op->stream_idx]; -+ prev = stream->buffer; -+ stream->buffer = op->buffer; -+ stream->offset = op->offset; -+ -+ if (op->buffer) -+ InterlockedIncrement(&op->buffer->resource.bind_count); -+ if (prev) -+ InterlockedDecrement(&prev->resource.bind_count); -+} -+ -+void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, -+ struct wined3d_buffer *buffer, UINT offset) -+{ -+ struct wined3d_cs_set_stream_output *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT; -+ op->stream_idx = stream_idx; -+ op->buffer = buffer; -+ op->offset = offset; -+ -+ cs->ops->submit(cs); -+} -+ -+static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_index_buffer *op = data; -+ struct wined3d_buffer *prev; -+ -+ prev = cs->state.index_buffer; -+ cs->state.index_buffer = op->buffer; -+ cs->state.index_format = op->format_id; -+ -+ if (op->buffer) -+ InterlockedIncrement(&op->buffer->resource.bind_count); -+ if (prev) -+ InterlockedDecrement(&prev->resource.bind_count); -+ -+ device_invalidate_state(cs->device, STATE_INDEXBUFFER); -+} -+ -+void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, -+ enum wined3d_format_id format_id) -+{ -+ struct wined3d_cs_set_index_buffer *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER; -+ op->buffer = buffer; -+ op->format_id = format_id; -+ -+ cs->ops->submit(cs); -+} ++ if (device->fb.render_targets) ++#endif /* STAGING_CSMT */ + { + for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + { +@@ -4524,6 +5215,7 @@ + } + wined3d_device_set_depth_stencil_view(device, NULL); + ++#if defined(STAGING_CSMT) + if (reset_state) + { + state_unbind_resources(&device->state); +@@ -4533,6 +5225,12 @@ + { + wined3d_texture_decref(device->cs->onscreen_depth_stencil->container); + device->cs->onscreen_depth_stencil = NULL; ++#else /* STAGING_CSMT */ ++ if (device->onscreen_depth_stencil) ++ { ++ wined3d_texture_decref(device->onscreen_depth_stencil->container); ++ device->onscreen_depth_stencil = NULL; ++#endif /* STAGING_CSMT */ + } + + if (reset_state) +@@ -4545,6 +5243,7 @@ + } + } + ++#if defined(STAGING_CSMT) + /* Free implicit resources and wait for the command stream before modifying + * swapchain parameters. After modifying the swapchain parameters a new GL + * context may be acquired by the worker thread. This causes problems in the +@@ -4566,6 +5265,7 @@ + } + device->cs->ops->finish(device->cs); + ++#endif /* STAGING_CSMT */ + TRACE("New params:\n"); + TRACE("backbuffer_width %u\n", swapchain_desc->backbuffer_width); + TRACE("backbuffer_height %u\n", swapchain_desc->backbuffer_height); +@@ -4692,6 +5392,13 @@ + swapchain_desc->multisample_type, swapchain_desc->multisample_quality))) + return hr; + ++#if !defined(STAGING_CSMT) ++ if (device->auto_depth_stencil_view) ++ { ++ wined3d_rendertarget_view_decref(device->auto_depth_stencil_view); ++ device->auto_depth_stencil_view = NULL; ++ } ++#endif /* STAGING_CSMT */ + if (swapchain->desc.enable_auto_depth_stencil) + { + struct wined3d_resource_desc texture_desc; +@@ -4733,6 +5440,13 @@ + wined3d_device_set_depth_stencil_view(device, device->auto_depth_stencil_view); + } + ++#if !defined(STAGING_CSMT) ++ if (device->back_buffer_view) ++ { ++ wined3d_rendertarget_view_decref(device->back_buffer_view); ++ device->back_buffer_view = NULL; ++ } ++#endif /* STAGING_CSMT */ + if (swapchain->desc.backbuffer_count) + { + view_desc.format_id = swapchain_desc->backbuffer_format; +@@ -4759,12 +5473,20 @@ + } + wined3d_cs_emit_reset_state(device->cs); + state_cleanup(&device->state); ++#if defined(STAGING_CSMT) + memset(&device->state, 0, sizeof(device->state)); + + if (device->d3d_initialized) + delete_opengl_contexts(device, swapchain); + + if (FAILED(hr = state_init(&device->state, &device->adapter->gl_info, ++#else /* STAGING_CSMT */ + -+static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_constant_buffer *op = data; -+ struct wined3d_buffer *prev; ++ if (device->d3d_initialized) ++ delete_opengl_contexts(device, swapchain); + -+ prev = cs->state.cb[op->type][op->cb_idx]; -+ cs->state.cb[op->type][op->cb_idx] = op->buffer; ++ if (FAILED(hr = state_init(&device->state, &device->fb, &device->adapter->gl_info, ++#endif /* STAGING_CSMT */ + &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) + ERR("Failed to initialize device state, hr %#x.\n", hr); + device->update_state = &device->state; +@@ -4773,6 +5495,7 @@ + } + else if (device->back_buffer_view) + { ++#if defined(STAGING_CSMT) + struct wined3d_state *state = &device->state; + + wined3d_device_set_rendertarget_view(device, 0, device->back_buffer_view, FALSE); +@@ -4788,6 +5511,24 @@ + state->scissor_rect.left = 0; + state->scissor_rect.right = swapchain->desc.backbuffer_width; + state->scissor_rect.bottom = swapchain->desc.backbuffer_height; ++#else /* STAGING_CSMT */ ++ struct wined3d_rendertarget_view *view = device->back_buffer_view; ++ struct wined3d_state *state = &device->state; + -+ if (op->buffer) -+ InterlockedIncrement(&op->buffer->resource.bind_count); -+ if (prev) -+ InterlockedDecrement(&prev->resource.bind_count); ++ wined3d_device_set_rendertarget_view(device, 0, view, FALSE); + -+ device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type)); -+} ++ /* Note the min_z / max_z is not reset. */ ++ state->viewport.x = 0; ++ state->viewport.y = 0; ++ state->viewport.width = view->width; ++ state->viewport.height = view->height; ++ wined3d_cs_emit_set_viewport(device->cs, &state->viewport); + -+void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type, -+ UINT cb_idx, struct wined3d_buffer *buffer) -+{ -+ struct wined3d_cs_set_constant_buffer *op; ++ state->scissor_rect.top = 0; ++ state->scissor_rect.left = 0; ++ state->scissor_rect.right = view->width; ++ state->scissor_rect.bottom = view->height; ++#endif /* STAGING_CSMT */ + wined3d_cs_emit_set_scissor_rect(device->cs, &state->scissor_rect); + } + +@@ -4870,6 +5611,10 @@ + + TRACE("device %p, resource %p, type %s.\n", device, resource, debug_d3dresourcetype(type)); + ++#if !defined(STAGING_CSMT) ++ context_resource_released(device, resource, type); + -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER; -+ op->type = type; -+ op->cb_idx = cb_idx; -+ op->buffer = buffer; ++#endif /* STAGING_CSMT */ + switch (type) + { + case WINED3D_RTYPE_SURFACE: +@@ -4880,6 +5625,7 @@ + + for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + { ++#if defined(STAGING_CSMT) + if (wined3d_rendertarget_view_get_surface(device->state.fb.render_targets[i]) == surface) + { + ERR("Surface %p is still in use as render target %u.\n", surface, i); +@@ -4891,6 +5637,19 @@ + { + ERR("Surface %p is still in use as depth/stencil buffer.\n", surface); + device->state.fb.depth_stencil = NULL; ++#else /* STAGING_CSMT */ ++ if (wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]) == surface) ++ { ++ ERR("Surface %p is still in use as render target %u.\n", surface, i); ++ device->fb.render_targets[i] = NULL; ++ } ++ } + -+ cs->ops->submit(cs); -+} -+ -+static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) ++ if (wined3d_rendertarget_view_get_surface(device->fb.depth_stencil) == surface) ++ { ++ ERR("Surface %p is still in use as depth/stencil buffer.\n", surface); ++ device->fb.depth_stencil = NULL; ++#endif /* STAGING_CSMT */ + } + } + break; +@@ -5052,7 +5811,11 @@ + + device->blitter = adapter->blitter; + ++#if defined(STAGING_CSMT) + if (FAILED(hr = state_init(&device->state, &adapter->gl_info, ++#else /* STAGING_CSMT */ ++ if (FAILED(hr = state_init(&device->state, &device->fb, &adapter->gl_info, ++#endif /* STAGING_CSMT */ + &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT))) + { + ERR("Failed to initialize device state, hr %#x.\n", hr); +@@ -5151,6 +5914,7 @@ + else + return CallWindowProcA(proc, window, message, wparam, lparam); + } ++#if defined(STAGING_CSMT) + + /* Context activation is done by the caller */ + struct wined3d_gl_bo *wined3d_device_get_bo(struct wined3d_device *device, UINT size, GLenum gl_usage, +@@ -5204,3 +5968,4 @@ + + wined3d_device_destroy_bo(device, context, bo); + } ++#endif /* STAGING_CSMT */ +diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c +--- a/dlls/wined3d/directx.c ++++ b/dlls/wined3d/directx.c +@@ -5554,9 +5554,15 @@ + DebugBreak(); + } + ++#if defined(STAGING_CSMT) + /* Helper functions for providing vertex data to opengl. The arrays are initialized based on + * the extension detection and are used in draw_strided_slow + */ ++#else /* STAGING_CSMT */ ++/* Helper functions for providing vertex data to opengl. The arrays are initialized based on ++ * the extension detection and are used in drawStridedSlow ++ */ ++#endif /* STAGING_CSMT */ + static void WINE_GLAPI position_d3dcolor(const void *data) + { + DWORD pos = *((const DWORD *)data); +diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c +--- a/dlls/wined3d/drawprim.c ++++ b/dlls/wined3d/drawprim.c +@@ -36,7 +36,11 @@ + #include + + /* Context activation is done by the caller. */ ++#if defined(STAGING_CSMT) + static void draw_strided_fast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, ++#else /* STAGING_CSMT */ ++static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size, ++#endif /* STAGING_CSMT */ + const void *idx_data, UINT start_idx, INT base_vertex_index, UINT start_instance, UINT instance_count) + { + if (idx_size) +@@ -95,7 +99,11 @@ + */ + + /* Context activation is done by the caller. */ ++#if defined(STAGING_CSMT) + static void draw_strided_slow(const struct wined3d_state *state, struct wined3d_context *context, ++#else /* STAGING_CSMT */ ++static void drawStridedSlow(const struct wined3d_device *device, struct wined3d_context *context, ++#endif /* STAGING_CSMT */ + const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType, + const void *idxData, UINT idxSize, UINT startIdx) + { +@@ -103,6 +111,9 @@ + const WORD *pIdxBufS = NULL; + const DWORD *pIdxBufL = NULL; + UINT vx_index; ++#if !defined(STAGING_CSMT) ++ const struct wined3d_state *state = &device->state; ++#endif /* STAGING_CSMT */ + LONG SkipnStrides = startIdx; + BOOL pixelShader = use_ps(state); + BOOL specular_fog = FALSE; +@@ -452,7 +463,11 @@ + } + + /* Context activation is done by the caller. */ ++#if defined(STAGING_CSMT) + static void draw_strided_slow_vs(struct wined3d_context *context, const struct wined3d_state *state, ++#else /* STAGING_CSMT */ ++static void drawStridedSlowVs(struct wined3d_context *context, const struct wined3d_state *state, ++#endif /* STAGING_CSMT */ + const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, + const void *idxData, UINT idxSize, UINT startIdx) + { +@@ -509,7 +524,11 @@ + } + + /* Context activation is done by the caller. */ ++#if defined(STAGING_CSMT) + static void draw_strided_instanced(struct wined3d_context *context, const struct wined3d_state *state, ++#else /* STAGING_CSMT */ ++static void drawStridedInstanced(struct wined3d_context *context, const struct wined3d_state *state, ++#endif /* STAGING_CSMT */ + const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, + const void *idxData, UINT idxSize, UINT startIdx, UINT base_vertex_index, UINT instance_count) + { +@@ -594,10 +613,17 @@ + } + + /* Routine common to the draw primitive and draw indexed primitive routines */ ++#if defined(STAGING_CSMT) + void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, + UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count, + BOOL indexed) + { ++#else /* STAGING_CSMT */ ++void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count, ++ UINT start_instance, UINT instance_count, BOOL indexed) +{ -+ const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; -+ const struct wined3d_cs_set_texture *op = data; -+ struct wined3d_texture *prev; -+ BOOL old_use_color_key = FALSE, new_use_color_key = FALSE; -+ -+ prev = cs->state.textures[op->stage]; -+ cs->state.textures[op->stage] = op->texture; -+ -+ if (op->texture) ++ const struct wined3d_state *state = &device->state; ++#endif /* STAGING_CSMT */ + const struct wined3d_stream_info *stream_info; + struct wined3d_event_query *ib_query = NULL; + struct wined3d_stream_info si_emulated; +@@ -610,7 +636,11 @@ + + if (!index_count) return; + ++#if defined(STAGING_CSMT) + context = context_acquire(device, wined3d_rendertarget_view_get_surface(state->fb.render_targets[0])); ++#else /* STAGING_CSMT */ ++ context = context_acquire(device, wined3d_rendertarget_view_get_surface(device->fb.render_targets[0])); ++#endif /* STAGING_CSMT */ + if (!context->valid) + { + context_release(context); +@@ -621,6 +651,7 @@ + + for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + { ++#if defined(STAGING_CSMT) + struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(state->fb.render_targets[i]); + if (target && target->resource.format->id != WINED3DFMT_NULL) + { +@@ -628,6 +659,15 @@ + { + wined3d_resource_load_location(&target->resource, context, target->container->resource.draw_binding); + wined3d_resource_invalidate_location(&target->resource, ~target->container->resource.draw_binding); ++#else /* STAGING_CSMT */ ++ struct wined3d_surface *target = wined3d_rendertarget_view_get_surface(device->fb.render_targets[i]); ++ if (target && target->resource.format->id != WINED3DFMT_NULL) ++ { ++ if (state->render_states[WINED3D_RS_COLORWRITEENABLE]) ++ { ++ surface_load_location(target, context, target->container->resource.draw_binding); ++ surface_invalidate_location(target, ~target->container->resource.draw_binding); ++#endif /* STAGING_CSMT */ + } + else + { +@@ -636,6 +676,7 @@ + } + } + ++#if defined(STAGING_CSMT) + if (state->fb.depth_stencil) + { + /* Note that this depends on the context_acquire() call above to set +@@ -655,6 +696,27 @@ + wined3d_cs_switch_onscreen_ds(device->cs, context, ds); + + if (ds->resource.locations & location) ++#else /* STAGING_CSMT */ ++ if (device->fb.depth_stencil) + { -+ const struct wined3d_format *new_format = op->texture->resource.format; -+ const struct wined3d_format *old_format = prev ? prev->resource.format : NULL; -+ unsigned int old_fmt_flags = prev ? prev->resource.format_flags : 0; -+ unsigned int new_fmt_flags = op->texture->resource.format_flags; -+ -+ if (InterlockedIncrement(&op->texture->resource.bind_count) == 1) -+ op->texture->sampler = op->stage; -+ -+ if (!prev || op->texture->target != prev->target -+ || !is_same_fixup(new_format->color_fixup, old_format->color_fixup) -+ || (new_fmt_flags & WINED3DFMT_FLAG_SHADOW) != (old_fmt_flags & WINED3DFMT_FLAG_SHADOW)) -+ device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); ++ /* Note that this depends on the context_acquire() call above to set ++ * context->render_offscreen properly. We don't currently take the ++ * Z-compare function into account, but we could skip loading the ++ * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note ++ * that we never copy the stencil data.*/ ++ DWORD location = context->render_offscreen ? device->fb.depth_stencil->resource->draw_binding ++ : WINED3D_LOCATION_DRAWABLE; ++ struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil); + -+ if (!prev && op->stage < d3d_info->limits.ffp_blend_stages) ++ if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE]) + { -+ /* The source arguments for color and alpha ops have different -+ * meanings when a NULL texture is bound, so the COLOR_OP and -+ * ALPHA_OP have to be dirtified. */ -+ device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP)); -+ device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP)); -+ } ++ RECT current_rect, draw_rect, r; + -+ if (!op->stage && op->texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) -+ new_use_color_key = TRUE; -+ } ++ if (!context->render_offscreen && ds != device->onscreen_depth_stencil) ++ device_switch_onscreen_ds(device, context, ds); + -+ if (prev) ++ if (ds->locations & location) ++#endif /* STAGING_CSMT */ + SetRect(¤t_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy); + else + SetRectEmpty(¤t_rect); +@@ -671,6 +733,7 @@ + wined3d_surface_prepare(ds, context, location); + } + ++#if defined(STAGING_CSMT) + if (!context_apply_draw_state(context, device, state)) + { + context_release(context); +@@ -681,6 +744,18 @@ + if (state->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE]) + { + struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(state->fb.depth_stencil); ++#else /* STAGING_CSMT */ ++ if (!context_apply_draw_state(context, device)) + { -+ if (InterlockedDecrement(&prev->resource.bind_count) && prev->sampler == op->stage) -+ { -+ unsigned int i; ++ context_release(context); ++ WARN("Unable to apply draw state, skipping draw.\n"); ++ return; ++ } + -+ /* Search for other stages the texture is bound to. Shouldn't -+ * happen if applications bind textures to a single stage only. */ -+ TRACE("Searching for other stages the texture is bound to.\n"); -+ for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) -+ { -+ if (cs->state.textures[i] == prev) -+ { -+ TRACE("Texture is also bound to stage %u.\n", i); -+ prev->sampler = i; -+ break; -+ } -+ } ++ if (device->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE]) ++ { ++ struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(device->fb.depth_stencil); ++#endif /* STAGING_CSMT */ + DWORD location = context->render_offscreen ? ds->container->resource.draw_binding : WINED3D_LOCATION_DRAWABLE; + + surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); +@@ -763,6 +838,7 @@ + else + WARN_(d3d_perf)("Using immediate mode with vertex shaders for half float emulation.\n"); + ++#if defined(STAGING_CSMT) + draw_strided_slow_vs(context, state, stream_info, index_count, + state->gl_primitive_type, idx_data, idx_size, start_idx); + } +@@ -785,6 +861,30 @@ + else + { + draw_strided_fast(gl_info, state->gl_primitive_type, index_count, idx_size, idx_data, ++#else /* STAGING_CSMT */ ++ drawStridedSlowVs(context, state, stream_info, index_count, ++ state->gl_primitive_type, idx_data, idx_size, start_idx); ++ } ++ else ++ { ++ if (context->d3d_info->ffp_generic_attributes) ++ drawStridedSlowVs(context, state, stream_info, index_count, ++ state->gl_primitive_type, idx_data, idx_size, start_idx); ++ else ++ drawStridedSlow(device, context, stream_info, index_count, ++ state->gl_primitive_type, idx_data, idx_size, start_idx); + } ++ } ++ else if (!gl_info->supported[ARB_INSTANCED_ARRAYS] && instance_count) ++ { ++ /* Instancing emulation by mixing immediate mode and arrays. */ ++ drawStridedInstanced(context, state, stream_info, index_count, state->gl_primitive_type, ++ idx_data, idx_size, start_idx, state->base_vertex_index, instance_count); ++ } ++ else ++ { ++ drawStridedFast(gl_info, state->gl_primitive_type, index_count, idx_size, idx_data, ++#endif /* STAGING_CSMT */ + start_idx, state->base_vertex_index, start_instance, instance_count); + } + +diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c +--- a/dlls/wined3d/glsl_shader.c ++++ b/dlls/wined3d/glsl_shader.c +@@ -1623,9 +1623,17 @@ + const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv) + { + const struct wined3d_shader_version *version = ®_maps->shader_version; ++#if defined(STAGING_CSMT) + const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; + const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; + const struct wined3d_gl_info *gl_info = context->gl_info; ++#else /* STAGING_CSMT */ ++ const struct wined3d_state *state = &shader->device->state; ++ const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; ++ const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; ++ const struct wined3d_gl_info *gl_info = context->gl_info; ++ const struct wined3d_fb_state *fb = &shader->device->fb; ++#endif /* STAGING_CSMT */ + unsigned int i, extra_constants_needed = 0; + const struct wined3d_shader_lconst *lconst; + const char *prefix; +@@ -1928,7 +1936,11 @@ + { + UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input); + ++#if defined(STAGING_CSMT) + if (ps_args->vp_mode == vertexshader) ++#else /* STAGING_CSMT */ ++ if (use_vs(state)) ++#endif /* STAGING_CSMT */ + declare_in_varying(gl_info, buffer, FALSE, "vec4 %s_link[%u];\n", prefix, in_count); + shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); + } +@@ -1969,6 +1981,7 @@ + } + else + { ++#if defined(STAGING_CSMT) + /* This happens because we do not have proper tracking of the + * constant registers that are actually used, only the max + * limit of the shader version. +@@ -1977,6 +1990,23 @@ + * it and just create the uniform. + */ + FIXME("Cannot find a free uniform for vpos correction params\n"); ++#else /* STAGING_CSMT */ ++ float ycorrection[] = ++ { ++ context->render_offscreen ? 0.0f : fb->render_targets[0]->height, ++ context->render_offscreen ? 1.0f : -1.0f, ++ 0.0f, ++ 0.0f, ++ }; + -+ if (!op->texture && op->stage < d3d_info->limits.ffp_blend_stages) ++ /* This happens because we do not have proper tracking of the ++ * constant registers that are actually used, only the max ++ * limit of the shader version. */ ++ FIXME("Cannot find a free uniform for vpos correction params\n"); ++ shader_addline(buffer, "const vec4 ycorrection = "); ++ shader_glsl_append_imm_vec4(buffer, ycorrection); ++ shader_addline(buffer, ";\n"); ++#endif /* STAGING_CSMT */ + } + shader_addline(buffer, "vec4 vpos;\n"); + } +diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c +--- a/dlls/wined3d/query.c ++++ b/dlls/wined3d/query.c +@@ -233,6 +233,7 @@ + return refcount; + } + ++#if defined(STAGING_CSMT) + void wined3d_query_destroy(struct wined3d_query *query) + { + /* Queries are specific to the GL context that created them. Not +@@ -263,6 +264,7 @@ + HeapFree(GetProcessHeap(), 0, query); + } + ++#endif /* STAGING_CSMT */ + ULONG CDECL wined3d_query_decref(struct wined3d_query *query) + { + ULONG refcount = InterlockedDecrement(&query->ref); +@@ -270,7 +272,38 @@ + TRACE("%p decreasing refcount to %u.\n", query, refcount); + + if (!refcount) ++#if defined(STAGING_CSMT) + wined3d_cs_emit_query_destroy(query->device->cs, query); ++#else /* STAGING_CSMT */ ++ { ++ /* Queries are specific to the GL context that created them. Not ++ * deleting the query will obviously leak it, but that's still better ++ * than potentially deleting a different query with the same id in this ++ * context, and (still) leaking the actual query. */ ++ if (query->type == WINED3D_QUERY_TYPE_EVENT) + { -+ device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP)); -+ device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP)); ++ struct wined3d_event_query *event_query = query->extendedData; ++ if (event_query) wined3d_event_query_destroy(event_query); + } ++ else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION) ++ { ++ struct wined3d_occlusion_query *oq = query->extendedData; + -+ if (!op->stage && prev->async.color_key_flags & WINED3D_CKEY_SRC_BLT) -+ old_use_color_key = TRUE; ++ if (oq->context) context_free_occlusion_query(oq); ++ HeapFree(GetProcessHeap(), 0, query->extendedData); ++ } ++ else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP) ++ { ++ struct wined3d_timestamp_query *tq = query->extendedData; ++ ++ if (tq->context) ++ context_free_timestamp_query(tq); ++ HeapFree(GetProcessHeap(), 0, query->extendedData); ++ } ++ ++ HeapFree(GetProcessHeap(), 0, query); ++ } ++#endif /* STAGING_CSMT */ + + return refcount; + } +@@ -295,6 +328,7 @@ + { + TRACE("query %p, flags %#x.\n", query, flags); + ++#if defined(STAGING_CSMT) + if (flags & WINED3DISSUE_END) + query->counter_main++; + +@@ -306,6 +340,9 @@ + query->state = QUERY_SIGNALLED; + + return WINED3D_OK; ++#else /* STAGING_CSMT */ ++ return query->query_ops->query_issue(query, flags); ++#endif /* STAGING_CSMT */ + } + + static void fill_query_data(void *out, unsigned int out_size, const void *result, unsigned int result_size) +@@ -316,10 +353,25 @@ + static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query, + void *data, DWORD size, DWORD flags) + { ++#if defined(STAGING_CSMT) + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_occlusion_query *oq = query->extendedData; + GLuint samples; ++#else /* STAGING_CSMT */ ++ struct wined3d_occlusion_query *oq = query->extendedData; ++ struct wined3d_device *device = query->device; ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++ struct wined3d_context *context; ++ GLuint available; ++ GLuint samples; ++ HRESULT res; ++ ++ TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); ++ ++ if (!oq->context) ++ query->state = QUERY_CREATED; ++#endif /* STAGING_CSMT */ + + if (query->state == QUERY_CREATED) + { +@@ -330,8 +382,10 @@ + return S_OK; + } + ++#if defined(STAGING_CSMT) + TRACE("(%p) : type D3DQUERY_OCCLUSION, data %p, size %#x, flags %#x.\n", query, data, size, flags); + ++#endif /* STAGING_CSMT */ + if (query->state == QUERY_BUILDING) + { + /* Msdn says this returns an error, but our tests show that S_FALSE is returned */ +@@ -347,6 +401,7 @@ + return S_OK; + } + ++#if defined(STAGING_CSMT) + if (!wined3d_settings.cs_multithreaded) + { + if (!query->query_ops->query_poll(query)) +@@ -378,6 +433,14 @@ + FIXME("%p Wrong thread, returning 1.\n", query); + oq->samples = 1; + return TRUE; ++#else /* STAGING_CSMT */ ++ if (oq->context->tid != GetCurrentThreadId()) ++ { ++ FIXME("%p Wrong thread, returning 1.\n", query); ++ samples = 1; ++ fill_query_data(data, size, &samples, sizeof(samples)); ++ return S_OK; ++#endif /* STAGING_CSMT */ + } + + context = context_acquire(query->device, oq->context->current_rt); +@@ -388,6 +451,7 @@ + + if (available) + { ++#if defined(STAGING_CSMT) + GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples)); + checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); + TRACE("Returning %d samples.\n", samples); +@@ -459,6 +523,69 @@ + + if (data) + fill_query_data(data, dwSize, &ret, sizeof(ret)); ++#else /* STAGING_CSMT */ ++ if (size) ++ { ++ GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples)); ++ checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); ++ TRACE("Returning %d samples.\n", samples); ++ fill_query_data(data, size, &samples, sizeof(samples)); ++ } ++ res = S_OK; ++ } ++ else ++ { ++ res = S_FALSE; ++ } ++ ++ context_release(context); ++ ++ return res; ++} ++ ++static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query, ++ void *data, DWORD size, DWORD flags) ++{ ++ struct wined3d_event_query *event_query = query->extendedData; ++ BOOL signaled; ++ enum wined3d_event_query_result ret; ++ ++ TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); ++ ++ if (!data || !size) return S_OK; ++ if (!event_query) ++ { ++ WARN("Event query not supported by GL, reporting GPU idle.\n"); ++ signaled = TRUE; ++ fill_query_data(data, size, &signaled, sizeof(signaled)); ++ return S_OK; ++ } ++ ++ ret = wined3d_event_query_test(event_query, query->device); ++ switch(ret) ++ { ++ case WINED3D_EVENT_QUERY_OK: ++ case WINED3D_EVENT_QUERY_NOT_STARTED: ++ signaled = TRUE; ++ fill_query_data(data, size, &signaled, sizeof(signaled)); ++ break; ++ ++ case WINED3D_EVENT_QUERY_WAITING: ++ signaled = FALSE; ++ fill_query_data(data, size, &signaled, sizeof(signaled)); ++ break; ++ ++ case WINED3D_EVENT_QUERY_WRONG_THREAD: ++ FIXME("(%p) Wrong thread, reporting GPU idle.\n", query); ++ signaled = TRUE; ++ fill_query_data(data, size, &signaled, sizeof(signaled)); ++ break; ++ ++ case WINED3D_EVENT_QUERY_ERROR: ++ ERR("The GL event query failed, returning D3DERR_INVALIDCALL\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++#endif /* STAGING_CSMT */ + + return S_OK; + } +@@ -477,7 +604,11 @@ + return query->type; + } + ++#if defined(STAGING_CSMT) + static BOOL wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) ++#else /* STAGING_CSMT */ ++static HRESULT wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags) ++#endif /* STAGING_CSMT */ + { + TRACE("query %p, flags %#x.\n", query, flags); + +@@ -487,6 +618,7 @@ + struct wined3d_event_query *event_query = query->extendedData; + + /* Faked event query support */ ++#if defined(STAGING_CSMT) + if (!event_query) return FALSE; + + wined3d_event_query_issue(event_query, query->device); +@@ -505,6 +637,30 @@ + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + BOOL poll = FALSE; ++#else /* STAGING_CSMT */ ++ if (!event_query) return WINED3D_OK; ++ ++ wined3d_event_query_issue(event_query, query->device); ++ } ++ else if (flags & WINED3DISSUE_BEGIN) ++ { ++ /* Started implicitly at device creation */ ++ ERR("Event query issued with START flag - what to do?\n"); ++ } ++ ++ if (flags & WINED3DISSUE_BEGIN) ++ query->state = QUERY_BUILDING; ++ else ++ query->state = QUERY_SIGNALLED; ++ ++ return WINED3D_OK; ++} ++ ++static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) ++{ ++ struct wined3d_device *device = query->device; ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++#endif /* STAGING_CSMT */ + + TRACE("query %p, flags %#x.\n", query, flags); + +@@ -516,7 +672,11 @@ + /* This is allowed according to msdn and our tests. Reset the query and restart */ + if (flags & WINED3DISSUE_BEGIN) + { ++#if defined(STAGING_CSMT) + if (oq->started) ++#else /* STAGING_CSMT */ ++ if (query->state == QUERY_BUILDING) ++#endif /* STAGING_CSMT */ + { + if (oq->context->tid != GetCurrentThreadId()) + { +@@ -545,7 +705,9 @@ + checkGLcall("glBeginQuery()"); + + context_release(context); ++#if defined(STAGING_CSMT) + oq->started = TRUE; ++#endif /* STAGING_CSMT */ + } + if (flags & WINED3DISSUE_END) + { +@@ -553,7 +715,11 @@ + * our tests show that it returns OK. But OpenGL doesn't like it, so avoid + * generating an error + */ ++#if defined(STAGING_CSMT) + if (oq->started) ++#else /* STAGING_CSMT */ ++ if (query->state == QUERY_BUILDING) ++#endif /* STAGING_CSMT */ + { + if (oq->context->tid != GetCurrentThreadId()) + { +@@ -567,10 +733,15 @@ + checkGLcall("glEndQuery()"); + + context_release(context); ++#if defined(STAGING_CSMT) + poll = TRUE; + } + } + oq->started = FALSE; ++#else /* STAGING_CSMT */ ++ } ++ } ++#endif /* STAGING_CSMT */ + } + } + else +@@ -578,6 +749,7 @@ + FIXME("%p Occlusion queries not supported.\n", query); + } + ++#if defined(STAGING_CSMT) + return poll; + } + +@@ -636,6 +808,47 @@ + FIXME("%p Wrong thread, returning 1.\n", query); + tq->timestamp = 1; + return TRUE; ++#else /* STAGING_CSMT */ ++ if (flags & WINED3DISSUE_BEGIN) ++ query->state = QUERY_BUILDING; ++ else ++ query->state = QUERY_SIGNALLED; ++ ++ return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */ ++} ++ ++static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, ++ void *data, DWORD size, DWORD flags) ++{ ++ struct wined3d_timestamp_query *tq = query->extendedData; ++ struct wined3d_device *device = query->device; ++ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; ++ struct wined3d_context *context; ++ GLuint available; ++ GLuint64 timestamp; ++ HRESULT res; ++ ++ TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); ++ ++ if (!tq->context) ++ query->state = QUERY_CREATED; ++ ++ if (query->state == QUERY_CREATED) ++ { ++ /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves. */ ++ TRACE("Query wasn't yet started, returning S_OK.\n"); ++ timestamp = 0; ++ fill_query_data(data, size, ×tamp, sizeof(timestamp)); ++ return S_OK; ++ } ++ ++ if (tq->context->tid != GetCurrentThreadId()) ++ { ++ FIXME("%p Wrong thread, returning 1.\n", query); ++ timestamp = 1; ++ fill_query_data(data, size, ×tamp, sizeof(timestamp)); ++ return S_OK; ++#endif /* STAGING_CSMT */ + } + + context = context_acquire(query->device, tq->context->current_rt); +@@ -646,6 +859,7 @@ + + if (available) + { ++#if defined(STAGING_CSMT) + GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); + checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); + TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); +@@ -663,6 +877,28 @@ + } + + static BOOL wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) ++#else /* STAGING_CSMT */ ++ if (size) ++ { ++ GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); ++ checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); ++ TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); ++ fill_query_data(data, size, ×tamp, sizeof(timestamp)); ++ } ++ res = S_OK; ++ } ++ else ++ { ++ res = S_FALSE; ++ } ++ ++ context_release(context); ++ ++ return res; ++} ++ ++static HRESULT wined3d_timestamp_query_ops_issue(struct wined3d_query *query, DWORD flags) ++#endif /* STAGING_CSMT */ + { + struct wined3d_device *device = query->device; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; +@@ -695,6 +931,7 @@ + } + + if (flags & WINED3DISSUE_END) ++#if defined(STAGING_CSMT) + return TRUE; + return FALSE; + } +@@ -711,6 +948,26 @@ + { + TRACE("Query is building, returning S_FALSE.\n"); + return S_FALSE; ++#else /* STAGING_CSMT */ ++ query->state = QUERY_SIGNALLED; ++ ++ return WINED3D_OK; ++} ++ ++static HRESULT wined3d_timestamp_disjoint_query_ops_get_data(struct wined3d_query *query, ++ void *data, DWORD size, DWORD flags) ++{ ++ TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); ++ ++ if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT) ++ { ++ static const struct wined3d_query_data_timestamp_disjoint disjoint_data = {1000 * 1000 * 1000, FALSE}; ++ ++ if (query->state == QUERY_BUILDING) ++ { ++ TRACE("Query is building, returning S_FALSE.\n"); ++ return S_FALSE; ++#endif /* STAGING_CSMT */ + } + + fill_query_data(data, size, &disjoint_data, sizeof(disjoint_data)); +@@ -724,6 +981,7 @@ + return S_OK; + } + ++#if defined(STAGING_CSMT) + static BOOL wined3d_timestamp_disjoint_query_ops_poll(struct wined3d_query *query) + { + return TRUE; +@@ -760,6 +1018,41 @@ + { + wined3d_timestamp_disjoint_query_ops_get_data, + wined3d_timestamp_disjoint_query_ops_poll, ++#else /* STAGING_CSMT */ ++static HRESULT wined3d_timestamp_disjoint_query_ops_issue(struct wined3d_query *query, DWORD flags) ++{ ++ TRACE("query %p, flags %#x.\n", query, flags); ++ ++ if (flags & WINED3DISSUE_BEGIN) ++ query->state = QUERY_BUILDING; ++ if (flags & WINED3DISSUE_END) ++ query->state = QUERY_SIGNALLED; ++ ++ return WINED3D_OK; ++} ++ ++static const struct wined3d_query_ops event_query_ops = ++{ ++ wined3d_event_query_ops_get_data, ++ wined3d_event_query_ops_issue, ++}; ++ ++static const struct wined3d_query_ops occlusion_query_ops = ++{ ++ wined3d_occlusion_query_ops_get_data, ++ wined3d_occlusion_query_ops_issue, ++}; ++ ++static const struct wined3d_query_ops timestamp_query_ops = ++{ ++ wined3d_timestamp_query_ops_get_data, ++ wined3d_timestamp_query_ops_issue, ++}; ++ ++static const struct wined3d_query_ops timestamp_disjoint_query_ops = ++{ ++ wined3d_timestamp_disjoint_query_ops_get_data, ++#endif /* STAGING_CSMT */ + wined3d_timestamp_disjoint_query_ops_issue, + }; + +@@ -781,6 +1074,7 @@ + } + query->query_ops = &occlusion_query_ops; + query->data_size = sizeof(DWORD); ++#if defined(STAGING_CSMT) + query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(struct wined3d_occlusion_query)); + if (!query->extendedData) +@@ -788,6 +1082,15 @@ + ERR("Failed to allocate occlusion query extended data.\n"); + return E_OUTOFMEMORY; + } ++#else /* STAGING_CSMT */ ++ query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query)); ++ if (!query->extendedData) ++ { ++ ERR("Failed to allocate occlusion query extended data.\n"); ++ return E_OUTOFMEMORY; ++ } ++ ((struct wined3d_occlusion_query *)query->extendedData)->context = NULL; ++#endif /* STAGING_CSMT */ + break; + + case WINED3D_QUERY_TYPE_EVENT: +@@ -860,7 +1163,9 @@ + query->state = QUERY_CREATED; + query->device = device; + query->ref = 1; ++#if defined(STAGING_CSMT) + list_init(&query->poll_list_entry); ++#endif /* STAGING_CSMT */ + + return WINED3D_OK; + } +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -213,7 +213,9 @@ + ERR("Failed to allocate system memory.\n"); + return E_OUTOFMEMORY; + } ++#if defined(STAGING_CSMT) + resource->heap_memory = resource->map_heap_memory; ++#endif /* STAGING_CSMT */ + } + else + { +@@ -237,6 +239,7 @@ + return WINED3D_OK; + } + ++#if defined(STAGING_CSMT) + void wined3d_resource_free_bo(struct wined3d_resource *resource) + { + struct wined3d_context *context = context_acquire(resource->device, NULL); +@@ -262,6 +265,7 @@ + resource->map_heap_memory = NULL; + } + ++#endif /* STAGING_CSMT */ + void resource_cleanup(struct wined3d_resource *resource) + { + const struct wined3d *d3d = resource->device->wined3d; +@@ -274,7 +278,11 @@ + adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size); + } + ++#if defined(STAGING_CSMT) + wined3d_cs_emit_resource_cleanup(resource->device->cs, resource); ++#else /* STAGING_CSMT */ ++ wined3d_resource_free_sysmem(resource); ++#endif /* STAGING_CSMT */ + + device_resource_released(resource->device, resource); + } +@@ -284,9 +292,11 @@ + if (resource->map_count) + ERR("Resource %p is being unloaded while mapped.\n", resource); + ++#if defined(STAGING_CSMT) + if (resource->buffer) + wined3d_resource_free_bo(resource); + ++#endif /* STAGING_CSMT */ + context_resource_unloaded(resource->device, + resource, resource->type); + } +@@ -365,7 +375,11 @@ + p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; + *p = mem; + ++#if defined(STAGING_CSMT) + resource->map_heap_memory = ++p; ++#else /* STAGING_CSMT */ ++ resource->heap_memory = ++p; ++#endif /* STAGING_CSMT */ + + return TRUE; + } +@@ -431,7 +445,11 @@ + return ret; + } + ++#if defined(STAGING_CSMT) + static GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) ++#else /* STAGING_CSMT */ ++GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) ++#endif /* STAGING_CSMT */ + { + if (d3d_flags & WINED3D_MAP_READONLY) + return GL_READ_ONLY_ARB; +@@ -472,6 +490,7 @@ + else + resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB; + } ++#if defined(STAGING_CSMT) + + void wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch, + UINT *slice_pitch) +@@ -1046,3 +1065,4 @@ + + wined3d_resource_invalidate_location(resource, ~resource->map_binding); + } ++#endif /* STAGING_CSMT */ +diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c +--- a/dlls/wined3d/sampler.c ++++ b/dlls/wined3d/sampler.c +@@ -33,6 +33,7 @@ + return refcount; + } + ++#if defined(STAGING_CSMT) + void wined3d_sampler_destroy(struct wined3d_sampler *sampler) + { + struct wined3d_context *context = context_acquire(sampler->device, NULL); +@@ -54,6 +55,24 @@ + { + struct wined3d_device *device = sampler->device; + wined3d_cs_emit_sampler_destroy(device->cs, sampler); ++#else /* STAGING_CSMT */ ++ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler) ++{ ++ ULONG refcount = InterlockedDecrement(&sampler->refcount); ++ const struct wined3d_gl_info *gl_info; ++ struct wined3d_context *context; ++ ++ TRACE("%p decreasing refcount to %u.\n", sampler, refcount); ++ ++ if (!refcount) ++ { ++ context = context_acquire(sampler->device, NULL); ++ gl_info = context->gl_info; ++ GL_EXTCALL(glDeleteSamplers(1, &sampler->name)); ++ context_release(context); ++ ++ HeapFree(GetProcessHeap(), 0, sampler); ++#endif /* STAGING_CSMT */ + } + + return refcount; +diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c +--- a/dlls/wined3d/shader.c ++++ b/dlls/wined3d/shader.c +@@ -2073,7 +2073,11 @@ + } + } + ++#if defined(STAGING_CSMT) + void shader_cleanup(struct wined3d_shader *shader) ++#else /* STAGING_CSMT */ ++static void shader_cleanup(struct wined3d_shader *shader) ++#endif /* STAGING_CSMT */ + { + HeapFree(GetProcessHeap(), 0, shader->output_signature.elements); + HeapFree(GetProcessHeap(), 0, shader->input_signature.elements); +@@ -2332,10 +2336,16 @@ + + if (!refcount) + { ++#if defined(STAGING_CSMT) + const struct wined3d_device *device = shader->device; + + shader->parent_ops->wined3d_object_destroyed(shader->parent); + wined3d_cs_emit_shader_cleanup(device->cs, shader); ++#else /* STAGING_CSMT */ ++ shader_cleanup(shader); ++ shader->parent_ops->wined3d_object_destroyed(shader->parent); ++ HeapFree(GetProcessHeap(), 0, shader); ++#endif /* STAGING_CSMT */ + } + + return refcount; +@@ -2618,7 +2628,11 @@ + memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */ + if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && state->render_states[WINED3D_RS_SRGBWRITEENABLE]) + { ++#if defined(STAGING_CSMT) + unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; ++#else /* STAGING_CSMT */ ++ unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; ++#endif /* STAGING_CSMT */ + if (rt_fmt_flags & WINED3DFMT_FLAG_SRGB_WRITE) + { + static unsigned int warned = 0; +diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c +--- a/dlls/wined3d/state.c ++++ b/dlls/wined3d/state.c +@@ -105,7 +105,11 @@ + const struct wined3d_gl_info *gl_info = context->gl_info; + + /* No z test without depth stencil buffers */ ++#if defined(STAGING_CSMT) + if (!state->fb.depth_stencil) ++#else /* STAGING_CSMT */ ++ if (!state->fb->depth_stencil) ++#endif /* STAGING_CSMT */ + { + TRACE("No Z buffer - disabling depth test\n"); + zenable = WINED3D_ZB_FALSE; +@@ -370,8 +374,13 @@ + + static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { ++#if defined(STAGING_CSMT) + const struct wined3d_format *rt_format = state->fb.render_targets[0]->format; + unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; ++#else /* STAGING_CSMT */ ++ const struct wined3d_format *rt_format = state->fb->render_targets[0]->format; ++ unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; ++#endif /* STAGING_CSMT */ + const struct wined3d_gl_info *gl_info = context->gl_info; + GLenum srcBlend, dstBlend; + enum wined3d_blend d3d_blend; +@@ -816,7 +825,11 @@ + GLint depthFail_ccw; + + /* No stencil test without a stencil buffer. */ ++#if defined(STAGING_CSMT) + if (!state->fb.depth_stencil) ++#else /* STAGING_CSMT */ ++ if (!state->fb->depth_stencil) ++#endif /* STAGING_CSMT */ + { + gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST); + checkGLcall("glDisable GL_STENCIL_TEST"); +@@ -912,7 +925,11 @@ + + static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { ++#if defined(STAGING_CSMT) + DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; ++#else /* STAGING_CSMT */ ++ DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; ++#endif /* STAGING_CSMT */ + const struct wined3d_gl_info *gl_info = context->gl_info; + + GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); +@@ -926,7 +943,11 @@ + + static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { ++#if defined(STAGING_CSMT) + DWORD mask = state->fb.depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; ++#else /* STAGING_CSMT */ ++ DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0; ++#endif /* STAGING_CSMT */ + const struct wined3d_gl_info *gl_info = context->gl_info; + + gl_info->gl_ops.gl.p_glStencilMask(mask); +@@ -1128,10 +1149,17 @@ + /* drop through */ + + case WINED3D_FOG_NONE: ++#if defined(STAGING_CSMT) + /* Both are none? According to msdn the alpha channel of the specular + * color contains a fog factor. Set it in draw_strided_slow. + * Same happens with Vertexfog on transformed vertices + */ ++#else /* STAGING_CSMT */ ++ /* Both are none? According to msdn the alpha channel of the specular ++ * color contains a fog factor. Set it in drawStridedSlow. ++ * Same happens with Vertexfog on transformed vertices ++ */ ++#endif /* STAGING_CSMT */ + new_source = FOGSOURCE_COORD; + gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR); + checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)"); +@@ -1653,7 +1681,11 @@ + if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS] + || state->render_states[WINED3D_RS_DEPTHBIAS]) + { ++#if defined(STAGING_CSMT) + const struct wined3d_rendertarget_view *depth = state->fb.depth_stencil; ++#else /* STAGING_CSMT */ ++ const struct wined3d_rendertarget_view *depth = state->fb->depth_stencil; ++#endif /* STAGING_CSMT */ + float scale; + + union +@@ -4190,9 +4222,15 @@ + } + } + } else { ++#if defined(STAGING_CSMT) + /* TODO: support blends in draw_strided_slow + * No need to write a FIXME here, this is done after the general vertex decl decoding + */ ++#else /* STAGING_CSMT */ ++ /* TODO: support blends in drawStridedSlow ++ * No need to write a FIXME here, this is done after the general vertex decl decoding ++ */ ++#endif /* STAGING_CSMT */ + WARN("unsupported blending in openGl\n"); + } + } +@@ -4546,7 +4584,11 @@ + + static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { ++#if defined(STAGING_CSMT) + const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; ++#else /* STAGING_CSMT */ ++ const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; ++#endif /* STAGING_CSMT */ + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_viewport vp = state->viewport; + +@@ -4724,7 +4766,11 @@ + } + else + { ++#if defined(STAGING_CSMT) + const struct wined3d_rendertarget_view *target = state->fb.render_targets[0]; ++#else /* STAGING_CSMT */ ++ const struct wined3d_rendertarget_view *target = state->fb->render_targets[0]; ++#endif /* STAGING_CSMT */ + UINT height; + UINT width; + +@@ -4788,7 +4834,11 @@ + + void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) + { ++#if defined(STAGING_CSMT) + unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; ++#else /* STAGING_CSMT */ ++ unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; ++#endif /* STAGING_CSMT */ + const struct wined3d_gl_info *gl_info = context->gl_info; + + TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); +diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c +--- a/dlls/wined3d/stateblock.c ++++ b/dlls/wined3d/stateblock.c +@@ -464,7 +464,9 @@ + struct wined3d_texture *texture; + struct wined3d_buffer *buffer; + struct wined3d_shader *shader; ++#if defined(STAGING_CSMT) + struct wined3d_rendertarget_view *view; ++#endif /* STAGING_CSMT */ + unsigned int i, j; + + if ((decl = state->vertex_declaration)) +@@ -541,6 +543,7 @@ + } + } + } ++#if defined(STAGING_CSMT) + + if (state->fb.depth_stencil) + { +@@ -566,6 +569,7 @@ + } + } + } ++#endif /* STAGING_CSMT */ + } + + void state_cleanup(struct wined3d_state *state) +@@ -593,7 +597,9 @@ + + HeapFree(GetProcessHeap(), 0, state->vs_consts_f); + HeapFree(GetProcessHeap(), 0, state->ps_consts_f); ++#if defined(STAGING_CSMT) + HeapFree(GetProcessHeap(), 0, state->fb.render_targets); ++#endif /* STAGING_CSMT */ + } + + ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock) +@@ -1075,8 +1081,13 @@ + gl_primitive_type = stateblock->state.gl_primitive_type; + prev = device->update_state->gl_primitive_type; + device->update_state->gl_primitive_type = gl_primitive_type; ++#if defined(STAGING_CSMT) + if (gl_primitive_type != prev) + wined3d_cs_emit_set_primitive_type(device->cs, gl_primitive_type); ++#else /* STAGING_CSMT */ ++ if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS)) ++ device_invalidate_state(device, STATE_POINT_ENABLE); ++#endif /* STAGING_CSMT */ + } + + if (stateblock->changed.indices) +@@ -1334,6 +1345,7 @@ + state->sampler_states[i][WINED3D_SAMP_ELEMENT_INDEX] = 0; + /* TODO: Vertex offset in the presampled displacement map. */ + state->sampler_states[i][WINED3D_SAMP_DMAP_OFFSET] = 0; ++#if defined(STAGING_CSMT) + state->textures[i] = NULL; + } + +@@ -1351,6 +1363,19 @@ + unsigned int i; + + state->flags = flags; ++#else /* STAGING_CSMT */ + } -+ -+ device_invalidate_state(cs->device, STATE_SAMPLER(op->stage)); -+ -+ if (new_use_color_key != old_use_color_key) -+ device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE)); -+ -+ if (new_use_color_key) -+ device_invalidate_state(cs->device, STATE_COLOR_KEY); -+} -+ -+void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture) -+{ -+ struct wined3d_cs_set_texture *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_TEXTURE; -+ op->stage = stage; -+ op->texture = texture; -+ -+ cs->ops->submit(cs); -+} -+ -+static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_shader_resource_view *op = data; -+ -+ cs->state.shader_resource_view[op->type][op->view_idx] = op->view; -+ device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); -+} -+ -+void wined3d_cs_emit_set_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type, -+ UINT view_idx, struct wined3d_shader_resource_view *view) -+{ -+ struct wined3d_cs_set_shader_resource_view *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW; -+ op->type = type; -+ op->view_idx = view_idx; -+ op->view = view; -+ -+ cs->ops->submit(cs); -+} -+ -+static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_sampler *op = data; -+ -+ cs->state.sampler[op->type][op->sampler_idx] = op->sampler; -+ device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); -+} -+ -+void wined3d_cs_emit_set_sampler(struct wined3d_cs *cs, enum wined3d_shader_type type, -+ UINT sampler_idx, struct wined3d_sampler *sampler) -+{ -+ struct wined3d_cs_set_sampler *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_SAMPLER; -+ op->type = type; -+ op->sampler_idx = sampler_idx; -+ op->sampler = sampler; -+ -+ cs->ops->submit(cs); -+} -+ -+static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_shader *op = data; -+ -+ cs->state.shader[op->type] = op->shader; -+ device_invalidate_state(cs->device, STATE_SHADER(op->type)); -+ device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING); -+} -+ -+void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) -+{ -+ struct wined3d_cs_set_shader *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_SHADER; -+ op->type = type; -+ op->shader = shader; -+ -+ cs->ops->submit(cs); -+} -+ -+static void wined3d_cs_exec_set_render_state(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_render_state *op = data; -+ -+ cs->state.render_states[op->state] = op->value; -+ device_invalidate_state(cs->device, STATE_RENDER(op->state)); -+} -+ -+void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value) -+{ -+ struct wined3d_cs_set_render_state *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_RENDER_STATE; -+ op->state = state; -+ op->value = value; -+ -+ cs->ops->submit(cs); -+} -+ -+static void wined3d_cs_exec_set_texture_state(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_texture_state *op = data; -+ -+ cs->state.texture_states[op->stage][op->state] = op->value; -+ device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, op->state)); -+} -+ -+void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage, -+ enum wined3d_texture_stage_state state, DWORD value) -+{ -+ struct wined3d_cs_set_texture_state *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_TEXTURE_STATE; -+ op->stage = stage; -+ op->state = state; -+ op->value = value; -+ -+ cs->ops->submit(cs); -+} -+ -+static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) -+{ -+ const struct wined3d_cs_set_sampler_state *op = data; -+ -+ cs->state.sampler_states[op->sampler_idx][op->state] = op->value; -+ device_invalidate_state(cs->device, STATE_SAMPLER(op->sampler_idx)); -+} -+ -+void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, -+ enum wined3d_sampler_state state, DWORD value) -+{ -+ struct wined3d_cs_set_sampler_state *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_SAMPLER_STATE; -+ op->sampler_idx = sampler_idx; -+ op->state = state; -+ op->value = value; -+ -+ cs->ops->submit(cs); +} + -+static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) ++HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, ++ const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, ++ DWORD flags) +{ -+ const struct wined3d_cs_set_transform *op = data; -+ -+ cs->state.transforms[op->state] = *op->matrix; -+ if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices)) -+ device_invalidate_state(cs->device, STATE_TRANSFORM(op->state)); -+} ++ unsigned int i; + -+void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state, -+ const struct wined3d_matrix *matrix) -+{ -+ struct wined3d_cs_set_transform *op; ++ state->flags = flags; ++ state->fb = fb; ++#endif /* STAGING_CSMT */ + + for (i = 0; i < LIGHTMAP_SIZE; i++) + { +@@ -1368,6 +1393,7 @@ + return E_OUTOFMEMORY; + } + ++#if defined(STAGING_CSMT) + if (!(state->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(*state->fb.render_targets) * gl_info->limits.buffers))) + { +@@ -1377,6 +1403,7 @@ + } + state->fb.rt_size = gl_info->limits.buffers; + ++#endif /* STAGING_CSMT */ + if (flags & WINED3D_STATE_INIT_DEFAULT) + state_init_default(state, gl_info); + +@@ -1387,6 +1414,7 @@ + struct wined3d_device *device, enum wined3d_stateblock_type type) + { + HRESULT hr; ++#if defined(STAGING_CSMT) + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; + +@@ -1394,6 +1422,14 @@ + stateblock->device = device; + + if (FAILED(hr = state_init(&stateblock->state, gl_info, d3d_info, 0))) ++#else /* STAGING_CSMT */ ++ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; + -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_TRANSFORM; -+ op->state = state; -+ op->matrix = matrix; ++ stateblock->ref = 1; ++ stateblock->device = device; + -+ cs->ops->submit(cs); -+} ++ if (FAILED(hr = state_init(&stateblock->state, NULL, &device->adapter->gl_info, d3d_info, 0))) ++#endif /* STAGING_CSMT */ + return hr; + + if (FAILED(hr = stateblock_allocate_shader_constants(stateblock))) +diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c +--- a/dlls/wined3d/surface.c ++++ b/dlls/wined3d/surface.c +@@ -36,6 +36,7 @@ + + #define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */ + ++#if defined(STAGING_CSMT) + + static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, + struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, +@@ -44,6 +45,20 @@ + void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) + { + if (surface->rb_multisample || surface->rb_resolved || !list_empty(&surface->renderbuffers)) ++#else /* STAGING_CSMT */ ++static const DWORD surface_simple_locations = ++ WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY ++ | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER; + -+static void wined3d_cs_exec_set_clip_plane(struct wined3d_cs *cs, const void *data) ++static void surface_cleanup(struct wined3d_surface *surface) +{ -+ const struct wined3d_cs_set_clip_plane *op = data; -+ -+ cs->state.clip_planes[op->plane_idx] = *op->plane; -+ device_invalidate_state(cs->device, STATE_CLIPPLANE(op->plane_idx)); -+} ++ struct wined3d_surface *overlay, *cur; + -+void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const struct wined3d_vec4 *plane) -+{ -+ struct wined3d_cs_set_clip_plane *op; ++ TRACE("surface %p.\n", surface); + -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_CLIP_PLANE; -+ op->plane_idx = plane_idx; -+ op->plane = plane; ++ if (surface->pbo || surface->rb_multisample ++ || surface->rb_resolved || !list_empty(&surface->renderbuffers)) ++#endif /* STAGING_CSMT */ + { + struct wined3d_renderbuffer_entry *entry, *entry2; + const struct wined3d_gl_info *gl_info; +@@ -52,6 +67,14 @@ + context = context_acquire(surface->resource.device, NULL); + gl_info = context->gl_info; + ++#if !defined(STAGING_CSMT) ++ if (surface->pbo) ++ { ++ TRACE("Deleting PBO %u.\n", surface->pbo); ++ GL_EXTCALL(glDeleteBuffers(1, &surface->pbo)); ++ } + -+ cs->ops->submit(cs); ++#endif /* STAGING_CSMT */ + if (surface->rb_multisample) + { + TRACE("Deleting multisample renderbuffer %u.\n", surface->rb_multisample); +@@ -78,6 +101,7 @@ + { + DeleteDC(surface->hDC); + DeleteObject(surface->dib.DIBsection); ++#if defined(STAGING_CSMT) + surface->resource.bitmap_data = NULL; + } + +@@ -92,6 +116,10 @@ + BOOL user_mem = surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY; + + TRACE("surface %p.\n", surface); ++#else /* STAGING_CSMT */ ++ surface->dib.bitmap_data = NULL; ++ } ++#endif /* STAGING_CSMT */ + + if (surface->overlay_dest) + list_remove(&surface->overlay_entry); +@@ -103,6 +131,7 @@ + } + + resource_cleanup(&surface->resource); ++#if defined(STAGING_CSMT) + wined3d_cs_emit_surface_cleanup(cs, surface); + + /* Wait for the CS to finish operations on this surface when user memory was in use. +@@ -118,6 +147,17 @@ + + surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent); + surface_cleanup(surface); ++#else /* STAGING_CSMT */ +} + -+static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data) ++void wined3d_surface_destroy(struct wined3d_surface *surface) +{ -+ const struct wined3d_cs_set_color_key *op = data; -+ struct wined3d_texture *texture = op->texture; ++ TRACE("surface %p.\n", surface); + -+ if (op->set) ++ surface_cleanup(surface); ++ surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent); ++ HeapFree(GetProcessHeap(), 0, surface); ++#endif /* STAGING_CSMT */ + } + + void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context, +@@ -372,7 +412,9 @@ + BITMAPINFO *b_info; + int extraline = 0; + DWORD *masks; ++#if defined(STAGING_CSMT) + UINT row_pitch, slice_pitch; ++#endif /* STAGING_CSMT */ + + TRACE("surface %p.\n", surface); + +@@ -418,11 +460,18 @@ + + b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + /* TODO: Is there a nicer way to force a specific alignment? (8 byte for ddraw) */ ++#if defined(STAGING_CSMT) + wined3d_resource_get_pitch(&surface->resource, &row_pitch, &slice_pitch); + b_info->bmiHeader.biWidth = row_pitch / format->byte_count; + b_info->bmiHeader.biHeight = 0 - surface->resource.height - extraline; + b_info->bmiHeader.biSizeImage = (surface->resource.height + extraline) + * row_pitch; ++#else /* STAGING_CSMT */ ++ b_info->bmiHeader.biWidth = wined3d_surface_get_pitch(surface) / format->byte_count; ++ b_info->bmiHeader.biHeight = 0 - surface->resource.height - extraline; ++ b_info->bmiHeader.biSizeImage = (surface->resource.height + extraline) ++ * wined3d_surface_get_pitch(surface); ++#endif /* STAGING_CSMT */ + b_info->bmiHeader.biPlanes = 1; + b_info->bmiHeader.biBitCount = format->byte_count * 8; + +@@ -464,7 +513,11 @@ + TRACE("Creating a DIB section with size %dx%dx%d, size=%d.\n", + b_info->bmiHeader.biWidth, b_info->bmiHeader.biHeight, + b_info->bmiHeader.biBitCount, b_info->bmiHeader.biSizeImage); ++#if defined(STAGING_CSMT) + surface->dib.DIBsection = CreateDIBSection(0, b_info, DIB_RGB_COLORS, &surface->resource.bitmap_data, 0, 0); ++#else /* STAGING_CSMT */ ++ surface->dib.DIBsection = CreateDIBSection(0, b_info, DIB_RGB_COLORS, &surface->dib.bitmap_data, 0, 0); ++#endif /* STAGING_CSMT */ + + if (!surface->dib.DIBsection) + { +@@ -473,7 +526,11 @@ + return HRESULT_FROM_WIN32(GetLastError()); + } + ++#if defined(STAGING_CSMT) + TRACE("DIBSection at %p.\n", surface->resource.bitmap_data); ++#else /* STAGING_CSMT */ ++ TRACE("DIBSection at %p.\n", surface->dib.bitmap_data); ++#endif /* STAGING_CSMT */ + surface->dib.bitmap_size = b_info->bmiHeader.biSizeImage; + + HeapFree(GetProcessHeap(), 0, b_info); +@@ -487,6 +544,116 @@ + return WINED3D_OK; + } + ++#if !defined(STAGING_CSMT) ++static void surface_get_memory(const struct wined3d_surface *surface, struct wined3d_bo_address *data, ++ DWORD location) ++{ ++ if (location & WINED3D_LOCATION_BUFFER) + { -+ switch (op->flags) -+ { -+ case WINED3D_CKEY_DST_BLT: -+ texture->async.dst_blt_color_key = op->color_key; -+ texture->async.color_key_flags |= WINED3D_CKEY_DST_BLT; -+ break; -+ -+ case WINED3D_CKEY_DST_OVERLAY: -+ texture->async.dst_overlay_color_key = op->color_key; -+ texture->async.color_key_flags |= WINED3D_CKEY_DST_OVERLAY; -+ break; -+ -+ case WINED3D_CKEY_SRC_BLT: -+ if (texture == cs->state.textures[0]) -+ { -+ device_invalidate_state(cs->device, STATE_COLOR_KEY); -+ if (!(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)) -+ device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE)); -+ } -+ -+ texture->async.src_blt_color_key = op->color_key; -+ texture->async.color_key_flags |= WINED3D_CKEY_SRC_BLT; -+ break; -+ -+ case WINED3D_CKEY_SRC_OVERLAY: -+ texture->async.src_overlay_color_key = op->color_key; -+ texture->async.color_key_flags |= WINED3D_CKEY_SRC_OVERLAY; -+ break; -+ } ++ data->addr = NULL; ++ data->buffer_object = surface->pbo; ++ return; + } -+ else ++ if (location & WINED3D_LOCATION_USER_MEMORY) + { -+ switch (op->flags) -+ { -+ case WINED3D_CKEY_DST_BLT: -+ texture->async.color_key_flags &= ~WINED3D_CKEY_DST_BLT; -+ break; -+ -+ case WINED3D_CKEY_DST_OVERLAY: -+ texture->async.color_key_flags &= ~WINED3D_CKEY_DST_OVERLAY; -+ break; -+ -+ case WINED3D_CKEY_SRC_BLT: -+ if (texture == cs->state.textures[0] && texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) -+ device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE)); -+ -+ texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_BLT; -+ break; -+ -+ case WINED3D_CKEY_SRC_OVERLAY: -+ texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_OVERLAY; -+ break; -+ } ++ data->addr = surface->user_memory; ++ data->buffer_object = 0; ++ return; + } -+} -+ -+void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture, -+ WORD flags, const struct wined3d_color_key *color_key) -+{ -+ struct wined3d_cs_set_color_key *op; -+ -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_COLOR_KEY; -+ op->texture = texture; -+ op->flags = flags; -+ if (color_key) ++ if (location & WINED3D_LOCATION_DIB) + { -+ op->color_key = *color_key; -+ op->set = 1; ++ data->addr = surface->dib.bitmap_data; ++ data->buffer_object = 0; ++ return; ++ } ++ if (location & WINED3D_LOCATION_SYSMEM) ++ { ++ data->addr = surface->resource.heap_memory; ++ data->buffer_object = 0; ++ return; + } -+ else -+ op->set = 0; + -+ cs->ops->submit(cs); ++ ERR("Unexpected locations %s.\n", wined3d_debug_location(location)); ++ data->addr = NULL; ++ data->buffer_object = 0; +} + -+static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data) ++static void surface_prepare_buffer(struct wined3d_surface *surface) +{ -+ const struct wined3d_cs_set_material *op = data; -+ -+ cs->state.material = *op->material; -+ device_invalidate_state(cs->device, STATE_MATERIAL); -+} ++ struct wined3d_context *context; ++ GLenum error; ++ const struct wined3d_gl_info *gl_info; + -+void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material) -+{ -+ struct wined3d_cs_set_material *op; ++ if (surface->pbo) ++ return; + -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_SET_MATERIAL; -+ op->material = material; ++ context = context_acquire(surface->resource.device, NULL); ++ gl_info = context->gl_info; + -+ cs->ops->submit(cs); -+} ++ GL_EXTCALL(glGenBuffers(1, &surface->pbo)); ++ error = gl_info->gl_ops.gl.p_glGetError(); ++ if (!surface->pbo || error != GL_NO_ERROR) ++ ERR("Failed to create a PBO with error %s (%#x).\n", debug_glerror(error), error); + -+static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) -+{ -+ struct wined3d_adapter *adapter = cs->device->adapter; -+ HRESULT hr; ++ TRACE("Binding PBO %u.\n", surface->pbo); + -+ state_cleanup(&cs->state); -+ memset(&cs->state, 0, sizeof(cs->state)); -+ if (FAILED(hr = state_init(&cs->state, &cs->fb, &adapter->gl_info, &adapter->d3d_info, -+ WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) -+ ERR("Failed to initialize CS state, hr %#x.\n", hr); -+} ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); ++ checkGLcall("glBindBuffer"); + -+void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) -+{ -+ struct wined3d_cs_reset_state *op; ++ GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, surface->resource.size + 4, ++ NULL, GL_STREAM_DRAW)); ++ checkGLcall("glBufferData"); + -+ op = cs->ops->require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_RESET_STATE; ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); ++ checkGLcall("glBindBuffer"); + -+ cs->ops->submit(cs); ++ context_release(context); +} + -+static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = -+{ -+#endif /* STAGING_CSMT */ -+ /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, -+ /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, -+ /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, -+ /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication, -+ /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport, -+ /* WINED3D_CS_OP_SET_SCISSOR_RECT */ wined3d_cs_exec_set_scissor_rect, -+ /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, -+ /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, -+ /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, -+ /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, -+ /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, -+ /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output, -+ /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, -+ /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, -+ /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, -+ /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, -+ /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, -+ /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, -+ /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, -+ /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, -+ /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, -+ /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, -+ /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, -+ /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, -+ /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, -+ /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, -+#if defined(STAGING_CSMT) -+ /* WINED3D_CS_OP_SET_VS_CONSTS_F */ wined3d_cs_exec_set_vs_consts_f, -+ /* WINED3D_CS_OP_SET_VS_CONSTS_B */ wined3d_cs_exec_set_vs_consts_b, -+ /* WINED3D_CS_OP_SET_VS_CONSTS_I */ wined3d_cs_exec_set_vs_consts_i, -+ /* WINED3D_CS_OP_SET_PS_CONSTS_F */ wined3d_cs_exec_set_ps_consts_f, -+ /* WINED3D_CS_OP_SET_PS_CONSTS_B */ wined3d_cs_exec_set_ps_consts_b, -+ /* WINED3D_CS_OP_SET_PS_CONSTS_I */ wined3d_cs_exec_set_ps_consts_i, -+ /* WINED3D_CS_OP_GLFINISH */ wined3d_cs_exec_glfinish, -+ /* WINED3D_CS_OP_SET_BASE_VERTEX_INDEX */ wined3d_cs_exec_set_base_vertex_index, -+ /* WINED3D_CS_OP_SET_PRIMITIVE_TYPE */ wined3d_cs_exec_set_primitive_type, -+ /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, -+ /* WINED3D_CS_OP_SET_LIGHT_ENABLE */ wined3d_cs_exec_set_light_enable, -+ /* WINED3D_CS_OP_BLT */ wined3d_cs_exec_blt, -+ /* WINED3D_CS_OP_CLEAR_RTV */ wined3d_cs_exec_clear_rtv, -+ /* WINED3D_CS_OP_RESOURCE_CHANGED */ wined3d_cs_exec_resource_changed, -+ /* WINED3D_CS_OP_RESOURCE_MAP */ wined3d_cs_exec_resource_map, -+ /* WINED3D_CS_OP_RESOURCE_UNMAP */ wined3d_cs_exec_resource_unmap, -+ /* WINED3D_CS_OP_BUFFER_SWAP_MEM */ wined3d_cs_exec_buffer_swap_mem, -+ /* WINED3D_CS_OP_BUFFER_INVALIDATE_RANGE */ wined3d_cs_exec_buffer_invalidate_bo_range, -+ /* WINED3D_CS_OP_BUFFER_PRELOAD */ wined3d_cs_exec_buffer_preload, -+ /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, -+ /* WINED3D_CS_OP_QUERY_DESTROY */ wined3d_cs_exec_query_destroy, -+ /* WINED3D_CS_OP_UPDATE_SURFACE */ wined3d_cs_exec_update_surface, -+ /* WINED3D_CS_OP_TEXTURE_PRELOAD */ wined3d_cs_exec_texture_preload, -+ /* WINED3D_CS_OP_SURFACE_PRELOAD */ wined3d_cs_exec_surface_preload, -+ /* WINED3D_CS_OP_UPDATE_TEXTURE */ wined3d_cs_exec_update_texture, -+ /* WINED3D_CS_OP_EVICT_RESOURCE */ wined3d_cs_exec_evict_resource, -+ /* WINED3D_CS_OP_VIEW_DESTROY */ wined3d_cs_exec_view_destroy, -+ /* WINED3D_CS_OP_VDECL_DESTROY */ wined3d_cs_exec_vertex_declaration_destroy, -+ /* WINED3D_CS_OP_SHADER_CLEANUP */ wined3d_cs_exec_shader_cleanup, -+ /* WINED3D_CS_OP_CREATE_VBO */ wined3d_cs_exec_create_vbo, -+ /* WINED3D_CS_OP_RESOURCE_CLEANUP */ wined3d_cs_exec_resource_cleanup, -+ /* WINED3D_CS_OP_BUFFER_CLEANUP */ wined3d_cs_exec_buffer_cleanup, -+ /* WINED3D_CS_OP_VOLUME_CLEANUP */ wined3d_cs_exec_volume_cleanup, -+ /* WINED3D_CS_OP_SURFACE_CLEANUP */ wined3d_cs_exec_surface_cleanup, -+ /* WINED3D_CS_OP_TEXTURE_CLEANUP */ wined3d_cs_exec_texture_cleanup, -+ /* WINED3D_CS_OP_CREATE_DUMMY_TEXTURES */ wined3d_cs_exec_create_dummy_textures, -+ /* WINED3D_CS_OP_CREATE_SWAPCHAIN_CONTEXT */ wined3d_cs_exec_create_swapchain_context, -+ /* WINED3D_CS_OP_DELETE_GL_CONTEXTS */ wined3d_cs_exec_delete_gl_contexts, -+ /* WINED3D_CS_OP_GETDC */ wined3d_cs_exec_getdc, -+ /* WINED3D_CS_OP_RELEASEDC */ wined3d_cs_exec_releasedc, -+ /* WINED3D_CS_OP_SAMPLER_DESTROY */ wined3d_cs_exec_sampler_destroy, -+ /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource, -+}; -+ -+static inline void *_wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, BOOL prio) ++static void surface_prepare_system_memory(struct wined3d_surface *surface) +{ -+ struct wined3d_cs_queue *queue = prio ? &cs->prio_queue : &cs->queue; -+ size_t queue_size = sizeof(queue->data) / sizeof(*queue->data); -+ -+ if (queue_size - size < queue->head) -+ { -+ struct wined3d_cs_skip *skip; -+ size_t nop_size = queue_size - queue->head; ++ TRACE("surface %p.\n", surface); + -+ skip = _wined3d_cs_mt_require_space(cs, nop_size, prio); -+ if (nop_size < sizeof(*skip)) -+ { -+ skip->opcode = WINED3D_CS_OP_NOP; -+ } -+ else -+ { -+ skip->opcode = WINED3D_CS_OP_SKIP; -+ skip->size = nop_size; -+ } ++ if (surface->resource.heap_memory) ++ return; + -+ if (prio) -+ cs->ops->submit_prio(cs, nop_size); -+ else -+ cs->ops->submit(cs, nop_size); ++ /* Whatever surface we have, make sure that there is memory allocated ++ * for the downloaded copy, or a PBO to map. */ ++ if (!wined3d_resource_allocate_sysmem(&surface->resource)) ++ ERR("Failed to allocate system memory.\n"); + -+ assert(!queue->head); -+ } ++ if (surface->locations & WINED3D_LOCATION_SYSMEM) ++ ERR("Surface without system memory has WINED3D_LOCATION_SYSMEM set.\n"); ++} + -+ while(1) ++void surface_prepare_map_memory(struct wined3d_surface *surface) ++{ ++ switch (surface->resource.map_binding) + { -+ LONG head = queue->head; -+ LONG tail = *((volatile LONG *)&queue->tail); -+ LONG new_pos; -+ /* Empty */ -+ if (head == tail) -+ break; -+ /* Head ahead of tail, take care of wrap-around */ -+ new_pos = (head + size) & (WINED3D_CS_QUEUE_SIZE - 1); -+ if (head > tail && (new_pos || tail)) -+ break; -+ /* Tail ahead of head, but still enough space */ -+ if (new_pos < tail && new_pos) ++ case WINED3D_LOCATION_SYSMEM: ++ surface_prepare_system_memory(surface); + break; + -+ TRACE("Waiting for free space. Head %u, tail %u, want %u\n", head, tail, -+ (unsigned int) size); -+ } ++ case WINED3D_LOCATION_USER_MEMORY: ++ if (!surface->user_memory) ++ ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but surface->user_memory is NULL.\n"); ++ break; + -+ return &queue->data[queue->head]; -+} ++ case WINED3D_LOCATION_DIB: ++ if (!surface->dib.bitmap_data) ++ ERR("Map binding is set to WINED3D_LOCATION_DIB but surface->dib.bitmap_data is NULL.\n"); ++ break; + -+static inline void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size) -+{ -+ return _wined3d_cs_mt_require_space(cs, size, FALSE); -+} ++ case WINED3D_LOCATION_BUFFER: ++ surface_prepare_buffer(surface); ++ break; + -+static inline void *wined3d_cs_mt_require_space_prio(struct wined3d_cs *cs, size_t size) -+{ -+ return _wined3d_cs_mt_require_space(cs, size, TRUE); ++ default: ++ ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); ++ } +} + -+/* FIXME: wined3d_device_uninit_3d() should either flush and wait, or be an -+ * OP itself. */ -+static void wined3d_cs_emit_stop(struct wined3d_cs *cs) ++#endif /* STAGING_CSMT */ + static void surface_evict_sysmem(struct wined3d_surface *surface) + { + /* In some conditions the surface memory must not be freed: +@@ -497,8 +664,12 @@ + return; + + wined3d_resource_free_sysmem(&surface->resource); ++#if defined(STAGING_CSMT) + surface->resource.map_heap_memory = NULL; + wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); ++#else /* STAGING_CSMT */ ++ surface_invalidate_location(surface, WINED3D_LOCATION_SYSMEM); ++#endif /* STAGING_CSMT */ + } + + static BOOL surface_use_pbo(const struct wined3d_surface *surface) +@@ -583,7 +754,11 @@ + } + + if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) ++#if defined(STAGING_CSMT) + surface->resource.locations = WINED3D_LOCATION_DISCARDED; ++#else /* STAGING_CSMT */ ++ surface->locations = WINED3D_LOCATION_DISCARDED; ++#endif /* STAGING_CSMT */ + + if (surface_use_pbo(surface)) + surface->resource.map_binding = WINED3D_LOCATION_BUFFER; +@@ -591,6 +766,7 @@ + return WINED3D_OK; + } + ++#if defined(STAGING_CSMT) + static void surface_frontbuffer_updated(struct wined3d_surface *surface) + { + struct wined3d_context *context = NULL; +@@ -607,6 +783,54 @@ + wined3d_resource_load_location(&surface->resource, context, surface->container->resource.draw_binding); + if (context) + context_release(context); ++#else /* STAGING_CSMT */ ++static void surface_unmap(struct wined3d_surface *surface) +{ -+ struct wined3d_cs_stop *op; -+ -+ op = wined3d_cs_mt_require_space(cs, sizeof(*op)); -+ op->opcode = WINED3D_CS_OP_STOP; ++ struct wined3d_device *device = surface->resource.device; ++ const struct wined3d_gl_info *gl_info; ++ struct wined3d_context *context; + -+ wined3d_cs_mt_submit(cs, sizeof(*op)); -+} ++ TRACE("surface %p.\n", surface); + -+static void wined3d_cs_mt_finish(struct wined3d_cs *cs) -+{ -+ BOOL fence; ++ memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); + -+ if (cs->thread_id == GetCurrentThreadId()) ++ switch (surface->resource.map_binding) + { -+ static BOOL once; -+ if (!once) -+ { -+ FIXME("flush_and_wait called from cs thread\n"); -+ once = TRUE; -+ } -+ return; -+ } ++ case WINED3D_LOCATION_SYSMEM: ++ case WINED3D_LOCATION_USER_MEMORY: ++ case WINED3D_LOCATION_DIB: ++ break; + -+ wined3d_cs_emit_fence(cs, &fence); ++ case WINED3D_LOCATION_BUFFER: ++ context = context_acquire(device, NULL); ++ gl_info = context->gl_info; + -+ /* A busy wait should be fine, we're not supposed to have to wait very -+ * long. */ -+ while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); -+} ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); ++ GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); ++ checkGLcall("glUnmapBuffer"); ++ context_release(context); ++ break; + -+static void wined3d_cs_mt_finish_prio(struct wined3d_cs *cs) -+{ -+ BOOL fence; ++ default: ++ ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); ++ } + -+ if (cs->thread_id == GetCurrentThreadId()) ++ if (surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)) + { -+ static BOOL once; -+ if (!once) -+ { -+ FIXME("flush_and_wait called from cs thread\n"); -+ once = TRUE; -+ } ++ TRACE("Not dirtified, nothing to do.\n"); + return; + } + -+ wined3d_cs_emit_fence_prio(cs, &fence); -+ -+ /* A busy wait should be fine, we're not supposed to have to wait very -+ * long. */ -+ while (!InterlockedCompareExchange(&fence, TRUE, TRUE)); -+} -+ -+static const struct wined3d_cs_ops wined3d_cs_mt_ops = -+{ -+ wined3d_cs_mt_require_space, - wined3d_cs_mt_require_space_prio, - wined3d_cs_mt_submit, - wined3d_cs_mt_submit_prio, -@@ -3293,5 +4127,80 @@ - ERR("Closing event failed.\n"); - } ++ if (surface->container->swapchain && surface->container->swapchain->front_buffer == surface->container) ++ { ++ context = context_acquire(device, surface); ++ surface_load_location(surface, context, surface->container->resource.draw_binding); ++ context_release(context); ++ } ++ else if (surface->container->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) ++ FIXME("Depth / stencil buffer locking is not implemented.\n"); ++#endif /* STAGING_CSMT */ + } + + static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r) +@@ -667,9 +891,15 @@ + + /* Make sure the locations are up-to-date. Loading the destination + * surface isn't required if the entire surface is overwritten. */ ++#if defined(STAGING_CSMT) + wined3d_resource_load_location(&src_surface->resource, context, src_location); + if (!surface_is_full_rect(dst_surface, dst_rect)) + wined3d_resource_load_location(&dst_surface->resource, context, dst_location); ++#else /* STAGING_CSMT */ ++ surface_load_location(src_surface, context, src_location); ++ if (!surface_is_full_rect(dst_surface, dst_rect)) ++ surface_load_location(dst_surface, context, dst_location); ++#endif /* STAGING_CSMT */ + else + wined3d_surface_prepare(dst_surface, context, dst_location); +@@ -760,9 +990,15 @@ + * surface isn't required if the entire surface is overwritten. (And is + * in fact harmful if we're being called by surface_load_location() with + * the purpose of loading the destination surface.) */ ++#if defined(STAGING_CSMT) + wined3d_resource_load_location(&src_surface->resource, old_ctx, src_location); + if (!surface_is_full_rect(dst_surface, &dst_rect)) + wined3d_resource_load_location(&dst_surface->resource, old_ctx, dst_location); +#else /* STAGING_CSMT */ -+}; -+ -+static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) -+{ -+ if (size > cs->data_size) ++ surface_load_location(src_surface, old_ctx, src_location); ++ if (!surface_is_full_rect(dst_surface, &dst_rect)) ++ surface_load_location(dst_surface, old_ctx, dst_location); ++#endif /* STAGING_CSMT */ + else + wined3d_surface_prepare(dst_surface, old_ctx, dst_location); + +@@ -923,8 +1159,13 @@ + { + struct wined3d_resource *resource = &surface->container->resource; + struct wined3d_device *device = resource->device; ++#if defined(STAGING_CSMT) + struct wined3d_rendertarget_view view; + struct wined3d_texture *texture = surface->container; ++#else /* STAGING_CSMT */ ++ struct wined3d_rendertarget_view_desc view_desc; ++ struct wined3d_rendertarget_view *view; ++#endif /* STAGING_CSMT */ + const struct blit_shader *blitter; + HRESULT hr; + +@@ -935,6 +1176,7 @@ + return WINED3DERR_INVALIDCALL; + } + ++#if defined(STAGING_CSMT) + view.resource = &surface->container->resource; + view.parent = NULL; + view.parent_ops = &wined3d_null_parent_ops; +@@ -946,6 +1188,21 @@ + view.sub_resource_idx = surface->texture_layer * texture->level_count + surface->texture_level; + + hr = blitter->depth_fill(device, &view, rect, depth); ++#else /* STAGING_CSMT */ ++ view_desc.format_id = resource->format->id; ++ view_desc.u.texture.level_idx = surface->texture_level; ++ view_desc.u.texture.layer_idx = surface->texture_layer; ++ view_desc.u.texture.layer_count = 1; ++ if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, ++ resource, NULL, &wined3d_null_parent_ops, &view))) + { -+ void *new_data; -+ -+ size = max( size, cs->data_size * 2 ); -+ if (!(new_data = HeapReAlloc(GetProcessHeap(), 0, cs->data, size))) -+ return NULL; -+ -+ cs->data_size = size; -+ cs->data = new_data; ++ ERR("Failed to create rendertarget view, hr %#x.\n", hr); ++ return hr; + } + -+ return cs->data; -+} -+ -+static void wined3d_cs_st_submit(struct wined3d_cs *cs) ++ hr = blitter->depth_fill(device, view, rect, depth); ++ wined3d_rendertarget_view_decref(view); ++#endif /* STAGING_CSMT */ + + return hr; + } +@@ -968,6 +1225,18 @@ + return WINED3D_OK; + } + ++#if !defined(STAGING_CSMT) ++/* Context activation is done by the caller. */ ++static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) +{ -+ enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)cs->data; ++ GL_EXTCALL(glDeleteBuffers(1, &surface->pbo)); ++ checkGLcall("glDeleteBuffers(1, &surface->pbo)"); + -+ wined3d_cs_op_handlers[opcode](cs, cs->data); ++ surface->pbo = 0; ++ surface_invalidate_location(surface, WINED3D_LOCATION_BUFFER); +} + -+static const struct wined3d_cs_ops wined3d_cs_st_ops = -+{ -+ wined3d_cs_st_require_space, -+ wined3d_cs_st_submit, -+}; -+ -+struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) -+{ -+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; -+ struct wined3d_cs *cs; -+ -+ if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs)))) -+ return NULL; -+ -+ if (!(cs->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(*cs->fb.render_targets) * gl_info->limits.buffers))) -+ { -+ HeapFree(GetProcessHeap(), 0, cs); -+ return NULL; -+ } -+ -+ if (FAILED(state_init(&cs->state, &cs->fb, gl_info, &device->adapter->d3d_info, -+ WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT))) -+ { -+ HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); -+ HeapFree(GetProcessHeap(), 0, cs); -+ return NULL; ++#endif /* STAGING_CSMT */ + static ULONG surface_resource_incref(struct wined3d_resource *resource) + { + struct wined3d_surface *surface = surface_from_resource(resource); +@@ -1001,6 +1270,7 @@ + + if (resource->pool == WINED3D_POOL_DEFAULT) + { ++#if defined(STAGING_CSMT) + /* Default pool resources are supposed to be destroyed before Reset is called. + * Implicit resources stay however. So this means we have an implicit render target + * or depth stencil. The content may be destroyed, but we still have to tear down +@@ -1014,6 +1284,40 @@ + wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); + wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); + } ++#else /* STAGING_CSMT */ ++ /* Default pool resources are supposed to be destroyed before Reset is called. ++ * Implicit resources stay however. So this means we have an implicit render target ++ * or depth stencil. The content may be destroyed, but we still have to tear down ++ * opengl resources, so we cannot leave early. ++ * ++ * Put the surfaces into sysmem, and reset the content. The D3D content is undefined, ++ * but we can't set the sysmem INDRAWABLE because when we're rendering the swapchain ++ * or the depth stencil into an FBO the texture or render buffer will be removed ++ * and all flags get lost */ ++ if (resource->usage & WINED3DUSAGE_DEPTHSTENCIL) ++ { ++ surface_validate_location(surface, WINED3D_LOCATION_DISCARDED); ++ surface_invalidate_location(surface, ~WINED3D_LOCATION_DISCARDED); ++ } ++ else ++ { ++ surface_prepare_system_memory(surface); ++ memset(surface->resource.heap_memory, 0, surface->resource.size); ++ surface_validate_location(surface, WINED3D_LOCATION_SYSMEM); ++ surface_invalidate_location(surface, ~WINED3D_LOCATION_SYSMEM); ++ } + } -+ -+ cs->ops = &wined3d_cs_st_ops; -+ cs->device = device; -+ -+ cs->data_size = WINED3D_INITIAL_CS_SIZE; -+ if (!(cs->data = HeapAlloc(GetProcessHeap(), 0, cs->data_size))) ++ else + { -+ HeapFree(GetProcessHeap(), 0, cs); -+ return NULL; ++ surface_prepare_map_memory(surface); ++ surface_load_location(surface, context, surface->resource.map_binding); ++ surface_invalidate_location(surface, ~surface->resource.map_binding); + } + -+ return cs; -+} -+ -+void wined3d_cs_destroy(struct wined3d_cs *cs) -+{ -+ state_cleanup(&cs->state); -+ HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); -+ HeapFree(GetProcessHeap(), 0, cs->data); ++ /* Destroy PBOs, but load them into real sysmem before */ ++ if (surface->pbo) ++ surface_remove_pbo(surface, gl_info); +#endif /* STAGING_CSMT */ - HeapFree(GetProcessHeap(), 0, cs); + + /* Destroy fbo render buffers. This is needed for implicit render targets, for + * all application-created targets the application has to release the surface +@@ -1057,6 +1361,7 @@ + return WINED3DERR_INVALIDCALL; } -diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c ---- a/dlls/wined3d/texture.c -+++ b/dlls/wined3d/texture.c -@@ -68,8 +68,10 @@ - { - ERR("Failed to allocate sub-resource array.\n"); - resource_cleanup(&texture->resource); + +#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - texture->resource.device->cs->ops->finish(texture->resource.device->cs); + static void wined3d_surface_location_invalidated(struct wined3d_resource *resource, DWORD location) + { + struct wined3d_surface *surface = surface_from_resource(resource); +@@ -1072,6 +1377,21 @@ + { + surface_private_setup, + surface_frontbuffer_updated, ++#else /* STAGING_CSMT */ ++static const struct wined3d_resource_ops surface_resource_ops = ++{ ++ surface_resource_incref, ++ surface_resource_decref, ++ surface_unload, ++ surface_resource_sub_resource_map, ++ surface_resource_sub_resource_unmap, ++}; ++ ++static const struct wined3d_surface_ops surface_ops = ++{ ++ surface_private_setup, ++ surface_unmap, +#endif /* STAGING_CSMT */ - return E_OUTOFMEMORY; - } + }; -@@ -114,6 +116,7 @@ - resource_unload(&texture->resource); + /***************************************************************************** +@@ -1115,6 +1435,7 @@ + return WINED3D_OK; } +#if defined(STAGING_CSMT) - void wined3d_texture_cleanup_cs(struct wined3d_texture *texture) + static void gdi_surface_frontbuffer_updated(struct wined3d_surface *surface) { - wined3d_texture_unload_gl_texture(texture); -@@ -126,6 +129,12 @@ - UINT sub_count = texture->level_count * texture->layer_count; - UINT i; - struct wined3d_device *device = texture->resource.device; + x11_copy_to_screen(surface->container->swapchain, &surface->lockedRect); +@@ -1124,6 +1445,23 @@ + { + gdi_surface_private_setup, + gdi_surface_frontbuffer_updated, +#else /* STAGING_CSMT */ -+static void wined3d_texture_cleanup(struct wined3d_texture *texture) ++static void gdi_surface_unmap(struct wined3d_surface *surface) +{ -+ UINT sub_count = texture->level_count * texture->layer_count; -+ UINT i; ++ TRACE("surface %p.\n", surface); ++ ++ /* Tell the swapchain to update the screen. */ ++ if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) ++ x11_copy_to_screen(surface->container->swapchain, &surface->lockedRect); ++ ++ memset(&surface->lockedRect, 0, sizeof(RECT)); ++} ++ ++static const struct wined3d_surface_ops gdi_surface_ops = ++{ ++ gdi_surface_private_setup, ++ gdi_surface_unmap, +#endif /* STAGING_CSMT */ + }; - TRACE("texture %p.\n", texture); - -@@ -137,8 +146,14 @@ - texture->texture_ops->texture_sub_resource_cleanup(sub_resource); + /* This call just downloads data, the caller is responsible for binding the +@@ -1142,7 +1480,11 @@ + return; } +#if defined(STAGING_CSMT) - resource_cleanup(&texture->resource); - wined3d_cs_emit_texture_cleanup(device->cs, texture); + wined3d_resource_get_memory(&surface->resource, dst_location, &data); +#else /* STAGING_CSMT */ -+ wined3d_texture_unload_gl_texture(texture); -+ HeapFree(GetProcessHeap(), 0, texture->sub_resources); -+ resource_cleanup(&texture->resource); ++ surface_get_memory(surface, &data, dst_location); +#endif /* STAGING_CSMT */ - } - - void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) -@@ -422,10 +437,16 @@ - if (!refcount) + if (surface->container->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) { +@@ -1170,6 +1512,7 @@ + void *mem; + GLenum gl_format = format->glFormat; + GLenum gl_type = format->glType; +#if defined(STAGING_CSMT) - void *parent = texture->resource.parent; - const struct wined3d_parent_ops *parent_ops = texture->resource.parent_ops; - wined3d_texture_cleanup(texture); - parent_ops->wined3d_object_destroyed(parent); + UINT src_pitch = 0; + UINT dst_row_pitch, dst_slice_pitch; + +@@ -1178,6 +1521,16 @@ + unsigned char alignment = surface->resource.device->surface_alignment; + src_pitch = format->byte_count * surface->pow2Width; + wined3d_resource_get_pitch(&surface->resource, &dst_row_pitch, &dst_slice_pitch); +#else /* STAGING_CSMT */ -+ wined3d_texture_cleanup(texture); -+ texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent); -+ HeapFree(GetProcessHeap(), 0, texture); ++ int src_pitch = 0; ++ int dst_pitch = 0; ++ ++ if (surface->flags & SFLAG_NONPOW2) ++ { ++ unsigned char alignment = surface->resource.device->surface_alignment; ++ src_pitch = format->byte_count * surface->pow2Width; ++ dst_pitch = wined3d_surface_get_pitch(surface); +#endif /* STAGING_CSMT */ - } + src_pitch = (src_pitch + alignment - 1) & ~(alignment - 1); + mem = HeapAlloc(GetProcessHeap(), 0, src_pitch * surface->pow2Height); + } +@@ -1264,12 +1617,21 @@ + * won't be released, and doesn't have to be re-read. */ + src_data = mem; + dst_data = data.addr; ++#if defined(STAGING_CSMT) + TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_row_pitch); + for (y = 0; y < surface->resource.height; ++y) + { + memcpy(dst_data, src_data, dst_row_pitch); + src_data += src_pitch; + dst_data += dst_row_pitch; ++#else /* STAGING_CSMT */ ++ TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_pitch); ++ for (y = 0; y < surface->resource.height; ++y) ++ { ++ memcpy(dst_data, src_data, dst_pitch); ++ src_data += src_pitch; ++ dst_data += dst_pitch; ++#endif /* STAGING_CSMT */ + } - return refcount; -@@ -497,8 +518,15 @@ + HeapFree(GetProcessHeap(), 0, mem); +@@ -1393,6 +1755,7 @@ - void CDECL wined3d_texture_preload(struct wined3d_texture *texture) + static BOOL surface_check_block_align(struct wined3d_surface *surface, const struct wined3d_box *box) { +#if defined(STAGING_CSMT) - const struct wined3d_device *device = texture->resource.device; - wined3d_cs_emit_texture_preload(device->cs, texture); -+#else /* STAGING_CSMT */ -+ struct wined3d_context *context; -+ context = context_acquire(texture->resource.device, NULL); -+ wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); -+ context_release(context); -+#endif /* STAGING_CSMT */ + if ((box->left >= box->right) + || (box->top >= box->bottom) + || (box->right > surface->resource.width) +@@ -1403,6 +1766,34 @@ } - void * CDECL wined3d_texture_get_parent(const struct wined3d_texture *texture) -@@ -527,6 +555,7 @@ + BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) ++#else /* STAGING_CSMT */ ++ UINT width_mask, height_mask; ++ ++ if (!box->left && !box->top ++ && box->right == surface->resource.width ++ && box->bottom == surface->resource.height) ++ return TRUE; ++ ++ if ((box->left >= box->right) ++ || (box->top >= box->bottom) ++ || (box->right > surface->resource.width) ++ || (box->bottom > surface->resource.height)) ++ return FALSE; ++ ++ /* This assumes power of two block sizes, but NPOT block sizes would be ++ * silly anyway. */ ++ width_mask = surface->resource.format->block_width - 1; ++ height_mask = surface->resource.format->block_height - 1; ++ ++ if (!(box->left & width_mask) && !(box->top & height_mask) ++ && !(box->right & width_mask) && !(box->bottom & height_mask)) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++static BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) ++#endif /* STAGING_CSMT */ + { + struct wined3d_box box = {rect->left, rect->top, rect->right, rect->bottom, 0, 1}; - if (texture->lod != lod) - { +@@ -1421,7 +1812,11 @@ + UINT update_w, update_h; + UINT dst_w, dst_h; + RECT r, dst_rect; +#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - { - struct wined3d_device *device = texture->resource.device; -@@ -534,6 +563,7 @@ - device->cs->ops->finish(device->cs); - } - + UINT src_row_pitch, src_slice_pitch; ++#else /* STAGING_CSMT */ ++ UINT src_pitch; +#endif /* STAGING_CSMT */ - texture->lod = lod; + POINT p; - texture->texture_rgb.base_level = ~0u; -@@ -652,10 +682,14 @@ + TRACE("dst_surface %p, dst_point %s, src_surface %p, src_rect %s.\n", +@@ -1492,11 +1887,17 @@ + return WINED3DERR_INVALIDCALL; } - if (device->d3d_initialized) +#if defined(STAGING_CSMT) - { - wined3d_cs_emit_evict_resource(device->cs, &surface->resource); - device->cs->ops->finish(device->cs); - } + /* Use surface_cpu_blt() instead of uploading directly if we need + * conversion. Avoid calling wined3d_surface_blt() since that goes + * through the CS. */ + if (dst_format->convert || wined3d_format_get_color_key_conversion(dst_surface->container, FALSE)) + return surface_cpu_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT); +#else /* STAGING_CSMT */ -+ texture->resource.resource_ops->resource_unload(&texture->resource); ++ /* Use wined3d_surface_blt() instead of uploading directly if we need conversion. */ ++ if (dst_format->convert || wined3d_format_get_color_key_conversion(dst_surface->container, FALSE)) ++ return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT); +#endif /* STAGING_CSMT */ - texture->resource.format = format; - texture->resource.multisample_type = multisample_type; -@@ -790,11 +824,19 @@ - struct wined3d_surface *surface = surface_from_resource(sub_resource); - struct wined3d_context *context; + context = context_acquire(dst_surface->resource.device, NULL); + gl_info = context->gl_info; +@@ -1507,6 +1908,7 @@ + if (update_w == dst_w && update_h == dst_h) + wined3d_texture_prepare_texture(dst_surface->container, context, FALSE); + else ++#if defined(STAGING_CSMT) + wined3d_resource_load_location(&dst_surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE); + +@@ -1520,6 +1922,21 @@ + + wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_resource_invalidate_location(&dst_surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); ++#else /* STAGING_CSMT */ ++ surface_load_location(dst_surface, context, WINED3D_LOCATION_TEXTURE_RGB); ++ wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE); ++ ++ surface_get_memory(src_surface, &data, src_surface->locations); ++ src_pitch = wined3d_surface_get_pitch(src_surface); ++ ++ wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect, ++ src_pitch, dst_point, FALSE, wined3d_const_bo_address(&data)); ++ ++ context_release(context); ++ ++ surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); ++ surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); ++#endif /* STAGING_CSMT */ + + return WINED3D_OK; + } +@@ -1633,6 +2050,7 @@ + if (surface->resource.pool == WINED3D_POOL_SCRATCH) + ERR("Not supported on scratch surfaces.\n"); +#if defined(STAGING_CSMT) - context = context_acquire(surface->resource.device, NULL); - wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - context_release(context); - wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); + if (surface->resource.locations & location) + { + TRACE("surface is already in texture\n"); +@@ -1641,6 +2059,16 @@ + TRACE("Reloading because surface is dirty.\n"); + + wined3d_resource_load_location(&surface->resource, context, location); +#else /* STAGING_CSMT */ -+ surface_prepare_map_memory(surface); -+ context = context_acquire(surface->resource.device, NULL); -+ surface_load_location(surface, context, surface->resource.map_binding); -+ context_release(context); -+ surface_invalidate_location(surface, ~surface->resource.map_binding); ++ if (surface->locations & location) ++ { ++ TRACE("surface is already in texture\n"); ++ return; ++ } ++ TRACE("Reloading because surface is dirty.\n"); ++ ++ surface_load_location(surface, context, location); +#endif /* STAGING_CSMT */ + surface_evict_sysmem(surface); } - static void texture2d_sub_resource_cleanup(struct wined3d_resource *sub_resource) -@@ -806,12 +848,25 @@ +@@ -1723,10 +2151,28 @@ - static void texture2d_sub_resource_invalidate_location(struct wined3d_resource *sub_resource, DWORD location) + DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface) { +#if defined(STAGING_CSMT) - wined3d_resource_invalidate_location(sub_resource, location); - } - - static void texture2d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) - { - wined3d_resource_validate_location(sub_resource, location); + UINT row_pitch, slice_pitch; + const struct wined3d_resource *resource = &surface->resource; + wined3d_resource_get_pitch(resource, &row_pitch, &slice_pitch); + return row_pitch; +#else /* STAGING_CSMT */ -+ struct wined3d_surface *surface = surface_from_resource(sub_resource); ++ unsigned int alignment; ++ DWORD pitch; + -+ surface_invalidate_location(surface, location); -+} ++ TRACE("surface %p.\n", surface); + -+static void texture2d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) -+{ -+ struct wined3d_surface *surface = surface_from_resource(sub_resource); ++ if (surface->pitch) ++ return surface->pitch; + -+ surface_validate_location(surface, location); ++ alignment = surface->resource.device->surface_alignment; ++ pitch = wined3d_format_calculate_pitch(surface->resource.format, surface->resource.width); ++ pitch = (pitch + alignment - 1) & ~(alignment - 1); ++ ++ TRACE("Returning %u.\n", pitch); ++ ++ return pitch; +#endif /* STAGING_CSMT */ } - static void texture2d_sub_resource_upload_data(struct wined3d_resource *sub_resource, -@@ -890,6 +945,7 @@ - - if (gl_info->supported[APPLE_CLIENT_STORAGE]) - { + HRESULT CDECL wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y) +@@ -1851,6 +2297,7 @@ + { + DeleteDC(surface->hDC); + DeleteObject(surface->dib.DIBsection); +#if defined(STAGING_CSMT) - if (surface->flags & (SFLAG_NONPOW2) - || texture->flags & WINED3D_TEXTURE_CONVERTED) - { -@@ -898,12 +954,26 @@ - * WINED3D_TEXTURE_CONVERTED: The conversion destination memory is freed after loading the surface - * heap_memory == NULL: Not defined in the extension. Seems to disable client storage effectively - */ + surface->resource.bitmap_data = NULL; + surface->flags &= ~SFLAG_DIBSECTION; + create_dib = TRUE; +@@ -1859,6 +2306,15 @@ + surface->resource.locations = 0; + wined3d_resource_free_sysmem(&surface->resource); + surface->resource.map_heap_memory = NULL; +#else /* STAGING_CSMT */ -+ if (surface->flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION) -+ || texture->flags & WINED3D_TEXTURE_CONVERTED -+ || !surface->resource.heap_memory) -+ { -+ /* In some cases we want to disable client storage. -+ * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches -+ * SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues... -+ * WINED3D_TEXTURE_CONVERTED: The conversion destination memory is freed after loading the surface -+ * heap_memory == NULL: Not defined in the extension. Seems to disable client storage effectively -+ */ -+#endif /* STAGING_CSMT */ - surface->flags &= ~SFLAG_CLIENT; - } - else - { -+#if defined(STAGING_CSMT) - wined3d_resource_prepare_system_memory(&surface->resource); - ++ surface->dib.bitmap_data = NULL; ++ surface->flags &= ~SFLAG_DIBSECTION; ++ create_dib = TRUE; ++ } ++ ++ surface->locations = 0; ++ wined3d_resource_free_sysmem(&surface->resource); +#endif /* STAGING_CSMT */ - surface->flags |= SFLAG_CLIENT; - mem = surface->resource.heap_memory; - -@@ -994,6 +1064,7 @@ - return wined3d_surface_unmap(surface_from_resource(sub_resource)); - } -+#if defined(STAGING_CSMT) - static void wined3d_texture_load_location_invalidated(struct wined3d_resource *resource, DWORD location) - { - ERR("Should not be called on textures.\n"); -@@ -1006,6 +1077,7 @@ - ERR("Should not be called on textures.\n"); - } + width = texture_resource->width; + height = texture_resource->height; +@@ -1884,6 +2340,7 @@ + else + surface->flags &= ~SFLAG_NONPOW2; -+#endif /* STAGING_CSMT */ - static const struct wined3d_resource_ops texture2d_resource_ops = - { - texture_resource_incref, -@@ -1013,8 +1085,10 @@ - wined3d_texture_unload, - texture2d_resource_sub_resource_map, - texture2d_resource_sub_resource_unmap, +#if defined(STAGING_CSMT) - wined3d_texture_load_location_invalidated, - wined3d_texture_load_location, + if ((surface->resource.user_memory = mem)) + { + surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY; +@@ -1904,6 +2361,27 @@ + surface->resource.size = wined3d_format_calculate_size(texture_resource->format, + 1, width, height, 1); + surface->resource.custom_row_pitch = wined3d_format_calculate_pitch(texture_resource->format, width); ++#else /* STAGING_CSMT */ ++ if ((surface->user_memory = mem)) ++ { ++ surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY; ++ valid_location = WINED3D_LOCATION_USER_MEMORY; ++ } ++ surface->pitch = pitch; ++ surface->resource.format = texture_resource->format; ++ surface->resource.multisample_type = texture_resource->multisample_type; ++ surface->resource.multisample_quality = texture_resource->multisample_quality; ++ if (surface->pitch) ++ { ++ surface->resource.size = height * surface->pitch; ++ } ++ else ++ { ++ /* User memory surfaces don't have the regular surface alignment. */ ++ surface->resource.size = wined3d_format_calculate_size(texture_resource->format, ++ 1, width, height, 1); ++ surface->pitch = wined3d_format_calculate_pitch(texture_resource->format, width); +#endif /* STAGING_CSMT */ - }; + } - static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, -@@ -1031,7 +1105,9 @@ - if (WINED3DFMT_UNKNOWN >= desc->format) + /* The format might be changed to a format that needs conversion. +@@ -1926,11 +2404,19 @@ + + if (!valid_location) { - WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); +#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); -+#endif /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; + wined3d_resource_prepare_system_memory(&surface->resource); + valid_location = WINED3D_LOCATION_SYSMEM; } -@@ -1041,6 +1117,7 @@ - if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); -+#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } -@@ -1049,6 +1126,14 @@ - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); - HeapFree(GetProcessHeap(), 0, texture); + wined3d_resource_validate_location(&surface->resource, valid_location); +#else /* STAGING_CSMT */ -+ return WINED3DERR_INVALIDCALL; -+ } ++ surface_prepare_system_memory(surface); ++ valid_location = WINED3D_LOCATION_SYSMEM; ++ } + -+ if (levels != 1) -+ { -+ WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); -+#endif /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; - } - } -@@ -1069,7 +1154,9 @@ - else - { - WARN("Attempted to create a NPOT cube texture (edge length %u) without GL support.\n", desc->width); -+#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); -+#endif /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; - } - } -@@ -1079,7 +1166,9 @@ - surface_flags, device, parent, parent_ops, &texture2d_resource_ops))) - { - WARN("Failed to initialize texture, returning %#x\n", hr); -+#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); ++ surface_validate_location(surface, valid_location); +#endif /* STAGING_CSMT */ - return hr; - } -@@ -1142,7 +1231,9 @@ - if (WINED3DFMT_UNKNOWN >= desc->format) - { - WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); + return WINED3D_OK; + } +@@ -2289,6 +2775,7 @@ + + static struct wined3d_texture *surface_convert_format(struct wined3d_surface *source, enum wined3d_format_id to_fmt) + { +#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); + void *dst_data = NULL, *src_data = NULL; + UINT src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; + const struct d3dfmt_converter_desc *conv; +@@ -2297,6 +2784,13 @@ + struct wined3d_surface *dst; + struct wined3d_context *context = NULL; + struct wined3d_device *device = source->resource.device; ++#else /* STAGING_CSMT */ ++ struct wined3d_map_desc src_map, dst_map; ++ const struct d3dfmt_converter_desc *conv; ++ struct wined3d_texture *ret = NULL; ++ struct wined3d_resource_desc desc; ++ struct wined3d_surface *dst; +#endif /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; + + conv = find_converter(source->resource.format->id, to_fmt); + if (!conv) +@@ -2321,6 +2815,7 @@ } + dst = surface_from_resource(wined3d_texture_get_sub_resource(ret, 0)); -@@ -1173,7 +1264,9 @@ - else - { - WARN("Attempted to create a mipmapped NPOT texture without unconditional NPOT support.\n"); -+#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); -+#endif /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; - } - } -@@ -1186,6 +1279,7 @@ - if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n"); +#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } -@@ -1194,6 +1288,14 @@ - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); - HeapFree(GetProcessHeap(), 0, texture); + wined3d_resource_get_pitch(&source->resource, &src_row_pitch, &src_slice_pitch); + wined3d_resource_get_pitch(&ret->resource, &dst_row_pitch, &dst_slice_pitch); + +@@ -2361,6 +2856,32 @@ + if (context) + context_release(context); + return NULL; +#else /* STAGING_CSMT */ -+ return WINED3DERR_INVALIDCALL; -+ } ++ memset(&src_map, 0, sizeof(src_map)); ++ memset(&dst_map, 0, sizeof(dst_map)); + -+ if (levels != 1) -+ { -+ WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); -+#endif /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; - } - } -@@ -1202,7 +1304,9 @@ - surface_flags, device, parent, parent_ops, &texture2d_resource_ops))) - { - WARN("Failed to initialize texture, returning %#x.\n", hr); -+#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); ++ if (FAILED(wined3d_surface_map(source, &src_map, NULL, WINED3D_MAP_READONLY))) ++ { ++ ERR("Failed to lock the source surface.\n"); ++ wined3d_texture_decref(ret); ++ return NULL; ++ } ++ if (FAILED(wined3d_surface_map(dst, &dst_map, NULL, 0))) ++ { ++ ERR("Failed to lock the destination surface.\n"); ++ wined3d_surface_unmap(source); ++ wined3d_texture_decref(ret); ++ return NULL; ++ } ++ ++ conv->convert(src_map.data, dst_map.data, src_map.row_pitch, dst_map.row_pitch, ++ source->resource.width, source->resource.height); ++ ++ wined3d_surface_unmap(dst); ++ wined3d_surface_unmap(source); ++ ++ return ret; +#endif /* STAGING_CSMT */ - return hr; - } + } -@@ -1288,12 +1392,25 @@ + static HRESULT _Blt_ColorFill(BYTE *buf, unsigned int width, unsigned int height, +@@ -2423,6 +2944,7 @@ - static void texture3d_sub_resource_invalidate_location(struct wined3d_resource *sub_resource, DWORD location) + HRESULT wined3d_surface_unmap(struct wined3d_surface *surface) { +#if defined(STAGING_CSMT) - wined3d_resource_invalidate_location(sub_resource, location); - } + HRESULT hr; + TRACE("surface %p.\n", surface); - static void texture3d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) - { - wined3d_resource_validate_location(sub_resource, location); +@@ -2433,6 +2955,20 @@ + memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); + + return hr; +#else /* STAGING_CSMT */ -+ struct wined3d_volume *volume = volume_from_resource(sub_resource); ++ TRACE("surface %p.\n", surface); + -+ wined3d_volume_invalidate_location(volume, location); -+} ++ if (!surface->resource.map_count) ++ { ++ WARN("Trying to unmap unmapped surface.\n"); ++ return WINEDDERR_NOTLOCKED; ++ } ++ --surface->resource.map_count; + -+static void texture3d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) -+{ -+ struct wined3d_volume *volume = volume_from_resource(sub_resource); ++ surface->surface_ops->surface_unmap(surface); + -+ wined3d_volume_validate_location(volume, location); ++ return WINED3D_OK; +#endif /* STAGING_CSMT */ } - static void texture3d_sub_resource_upload_data(struct wined3d_resource *sub_resource, -@@ -1303,7 +1420,11 @@ - struct wined3d_const_bo_address addr; - unsigned int row_pitch, slice_pitch; - -+#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(sub_resource, &row_pitch, &slice_pitch); -+#else /* STAGING_CSMT */ -+ wined3d_volume_get_pitch(volume, &row_pitch, &slice_pitch); + HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, +@@ -2440,6 +2976,21 @@ + { + const struct wined3d_format *format = surface->resource.format; + unsigned int fmt_flags = surface->container->resource.format_flags; ++#if !defined(STAGING_CSMT) ++ struct wined3d_device *device = surface->resource.device; ++ struct wined3d_context *context; ++ const struct wined3d_gl_info *gl_info; ++ BYTE *base_memory; ++ ++ TRACE("surface %p, map_desc %p, box %s, flags %#x.\n", ++ surface, map_desc, debug_box(box), flags); ++ ++ if (surface->resource.map_count) ++ { ++ WARN("Surface is already mapped.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } +#endif /* STAGING_CSMT */ - if (row_pitch != data->row_pitch || slice_pitch != data->slice_pitch) - FIXME("Ignoring row/slice pitch (%u/%u).\n", data->row_pitch, data->slice_pitch); -@@ -1328,7 +1449,11 @@ - void *mem = NULL; + if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box + && !surface_check_block_align(surface, box)) +@@ -2451,6 +3002,13 @@ + return WINED3DERR_INVALIDCALL; + } - if (gl_info->supported[APPLE_CLIENT_STORAGE] && !format->convert -+#if defined(STAGING_CSMT) - && wined3d_resource_prepare_system_memory(&volume->resource)) -+#else /* STAGING_CSMT */ -+ && volume_prepare_system_memory(volume)) ++#if !defined(STAGING_CSMT) ++ ++surface->resource.map_count; ++ ++ if (!(surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) ++ WARN("Trying to lock unlockable surface.\n"); ++ +#endif /* STAGING_CSMT */ - { - TRACE("Enabling GL_UNPACK_CLIENT_STORAGE_APPLE for volume %p\n", volume); - gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); -@@ -1405,6 +1530,7 @@ - if (WINED3DFMT_UNKNOWN >= desc->format) - { - WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); -+#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; + /* Performance optimization: Count how often a surface is mapped, if it is + * mapped regularly do not throw away the system memory copy. This avoids + * the need to download the surface from OpenGL all the time. The surface +@@ -2466,6 +3024,7 @@ + } } -@@ -1413,6 +1539,14 @@ + ++#if defined(STAGING_CSMT) + if (box) { - WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture); - HeapFree(GetProcessHeap(), 0, texture); + surface->lockedRect.left = box->left; +@@ -2555,6 +3114,119 @@ + DWORD slice_pitch, pitch; + + wined3d_resource_get_memory(&surface->resource, dst_location, &data); +#else /* STAGING_CSMT */ -+ return WINED3DERR_INVALIDCALL; ++ surface_prepare_map_memory(surface); ++ if (flags & WINED3D_MAP_DISCARD) ++ { ++ TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", ++ wined3d_debug_location(surface->resource.map_binding)); ++ surface_validate_location(surface, surface->resource.map_binding); + } ++ else ++ { ++ struct wined3d_context *context = NULL; + -+ if (!gl_info->supported[EXT_TEXTURE3D]) ++ if (surface->resource.usage & WINED3DUSAGE_DYNAMIC) ++ WARN_(d3d_perf)("Mapping a dynamic surface without WINED3D_MAP_DISCARD.\n"); ++ ++ if (surface->resource.device->d3d_initialized) ++ context = context_acquire(surface->resource.device, NULL); ++ surface_load_location(surface, context, surface->resource.map_binding); ++ if (context) ++ context_release(context); ++ } ++ ++ if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) ++ surface_invalidate_location(surface, ~surface->resource.map_binding); ++ ++ switch (surface->resource.map_binding) + { -+ WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture); ++ case WINED3D_LOCATION_SYSMEM: ++ base_memory = surface->resource.heap_memory; ++ break; ++ ++ case WINED3D_LOCATION_USER_MEMORY: ++ base_memory = surface->user_memory; ++ break; ++ ++ case WINED3D_LOCATION_DIB: ++ base_memory = surface->dib.bitmap_data; ++ break; ++ ++ case WINED3D_LOCATION_BUFFER: ++ context = context_acquire(device, NULL); ++ gl_info = context->gl_info; ++ ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); ++ base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); ++ checkGLcall("map PBO"); ++ ++ context_release(context); ++ break; ++ ++ default: ++ ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); ++ base_memory = NULL; ++ } ++ ++ if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) ++ map_desc->row_pitch = surface->resource.width * format->byte_count; ++ else ++ map_desc->row_pitch = wined3d_surface_get_pitch(surface); ++ map_desc->slice_pitch = surface->resource.height * map_desc->row_pitch; ++ ++ if (!box) ++ { ++ map_desc->data = base_memory; ++ surface->lockedRect.left = 0; ++ surface->lockedRect.top = 0; ++ surface->lockedRect.right = surface->resource.width; ++ surface->lockedRect.bottom = surface->resource.height; ++ } ++ else ++ { ++ if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) ++ { ++ /* Compressed textures are block based, so calculate the offset of ++ * the block that contains the top-left pixel of the locked rectangle. */ ++ map_desc->data = base_memory ++ + ((box->top / format->block_height) * map_desc->row_pitch) ++ + ((box->left / format->block_width) * format->block_byte_count); ++ } ++ else ++ { ++ map_desc->data = base_memory ++ + (map_desc->row_pitch * box->top) ++ + (box->left * format->byte_count); ++ } ++ surface->lockedRect.left = box->left; ++ surface->lockedRect.top = box->top; ++ surface->lockedRect.right = box->right; ++ surface->lockedRect.bottom = box->bottom; ++ } ++ ++ TRACE("Locked rect %s.\n", wine_dbgstr_rect(&surface->lockedRect)); ++ TRACE("Returning memory %p, pitch %u.\n", map_desc->data, map_desc->row_pitch); ++ ++ return WINED3D_OK; ++} ++ ++static void read_from_framebuffer(struct wined3d_surface *surface, ++ struct wined3d_context *old_ctx, DWORD dst_location) ++{ ++ struct wined3d_device *device = surface->resource.device; ++ const struct wined3d_gl_info *gl_info; ++ struct wined3d_context *context = old_ctx; ++ struct wined3d_surface *restore_rt = NULL; ++ BYTE *mem; ++ BYTE *row, *top, *bottom; ++ int i; ++ BOOL srcIsUpsideDown; ++ struct wined3d_bo_address data; ++ ++ surface_get_memory(surface, &data, dst_location); +#endif /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; + + if (surface != old_ctx->current_rt) + { +@@ -2594,8 +3266,13 @@ } -@@ -1422,6 +1556,7 @@ - if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); + /* Setup pixel store pack state -- to glReadPixels into the correct place */ +#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); - return WINED3DERR_INVALIDCALL; - } -@@ -1430,6 +1565,14 @@ - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); - HeapFree(GetProcessHeap(), 0, texture); + wined3d_resource_get_pitch(&surface->resource, &pitch, &slice_pitch); + gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, pitch / surface->resource.format->byte_count); +#else /* STAGING_CSMT */ -+ return WINED3DERR_INVALIDCALL; -+ } ++ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, ++ wined3d_surface_get_pitch(surface) / surface->resource.format->byte_count); ++#endif /* STAGING_CSMT */ + checkGLcall("glPixelStorei"); + + gl_info->gl_ops.gl.p_glReadPixels(0, 0, +@@ -2612,6 +3289,10 @@ + { + /* glReadPixels returns the image upside down, and there is no way to prevent this. + * Flip the lines in software. */ ++#if !defined(STAGING_CSMT) ++ UINT pitch = wined3d_surface_get_pitch(surface); + -+ if (levels != 1) -+ { -+ WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); +#endif /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; - } - } -@@ -1457,7 +1600,9 @@ - { - WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n", - desc->width, desc->height, desc->depth); + if (!(row = HeapAlloc(GetProcessHeap(), 0, pitch))) + goto error; + +@@ -2856,8 +3537,13 @@ + + /* The texture is now most up to date - If the surface is a render target + * and has a drawable, this path is never entered. */ +#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); + wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_resource_invalidate_location(&dst_surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); ++#else /* STAGING_CSMT */ ++ surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); ++ surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); +#endif /* STAGING_CSMT */ - return WINED3DERR_INVALIDCALL; - } - } -@@ -1467,7 +1612,9 @@ - 0, device, parent, parent_ops, &texture3d_resource_ops))) - { - WARN("Failed to initialize texture, returning %#x.\n", hr); + } + + /* Uses the hardware to stretch and flip the image */ +@@ -2925,7 +3611,11 @@ + checkGLcall("glEnable(texture_target)"); + + /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */ +#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, texture); + wined3d_resource_invalidate_location(&src_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); ++#else /* STAGING_CSMT */ ++ src_surface->locations &= ~WINED3D_LOCATION_TEXTURE_RGB; +#endif /* STAGING_CSMT */ - return hr; } -@@ -1568,6 +1715,9 @@ - if (FAILED(hr)) - { - WARN("Failed to initialize texture, returning %#x.\n", hr); -+#if !defined(STAGING_CSMT) -+ HeapFree(GetProcessHeap(), 0, object); -+#endif /* STAGING_CSMT */ - return hr; + /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag +@@ -3122,6 +3812,7 @@ + checkGLcall("glDeleteTextures(1, &backup)"); } -diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c ---- a/dlls/wined3d/surface.c -+++ b/dlls/wined3d/surface.c -@@ -36,6 +36,7 @@ - - #define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */ - +#if defined(STAGING_CSMT) - - static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, -@@ -44,6 +45,20 @@ - void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) - { - if (surface->rb_multisample || surface->rb_resolved || !list_empty(&surface->renderbuffers)) + if (wined3d_settings.cs_multithreaded) + gl_info->gl_ops.gl.p_glFinish(); + else if (wined3d_settings.strict_draw_ordering) +@@ -3133,6 +3824,17 @@ + * and has a drawable, this path is never entered. */ + wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_resource_invalidate_location(&dst_surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); +#else /* STAGING_CSMT */ -+static const DWORD surface_simple_locations = -+ WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY -+ | WINED3D_LOCATION_DIB | WINED3D_LOCATION_BUFFER; -+ -+static void surface_cleanup(struct wined3d_surface *surface) -+{ -+ struct wined3d_surface *overlay, *cur; ++ if (wined3d_settings.strict_draw_ordering) ++ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + -+ TRACE("surface %p.\n", surface); ++ context_release(context); + -+ if (surface->pbo || surface->rb_multisample -+ || surface->rb_resolved || !list_empty(&surface->renderbuffers)) ++ /* The texture is now most up to date - If the surface is a render target ++ * and has a drawable, this path is never entered. */ ++ surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); ++ surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); +#endif /* STAGING_CSMT */ - { - struct wined3d_renderbuffer_entry *entry, *entry2; - const struct wined3d_gl_info *gl_info; -@@ -52,6 +67,14 @@ - context = context_acquire(surface->resource.device, NULL); - gl_info = context->gl_info; + } + + /* Front buffer coordinates are always full screen coordinates, but our GL +@@ -3187,9 +3889,15 @@ + + gl_info = context->gl_info; -+#if !defined(STAGING_CSMT) -+ if (surface->pbo) -+ { -+ TRACE("Deleting PBO %u.\n", surface->pbo); -+ GL_EXTCALL(glDeleteBuffers(1, &surface->pbo)); -+ } -+ -+#endif /* STAGING_CSMT */ - if (surface->rb_multisample) - { - TRACE("Deleting multisample renderbuffer %u.\n", surface->rb_multisample); -@@ -78,6 +101,7 @@ - { - DeleteDC(surface->hDC); - DeleteObject(surface->dib.DIBsection); +#if defined(STAGING_CSMT) - surface->resource.bitmap_data = NULL; - } + /* Make sure the surface is up-to-date. This should probably use + * wined3d_resource_load_location() and worry about the destination + * surface too, unless we're overwriting it completely. */ ++#else /* STAGING_CSMT */ ++ /* Make sure the surface is up-to-date. This should probably use ++ * surface_load_location() and worry about the destination surface too, ++ * unless we're overwriting it completely. */ ++#endif /* STAGING_CSMT */ + wined3d_texture_load(src_surface->container, context, FALSE); -@@ -92,6 +116,10 @@ - BOOL user_mem = surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY; + /* Activate the destination context, set it up for blitting */ +@@ -3232,9 +3940,13 @@ + /* Leave the opengl state valid for blitting */ + device->blitter->unset_shader(context->gl_info); - TRACE("surface %p.\n", surface); ++#if defined(STAGING_CSMT) + if (wined3d_settings.cs_multithreaded) + gl_info->gl_ops.gl.p_glFinish(); + else if (wined3d_settings.strict_draw_ordering +#else /* STAGING_CSMT */ -+ surface->dib.bitmap_data = NULL; -+ } ++ if (wined3d_settings.strict_draw_ordering ++#endif /* STAGING_CSMT */ + || (dst_surface->container->swapchain + && dst_surface->container->swapchain->front_buffer == dst_surface->container)) + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ +@@ -3247,8 +3959,13 @@ + { + struct wined3d_resource *resource = &s->container->resource; + struct wined3d_device *device = resource->device; ++#if defined(STAGING_CSMT) + struct wined3d_rendertarget_view view; + struct wined3d_texture *texture = s->container; ++#else /* STAGING_CSMT */ ++ struct wined3d_rendertarget_view_desc view_desc; ++ struct wined3d_rendertarget_view *view; +#endif /* STAGING_CSMT */ + const struct blit_shader *blitter; + HRESULT hr; - if (surface->overlay_dest) - list_remove(&surface->overlay_entry); -@@ -103,6 +131,7 @@ +@@ -3259,6 +3976,7 @@ + return WINED3DERR_INVALIDCALL; } - resource_cleanup(&surface->resource); +#if defined(STAGING_CSMT) - wined3d_cs_emit_surface_cleanup(cs, surface); + /* Can't incref / decref the resource here. This is executed inside the worker + * thread. Playing with the refcount here makes the worker thread visible to + * the client lib. Problems occur when the worker thread happens to hold the +@@ -3275,6 +3993,21 @@ + view.sub_resource_idx = s->texture_layer * texture->level_count + s->texture_level; + + hr = blitter->color_fill(device, &view, rect, color); ++#else /* STAGING_CSMT */ ++ view_desc.format_id = resource->format->id; ++ view_desc.u.texture.level_idx = s->texture_level; ++ view_desc.u.texture.layer_idx = s->texture_layer; ++ view_desc.u.texture.layer_count = 1; ++ if (FAILED(hr = wined3d_rendertarget_view_create(&view_desc, ++ resource, NULL, &wined3d_null_parent_ops, &view))) ++ { ++ ERR("Failed to create rendertarget view, hr %#x.\n", hr); ++ return hr; ++ } ++ ++ hr = blitter->color_fill(device, view, rect, color); ++ wined3d_rendertarget_view_decref(view); ++#endif /* STAGING_CSMT */ - /* Wait for the CS to finish operations on this surface when user memory was in use. -@@ -118,6 +147,17 @@ + return hr; + } +@@ -3284,8 +4017,13 @@ + enum wined3d_texture_filter_type filter) + { + struct wined3d_device *device = dst_surface->resource.device; ++#if defined(STAGING_CSMT) + struct wined3d_swapchain *src_swapchain, *dst_swapchain; + const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->state.fb.render_targets[0]); ++#else /* STAGING_CSMT */ ++ const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]); ++ struct wined3d_swapchain *src_swapchain, *dst_swapchain; ++#endif /* STAGING_CSMT */ - surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent); - surface_cleanup(surface); + TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, blt_fx %p, filter %s.\n", + dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), +@@ -3476,6 +4214,7 @@ + { + TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h); + ++#if defined(STAGING_CSMT) + if (((surface->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) && !(location & WINED3D_LOCATION_TEXTURE_RGB)) + || (!(surface->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) + && (location & WINED3D_LOCATION_TEXTURE_RGB))) +@@ -3484,6 +4223,15 @@ + surface->ds_current_size.cx = w; + surface->ds_current_size.cy = h; + surface->resource.locations = location; +#else /* STAGING_CSMT */ -+} -+ -+void wined3d_surface_destroy(struct wined3d_surface *surface) -+{ -+ TRACE("surface %p.\n", surface); ++ if (((surface->locations & WINED3D_LOCATION_TEXTURE_RGB) && !(location & WINED3D_LOCATION_TEXTURE_RGB)) ++ || (!(surface->locations & WINED3D_LOCATION_TEXTURE_RGB) && (location & WINED3D_LOCATION_TEXTURE_RGB))) ++ wined3d_texture_set_dirty(surface->container); + -+ surface_cleanup(surface); -+ surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent); -+ HeapFree(GetProcessHeap(), 0, surface); ++ surface->ds_current_size.cx = w; ++ surface->ds_current_size.cy = h; ++ surface->locations = location; +#endif /* STAGING_CSMT */ } - void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context, -@@ -372,7 +412,9 @@ - BITMAPINFO *b_info; - int extraline = 0; - DWORD *masks; + /* Context activation is done by the caller. */ +@@ -3498,7 +4246,11 @@ + /* TODO: Make this work for modes other than FBO */ + if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return; + +#if defined(STAGING_CSMT) - UINT row_pitch, slice_pitch; + if (!(surface->resource.locations & location)) ++#else /* STAGING_CSMT */ ++ if (!(surface->locations & location)) +#endif /* STAGING_CSMT */ + { + w = surface->ds_current_size.cx; + h = surface->ds_current_size.cy; +@@ -3525,6 +4277,7 @@ + } - TRACE("surface %p.\n", surface); - -@@ -418,11 +460,18 @@ - - b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - /* TODO: Is there a nicer way to force a specific alignment? (8 byte for ddraw) */ + wined3d_surface_prepare(surface, context, location); +#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(&surface->resource, &row_pitch, &slice_pitch); - b_info->bmiHeader.biWidth = row_pitch / format->byte_count; - b_info->bmiHeader.biHeight = 0 - surface->resource.height - extraline; - b_info->bmiHeader.biSizeImage = (surface->resource.height + extraline) - * row_pitch; + if (surface->resource.locations & WINED3D_LOCATION_DISCARDED) + { + TRACE("Surface was discarded, no need copy data.\n"); +@@ -3539,6 +4292,22 @@ + { + FIXME("No up to date depth stencil location.\n"); + surface->resource.locations |= location; +#else /* STAGING_CSMT */ -+ b_info->bmiHeader.biWidth = wined3d_surface_get_pitch(surface) / format->byte_count; -+ b_info->bmiHeader.biHeight = 0 - surface->resource.height - extraline; -+ b_info->bmiHeader.biSizeImage = (surface->resource.height + extraline) -+ * wined3d_surface_get_pitch(surface); ++ if (surface->locations & WINED3D_LOCATION_DISCARDED) ++ { ++ TRACE("Surface was discarded, no need copy data.\n"); ++ surface->locations &= ~WINED3D_LOCATION_DISCARDED; ++ surface->locations |= location; ++ surface->ds_current_size.cx = surface->resource.width; ++ surface->ds_current_size.cy = surface->resource.height; ++ return; ++ } ++ ++ if (!surface->locations) ++ { ++ FIXME("No up to date depth stencil location.\n"); ++ surface->locations |= location; +#endif /* STAGING_CSMT */ - b_info->bmiHeader.biPlanes = 1; - b_info->bmiHeader.biBitCount = format->byte_count * 8; + surface->ds_current_size.cx = surface->resource.width; + surface->ds_current_size.cy = surface->resource.height; + return; +@@ -3602,9 +4371,13 @@ + + context_invalidate_state(context, STATE_FRAMEBUFFER); -@@ -464,7 +513,11 @@ - TRACE("Creating a DIB section with size %dx%dx%d, size=%d.\n", - b_info->bmiHeader.biWidth, b_info->bmiHeader.biHeight, - b_info->bmiHeader.biBitCount, b_info->bmiHeader.biSizeImage); +#if defined(STAGING_CSMT) - surface->dib.DIBsection = CreateDIBSection(0, b_info, DIB_RGB_COLORS, &surface->resource.bitmap_data, 0, 0); + if (wined3d_settings.cs_multithreaded) + gl_info->gl_ops.gl.p_glFinish(); + else if (wined3d_settings.strict_draw_ordering) +#else /* STAGING_CSMT */ -+ surface->dib.DIBsection = CreateDIBSection(0, b_info, DIB_RGB_COLORS, &surface->dib.bitmap_data, 0, 0); ++ if (wined3d_settings.strict_draw_ordering) +#endif /* STAGING_CSMT */ - - if (!surface->dib.DIBsection) - { -@@ -473,7 +526,11 @@ - return HRESULT_FROM_WIN32(GetLastError()); + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ } + else if (location == WINED3D_LOCATION_DRAWABLE) +@@ -3620,9 +4393,13 @@ + + context_invalidate_state(context, STATE_FRAMEBUFFER); +#if defined(STAGING_CSMT) - TRACE("DIBSection at %p.\n", surface->resource.bitmap_data); + if (wined3d_settings.cs_multithreaded) + gl_info->gl_ops.gl.p_glFinish(); + else if (wined3d_settings.strict_draw_ordering) +#else /* STAGING_CSMT */ -+ TRACE("DIBSection at %p.\n", surface->dib.bitmap_data); ++ if (wined3d_settings.strict_draw_ordering) +#endif /* STAGING_CSMT */ - surface->dib.bitmap_size = b_info->bmiHeader.biSizeImage; + gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ + } + else +@@ -3630,6 +4407,7 @@ + ERR("Invalid location (%#x) specified.\n", location); + } - HeapFree(GetProcessHeap(), 0, b_info); -@@ -487,6 +544,116 @@ - return WINED3D_OK; - } ++#if defined(STAGING_CSMT) + surface->resource.locations |= location; + surface->ds_current_size.cx = surface->resource.width; + surface->ds_current_size.cy = surface->resource.height; +@@ -3662,6 +4440,124 @@ -+#if !defined(STAGING_CSMT) -+static void surface_get_memory(const struct wined3d_surface *surface, struct wined3d_bo_address *data, -+ DWORD location) + FIXME("Can't load surface %p with location flags %s into sysmem.\n", + surface, wined3d_debug_location(surface->resource.locations)); ++#else /* STAGING_CSMT */ ++ surface->locations |= location; ++ surface->ds_current_size.cx = surface->resource.width; ++ surface->ds_current_size.cy = surface->resource.height; ++} ++ ++void surface_validate_location(struct wined3d_surface *surface, DWORD location) +{ -+ if (location & WINED3D_LOCATION_BUFFER) -+ { -+ data->addr = NULL; -+ data->buffer_object = surface->pbo; -+ return; -+ } -+ if (location & WINED3D_LOCATION_USER_MEMORY) -+ { -+ data->addr = surface->user_memory; -+ data->buffer_object = 0; -+ return; -+ } -+ if (location & WINED3D_LOCATION_DIB) -+ { -+ data->addr = surface->dib.bitmap_data; -+ data->buffer_object = 0; -+ return; -+ } -+ if (location & WINED3D_LOCATION_SYSMEM) -+ { -+ data->addr = surface->resource.heap_memory; -+ data->buffer_object = 0; -+ return; -+ } ++ TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); + -+ ERR("Unexpected locations %s.\n", wined3d_debug_location(location)); -+ data->addr = NULL; -+ data->buffer_object = 0; ++ surface->locations |= location; +} + -+static void surface_prepare_buffer(struct wined3d_surface *surface) ++void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) +{ -+ struct wined3d_context *context; -+ GLenum error; -+ const struct wined3d_gl_info *gl_info; ++ TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); + -+ if (surface->pbo) -+ return; ++ if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) ++ wined3d_texture_set_dirty(surface->container); ++ surface->locations &= ~location; + -+ context = context_acquire(surface->resource.device, NULL); -+ gl_info = context->gl_info; ++ if (!surface->locations) ++ ERR("Surface %p does not have any up to date location.\n", surface); ++} + -+ GL_EXTCALL(glGenBuffers(1, &surface->pbo)); -+ error = gl_info->gl_ops.gl.p_glGetError(); -+ if (!surface->pbo || error != GL_NO_ERROR) -+ ERR("Failed to create a PBO with error %s (%#x).\n", debug_glerror(error), error); ++static DWORD resource_access_from_location(DWORD location) ++{ ++ switch (location) ++ { ++ case WINED3D_LOCATION_SYSMEM: ++ case WINED3D_LOCATION_USER_MEMORY: ++ case WINED3D_LOCATION_DIB: ++ case WINED3D_LOCATION_BUFFER: ++ return WINED3D_RESOURCE_ACCESS_CPU; + -+ TRACE("Binding PBO %u.\n", surface->pbo); ++ case WINED3D_LOCATION_DRAWABLE: ++ case WINED3D_LOCATION_TEXTURE_SRGB: ++ case WINED3D_LOCATION_TEXTURE_RGB: ++ case WINED3D_LOCATION_RB_MULTISAMPLE: ++ case WINED3D_LOCATION_RB_RESOLVED: ++ return WINED3D_RESOURCE_ACCESS_GPU; + -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); -+ checkGLcall("glBindBuffer"); ++ default: ++ FIXME("Unhandled location %#x.\n", location); ++ return 0; ++ } ++} + -+ GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, surface->resource.size + 4, -+ NULL, GL_STREAM_DRAW)); -+ checkGLcall("glBufferData"); ++static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD location) ++{ ++ struct wined3d_device *device = surface->resource.device; ++ struct wined3d_context *context; ++ const struct wined3d_gl_info *gl_info; ++ struct wined3d_bo_address dst, src; ++ UINT size = surface->resource.size; + -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); -+ checkGLcall("glBindBuffer"); ++ surface_get_memory(surface, &dst, location); ++ surface_get_memory(surface, &src, surface->locations); + -+ context_release(context); ++ if (dst.buffer_object) ++ { ++ context = context_acquire(device, NULL); ++ gl_info = context->gl_info; ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); ++ GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); ++ checkGLcall("Upload PBO"); ++ context_release(context); ++ return; ++ } ++ if (src.buffer_object) ++ { ++ context = context_acquire(device, NULL); ++ gl_info = context->gl_info; ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); ++ GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); ++ checkGLcall("Download PBO"); ++ context_release(context); ++ return; ++ } ++ memcpy(dst.addr, src.addr, size); +} + -+static void surface_prepare_system_memory(struct wined3d_surface *surface) ++/* Context activation is done by the caller. */ ++static void surface_load_sysmem(struct wined3d_surface *surface, ++ struct wined3d_context *context, DWORD dst_location) +{ -+ TRACE("surface %p.\n", surface); ++ const struct wined3d_gl_info *gl_info = context->gl_info; + -+ if (surface->resource.heap_memory) ++ if (surface->locations & surface_simple_locations) ++ { ++ surface_copy_simple_location(surface, dst_location); + return; ++ } + -+ /* Whatever surface we have, make sure that there is memory allocated -+ * for the downloaded copy, or a PBO to map. */ -+ if (!wined3d_resource_allocate_sysmem(&surface->resource)) -+ ERR("Failed to allocate system memory.\n"); -+ -+ if (surface->locations & WINED3D_LOCATION_SYSMEM) -+ ERR("Surface without system memory has WINED3D_LOCATION_SYSMEM set.\n"); -+} ++ if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) ++ surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB); + -+void surface_prepare_map_memory(struct wined3d_surface *surface) -+{ -+ switch (surface->resource.map_binding) ++ /* Download the surface to system memory. */ ++ if (surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { -+ case WINED3D_LOCATION_SYSMEM: -+ surface_prepare_system_memory(surface); -+ break; ++ wined3d_texture_bind_and_dirtify(surface->container, context, ++ !(surface->locations & WINED3D_LOCATION_TEXTURE_RGB)); ++ surface_download_data(surface, gl_info, dst_location); + -+ case WINED3D_LOCATION_USER_MEMORY: -+ if (!surface->user_memory) -+ ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but surface->user_memory is NULL.\n"); -+ break; ++ return; ++ } + -+ case WINED3D_LOCATION_DIB: -+ if (!surface->dib.bitmap_data) -+ ERR("Map binding is set to WINED3D_LOCATION_DIB but surface->dib.bitmap_data is NULL.\n"); -+ break; ++ if (surface->locations & WINED3D_LOCATION_DRAWABLE) ++ { ++ read_from_framebuffer(surface, context, dst_location); ++ return; ++ } + -+ case WINED3D_LOCATION_BUFFER: -+ surface_prepare_buffer(surface); -+ break; ++ FIXME("Can't load surface %p with location flags %s into sysmem.\n", ++ surface, wined3d_debug_location(surface->locations)); ++#endif /* STAGING_CSMT */ + } + + /* Context activation is done by the caller. */ +@@ -3670,12 +4566,14 @@ + { + RECT r; + ++#if defined(STAGING_CSMT) + if (surface->resource.locations & WINED3D_LOCATION_DISCARDED) + { + TRACE("Surface was discarded, nothing to do.\n"); + return WINED3D_OK; + } + ++#endif /* STAGING_CSMT */ + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO + && wined3d_resource_is_offscreen(&surface->container->resource)) + { +@@ -3684,7 +4582,11 @@ + } + + surface_get_rect(surface, NULL, &r); ++#if defined(STAGING_CSMT) + wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); ++#else /* STAGING_CSMT */ ++ surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB); ++#endif /* STAGING_CSMT */ + surface_blt_to_drawable(surface->resource.device, context, + WINED3D_TEXF_POINT, FALSE, surface, &r, surface, &r); + +@@ -3699,6 +4601,7 @@ + struct wined3d_device *device = surface->resource.device; + const struct wined3d_color_key_conversion *conversion; + struct wined3d_texture *texture = surface->container; ++#if defined(STAGING_CSMT) + UINT width, src_row_pitch, src_slice_pitch, dst_pitch; + struct wined3d_bo_address data; + struct wined3d_format format; +@@ -3725,6 +4628,24 @@ + } + + if (surface->resource.locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB) ++#else /* STAGING_CSMT */ ++ UINT width, src_pitch, dst_pitch; ++ struct wined3d_bo_address data; ++ struct wined3d_format format; ++ POINT dst_point = {0, 0}; ++ BYTE *mem = NULL; + -+ default: -+ ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); ++ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO ++ && wined3d_resource_is_offscreen(&texture->resource) ++ && (surface->locations & WINED3D_LOCATION_DRAWABLE)) ++ { ++ surface_load_fb_texture(surface, srgb, context); ++ ++ return WINED3D_OK; + } -+} + ++ if (surface->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB) ++#endif /* STAGING_CSMT */ + && (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB) + && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, + NULL, surface->resource.usage, surface->resource.pool, surface->resource.format, +@@ -3740,6 +4661,7 @@ + return WINED3D_OK; + } + ++#if defined(STAGING_CSMT) + if (surface->resource.locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED) + && (!srgb || (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)) + && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, +@@ -3747,6 +4669,15 @@ + NULL, surface->resource.usage, surface->resource.pool, surface->resource.format)) + { + DWORD src_location = surface->resource.locations & WINED3D_LOCATION_RB_RESOLVED ? ++#else /* STAGING_CSMT */ ++ if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED) ++ && (!srgb || (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)) ++ && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, ++ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format, ++ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format)) ++ { ++ DWORD src_location = surface->locations & WINED3D_LOCATION_RB_RESOLVED ? +#endif /* STAGING_CSMT */ - static void surface_evict_sysmem(struct wined3d_surface *surface) - { - /* In some conditions the surface memory must not be freed: -@@ -499,8 +666,34 @@ - return; + WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE; + DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; + RECT rect = {0, 0, surface->resource.width, surface->resource.height}; +@@ -3761,6 +4692,7 @@ - wined3d_resource_free_sysmem(&surface->resource); + if (srgb) + { +#if defined(STAGING_CSMT) - surface->resource.map_heap_memory = NULL; - wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); + if ((surface->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding)) + == WINED3D_LOCATION_TEXTURE_RGB) + { +@@ -3795,6 +4727,42 @@ + + width = surface->resource.width; + wined3d_resource_get_pitch(&surface->resource, &src_row_pitch, &src_slice_pitch); +#else /* STAGING_CSMT */ -+ surface_invalidate_location(surface, WINED3D_LOCATION_SYSMEM); -+} -+ -+static void surface_release_client_storage(struct wined3d_surface *surface) -+{ -+ struct wined3d_context *context = context_acquire(surface->resource.device, NULL); -+ const struct wined3d_gl_info *gl_info = context->gl_info; -+ -+ if (surface->container->texture_rgb.name) ++ if ((surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding)) ++ == WINED3D_LOCATION_TEXTURE_RGB) ++ { ++ /* Performance warning... */ ++ FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface); ++ surface_prepare_map_memory(surface); ++ surface_load_location(surface, context, surface->resource.map_binding); ++ } ++ } ++ else + { -+ wined3d_texture_bind_and_dirtify(surface->container, context, FALSE); -+ gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, -+ GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); ++ if ((surface->locations & (WINED3D_LOCATION_TEXTURE_SRGB | surface->resource.map_binding)) ++ == WINED3D_LOCATION_TEXTURE_SRGB) ++ { ++ /* Performance warning... */ ++ FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface); ++ surface_prepare_map_memory(surface); ++ surface_load_location(surface, context, surface->resource.map_binding); ++ } + } -+ if (surface->container->texture_srgb.name) ++ ++ if (!(surface->locations & surface_simple_locations)) + { -+ wined3d_texture_bind_and_dirtify(surface->container, context, TRUE); -+ gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, -+ GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); ++ WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); ++ /* Lets hope we get it from somewhere... */ ++ surface_prepare_system_memory(surface); ++ surface_load_location(surface, context, WINED3D_LOCATION_SYSMEM); + } -+ wined3d_texture_force_reload(surface->container); + -+ context_release(context); ++ wined3d_texture_prepare_texture(texture, context, srgb); ++ wined3d_texture_bind_and_dirtify(texture, context, srgb); ++ ++ width = surface->resource.width; ++ src_pitch = wined3d_surface_get_pitch(surface); +#endif /* STAGING_CSMT */ - } - static BOOL surface_use_pbo(const struct wined3d_surface *surface) -@@ -585,7 +778,11 @@ + format = *texture->resource.format; + if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE))) +@@ -3803,7 +4771,11 @@ + /* Don't use PBOs for converted surfaces. During PBO conversion we look at + * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is + * getting called. */ ++#if defined(STAGING_CSMT) + if ((format.convert || conversion) && surface->resource.buffer) ++#else /* STAGING_CSMT */ ++ if ((format.convert || conversion) && surface->pbo) ++#endif /* STAGING_CSMT */ + { + TRACE("Removing the pbo attached to surface %p.\n", surface); + +@@ -3812,6 +4784,7 @@ + else + surface->resource.map_binding = WINED3D_LOCATION_SYSMEM; + ++#if defined(STAGING_CSMT) + wined3d_resource_prepare_map_memory(&surface->resource, context); + wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); + wined3d_resource_free_bo(&surface->resource); +@@ -3819,6 +4792,14 @@ } - if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) + wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &data); ++#else /* STAGING_CSMT */ ++ surface_prepare_map_memory(surface); ++ surface_load_location(surface, context, surface->resource.map_binding); ++ surface_remove_pbo(surface, gl_info); ++ } ++ ++ surface_get_memory(surface, &data, surface->locations); ++#endif /* STAGING_CSMT */ + if (format.convert) + { + /* This code is entered for texture formats which need a fixup. */ +@@ -3833,9 +4814,15 @@ + context_release(context); + return E_OUTOFMEMORY; + } +#if defined(STAGING_CSMT) - surface->resource.locations = WINED3D_LOCATION_DISCARDED; + format.convert(data.addr, mem, src_row_pitch, src_row_pitch * height, + dst_pitch, dst_pitch * height, width, height, 1); + src_row_pitch = dst_pitch; +#else /* STAGING_CSMT */ -+ surface->locations = WINED3D_LOCATION_DISCARDED; ++ format.convert(data.addr, mem, src_pitch, src_pitch * height, ++ dst_pitch, dst_pitch * height, width, height, 1); ++ src_pitch = dst_pitch; +#endif /* STAGING_CSMT */ + data.addr = mem; + } + else if (conversion) +@@ -3855,6 +4842,7 @@ + } + if (texture->swapchain && texture->swapchain->palette) + palette = texture->swapchain->palette; ++#if defined(STAGING_CSMT) + conversion->convert(data.addr, src_row_pitch, mem, dst_pitch, + width, height, palette, &texture->async.gl_color_key); + src_row_pitch = dst_pitch; +@@ -3863,6 +4851,16 @@ - if (surface_use_pbo(surface)) - surface->resource.map_binding = WINED3D_LOCATION_BUFFER; -@@ -593,6 +790,7 @@ - return WINED3D_OK; + wined3d_surface_upload_data(surface, gl_info, &format, &src_rect, + src_row_pitch, &dst_point, srgb, wined3d_const_bo_address(&data)); ++#else /* STAGING_CSMT */ ++ conversion->convert(data.addr, src_pitch, mem, dst_pitch, ++ width, height, palette, &texture->async.gl_color_key); ++ src_pitch = dst_pitch; ++ data.addr = mem; ++ } ++ ++ wined3d_surface_upload_data(surface, gl_info, &format, &src_rect, ++ src_pitch, &dst_point, srgb, wined3d_const_bo_address(&data)); ++#endif /* STAGING_CSMT */ + + HeapFree(GetProcessHeap(), 0, mem); + +@@ -3876,11 +4874,19 @@ + const RECT rect = {0, 0, surface->resource.width, surface->resource.height}; + DWORD src_location; + ++#if defined(STAGING_CSMT) + if (surface->resource.locations & WINED3D_LOCATION_RB_MULTISAMPLE) + src_location = WINED3D_LOCATION_RB_MULTISAMPLE; + else if (surface->resource.locations & WINED3D_LOCATION_RB_RESOLVED) + src_location = WINED3D_LOCATION_RB_RESOLVED; + else if (surface->resource.locations & WINED3D_LOCATION_TEXTURE_SRGB) ++#else /* STAGING_CSMT */ ++ if (surface->locations & WINED3D_LOCATION_RB_MULTISAMPLE) ++ src_location = WINED3D_LOCATION_RB_MULTISAMPLE; ++ else if (surface->locations & WINED3D_LOCATION_RB_RESOLVED) ++ src_location = WINED3D_LOCATION_RB_RESOLVED; ++ else if (surface->locations & WINED3D_LOCATION_TEXTURE_SRGB) ++#endif /* STAGING_CSMT */ + src_location = WINED3D_LOCATION_TEXTURE_SRGB; + else /* surface_blt_fbo will load the source location if necessary. */ + src_location = WINED3D_LOCATION_TEXTURE_RGB; +@@ -3889,11 +4895,17 @@ + surface, src_location, &rect, surface, dst_location, &rect); } +#if defined(STAGING_CSMT) - static void surface_frontbuffer_updated(struct wined3d_surface *surface) + /* Context activation is done by the caller. */ + static void wined3d_surface_load_location(struct wined3d_resource *resource, + struct wined3d_context *context, DWORD location) { - struct wined3d_context *context = NULL; -@@ -609,6 +807,54 @@ - wined3d_resource_load_location(&surface->resource, context, surface->container->resource.draw_binding); - if (context) - context_release(context); + struct wined3d_surface *surface = surface_from_resource(resource); +#else /* STAGING_CSMT */ -+static void surface_unmap(struct wined3d_surface *surface) ++/* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */ ++HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) +{ -+ struct wined3d_device *device = surface->resource.device; -+ const struct wined3d_gl_info *gl_info; -+ struct wined3d_context *context; -+ -+ TRACE("surface %p.\n", surface); -+ -+ memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); ++#endif /* STAGING_CSMT */ + HRESULT hr; + + TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); +@@ -3901,6 +4913,7 @@ + if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) + { + if (location == WINED3D_LOCATION_TEXTURE_RGB ++#if defined(STAGING_CSMT) + && surface->resource.locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_DISCARDED)) + { + surface_load_ds_location(surface, context, location); +@@ -3924,6 +4937,45 @@ + { + ERR("Surface %p does not have any up to date location.\n", surface); + return; ++#else /* STAGING_CSMT */ ++ && surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_DISCARDED)) ++ { ++ surface_load_ds_location(surface, context, location); ++ return WINED3D_OK; ++ } ++ else if (location & surface->locations ++ && surface->container->resource.draw_binding != WINED3D_LOCATION_DRAWABLE) ++ { ++ /* Already up to date, nothing to do. */ ++ return WINED3D_OK; ++ } ++ else ++ { ++ FIXME("Unimplemented copy from %s to %s for depth/stencil buffers.\n", ++ wined3d_debug_location(surface->locations), wined3d_debug_location(location)); ++ return WINED3DERR_INVALIDCALL; ++ } ++ } + -+ switch (surface->resource.map_binding) ++ if (surface->locations & location) + { -+ case WINED3D_LOCATION_SYSMEM: -+ case WINED3D_LOCATION_USER_MEMORY: -+ case WINED3D_LOCATION_DIB: -+ break; -+ -+ case WINED3D_LOCATION_BUFFER: -+ context = context_acquire(device, NULL); -+ gl_info = context->gl_info; -+ -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); -+ GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); -+ checkGLcall("glUnmapBuffer"); -+ context_release(context); -+ break; -+ -+ default: -+ ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); ++ TRACE("Location already up to date.\n"); ++ return WINED3D_OK; + } + -+ if (surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)) ++ if (WARN_ON(d3d_surface)) + { -+ TRACE("Not dirtified, nothing to do.\n"); -+ return; ++ DWORD required_access = resource_access_from_location(location); ++ if ((surface->resource.access_flags & required_access) != required_access) ++ WARN("Operation requires %#x access, but surface only has %#x.\n", ++ required_access, surface->resource.access_flags); + } + -+ if (surface->container->swapchain && surface->container->swapchain->front_buffer == surface->container) ++ if (!surface->locations) + { -+ context = context_acquire(device, surface); -+ surface_load_location(surface, context, surface->container->resource.draw_binding); -+ context_release(context); -+ } -+ else if (surface->container->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) -+ FIXME("Depth / stencil buffer locking is not implemented.\n"); ++ ERR("Surface %p does not have any up to date location.\n", surface); ++ return WINED3DERR_INVALIDCALL; +#endif /* STAGING_CSMT */ - } + } - static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r) -@@ -669,9 +915,15 @@ + switch (location) +@@ -3937,7 +4989,11 @@ - /* Make sure the locations are up-to-date. Loading the destination - * surface isn't required if the entire surface is overwritten. */ -+#if defined(STAGING_CSMT) - wined3d_resource_load_location(&src_surface->resource, context, src_location); - if (!surface_is_full_rect(dst_surface, dst_rect)) - wined3d_resource_load_location(&dst_surface->resource, context, dst_location); + case WINED3D_LOCATION_DRAWABLE: + if (FAILED(hr = surface_load_drawable(surface, context))) ++#if defined(STAGING_CSMT) + return; +#else /* STAGING_CSMT */ -+ surface_load_location(src_surface, context, src_location); -+ if (!surface_is_full_rect(dst_surface, dst_rect)) -+ surface_load_location(dst_surface, context, dst_location); ++ return hr; +#endif /* STAGING_CSMT */ - else - wined3d_surface_prepare(dst_surface, context, dst_location); + break; -@@ -762,9 +1014,15 @@ - * surface isn't required if the entire surface is overwritten. (And is - * in fact harmful if we're being called by surface_load_location() with - * the purpose of loading the destination surface.) */ + case WINED3D_LOCATION_RB_RESOLVED: +@@ -3949,7 +5005,11 @@ + case WINED3D_LOCATION_TEXTURE_SRGB: + if (FAILED(hr = surface_load_texture(surface, context, + location == WINED3D_LOCATION_TEXTURE_SRGB))) +#if defined(STAGING_CSMT) - wined3d_resource_load_location(&src_surface->resource, old_ctx, src_location); - if (!surface_is_full_rect(dst_surface, &dst_rect)) - wined3d_resource_load_location(&dst_surface->resource, old_ctx, dst_location); + return; +#else /* STAGING_CSMT */ -+ surface_load_location(src_surface, old_ctx, src_location); -+ if (!surface_is_full_rect(dst_surface, &dst_rect)) -+ surface_load_location(dst_surface, old_ctx, dst_location); ++ return hr; +#endif /* STAGING_CSMT */ - else - wined3d_surface_prepare(dst_surface, old_ctx, dst_location); + break; -@@ -956,6 +1214,18 @@ - return WINED3D_OK; - } + default: +@@ -3957,12 +5017,21 @@ + break; + } -+#if !defined(STAGING_CSMT) -+/* Context activation is done by the caller. */ -+static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) -+{ -+ GL_EXTCALL(glDeleteBuffers(1, &surface->pbo)); -+ checkGLcall("glDeleteBuffers(1, &surface->pbo)"); ++#if defined(STAGING_CSMT) + wined3d_resource_validate_location(&surface->resource, location); + + if (location != WINED3D_LOCATION_SYSMEM && (surface->resource.locations & WINED3D_LOCATION_SYSMEM)) + surface_evict_sysmem(surface); + + return; ++#else /* STAGING_CSMT */ ++ surface_validate_location(surface, location); + -+ surface->pbo = 0; -+ surface_invalidate_location(surface, WINED3D_LOCATION_BUFFER); -+} ++ if (location != WINED3D_LOCATION_SYSMEM && (surface->locations & WINED3D_LOCATION_SYSMEM)) ++ surface_evict_sysmem(surface); + ++ return WINED3D_OK; +#endif /* STAGING_CSMT */ - static ULONG surface_resource_incref(struct wined3d_resource *resource) - { - return wined3d_surface_incref(surface_from_resource(resource)); -@@ -981,6 +1251,7 @@ + } - if (resource->pool == WINED3D_POOL_DEFAULT) - { + static HRESULT ffp_blit_alloc(struct wined3d_device *device) { return WINED3D_OK; } +@@ -4071,7 +5140,11 @@ + const RECT *rect, const struct wined3d_color *color) + { + const RECT draw_rect = {0, 0, view->width, view->height}; +#if defined(STAGING_CSMT) - /* Default pool resources are supposed to be destroyed before Reset is called. - * Implicit resources stay however. So this means we have an implicit render target - * or depth stencil. The content may be destroyed, but we still have to tear down -@@ -994,6 +1265,40 @@ - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); - } + struct wined3d_fb_state fb = {&view, NULL, 1}; +#else /* STAGING_CSMT */ -+ /* Default pool resources are supposed to be destroyed before Reset is called. -+ * Implicit resources stay however. So this means we have an implicit render target -+ * or depth stencil. The content may be destroyed, but we still have to tear down -+ * opengl resources, so we cannot leave early. -+ * -+ * Put the surfaces into sysmem, and reset the content. The D3D content is undefined, -+ * but we can't set the sysmem INDRAWABLE because when we're rendering the swapchain -+ * or the depth stencil into an FBO the texture or render buffer will be removed -+ * and all flags get lost */ -+ if (resource->usage & WINED3DUSAGE_DEPTHSTENCIL) -+ { -+ surface_validate_location(surface, WINED3D_LOCATION_DISCARDED); -+ surface_invalidate_location(surface, ~WINED3D_LOCATION_DISCARDED); -+ } -+ else -+ { -+ surface_prepare_system_memory(surface); -+ memset(surface->resource.heap_memory, 0, surface->resource.size); -+ surface_validate_location(surface, WINED3D_LOCATION_SYSMEM); -+ surface_invalidate_location(surface, ~WINED3D_LOCATION_SYSMEM); -+ } -+ } -+ else -+ { -+ surface_prepare_map_memory(surface); -+ surface_load_location(surface, context, surface->resource.map_binding); -+ surface_invalidate_location(surface, ~surface->resource.map_binding); -+ } -+ -+ /* Destroy PBOs, but load them into real sysmem before */ -+ if (surface->pbo) -+ surface_remove_pbo(surface, gl_info); ++ struct wined3d_fb_state fb = {&view, NULL}; +#endif /* STAGING_CSMT */ - /* Destroy fbo render buffers. This is needed for implicit render targets, for - * all application-created targets the application has to release the surface -@@ -1037,6 +1342,7 @@ - return WINED3DERR_INVALIDCALL; - } + device_clear_render_targets(device, 1, &fb, 1, rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0); + +@@ -4121,8 +5194,13 @@ + wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, + (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL); +#if defined(STAGING_CSMT) - static void wined3d_surface_location_invalidated(struct wined3d_resource *resource, DWORD location) - { - struct wined3d_surface *surface = surface_from_resource(resource); -@@ -1052,6 +1358,21 @@ - { - surface_private_setup, - surface_frontbuffer_updated, + wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); + wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding); +#else /* STAGING_CSMT */ -+static const struct wined3d_resource_ops surface_resource_ops = -+{ -+ surface_resource_incref, -+ surface_resource_decref, -+ surface_unload, -+ surface_resource_sub_resource_map, -+ surface_resource_sub_resource_unmap, -+}; -+ -+static const struct wined3d_surface_ops surface_ops = -+{ -+ surface_private_setup, -+ surface_unmap, ++ surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); ++ surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); +#endif /* STAGING_CSMT */ - }; - - /***************************************************************************** -@@ -1095,6 +1416,7 @@ - return WINED3D_OK; } -+#if defined(STAGING_CSMT) - static void gdi_surface_frontbuffer_updated(struct wined3d_surface *surface) - { - x11_copy_to_screen(surface->container->swapchain, &surface->lockedRect); -@@ -1104,6 +1426,23 @@ + const struct blit_shader ffp_blit = { +@@ -4278,6 +5356,7 @@ + struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, + const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) { - gdi_surface_private_setup, - gdi_surface_frontbuffer_updated, ++#if defined(STAGING_CSMT) + int bpp, srcheight, srcwidth, dstheight, dstwidth, width; + const struct wined3d_format *src_format, *dst_format; + unsigned int src_fmt_flags, dst_fmt_flags; +@@ -4312,6 +5391,28 @@ + wined3d_resource_get_pitch(&dst_surface->resource, &dst_row_pitch, &dst_slice_pitch); + src_data = dst_data; + src_row_pitch = dst_row_pitch; +#else /* STAGING_CSMT */ -+static void gdi_surface_unmap(struct wined3d_surface *surface) -+{ -+ TRACE("surface %p.\n", surface); -+ -+ /* Tell the swapchain to update the screen. */ -+ if (surface->container->swapchain && surface->container == surface->container->swapchain->front_buffer) -+ x11_copy_to_screen(surface->container->swapchain, &surface->lockedRect); ++ const struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; ++ int bpp, srcheight, srcwidth, dstheight, dstwidth, width; ++ const struct wined3d_format *src_format, *dst_format; ++ unsigned int src_fmt_flags, dst_fmt_flags; ++ struct wined3d_texture *src_texture = NULL; ++ struct wined3d_map_desc dst_map, src_map; ++ const BYTE *sbase = NULL; ++ HRESULT hr = WINED3D_OK; ++ const BYTE *sbuf; ++ BYTE *dbuf; ++ int x, y; + -+ memset(&surface->lockedRect, 0, sizeof(RECT)); -+} ++ TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", ++ dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), ++ flags, fx, debug_d3dtexturefiltertype(filter)); + -+static const struct wined3d_surface_ops gdi_surface_ops = -+{ -+ gdi_surface_private_setup, -+ gdi_surface_unmap, ++ if (src_surface == dst_surface) ++ { ++ wined3d_surface_map(dst_surface, &dst_map, NULL, 0); ++ src_map = dst_map; +#endif /* STAGING_CSMT */ - }; - - /* This call just downloads data, the caller is responsible for binding the -@@ -1122,7 +1461,11 @@ - return; - } + src_format = dst_surface->resource.format; + dst_format = src_format; + dst_fmt_flags = dst_surface->container->resource.format_flags; +@@ -4323,12 +5424,14 @@ + dst_fmt_flags = dst_surface->container->resource.format_flags; + if (src_surface) + { ++#if defined(STAGING_CSMT) + if (!wined3d_resource_prepare_map_memory(&src_surface->resource, context)) + { + hr = E_OUTOFMEMORY; + goto error; + } ++#endif /* STAGING_CSMT */ + if (dst_surface->resource.format->id != src_surface->resource.format->id) + { + if (!(src_texture = surface_convert_format(src_surface, dst_format->id))) +@@ -4339,9 +5442,13 @@ + } + src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, 0)); + } +#if defined(STAGING_CSMT) - wined3d_resource_get_memory(&surface->resource, dst_location, &data); + wined3d_resource_load_location(&src_surface->resource, context, src_surface->resource.map_binding); + wined3d_resource_get_pitch(&src_surface->resource, &src_row_pitch, &src_slice_pitch); + src_data = wined3d_resource_get_map_ptr(&src_surface->resource, context, 0); +#else /* STAGING_CSMT */ -+ surface_get_memory(surface, &data, dst_location); ++ wined3d_surface_map(src_surface, &src_map, NULL, WINED3D_MAP_READONLY); +#endif /* STAGING_CSMT */ + src_format = src_surface->resource.format; + src_fmt_flags = src_surface->container->resource.format_flags; + } +@@ -4351,8 +5458,12 @@ + src_fmt_flags = dst_fmt_flags; + } - if (surface->container->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED) - { -@@ -1150,6 +1493,7 @@ - void *mem; - GLenum gl_format = format->glFormat; - GLenum gl_type = format->glType; +#if defined(STAGING_CSMT) - UINT src_pitch = 0; - UINT dst_row_pitch, dst_slice_pitch; - -@@ -1158,6 +1502,16 @@ - unsigned char alignment = surface->resource.device->surface_alignment; - src_pitch = format->byte_count * surface->pow2Width; - wined3d_resource_get_pitch(&surface->resource, &dst_row_pitch, &dst_slice_pitch); + wined3d_resource_get_pitch(&dst_surface->resource, &dst_row_pitch, &dst_slice_pitch); + dst_data = wined3d_resource_get_map_ptr(&dst_surface->resource, context, 0); +#else /* STAGING_CSMT */ -+ int src_pitch = 0; -+ int dst_pitch = 0; -+ -+ if (surface->flags & SFLAG_NONPOW2) -+ { -+ unsigned char alignment = surface->resource.device->surface_alignment; -+ src_pitch = format->byte_count * surface->pow2Width; -+ dst_pitch = wined3d_surface_get_pitch(surface); ++ wined3d_surface_map(dst_surface, &dst_map, &dst_box, 0); +#endif /* STAGING_CSMT */ - src_pitch = (src_pitch + alignment - 1) & ~(alignment - 1); - mem = HeapAlloc(GetProcessHeap(), 0, src_pitch * surface->pow2Height); - } -@@ -1244,12 +1598,21 @@ - * won't be released, and doesn't have to be re-read. */ - src_data = mem; - dst_data = data.addr; + } + + bpp = dst_surface->resource.format->byte_count; +@@ -4363,12 +5474,24 @@ + width = (dst_rect->right - dst_rect->left) * bpp; + + if (src_surface) +#if defined(STAGING_CSMT) - TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_row_pitch); - for (y = 0; y < surface->resource.height; ++y) - { - memcpy(dst_data, src_data, dst_row_pitch); - src_data += src_pitch; - dst_data += dst_row_pitch; + sbase = (BYTE *)src_data + + ((src_rect->top / src_format->block_height) * src_row_pitch) + + ((src_rect->left / src_format->block_width) * src_format->block_byte_count); + dbuf = (BYTE *)dst_data + + ((dst_rect->top / dst_format->block_height) * dst_row_pitch) + + ((dst_rect->left / dst_format->block_width) * dst_format->block_byte_count); +#else /* STAGING_CSMT */ -+ TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_pitch); -+ for (y = 0; y < surface->resource.height; ++y) -+ { -+ memcpy(dst_data, src_data, dst_pitch); -+ src_data += src_pitch; -+ dst_data += dst_pitch; ++ sbase = (BYTE *)src_map.data ++ + ((src_rect->top / src_format->block_height) * src_map.row_pitch) ++ + ((src_rect->left / src_format->block_width) * src_format->block_byte_count); ++ if (src_surface != dst_surface) ++ dbuf = dst_map.data; ++ else ++ dbuf = (BYTE *)dst_map.data ++ + ((dst_rect->top / dst_format->block_height) * dst_map.row_pitch) ++ + ((dst_rect->left / dst_format->block_width) * dst_format->block_byte_count); +#endif /* STAGING_CSMT */ - } - HeapFree(GetProcessHeap(), 0, mem); -@@ -1373,10 +1736,33 @@ + if (src_fmt_flags & dst_fmt_flags & WINED3DFMT_FLAG_BLOCKS) + { +@@ -4403,7 +5526,11 @@ + } - static BOOL surface_check_block_align(struct wined3d_surface *surface, const struct wined3d_box *box) - { + hr = surface_cpu_blt_compressed(sbase, dbuf, +#if defined(STAGING_CSMT) - return wined3d_resource_check_block_align(&surface->resource, box); - } - - BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) + src_row_pitch, dst_row_pitch, dstwidth, dstheight, +#else /* STAGING_CSMT */ -+ UINT width_mask, height_mask; -+ -+ if (!box->left && !box->top -+ && box->right == surface->resource.width -+ && box->bottom == surface->resource.height) -+ return TRUE; -+ -+ /* This assumes power of two block sizes, but NPOT block sizes would be -+ * silly anyway. */ -+ width_mask = surface->resource.format->block_width - 1; -+ height_mask = surface->resource.format->block_height - 1; -+ -+ if (!(box->left & width_mask) && !(box->top & height_mask) -+ && !(box->right & width_mask) && !(box->bottom & height_mask)) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+static BOOL surface_check_block_align_rect(struct wined3d_surface *surface, const RECT *rect) ++ src_map.row_pitch, dst_map.row_pitch, dstwidth, dstheight, +#endif /* STAGING_CSMT */ - { - struct wined3d_box box = {rect->left, rect->top, rect->right, rect->bottom, 0, 1}; - -@@ -1395,7 +1781,11 @@ - UINT update_w, update_h; - UINT dst_w, dst_h; - RECT r, dst_rect; + src_format, flags, fx); + goto release; + } +@@ -4411,7 +5538,11 @@ + /* First, all the 'source-less' blits */ + if (flags & WINEDDBLT_COLORFILL) + { +#if defined(STAGING_CSMT) - UINT src_row_pitch, src_slice_pitch; + hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_row_pitch, fx->u5.dwFillColor); +#else /* STAGING_CSMT */ -+ UINT src_pitch; ++ hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_map.row_pitch, fx->u5.dwFillColor); +#endif /* STAGING_CSMT */ - POINT p; - - TRACE("dst_surface %p, dst_point %s, src_surface %p, src_rect %s.\n", -@@ -1466,11 +1856,17 @@ - return WINED3DERR_INVALIDCALL; + flags &= ~WINEDDBLT_COLORFILL; } +@@ -4461,6 +5592,7 @@ + for (y = 0; y < dstheight; ++y) + { + memcpy(dbuf, sbuf, width); +#if defined(STAGING_CSMT) - /* Use surface_cpu_blt() instead of uploading directly if we need - * conversion. Avoid calling wined3d_surface_blt() since that goes - * through the CS. */ - if (dst_format->convert || wined3d_format_get_color_key_conversion(dst_surface->container, FALSE)) - return surface_cpu_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT); + sbuf += src_row_pitch; + dbuf += dst_row_pitch; + } +@@ -4474,6 +5606,21 @@ + { + sbuf -= src_row_pitch; + dbuf -= dst_row_pitch; +#else /* STAGING_CSMT */ -+ /* Use wined3d_surface_blt() instead of uploading directly if we need conversion. */ -+ if (dst_format->convert || wined3d_format_get_color_key_conversion(dst_surface->container, FALSE)) -+ return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT); ++ sbuf += src_map.row_pitch; ++ dbuf += dst_map.row_pitch; ++ } ++ } ++ else if (dst_rect->top > src_rect->top) ++ { ++ /* Copy from bottom upwards. */ ++ sbuf += src_map.row_pitch * dstheight; ++ dbuf += dst_map.row_pitch * dstheight; ++ for (y = 0; y < dstheight; ++y) ++ { ++ sbuf -= src_map.row_pitch; ++ dbuf -= dst_map.row_pitch; +#endif /* STAGING_CSMT */ - - context = context_acquire(dst_surface->resource.device, NULL); - gl_info = context->gl_info; -@@ -1481,6 +1877,7 @@ - if (update_w == dst_w && update_h == dst_h) - wined3d_texture_prepare_texture(dst_surface->container, context, FALSE); - else + memcpy(dbuf, sbuf, width); + } + } +@@ -4483,8 +5630,13 @@ + for (y = 0; y < dstheight; ++y) + { + memmove(dbuf, sbuf, width); +#if defined(STAGING_CSMT) - wined3d_resource_load_location(&dst_surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE); - -@@ -1494,6 +1891,21 @@ - - wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_resource_invalidate_location(&dst_surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); + sbuf += src_row_pitch; + dbuf += dst_row_pitch; +#else /* STAGING_CSMT */ -+ surface_load_location(dst_surface, context, WINED3D_LOCATION_TEXTURE_RGB); -+ wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE); -+ -+ surface_get_memory(src_surface, &data, src_surface->locations); -+ src_pitch = wined3d_surface_get_pitch(src_surface); -+ -+ wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect, -+ src_pitch, dst_point, FALSE, wined3d_const_bo_address(&data)); -+ -+ context_release(context); -+ -+ surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); -+ surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); ++ sbuf += src_map.row_pitch; ++ dbuf += dst_map.row_pitch; +#endif /* STAGING_CSMT */ - - return WINED3D_OK; - } -@@ -1607,6 +2019,7 @@ - if (surface->resource.pool == WINED3D_POOL_SCRATCH) - ERR("Not supported on scratch surfaces.\n"); - + } + } + } +@@ -4493,9 +5645,15 @@ + /* Stretching in y direction only. */ + for (y = sy = 0; y < dstheight; ++y, sy += yinc) + { +#if defined(STAGING_CSMT) - if (surface->resource.locations & location) - { - TRACE("surface is already in texture\n"); -@@ -1615,6 +2028,16 @@ - TRACE("Reloading because surface is dirty.\n"); - - wined3d_resource_load_location(&surface->resource, context, location); + sbuf = sbase + (sy >> 16) * src_row_pitch; + memcpy(dbuf, sbuf, width); + dbuf += dst_row_pitch; +#else /* STAGING_CSMT */ -+ if (surface->locations & location) -+ { -+ TRACE("surface is already in texture\n"); -+ return; -+ } -+ TRACE("Reloading because surface is dirty.\n"); -+ -+ surface_load_location(surface, context, location); ++ sbuf = sbase + (sy >> 16) * src_map.row_pitch; ++ memcpy(dbuf, sbuf, width); ++ dbuf += dst_map.row_pitch; +#endif /* STAGING_CSMT */ - surface_evict_sysmem(surface); - } - -@@ -1697,6 +2120,7 @@ - - void CDECL wined3d_surface_preload(struct wined3d_surface *surface) - { + } + } + } +@@ -4505,6 +5663,7 @@ + int last_sy = -1; + for (y = sy = 0; y < dstheight; ++y, sy += yinc) + { +#if defined(STAGING_CSMT) - const struct wined3d_device *device = surface->resource.device; - TRACE("surface %p.\n", surface); - -@@ -1707,6 +2131,17 @@ - } + sbuf = sbase + (sy >> 16) * src_row_pitch; - wined3d_cs_emit_surface_preload(device->cs, surface); + if ((sy >> 16) == (last_sy >> 16)) +@@ -4512,6 +5671,15 @@ + /* This source row is the same as last source row - + * Copy the already stretched row. */ + memcpy(dbuf, dbuf - dst_row_pitch, width); +#else /* STAGING_CSMT */ -+ TRACE("surface %p.\n", surface); -+ -+ if (!surface->resource.device->d3d_initialized) -+ { -+ ERR("D3D not initialized.\n"); -+ return; -+ } ++ sbuf = sbase + (sy >> 16) * src_map.row_pitch; + -+ wined3d_texture_preload(surface->container); ++ if ((sy >> 16) == (last_sy >> 16)) ++ { ++ /* This source row is the same as last source row - ++ * Copy the already stretched row. */ ++ memcpy(dbuf, dbuf - dst_map.row_pitch, width); +#endif /* STAGING_CSMT */ - } - - void * CDECL wined3d_surface_get_parent(const struct wined3d_surface *surface) -@@ -1725,10 +2160,28 @@ - - DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface) - { + } + else + { +@@ -4558,6 +5726,7 @@ + } + #undef STRETCH_ROW + } +#if defined(STAGING_CSMT) - UINT row_pitch, slice_pitch; - const struct wined3d_resource *resource = &surface->resource; - wined3d_resource_get_pitch(resource, &row_pitch, &slice_pitch); - return row_pitch; + dbuf += dst_row_pitch; + last_sy = sy; + } +@@ -4566,6 +5735,16 @@ + else + { + LONG dstyinc = dst_row_pitch, dstxinc = bpp; +#else /* STAGING_CSMT */ -+ unsigned int alignment; -+ DWORD pitch; -+ -+ TRACE("surface %p.\n", surface); -+ -+ if (surface->pitch) -+ return surface->pitch; -+ -+ alignment = surface->resource.device->surface_alignment; -+ pitch = wined3d_format_calculate_pitch(surface->resource.format, surface->resource.width); -+ pitch = (pitch + alignment - 1) & ~(alignment - 1); -+ -+ TRACE("Returning %u.\n", pitch); -+ -+ return pitch; ++ dbuf += dst_map.row_pitch; ++ last_sy = sy; ++ } ++ } ++ } ++ else ++ { ++ LONG dstyinc = dst_map.row_pitch, dstxinc = bpp; +#endif /* STAGING_CSMT */ - } - - HRESULT CDECL wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y) -@@ -1853,6 +2306,7 @@ - { - DeleteDC(surface->hDC); - DeleteObject(surface->dib.DIBsection); + DWORD keylow = 0xffffffff, keyhigh = 0, keymask = 0xffffffff; + DWORD destkeylow = 0x0, destkeyhigh = 0xffffffff, destkeymask = 0xffffffff; + if (flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYDEST | WINEDDBLT_KEYSRCOVERRIDE | WINEDDBLT_KEYDESTOVERRIDE)) +@@ -4615,7 +5794,11 @@ + LONG tmpxy; + dTopLeft = dbuf; + dTopRight = dbuf + ((dstwidth - 1) * bpp); +#if defined(STAGING_CSMT) - surface->resource.bitmap_data = NULL; - surface->flags &= ~SFLAG_DIBSECTION; - create_dib = TRUE; -@@ -1861,6 +2315,15 @@ - surface->resource.locations = 0; - wined3d_resource_free_sysmem(&surface->resource); - surface->resource.map_heap_memory = NULL; + dBottomLeft = dTopLeft + ((dstheight - 1) * dst_row_pitch); +#else /* STAGING_CSMT */ -+ surface->dib.bitmap_data = NULL; -+ surface->flags &= ~SFLAG_DIBSECTION; -+ create_dib = TRUE; -+ } -+ -+ surface->locations = 0; -+ wined3d_resource_free_sysmem(&surface->resource); ++ dBottomLeft = dTopLeft + ((dstheight - 1) * dst_map.row_pitch); +#endif /* STAGING_CSMT */ + dBottomRight = dBottomLeft + ((dstwidth - 1) * bpp); - width = texture_resource->width; - height = texture_resource->height; -@@ -1886,6 +2349,7 @@ - else - surface->flags &= ~SFLAG_NONPOW2; + if (fx->dwDDFX & WINEDDBLTFX_ARITHSTRETCHY) +@@ -4692,6 +5875,7 @@ + flags &= ~(WINEDDBLT_DDFX); + } +#if defined(STAGING_CSMT) - if ((surface->resource.user_memory = mem)) - { - surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY; -@@ -1906,6 +2370,27 @@ - surface->resource.size = wined3d_format_calculate_size(texture_resource->format, - 1, width, height, 1); - surface->resource.custom_row_pitch = wined3d_format_calculate_pitch(texture_resource->format, width); + #define COPY_COLORKEY_FX(type) \ + do { \ + const type *s; \ +@@ -4713,6 +5897,29 @@ + d = (type *)(((BYTE *)d) + dstyinc); \ + } \ + } while(0) +#else /* STAGING_CSMT */ -+ if ((surface->user_memory = mem)) -+ { -+ surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY; -+ valid_location = WINED3D_LOCATION_USER_MEMORY; -+ } -+ surface->pitch = pitch; -+ surface->resource.format = texture_resource->format; -+ surface->resource.multisample_type = texture_resource->multisample_type; -+ surface->resource.multisample_quality = texture_resource->multisample_quality; -+ if (surface->pitch) -+ { -+ surface->resource.size = height * surface->pitch; -+ } -+ else -+ { -+ /* User memory surfaces don't have the regular surface alignment. */ -+ surface->resource.size = wined3d_format_calculate_size(texture_resource->format, -+ 1, width, height, 1); -+ surface->pitch = wined3d_format_calculate_pitch(texture_resource->format, width); ++#define COPY_COLORKEY_FX(type) \ ++do { \ ++ const type *s; \ ++ type *d = (type *)dbuf, *dx, tmp; \ ++ for (y = sy = 0; y < dstheight; ++y, sy += yinc) \ ++ { \ ++ s = (const type *)(sbase + (sy >> 16) * src_map.row_pitch); \ ++ dx = d; \ ++ for (x = sx = 0; x < dstwidth; ++x, sx += xinc) \ ++ { \ ++ tmp = s[sx >> 16]; \ ++ if (((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) \ ++ && ((dx[0] & destkeymask) >= destkeylow && (dx[0] & destkeymask) <= destkeyhigh)) \ ++ { \ ++ dx[0] = tmp; \ ++ } \ ++ dx = (type *)(((BYTE *)dx) + dstxinc); \ ++ } \ ++ d = (type *)(((BYTE *)d) + dstyinc); \ ++ } \ ++} while(0) +#endif /* STAGING_CSMT */ - } - - /* The format might be changed to a format that needs conversion. -@@ -1928,11 +2413,19 @@ - if (!valid_location) - { + switch (bpp) + { +@@ -4731,7 +5938,11 @@ + BYTE *d = dbuf, *dx; + for (y = sy = 0; y < dstheight; ++y, sy += yinc) + { +#if defined(STAGING_CSMT) - wined3d_resource_prepare_system_memory(&surface->resource); - valid_location = WINED3D_LOCATION_SYSMEM; - } - - wined3d_resource_validate_location(&surface->resource, valid_location); + sbuf = sbase + (sy >> 16) * src_row_pitch; +#else /* STAGING_CSMT */ -+ surface_prepare_system_memory(surface); -+ valid_location = WINED3D_LOCATION_SYSMEM; -+ } -+ -+ surface_validate_location(surface, valid_location); ++ sbuf = sbase + (sy >> 16) * src_map.row_pitch; +#endif /* STAGING_CSMT */ + dx = d; + for (x = sx = 0; x < dstwidth; ++x, sx+= xinc) + { +@@ -4762,10 +5973,12 @@ + } + } - return WINED3D_OK; - } -@@ -2291,6 +2784,7 @@ - - static struct wined3d_texture *surface_convert_format(struct wined3d_surface *source, enum wined3d_format_id to_fmt) - { +#if defined(STAGING_CSMT) - void *dst_data = NULL, *src_data = NULL; - UINT src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch; - const struct d3dfmt_converter_desc *conv; -@@ -2299,6 +2793,13 @@ - struct wined3d_surface *dst; - struct wined3d_context *context = NULL; - struct wined3d_device *device = source->resource.device; -+#else /* STAGING_CSMT */ -+ struct wined3d_map_desc src_map, dst_map; -+ const struct d3dfmt_converter_desc *conv; -+ struct wined3d_texture *ret = NULL; -+ struct wined3d_resource_desc desc; -+ struct wined3d_surface *dst; -+#endif /* STAGING_CSMT */ + wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->resource.map_binding); + if (dst_surface->container) + wined3d_texture_set_dirty(dst_surface->container); - conv = find_converter(source->resource.format->id, to_fmt); - if (!conv) -@@ -2322,6 +2823,7 @@ ++#endif /* STAGING_CSMT */ + error: + if (flags && FIXME_ON(d3d_surface)) + { +@@ -4773,6 +5986,7 @@ } - dst = surface_from_resource(wined3d_texture_get_sub_resource(ret, 0)); + release: +#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(&source->resource, &src_row_pitch, &src_slice_pitch); - wined3d_resource_get_pitch(&ret->resource, &dst_row_pitch, &dst_slice_pitch); - -@@ -2362,6 +2864,32 @@ + if (dst_data) + { + wined3d_resource_release_map_ptr(&dst_surface->resource, context); +@@ -4791,6 +6005,14 @@ + wined3d_texture_decref(src_texture); if (context) context_release(context); - return NULL; +#else /* STAGING_CSMT */ -+ memset(&src_map, 0, sizeof(src_map)); -+ memset(&dst_map, 0, sizeof(dst_map)); -+ -+ if (FAILED(wined3d_surface_map(source, &src_map, NULL, WINED3D_MAP_READONLY))) -+ { -+ ERR("Failed to lock the source surface.\n"); -+ wined3d_texture_decref(ret); -+ return NULL; -+ } -+ if (FAILED(wined3d_surface_map(dst, &dst_map, NULL, 0))) -+ { -+ ERR("Failed to lock the destination surface.\n"); -+ wined3d_surface_unmap(source); -+ wined3d_texture_decref(ret); -+ return NULL; -+ } -+ -+ conv->convert(src_map.data, dst_map.data, src_map.row_pitch, dst_map.row_pitch, -+ source->resource.width, source->resource.height); -+ -+ wined3d_surface_unmap(dst); -+ wined3d_surface_unmap(source); -+ -+ return ret; ++ wined3d_surface_unmap(dst_surface); ++ if (src_surface && src_surface != dst_surface) ++ wined3d_surface_unmap(src_surface); ++ /* Release the converted surface, if any. */ ++ if (src_texture) ++ wined3d_texture_decref(src_texture); +#endif /* STAGING_CSMT */ - } - - static HRESULT _Blt_ColorFill(BYTE *buf, unsigned int width, unsigned int height, -@@ -2429,6 +2957,7 @@ - - HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface) - { -+#if defined(STAGING_CSMT) - HRESULT hr; - TRACE("surface %p.\n", surface); - -@@ -2439,6 +2968,20 @@ - memset(&surface->lockedRect, 0, sizeof(surface->lockedRect)); return hr; -+#else /* STAGING_CSMT */ -+ TRACE("surface %p.\n", surface); -+ -+ if (!surface->resource.map_count) -+ { -+ WARN("Trying to unmap unmapped surface.\n"); -+ return WINEDDERR_NOTLOCKED; -+ } -+ --surface->resource.map_count; -+ -+ surface->surface_ops->surface_unmap(surface); -+ -+ return WINED3D_OK; -+#endif /* STAGING_CSMT */ } - - HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface, -@@ -2446,7 +2989,22 @@ - { - const struct wined3d_format *format = surface->resource.format; - unsigned int fmt_flags = surface->container->resource.format_flags; -- -+#if !defined(STAGING_CSMT) -+ struct wined3d_device *device = surface->resource.device; -+ struct wined3d_context *context; -+ const struct wined3d_gl_info *gl_info; -+ BYTE *base_memory; -+ -+ TRACE("surface %p, map_desc %p, box %p, flags %#x.\n", -+ surface, map_desc, box, flags); -+ -+ if (surface->resource.map_count) -+ { -+ WARN("Surface is already mapped.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+#endif /* STAGING_CSMT */ -+ - if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && box - && !surface_check_block_align(surface, box)) - { -@@ -2457,6 +3015,13 @@ - return WINED3DERR_INVALIDCALL; - } - -+#if !defined(STAGING_CSMT) -+ ++surface->resource.map_count; -+ -+ if (!(surface->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) -+ WARN("Trying to lock unlockable surface.\n"); -+ -+#endif /* STAGING_CSMT */ - /* Performance optimization: Count how often a surface is mapped, if it is - * mapped regularly do not throw away the system memory copy. This avoids - * the need to download the surface from OpenGL all the time. The surface -@@ -2472,6 +3037,7 @@ - } - } +@@ -4836,7 +6058,11 @@ + cpu_blit_blit_surface, + }; +#if defined(STAGING_CSMT) - if (box) - { - surface->lockedRect.left = box->left; -@@ -2553,6 +3119,179 @@ - void wined3d_surface_releasedc_cs(struct wined3d_surface *surface) - { - if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM + void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect, +#else /* STAGING_CSMT */ -+ surface_prepare_map_memory(surface); -+ if (flags & WINED3D_MAP_DISCARD) -+ { -+ TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n", -+ wined3d_debug_location(surface->resource.map_binding)); -+ surface_validate_location(surface, surface->resource.map_binding); -+ } -+ else -+ { -+ struct wined3d_context *context = NULL; -+ -+ if (surface->resource.usage & WINED3DUSAGE_DYNAMIC) -+ WARN_(d3d_perf)("Mapping a dynamic surface without WINED3D_MAP_DISCARD.\n"); ++HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect, ++#endif /* STAGING_CSMT */ + struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, + const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) + { +@@ -4854,6 +6080,98 @@ + | WINEDDBLT_DONOTWAIT + | WINEDDBLT_ALPHATEST; + ++#if !defined(STAGING_CSMT) ++ TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", ++ dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), ++ flags, fx, debug_d3dtexturefiltertype(filter)); ++ TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage)); + -+ if (surface->resource.device->d3d_initialized) -+ context = context_acquire(surface->resource.device, NULL); -+ surface_load_location(surface, context, surface->resource.map_binding); -+ if (context) -+ context_release(context); ++ if (fx) ++ { ++ TRACE("dwSize %#x.\n", fx->dwSize); ++ TRACE("dwDDFX %#x.\n", fx->dwDDFX); ++ TRACE("dwROP %#x.\n", fx->dwROP); ++ TRACE("dwDDROP %#x.\n", fx->dwDDROP); ++ TRACE("dwRotationAngle %#x.\n", fx->dwRotationAngle); ++ TRACE("dwZBufferOpCode %#x.\n", fx->dwZBufferOpCode); ++ TRACE("dwZBufferLow %#x.\n", fx->dwZBufferLow); ++ TRACE("dwZBufferHigh %#x.\n", fx->dwZBufferHigh); ++ TRACE("dwZBufferBaseDest %#x.\n", fx->dwZBufferBaseDest); ++ TRACE("dwZDestConstBitDepth %#x.\n", fx->dwZDestConstBitDepth); ++ TRACE("lpDDSZBufferDest %p.\n", fx->u1.lpDDSZBufferDest); ++ TRACE("dwZSrcConstBitDepth %#x.\n", fx->dwZSrcConstBitDepth); ++ TRACE("lpDDSZBufferSrc %p.\n", fx->u2.lpDDSZBufferSrc); ++ TRACE("dwAlphaEdgeBlendBitDepth %#x.\n", fx->dwAlphaEdgeBlendBitDepth); ++ TRACE("dwAlphaEdgeBlend %#x.\n", fx->dwAlphaEdgeBlend); ++ TRACE("dwReserved %#x.\n", fx->dwReserved); ++ TRACE("dwAlphaDestConstBitDepth %#x.\n", fx->dwAlphaDestConstBitDepth); ++ TRACE("lpDDSAlphaDest %p.\n", fx->u3.lpDDSAlphaDest); ++ TRACE("dwAlphaSrcConstBitDepth %#x.\n", fx->dwAlphaSrcConstBitDepth); ++ TRACE("lpDDSAlphaSrc %p.\n", fx->u4.lpDDSAlphaSrc); ++ TRACE("lpDDSPattern %p.\n", fx->u5.lpDDSPattern); ++ TRACE("ddckDestColorkey {%#x, %#x}.\n", ++ fx->ddckDestColorkey.color_space_low_value, ++ fx->ddckDestColorkey.color_space_high_value); ++ TRACE("ddckSrcColorkey {%#x, %#x}.\n", ++ fx->ddckSrcColorkey.color_space_low_value, ++ fx->ddckSrcColorkey.color_space_high_value); + } + -+ if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) -+ surface_invalidate_location(surface, ~surface->resource.map_binding); -+ -+ switch (surface->resource.map_binding) ++ if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) + { -+ case WINED3D_LOCATION_SYSMEM: -+ base_memory = surface->resource.heap_memory; -+ break; -+ -+ case WINED3D_LOCATION_USER_MEMORY: -+ base_memory = surface->user_memory; -+ break; -+ -+ case WINED3D_LOCATION_DIB: -+ base_memory = surface->dib.bitmap_data; -+ break; -+ -+ case WINED3D_LOCATION_BUFFER: -+ context = context_acquire(device, NULL); -+ gl_info = context->gl_info; -+ -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, surface->pbo)); -+ base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); -+ checkGLcall("map PBO"); -+ -+ context_release(context); -+ break; -+ -+ default: -+ ERR("Unexpected map binding %s.\n", wined3d_debug_location(surface->resource.map_binding)); -+ base_memory = NULL; ++ WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); ++ return WINEDDERR_SURFACEBUSY; + } + -+ if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) -+ map_desc->row_pitch = surface->resource.width * format->byte_count; -+ else -+ map_desc->row_pitch = wined3d_surface_get_pitch(surface); -+ map_desc->slice_pitch = surface->resource.height * map_desc->row_pitch; -+ -+ if (!box) ++ if (dst_rect->left >= dst_rect->right || dst_rect->top >= dst_rect->bottom ++ || dst_rect->left > dst_surface->resource.width || dst_rect->left < 0 ++ || dst_rect->top > dst_surface->resource.height || dst_rect->top < 0 ++ || dst_rect->right > dst_surface->resource.width || dst_rect->right < 0 ++ || dst_rect->bottom > dst_surface->resource.height || dst_rect->bottom < 0) + { -+ map_desc->data = base_memory; -+ surface->lockedRect.left = 0; -+ surface->lockedRect.top = 0; -+ surface->lockedRect.right = surface->resource.width; -+ surface->lockedRect.bottom = surface->resource.height; ++ WARN("The application gave us a bad destination rectangle.\n"); ++ return WINEDDERR_INVALIDRECT; + } -+ else ++ ++ if (src_surface) + { -+ if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) -+ { -+ /* Compressed textures are block based, so calculate the offset of -+ * the block that contains the top-left pixel of the locked rectangle. */ -+ map_desc->data = base_memory -+ + ((box->top / format->block_height) * map_desc->row_pitch) -+ + ((box->left / format->block_width) * format->block_byte_count); -+ } -+ else ++ if (src_rect->left >= src_rect->right || src_rect->top >= src_rect->bottom ++ || src_rect->left > src_surface->resource.width || src_rect->left < 0 ++ || src_rect->top > src_surface->resource.height || src_rect->top < 0 ++ || src_rect->right > src_surface->resource.width || src_rect->right < 0 ++ || src_rect->bottom > src_surface->resource.height || src_rect->bottom < 0) + { -+ map_desc->data = base_memory -+ + (map_desc->row_pitch * box->top) -+ + (box->left * format->byte_count); ++ WARN("The application gave us a bad source rectangle.\n"); ++ return WINEDDERR_INVALIDRECT; + } -+ surface->lockedRect.left = box->left; -+ surface->lockedRect.top = box->top; -+ surface->lockedRect.right = box->right; -+ surface->lockedRect.bottom = box->bottom; + } + -+ TRACE("Locked rect %s.\n", wine_dbgstr_rect(&surface->lockedRect)); -+ TRACE("Returning memory %p, pitch %u.\n", map_desc->data, map_desc->row_pitch); ++ if (!fx || !(fx->dwDDFX)) ++ flags &= ~WINEDDBLT_DDFX; + -+ return WINED3D_OK; -+} ++ if (flags & WINEDDBLT_WAIT) ++ flags &= ~WINEDDBLT_WAIT; + -+HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc) -+{ -+ HRESULT hr; -+ struct wined3d_device *device = surface->resource.device; -+ struct wined3d_context *context = NULL; ++ if (flags & WINEDDBLT_ASYNC) ++ { ++ static unsigned int once; + -+ TRACE("surface %p, dc %p.\n", surface, dc); ++ if (!once++) ++ FIXME("Can't handle WINEDDBLT_ASYNC flag.\n"); ++ flags &= ~WINEDDBLT_ASYNC; ++ } + -+ /* Give more detailed info for ddraw. */ -+ if (surface->flags & SFLAG_DCINUSE) -+ return WINEDDERR_DCALREADYCREATED; ++ /* WINEDDBLT_DONOTWAIT appeared in DX7. */ ++ if (flags & WINEDDBLT_DONOTWAIT) ++ { ++ static unsigned int once; + -+ /* Can't GetDC if the surface is locked. */ -+ if (surface->resource.map_count) -+ return WINED3DERR_INVALIDCALL; ++ if (!once++) ++ FIXME("Can't handle WINEDDBLT_DONOTWAIT flag.\n"); ++ flags &= ~WINEDDBLT_DONOTWAIT; ++ } + -+ if (device->d3d_initialized) -+ context = context_acquire(surface->resource.device, NULL); ++#endif /* STAGING_CSMT */ + if (!device->d3d_initialized) + { + WARN("D3D not initialized, using fallback.\n"); +@@ -4917,6 +6235,7 @@ + TRACE("Depth fill.\n"); + + if (!surface_convert_depth_to_float(dst_surface, fx->u5.dwFillDepth, &depth)) ++#if defined(STAGING_CSMT) + return; + + if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, dst_rect, depth))) +@@ -4927,6 +6246,24 @@ + if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->container->resource.draw_binding, + src_rect, dst_surface, dst_surface->container->resource.draw_binding, dst_rect))) + return; ++#else /* STAGING_CSMT */ ++ return WINED3DERR_INVALIDCALL; + -+ /* Create a DIB section if there isn't a dc yet. */ -+ if (!surface->hDC) -+ { -+ if (surface->flags & SFLAG_CLIENT) -+ { -+ surface_load_location(surface, context, WINED3D_LOCATION_SYSMEM); -+ surface_release_client_storage(surface); ++ if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, dst_rect, depth))) ++ return WINED3D_OK; + } -+ hr = surface_create_dib_section(surface); -+ if (FAILED(hr)) ++ else + { -+ if (context) -+ context_release(context); -+ return WINED3DERR_INVALIDCALL; -+ } -+ if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY -+ || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM -+ || surface->pbo)) -+ surface->resource.map_binding = WINED3D_LOCATION_DIB; -+ } -+ -+ surface_load_location(surface, context, WINED3D_LOCATION_DIB); -+ surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB); -+ -+ if (context) -+ context_release(context); -+ -+ surface->flags |= SFLAG_DCINUSE; -+ surface->resource.map_count++; -+ -+ *dc = surface->hDC; -+ TRACE("Returning dc %p.\n", *dc); -+ -+ return WINED3D_OK; -+} -+ -+HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc) -+{ -+ TRACE("surface %p, dc %p.\n", surface, dc); -+ -+ if (!(surface->flags & SFLAG_DCINUSE)) -+ return WINEDDERR_NODC; -+ -+ if (surface->hDC != dc) -+ { -+ WARN("Application tries to release invalid DC %p, surface DC is %p.\n", -+ dc, surface->hDC); -+ return WINEDDERR_NODC; -+ } -+ -+ surface->resource.map_count--; -+ surface->flags &= ~SFLAG_DCINUSE; ++ if (src_ds_flags != dst_ds_flags) ++ { ++ WARN("Rejecting depth / stencil blit between incompatible formats.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } + -+ if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY -+ || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM ++ if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->container->resource.draw_binding, ++ src_rect, dst_surface, dst_surface->container->resource.draw_binding, dst_rect))) ++ return WINED3D_OK; ++#endif /* STAGING_CSMT */ + } + } + else +@@ -4935,8 +6272,13 @@ + + /* In principle this would apply to depth blits as well, but we don't + * implement those in the CPU blitter at the moment. */ ++#if defined(STAGING_CSMT) + if ((dst_surface->resource.locations & dst_surface->resource.map_binding) + && (!src_surface || (src_surface->resource.locations & src_surface->resource.map_binding))) ++#else /* STAGING_CSMT */ ++ if ((dst_surface->locations & dst_surface->resource.map_binding) ++ && (!src_surface || (src_surface->locations & src_surface->resource.map_binding))) ++#endif /* STAGING_CSMT */ + { + if (scale) + TRACE("Not doing sysmem blit because of scaling.\n"); +@@ -4958,7 +6300,11 @@ + goto fallback; + + if (SUCCEEDED(surface_color_fill(dst_surface, dst_rect, &color))) ++#if defined(STAGING_CSMT) + return; ++#else /* STAGING_CSMT */ ++ return WINED3D_OK; ++#endif /* STAGING_CSMT */ + } + else + { +@@ -4980,8 +6326,13 @@ + { + blit_op = WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST; + } ++#if defined(STAGING_CSMT) + else if ((src_surface->resource.locations & WINED3D_LOCATION_SYSMEM) + && !(dst_surface->resource.locations & WINED3D_LOCATION_SYSMEM)) ++#else /* STAGING_CSMT */ ++ else if ((src_surface->locations & WINED3D_LOCATION_SYSMEM) ++ && !(dst_surface->locations & WINED3D_LOCATION_SYSMEM)) ++#endif /* STAGING_CSMT */ + { + /* Upload */ + if (scale) +@@ -4997,11 +6348,18 @@ + if (!wined3d_resource_is_offscreen(&dst_surface->container->resource)) + { + struct wined3d_context *context = context_acquire(device, dst_surface); ++#if defined(STAGING_CSMT) + wined3d_resource_load_location(&dst_surface->resource, context, + dst_surface->container->resource.draw_binding); + context_release(context); + } + return; ++#else /* STAGING_CSMT */ ++ surface_load_location(dst_surface, context, dst_surface->container->resource.draw_binding); ++ context_release(context); ++ } ++ return WINED3D_OK; ++#endif /* STAGING_CSMT */ + } + } + } +@@ -5025,7 +6383,11 @@ + wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, NULL, 0); + dst_swapchain->desc.swap_effect = swap_effect; + ++#if defined(STAGING_CSMT) + return; ++#else /* STAGING_CSMT */ ++ return WINED3D_OK; +#endif /* STAGING_CSMT */ - && surface->resource.map_binding != WINED3D_LOCATION_DIB)) - { - /* The game Salammbo modifies the surface contents without mapping the surface between -@@ -2568,6 +3307,7 @@ - if (device->d3d_initialized) - context = context_acquire(device, NULL); + } + + if (fbo_blit_supported(&device->adapter->gl_info, blit_op, +@@ -5041,10 +6403,17 @@ + dst_surface, dst_surface->container->resource.draw_binding, dst_rect); + context_release(context); +#if defined(STAGING_CSMT) - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_DIB); - if (context) -@@ -2593,6 +3333,13 @@ - surface->flags &= ~SFLAG_DCINUSE; + wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); + wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding); - wined3d_cs_emit_releasedc(surface->resource.device->cs, surface); + return; +#else /* STAGING_CSMT */ -+ surface_load_location(surface, context, surface->resource.map_binding); -+ surface_invalidate_location(surface, WINED3D_LOCATION_DIB); -+ if (context) -+ context_release(context); -+ } ++ surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); ++ surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); ++ ++ return WINED3D_OK; +#endif /* STAGING_CSMT */ + } - return WINED3D_OK; - } -@@ -2609,9 +3356,14 @@ - int i; - BOOL srcIsUpsideDown; - struct wined3d_bo_address data; + blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, blit_op, +@@ -5054,6 +6423,7 @@ + { + blitter->blit_surface(device, blit_op, filter, src_surface, + src_rect, dst_surface, dst_rect, color_key); +#if defined(STAGING_CSMT) - DWORD slice_pitch, pitch; - - wined3d_resource_get_memory(&surface->resource, dst_location, &data); + return; + } + } +@@ -5219,6 +6589,21 @@ + wined3d_surface_location_invalidated, + wined3d_surface_load_location, + }; +#else /* STAGING_CSMT */ ++ return WINED3D_OK; ++ } ++ } ++ } + -+ surface_get_memory(surface, &data, dst_location); ++fallback: ++ /* Special cases for render targets. */ ++ if (SUCCEEDED(surface_blt_special(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter))) ++ return WINED3D_OK; ++ ++cpu: ++ return surface_cpu_blt(dst_surface, dst_rect, src_surface, src_rect, flags, fx, filter); ++} +#endif /* STAGING_CSMT */ - if (surface != old_ctx->current_rt) - { -@@ -2651,8 +3403,13 @@ + static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_texture *container, + const struct wined3d_resource_desc *desc, GLenum target, unsigned int level, unsigned int layer, DWORD flags) +@@ -5280,7 +6665,11 @@ } - /* Setup pixel store pack state -- to glReadPixels into the correct place */ + surface->container = container; +#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(&surface->resource, &pitch, &slice_pitch); - gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, pitch / surface->resource.format->byte_count); + wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); +#else /* STAGING_CSMT */ -+ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, -+ wined3d_surface_get_pitch(surface) / surface->resource.format->byte_count); ++ surface_validate_location(surface, WINED3D_LOCATION_SYSMEM); +#endif /* STAGING_CSMT */ - checkGLcall("glPixelStorei"); + list_init(&surface->renderbuffers); + list_init(&surface->overlays); - gl_info->gl_ops.gl.p_glReadPixels(0, 0, -@@ -2669,6 +3426,10 @@ +@@ -5312,9 +6701,14 @@ + if (surface->resource.map_binding == WINED3D_LOCATION_DIB) { - /* glReadPixels returns the image upside down, and there is no way to prevent this. - * Flip the lines in software. */ -+#if !defined(STAGING_CSMT) -+ UINT pitch = wined3d_surface_get_pitch(surface); -+ + wined3d_resource_free_sysmem(&surface->resource); ++#if defined(STAGING_CSMT) + surface->resource.map_heap_memory = NULL; + wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_DIB); + wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); ++#else /* STAGING_CSMT */ ++ surface_validate_location(surface, WINED3D_LOCATION_DIB); ++ surface_invalidate_location(surface, WINED3D_LOCATION_SYSMEM); +#endif /* STAGING_CSMT */ - if (!(row = HeapAlloc(GetProcessHeap(), 0, pitch))) - goto error; - -@@ -2895,8 +3656,13 @@ + } - /* The texture is now most up to date - If the surface is a render target - * and has a drawable, this path is never entered. */ + return hr; +@@ -5341,7 +6735,11 @@ + if (FAILED(hr = surface_init(object, container, desc, target, level, layer, flags))) + { + WARN("Failed to initialize surface, returning %#x.\n", hr); +#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_resource_invalidate_location(&dst_surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); + /* The command stream takes care of freeing the memory. */ +#else /* STAGING_CSMT */ -+ surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); -+ surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); ++ HeapFree(GetProcessHeap(), 0, object); +#endif /* STAGING_CSMT */ - } - - /* Uses the hardware to stretch and flip the image */ -@@ -2964,7 +3730,11 @@ - checkGLcall("glEnable(texture_target)"); + return hr; + } - /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */ +diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c +--- a/dlls/wined3d/swapchain.c ++++ b/dlls/wined3d/swapchain.c +@@ -320,7 +320,11 @@ + if (backbuffer->resource.multisample_type) + { + location = WINED3D_LOCATION_RB_RESOLVED; +#if defined(STAGING_CSMT) - wined3d_resource_invalidate_location(&src_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_resource_load_location(&backbuffer->resource, context, location); +#else /* STAGING_CSMT */ -+ src_surface->locations &= ~WINED3D_LOCATION_TEXTURE_RGB; ++ surface_load_location(backbuffer, context, location); +#endif /* STAGING_CSMT */ - } + } - /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag -@@ -3161,6 +3931,7 @@ - checkGLcall("glDeleteTextures(1, &backup)"); - } + context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, backbuffer, NULL, location); +@@ -428,11 +432,19 @@ + } + static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in, +#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering) -@@ -3172,6 +3943,17 @@ - * and has a drawable, this path is never entered. */ - wined3d_resource_validate_location(&dst_surface->resource, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_resource_invalidate_location(&dst_surface->resource, ~WINED3D_LOCATION_TEXTURE_RGB); + const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags, + struct wined3d_surface *depth_stencil) + { + struct wined3d_surface *back_buffer = surface_from_resource( + wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); +#else /* STAGING_CSMT */ -+ if (wined3d_settings.strict_draw_ordering) -+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ ++ const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags) ++{ ++ struct wined3d_surface *back_buffer = surface_from_resource( ++ wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0)); ++ const struct wined3d_fb_state *fb = &swapchain->device->fb; ++#endif /* STAGING_CSMT */ + const struct wined3d_gl_info *gl_info; + struct wined3d_context *context; + struct wined3d_surface *front; +@@ -460,6 +472,37 @@ + NULL, WINED3D_TEXF_POINT); + } + ++#if !defined(STAGING_CSMT) ++ if (swapchain->device->bCursorVisible && swapchain->device->cursor_texture ++ && !swapchain->device->hardwareCursor) ++ { ++ struct wined3d_surface *cursor = surface_from_resource( ++ wined3d_texture_get_sub_resource(swapchain->device->cursor_texture, 0)); ++ RECT destRect = ++ { ++ swapchain->device->xScreenSpace - swapchain->device->xHotSpot, ++ swapchain->device->yScreenSpace - swapchain->device->yHotSpot, ++ swapchain->device->xScreenSpace + swapchain->device->cursorWidth - swapchain->device->xHotSpot, ++ swapchain->device->yScreenSpace + swapchain->device->cursorHeight - swapchain->device->yHotSpot, ++ }; ++ RECT src_rect = ++ { ++ 0, 0, ++ swapchain->device->cursor_texture->resource.width, ++ swapchain->device->cursor_texture->resource.height ++ }; ++ const RECT clip_rect = {0, 0, back_buffer->resource.width, back_buffer->resource.height}; + -+ context_release(context); ++ TRACE("Rendering the software cursor.\n"); ++ ++ if (swapchain->desc.windowed) ++ MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&destRect, 2); ++ if (wined3d_clip_blit(&clip_rect, &destRect, &src_rect)) ++ wined3d_surface_blt(back_buffer, &destRect, cursor, &src_rect, WINEDDBLT_ALPHATEST, ++ NULL, WINED3D_TEXF_POINT); ++ } + -+ /* The texture is now most up to date - If the surface is a render target -+ * and has a drawable, this path is never entered. */ -+ surface_validate_location(dst_surface, WINED3D_LOCATION_TEXTURE_RGB); -+ surface_invalidate_location(dst_surface, ~WINED3D_LOCATION_TEXTURE_RGB); +#endif /* STAGING_CSMT */ - } - - /* Front buffer coordinates are always full screen coordinates, but our GL -@@ -3226,9 +4008,15 @@ - - gl_info = context->gl_info; + TRACE("Presenting HDC %p.\n", context->hdc); + render_to_fbo = swapchain->render_to_fbo; +@@ -501,6 +544,7 @@ + */ + if (!swapchain->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { +#if defined(STAGING_CSMT) - /* Make sure the surface is up-to-date. This should probably use - * wined3d_resource_load_location() and worry about the destination - * surface too, unless we're overwriting it completely. */ + wined3d_resource_load_location(&back_buffer->resource, context, WINED3D_LOCATION_TEXTURE_RGB); + wined3d_resource_invalidate_location(&back_buffer->resource, WINED3D_LOCATION_DRAWABLE); + swapchain->render_to_fbo = TRUE; +@@ -509,6 +553,16 @@ + else + { + wined3d_resource_load_location(&back_buffer->resource, context, back_buffer->container->resource.draw_binding); +#else /* STAGING_CSMT */ -+ /* Make sure the surface is up-to-date. This should probably use -+ * surface_load_location() and worry about the destination surface too, -+ * unless we're overwriting it completely. */ ++ surface_load_location(back_buffer, context, WINED3D_LOCATION_TEXTURE_RGB); ++ surface_invalidate_location(back_buffer, WINED3D_LOCATION_DRAWABLE); ++ swapchain->render_to_fbo = TRUE; ++ swapchain_update_draw_bindings(swapchain); ++ } ++ else ++ { ++ surface_load_location(back_buffer, context, back_buffer->container->resource.draw_binding); +#endif /* STAGING_CSMT */ - wined3d_texture_load(src_surface->container, context, FALSE); + } - /* Activate the destination context, set it up for blitting */ -@@ -3271,9 +4059,13 @@ - /* Leave the opengl state valid for blitting */ - device->blitter->unset_shader(context->gl_info); + if (swapchain->render_to_fbo) +@@ -521,8 +575,13 @@ + swapchain_blit(swapchain, context, &src_rect, &dst_rect); + } +#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering + if (swapchain->num_contexts > 1 && !wined3d_settings.cs_multithreaded) + gl_info->gl_ops.gl.p_glFlush(); +#else /* STAGING_CSMT */ -+ if (wined3d_settings.strict_draw_ordering ++ if (swapchain->num_contexts > 1) ++ gl_info->gl_ops.gl.p_glFinish(); +#endif /* STAGING_CSMT */ - || (dst_surface->container->swapchain - && dst_surface->container->swapchain->front_buffer == dst_surface->container)) - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ -@@ -3303,8 +4095,13 @@ - enum wined3d_texture_filter_type filter) - { - struct wined3d_device *device = dst_surface->resource.device; + + /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */ + gl_info->gl_ops.wgl.p_wglSwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */ +@@ -546,6 +605,7 @@ + + front = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); + +#if defined(STAGING_CSMT) - struct wined3d_swapchain *src_swapchain, *dst_swapchain; - const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->state.fb.render_targets[0]); + wined3d_resource_validate_location(&front->resource, WINED3D_LOCATION_DRAWABLE); + wined3d_resource_invalidate_location(&front->resource, ~WINED3D_LOCATION_DRAWABLE); + switch (swapchain->desc.swap_effect) +@@ -574,6 +634,31 @@ + { + wined3d_texture_decref(swapchain->device->cs->onscreen_depth_stencil->container); + swapchain->device->cs->onscreen_depth_stencil = NULL; +#else /* STAGING_CSMT */ -+ const struct wined3d_surface *rt = wined3d_rendertarget_view_get_surface(device->fb.render_targets[0]); -+ struct wined3d_swapchain *src_swapchain, *dst_swapchain; ++ surface_validate_location(front, WINED3D_LOCATION_DRAWABLE); ++ surface_invalidate_location(front, ~WINED3D_LOCATION_DRAWABLE); ++ /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM ++ * and INTEXTURE copies can keep their old content if they have any defined content. ++ * If the swapeffect is COPY, the content remains the same. ++ * ++ * The FLIP swap effect is not implemented yet. We could mark WINED3D_LOCATION_DRAWABLE ++ * up to date and hope WGL flipped front and back buffers and read this data into ++ * the FBO. Don't bother about this for now. */ ++ ++ if (fb->depth_stencil) ++ { ++ struct wined3d_surface *ds = wined3d_rendertarget_view_get_surface(fb->depth_stencil); ++ ++ if (ds && (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL ++ || ds->flags & SFLAG_DISCARD)) ++ { ++ surface_modify_ds_location(ds, WINED3D_LOCATION_DISCARDED, ++ fb->depth_stencil->width, fb->depth_stencil->height); ++ if (ds == swapchain->device->onscreen_depth_stencil) ++ { ++ wined3d_texture_decref(swapchain->device->onscreen_depth_stencil->container); ++ swapchain->device->onscreen_depth_stencil = NULL; +#endif /* STAGING_CSMT */ + } + } + } +@@ -606,7 +691,11 @@ - TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, blt_fx %p, filter %s.\n", - dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), -@@ -3495,6 +4292,7 @@ - { - TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h); + TRACE("Copying surface %p to screen.\n", front); +#if defined(STAGING_CSMT) - if (((surface->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) && !(location & WINED3D_LOCATION_TEXTURE_RGB)) - || (!(surface->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) - && (location & WINED3D_LOCATION_TEXTURE_RGB))) -@@ -3503,6 +4301,15 @@ - surface->ds_current_size.cx = w; - surface->ds_current_size.cy = h; - surface->resource.locations = location; + wined3d_resource_load_location(&front->resource, NULL, WINED3D_LOCATION_DIB); +#else /* STAGING_CSMT */ -+ if (((surface->locations & WINED3D_LOCATION_TEXTURE_RGB) && !(location & WINED3D_LOCATION_TEXTURE_RGB)) -+ || (!(surface->locations & WINED3D_LOCATION_TEXTURE_RGB) && (location & WINED3D_LOCATION_TEXTURE_RGB))) -+ wined3d_texture_set_dirty(surface->container); -+ -+ surface->ds_current_size.cx = w; -+ surface->ds_current_size.cy = h; -+ surface->locations = location; ++ surface_load_location(front, NULL, WINED3D_LOCATION_DIB); +#endif /* STAGING_CSMT */ - } - /* Context activation is done by the caller. */ -@@ -3517,7 +4324,11 @@ - /* TODO: Make this work for modes other than FBO */ - if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return; + src_dc = front->hDC; + window = swapchain->win_handle; +@@ -634,8 +723,12 @@ + } + static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in, +#if defined(STAGING_CSMT) - if (!(surface->resource.locations & location)) + const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags, + struct wined3d_surface *depth_stencil) +#else /* STAGING_CSMT */ -+ if (!(surface->locations & location)) ++ const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags) +#endif /* STAGING_CSMT */ + { + struct wined3d_surface *front, *back; + +@@ -662,9 +755,15 @@ { - w = surface->ds_current_size.cx; - h = surface->ds_current_size.cy; -@@ -3543,6 +4354,7 @@ - return; - } + void *tmp; +#if defined(STAGING_CSMT) - if (surface->resource.locations & WINED3D_LOCATION_DISCARDED) - { - TRACE("Surface was discarded, no need copy data.\n"); -@@ -3558,6 +4370,23 @@ - { - FIXME("No up to date depth stencil location.\n"); - surface->resource.locations |= location; + tmp = front->resource.bitmap_data; + front->resource.bitmap_data = back->resource.bitmap_data; + back->resource.bitmap_data = tmp; +#else /* STAGING_CSMT */ -+ if (surface->locations & WINED3D_LOCATION_DISCARDED) -+ { -+ TRACE("Surface was discarded, no need copy data.\n"); -+ wined3d_surface_prepare(surface, context, location); -+ surface->locations &= ~WINED3D_LOCATION_DISCARDED; -+ surface->locations |= location; -+ surface->ds_current_size.cx = surface->resource.width; -+ surface->ds_current_size.cy = surface->resource.height; -+ return; -+ } -+ -+ if (!surface->locations) -+ { -+ FIXME("No up to date depth stencil location.\n"); -+ surface->locations |= location; ++ tmp = front->dib.bitmap_data; ++ front->dib.bitmap_data = back->dib.bitmap_data; ++ back->dib.bitmap_data = tmp; +#endif /* STAGING_CSMT */ - surface->ds_current_size.cx = surface->resource.width; - surface->ds_current_size.cy = surface->resource.height; - return; -@@ -3621,9 +4450,13 @@ - context_invalidate_state(context, STATE_FRAMEBUFFER); + if (front->resource.heap_memory) + ERR("GDI Surface %p has heap memory allocated.\n", front); +@@ -735,6 +834,7 @@ + swapchain->render_to_fbo = TRUE; + } +#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering) -+#else /* STAGING_CSMT */ -+ if (wined3d_settings.strict_draw_ordering) -+#endif /* STAGING_CSMT */ - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - } - else if (location == WINED3D_LOCATION_DRAWABLE) -@@ -3639,9 +4472,13 @@ - - context_invalidate_state(context, STATE_FRAMEBUFFER); + HRESULT swapchain_create_context_cs(struct wined3d_device *device, struct wined3d_swapchain *swapchain) + { + const struct wined3d_adapter *adapter = device->adapter; +@@ -798,6 +898,7 @@ + return WINED3D_OK; + } ++#endif /* STAGING_CSMT */ + static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, + struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) + { +@@ -888,8 +989,13 @@ + front_buffer = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0)); + if (!(device->wined3d->flags & WINED3D_NO3D)) + { +#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering) + wined3d_resource_validate_location(&front_buffer->resource, WINED3D_LOCATION_DRAWABLE); + wined3d_resource_invalidate_location(&front_buffer->resource, ~WINED3D_LOCATION_DRAWABLE); +#else /* STAGING_CSMT */ -+ if (wined3d_settings.strict_draw_ordering) ++ surface_validate_location(front_buffer, WINED3D_LOCATION_DRAWABLE); ++ surface_invalidate_location(front_buffer, ~WINED3D_LOCATION_DRAWABLE); +#endif /* STAGING_CSMT */ - gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ - } - else -@@ -3649,6 +4486,7 @@ - ERR("Invalid location (%#x) specified.\n", location); } -+#if defined(STAGING_CSMT) - surface->resource.locations |= location; - surface->ds_current_size.cx = surface->resource.width; - surface->ds_current_size.cy = surface->resource.height; -@@ -3681,6 +4519,124 @@ + /* MSDN says we're only allowed a single fullscreen swapchain per device, +@@ -915,9 +1021,66 @@ - FIXME("Can't load surface %p with location flags %s into sysmem.\n", - surface, wined3d_debug_location(surface->resource.locations)); + if (!(device->wined3d->flags & WINED3D_NO3D)) + { ++#if defined(STAGING_CSMT) + hr = wined3d_cs_emit_create_swapchain_context(device->cs, swapchain); + if (FAILED(hr)) + goto err; +#else /* STAGING_CSMT */ -+ surface->locations |= location; -+ surface->ds_current_size.cx = surface->resource.width; -+ surface->ds_current_size.cy = surface->resource.height; -+} -+ -+void surface_validate_location(struct wined3d_surface *surface, DWORD location) -+{ -+ TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); -+ -+ surface->locations |= location; -+} -+ -+void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) -+{ -+ TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); -+ -+ if (location & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) -+ wined3d_texture_set_dirty(surface->container); -+ surface->locations &= ~location; -+ -+ if (!surface->locations) -+ ERR("Surface %p does not have any up to date location.\n", surface); -+} -+ -+static DWORD resource_access_from_location(DWORD location) -+{ -+ switch (location) -+ { -+ case WINED3D_LOCATION_SYSMEM: -+ case WINED3D_LOCATION_USER_MEMORY: -+ case WINED3D_LOCATION_DIB: -+ case WINED3D_LOCATION_BUFFER: -+ return WINED3D_RESOURCE_ACCESS_CPU; -+ -+ case WINED3D_LOCATION_DRAWABLE: -+ case WINED3D_LOCATION_TEXTURE_SRGB: -+ case WINED3D_LOCATION_TEXTURE_RGB: -+ case WINED3D_LOCATION_RB_MULTISAMPLE: -+ case WINED3D_LOCATION_RB_RESOLVED: -+ return WINED3D_RESOURCE_ACCESS_GPU; -+ -+ default: -+ FIXME("Unhandled location %#x.\n", location); -+ return 0; -+ } -+} -+ -+static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD location) -+{ -+ struct wined3d_device *device = surface->resource.device; -+ struct wined3d_context *context; -+ const struct wined3d_gl_info *gl_info; -+ struct wined3d_bo_address dst, src; -+ UINT size = surface->resource.size; -+ -+ surface_get_memory(surface, &dst, location); -+ surface_get_memory(surface, &src, surface->locations); -+ -+ if (dst.buffer_object) -+ { -+ context = context_acquire(device, NULL); -+ gl_info = context->gl_info; -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); -+ GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); -+ checkGLcall("Upload PBO"); -+ context_release(context); -+ return; -+ } -+ if (src.buffer_object) -+ { -+ context = context_acquire(device, NULL); -+ gl_info = context->gl_info; -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); -+ GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); -+ GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); -+ checkGLcall("Download PBO"); -+ context_release(context); -+ return; -+ } -+ memcpy(dst.addr, src.addr, size); -+} -+ -+/* Context activation is done by the caller. */ -+static void surface_load_sysmem(struct wined3d_surface *surface, -+ struct wined3d_context *context, DWORD dst_location) -+{ -+ const struct wined3d_gl_info *gl_info = context->gl_info; -+ -+ if (surface->locations & surface_simple_locations) -+ { -+ surface_copy_simple_location(surface, dst_location); -+ return; -+ } ++ static const enum wined3d_format_id formats[] = ++ { ++ WINED3DFMT_D24_UNORM_S8_UINT, ++ WINED3DFMT_D32_UNORM, ++ WINED3DFMT_R24_UNORM_X8_TYPELESS, ++ WINED3DFMT_D16_UNORM, ++ WINED3DFMT_S1_UINT_D15_UNORM ++ }; + -+ if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) -+ surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB); ++ const struct wined3d_gl_info *gl_info = &adapter->gl_info; + -+ /* Download the surface to system memory. */ -+ if (surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) -+ { -+ wined3d_texture_bind_and_dirtify(surface->container, context, -+ !(surface->locations & WINED3D_LOCATION_TEXTURE_RGB)); -+ surface_download_data(surface, gl_info, dst_location); ++ swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context)); ++ if (!swapchain->context) ++ { ++ ERR("Failed to create the context array.\n"); ++ hr = E_OUTOFMEMORY; ++ goto err; ++ } ++ swapchain->num_contexts = 1; + -+ return; -+ } ++ /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate. ++ * You are able to add a depth + stencil surface at a later stage when you need it. ++ * In order to support this properly in WineD3D we need the ability to recreate the opengl context and ++ * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new ++ * context, need torecreate shaders, textures and other resources. ++ * ++ * The context manager already takes care of the state problem and for the other tasks code from Reset ++ * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now. ++ * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the ++ * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this ++ * issue needs to be fixed. */ ++ for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++) ++ { ++ swapchain->ds_format = wined3d_get_format(gl_info, formats[i]); ++ swapchain->context[0] = context_create(swapchain, front_buffer, swapchain->ds_format); ++ if (swapchain->context[0]) break; ++ TRACE("Depth stencil format %s is not supported, trying next format\n", ++ debug_d3dformat(formats[i])); ++ } + -+ if (surface->locations & WINED3D_LOCATION_DRAWABLE) -+ { -+ read_from_framebuffer(surface, context, dst_location); -+ return; -+ } ++ if (!swapchain->context[0]) ++ { ++ WARN("Failed to create context.\n"); ++ hr = WINED3DERR_NOTAVAILABLE; ++ goto err; ++ } + -+ FIXME("Can't load surface %p with location flags %s into sysmem.\n", -+ surface, wined3d_debug_location(surface->locations)); ++ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO ++ && (!desc->enable_auto_depth_stencil ++ || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id)) ++ { ++ FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n"); ++ } ++ context_release(swapchain->context[0]); +#endif /* STAGING_CSMT */ - } - - /* Context activation is done by the caller. */ -@@ -3689,12 +4645,14 @@ - { - RECT r; + } -+#if defined(STAGING_CSMT) - if (surface->resource.locations & WINED3D_LOCATION_DISCARDED) + if (swapchain->desc.backbuffer_count > 0) +diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c +--- a/dlls/wined3d/texture.c ++++ b/dlls/wined3d/texture.c +@@ -68,8 +68,10 @@ { - TRACE("Surface was discarded, nothing to do.\n"); - return WINED3D_OK; + ERR("Failed to allocate sub-resource array.\n"); + resource_cleanup(&texture->resource); ++#if defined(STAGING_CSMT) + if (wined3d_settings.cs_multithreaded) + texture->resource.device->cs->ops->finish(texture->resource.device->cs); ++#endif /* STAGING_CSMT */ + return E_OUTOFMEMORY; } +@@ -114,6 +116,7 @@ + resource_unload(&texture->resource); + } + ++#if defined(STAGING_CSMT) + void wined3d_texture_cleanup_cs(struct wined3d_texture *texture) + { + wined3d_texture_unload_gl_texture(texture); +@@ -126,6 +129,12 @@ + UINT sub_count = texture->level_count * texture->layer_count; + UINT i; + struct wined3d_device *device = texture->resource.device; ++#else /* STAGING_CSMT */ ++static void wined3d_texture_cleanup(struct wined3d_texture *texture) ++{ ++ UINT sub_count = texture->level_count * texture->layer_count; ++ UINT i; +#endif /* STAGING_CSMT */ - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO - && wined3d_resource_is_offscreen(&surface->container->resource)) - { -@@ -3703,7 +4661,11 @@ + + TRACE("texture %p.\n", texture); + +@@ -137,8 +146,14 @@ + texture->texture_ops->texture_sub_resource_cleanup(sub_resource); } - surface_get_rect(surface, NULL, &r); +#if defined(STAGING_CSMT) - wined3d_resource_load_location(&surface->resource, context, WINED3D_LOCATION_TEXTURE_RGB); + resource_cleanup(&texture->resource); + wined3d_cs_emit_texture_cleanup(device->cs, texture); +#else /* STAGING_CSMT */ -+ surface_load_location(surface, context, WINED3D_LOCATION_TEXTURE_RGB); ++ wined3d_texture_unload_gl_texture(texture); ++ HeapFree(GetProcessHeap(), 0, texture->sub_resources); ++ resource_cleanup(&texture->resource); +#endif /* STAGING_CSMT */ - surface_blt_to_drawable(surface->resource.device, context, - WINED3D_TEXF_POINT, FALSE, surface, &r, surface, &r); + } -@@ -3718,6 +4680,7 @@ - struct wined3d_device *device = surface->resource.device; - const struct wined3d_color_key_conversion *conversion; - struct wined3d_texture *texture = surface->container; -+#if defined(STAGING_CSMT) - UINT width, src_row_pitch, src_slice_pitch, dst_pitch; - struct wined3d_bo_address data; - struct wined3d_format format; -@@ -3744,6 +4707,24 @@ - } + void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) +@@ -422,10 +437,16 @@ - if (surface->resource.locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB) + if (!refcount) + { ++#if defined(STAGING_CSMT) + void *parent = texture->resource.parent; + const struct wined3d_parent_ops *parent_ops = texture->resource.parent_ops; + wined3d_texture_cleanup(texture); + parent_ops->wined3d_object_destroyed(parent); +#else /* STAGING_CSMT */ -+ UINT width, src_pitch, dst_pitch; -+ struct wined3d_bo_address data; -+ struct wined3d_format format; -+ POINT dst_point = {0, 0}; -+ BYTE *mem = NULL; -+ -+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO -+ && wined3d_resource_is_offscreen(&texture->resource) -+ && (surface->locations & WINED3D_LOCATION_DRAWABLE)) -+ { -+ surface_load_fb_texture(surface, srgb, context); -+ -+ return WINED3D_OK; -+ } -+ -+ if (surface->locations & (WINED3D_LOCATION_TEXTURE_SRGB | WINED3D_LOCATION_TEXTURE_RGB) ++ wined3d_texture_cleanup(texture); ++ texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent); ++ HeapFree(GetProcessHeap(), 0, texture); +#endif /* STAGING_CSMT */ - && (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB) - && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, - NULL, surface->resource.usage, surface->resource.pool, surface->resource.format, -@@ -3759,6 +4740,7 @@ - return WINED3D_OK; } + return refcount; +@@ -497,8 +518,15 @@ + + void CDECL wined3d_texture_preload(struct wined3d_texture *texture) + { +#if defined(STAGING_CSMT) - if (surface->resource.locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED) - && (!srgb || (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)) - && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, -@@ -3766,6 +4748,15 @@ - NULL, surface->resource.usage, surface->resource.pool, surface->resource.format)) - { - DWORD src_location = surface->resource.locations & WINED3D_LOCATION_RB_RESOLVED ? + const struct wined3d_device *device = texture->resource.device; + wined3d_cs_emit_texture_preload(device->cs, texture); +#else /* STAGING_CSMT */ -+ if (surface->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED) -+ && (!srgb || (surface->container->resource.format_flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)) -+ && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT, -+ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format, -+ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format)) -+ { -+ DWORD src_location = surface->locations & WINED3D_LOCATION_RB_RESOLVED ? ++ struct wined3d_context *context; ++ context = context_acquire(texture->resource.device, NULL); ++ wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB); ++ context_release(context); +#endif /* STAGING_CSMT */ - WINED3D_LOCATION_RB_RESOLVED : WINED3D_LOCATION_RB_MULTISAMPLE; - DWORD dst_location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; - RECT rect = {0, 0, surface->resource.width, surface->resource.height}; -@@ -3780,6 +4771,7 @@ + } - if (srgb) + void * CDECL wined3d_texture_get_parent(const struct wined3d_texture *texture) +@@ -527,6 +555,7 @@ + + if (texture->lod != lod) { +#if defined(STAGING_CSMT) - if ((surface->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding)) - == WINED3D_LOCATION_TEXTURE_RGB) + if (wined3d_settings.cs_multithreaded) { -@@ -3814,6 +4806,42 @@ + struct wined3d_device *device = texture->resource.device; +@@ -534,6 +563,7 @@ + device->cs->ops->finish(device->cs); + } - width = surface->resource.width; - wined3d_resource_get_pitch(&surface->resource, &src_row_pitch, &src_slice_pitch); ++#endif /* STAGING_CSMT */ + texture->lod = lod; + + texture->texture_rgb.base_level = ~0u; +@@ -652,10 +682,14 @@ + } + + if (device->d3d_initialized) ++#if defined(STAGING_CSMT) + { + wined3d_cs_emit_evict_resource(device->cs, &surface->resource); + device->cs->ops->finish(device->cs); + } +#else /* STAGING_CSMT */ -+ if ((surface->locations & (WINED3D_LOCATION_TEXTURE_RGB | surface->resource.map_binding)) -+ == WINED3D_LOCATION_TEXTURE_RGB) -+ { -+ /* Performance warning... */ -+ FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface); -+ surface_prepare_map_memory(surface); -+ surface_load_location(surface, context, surface->resource.map_binding); -+ } -+ } -+ else -+ { -+ if ((surface->locations & (WINED3D_LOCATION_TEXTURE_SRGB | surface->resource.map_binding)) -+ == WINED3D_LOCATION_TEXTURE_SRGB) -+ { -+ /* Performance warning... */ -+ FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface); -+ surface_prepare_map_memory(surface); -+ surface_load_location(surface, context, surface->resource.map_binding); -+ } -+ } -+ -+ if (!(surface->locations & surface_simple_locations)) -+ { -+ WARN("Trying to load a texture from sysmem, but no simple location is valid.\n"); -+ /* Lets hope we get it from somewhere... */ -+ surface_prepare_system_memory(surface); -+ surface_load_location(surface, context, WINED3D_LOCATION_SYSMEM); -+ } -+ -+ wined3d_texture_prepare_texture(texture, context, srgb); -+ wined3d_texture_bind_and_dirtify(texture, context, srgb); -+ -+ width = surface->resource.width; -+ src_pitch = wined3d_surface_get_pitch(surface); ++ texture->resource.resource_ops->resource_unload(&texture->resource); +#endif /* STAGING_CSMT */ - format = *texture->resource.format; - if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE))) -@@ -3822,7 +4850,11 @@ - /* Don't use PBOs for converted surfaces. During PBO conversion we look at - * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is - * getting called. */ + texture->resource.format = format; + texture->resource.multisample_type = multisample_type; +@@ -790,11 +824,19 @@ + struct wined3d_surface *surface = surface_from_resource(sub_resource); + struct wined3d_context *context; + +#if defined(STAGING_CSMT) - if ((format.convert || conversion) && surface->resource.buffer) + context = context_acquire(surface->resource.device, NULL); + wined3d_resource_prepare_map_memory(&surface->resource, context); + wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); + context_release(context); + wined3d_resource_invalidate_location(&surface->resource, ~surface->resource.map_binding); +#else /* STAGING_CSMT */ -+ if ((format.convert || conversion) && surface->pbo) ++ surface_prepare_map_memory(surface); ++ context = context_acquire(surface->resource.device, NULL); ++ surface_load_location(surface, context, surface->resource.map_binding); ++ context_release(context); ++ surface_invalidate_location(surface, ~surface->resource.map_binding); +#endif /* STAGING_CSMT */ - { - TRACE("Removing the pbo attached to surface %p.\n", surface); + } -@@ -3831,6 +4863,7 @@ - else - surface->resource.map_binding = WINED3D_LOCATION_SYSMEM; + static void texture2d_sub_resource_cleanup(struct wined3d_resource *sub_resource) +@@ -806,12 +848,25 @@ + static void texture2d_sub_resource_invalidate_location(struct wined3d_resource *sub_resource, DWORD location) + { +#if defined(STAGING_CSMT) - wined3d_resource_prepare_map_memory(&surface->resource, context); - wined3d_resource_load_location(&surface->resource, context, surface->resource.map_binding); - wined3d_resource_free_bo(&surface->resource); -@@ -3838,6 +4871,14 @@ - } + wined3d_resource_invalidate_location(sub_resource, location); + } - wined3d_resource_get_memory(&surface->resource, surface->resource.locations, &data); + static void texture2d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) + { + wined3d_resource_validate_location(sub_resource, location); +#else /* STAGING_CSMT */ -+ surface_prepare_map_memory(surface); -+ surface_load_location(surface, context, surface->resource.map_binding); -+ surface_remove_pbo(surface, gl_info); -+ } ++ struct wined3d_surface *surface = surface_from_resource(sub_resource); + -+ surface_get_memory(surface, &data, surface->locations); ++ surface_invalidate_location(surface, location); ++} ++ ++static void texture2d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) ++{ ++ struct wined3d_surface *surface = surface_from_resource(sub_resource); ++ ++ surface_validate_location(surface, location); +#endif /* STAGING_CSMT */ - if (format.convert) + } + + static void texture2d_sub_resource_upload_data(struct wined3d_resource *sub_resource, +@@ -954,6 +1009,7 @@ + return wined3d_surface_unmap(surface_from_resource(sub_resource)); + } + ++#if defined(STAGING_CSMT) + static void wined3d_texture_load_location_invalidated(struct wined3d_resource *resource, DWORD location) + { + ERR("Should not be called on textures.\n"); +@@ -966,6 +1022,7 @@ + ERR("Should not be called on textures.\n"); + } + ++#endif /* STAGING_CSMT */ + static const struct wined3d_resource_ops texture2d_resource_ops = + { + texture_resource_incref, +@@ -973,8 +1030,10 @@ + wined3d_texture_unload, + texture2d_resource_sub_resource_map, + texture2d_resource_sub_resource_unmap, ++#if defined(STAGING_CSMT) + wined3d_texture_load_location_invalidated, + wined3d_texture_load_location, ++#endif /* STAGING_CSMT */ + }; + + static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, +@@ -993,7 +1052,9 @@ + if (WINED3DFMT_UNKNOWN >= desc->format) { - /* This code is entered for texture formats which need a fixup. */ -@@ -3852,9 +4893,15 @@ - context_release(context); - return E_OUTOFMEMORY; - } + WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); +#if defined(STAGING_CSMT) - format.convert(data.addr, mem, src_row_pitch, src_row_pitch * height, - dst_pitch, dst_pitch * height, width, height, 1); - src_row_pitch = dst_pitch; -+#else /* STAGING_CSMT */ -+ format.convert(data.addr, mem, src_pitch, src_pitch * height, -+ dst_pitch, dst_pitch * height, width, height, 1); -+ src_pitch = dst_pitch; + HeapFree(GetProcessHeap(), 0, texture); +#endif /* STAGING_CSMT */ - data.addr = mem; + return WINED3DERR_INVALIDCALL; } - else if (conversion) -@@ -3874,6 +4921,7 @@ - } - if (texture->swapchain && texture->swapchain->palette) - palette = texture->swapchain->palette; -+#if defined(STAGING_CSMT) - conversion->convert(data.addr, src_row_pitch, mem, dst_pitch, - width, height, palette, &texture->async.gl_color_key); - src_row_pitch = dst_pitch; -@@ -3882,6 +4930,16 @@ - wined3d_surface_upload_data(surface, gl_info, &format, &src_rect, - src_row_pitch, &dst_point, srgb, wined3d_const_bo_address(&data)); +@@ -1024,7 +1085,9 @@ + else + { + WARN("Attempted to create a mipmapped/cube NPOT texture without unconditional NPOT support.\n"); ++#if defined(STAGING_CSMT) + HeapFree(GetProcessHeap(), 0, texture); ++#endif /* STAGING_CSMT */ + return WINED3DERR_INVALIDCALL; + } + } +@@ -1037,6 +1100,7 @@ + if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) + { + WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n"); ++#if defined(STAGING_CSMT) + HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; + } +@@ -1045,6 +1109,14 @@ + { + WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); + HeapFree(GetProcessHeap(), 0, texture); +#else /* STAGING_CSMT */ -+ conversion->convert(data.addr, src_pitch, mem, dst_pitch, -+ width, height, palette, &texture->async.gl_color_key); -+ src_pitch = dst_pitch; -+ data.addr = mem; -+ } ++ return WINED3DERR_INVALIDCALL; ++ } + -+ wined3d_surface_upload_data(surface, gl_info, &format, &src_rect, -+ src_pitch, &dst_point, srgb, wined3d_const_bo_address(&data)); ++ if (level_count != 1) ++ { ++ WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); +#endif /* STAGING_CSMT */ + return WINED3DERR_INVALIDCALL; + } + } +@@ -1053,7 +1125,9 @@ + flags, device, parent, parent_ops, &texture2d_resource_ops))) + { + WARN("Failed to initialize texture, returning %#x.\n", hr); ++#if defined(STAGING_CSMT) + HeapFree(GetProcessHeap(), 0, texture); ++#endif /* STAGING_CSMT */ + return hr; + } - HeapFree(GetProcessHeap(), 0, mem); - -@@ -3895,11 +4953,19 @@ - const RECT rect = {0, 0, surface->resource.width, surface->resource.height}; - DWORD src_location; +@@ -1156,12 +1230,25 @@ + static void texture3d_sub_resource_invalidate_location(struct wined3d_resource *sub_resource, DWORD location) + { +#if defined(STAGING_CSMT) - if (surface->resource.locations & WINED3D_LOCATION_RB_MULTISAMPLE) - src_location = WINED3D_LOCATION_RB_MULTISAMPLE; - else if (surface->resource.locations & WINED3D_LOCATION_RB_RESOLVED) - src_location = WINED3D_LOCATION_RB_RESOLVED; - else if (surface->resource.locations & WINED3D_LOCATION_TEXTURE_SRGB) -+#else /* STAGING_CSMT */ -+ if (surface->locations & WINED3D_LOCATION_RB_MULTISAMPLE) -+ src_location = WINED3D_LOCATION_RB_MULTISAMPLE; -+ else if (surface->locations & WINED3D_LOCATION_RB_RESOLVED) -+ src_location = WINED3D_LOCATION_RB_RESOLVED; -+ else if (surface->locations & WINED3D_LOCATION_TEXTURE_SRGB) -+#endif /* STAGING_CSMT */ - src_location = WINED3D_LOCATION_TEXTURE_SRGB; - else /* surface_blt_fbo will load the source location if necessary. */ - src_location = WINED3D_LOCATION_TEXTURE_RGB; -@@ -3908,41 +4974,87 @@ - surface, src_location, &rect, surface, dst_location, &rect); + wined3d_resource_invalidate_location(sub_resource, location); } -+#if defined(STAGING_CSMT) - /* Context activation is done by the caller. */ - static void wined3d_surface_load_location(struct wined3d_resource *resource, - struct wined3d_context *context, DWORD location) + static void texture3d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) { - struct wined3d_surface *surface = surface_from_resource(resource); + wined3d_resource_validate_location(sub_resource, location); +#else /* STAGING_CSMT */ -+/* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */ -+HRESULT surface_load_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location) ++ struct wined3d_volume *volume = volume_from_resource(sub_resource); ++ ++ wined3d_volume_invalidate_location(volume, location); ++} ++ ++static void texture3d_sub_resource_validate_location(struct wined3d_resource *sub_resource, DWORD location) +{ ++ struct wined3d_volume *volume = volume_from_resource(sub_resource); ++ ++ wined3d_volume_validate_location(volume, location); +#endif /* STAGING_CSMT */ - HRESULT hr; + } - TRACE("surface %p, location %s.\n", surface, wined3d_debug_location(location)); + static void texture3d_sub_resource_upload_data(struct wined3d_resource *sub_resource, +@@ -1171,7 +1258,11 @@ + struct wined3d_const_bo_address addr; + unsigned int row_pitch, slice_pitch; - if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) ++#if defined(STAGING_CSMT) + wined3d_resource_get_pitch(sub_resource, &row_pitch, &slice_pitch); ++#else /* STAGING_CSMT */ ++ wined3d_volume_get_pitch(volume, &row_pitch, &slice_pitch); ++#endif /* STAGING_CSMT */ + if (row_pitch != data->row_pitch || slice_pitch != data->slice_pitch) + FIXME("Ignoring row/slice pitch (%u/%u).\n", data->row_pitch, data->slice_pitch); + +@@ -1256,6 +1347,7 @@ + if (WINED3DFMT_UNKNOWN >= desc->format) { -- if (location == WINED3D_LOCATION_TEXTURE_RGB -- && surface->resource.locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_DISCARDED)) -+ if (location == WINED3D_LOCATION_TEXTURE_RGB + WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); +#if defined(STAGING_CSMT) -+ && surface->resource.locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_DISCARDED)) -+ { -+ surface_load_ds_location(surface, context, location); -+ return; -+ } -+ else if (location & surface->resource.locations -+ && surface->container->resource.draw_binding != WINED3D_LOCATION_DRAWABLE) -+ { -+ /* Already up to date, nothing to do. */ -+ return; -+ } -+ else -+ { -+ FIXME("Unimplemented copy from %s to %s for depth/stencil buffers.\n", -+ wined3d_debug_location(surface->resource.locations), wined3d_debug_location(location)); -+ return; -+ } + HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; + } +@@ -1264,6 +1356,14 @@ + { + WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture); + HeapFree(GetProcessHeap(), 0, texture); ++#else /* STAGING_CSMT */ ++ return WINED3DERR_INVALIDCALL; + } + -+ if (!surface->resource.locations) ++ if (!gl_info->supported[EXT_TEXTURE3D]) + { -+ ERR("Surface %p does not have any up to date location.\n", surface); -+ return; -+#else /* STAGING_CSMT */ -+ && surface->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_DISCARDED)) - { - surface_load_ds_location(surface, context, location); -- return; -+ return WINED3D_OK; - } -- else if (location & surface->resource.locations -+ else if (location & surface->locations - && surface->container->resource.draw_binding != WINED3D_LOCATION_DRAWABLE) ++ WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture); ++#endif /* STAGING_CSMT */ + return WINED3DERR_INVALIDCALL; + } + +@@ -1273,6 +1373,7 @@ + if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) { - /* Already up to date, nothing to do. */ -- return; -+ return WINED3D_OK; + WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); ++#if defined(STAGING_CSMT) + HeapFree(GetProcessHeap(), 0, texture); + return WINED3DERR_INVALIDCALL; } - else +@@ -1281,6 +1382,14 @@ { - FIXME("Unimplemented copy from %s to %s for depth/stencil buffers.\n", -- wined3d_debug_location(surface->resource.locations), wined3d_debug_location(location)); -- return; -+ wined3d_debug_location(surface->locations), wined3d_debug_location(location)); + WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); + HeapFree(GetProcessHeap(), 0, texture); ++#else /* STAGING_CSMT */ + return WINED3DERR_INVALIDCALL; ++ } ++ ++ if (levels != 1) ++ { ++ WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); ++#endif /* STAGING_CSMT */ + return WINED3DERR_INVALIDCALL; + } + } +@@ -1308,7 +1417,9 @@ + { + WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n", + desc->width, desc->height, desc->depth); ++#if defined(STAGING_CSMT) + HeapFree(GetProcessHeap(), 0, texture); ++#endif /* STAGING_CSMT */ + return WINED3DERR_INVALIDCALL; + } } +@@ -1318,7 +1429,9 @@ + 0, device, parent, parent_ops, &texture3d_resource_ops))) + { + WARN("Failed to initialize texture, returning %#x.\n", hr); ++#if defined(STAGING_CSMT) + HeapFree(GetProcessHeap(), 0, texture); ++#endif /* STAGING_CSMT */ + return hr; } -- if (!surface->resource.locations) -+ if (surface->locations & location) -+ { -+ TRACE("Location already up to date.\n"); -+ return WINED3D_OK; -+ } -+ -+ if (WARN_ON(d3d_surface)) -+ { -+ DWORD required_access = resource_access_from_location(location); -+ if ((surface->resource.access_flags & required_access) != required_access) -+ WARN("Operation requires %#x access, but surface only has %#x.\n", -+ required_access, surface->resource.access_flags); -+ } -+ -+ if (!surface->locations) +@@ -1438,6 +1551,9 @@ + if (FAILED(hr)) { - ERR("Surface %p does not have any up to date location.\n", surface); -- return; -+ return WINED3DERR_INVALIDCALL; + WARN("Failed to initialize texture, returning %#x.\n", hr); ++#if !defined(STAGING_CSMT) ++ HeapFree(GetProcessHeap(), 0, object); +#endif /* STAGING_CSMT */ + return hr; } - switch (location) -@@ -3956,7 +5068,11 @@ - - case WINED3D_LOCATION_DRAWABLE: - if (FAILED(hr = surface_load_drawable(surface, context))) +@@ -1459,8 +1575,15 @@ + HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc) + { + struct wined3d_device *device = texture->resource.device; +#if defined(STAGING_CSMT) - return; + struct wined3d_resource *sub_resource; + struct wined3d_surface *surface; +#else /* STAGING_CSMT */ -+ return hr; ++ struct wined3d_context *context = NULL; ++ struct wined3d_resource *sub_resource; ++ struct wined3d_surface *surface; ++ HRESULT hr; +#endif /* STAGING_CSMT */ - break; - case WINED3D_LOCATION_RB_RESOLVED: -@@ -3968,7 +5084,11 @@ - case WINED3D_LOCATION_TEXTURE_SRGB: - if (FAILED(hr = surface_load_texture(surface, context, - location == WINED3D_LOCATION_TEXTURE_SRGB))) -+#if defined(STAGING_CSMT) - return; -+#else /* STAGING_CSMT */ -+ return hr; -+#endif /* STAGING_CSMT */ - break; + TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc); - default: -@@ -3976,12 +5096,21 @@ - break; - } +@@ -1475,12 +1598,14 @@ -+#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&surface->resource, location); + surface = surface_from_resource(sub_resource); - if (location != WINED3D_LOCATION_SYSMEM && (surface->resource.locations & WINED3D_LOCATION_SYSMEM)) - surface_evict_sysmem(surface); ++#if defined(STAGING_CSMT) + if (!(surface->container->resource.format_flags & WINED3DFMT_FLAG_GETDC)) + { + WARN("Cannot use GetDC on a %s surface.\n", debug_d3dformat(surface->resource.format->id)); + return WINED3DERR_INVALIDCALL; + } - return; -+#else /* STAGING_CSMT */ -+ surface_validate_location(surface, location); -+ -+ if (location != WINED3D_LOCATION_SYSMEM && (surface->locations & WINED3D_LOCATION_SYSMEM)) -+ surface_evict_sysmem(surface); -+ -+ return WINED3D_OK; +#endif /* STAGING_CSMT */ - } + /* Give more detailed info for ddraw. */ + if (surface->flags & SFLAG_DCINUSE) + return WINEDDERR_DCALREADYCREATED; +@@ -1489,6 +1614,7 @@ + if (surface->resource.map_count) + return WINED3DERR_INVALIDCALL; - static HRESULT ffp_blit_alloc(struct wined3d_device *device) { return WINED3D_OK; } -@@ -4090,6 +5219,7 @@ - const RECT *dst_rect, const struct wined3d_color *color) - { - const RECT draw_rect = {0, 0, dst_surface->resource.width, dst_surface->resource.height}; +#if defined(STAGING_CSMT) - struct wined3d_rendertarget_view view, *view_ptr = &view; - struct wined3d_fb_state fb = {&view_ptr, NULL, 1}; - struct wined3d_texture *texture = dst_surface->container; -@@ -4110,6 +5240,21 @@ - view.sub_resource_idx = dst_surface->texture_layer * texture->level_count + dst_surface->texture_level; - - device_clear_render_targets(device, 1, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0); + surface->flags |= SFLAG_DCINUSE; + surface->resource.map_count++; + wined3d_cs_emit_getdc(device->cs, surface); +@@ -1501,6 +1627,45 @@ + HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc) + { + struct wined3d_device *device = texture->resource.device; +#else /* STAGING_CSMT */ -+ struct wined3d_rendertarget_view *view; -+ struct wined3d_fb_state fb = {&view, NULL}; -+ HRESULT hr; ++ if (device->d3d_initialized) ++ context = context_acquire(device, NULL); + -+ if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(dst_surface, -+ NULL, &wined3d_null_parent_ops, &view))) ++ /* Create a DIB section if there isn't a dc yet. */ ++ if (!surface->hDC) + { -+ ERR("Failed to create rendertarget view, hr %#x.\n", hr); -+ return hr; ++ if (FAILED(hr = surface_create_dib_section(surface))) ++ { ++ if (context) ++ context_release(context); ++ return WINED3DERR_INVALIDCALL; ++ } ++ if (!(surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY ++ || surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM ++ || surface->pbo)) ++ surface->resource.map_binding = WINED3D_LOCATION_DIB; + } + -+ device_clear_render_targets(device, 1, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0); -+ wined3d_rendertarget_view_decref(view); ++ surface_load_location(surface, context, WINED3D_LOCATION_DIB); ++ surface_invalidate_location(surface, ~WINED3D_LOCATION_DIB); ++ ++ if (context) ++ context_release(context); ++ ++ surface->flags |= SFLAG_DCINUSE; ++ surface->resource.map_count++; ++ ++ *dc = surface->hDC; ++ TRACE("Returning dc %p.\n", *dc); ++ ++ return WINED3D_OK; ++} ++ ++HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc) ++{ ++ struct wined3d_device *device = texture->resource.device; ++ struct wined3d_context *context = NULL; +#endif /* STAGING_CSMT */ + struct wined3d_resource *sub_resource; + struct wined3d_surface *surface; - return WINED3D_OK; - } -@@ -4118,6 +5263,7 @@ - const RECT *dst_rect, float depth) - { - const RECT draw_rect = {0, 0, dst_surface->resource.width, dst_surface->resource.height}; -+#if defined(STAGING_CSMT) - struct wined3d_rendertarget_view view; - struct wined3d_fb_state fb = {NULL, &view}; - struct wined3d_texture *texture = dst_surface->container; -@@ -4133,6 +5279,20 @@ - view.sub_resource_idx = dst_surface->texture_layer * texture->level_count + dst_surface->texture_level; +@@ -1530,7 +1695,30 @@ + surface->resource.map_count--; + surface->flags &= ~SFLAG_DCINUSE; - device_clear_render_targets(device, 0, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_ZBUFFER, 0, depth, 0); ++#if defined(STAGING_CSMT) + wined3d_cs_emit_releasedc(device->cs, surface); +#else /* STAGING_CSMT */ -+ struct wined3d_fb_state fb = {NULL, NULL}; -+ HRESULT hr; -+ -+ if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(dst_surface, -+ NULL, &wined3d_null_parent_ops, &fb.depth_stencil))) ++ if (surface->resource.map_binding == WINED3D_LOCATION_USER_MEMORY ++ || (surface->container->flags & WINED3D_TEXTURE_PIN_SYSMEM ++ && surface->resource.map_binding != WINED3D_LOCATION_DIB)) + { -+ ERR("Failed to create rendertarget view, hr %#x.\n", hr); -+ return hr; -+ } ++ /* The game Salammbo modifies the surface contents without mapping the surface between ++ * a GetDC/ReleaseDC operation and flipping the surface. If the DIB remains the active ++ * copy and is copied to the screen, this update, which draws the mouse pointer, is lost. ++ * Do not only copy the DIB to the map location, but also make sure the map location is ++ * copied back to the DIB in the next getdc call. ++ * ++ * The same consideration applies to user memory surfaces. */ + -+ device_clear_render_targets(device, 0, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_ZBUFFER, 0, depth, 0); -+ wined3d_rendertarget_view_decref(fb.depth_stencil); ++ if (device->d3d_initialized) ++ context = context_acquire(device, NULL); ++ ++ surface_load_location(surface, context, surface->resource.map_binding); ++ surface_invalidate_location(surface, WINED3D_LOCATION_DIB); ++ if (context) ++ context_release(context); ++ } +#endif /* STAGING_CSMT */ return WINED3D_OK; } -@@ -4169,8 +5329,13 @@ - wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, - (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_blt_key : NULL); - +diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c +--- a/dlls/wined3d/utils.c ++++ b/dlls/wined3d/utils.c +@@ -3824,7 +3824,11 @@ + float y_offset = context->render_offscreen + ? (center_offset - (2.0f * y) - h) / h + : (center_offset - (2.0f * y) - h) / -h; +#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&dst_surface->resource, dst_surface->container->resource.draw_binding); - wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->container->resource.draw_binding); + enum wined3d_depth_buffer_type zenable = state->fb.depth_stencil ? +#else /* STAGING_CSMT */ -+ surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); -+ surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); ++ enum wined3d_depth_buffer_type zenable = state->fb->depth_stencil ? +#endif /* STAGING_CSMT */ - } - - const struct blit_shader ffp_blit = { -@@ -4326,6 +5491,7 @@ - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) - { + state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE; + float z_scale = zenable ? 2.0f : 0.0f; + float z_offset = zenable ? -1.0f : 0.0f; +@@ -3947,6 +3951,7 @@ + /* case WINED3D_TTFF_COUNT1: Won't ever get here. */ + case WINED3D_TTFF_COUNT2: + mat._13 = mat._23 = mat._33 = mat._43 = 0.0f; +#if defined(STAGING_CSMT) - int bpp, srcheight, srcwidth, dstheight, dstwidth, width; - const struct wined3d_format *src_format, *dst_format; - unsigned int src_fmt_flags, dst_fmt_flags; -@@ -4360,6 +5526,28 @@ - wined3d_resource_get_pitch(&dst_surface->resource, &dst_row_pitch, &dst_slice_pitch); - src_data = dst_data; - src_row_pitch = dst_row_pitch; + /* OpenGL divides the first 3 vertex coord by the 4th by default, + * which is essentially the same as D3DTTFF_PROJECTED. Make sure that + * the 4th coord evaluates to 1.0 to eliminate that. +@@ -3959,6 +3964,20 @@ + * A more serious problem occurs if the app passes 4 coordinates in, and the + * 4th is != 1.0(opengl default). This would have to be fixed in draw_strided_slow + * or a replacement shader. */ +#else /* STAGING_CSMT */ -+ const struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1}; -+ int bpp, srcheight, srcwidth, dstheight, dstwidth, width; -+ const struct wined3d_format *src_format, *dst_format; -+ unsigned int src_fmt_flags, dst_fmt_flags; -+ struct wined3d_texture *src_texture = NULL; -+ struct wined3d_map_desc dst_map, src_map; -+ const BYTE *sbase = NULL; -+ HRESULT hr = WINED3D_OK; -+ const BYTE *sbuf; -+ BYTE *dbuf; -+ int x, y; -+ -+ TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n", -+ dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), -+ flags, fx, debug_d3dtexturefiltertype(filter)); -+ -+ if (src_surface == dst_surface) -+ { -+ wined3d_surface_map(dst_surface, &dst_map, NULL, 0); -+ src_map = dst_map; -+#endif /* STAGING_CSMT */ - src_format = dst_surface->resource.format; - dst_format = src_format; - dst_fmt_flags = dst_surface->container->resource.format_flags; -@@ -4371,12 +5559,14 @@ - dst_fmt_flags = dst_surface->container->resource.format_flags; - if (src_surface) - { -+#if defined(STAGING_CSMT) - if (!wined3d_resource_prepare_map_memory(&src_surface->resource, context)) - { - hr = E_OUTOFMEMORY; - goto error; - } - ++ /* OpenGL divides the first 3 vertex coord by the 4th by default, ++ * which is essentially the same as D3DTTFF_PROJECTED. Make sure that ++ * the 4th coord evaluates to 1.0 to eliminate that. ++ * ++ * If the fixed function pipeline is used, the 4th value remains unused, ++ * so there is no danger in doing this. With vertex shaders we have a ++ * problem. Should an app hit that problem, the code here would have to ++ * check for pixel shaders, and the shader has to undo the default gl divide. ++ * ++ * A more serious problem occurs if the app passes 4 coordinates in, and the ++ * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow ++ * or a replacement shader. */ +#endif /* STAGING_CSMT */ - if (dst_surface->resource.format->id != src_surface->resource.format->id) - { - if (!(src_texture = surface_convert_format(src_surface, dst_format->id))) -@@ -4387,9 +5577,13 @@ - } - src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, 0)); + default: + mat._14 = mat._24 = mat._34 = 0.0f; mat._44 = 1.0f; } +@@ -4405,7 +4424,11 @@ + unsigned int i; + DWORD ttff; + DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; +#if defined(STAGING_CSMT) - wined3d_resource_load_location(&src_surface->resource, context, src_surface->resource.map_binding); - wined3d_resource_get_pitch(&src_surface->resource, &src_row_pitch, &src_slice_pitch); - src_data = wined3d_resource_get_map_ptr(&src_surface->resource, context, 0); + unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; +#else /* STAGING_CSMT */ -+ wined3d_surface_map(src_surface, &src_map, NULL, WINED3D_MAP_READONLY); ++ unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; ++#endif /* STAGING_CSMT */ + const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_d3d_info *d3d_info = context->d3d_info; + +diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c +--- a/dlls/wined3d/vertexdeclaration.c ++++ b/dlls/wined3d/vertexdeclaration.c +@@ -50,12 +50,14 @@ + return refcount; + } + ++#if defined(STAGING_CSMT) + void wined3d_vertex_declaration_destroy(struct wined3d_vertex_declaration *declaration) + { + HeapFree(GetProcessHeap(), 0, declaration->elements); + HeapFree(GetProcessHeap(), 0, declaration); + } + +#endif /* STAGING_CSMT */ - src_format = src_surface->resource.format; - src_fmt_flags = src_surface->container->resource.format_flags; - } -@@ -4399,8 +5593,12 @@ - src_fmt_flags = dst_fmt_flags; - } + ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration *declaration) + { + ULONG refcount = InterlockedDecrement(&declaration->ref); +@@ -64,9 +66,15 @@ + if (!refcount) + { +#if defined(STAGING_CSMT) - wined3d_resource_get_pitch(&dst_surface->resource, &dst_row_pitch, &dst_slice_pitch); - dst_data = wined3d_resource_get_map_ptr(&dst_surface->resource, context, 0); + const struct wined3d_device *device = declaration->device; + declaration->parent_ops->wined3d_object_destroyed(declaration->parent); + wined3d_cs_emit_vertex_declaration_destroy(device->cs, declaration); +#else /* STAGING_CSMT */ -+ wined3d_surface_map(dst_surface, &dst_map, &dst_box, 0); ++ HeapFree(GetProcessHeap(), 0, declaration->elements); ++ declaration->parent_ops->wined3d_object_destroyed(declaration->parent); ++ HeapFree(GetProcessHeap(), 0, declaration); +#endif /* STAGING_CSMT */ } - bpp = dst_surface->resource.format->byte_count; -@@ -4411,12 +5609,24 @@ - width = (dst_rect->right - dst_rect->left) * bpp; + return refcount; +diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c +--- a/dlls/wined3d/view.c ++++ b/dlls/wined3d/view.c +@@ -33,11 +33,13 @@ + return refcount; + } - if (src_surface) +#if defined(STAGING_CSMT) - sbase = (BYTE *)src_data - + ((src_rect->top / src_format->block_height) * src_row_pitch) - + ((src_rect->left / src_format->block_width) * src_format->block_byte_count); - dbuf = (BYTE *)dst_data - + ((dst_rect->top / dst_format->block_height) * dst_row_pitch) - + ((dst_rect->left / dst_format->block_width) * dst_format->block_byte_count); -+#else /* STAGING_CSMT */ -+ sbase = (BYTE *)src_map.data -+ + ((src_rect->top / src_format->block_height) * src_map.row_pitch) -+ + ((src_rect->left / src_format->block_width) * src_format->block_byte_count); -+ if (src_surface != dst_surface) -+ dbuf = dst_map.data; -+ else -+ dbuf = (BYTE *)dst_map.data -+ + ((dst_rect->top / dst_format->block_height) * dst_map.row_pitch) -+ + ((dst_rect->left / dst_format->block_width) * dst_format->block_byte_count); + void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) + { + HeapFree(GetProcessHeap(), 0, view); + } + +#endif /* STAGING_CSMT */ + ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view) + { + ULONG refcount = InterlockedDecrement(&view->refcount); +@@ -46,6 +48,7 @@ - if (src_fmt_flags & dst_fmt_flags & WINED3DFMT_FLAG_BLOCKS) + if (!refcount) { -@@ -4451,7 +5661,11 @@ - } - - hr = surface_cpu_blt_compressed(sbase, dbuf, +#if defined(STAGING_CSMT) - src_row_pitch, dst_row_pitch, dstwidth, dstheight, + struct wined3d_device *device = view->resource->device; + + /* Call wined3d_object_destroyed() before releasing the resource, +@@ -53,6 +56,13 @@ + view->parent_ops->wined3d_object_destroyed(view->parent); + wined3d_resource_decref(view->resource); + wined3d_cs_emit_view_destroy(device->cs, view); +#else /* STAGING_CSMT */ -+ src_map.row_pitch, dst_map.row_pitch, dstwidth, dstheight, ++ /* Call wined3d_object_destroyed() before releasing the resource, ++ * since releasing the resource may end up destroying the parent. */ ++ view->parent_ops->wined3d_object_destroyed(view->parent); ++ wined3d_resource_decref(view->resource); ++ HeapFree(GetProcessHeap(), 0, view); +#endif /* STAGING_CSMT */ - src_format, flags, fx); - goto release; } -@@ -4459,7 +5673,11 @@ - /* First, all the 'source-less' blits */ - if (flags & WINEDDBLT_COLORFILL) - { + + return refcount; +diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c +--- a/dlls/wined3d/volume.c ++++ b/dlls/wined3d/volume.c +@@ -40,6 +40,32 @@ + return TRUE; + } + ++#if !defined(STAGING_CSMT) ++void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch) ++{ ++ const struct wined3d_format *format = volume->resource.format; ++ ++ if (volume->container->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) ++ { ++ /* Since compressed formats are block based, pitch means the amount of ++ * bytes to the next row of block rather than the next row of pixels. */ ++ UINT row_block_count = (volume->resource.width + format->block_width - 1) / format->block_width; ++ UINT slice_block_count = (volume->resource.height + format->block_height - 1) / format->block_height; ++ *row_pitch = row_block_count * format->block_byte_count; ++ *slice_pitch = *row_pitch * slice_block_count; ++ } ++ else ++ { ++ unsigned char alignment = volume->resource.device->surface_alignment; ++ *row_pitch = format->byte_count * volume->resource.width; /* Bytes / row */ ++ *row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1); ++ *slice_pitch = *row_pitch * volume->resource.height; ++ } ++ ++ TRACE("Returning row pitch %u, slice pitch %u.\n", *row_pitch, *slice_pitch); ++} ++ ++#endif /* STAGING_CSMT */ + /* This call just uploads data, the caller is responsible for binding the + * correct texture. */ + /* Context activation is done by the caller. */ +@@ -71,7 +97,11 @@ + dst_row_pitch = width * format->conv_byte_count; + dst_slice_pitch = dst_row_pitch * height; + +#if defined(STAGING_CSMT) - hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_row_pitch, fx->u5.dwFillColor); + wined3d_resource_get_pitch(&volume->resource, &src_row_pitch, &src_slice_pitch); +#else /* STAGING_CSMT */ -+ hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_map.row_pitch, fx->u5.dwFillColor); ++ wined3d_volume_get_pitch(volume, &src_row_pitch, &src_slice_pitch); +#endif /* STAGING_CSMT */ - flags &= ~WINEDDBLT_COLORFILL; - } -@@ -4509,6 +5727,7 @@ - for (y = 0; y < dstheight; ++y) - { - memcpy(dbuf, sbuf, width); + converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth); + format->convert(data->addr, converted_mem, src_row_pitch, src_slice_pitch, +@@ -99,6 +129,22 @@ + HeapFree(GetProcessHeap(), 0, converted_mem); + } + ++#if !defined(STAGING_CSMT) ++void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) ++{ ++ TRACE("Volume %p, setting %s.\n", volume, wined3d_debug_location(location)); ++ volume->locations |= location; ++ TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations)); ++} ++ ++void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) ++{ ++ TRACE("Volume %p, clearing %s.\n", volume, wined3d_debug_location(location)); ++ volume->locations &= ~location; ++ TRACE("new location flags are %s.\n", wined3d_debug_location(volume->locations)); ++} ++ ++#endif /* STAGING_CSMT */ + /* Context activation is done by the caller. */ + static void wined3d_volume_download_data(struct wined3d_volume *volume, + const struct wined3d_context *context, const struct wined3d_bo_address *data) +@@ -134,8 +180,33 @@ + static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume) + { + wined3d_resource_free_sysmem(&volume->resource); +#if defined(STAGING_CSMT) - sbuf += src_row_pitch; - dbuf += dst_row_pitch; - } -@@ -4522,6 +5741,21 @@ - { - sbuf -= src_row_pitch; - dbuf -= dst_row_pitch; + volume->resource.map_heap_memory = NULL; + wined3d_resource_invalidate_location(&volume->resource, WINED3D_LOCATION_SYSMEM); +#else /* STAGING_CSMT */ -+ sbuf += src_map.row_pitch; -+ dbuf += dst_map.row_pitch; -+ } -+ } -+ else if (dst_rect->top > src_rect->top) -+ { -+ /* Copy from bottom upwards. */ -+ sbuf += src_map.row_pitch * dstheight; -+ dbuf += dst_map.row_pitch * dstheight; -+ for (y = 0; y < dstheight; ++y) -+ { -+ sbuf -= src_map.row_pitch; -+ dbuf -= dst_map.row_pitch; ++ wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_SYSMEM); ++} ++ ++static DWORD volume_access_from_location(DWORD location) ++{ ++ switch (location) ++ { ++ case WINED3D_LOCATION_DISCARDED: ++ return 0; ++ ++ case WINED3D_LOCATION_SYSMEM: ++ return WINED3D_RESOURCE_ACCESS_CPU; ++ ++ case WINED3D_LOCATION_BUFFER: ++ case WINED3D_LOCATION_TEXTURE_RGB: ++ case WINED3D_LOCATION_TEXTURE_SRGB: ++ return WINED3D_RESOURCE_ACCESS_GPU; ++ ++ default: ++ FIXME("Unhandled location %#x.\n", location); ++ return 0; ++ } +#endif /* STAGING_CSMT */ - memcpy(dbuf, sbuf, width); - } - } -@@ -4531,8 +5765,13 @@ - for (y = 0; y < dstheight; ++y) - { - memmove(dbuf, sbuf, width); + } + + /* Context activation is done by the caller. */ +@@ -175,6 +246,7 @@ + + return TRUE; + } +#if defined(STAGING_CSMT) - sbuf += src_row_pitch; - dbuf += dst_row_pitch; + + /* Context activation is done by the caller. */ + static void wined3d_volume_load_location(struct wined3d_resource *resource, +@@ -185,6 +257,22 @@ + + TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location), + wined3d_debug_location(volume->resource.locations)); +#else /* STAGING_CSMT */ -+ sbuf += src_map.row_pitch; -+ dbuf += dst_map.row_pitch; ++/* Context activation is done by the caller. */ ++static void wined3d_volume_load_location(struct wined3d_volume *volume, ++ struct wined3d_context *context, DWORD location) ++{ ++ DWORD required_access = volume_access_from_location(location); ++ ++ TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location), ++ wined3d_debug_location(volume->locations)); ++ ++ if ((volume->locations & location) == location) ++ { ++ TRACE("Location(s) already up to date.\n"); ++ return; ++ } +#endif /* STAGING_CSMT */ - } - } - } -@@ -4541,9 +5780,15 @@ - /* Stretching in y direction only. */ - for (y = sy = 0; y < dstheight; ++y, sy += yinc) - { + + if ((volume->resource.access_flags & required_access) != required_access) + { +@@ -203,6 +291,7 @@ + && !(volume->container->flags & WINED3D_TEXTURE_SRGB_ALLOCATED))) + ERR("Trying to load (s)RGB texture without prior allocation.\n"); + +#if defined(STAGING_CSMT) - sbuf = sbase + (sy >> 16) * src_row_pitch; - memcpy(dbuf, sbuf, width); - dbuf += dst_row_pitch; + if (volume->resource.locations & WINED3D_LOCATION_DISCARDED) + { + TRACE("Volume previously discarded, nothing to do.\n"); +@@ -236,6 +325,41 @@ + return; + } + wined3d_resource_validate_location(&volume->resource, location); +#else /* STAGING_CSMT */ -+ sbuf = sbase + (sy >> 16) * src_map.row_pitch; -+ memcpy(dbuf, sbuf, width); -+ dbuf += dst_map.row_pitch; ++ if (volume->locations & WINED3D_LOCATION_DISCARDED) ++ { ++ TRACE("Volume previously discarded, nothing to do.\n"); ++ wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); ++ } ++ else if (volume->locations & WINED3D_LOCATION_SYSMEM) ++ { ++ struct wined3d_const_bo_address data = {0, volume->resource.heap_memory}; ++ wined3d_texture_bind_and_dirtify(volume->container, context, ++ location == WINED3D_LOCATION_TEXTURE_SRGB); ++ wined3d_volume_upload_data(volume, context, &data); ++ } ++ else if (volume->locations & WINED3D_LOCATION_BUFFER) ++ { ++ struct wined3d_const_bo_address data = {volume->pbo, NULL}; ++ wined3d_texture_bind_and_dirtify(volume->container, context, ++ location == WINED3D_LOCATION_TEXTURE_SRGB); ++ wined3d_volume_upload_data(volume, context, &data); ++ } ++ else if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) ++ { ++ wined3d_volume_srgb_transfer(volume, context, TRUE); ++ } ++ else if (volume->locations & WINED3D_LOCATION_TEXTURE_SRGB) ++ { ++ wined3d_volume_srgb_transfer(volume, context, FALSE); ++ } ++ else ++ { ++ FIXME("Implement texture loading from %s.\n", wined3d_debug_location(volume->locations)); ++ return; ++ } ++ wined3d_volume_validate_location(volume, location); +#endif /* STAGING_CSMT */ - } - } - } -@@ -4553,6 +5798,7 @@ - int last_sy = -1; - for (y = sy = 0; y < dstheight; ++y, sy += yinc) - { + + if (wined3d_volume_can_evict(volume)) + wined3d_volume_evict_sysmem(volume); +@@ -246,11 +370,24 @@ + if (!volume->resource.heap_memory) + ERR("Trying to load WINED3D_LOCATION_SYSMEM without setting it up first.\n"); + +#if defined(STAGING_CSMT) - sbuf = sbase + (sy >> 16) * src_row_pitch; + if (volume->resource.locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { + struct wined3d_bo_address data = {0, volume->resource.heap_memory}; - if ((sy >> 16) == (last_sy >> 16)) -@@ -4560,6 +5806,15 @@ - /* This source row is the same as last source row - - * Copy the already stretched row. */ - memcpy(dbuf, dbuf - dst_row_pitch, width); + if (volume->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) +#else /* STAGING_CSMT */ -+ sbuf = sbase + (sy >> 16) * src_map.row_pitch; ++ if (volume->locations & WINED3D_LOCATION_DISCARDED) ++ { ++ TRACE("Volume previously discarded, nothing to do.\n"); ++ wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); ++ } ++ else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) ++ { ++ struct wined3d_bo_address data = {0, volume->resource.heap_memory}; + -+ if ((sy >> 16) == (last_sy >> 16)) -+ { -+ /* This source row is the same as last source row - -+ * Copy the already stretched row. */ -+ memcpy(dbuf, dbuf - dst_map.row_pitch, width); ++ if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) +#endif /* STAGING_CSMT */ - } - else - { -@@ -4606,6 +5861,7 @@ - } - #undef STRETCH_ROW - } + wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); + else + wined3d_texture_bind_and_dirtify(volume->container, context, TRUE); +@@ -261,6 +398,7 @@ + else + { + FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", +#if defined(STAGING_CSMT) - dbuf += dst_row_pitch; - last_sy = sy; - } -@@ -4614,6 +5870,16 @@ - else - { - LONG dstyinc = dst_row_pitch, dstxinc = bpp; + wined3d_debug_location(volume->resource.locations)); + return; + } +@@ -276,6 +414,28 @@ + struct wined3d_bo_address data = {volume->resource.buffer->name, NULL}; + + if (volume->resource.locations & WINED3D_LOCATION_TEXTURE_RGB) +#else /* STAGING_CSMT */ -+ dbuf += dst_map.row_pitch; -+ last_sy = sy; -+ } ++ wined3d_debug_location(volume->locations)); ++ return; + } -+ } -+ else -+ { -+ LONG dstyinc = dst_map.row_pitch, dstxinc = bpp; ++ wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM); ++ break; ++ ++ case WINED3D_LOCATION_BUFFER: ++ if (!volume->pbo) ++ ERR("Trying to load WINED3D_LOCATION_BUFFER without setting it up first.\n"); ++ ++ if (volume->locations & WINED3D_LOCATION_DISCARDED) ++ { ++ TRACE("Volume previously discarded, nothing to do.\n"); ++ wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); ++ } ++ else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) ++ { ++ struct wined3d_bo_address data = {volume->pbo, NULL}; ++ ++ if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) +#endif /* STAGING_CSMT */ - DWORD keylow = 0xffffffff, keyhigh = 0, keymask = 0xffffffff; - DWORD destkeylow = 0x0, destkeyhigh = 0xffffffff, destkeymask = 0xffffffff; - if (flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYDEST | WINEDDBLT_KEYSRCOVERRIDE | WINEDDBLT_KEYDESTOVERRIDE)) -@@ -4663,7 +5929,11 @@ - LONG tmpxy; - dTopLeft = dbuf; - dTopRight = dbuf + ((dstwidth - 1) * bpp); + wined3d_texture_bind_and_dirtify(volume->container, context, FALSE); + else + wined3d_texture_bind_and_dirtify(volume->container, context, TRUE); +@@ -285,6 +445,7 @@ + else + { + FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", +#if defined(STAGING_CSMT) - dBottomLeft = dTopLeft + ((dstheight - 1) * dst_row_pitch); -+#else /* STAGING_CSMT */ -+ dBottomLeft = dTopLeft + ((dstheight - 1) * dst_map.row_pitch); -+#endif /* STAGING_CSMT */ - dBottomRight = dBottomLeft + ((dstwidth - 1) * bpp); - - if (fx->dwDDFX & WINEDDBLTFX_ARITHSTRETCHY) -@@ -4740,6 +6010,7 @@ - flags &= ~(WINEDDBLT_DDFX); + wined3d_debug_location(volume->resource.locations)); + return; } - -+#if defined(STAGING_CSMT) - #define COPY_COLORKEY_FX(type) \ - do { \ - const type *s; \ -@@ -4761,6 +6032,29 @@ - d = (type *)(((BYTE *)d) + dstyinc); \ - } \ - } while(0) +@@ -294,6 +455,17 @@ + default: + FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), + wined3d_debug_location(volume->resource.locations)); +#else /* STAGING_CSMT */ -+#define COPY_COLORKEY_FX(type) \ -+do { \ -+ const type *s; \ -+ type *d = (type *)dbuf, *dx, tmp; \ -+ for (y = sy = 0; y < dstheight; ++y, sy += yinc) \ -+ { \ -+ s = (const type *)(sbase + (sy >> 16) * src_map.row_pitch); \ -+ dx = d; \ -+ for (x = sx = 0; x < dstwidth; ++x, sx += xinc) \ -+ { \ -+ tmp = s[sx >> 16]; \ -+ if (((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) \ -+ && ((dx[0] & destkeymask) >= destkeylow && (dx[0] & destkeymask) <= destkeyhigh)) \ -+ { \ -+ dx[0] = tmp; \ -+ } \ -+ dx = (type *)(((BYTE *)dx) + dstxinc); \ -+ } \ -+ d = (type *)(((BYTE *)d) + dstyinc); \ -+ } \ -+} while(0) ++ wined3d_debug_location(volume->locations)); ++ return; ++ } ++ wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER); ++ break; ++ ++ default: ++ FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), ++ wined3d_debug_location(volume->locations)); +#endif /* STAGING_CSMT */ + } + } - switch (bpp) - { -@@ -4779,7 +6073,11 @@ - BYTE *d = dbuf, *dx; - for (y = sy = 0; y < dstheight; ++y, sy += yinc) - { +@@ -301,6 +473,7 @@ + void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) + { + wined3d_texture_prepare_texture(volume->container, context, srgb_mode); +#if defined(STAGING_CSMT) - sbuf = sbase + (sy >> 16) * src_row_pitch; + wined3d_resource_load_location(&volume->resource, context, + srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB); + } +@@ -313,6 +486,51 @@ + resource_cleanup(&volume->resource); + volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent); + wined3d_cs_emit_volume_cleanup(device->cs, volume); +#else /* STAGING_CSMT */ -+ sbuf = sbase + (sy >> 16) * src_map.row_pitch; ++ wined3d_volume_load_location(volume, context, ++ srgb_mode ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB); ++} ++ ++/* Context activation is done by the caller. */ ++static void wined3d_volume_prepare_pbo(struct wined3d_volume *volume, struct wined3d_context *context) ++{ ++ const struct wined3d_gl_info *gl_info = context->gl_info; ++ ++ if (volume->pbo) ++ return; ++ ++ GL_EXTCALL(glGenBuffers(1, &volume->pbo)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo)); ++ GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, volume->resource.size, NULL, GL_STREAM_DRAW)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); ++ checkGLcall("Create PBO"); ++ ++ TRACE("Created PBO %u for volume %p.\n", volume->pbo, volume); ++} ++ ++static void wined3d_volume_free_pbo(struct wined3d_volume *volume) ++{ ++ struct wined3d_context *context = context_acquire(volume->resource.device, NULL); ++ const struct wined3d_gl_info *gl_info = context->gl_info; ++ ++ TRACE("Deleting PBO %u belonging to volume %p.\n", volume->pbo, volume); ++ GL_EXTCALL(glDeleteBuffers(1, &volume->pbo)); ++ checkGLcall("glDeleteBuffers"); ++ volume->pbo = 0; ++ context_release(context); ++} ++ ++void wined3d_volume_destroy(struct wined3d_volume *volume) ++{ ++ TRACE("volume %p.\n", volume); ++ ++ if (volume->pbo) ++ wined3d_volume_free_pbo(volume); ++ ++ resource_cleanup(&volume->resource); ++ volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent); ++ HeapFree(GetProcessHeap(), 0, volume); +#endif /* STAGING_CSMT */ - dx = d; - for (x = sx = 0; x < dstwidth; ++x, sx+= xinc) - { -@@ -4810,10 +6108,12 @@ - } - } + } -+#if defined(STAGING_CSMT) - wined3d_resource_invalidate_location(&dst_surface->resource, ~dst_surface->resource.map_binding); - if (dst_surface->container) - wined3d_texture_set_dirty(dst_surface->container); + static void volume_unload(struct wined3d_resource *resource) +@@ -326,6 +544,7 @@ -+#endif /* STAGING_CSMT */ - error: - if (flags && FIXME_ON(d3d_surface)) - { -@@ -4821,6 +6121,7 @@ - } + TRACE("texture %p.\n", resource); - release: +#if defined(STAGING_CSMT) - if (dst_data) + if (wined3d_resource_prepare_system_memory(&volume->resource)) { - wined3d_resource_release_map_ptr(&dst_surface->resource, context); -@@ -4839,6 +6140,14 @@ - wined3d_texture_decref(src_texture); - if (context) - context_release(context); + context = context_acquire(device, NULL); +@@ -338,6 +557,29 @@ + ERR("Out of memory when unloading volume %p.\n", volume); + wined3d_resource_validate_location(&volume->resource, WINED3D_LOCATION_DISCARDED); + wined3d_resource_invalidate_location(&volume->resource, ~WINED3D_LOCATION_DISCARDED); +#else /* STAGING_CSMT */ -+ wined3d_surface_unmap(dst_surface); -+ if (src_surface && src_surface != dst_surface) -+ wined3d_surface_unmap(src_surface); -+ /* Release the converted surface, if any. */ -+ if (src_texture) -+ wined3d_texture_decref(src_texture); ++ if (volume_prepare_system_memory(volume)) ++ { ++ context = context_acquire(device, NULL); ++ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM); ++ context_release(context); ++ wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_SYSMEM); ++ } ++ else ++ { ++ ERR("Out of memory when unloading volume %p.\n", volume); ++ wined3d_volume_validate_location(volume, WINED3D_LOCATION_DISCARDED); ++ wined3d_volume_invalidate_location(volume, ~WINED3D_LOCATION_DISCARDED); ++ } ++ ++ if (volume->pbo) ++ { ++ /* Should not happen because only dynamic default pool volumes ++ * have a buffer, and those are not evicted by device_evit_managed_resources ++ * and must be freed before a non-ex device reset. */ ++ ERR("Unloading a volume with a buffer\n"); ++ wined3d_volume_free_pbo(volume); +#endif /* STAGING_CSMT */ + } - return hr; + /* The texture name is managed by the container. */ +@@ -345,6 +587,36 @@ + resource_unload(resource); } -@@ -4883,6 +6192,7 @@ - cpu_blit_blit_surface, - }; -+#if defined(STAGING_CSMT) - void surface_blt_ugly(struct wined3d_surface *dst_surface, const RECT *dst_rect, - struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, - const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) -@@ -4890,6 +6200,16 @@ - struct wined3d_swapchain *src_swapchain, *dst_swapchain; - struct wined3d_device *device = dst_surface->resource.device; - DWORD src_ds_flags, dst_ds_flags; -+#else /* STAGING_CSMT */ -+HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect_in, -+ struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags, -+ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) ++#if !defined(STAGING_CSMT) ++static BOOL volume_check_block_align(const struct wined3d_volume *volume, ++ const struct wined3d_box *box) +{ -+ struct wined3d_swapchain *src_swapchain, *dst_swapchain; -+ struct wined3d_device *device = dst_surface->resource.device; -+ DWORD src_ds_flags, dst_ds_flags; -+ RECT src_rect, dst_rect; ++ UINT width_mask, height_mask; ++ const struct wined3d_format *format = volume->resource.format; ++ ++ if (!box) ++ return TRUE; ++ ++ /* This assumes power of two block sizes, but NPOT block sizes would be ++ * silly anyway. ++ * ++ * This also assumes that the format's block depth is 1. */ ++ width_mask = format->block_width - 1; ++ height_mask = format->block_height - 1; ++ ++ if (box->left & width_mask) ++ return FALSE; ++ if (box->top & height_mask) ++ return FALSE; ++ if (box->right & width_mask && box->right != volume->resource.width) ++ return FALSE; ++ if (box->bottom & height_mask && box->bottom != volume->resource.height) ++ return FALSE; ++ ++ return TRUE; ++} ++ +#endif /* STAGING_CSMT */ - BOOL scale, convert; - - static const DWORD simple_blit = WINEDDBLT_ASYNC -@@ -4901,6 +6221,106 @@ - | WINEDDBLT_DONOTWAIT - | WINEDDBLT_ALPHATEST; - -+#if !defined(STAGING_CSMT) -+ TRACE("dst_surface %p, dst_rect_in %s, src_surface %p, src_rect_in %s, flags %#x, fx %p, filter %s.\n", -+ dst_surface, wine_dbgstr_rect(dst_rect_in), src_surface, wine_dbgstr_rect(src_rect_in), -+ flags, fx, debug_d3dtexturefiltertype(filter)); -+ TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage)); + static BOOL wined3d_volume_check_box_dimensions(const struct wined3d_volume *volume, + const struct wined3d_box *box) + { +@@ -370,6 +642,7 @@ + HRESULT wined3d_volume_map(struct wined3d_volume *volume, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) + { ++#if defined(STAGING_CSMT) + HRESULT hr; + const struct wined3d_format *format = volume->resource.format; + const unsigned int fmt_flags = volume->container->resource.format_flags; +@@ -410,6 +683,173 @@ + if (hr == WINEDDERR_NOTLOCKED) + return WINED3DERR_INVALIDCALL; + return hr; ++#else /* STAGING_CSMT */ ++ struct wined3d_device *device = volume->resource.device; ++ struct wined3d_context *context; ++ const struct wined3d_gl_info *gl_info; ++ BYTE *base_memory; ++ const struct wined3d_format *format = volume->resource.format; ++ const unsigned int fmt_flags = volume->container->resource.format_flags; + -+ if (fx) ++ TRACE("volume %p, map_desc %p, box %s, flags %#x.\n", ++ volume, map_desc, debug_box(box), flags); ++ ++ map_desc->data = NULL; ++ if (!(volume->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU)) + { -+ TRACE("dwSize %#x.\n", fx->dwSize); -+ TRACE("dwDDFX %#x.\n", fx->dwDDFX); -+ TRACE("dwROP %#x.\n", fx->dwROP); -+ TRACE("dwDDROP %#x.\n", fx->dwDDROP); -+ TRACE("dwRotationAngle %#x.\n", fx->dwRotationAngle); -+ TRACE("dwZBufferOpCode %#x.\n", fx->dwZBufferOpCode); -+ TRACE("dwZBufferLow %#x.\n", fx->dwZBufferLow); -+ TRACE("dwZBufferHigh %#x.\n", fx->dwZBufferHigh); -+ TRACE("dwZBufferBaseDest %#x.\n", fx->dwZBufferBaseDest); -+ TRACE("dwZDestConstBitDepth %#x.\n", fx->dwZDestConstBitDepth); -+ TRACE("lpDDSZBufferDest %p.\n", fx->u1.lpDDSZBufferDest); -+ TRACE("dwZSrcConstBitDepth %#x.\n", fx->dwZSrcConstBitDepth); -+ TRACE("lpDDSZBufferSrc %p.\n", fx->u2.lpDDSZBufferSrc); -+ TRACE("dwAlphaEdgeBlendBitDepth %#x.\n", fx->dwAlphaEdgeBlendBitDepth); -+ TRACE("dwAlphaEdgeBlend %#x.\n", fx->dwAlphaEdgeBlend); -+ TRACE("dwReserved %#x.\n", fx->dwReserved); -+ TRACE("dwAlphaDestConstBitDepth %#x.\n", fx->dwAlphaDestConstBitDepth); -+ TRACE("lpDDSAlphaDest %p.\n", fx->u3.lpDDSAlphaDest); -+ TRACE("dwAlphaSrcConstBitDepth %#x.\n", fx->dwAlphaSrcConstBitDepth); -+ TRACE("lpDDSAlphaSrc %p.\n", fx->u4.lpDDSAlphaSrc); -+ TRACE("lpDDSPattern %p.\n", fx->u5.lpDDSPattern); -+ TRACE("ddckDestColorkey {%#x, %#x}.\n", -+ fx->ddckDestColorkey.color_space_low_value, -+ fx->ddckDestColorkey.color_space_high_value); -+ TRACE("ddckSrcColorkey {%#x, %#x}.\n", -+ fx->ddckSrcColorkey.color_space_low_value, -+ fx->ddckSrcColorkey.color_space_high_value); ++ WARN("Volume %p is not CPU accessible.\n", volume); ++ return WINED3DERR_INVALIDCALL; ++ } ++ if (volume->resource.map_count) ++ { ++ WARN("Volume is already mapped.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ if (!wined3d_volume_check_box_dimensions(volume, box)) ++ { ++ WARN("Map box is invalid.\n"); ++ return WINED3DERR_INVALIDCALL; ++ } ++ if ((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !volume_check_block_align(volume, box)) ++ { ++ WARN("Map box %s is misaligned for %ux%u blocks.\n", ++ debug_box(box), format->block_width, format->block_height); ++ return WINED3DERR_INVALIDCALL; + } + -+ if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count)) ++ flags = wined3d_resource_sanitize_map_flags(&volume->resource, flags); ++ ++ if (volume->resource.map_binding == WINED3D_LOCATION_BUFFER) + { -+ WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n"); -+ return WINEDDERR_SURFACEBUSY; ++ context = context_acquire(device, NULL); ++ gl_info = context->gl_info; ++ ++ wined3d_volume_prepare_pbo(volume, context); ++ if (flags & WINED3D_MAP_DISCARD) ++ wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER); ++ else ++ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_BUFFER); ++ ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo)); ++ ++ if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) ++ { ++ GLbitfield mapflags = wined3d_resource_gl_map_flags(flags); ++ mapflags &= ~GL_MAP_FLUSH_EXPLICIT_BIT; ++ base_memory = GL_EXTCALL(glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, ++ 0, volume->resource.size, mapflags)); ++ } ++ else ++ { ++ GLenum access = wined3d_resource_gl_legacy_map_flags(flags); ++ base_memory = GL_EXTCALL(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, access)); ++ } ++ ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); ++ checkGLcall("Map PBO"); ++ ++ context_release(context); ++ } ++ else ++ { ++ if (!volume_prepare_system_memory(volume)) ++ { ++ WARN("Out of memory.\n"); ++ map_desc->data = NULL; ++ return E_OUTOFMEMORY; ++ } ++ ++ if (flags & WINED3D_MAP_DISCARD) ++ { ++ wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM); ++ } ++ else if (!(volume->locations & WINED3D_LOCATION_SYSMEM)) ++ { ++ context = context_acquire(device, NULL); ++ wined3d_volume_load_location(volume, context, WINED3D_LOCATION_SYSMEM); ++ context_release(context); ++ } ++ base_memory = volume->resource.heap_memory; ++ } ++ ++ TRACE("Base memory pointer %p.\n", base_memory); ++ ++ if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH) ++ { ++ map_desc->row_pitch = volume->resource.width * format->byte_count; ++ map_desc->slice_pitch = map_desc->row_pitch * volume->resource.height; ++ } ++ else ++ { ++ wined3d_volume_get_pitch(volume, &map_desc->row_pitch, &map_desc->slice_pitch); ++ } ++ ++ if (!box) ++ { ++ map_desc->data = base_memory; ++ } ++ else ++ { ++ if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS) ++ { ++ /* Compressed textures are block based, so calculate the offset of ++ * the block that contains the top-left pixel of the locked rectangle. */ ++ map_desc->data = base_memory ++ + (box->front * map_desc->slice_pitch) ++ + ((box->top / format->block_height) * map_desc->row_pitch) ++ + ((box->left / format->block_width) * format->block_byte_count); ++ } ++ else ++ { ++ map_desc->data = base_memory ++ + (map_desc->slice_pitch * box->front) ++ + (map_desc->row_pitch * box->top) ++ + (box->left * volume->resource.format->byte_count); ++ } + } + -+ surface_get_rect(dst_surface, dst_rect_in, &dst_rect); -+ -+ if (dst_rect.left >= dst_rect.right || dst_rect.top >= dst_rect.bottom -+ || dst_rect.left > dst_surface->resource.width || dst_rect.left < 0 -+ || dst_rect.top > dst_surface->resource.height || dst_rect.top < 0 -+ || dst_rect.right > dst_surface->resource.width || dst_rect.right < 0 -+ || dst_rect.bottom > dst_surface->resource.height || dst_rect.bottom < 0) ++ if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY))) + { -+ WARN("The application gave us a bad destination rectangle.\n"); -+ return WINEDDERR_INVALIDRECT; ++ wined3d_texture_set_dirty(volume->container); ++ wined3d_volume_invalidate_location(volume, ~volume->resource.map_binding); + } + -+ if (src_surface) -+ { -+ surface_get_rect(src_surface, src_rect_in, &src_rect); ++ volume->resource.map_count++; + -+ if (src_rect.left >= src_rect.right || src_rect.top >= src_rect.bottom -+ || src_rect.left > src_surface->resource.width || src_rect.left < 0 -+ || src_rect.top > src_surface->resource.height || src_rect.top < 0 -+ || src_rect.right > src_surface->resource.width || src_rect.right < 0 -+ || src_rect.bottom > src_surface->resource.height || src_rect.bottom < 0) -+ { -+ WARN("Application gave us bad source rectangle for Blt.\n"); -+ return WINEDDERR_INVALIDRECT; -+ } -+ } -+ else -+ { -+ memset(&src_rect, 0, sizeof(src_rect)); -+ } ++ TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n", ++ map_desc->data, map_desc->row_pitch, map_desc->slice_pitch); + -+ if (!fx || !(fx->dwDDFX)) -+ flags &= ~WINEDDBLT_DDFX; ++ return WINED3D_OK; ++} + -+ if (flags & WINEDDBLT_WAIT) -+ flags &= ~WINEDDBLT_WAIT; ++HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) ++{ ++ TRACE("volume %p.\n", volume); + -+ if (flags & WINEDDBLT_ASYNC) ++ if (!volume->resource.map_count) + { -+ static unsigned int once; -+ -+ if (!once++) -+ FIXME("Can't handle WINEDDBLT_ASYNC flag.\n"); -+ flags &= ~WINEDDBLT_ASYNC; ++ WARN("Trying to unlock an unlocked volume %p.\n", volume); ++ return WINED3DERR_INVALIDCALL; + } + -+ /* WINEDDBLT_DONOTWAIT appeared in DX7. */ -+ if (flags & WINEDDBLT_DONOTWAIT) ++ if (volume->resource.map_binding == WINED3D_LOCATION_BUFFER) + { -+ static unsigned int once; ++ struct wined3d_device *device = volume->resource.device; ++ struct wined3d_context *context = context_acquire(device, NULL); ++ const struct wined3d_gl_info *gl_info = context->gl_info; + -+ if (!once++) -+ FIXME("Can't handle WINEDDBLT_DONOTWAIT flag.\n"); -+ flags &= ~WINEDDBLT_DONOTWAIT; ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo)); ++ GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); ++ GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); ++ checkGLcall("Unmap PBO"); ++ ++ context_release(context); + } + ++ volume->resource.map_count--; ++ ++ return WINED3D_OK; +#endif /* STAGING_CSMT */ - if (!device->d3d_initialized) - { - WARN("D3D not initialized, using fallback.\n"); -@@ -4943,8 +6363,13 @@ - } - - scale = src_surface -+#if defined(STAGING_CSMT) - && (src_rect->right - src_rect->left != dst_rect->right - dst_rect->left - || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top); -+#else /* STAGING_CSMT */ -+ && (src_rect.right - src_rect.left != dst_rect.right - dst_rect.left -+ || src_rect.bottom - src_rect.top != dst_rect.bottom - dst_rect.top); -+#endif /* STAGING_CSMT */ - convert = src_surface && src_surface->resource.format->id != dst_surface->resource.format->id; + } - dst_ds_flags = dst_surface->container->resource.format_flags -@@ -4964,6 +6389,7 @@ - TRACE("Depth fill.\n"); + static ULONG volume_resource_incref(struct wined3d_resource *resource) +@@ -420,11 +860,13 @@ + return wined3d_texture_incref(volume->container); + } - if (!surface_convert_depth_to_float(dst_surface, fx->u5.dwFillDepth, &depth)) +#if defined(STAGING_CSMT) - return; + void wined3d_volume_cleanup_cs(struct wined3d_volume *volume) + { + HeapFree(GetProcessHeap(), 0, volume); + } - if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, dst_rect, depth))) -@@ -4974,6 +6400,24 @@ - if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->container->resource.draw_binding, - src_rect, dst_surface, dst_surface->container->resource.draw_binding, dst_rect))) - return; -+#else /* STAGING_CSMT */ -+ return WINED3DERR_INVALIDCALL; -+ -+ if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, &dst_rect, depth))) -+ return WINED3D_OK; -+ } -+ else -+ { -+ if (src_ds_flags != dst_ds_flags) -+ { -+ WARN("Rejecting depth / stencil blit between incompatible formats.\n"); -+ return WINED3DERR_INVALIDCALL; -+ } -+ -+ if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->container->resource.draw_binding, -+ &src_rect, dst_surface, dst_surface->container->resource.draw_binding, &dst_rect))) -+ return WINED3D_OK; +#endif /* STAGING_CSMT */ - } - } - else -@@ -4982,8 +6426,13 @@ + static ULONG volume_resource_decref(struct wined3d_resource *resource) + { + struct wined3d_volume *volume = volume_from_resource(resource); +@@ -446,6 +888,7 @@ + return WINED3DERR_INVALIDCALL; + } - /* In principle this would apply to depth blits as well, but we don't - * implement those in the CPU blitter at the moment. */ +#if defined(STAGING_CSMT) - if ((dst_surface->resource.locations & dst_surface->resource.map_binding) - && (!src_surface || (src_surface->resource.locations & src_surface->resource.map_binding))) -+#else /* STAGING_CSMT */ -+ if ((dst_surface->locations & dst_surface->resource.map_binding) -+ && (!src_surface || (src_surface->locations & src_surface->resource.map_binding))) -+#endif /* STAGING_CSMT */ - { - if (scale) - TRACE("Not doing sysmem blit because of scaling.\n"); -@@ -5004,8 +6453,13 @@ - palette, fx->u5.dwFillColor, &color)) - goto fallback; + static void wined3d_volume_location_invalidated(struct wined3d_resource *resource, DWORD location) + { + struct wined3d_volume *volume = volume_from_resource(resource); +@@ -454,6 +897,7 @@ + wined3d_texture_set_dirty(volume->container); + } -+#if defined(STAGING_CSMT) - if (SUCCEEDED(surface_color_fill(dst_surface, dst_rect, &color))) - return; -+#else /* STAGING_CSMT */ -+ if (SUCCEEDED(surface_color_fill(dst_surface, &dst_rect, &color))) -+ return WINED3D_OK; +#endif /* STAGING_CSMT */ - } - else - { -@@ -5027,8 +6481,13 @@ - { - blit_op = WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST; - } + static const struct wined3d_resource_ops volume_resource_ops = + { + volume_resource_incref, +@@ -461,8 +905,10 @@ + volume_unload, + volume_resource_sub_resource_map, + volume_resource_sub_resource_unmap, +#if defined(STAGING_CSMT) - else if ((src_surface->resource.locations & WINED3D_LOCATION_SYSMEM) - && !(dst_surface->resource.locations & WINED3D_LOCATION_SYSMEM)) -+#else /* STAGING_CSMT */ -+ else if ((src_surface->locations & WINED3D_LOCATION_SYSMEM) -+ && !(dst_surface->locations & WINED3D_LOCATION_SYSMEM)) + wined3d_volume_location_invalidated, + wined3d_volume_load_location, +#endif /* STAGING_CSMT */ - { - /* Upload */ - if (scale) -@@ -5037,6 +6496,7 @@ - TRACE("Not doing upload because of format conversion.\n"); - else - { -+#if defined(STAGING_CSMT) - POINT dst_point = {dst_rect->left, dst_rect->top}; + }; - if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, src_rect))) -@@ -5049,6 +6509,19 @@ - context_release(context); - } - return; -+#else /* STAGING_CSMT */ -+ POINT dst_point = {dst_rect.left, dst_rect.top}; -+ -+ if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, &src_rect))) -+ { -+ if (!wined3d_resource_is_offscreen(&dst_surface->container->resource)) -+ { -+ struct wined3d_context *context = context_acquire(device, dst_surface); -+ surface_load_location(dst_surface, context, dst_surface->container->resource.draw_binding); -+ context_release(context); -+ } -+ return WINED3D_OK; -+#endif /* STAGING_CSMT */ - } - } - } -@@ -5072,6 +6545,7 @@ - wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, NULL, 0); - dst_swapchain->desc.swap_effect = swap_effect; + static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture *container, +@@ -494,7 +940,11 @@ + } + volume->texture_level = level; +#if defined(STAGING_CSMT) - return; - } - -@@ -5280,6 +6754,54 @@ - wined3d_surface_location_invalidated, - wined3d_surface_load_location, - }; + volume->resource.locations = WINED3D_LOCATION_DISCARDED; +#else /* STAGING_CSMT */ -+ return WINED3D_OK; -+ } -+ -+ if (fbo_blit_supported(&device->adapter->gl_info, blit_op, -+ &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, -+ &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format)) -+ { -+ struct wined3d_context *context; -+ TRACE("Using FBO blit.\n"); -+ -+ context = context_acquire(device, NULL); -+ surface_blt_fbo(device, context, filter, -+ src_surface, src_surface->container->resource.draw_binding, &src_rect, -+ dst_surface, dst_surface->container->resource.draw_binding, &dst_rect); -+ context_release(context); -+ -+ surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding); -+ surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding); -+ -+ return WINED3D_OK; -+ } -+ -+ blitter = wined3d_select_blitter(&device->adapter->gl_info, &device->adapter->d3d_info, blit_op, -+ &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format, -+ &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format); -+ if (blitter) -+ { -+ blitter->blit_surface(device, blit_op, filter, src_surface, -+ &src_rect, dst_surface, &dst_rect, color_key); -+ return WINED3D_OK; -+ } -+ } -+ } -+ -+fallback: -+ /* Special cases for render targets. */ -+ if (SUCCEEDED(surface_blt_special(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter))) -+ return WINED3D_OK; -+ -+cpu: -+ -+ /* For the rest call the X11 surface implementation. For render targets -+ * this should be implemented OpenGL accelerated in surface_blt_special(), -+ * other blits are rather rare. */ -+ return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter); -+} ++ volume->locations = WINED3D_LOCATION_DISCARDED; +#endif /* STAGING_CSMT */ - static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_texture *container, - const struct wined3d_resource_desc *desc, GLenum target, unsigned int level, unsigned int layer, DWORD flags) -@@ -5341,7 +6863,11 @@ + if (desc->pool == WINED3D_POOL_DEFAULT && desc->usage & WINED3DUSAGE_DYNAMIC + && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] +@@ -502,7 +952,9 @@ + { + wined3d_resource_free_sysmem(&volume->resource); + volume->resource.map_binding = WINED3D_LOCATION_BUFFER; ++#if defined(STAGING_CSMT) + volume->resource.map_heap_memory = NULL; ++#endif /* STAGING_CSMT */ } - surface->container = container; + volume->container = container; +diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c +--- a/dlls/wined3d/wined3d_main.c ++++ b/dlls/wined3d/wined3d_main.c +@@ -86,8 +86,10 @@ + ~0U, /* No GS shader model limit by default. */ + ~0U, /* No PS shader model limit by default. */ + FALSE, /* 3D support enabled by default. */ +#if defined(STAGING_CSMT) - wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); -+#else /* STAGING_CSMT */ -+ surface_validate_location(surface, WINED3D_LOCATION_SYSMEM); + TRUE, /* Multithreaded CS by default. */ + FALSE, /* Do not ignore render target maps. */ +#endif /* STAGING_CSMT */ - list_init(&surface->renderbuffers); - list_init(&surface->overlays); + }; -@@ -5373,9 +6899,14 @@ - if (surface->resource.map_binding == WINED3D_LOCATION_DIB) - { - wined3d_resource_free_sysmem(&surface->resource); + struct wined3d * CDECL wined3d_create(DWORD flags) +@@ -316,6 +318,7 @@ + TRACE("Disabling 3D support.\n"); + wined3d_settings.no_3d = TRUE; + } +#if defined(STAGING_CSMT) - surface->resource.map_heap_memory = NULL; - wined3d_resource_validate_location(&surface->resource, WINED3D_LOCATION_DIB); - wined3d_resource_invalidate_location(&surface->resource, WINED3D_LOCATION_SYSMEM); + if (!get_config_key(hkey, appkey, "CSMT", buffer, size) + && !strcmp(buffer,"disabled")) + { +@@ -332,6 +335,9 @@ + + FIXME_(winediag)("Experimental wined3d CSMT feature is currently %s.\n", + wined3d_settings.cs_multithreaded ? "enabled" : "disabled"); +#else /* STAGING_CSMT */ -+ surface_validate_location(surface, WINED3D_LOCATION_DIB); -+ surface_invalidate_location(surface, WINED3D_LOCATION_SYSMEM); ++ } +#endif /* STAGING_CSMT */ - } - return hr; -@@ -5402,7 +6933,11 @@ - if (FAILED(hr = surface_init(object, container, desc, target, level, layer, flags))) - { - WARN("Failed to initialize surface, returning %#x.\n", hr); + if (appkey) RegCloseKey( appkey ); + if (hkey) RegCloseKey( hkey ); +diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h +--- a/dlls/wined3d/wined3d_private.h ++++ b/dlls/wined3d/wined3d_private.h +@@ -1,3 +1,4 @@ +#if defined(STAGING_CSMT) - /* The command stream takes care of freeing the memory. */ + /* + * Direct3D wine internal private include file + * +@@ -21,6 +22,31 @@ + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#else /* STAGING_CSMT */ -+ HeapFree(GetProcessHeap(), 0, object); ++/* ++ * Direct3D wine internal private include file ++ * ++ * Copyright 2002-2003 The wine-d3d team ++ * Copyright 2002-2003 Raphael Junqueira ++ * Copyright 2002-2003, 2004 Jason Edmeades ++ * Copyright 2005 Oliver Stieber ++ * Copyright 2006-2011, 2013 Stefan Dösinger for CodeWeavers ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ +#endif /* STAGING_CSMT */ - return hr; - } -diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c ---- a/dlls/wined3d/shader.c -+++ b/dlls/wined3d/shader.c -@@ -1872,7 +1872,11 @@ - } - } + #ifndef __WINE_WINED3D_PRIVATE_H + #define __WINE_WINED3D_PRIVATE_H +@@ -31,7 +57,9 @@ + #define WINE_GLAPI + #endif +#if defined(STAGING_CSMT) - void shader_cleanup(struct wined3d_shader *shader) -+#else /* STAGING_CSMT */ -+static void shader_cleanup(struct wined3d_shader *shader) + #include +#endif /* STAGING_CSMT */ - { - HeapFree(GetProcessHeap(), 0, shader->output_signature.elements); - HeapFree(GetProcessHeap(), 0, shader->input_signature.elements); -@@ -2131,10 +2135,16 @@ - - if (!refcount) - { + #include + #include + #include +@@ -295,8 +323,10 @@ + unsigned int max_sm_gs; + unsigned int max_sm_ps; + BOOL no_3d; +#if defined(STAGING_CSMT) - const struct wined3d_device *device = shader->device; - - shader->parent_ops->wined3d_object_destroyed(shader->parent); - wined3d_cs_emit_shader_cleanup(device->cs, shader); -+#else /* STAGING_CSMT */ -+ shader_cleanup(shader); -+ shader->parent_ops->wined3d_object_destroyed(shader->parent); -+ HeapFree(GetProcessHeap(), 0, shader); + BOOL cs_multithreaded; + BOOL ignore_rt_map; +#endif /* STAGING_CSMT */ - } + }; + + extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN; +@@ -1104,9 +1134,14 @@ + WORD use_map; /* MAX_ATTRIBS, 16 */ + }; - return refcount; -@@ -2417,7 +2427,11 @@ - memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */ - if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && state->render_states[WINED3D_RS_SRGBWRITEENABLE]) - { +#if defined(STAGING_CSMT) - unsigned int rt_fmt_flags = state->fb.render_targets[0]->format_flags; + void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, + UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count, + BOOL indexed) DECLSPEC_HIDDEN; +#else /* STAGING_CSMT */ -+ unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; ++void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count, ++ UINT start_instance, UINT instance_count, BOOL indexed) DECLSPEC_HIDDEN; +#endif /* STAGING_CSMT */ - if (rt_fmt_flags & WINED3DFMT_FLAG_SRGB_WRITE) - { - static unsigned int warned = 0; -diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c ---- a/dlls/wined3d/sampler.c -+++ b/dlls/wined3d/sampler.c -@@ -33,6 +33,7 @@ - return refcount; - } + DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; + #define eps 1e-8f +@@ -1194,8 +1229,10 @@ + struct list entry; + GLuint id; + struct wined3d_context *context; +#if defined(STAGING_CSMT) - void wined3d_sampler_destroy(struct wined3d_sampler *sampler) - { - struct wined3d_context *context = context_acquire(sampler->device, NULL); -@@ -54,6 +55,24 @@ - { - struct wined3d_device *device = sampler->device; - wined3d_cs_emit_sampler_destroy(device->cs, sampler); -+#else /* STAGING_CSMT */ -+ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler) -+{ -+ ULONG refcount = InterlockedDecrement(&sampler->refcount); -+ const struct wined3d_gl_info *gl_info; -+ struct wined3d_context *context; -+ -+ TRACE("%p decreasing refcount to %u.\n", sampler, refcount); -+ -+ if (!refcount) -+ { -+ context = context_acquire(sampler->device, NULL); -+ gl_info = context->gl_info; -+ GL_EXTCALL(glDeleteSamplers(1, &sampler->name)); -+ context_release(context); -+ -+ HeapFree(GetProcessHeap(), 0, sampler); + DWORD samples; + BOOL started; +#endif /* STAGING_CSMT */ - } + }; - return refcount; -diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c ---- a/dlls/wined3d/buffer.c -+++ b/dlls/wined3d/buffer.c -@@ -32,6 +32,7 @@ - #define WINED3D_BUFFER_HASDESC 0x01 /* A vertex description has been found. */ - #define WINED3D_BUFFER_CREATEBO 0x02 /* Create a buffer object for this buffer. */ - #define WINED3D_BUFFER_DOUBLEBUFFER 0x04 /* Keep both a buffer object and a system memory copy for this buffer. */ + union wined3d_gl_query_object +@@ -1231,6 +1268,7 @@ + struct list entry; + GLuint id; + struct wined3d_context *context; +#if defined(STAGING_CSMT) - #define WINED3D_BUFFER_DISCARD 0x08 /* The next PreLoad may discard the buffer contents. */ - #define WINED3D_BUFFER_SYNC 0x10 /* There has been at least one synchronized map since the last preload. */ - #define WINED3D_BUFFER_APPLESYNC 0x20 /* Using sync as in GL_APPLE_flush_buffer_range. */ -@@ -42,6 +43,19 @@ - #define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */ + UINT64 timestamp; + }; - void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, UINT offset, UINT size) +@@ -1266,6 +1304,12 @@ + for (i = 0; i < min(dst->rt_size, src->rt_size); i++) + dst->render_targets[i] = src->render_targets[i]; + } +#else /* STAGING_CSMT */ -+#define WINED3D_BUFFER_FLUSH 0x08 /* Manual unmap flushing. */ -+#define WINED3D_BUFFER_DISCARD 0x10 /* A DISCARD lock has occurred since the last preload. */ -+#define WINED3D_BUFFER_SYNC 0x20 /* There has been at least one synchronized map since the last preload. */ -+#define WINED3D_BUFFER_APPLESYNC 0x40 /* Using sync as in GL_APPLE_flush_buffer_range. */ -+ -+#define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */ -+#define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */ -+#define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */ -+#define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */ ++}; + -+static void buffer_invalidate_bo_range(struct wined3d_buffer *buffer, UINT offset, UINT size) ++void context_alloc_timestamp_query(struct wined3d_context *context, struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; ++void context_free_timestamp_query(struct wined3d_timestamp_query *query) DECLSPEC_HIDDEN; +#endif /* STAGING_CSMT */ - { - if (!offset && !size) - goto invalidate_all; -@@ -117,7 +131,11 @@ - } - /* Context activation is done by the caller. */ -+#if defined(STAGING_CSMT) - void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) -+#else /* STAGING_CSMT */ -+static void buffer_create_buffer_object(struct wined3d_buffer *This, struct wined3d_context *context) -+#endif /* STAGING_CSMT */ + struct wined3d_context { - GLenum gl_usage = GL_STATIC_DRAW_ARB; - GLenum error; -@@ -166,6 +184,10 @@ - { - GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)); - checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)"); -+#if !defined(STAGING_CSMT) -+ This->flags |= WINED3D_BUFFER_FLUSH; -+ -+#endif /* STAGING_CSMT */ - GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)); - checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)"); - This->flags |= WINED3D_BUFFER_APPLESYNC; -@@ -191,10 +213,14 @@ - if (This->flags & WINED3D_BUFFER_DOUBLEBUFFER) - buffer_invalidate_bo_range(This, 0, 0); - else +@@ -1281,7 +1325,9 @@ + DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */ + DWORD numDirtyEntries; + DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ +#if defined(STAGING_CSMT) - { - wined3d_resource_free_sysmem(&This->resource); - This->resource.map_heap_memory = NULL; - } -+#else /* STAGING_CSMT */ -+ wined3d_resource_free_sysmem(&This->resource); + struct wined3d_fb_state current_fb; +#endif /* STAGING_CSMT */ - return; - -@@ -423,6 +449,7 @@ - { - DWORD src_color = *dst_color; - + struct wined3d_swapchain *swapchain; + struct wined3d_surface *current_rt; +@@ -1379,8 +1425,17 @@ + GLfloat fog_coord_value; + GLfloat color[4], fogstart, fogend, fogcolor[4]; + GLuint dummy_arbfp_prog; +#if defined(STAGING_CSMT) - /* Color conversion like in draw_strided_slow. watch out for little endianity - * If we want that stuff to work on big endian machines too we have to consider more things - * -@@ -431,6 +458,16 @@ - * 0x0000ff00: Green mask - * 0x000000ff: Red mask - */ + + GLenum offscreenBuffer; +#else /* STAGING_CSMT */ -+ /* Color conversion like in drawStridedSlow. watch out for little endianity -+ * If we want that stuff to work on big endian machines too we have to consider more things -+ * -+ * 0xff000000: Alpha mask -+ * 0x00ff0000: Blue mask -+ * 0x0000ff00: Green mask -+ * 0x000000ff: Red mask -+ */ ++}; ++ ++struct wined3d_fb_state ++{ ++ struct wined3d_rendertarget_view **render_targets; ++ struct wined3d_rendertarget_view *depth_stencil; +#endif /* STAGING_CSMT */ - *dst_color = 0; - *dst_color |= (src_color & 0xff00ff00u); /* Alpha Green */ - *dst_color |= (src_color & 0x00ff0000u) >> 16; /* Red */ -@@ -457,8 +494,12 @@ - data->buffer_object = buffer->buffer_object; - if (!buffer->buffer_object) - { + }; + + typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id); +@@ -1523,8 +1578,12 @@ + void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN; + BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_device *device, + UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN; +#if defined(STAGING_CSMT) - if ((!buffer->resource.map_count || buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER) - && buffer->flags & WINED3D_BUFFER_CREATEBO) + BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, + const struct wined3d_state *state) DECLSPEC_HIDDEN; +#else /* STAGING_CSMT */ -+ if ((buffer->flags & WINED3D_BUFFER_CREATEBO) && !buffer->resource.map_count) ++BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) DECLSPEC_HIDDEN; +#endif /* STAGING_CSMT */ - { - buffer_create_buffer_object(buffer, context); - buffer->flags &= ~WINED3D_BUFFER_CREATEBO; -@@ -497,7 +538,9 @@ - - if (!wined3d_resource_allocate_sysmem(&This->resource)) - ERR("Failed to allocate system memory.\n"); + void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, + struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN; + void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, +@@ -2107,7 +2166,11 @@ + struct wined3d_state + { + DWORD flags; +#if defined(STAGING_CSMT) - This->resource.heap_memory = This->resource.map_heap_memory; + struct wined3d_fb_state fb; ++#else /* STAGING_CSMT */ ++ const struct wined3d_fb_state *fb; +#endif /* STAGING_CSMT */ - if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) - context_invalidate_state(context, STATE_INDEXBUFFER); -@@ -545,6 +588,7 @@ - resource_unload(resource); - } + struct wined3d_vertex_declaration *vertex_declaration; + struct wined3d_stream_output stream_output[MAX_STREAM_OUT]; +@@ -2152,6 +2215,7 @@ + DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; + }; +#if defined(STAGING_CSMT) - void wined3d_buffer_cleanup_cs(struct wined3d_buffer *buffer) + struct wined3d_gl_bo { - struct wined3d_context *context; -@@ -577,6 +621,30 @@ + GLuint name; +@@ -2160,6 +2224,7 @@ + UINT size; + }; - buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent); - wined3d_cs_emit_buffer_cleanup(device->cs, buffer); ++#endif /* STAGING_CSMT */ + #define WINED3D_UNMAPPED_STAGE ~0U + + /* Multithreaded flag. Removed from the public header to signal that +@@ -2215,11 +2280,23 @@ + struct wined3d_rendertarget_view *back_buffer_view; + struct wined3d_swapchain **swapchains; + UINT swapchain_count; ++#if defined(STAGING_CSMT) + struct wined3d_rendertarget_view *auto_depth_stencil_view; + + struct list resources; /* a linked list to track resources created by the device */ + struct list shaders; /* a linked list to track shaders (pixel and vertex) */ + struct wine_rb_tree samplers; +#else /* STAGING_CSMT */ -+ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer) -+{ -+ ULONG refcount = InterlockedDecrement(&buffer->resource.ref); -+ struct wined3d_context *context; -+ -+ TRACE("%p decreasing refcount to %u.\n", buffer, refcount); -+ -+ if (!refcount) -+ { -+ if (buffer->buffer_object) -+ { -+ context = context_acquire(buffer->resource.device, NULL); -+ delete_gl_buffer(buffer, context->gl_info); -+ context_release(context); + -+ HeapFree(GetProcessHeap(), 0, buffer->conversion_map); -+ } ++ struct list resources; /* a linked list to track resources created by the device */ ++ struct list shaders; /* a linked list to track shaders (pixel and vertex) */ ++ struct wine_rb_tree samplers; + -+ resource_cleanup(&buffer->resource); -+ buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent); -+ HeapFree(GetProcessHeap(), 0, buffer->maps); -+ HeapFree(GetProcessHeap(), 0, buffer); ++ /* Render Target Support */ ++ struct wined3d_fb_state fb; ++ struct wined3d_surface *onscreen_depth_stencil; ++ struct wined3d_rendertarget_view *auto_depth_stencil_view; +#endif /* STAGING_CSMT */ - } - return refcount; -@@ -661,6 +729,7 @@ - /* The caller provides a GL context */ - static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info, DWORD flags) + /* For rendering to a texture using glCopyTexImage */ + GLuint depth_blt_texture; +@@ -2230,6 +2307,9 @@ + UINT xScreenSpace; + UINT yScreenSpace; + UINT cursorWidth, cursorHeight; ++#if !defined(STAGING_CSMT) ++ struct wined3d_texture *cursor_texture; ++#endif /* STAGING_CSMT */ + HCURSOR hardwareCursor; + + /* The Wine logo texture */ +@@ -2264,6 +2344,7 @@ + UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN; + void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++#if defined(STAGING_CSMT) + void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; + void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) DECLSPEC_HIDDEN; + void device_exec_update_texture(struct wined3d_context *context, struct wined3d_texture *src_texture, +@@ -2276,6 +2357,11 @@ + void device_create_default_sampler(struct wined3d_device *device); + void device_delete_opengl_contexts_cs(struct wined3d_device *device, + struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; ++#else /* STAGING_CSMT */ ++void device_switch_onscreen_ds(struct wined3d_device *device, struct wined3d_context *context, ++ struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; ++void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; ++#endif /* STAGING_CSMT */ + + static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) { +@@ -2295,9 +2381,11 @@ + HRESULT (*resource_sub_resource_map)(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); + HRESULT (*resource_sub_resource_unmap)(struct wined3d_resource *resource, unsigned int sub_resource_idx); +#if defined(STAGING_CSMT) - UINT start = 0, len = 0; + void (*resource_location_invalidated)(struct wined3d_resource *resource, DWORD location); + void (*resource_load_location)(struct wined3d_resource *resource, + struct wined3d_context *context, DWORD location); ++#endif /* STAGING_CSMT */ + }; - /* This potentially invalidates the element array buffer binding, but the -@@ -684,6 +753,45 @@ - GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)); - checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)"); - This->flags &= ~WINED3D_BUFFER_APPLESYNC; + struct wined3d_resource +@@ -2322,6 +2410,7 @@ + UINT depth; + UINT size; + DWORD priority; ++#if defined(STAGING_CSMT) + void *heap_memory, *map_heap_memory, *user_memory, *bitmap_data; + UINT custom_row_pitch, custom_slice_pitch; + struct wined3d_gl_bo *buffer, *map_buffer; +@@ -2329,6 +2418,10 @@ + DWORD locations; + LONG access_fence; + BOOL unmap_dirtify; +#else /* STAGING_CSMT */ -+ BYTE *map; -+ UINT start = 0, len = 0; -+ -+ /* This potentially invalidates the element array buffer binding, but the -+ * caller always takes care of this. */ -+ GL_EXTCALL(glBindBuffer(This->buffer_type_hint, This->buffer_object)); -+ checkGLcall("glBindBuffer"); -+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) -+ { -+ GLbitfield mapflags; -+ mapflags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; -+ if (flags & WINED3D_BUFFER_DISCARD) -+ mapflags |= GL_MAP_INVALIDATE_BUFFER_BIT; -+ else if (!(flags & WINED3D_BUFFER_SYNC)) -+ mapflags |= GL_MAP_UNSYNCHRONIZED_BIT; -+ map = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0, -+ This->resource.size, mapflags)); -+ checkGLcall("glMapBufferRange"); -+ } -+ else -+ { -+ if (This->flags & WINED3D_BUFFER_APPLESYNC) -+ { -+ DWORD syncflags = 0; -+ if (flags & WINED3D_BUFFER_DISCARD) -+ syncflags |= WINED3D_MAP_DISCARD; -+ else if (!(flags & WINED3D_BUFFER_SYNC)) -+ syncflags |= WINED3D_MAP_NOOVERWRITE; -+ buffer_sync_apple(This, syncflags, gl_info); -+ } -+ map = GL_EXTCALL(glMapBuffer(This->buffer_type_hint, GL_WRITE_ONLY)); -+ checkGLcall("glMapBuffer"); -+ } -+ if (!map) -+ { -+ ERR("Failed to map opengl buffer\n"); -+ return; ++ void *heap_memory; ++ struct list resource_list_entry; +#endif /* STAGING_CSMT */ - } - - while (This->modified_areas) -@@ -692,12 +800,33 @@ - start = This->maps[This->modified_areas].offset; - len = This->maps[This->modified_areas].size; + void *parent; + const struct wined3d_parent_ops *parent_ops; +@@ -2353,6 +2446,7 @@ + void *parent, const struct wined3d_parent_ops *parent_ops, + const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN; + void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; +#if defined(STAGING_CSMT) - GL_EXTCALL(glBufferSubData(This->buffer_type_hint, start, len, (BYTE *)This->resource.heap_memory + start)); - checkGLcall("glBufferSubData"); - } + DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; + BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; + void wined3d_resource_changed(struct wined3d_resource *resource, +@@ -2401,6 +2495,15 @@ + { + while(InterlockedCompareExchange(&resource->access_fence, 0, 0)); } ++#else /* STAGING_CSMT */ ++BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; ++GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN; ++BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++DWORD wined3d_resource_sanitize_map_flags(const struct wined3d_resource *resource, DWORD flags) DECLSPEC_HIDDEN; ++void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; ++#endif /* STAGING_CSMT */ - static void buffer_mark_used(struct wined3d_buffer *buffer) + /* Tests show that the start address of resources is 32 byte aligned */ + #define RESOURCE_ALIGNMENT 16 +@@ -2485,7 +2588,9 @@ + + void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, + const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; ++#if defined(STAGING_CSMT) + void wined3d_texture_cleanup_cs(struct wined3d_texture *texture) DECLSPEC_HIDDEN; ++#endif /* STAGING_CSMT */ + void wined3d_texture_bind(struct wined3d_texture *texture, + struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; + void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, +@@ -2517,8 +2622,15 @@ + struct wined3d_resource resource; + struct wined3d_texture *container; + ++#if defined(STAGING_CSMT) ++ GLint texture_level; ++ DWORD download_count; +#else /* STAGING_CSMT */ -+ memcpy(map + start, (BYTE *)This->resource.heap_memory + start, len); -+ -+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE]) -+ { -+ GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len)); -+ checkGLcall("glFlushMappedBufferRange"); -+ } -+ else if (This->flags & WINED3D_BUFFER_FLUSH) -+ { -+ GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len)); -+ checkGLcall("glFlushMappedBufferRangeAPPLE"); -+ } -+ } -+ GL_EXTCALL(glUnmapBuffer(This->buffer_type_hint)); -+ checkGLcall("glUnmapBuffer"); -+} -+ -+void buffer_mark_used(struct wined3d_buffer *buffer) ++ DWORD locations; + GLint texture_level; + DWORD download_count; ++ GLuint pbo; +#endif /* STAGING_CSMT */ - { - buffer->flags &= ~(WINED3D_BUFFER_SYNC | WINED3D_BUFFER_DISCARD); - } -@@ -716,6 +845,14 @@ + }; - TRACE("buffer %p.\n", buffer); + static inline struct wined3d_volume *volume_from_resource(struct wined3d_resource *resource) +@@ -2526,6 +2638,7 @@ + return CONTAINING_RECORD(resource, struct wined3d_volume, resource); + } -+#if !defined(STAGING_CSMT) -+ if (buffer->resource.map_count) -+ { -+ WARN("Buffer is mapped, skipping preload.\n"); -+ return; -+ } ++#if defined(STAGING_CSMT) + HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, + unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN; + void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN; +@@ -2541,6 +2654,27 @@ + struct wined3d_surface_dib + { + HBITMAP DIBsection; ++#else /* STAGING_CSMT */ ++BOOL volume_prepare_system_memory(struct wined3d_volume *volume) DECLSPEC_HIDDEN; ++HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, ++ unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN; ++void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN; ++void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch) DECLSPEC_HIDDEN; ++void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, ++ BOOL srgb_mode) DECLSPEC_HIDDEN; ++void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; ++HRESULT wined3d_volume_map(struct wined3d_volume *volume, ++ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; ++void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN; ++HRESULT wined3d_volume_unmap(struct wined3d_volume *volume) DECLSPEC_HIDDEN; ++void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, ++ const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; + ++struct wined3d_surface_dib ++{ ++ HBITMAP DIBsection; ++ void *bitmap_data; +#endif /* STAGING_CSMT */ - buffer_mark_used(buffer); - - if (!buffer->buffer_object) -@@ -904,6 +1041,7 @@ + UINT bitmap_size; + }; - void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer) +@@ -2566,7 +2700,11 @@ + struct wined3d_surface_ops { + HRESULT (*surface_private_setup)(struct wined3d_surface *surface); +#if defined(STAGING_CSMT) - struct wined3d_device *device = buffer->resource.device; - - if (buffer->resource.map_count) -@@ -913,6 +1051,12 @@ - } - - wined3d_cs_emit_buffer_preload(device->cs, buffer); + void (*surface_frontbuffer_updated)(struct wined3d_surface *surface); +#else /* STAGING_CSMT */ -+ struct wined3d_context *context; -+ context = context_acquire(buffer->resource.device, NULL); -+ buffer_internal_preload(buffer, context, NULL); -+ context_release(context); ++ void (*surface_unmap)(struct wined3d_surface *surface); +#endif /* STAGING_CSMT */ - } + }; - struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer) -@@ -926,6 +1070,7 @@ - { - LONG count; - BYTE *base; + struct wined3d_surface +@@ -2574,12 +2712,26 @@ + struct wined3d_resource resource; + const struct wined3d_surface_ops *surface_ops; + struct wined3d_texture *container; +#if defined(STAGING_CSMT) - struct wined3d_device *device = buffer->resource.device; - struct wined3d_context *context; -@@ -950,6 +1095,10 @@ - wined3d_cs_emit_create_vbo(device->cs, buffer); - buffer->flags &= ~WINED3D_BUFFER_CREATEBO; - } + DWORD flags; + + UINT pow2Width; + UINT pow2Height; + +#else /* STAGING_CSMT */ ++ void *user_memory; ++ DWORD locations; + -+ TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags); ++ DWORD flags; ++ ++ UINT pitch; ++ UINT pow2Width; ++ UINT pow2Height; ++ ++ /* PBO */ ++ GLuint pbo; +#endif /* STAGING_CSMT */ - - flags = wined3d_resource_sanitize_map_flags(&buffer->resource, flags); - /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001 multitexture -@@ -958,7 +1107,11 @@ - * previous contents of the buffer. The r600g driver only does this when - * the buffer is currently in use, while the proprietary NVIDIA driver - * appears to do this unconditionally. */ + GLuint rb_multisample; + GLuint rb_resolved; + GLenum texture_target; +@@ -2627,11 +2779,22 @@ + GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) DECLSPEC_HIDDEN; + void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context, + unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN; +#if defined(STAGING_CSMT) - if (buffer->ignore_discard) + void surface_load(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; + void surface_load_ds_location(struct wined3d_surface *surface, + struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; + void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, + struct wined3d_context *context) DECLSPEC_HIDDEN; +#else /* STAGING_CSMT */ -+ if (buffer->flags & WINED3D_BUFFER_DISCARD) ++void surface_invalidate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN; ++void surface_load(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; ++void surface_load_ds_location(struct wined3d_surface *surface, ++ struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; ++void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb, ++ struct wined3d_context *context) DECLSPEC_HIDDEN; ++HRESULT surface_load_location(struct wined3d_surface *surface, ++ struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN; +#endif /* STAGING_CSMT */ - flags &= ~WINED3D_MAP_DISCARD; - count = ++buffer->resource.map_count; - -@@ -969,6 +1122,7 @@ - * being uploaded in that case. Two such applications are Port Royale - * and Darkstar One. */ - if (flags & WINED3D_MAP_DISCARD) + HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_desc *map_desc, + const struct wined3d_box *box, DWORD flags) DECLSPEC_HIDDEN; + void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; +@@ -2646,6 +2809,7 @@ + const struct wined3d_gl_info *gl_info, void *mem, unsigned int pitch) DECLSPEC_HIDDEN; + HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, + struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN; +#if defined(STAGING_CSMT) - wined3d_cs_emit_buffer_invalidate_bo_range(device->cs, buffer, 0, 0); - else if (!(flags & WINED3D_MAP_READONLY)) - wined3d_cs_emit_buffer_invalidate_bo_range(device->cs, buffer, offset, size); -@@ -986,6 +1140,19 @@ - wined3d_cs_emit_glfinish(device->cs); - device->cs->ops->finish(device->cs); - } + HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, + GLenum target, unsigned int level, unsigned int layer, DWORD flags, + struct wined3d_surface **surface) DECLSPEC_HIDDEN; +@@ -2660,6 +2824,17 @@ + void wined3d_surface_cleanup_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; + void wined3d_surface_getdc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; + void wined3d_surface_releasedc_cs(struct wined3d_surface *surface) DECLSPEC_HIDDEN; +#else /* STAGING_CSMT */ -+ buffer_invalidate_bo_range(buffer, 0, 0); -+ else if (!(flags & WINED3D_MAP_READONLY)) -+ buffer_invalidate_bo_range(buffer, offset, size); -+ -+ if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER)) -+ { -+ if (count == 1) -+ { -+ struct wined3d_device *device = buffer->resource.device; -+ struct wined3d_context *context; -+ const struct wined3d_gl_info *gl_info; ++void surface_validate_location(struct wined3d_surface *surface, DWORD location) DECLSPEC_HIDDEN; ++HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, ++ GLenum target, unsigned int level, unsigned int layer, DWORD flags, ++ struct wined3d_surface **surface) DECLSPEC_HIDDEN; ++void wined3d_surface_destroy(struct wined3d_surface *surface) DECLSPEC_HIDDEN; ++void surface_prepare_map_memory(struct wined3d_surface *surface) DECLSPEC_HIDDEN; ++void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, ++ const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point, ++ BOOL srgb, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN; +#endif /* STAGING_CSMT */ - context = context_acquire(device, NULL); - gl_info = context->gl_info; -@@ -1036,6 +1203,7 @@ - buffer_get_sysmem(buffer, context); - } - TRACE("New pointer is %p.\n", buffer->resource.heap_memory); + void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, + const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; +@@ -2680,8 +2855,10 @@ + GLuint name; + }; + +#if defined(STAGING_CSMT) - } - context_release(context); - } -@@ -1075,6 +1243,21 @@ - } + void wined3d_sampler_destroy(struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; - base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.map_heap_memory; -+#else /* STAGING_CSMT */ -+ buffer->map_ptr = NULL; -+ } -+ context_release(context); -+ } -+ } -+ -+ if (flags & WINED3D_MAP_DISCARD) -+ buffer->flags |= WINED3D_BUFFER_DISCARD; -+ else if (!(flags & WINED3D_MAP_NOOVERWRITE)) -+ buffer->flags |= WINED3D_BUFFER_SYNC; -+ } -+ -+ base = buffer->map_ptr ? buffer->map_ptr : buffer->resource.heap_memory; +#endif /* STAGING_CSMT */ - *data = base + offset; + struct wined3d_vertex_declaration_element + { + const struct wined3d_format *format; +@@ -2710,8 +2887,10 @@ + BOOL half_float_conv_needed; + }; - TRACE("Returning memory at %p (base %p, offset %u).\n", *data, base, offset); -@@ -1128,7 +1311,11 @@ - checkGLcall("glFlushMappedBufferRange"); - } - } +#if defined(STAGING_CSMT) - else if (buffer->flags & WINED3D_BUFFER_APPLESYNC) -+#else /* STAGING_CSMT */ -+ else if (buffer->flags & WINED3D_BUFFER_FLUSH) + void wined3d_vertex_declaration_destroy(struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; + +#endif /* STAGING_CSMT */ - { - for (i = 0; i < buffer->modified_areas; ++i) - { -@@ -1139,6 +1326,7 @@ - } + struct wined3d_saved_states + { + DWORD transform[(HIGHEST_TRANSFORMSTATE >> 5) + 1]; +@@ -2779,6 +2958,7 @@ + void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN; - GL_EXTCALL(glUnmapBuffer(buffer->buffer_type_hint)); + void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; +#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - gl_info->gl_ops.gl.p_glFinish(); - else if (wined3d_settings.strict_draw_ordering) -@@ -1147,6 +1335,18 @@ - - buffer_clear_dirty_areas(buffer); - buffer->map_ptr = NULL; + HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl_info, + const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; + void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; +@@ -2829,6 +3009,32 @@ + void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN; + void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, struct wined3d_context *context, + struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; +#else /* STAGING_CSMT */ -+ if (wined3d_settings.strict_draw_ordering) -+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */ -+ context_release(context); ++HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, ++ const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, ++ DWORD flags) DECLSPEC_HIDDEN; ++void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; ++ ++struct wined3d_cs_ops ++{ ++ void *(*require_space)(struct wined3d_cs *cs, size_t size); ++ void (*submit)(struct wined3d_cs *cs); ++}; ++ ++struct wined3d_cs ++{ ++ const struct wined3d_cs_ops *ops; ++ struct wined3d_device *device; ++ struct wined3d_fb_state fb; ++ struct wined3d_state state; ++ ++ size_t data_size; ++ void *data; ++}; + -+ buffer_clear_dirty_areas(buffer); -+ buffer->map_ptr = NULL; -+ } -+ else if (buffer->flags & WINED3D_BUFFER_HASDESC) -+ { -+ wined3d_buffer_preload(buffer); ++struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) DECLSPEC_HIDDEN; ++void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN; +#endif /* STAGING_CSMT */ - } - } - -@@ -1198,6 +1398,7 @@ - return WINED3D_OK; - } + void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, + DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; +@@ -2878,6 +3084,7 @@ + void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, + struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; +#if defined(STAGING_CSMT) - static void wined3d_buffer_location_invalidated(struct wined3d_resource *resource, DWORD location) - { - ERR("Not yet implemented.\n"); -@@ -1210,6 +1411,7 @@ - ERR("Not yet implemented.\n"); - } - + void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, + UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; + void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, +@@ -2940,6 +3147,7 @@ + void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource, + unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, + unsigned int depth_pitch) DECLSPEC_HIDDEN; +#endif /* STAGING_CSMT */ - static const struct wined3d_resource_ops buffer_resource_ops = + + /* Direct3D terminology with little modifications. We do not have an issued state + * because only the driver knows about it, but we have a created state because d3d +@@ -2954,8 +3162,12 @@ + struct wined3d_query_ops { - buffer_resource_incref, -@@ -1217,8 +1419,10 @@ - buffer_unload, - buffer_resource_sub_resource_map, - buffer_resource_sub_resource_unmap, + HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags); +#if defined(STAGING_CSMT) - wined3d_buffer_location_invalidated, - wined3d_buffer_load_location, + BOOL (*query_poll)(struct wined3d_query *query); + BOOL (*query_issue)(struct wined3d_query *query, DWORD flags); ++#else /* STAGING_CSMT */ ++ HRESULT (*query_issue)(struct wined3d_query *query, DWORD flags); +#endif /* STAGING_CSMT */ }; - static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device *device, -@@ -1250,7 +1454,9 @@ - return hr; - } - buffer->buffer_type_hint = bind_hint; + struct wined3d_query +@@ -2969,12 +3181,16 @@ + enum wined3d_query_type type; + DWORD data_size; + void *extendedData; +#if defined(STAGING_CSMT) - buffer->ignore_discard = TRUE; -+#endif /* STAGING_CSMT */ - TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage, - debug_d3dformat(buffer->resource.format->id), buffer->resource.heap_memory, buffer); -@@ -1266,6 +1472,7 @@ - - dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE]; + LONG counter_main, counter_retrieved; + struct list poll_list_entry; + }; -+#if defined(STAGING_CSMT) - /* Observations show that draw_strided_slow is faster on dynamic VBs than converting + - * drawStridedFast (half-life 2 and others). - * -@@ -1273,6 +1480,15 @@ - * show that draw_strided_slow is faster than converting + uploading + drawStridedFast. - * Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers. - */ + void wined3d_query_destroy(struct wined3d_query *query) DECLSPEC_HIDDEN; +#else /* STAGING_CSMT */ -+ /* Observations show that drawStridedSlow is faster on dynamic VBs than converting + -+ * drawStridedFast (half-life 2 and others). -+ * -+ * Basically converting the vertices in the buffer is quite expensive, and observations -+ * show that drawStridedSlow is faster than converting + uploading + drawStridedFast. -+ * Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers. -+ */ ++}; +#endif /* STAGING_CSMT */ - if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT]) - { - TRACE("Not creating a vbo because GL_ARB_vertex_buffer is not supported\n"); -@@ -1290,6 +1506,7 @@ - buffer->flags |= WINED3D_BUFFER_CREATEBO; - } - -+#if defined(STAGING_CSMT) - buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)); - if (!buffer->maps) - { -@@ -1300,6 +1517,7 @@ - } - buffer->maps_size = 1; -+#endif /* STAGING_CSMT */ - if (data) - { - BYTE *ptr; -@@ -1308,7 +1526,9 @@ - if (FAILED(hr)) - { - ERR("Failed to map buffer, hr %#x\n", hr); + /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other + * fixed function semantics as D3DCOLOR or FLOAT16 */ +@@ -3001,7 +3217,9 @@ + GLenum buffer_object_usage; + GLenum buffer_type_hint; + DWORD flags; +#if defined(STAGING_CSMT) - HeapFree(GetProcessHeap(), 0, buffer->maps); + BOOL ignore_discard; +#endif /* STAGING_CSMT */ - buffer_unload(&buffer->resource); - resource_cleanup(&buffer->resource); - return hr; -@@ -1319,8 +1539,20 @@ - wined3d_buffer_unmap(buffer); - } + void *map_ptr; + struct wined3d_map_range *maps; +@@ -3026,11 +3244,15 @@ + BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *context) DECLSPEC_HIDDEN; + void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, + const struct wined3d_state *state) DECLSPEC_HIDDEN; +#if defined(STAGING_CSMT) - if (wined3d_settings.cs_multithreaded) - buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER; + void buffer_invalidate_bo_range(struct wined3d_buffer *This, UINT offset, UINT size) DECLSPEC_HIDDEN; + void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) DECLSPEC_HIDDEN; + void buffer_create_buffer_object(struct wined3d_buffer *This, + struct wined3d_context *context) DECLSPEC_HIDDEN; + void wined3d_buffer_cleanup_cs(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; +#else /* STAGING_CSMT */ -+ buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps)); -+ if (!buffer->maps) -+ { -+ ERR("Out of memory\n"); -+ buffer_unload(&buffer->resource); -+ resource_cleanup(&buffer->resource); -+ return E_OUTOFMEMORY; -+ } -+ buffer->maps_size = 1; ++void buffer_mark_used(struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; +#endif /* STAGING_CSMT */ + HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, + const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN; - return WINED3D_OK; +@@ -3068,8 +3290,10 @@ + return surface_from_resource(resource); } -@@ -1429,6 +1661,7 @@ - return WINED3D_OK; - } +#if defined(STAGING_CSMT) + void wined3d_rendertarget_view_destroy(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; - void buffer_swap_mem(struct wined3d_buffer *buffer, BYTE *mem) - { -@@ -1436,3 +1669,4 @@ - buffer->resource.heap_memory = mem; - buffer->flags |= WINED3D_BUFFER_DISCARD; - } -+#endif /* STAGING_CSMT */ -diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c ---- a/dlls/wined3d/directx.c -+++ b/dlls/wined3d/directx.c -@@ -5555,9 +5555,15 @@ - DebugBreak(); - } - -+#if defined(STAGING_CSMT) - /* Helper functions for providing vertex data to opengl. The arrays are initialized based on - * the extension detection and are used in draw_strided_slow - */ -+#else /* STAGING_CSMT */ -+/* Helper functions for providing vertex data to opengl. The arrays are initialized based on -+ * the extension detection and are used in drawStridedSlow -+ */ -+#endif /* STAGING_CSMT */ - static void WINE_GLAPI position_d3dcolor(const void *data) - { - DWORD pos = *((const DWORD *)data); -diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c ---- a/dlls/wined3d/resource.c -+++ b/dlls/wined3d/resource.c -@@ -203,7 +203,9 @@ - ERR("Failed to allocate system memory.\n"); - return E_OUTOFMEMORY; - } -+#if defined(STAGING_CSMT) - resource->heap_memory = resource->map_heap_memory; +#endif /* STAGING_CSMT */ - } - else - { -@@ -227,6 +229,7 @@ - return WINED3D_OK; - } - -+#if defined(STAGING_CSMT) - void wined3d_resource_free_bo(struct wined3d_resource *resource) + struct wined3d_shader_resource_view { - struct wined3d_context *context = context_acquire(resource->device, NULL); -@@ -252,6 +255,7 @@ - resource->map_heap_memory = NULL; - } - -+#endif /* STAGING_CSMT */ - void resource_cleanup(struct wined3d_resource *resource) + LONG refcount; +@@ -3082,8 +3306,12 @@ + struct wined3d_swapchain_ops { - const struct wined3d *d3d = resource->device->wined3d; -@@ -264,7 +268,11 @@ - adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size); - } - + void (*swapchain_present)(struct wined3d_swapchain *swapchain, const RECT *src_rect, +#if defined(STAGING_CSMT) - wined3d_cs_emit_resource_cleanup(resource->device->cs, resource); + const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags, + struct wined3d_surface *depth_stencil); +#else /* STAGING_CSMT */ -+ wined3d_resource_free_sysmem(resource); ++ const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags); +#endif /* STAGING_CSMT */ + }; - device_resource_released(resource->device, resource); - } -@@ -274,9 +282,11 @@ - if (resource->map_count) - ERR("Resource %p is being unloaded while mapped.\n", resource); - + struct wined3d_swapchain +@@ -3122,8 +3350,10 @@ + void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; + void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; +#if defined(STAGING_CSMT) - if (resource->buffer) - wined3d_resource_free_bo(resource); - + HRESULT swapchain_create_context_cs(struct wined3d_device *device, + struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; +#endif /* STAGING_CSMT */ - context_resource_unloaded(resource->device, - resource, resource->type); - } -@@ -355,7 +365,11 @@ - p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1; - *p = mem; + /***************************************************************************** + * Utility function prototypes +@@ -3327,7 +3557,9 @@ + void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, + const struct wined3d_shader_reg_maps *reg_maps, const DWORD *byte_code, void *backend_ctx) DECLSPEC_HIDDEN; + BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage) DECLSPEC_HIDDEN; +#if defined(STAGING_CSMT) - resource->map_heap_memory = ++p; -+#else /* STAGING_CSMT */ -+ resource->heap_memory = ++p; + void shader_cleanup(struct wined3d_shader *shader) DECLSPEC_HIDDEN; +#endif /* STAGING_CSMT */ - return TRUE; - } -@@ -421,7 +435,11 @@ - return ret; - } + static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg) + { +diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c +--- a/dlls/winex11.drv/opengl.c ++++ b/dlls/winex11.drv/opengl.c +@@ -1980,7 +1980,9 @@ + escape.code = X11DRV_FLUSH_GL_DRAWABLE; + escape.gl_drawable = 0; +#if defined(STAGING_CSMT) - static GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) -+#else /* STAGING_CSMT */ -+GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) + ERR("glFinish\n"); +#endif /* STAGING_CSMT */ - { - if (d3d_flags & WINED3D_MAP_READONLY) - return GL_READ_ONLY_ARB; -@@ -462,6 +480,7 @@ - else - resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB; - } -+#if defined(STAGING_CSMT) - - void wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch, - UINT *slice_pitch) -@@ -1040,3 +1059,4 @@ + if ((gl = get_gl_drawable( WindowFromDC( ctx->hdc ), 0 ))) + { + switch (gl->type) +@@ -2006,7 +2008,9 @@ + escape.code = X11DRV_FLUSH_GL_DRAWABLE; + escape.gl_drawable = 0; - wined3d_resource_invalidate_location(resource, ~resource->map_binding); - } ++#if defined(STAGING_CSMT) + ERR("glFlush\n"); +#endif /* STAGING_CSMT */ + if ((gl = get_gl_drawable( WindowFromDC( ctx->hdc ), 0 ))) + { + switch (gl->type) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-Multisampling/0001-wined3d-Allow-to-specify-multisampling-AA-quality-le.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-Multisampling/0001-wined3d-Allow-to-specify-multisampling-AA-quality-le.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-Multisampling/0001-wined3d-Allow-to-specify-multisampling-AA-quality-le.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-Multisampling/0001-wined3d-Allow-to-specify-multisampling-AA-quality-le.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -From 20c5727bab6314d9d788f5b782cf8f5d1b6fc281 Mon Sep 17 00:00:00 2001 -From: Austin English -Date: Sat, 28 Feb 2015 00:34:07 +0100 -Subject: wined3d: Allow to specify multisampling AA quality levels via - registry. - ---- - dlls/wined3d/directx.c | 7 ++++++- - dlls/wined3d/wined3d_main.c | 12 ++++++++++++ - dlls/wined3d/wined3d_private.h | 1 + - 3 files changed, 19 insertions(+), 1 deletion(-) - -diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c -index 019b415..b9eb03c 100644 ---- a/dlls/wined3d/directx.c -+++ b/dlls/wined3d/directx.c -@@ -4404,7 +4404,12 @@ HRESULT CDECL wined3d_check_device_multisample_type(const struct wined3d *wined3 - - if (quality_levels) - { -- if (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE) -+ if (wined3d_settings.msaa_quality_levels) -+ { -+ *quality_levels = wined3d_settings.msaa_quality_levels; -+ TRACE("Overriding MSAA quality levels to %i\n", *quality_levels); -+ } -+ else if (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE) - *quality_levels = gl_info->limits.samples; - else - *quality_levels = 1; -diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c -index 0543d97..c985c2d 100644 ---- a/dlls/wined3d/wined3d_main.c -+++ b/dlls/wined3d/wined3d_main.c -@@ -77,6 +77,7 @@ struct wined3d_settings wined3d_settings = - ORM_FBO, /* Use FBOs to do offscreen rendering */ - PCI_VENDOR_NONE,/* PCI Vendor ID */ - PCI_DEVICE_NONE,/* PCI Device ID */ -+ 0, /* Multisampling AA Quality Levels */ - 0, /* The default of memory is set in init_driver_info */ - NULL, /* No wine logo by default */ - TRUE, /* Multisampling enabled by default. */ -@@ -261,6 +262,17 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) - wined3d_settings.pci_vendor_id = pci_vendor_id; - } - } -+ if (!get_config_key( hkey, appkey, "MultisamplingAAQualityLevels", buffer, size )) -+ { -+ int quality_levels = atoi(buffer); -+ if(quality_levels > 0) -+ { -+ wined3d_settings.msaa_quality_levels = quality_levels; -+ TRACE("Setting MultisamplingAAQualityLevels to %i\n", quality_levels); -+ } -+ else -+ ERR("MultisamplingAAQualityLevels is %i but must be >0\n", quality_levels); -+ } - if ( !get_config_key( hkey, appkey, "VideoMemorySize", buffer, size) ) - { - int TmpVideoMemorySize = atoi(buffer); -diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 7847557..9e39dd7 100644 ---- a/dlls/wined3d/wined3d_private.h -+++ b/dlls/wined3d/wined3d_private.h -@@ -268,6 +268,7 @@ struct wined3d_settings - unsigned short pci_vendor_id; - unsigned short pci_device_id; - /* Memory tracking and object counting. */ -+ unsigned int msaa_quality_levels; - UINT64 emulated_textureram; - char *logo; - int allow_multisampling; --- -2.5.0 - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-Multisampling/definition wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-Multisampling/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-Multisampling/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-Multisampling/definition 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -Fixes: [12652] Allow to override number of quality levels for D3DMULTISAMPLE_NONMASKABLE. -Category: stable diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-resource_map/0001-wined3d-Rename-wined3d_resource_-un-map-to-wined3d_r.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-resource_map/0001-wined3d-Rename-wined3d_resource_-un-map-to-wined3d_r.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-resource_map/0001-wined3d-Rename-wined3d_resource_-un-map-to-wined3d_r.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-resource_map/0001-wined3d-Rename-wined3d_resource_-un-map-to-wined3d_r.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,287 @@ +From 93ac240a91cc8c02bafe7207ffdb64fe9f9945f9 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 4 Nov 2015 19:31:30 +0100 +Subject: wined3d: Rename wined3d_resource_(un)map to + wined3d_resource_sub_resource_(un)map. + +To avoid name conflicts in the CSMT patchset. +--- + dlls/d3d11/device.c | 4 ++-- + dlls/d3d11/texture.c | 8 ++++---- + dlls/d3d8/surface.c | 4 ++-- + dlls/d3d8/volume.c | 4 ++-- + dlls/d3d9/surface.c | 4 ++-- + dlls/d3d9/volume.c | 4 ++-- + dlls/ddraw/surface.c | 14 +++++++------- + dlls/wined3d/resource.c | 4 ++-- + dlls/wined3d/wined3d.spec | 4 ++-- + include/wine/wined3d.h | 6 +++--- + 10 files changed, 28 insertions(+), 28 deletions(-) + +diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c +index fb308d0..9658c21 100644 +--- a/dlls/d3d11/device.c ++++ b/dlls/d3d11/device.c +@@ -267,7 +267,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_immediate_context_Map(ID3D11DeviceContext + wined3d_resource = wined3d_resource_from_d3d11_resource(resource); + + wined3d_mutex_lock(); +- hr = wined3d_resource_map(wined3d_resource, subresource_idx, ++ hr = wined3d_resource_sub_resource_map(wined3d_resource, subresource_idx, + &map_desc, NULL, wined3d_map_flags_from_d3d11_map_type(map_type)); + wined3d_mutex_unlock(); + +@@ -288,7 +288,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_Unmap(ID3D11DeviceContext + wined3d_resource = wined3d_resource_from_d3d11_resource(resource); + + wined3d_mutex_lock(); +- wined3d_resource_unmap(wined3d_resource, subresource_idx); ++ wined3d_resource_sub_resource_unmap(wined3d_resource, subresource_idx); + wined3d_mutex_unlock(); + } + +diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c +index 11bda45..e24f945 100644 +--- a/dlls/d3d11/texture.c ++++ b/dlls/d3d11/texture.c +@@ -366,7 +366,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_texture2d_Map(ID3D10Texture2D *iface, UIN + FIXME("Ignoring map_flags %#x.\n", map_flags); + + wined3d_mutex_lock(); +- if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx, ++ if (SUCCEEDED(hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx, + &wined3d_map_desc, NULL, wined3d_map_flags_from_d3d11_map_type(map_type)))) + { + mapped_texture->pData = wined3d_map_desc.data; +@@ -384,7 +384,7 @@ static void STDMETHODCALLTYPE d3d10_texture2d_Unmap(ID3D10Texture2D *iface, UINT + TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx); + + wined3d_mutex_lock(); +- wined3d_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx); ++ wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx); + wined3d_mutex_unlock(); + } + +@@ -825,7 +825,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_texture3d_Map(ID3D10Texture3D *iface, UIN + FIXME("Ignoring map_flags %#x.\n", map_flags); + + wined3d_mutex_lock(); +- if (SUCCEEDED(hr = wined3d_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx, ++ if (SUCCEEDED(hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx, + &wined3d_map_desc, NULL, wined3d_map_flags_from_d3d11_map_type(map_type)))) + { + mapped_texture->pData = wined3d_map_desc.data; +@@ -844,7 +844,7 @@ static void STDMETHODCALLTYPE d3d10_texture3d_Unmap(ID3D10Texture3D *iface, UINT + TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx); + + wined3d_mutex_lock(); +- wined3d_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx); ++ wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(texture->wined3d_texture), sub_resource_idx); + wined3d_mutex_unlock(); + } + +diff --git a/dlls/d3d8/surface.c b/dlls/d3d8/surface.c +index ec263b1..5100101 100644 +--- a/dlls/d3d8/surface.c ++++ b/dlls/d3d8/surface.c +@@ -244,7 +244,7 @@ static HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface, + box.back = 1; + } + +- hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, ++ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, + &map_desc, rect ? &box : NULL, flags); + wined3d_mutex_unlock(); + +@@ -270,7 +270,7 @@ static HRESULT WINAPI d3d8_surface_UnlockRect(IDirect3DSurface8 *iface) + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); +- hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); ++ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); + wined3d_mutex_unlock(); + + switch(hr) +diff --git a/dlls/d3d8/volume.c b/dlls/d3d8/volume.c +index f26e424..d1ee0b5 100644 +--- a/dlls/d3d8/volume.c ++++ b/dlls/d3d8/volume.c +@@ -148,7 +148,7 @@ static HRESULT WINAPI d3d8_volume_LockBox(IDirect3DVolume8 *iface, + iface, locked_box, box, flags); + + wined3d_mutex_lock(); +- hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, ++ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, + &map_desc, (const struct wined3d_box *)box, flags); + wined3d_mutex_unlock(); + +@@ -167,7 +167,7 @@ static HRESULT WINAPI d3d8_volume_UnlockBox(IDirect3DVolume8 *iface) + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); +- hr = wined3d_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); ++ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); + wined3d_mutex_unlock(); + + return hr; +diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c +index c3032dc..120f5c9 100644 +--- a/dlls/d3d9/surface.c ++++ b/dlls/d3d9/surface.c +@@ -251,7 +251,7 @@ static HRESULT WINAPI d3d9_surface_LockRect(IDirect3DSurface9 *iface, + } + + wined3d_mutex_lock(); +- hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, ++ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx, + &map_desc, rect ? &box : NULL, flags); + wined3d_mutex_unlock(); + +@@ -272,7 +272,7 @@ static HRESULT WINAPI d3d9_surface_UnlockRect(IDirect3DSurface9 *iface) + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); +- hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); ++ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); + wined3d_mutex_unlock(); + + switch(hr) +diff --git a/dlls/d3d9/volume.c b/dlls/d3d9/volume.c +index 52502bf..a81b6c7 100644 +--- a/dlls/d3d9/volume.c ++++ b/dlls/d3d9/volume.c +@@ -148,7 +148,7 @@ static HRESULT WINAPI d3d9_volume_LockBox(IDirect3DVolume9 *iface, + iface, locked_box, box, flags); + + wined3d_mutex_lock(); +- hr = wined3d_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, ++ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx, + &map_desc, (const struct wined3d_box *)box, flags); + wined3d_mutex_unlock(); + +@@ -167,7 +167,7 @@ static HRESULT WINAPI d3d9_volume_UnlockBox(IDirect3DVolume9 *iface) + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); +- hr = wined3d_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); ++ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(volume->wined3d_texture), volume->sub_resource_idx); + wined3d_mutex_unlock(); + + return hr; +diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c +index 923a935..409fa32 100644 +--- a/dlls/ddraw/surface.c ++++ b/dlls/ddraw/surface.c +@@ -984,7 +984,7 @@ static HRESULT surface_lock(struct ddraw_surface *surface, + if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE); + if (SUCCEEDED(hr)) +- hr = wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), ++ hr = wined3d_resource_sub_resource_map(wined3d_texture_get_resource(surface->wined3d_texture), + surface->sub_resource_idx, &map_desc, rect ? &box : NULL, flags); + if (FAILED(hr)) + { +@@ -1159,7 +1159,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Unlock(IDirectDrawSurface + TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(pRect)); + + wined3d_mutex_lock(); +- hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); ++ hr = wined3d_resource_sub_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); + if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE); + wined3d_mutex_unlock(); +@@ -5134,7 +5134,7 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu + DDCKEY_SRCBLT, &src_desc->ddckCKSrcBlt); + } + +- if (FAILED(hr = wined3d_resource_map(src_resource, ++ if (FAILED(hr = wined3d_resource_sub_resource_map(src_resource, + src_surface->sub_resource_idx, &src_map_desc, NULL, 0))) + { + ERR("Failed to lock source surface, hr %#x.\n", hr); +@@ -5142,11 +5142,11 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu + return D3DERR_TEXTURE_LOAD_FAILED; + } + +- if (FAILED(hr = wined3d_resource_map(dst_resource, ++ if (FAILED(hr = wined3d_resource_sub_resource_map(dst_resource, + dst_surface->sub_resource_idx, &dst_map_desc, NULL, 0))) + { + ERR("Failed to lock destination surface, hr %#x.\n", hr); +- wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx); ++ wined3d_resource_sub_resource_unmap(src_resource, src_surface->sub_resource_idx); + wined3d_mutex_unlock(); + return D3DERR_TEXTURE_LOAD_FAILED; + } +@@ -5156,8 +5156,8 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu + else + memcpy(dst_map_desc.data, src_map_desc.data, src_map_desc.row_pitch * src_desc->dwHeight); + +- wined3d_resource_unmap(dst_resource, dst_surface->sub_resource_idx); +- wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx); ++ wined3d_resource_sub_resource_unmap(dst_resource, dst_surface->sub_resource_idx); ++ wined3d_resource_sub_resource_unmap(src_resource, src_surface->sub_resource_idx); + } + + if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) +diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c +index a4936cf..44cdb43 100644 +--- a/dlls/wined3d/resource.c ++++ b/dlls/wined3d/resource.c +@@ -305,7 +305,7 @@ void CDECL wined3d_resource_get_desc(const struct wined3d_resource *resource, st + desc->size = resource->size; + } + +-HRESULT CDECL wined3d_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, ++HRESULT CDECL wined3d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags) + { + TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %s, flags %#x.\n", +@@ -314,7 +314,7 @@ HRESULT CDECL wined3d_resource_map(struct wined3d_resource *resource, unsigned i + return resource->resource_ops->resource_sub_resource_map(resource, sub_resource_idx, map_desc, box, flags); + } + +-HRESULT CDECL wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) ++HRESULT CDECL wined3d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx) + { + TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx); + +diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec +index aa468d1..9d451a1 100644 +--- a/dlls/wined3d/wined3d.spec ++++ b/dlls/wined3d/wined3d.spec +@@ -182,10 +182,10 @@ + @ cdecl wined3d_resource_get_desc(ptr ptr) + @ cdecl wined3d_resource_get_parent(ptr) + @ cdecl wined3d_resource_get_priority(ptr) +-@ cdecl wined3d_resource_map(ptr long ptr ptr long) + @ cdecl wined3d_resource_set_parent(ptr ptr) + @ cdecl wined3d_resource_set_priority(ptr long) +-@ cdecl wined3d_resource_unmap(ptr long) ++@ cdecl wined3d_resource_sub_resource_map(ptr long ptr ptr long) ++@ cdecl wined3d_resource_sub_resource_unmap(ptr long) + + @ cdecl wined3d_rendertarget_view_create(ptr ptr ptr ptr ptr) + @ cdecl wined3d_rendertarget_view_create_from_sub_resource(ptr long ptr ptr ptr) +diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h +index 507d63f..50d3213 100644 +--- a/include/wine/wined3d.h ++++ b/include/wine/wined3d.h +@@ -2421,11 +2421,11 @@ void __cdecl wined3d_resource_get_desc(const struct wined3d_resource *resource, + struct wined3d_resource_desc *desc); + void * __cdecl wined3d_resource_get_parent(const struct wined3d_resource *resource); + DWORD __cdecl wined3d_resource_get_priority(const struct wined3d_resource *resource); +-HRESULT __cdecl wined3d_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, +- struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); + void __cdecl wined3d_resource_set_parent(struct wined3d_resource *resource, void *parent); + DWORD __cdecl wined3d_resource_set_priority(struct wined3d_resource *resource, DWORD priority); +-HRESULT __cdecl wined3d_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx); ++HRESULT __cdecl wined3d_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, ++ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags); ++HRESULT __cdecl wined3d_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx); + + HRESULT __cdecl wined3d_rendertarget_view_create(const struct wined3d_rendertarget_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-Revert_PixelFormat/0002-Revert-wined3d-Track-if-a-context-s-private-hdc-has-.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-Revert_PixelFormat/0002-Revert-wined3d-Track-if-a-context-s-private-hdc-has-.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-Revert_PixelFormat/0002-Revert-wined3d-Track-if-a-context-s-private-hdc-has-.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-Revert_PixelFormat/0002-Revert-wined3d-Track-if-a-context-s-private-hdc-has-.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 864636075386f9057b53c8e076978d95dd782360 Mon Sep 17 00:00:00 2001 +From 5b04c29a2a330612a11d53e72d32487315efb085 Mon Sep 17 00:00:00 2001 From: Ken Thomases Date: Sun, 14 Sep 2014 19:46:53 -0500 Subject: Revert "wined3d: Track if a context's private hdc has had its pixel @@ -11,10 +11,10 @@ 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c -index d3f7629..11c8804 100644 +index d83cad5..c11dd08 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c -@@ -800,13 +800,9 @@ static BOOL context_restore_pixel_format(struct wined3d_context *ctx) +@@ -815,13 +815,9 @@ static BOOL context_restore_pixel_format(struct wined3d_context *ctx) static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BOOL private, int format) { const struct wined3d_gl_info *gl_info = context->gl_info; @@ -30,7 +30,7 @@ if (!current) { -@@ -820,7 +816,7 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO +@@ -835,7 +831,7 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO context->restore_pf = 0; context->restore_pf_win = private ? NULL : WindowFromDC(dc); @@ -39,7 +39,7 @@ } /* By default WGL doesn't allow pixel format adjustments but we need it -@@ -847,7 +843,7 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO +@@ -862,7 +858,7 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO context->restore_pf_win = win; } @@ -48,7 +48,7 @@ } /* OpenGL doesn't allow pixel format adjustments. Print an error and -@@ -857,11 +853,6 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO +@@ -872,11 +868,6 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO ERR("Unable to set pixel format %d on device context %p. Already using format %d.\n", format, dc, current); return TRUE; @@ -60,7 +60,7 @@ } static BOOL context_set_gl_context(struct wined3d_context *ctx) -@@ -947,7 +938,6 @@ static void context_update_window(struct wined3d_context *context) +@@ -962,7 +953,6 @@ static void context_update_window(struct wined3d_context *context) context->win_handle = context->swapchain->win_handle; context->hdc_is_private = FALSE; @@ -68,7 +68,7 @@ context->needs_set = 1; context->valid = 1; -@@ -1189,8 +1179,7 @@ static void context_enter(struct wined3d_context *context) +@@ -1223,8 +1213,7 @@ static void context_enter(struct wined3d_context *context) context->restore_dc = wglGetCurrentDC(); context->needs_set = 1; } @@ -78,7 +78,7 @@ context->needs_set = 1; } } -@@ -1598,7 +1587,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, +@@ -1662,7 +1651,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, ret->win_handle = swapchain->win_handle; ret->hdc = hdc; ret->hdc_is_private = hdc_is_private; @@ -87,20 +87,20 @@ ret->needs_set = 1; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 4373805..d98fcae 100644 +index 288d683..d5a881f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -1158,9 +1158,8 @@ struct wined3d_context +@@ -1196,9 +1196,8 @@ struct wined3d_context DWORD rebind_fbo : 1; DWORD needs_set : 1; DWORD hdc_is_private : 1; - DWORD hdc_has_format : 1; /* only meaningful if hdc_is_private */ DWORD update_shader_resource_bindings : 1; -- DWORD padding : 15; -+ DWORD padding : 16; +- DWORD padding : 14; ++ DWORD padding : 15; DWORD shader_update_mask; DWORD constant_update_mask; DWORD numbered_array_mask; -- -2.2.1 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-Revert_PixelFormat/0003-Revert-wined3d-Track-if-a-context-s-hdc-is-private-s.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-Revert_PixelFormat/0003-Revert-wined3d-Track-if-a-context-s-hdc-is-private-s.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wined3d-Revert_PixelFormat/0003-Revert-wined3d-Track-if-a-context-s-hdc-is-private-s.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wined3d-Revert_PixelFormat/0003-Revert-wined3d-Track-if-a-context-s-hdc-is-private-s.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From cb2d95c1590eb4e9e8eb18ad81297d30dc8b9f85 Mon Sep 17 00:00:00 2001 +From 8e605496655d72d832a822ba6adc77fdc2540216 Mon Sep 17 00:00:00 2001 From: Ken Thomases Date: Sun, 14 Sep 2014 19:47:03 -0500 Subject: Revert "wined3d: Track if a context's hdc is private so we never need @@ -11,10 +11,10 @@ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c -index 40b5ef1..0e3d539 100644 +index cfd6ec6..ed14aa4 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c -@@ -797,7 +797,7 @@ static BOOL context_restore_pixel_format(struct wined3d_context *ctx) +@@ -812,7 +812,7 @@ static BOOL context_restore_pixel_format(struct wined3d_context *ctx) return ret; } @@ -23,7 +23,7 @@ { const struct wined3d_gl_info *gl_info = context->gl_info; int current = GetPixelFormat(dc); -@@ -815,7 +815,7 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO +@@ -830,7 +830,7 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO } context->restore_pf = 0; @@ -32,7 +32,7 @@ return TRUE; } -@@ -834,12 +834,12 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO +@@ -849,12 +849,12 @@ static BOOL context_set_pixel_format(struct wined3d_context *context, HDC dc, BO return FALSE; } @@ -47,7 +47,7 @@ context->restore_pf_win = win; } -@@ -860,7 +860,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx) +@@ -875,7 +875,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx) struct wined3d_swapchain *swapchain = ctx->swapchain; BOOL backup = FALSE; @@ -56,7 +56,7 @@ { WARN("Failed to set pixel format %d on device context %p.\n", ctx->pixel_format, ctx->hdc); -@@ -893,7 +893,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx) +@@ -908,7 +908,7 @@ static BOOL context_set_gl_context(struct wined3d_context *ctx) return FALSE; } @@ -65,7 +65,7 @@ { ERR("Failed to set pixel format %d on device context %p.\n", ctx->pixel_format, dc); -@@ -937,7 +937,6 @@ static void context_update_window(struct wined3d_context *context) +@@ -952,7 +952,6 @@ static void context_update_window(struct wined3d_context *context) wined3d_release_dc(context->win_handle, context->hdc); context->win_handle = context->swapchain->win_handle; @@ -73,15 +73,15 @@ context->needs_set = 1; context->valid = 1; -@@ -1388,7 +1387,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, +@@ -1446,7 +1445,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, int swap_interval; DWORD state; - HDC hdc; + HDC hdc = 0; - BOOL hdc_is_private = FALSE; TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle); -@@ -1456,9 +1454,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, +@@ -1519,9 +1517,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, { WARN("Failed to retrieve device context, trying swapchain backup.\n"); @@ -92,7 +92,7 @@ { ERR("Failed to retrieve a device context.\n"); goto out; -@@ -1509,7 +1505,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, +@@ -1587,7 +1583,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, ret->gl_info = gl_info; @@ -101,7 +101,7 @@ { ERR("Failed to set pixel format %d on device context %p.\n", pixel_format, hdc); context_release(ret); -@@ -1586,7 +1582,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, +@@ -1650,7 +1646,6 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, ret->glCtx = ctx; ret->win_handle = swapchain->win_handle; ret->hdc = hdc; @@ -110,20 +110,20 @@ ret->needs_set = 1; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index 0b9b767..926f1dc 100644 +index a5e7167..00ecbc4 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -1159,9 +1159,8 @@ struct wined3d_context - DWORD lowest_disabled_stage : 4; /* Max MAX_TEXTURES, 8 */ +@@ -1218,9 +1218,8 @@ struct wined3d_context + DWORD use_immediate_mode_draw : 1; DWORD rebind_fbo : 1; DWORD needs_set : 1; - DWORD hdc_is_private : 1; DWORD update_shader_resource_bindings : 1; -- DWORD padding : 16; -+ DWORD padding : 17; +- DWORD padding : 15; ++ DWORD padding : 16; DWORD shader_update_mask; DWORD constant_update_mask; DWORD numbered_array_mask; -- -2.3.1 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wpcap-Dynamic_Linking/0001-wpcap-Load-libpcap-dynamically.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wpcap-Dynamic_Linking/0001-wpcap-Load-libpcap-dynamically.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wpcap-Dynamic_Linking/0001-wpcap-Load-libpcap-dynamically.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wpcap-Dynamic_Linking/0001-wpcap-Load-libpcap-dynamically.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 811b0381cc2979ba6dee508e0f497e50d2ed499d Mon Sep 17 00:00:00 2001 +From 09e0c732f3c13f7ac1ba8c40e918092c642051a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hentschel?= Date: Tue, 26 Aug 2014 00:59:37 +0200 Subject: wpcap: Load libpcap dynamically. @@ -8,14 +8,14 @@ --- configure.ac | 6 +- dlls/wpcap/Makefile.in | 1 - - dlls/wpcap/wpcap.c | 163 +++++++++++++++++++++++++++++++++++++++---------- - 3 files changed, 134 insertions(+), 36 deletions(-) + dlls/wpcap/wpcap.c | 171 +++++++++++++++++++++++++++++++++++++++---------- + 3 files changed, 140 insertions(+), 38 deletions(-) diff --git a/configure.ac b/configure.ac -index aec53f6..58112de 100644 +index 811e2aa..30b500a 100644 --- a/configure.ac +++ b/configure.ac -@@ -1288,11 +1288,11 @@ test "x$ac_cv_lib_OpenCL_clGetPlatformInfo" != xyes && enable_opencl=${enable_op +@@ -1182,11 +1182,11 @@ test "x$ac_cv_lib_OpenCL_clGetPlatformInfo" != xyes && enable_opencl=${enable_op dnl **** Check for libpcap **** if test "$ac_cv_header_pcap_pcap_h" = "yes" then @@ -31,7 +31,7 @@ dnl **** Check for libxml2 **** diff --git a/dlls/wpcap/Makefile.in b/dlls/wpcap/Makefile.in -index e44613f..aeef71a 100644 +index 91b4a95..aeef71a 100644 --- a/dlls/wpcap/Makefile.in +++ b/dlls/wpcap/Makefile.in @@ -1,6 +1,5 @@ @@ -42,7 +42,7 @@ C_SRCS = \ wpcap.c diff --git a/dlls/wpcap/wpcap.c b/dlls/wpcap/wpcap.c -index ae9e482..3e5c82b 100644 +index 44e8c2a..f9029c8 100644 --- a/dlls/wpcap/wpcap.c +++ b/dlls/wpcap/wpcap.c @@ -18,6 +18,9 @@ @@ -55,7 +55,7 @@ #include #include "winsock2.h" #include "windef.h" -@@ -40,47 +43,124 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); +@@ -40,47 +43,128 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); #define PCAP_SRC_IFLOCAL 3 #endif @@ -67,6 +67,8 @@ +static const char* (*ppcap_datalink_val_to_description)(int); +static const char* (*ppcap_datalink_val_to_name)(int); +static int (*ppcap_dispatch)(pcap_t *, int, pcap_handler, u_char *); ++static void (*ppcap_dump)(u_char *, const struct pcap_pkthdr *, const u_char *); ++static pcap_dumper_t* (*ppcap_dump_open)(pcap_t *, const char *); +static int (*ppcap_findalldevs)(pcap_if_t **, char *); +static void (*ppcap_freealldevs)(pcap_if_t *); +static void (*ppcap_freecode)(struct bpf_program *); @@ -110,6 +112,8 @@ + LOAD_FUNCPTR(pcap_datalink_val_to_description); + LOAD_FUNCPTR(pcap_datalink_val_to_name); + LOAD_FUNCPTR(pcap_dispatch); ++ LOAD_FUNCPTR(pcap_dump); ++ LOAD_FUNCPTR(pcap_dump_open); + LOAD_FUNCPTR(pcap_findalldevs); + LOAD_FUNCPTR(pcap_freealldevs); + LOAD_FUNCPTR(pcap_freecode); @@ -187,12 +191,14 @@ } typedef struct -@@ -111,10 +191,10 @@ int CDECL wine_pcap_dispatch(pcap_t *p, int cnt, +@@ -112,12 +196,12 @@ int CDECL wine_pcap_dispatch(pcap_t *p, int cnt, pcb = HeapAlloc(GetProcessHeap(), 0, sizeof(PCAP_HANDLER_CALLBACK)); pcb->pfn_cb = callback; pcb->user_data = user; -- return pcap_dispatch(p, cnt, pcap_handler_callback, (unsigned char*)pcb); -+ return ppcap_dispatch(p, cnt, pcap_handler_callback, (unsigned char*)pcb); +- res = pcap_dispatch(p, cnt, pcap_handler_callback, (unsigned char *)pcb); ++ res = ppcap_dispatch(p, cnt, pcap_handler_callback, (unsigned char *)pcb); + HeapFree(GetProcessHeap(), 0, pcb); + return res; } - return pcap_dispatch(p, cnt, NULL, user); @@ -200,7 +206,7 @@ } int CDECL wine_pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) -@@ -122,7 +202,7 @@ int CDECL wine_pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) +@@ -125,7 +209,7 @@ int CDECL wine_pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) int ret; TRACE("(%p %p)\n", alldevsp, errbuf); @@ -209,7 +215,7 @@ if(alldevsp && !*alldevsp) ERR_(winediag)("Failed to access raw network (pcap), this requires special permissions.\n"); -@@ -138,13 +218,13 @@ int CDECL wine_pcap_findalldevs_ex(char *source, void *auth, pcap_if_t **alldevs +@@ -141,13 +225,13 @@ int CDECL wine_pcap_findalldevs_ex(char *source, void *auth, pcap_if_t **alldevs void CDECL wine_pcap_freealldevs(pcap_if_t *alldevs) { TRACE("(%p)\n", alldevs); @@ -225,7 +231,7 @@ } typedef struct _AirpcapHandle *PAirpcapHandle; -@@ -157,18 +237,18 @@ PAirpcapHandle CDECL wine_pcap_get_airpcap_handle(pcap_t *p) +@@ -160,18 +244,18 @@ PAirpcapHandle CDECL wine_pcap_get_airpcap_handle(pcap_t *p) char* CDECL wine_pcap_geterr(pcap_t *p) { TRACE("(%p)\n", p); @@ -247,7 +253,7 @@ TRACE("%s\n", debugstr_a(ret)); return ret; } -@@ -176,20 +256,20 @@ const char* CDECL wine_pcap_lib_version(void) +@@ -179,20 +263,20 @@ const char* CDECL wine_pcap_lib_version(void) int CDECL wine_pcap_list_datalinks(pcap_t *p, int **dlt_buffer) { TRACE("(%p %p)\n", p, dlt_buffer); @@ -271,12 +277,14 @@ } int CDECL wine_pcap_loop(pcap_t *p, int cnt, -@@ -204,34 +284,34 @@ int CDECL wine_pcap_loop(pcap_t *p, int cnt, +@@ -209,36 +293,36 @@ int CDECL wine_pcap_loop(pcap_t *p, int cnt, pcb = HeapAlloc(GetProcessHeap(), 0, sizeof(PCAP_HANDLER_CALLBACK)); pcb->pfn_cb = callback; pcb->user_data = user; -- return pcap_loop(p, cnt, pcap_handler_callback, (unsigned char*)pcb); -+ return ppcap_loop(p, cnt, pcap_handler_callback, (unsigned char*)pcb); +- res = pcap_loop(p, cnt, pcap_handler_callback, (unsigned char *)pcb); ++ res = ppcap_loop(p, cnt, pcap_handler_callback, (unsigned char *)pcb); + HeapFree(GetProcessHeap(), 0, pcb); + return res; } - return pcap_loop(p, cnt, NULL, user); @@ -312,7 +320,7 @@ } #define PCAP_OPENFLAG_PROMISCUOUS 1 -@@ -242,14 +322,14 @@ pcap_t* CDECL wine_pcap_open(const char *source, int snaplen, int flags, int rea +@@ -249,14 +333,14 @@ pcap_t* CDECL wine_pcap_open(const char *source, int snaplen, int flags, int rea int promisc = flags & PCAP_OPENFLAG_PROMISCUOUS; FIXME("(%s %i %i %i %p %p): partial stub\n", debugstr_a(source), snaplen, flags, read_timeout, auth, errbuf); @@ -329,7 +337,7 @@ } int CDECL wine_pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf) -@@ -293,13 +373,13 @@ int CDECL wine_pcap_parsesrcstr(const char *source, int *type, char *host, char +@@ -300,13 +384,13 @@ int CDECL wine_pcap_parsesrcstr(const char *source, int *type, char *host, char int CDECL wine_pcap_sendpacket(pcap_t *p, const unsigned char *buf, int size) { TRACE("(%p %p %i)\n", p, buf, size); @@ -345,7 +353,7 @@ } int CDECL wine_pcap_setbuff(pcap_t * p, int dim) -@@ -311,25 +391,25 @@ int CDECL wine_pcap_setbuff(pcap_t * p, int dim) +@@ -318,25 +402,25 @@ int CDECL wine_pcap_setbuff(pcap_t * p, int dim) int CDECL wine_pcap_setfilter(pcap_t *p, struct bpf_program *fp) { TRACE("(%p %p)\n", p, fp); @@ -375,10 +383,19 @@ } int CDECL wine_wsockinit(void) -@@ -339,3 +419,22 @@ int CDECL wine_wsockinit(void) - if (WSAStartup(MAKEWORD(1,1), &wsadata)) return -1; - return 0; +@@ -349,10 +433,29 @@ int CDECL wine_wsockinit(void) + + pcap_dumper_t* CDECL wine_pcap_dump_open(pcap_t *p, const char *fname) + { +- return pcap_dump_open(p, fname); ++ return ppcap_dump_open(p, fname); } + + void CDECL wine_pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) + { +- return pcap_dump(user, h, sp); ++ return ppcap_dump(user, h, sp); ++} + +BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ @@ -397,7 +414,7 @@ + } + + return TRUE; -+} + } -- -2.5.0 +2.6.4 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wpcap-Dynamic_Linking/definition wine-staging-1.9.3~ubuntu12.04.1/patches/wpcap-Dynamic_Linking/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/wpcap-Dynamic_Linking/definition 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wpcap-Dynamic_Linking/definition 2016-02-08 20:07:32.000000000 +0000 @@ -1 +1 @@ -Category: stable +Depends: wpcap-Several_Fixes diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wpcap-Several_Fixes/0001-wpcap-Implement-pcap_dump_open-and-pcap_dump.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wpcap-Several_Fixes/0001-wpcap-Implement-pcap_dump_open-and-pcap_dump.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wpcap-Several_Fixes/0001-wpcap-Implement-pcap_dump_open-and-pcap_dump.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wpcap-Several_Fixes/0001-wpcap-Implement-pcap_dump_open-and-pcap_dump.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,51 @@ +From 9e5dd79c03afddd6a3d327b33cef358b849e891d Mon Sep 17 00:00:00 2001 +From: Jianqiu Zhang +Date: Thu, 7 Jan 2016 16:33:34 +0800 +Subject: wpcap: Implement pcap_dump_open and pcap_dump + +Signed-off-by: Jianqiu Zhang +--- + dlls/wpcap/wpcap.c | 10 ++++++++++ + dlls/wpcap/wpcap.spec | 4 ++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/dlls/wpcap/wpcap.c b/dlls/wpcap/wpcap.c +index ae9e482..da911c7 100644 +--- a/dlls/wpcap/wpcap.c ++++ b/dlls/wpcap/wpcap.c +@@ -339,3 +339,13 @@ int CDECL wine_wsockinit(void) + if (WSAStartup(MAKEWORD(1,1), &wsadata)) return -1; + return 0; + } ++ ++pcap_dumper_t* CDECL wine_pcap_dump_open(pcap_t *p, const char *fname) ++{ ++ return pcap_dump_open(p, fname); ++} ++ ++void CDECL wine_pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) ++{ ++ return pcap_dump(user, h, sp); ++} +diff --git a/dlls/wpcap/wpcap.spec b/dlls/wpcap/wpcap.spec +index 0e1e208..cf2ed43 100644 +--- a/dlls/wpcap/wpcap.spec ++++ b/dlls/wpcap/wpcap.spec +@@ -16,12 +16,12 @@ + @ cdecl pcap_datalink_val_to_description(long) wine_pcap_datalink_val_to_description + @ cdecl pcap_datalink_val_to_name(long) wine_pcap_datalink_val_to_name + @ cdecl pcap_dispatch(ptr long ptr ptr) wine_pcap_dispatch +-@ stub pcap_dump ++@ cdecl pcap_dump(ptr ptr str) wine_pcap_dump + @ stub pcap_dump_close + @ stub pcap_dump_file + @ stub pcap_dump_flush + @ stub pcap_dump_ftell +-@ stub pcap_dump_open ++@ cdecl pcap_dump_open(ptr str) wine_pcap_dump_open + @ stub pcap_file + @ stub pcap_fileno + @ cdecl pcap_findalldevs(ptr ptr) wine_pcap_findalldevs +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wpcap-Several_Fixes/0002-wpcap-Fix-crash-on-pcap_loop.patch wine-staging-1.9.3~ubuntu12.04.1/patches/wpcap-Several_Fixes/0002-wpcap-Fix-crash-on-pcap_loop.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/wpcap-Several_Fixes/0002-wpcap-Fix-crash-on-pcap_loop.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wpcap-Several_Fixes/0002-wpcap-Fix-crash-on-pcap_loop.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,57 @@ +From b20a7a0ed29c40ad50c0e43b1f3d1cf3558f492e Mon Sep 17 00:00:00 2001 +From: Jianqiu Zhang +Date: Thu, 7 Jan 2016 16:34:17 +0800 +Subject: wpcap: Fix crash on pcap_loop + +Signed-off-by: Jianqiu Zhang +--- + dlls/wpcap/wpcap.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/dlls/wpcap/wpcap.c b/dlls/wpcap/wpcap.c +index da911c7..44e8c2a 100644 +--- a/dlls/wpcap/wpcap.c ++++ b/dlls/wpcap/wpcap.c +@@ -95,7 +95,6 @@ static void pcap_handler_callback(u_char *user_data, const struct pcap_pkthdr *h + TRACE("(%p %p %p)\n", user_data, h, p); + pcb = (PCAP_HANDLER_CALLBACK *)user_data; + pcb->pfn_cb(pcb->user_data, h, p); +- HeapFree(GetProcessHeap(), 0, pcb); + TRACE("Callback COMPLETED\n"); + } + +@@ -108,10 +107,14 @@ int CDECL wine_pcap_dispatch(pcap_t *p, int cnt, + if (callback) + { + PCAP_HANDLER_CALLBACK *pcb; ++ int res; ++ + pcb = HeapAlloc(GetProcessHeap(), 0, sizeof(PCAP_HANDLER_CALLBACK)); + pcb->pfn_cb = callback; + pcb->user_data = user; +- return pcap_dispatch(p, cnt, pcap_handler_callback, (unsigned char*)pcb); ++ res = pcap_dispatch(p, cnt, pcap_handler_callback, (unsigned char *)pcb); ++ HeapFree(GetProcessHeap(), 0, pcb); ++ return res; + } + + return pcap_dispatch(p, cnt, NULL, user); +@@ -201,10 +204,14 @@ int CDECL wine_pcap_loop(pcap_t *p, int cnt, + if (callback) + { + PCAP_HANDLER_CALLBACK *pcb; ++ int res; ++ + pcb = HeapAlloc(GetProcessHeap(), 0, sizeof(PCAP_HANDLER_CALLBACK)); + pcb->pfn_cb = callback; + pcb->user_data = user; +- return pcap_loop(p, cnt, pcap_handler_callback, (unsigned char*)pcb); ++ res = pcap_loop(p, cnt, pcap_handler_callback, (unsigned char *)pcb); ++ HeapFree(GetProcessHeap(), 0, pcb); ++ return res; + } + + return pcap_loop(p, cnt, NULL, user); +-- +2.6.4 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/wpcap-Several_Fixes/definition wine-staging-1.9.3~ubuntu12.04.1/patches/wpcap-Several_Fixes/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/wpcap-Several_Fixes/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/wpcap-Several_Fixes/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,2 @@ +Fixes: Implement pcap_dump_open and pcap_dump +Fixes: Fix possible crash in pcap_loop diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ws2_32-getsockopt/0001-ws2_32-Divide-values-returned-by-SO_RCVBUF-and-SO_SN.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ws2_32-getsockopt/0001-ws2_32-Divide-values-returned-by-SO_RCVBUF-and-SO_SN.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ws2_32-getsockopt/0001-ws2_32-Divide-values-returned-by-SO_RCVBUF-and-SO_SN.patch 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ws2_32-getsockopt/0001-ws2_32-Divide-values-returned-by-SO_RCVBUF-and-SO_SN.patch 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1,73 @@ +From 881b4446e9f6abc97ff6bead1bfba18b49a5acca Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Mon, 8 Feb 2016 02:31:00 +0100 +Subject: ws2_32: Divide values returned by SO_RCVBUF and SO_SNDBUF getsockopt + options by two. + +--- + dlls/ws2_32/socket.c | 8 ++++++++ + dlls/ws2_32/tests/sock.c | 22 ++++++++++++++++++++++ + 2 files changed, 30 insertions(+) + +diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c +index f62c9cd..e17b163 100644 +--- a/dlls/ws2_32/socket.c ++++ b/dlls/ws2_32/socket.c +@@ -3736,6 +3736,14 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, + SetLastError(wsaErrno()); + ret = SOCKET_ERROR; + } ++ #ifdef __linux__ ++ else if (optname == SO_RCVBUF || optname == SO_SNDBUF) ++ { ++ /* For SO_RCVBUF / SO_SNDBUF, the Linux kernel always sets twice the value. ++ * Divide by two to ensure applications do not get confused by the result. */ ++ *(int *)optval /= 2; ++ } ++ #endif + release_sock_fd( s, fd ); + return ret; + case WS_SO_ACCEPTCONN: +diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c +index aeb7a62..2e7ab20 100644 +--- a/dlls/ws2_32/tests/sock.c ++++ b/dlls/ws2_32/tests/sock.c +@@ -1328,6 +1328,7 @@ static void test_set_getsockopt(void) + WSAPROTOCOL_INFOA infoA; + WSAPROTOCOL_INFOW infoW; + char providername[WSAPROTOCOL_LEN + 1]; ++ DWORD value; + struct _prottest + { + int family, type, proto; +@@ -1371,6 +1372,27 @@ static void test_set_getsockopt(void) + err = getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, &size); + ok( !err, "get/setsockopt(SO_SNDTIMEO) failed error: %d\n", WSAGetLastError()); + ok( timeout == SOCKTIMEOUT2, "getsockopt(SO_SNDTIMEO) returned wrong value %d\n", timeout); ++ ++ /* SO_SNDBUF */ ++ value = 4096; ++ size = sizeof(DWORD); ++ err = setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, size); ++ ok( !err, "setsockopt(SO_SNDBUF) failed error: %u\n", WSAGetLastError()); ++ value = 0xdeadbeef; ++ err = getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, &size); ++ ok( !err, "getsockopt(SO_SNDBUF) failed error: %u\n", WSAGetLastError()); ++ ok( value == 4096, "expected 4096, got %u\n", value ); ++ ++ /* SO_RCVBUF */ ++ value = 4096; ++ size = sizeof(DWORD); ++ err = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, size); ++ ok( !err, "setsockopt(SO_RCVBUF) failed error: %u\n", WSAGetLastError()); ++ value = 0xdeadbeef; ++ err = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, &size); ++ ok( !err, "getsockopt(SO_RCVBUF) failed error: %u\n", WSAGetLastError()); ++ ok( value == 4096, "expected 4096, got %u\n", value ); ++ + /* SO_LINGER */ + for( i = 0; i < sizeof(linger_testvals)/sizeof(LINGER);i++) { + size = sizeof(lingval); +-- +2.7.0 + diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ws2_32-getsockopt/definition wine-staging-1.9.3~ubuntu12.04.1/patches/ws2_32-getsockopt/definition --- wine-staging-1.9.0~ubuntu12.04.1/patches/ws2_32-getsockopt/definition 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ws2_32-getsockopt/definition 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Fixes: [8606] Divide values returned by SO_RCVBUF and SO_SNDBUF getsockopt options by two diff -Nru wine-staging-1.9.0~ubuntu12.04.1/patches/ws2_32-TransmitFile/0002-ws2_32-Add-support-for-TF_REUSE_SOCKET-to-TransmitFi.patch wine-staging-1.9.3~ubuntu12.04.1/patches/ws2_32-TransmitFile/0002-ws2_32-Add-support-for-TF_REUSE_SOCKET-to-TransmitFi.patch --- wine-staging-1.9.0~ubuntu12.04.1/patches/ws2_32-TransmitFile/0002-ws2_32-Add-support-for-TF_REUSE_SOCKET-to-TransmitFi.patch 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/patches/ws2_32-TransmitFile/0002-ws2_32-Add-support-for-TF_REUSE_SOCKET-to-TransmitFi.patch 2016-02-08 20:07:32.000000000 +0000 @@ -1,4 +1,4 @@ -From 361a906c0026d132a08bc292450a098fd2fc072b Mon Sep 17 00:00:00 2001 +From 93e58d6178dcfdea0c120c1330e28df88c47439b Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 16 Jan 2014 19:08:30 -0700 Subject: ws2_32: Add support for TF_REUSE_SOCKET to TransmitFile. @@ -12,10 +12,10 @@ 5 files changed, 75 insertions(+), 11 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c -index 9cff400..c2dbbf4 100644 +index cb16583..c7a7c54 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c -@@ -2888,6 +2888,17 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws +@@ -2933,6 +2933,17 @@ static NTSTATUS WS2_transmitfile_base( int fd, struct ws2_transmitfile_async *ws if (status != STATUS_SUCCESS) return status; @@ -33,7 +33,7 @@ if (wsa->flags & TF_DISCONNECT) { /* we can't use WS_closesocket because it modifies the last error */ -@@ -2931,7 +2942,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD +@@ -2976,7 +2987,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD LPOVERLAPPED overlapped, LPTRANSMIT_FILE_BUFFERS buffers, DWORD flags ) { @@ -43,10 +43,10 @@ unsigned int uaddrlen = sizeof(uaddr); struct ws2_transmitfile_async *wsa; diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c -index 41554b4..9462628 100644 +index e10d01c..82f8ef0 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c -@@ -8049,7 +8049,6 @@ static void test_TransmitFile(void) +@@ -8053,7 +8053,6 @@ static void test_TransmitFile(void) err, WSAENOTSOCK); /* Test TransmitFile with a UDP datagram socket */ @@ -67,10 +67,10 @@ #define FD_WINE_NONBLOCKING 0x20000000 #define FD_WINE_CONNECTED 0x40000000 diff --git a/server/protocol.def b/server/protocol.def -index 04814c9..8a2d395 100644 +index a5a45eb..592fbe2 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -1263,6 +1263,12 @@ enum server_fd_type +@@ -1260,6 +1260,12 @@ enum server_fd_type @END @@ -84,7 +84,7 @@ @REQ(set_socket_event) obj_handle_t handle; /* handle to the socket */ diff --git a/server/sock.c b/server/sock.c -index 57d3d93..37c78b1 100644 +index a11964f..26f1c72 100644 --- a/server/sock.c +++ b/server/sock.c @@ -86,6 +86,7 @@ @@ -103,8 +103,8 @@ static int sock_get_ntstatus( int err ); static int sock_get_error( int err ); -@@ -155,7 +157,7 @@ static const struct object_ops sock_ops = - no_lookup_name, /* lookup_name */ +@@ -157,7 +159,7 @@ static const struct object_ops sock_ops = + NULL, /* unlink_name */ no_open_file, /* open_file */ no_alloc_handle, /* alloc_handle */ - fd_close_handle, /* close_handle */ @@ -112,7 +112,7 @@ sock_destroy /* destroy */ }; -@@ -627,6 +629,47 @@ static struct fd *sock_get_fd( struct object *obj ) +@@ -629,6 +631,47 @@ static struct fd *sock_get_fd( struct object *obj ) return (struct fd *)grab_object( sock->fd ); } @@ -160,7 +160,7 @@ static void sock_destroy( struct object *obj ) { struct sock *sock = (struct sock *)obj; -@@ -678,15 +721,8 @@ static struct object *create_socket( int family, int type, int protocol, unsigne +@@ -680,15 +723,8 @@ static struct object *create_socket( int family, int type, int protocol, unsigne struct sock *sock; int sockfd; @@ -177,7 +177,7 @@ if (!(sock = alloc_object( &sock_ops ))) { close( sockfd ); -@@ -1263,6 +1299,17 @@ DECL_HANDLER(accept_into_socket) +@@ -1267,6 +1303,17 @@ DECL_HANDLER(accept_into_socket) release_object( sock ); } @@ -196,5 +196,5 @@ DECL_HANDLER(set_socket_event) { -- -2.6.2 +2.7.0 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/ar.po wine-staging-1.9.3~ubuntu12.04.1/po/ar.po --- wine-staging-1.9.0~ubuntu12.04.1/po/ar.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/ar.po 2016-02-08 19:32:34.000000000 +0000 @@ -13238,7 +13238,9 @@ "معين." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "أ&ضف تطبيقًا..." #: winecfg.rc:160 @@ -13299,9 +13301,9 @@ msgid "&New override for library:" msgstr "إعداد سي&طرة مكتباتية جديد:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "أ&ضف" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13328,7 +13330,9 @@ msgstr "الأ&صليّة (المأخوذة من وندوز)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "المضمّنة ثمّ الأصليّة" #: winecfg.rc:212 @@ -13353,19 +13357,25 @@ msgstr "فشل الاتّصال بمدير المحرّكات ، لا يمكن تحريرالاعدادات" #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "أ&ضف..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "ك&شف تلقائي" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "تحديد تلقائي" #: winecfg.rc:241 msgid "&Path:" msgstr "الم&سار:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "الخيارات المتقدمة" #: winecfg.rc:249 @@ -13385,7 +13395,9 @@ msgstr "المس&لسل:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "أظهر الملفات المخفيّة" #: winecfg.rc:265 @@ -13467,7 +13479,9 @@ msgstr "اختر دليلًا متوافقًا مع طريقة يونكس من فضلك." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "أخفِ الخيارات المت&قدمة" #: winecfg.rc:39 @@ -13942,7 +13956,11 @@ msgstr "خطأ في التهيئة" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "حجم تدفق الشاشة يجب ان يكون أكبر أو يساوي حجم تدفق النافذة" #: wineconsole.rc:37 @@ -14644,6 +14662,10 @@ msgid "Tab stops" msgstr "وقف اللسان" +#: wordpad.rc:247 +msgid "&Add" +msgstr "أ&ضف" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "حذف ال&كل" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/bg.po wine-staging-1.9.3~ubuntu12.04.1/po/bg.po --- wine-staging-1.9.0~ubuntu12.04.1/po/bg.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/bg.po 2016-02-08 19:32:34.000000000 +0000 @@ -12871,7 +12871,9 @@ "приложенията настройки." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Добавяне на приложение..." #: winecfg.rc:160 @@ -12934,9 +12936,9 @@ msgid "&New override for library:" msgstr "Нова библиотечна замяна:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Добави" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -12964,7 +12966,9 @@ msgstr "&Собствена (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "В&градена, после собствена" #: winecfg.rc:212 @@ -12989,11 +12993,14 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Добави..." #: winecfg.rc:238 -msgid "Auto&detect" +#, fuzzy +msgid "Aut&odetect" msgstr "&Открий" #: winecfg.rc:241 @@ -13001,7 +13008,9 @@ msgstr "&Път:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Покажи допълнителните" #: winecfg.rc:249 @@ -13021,7 +13030,9 @@ msgstr "&Номер:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Показвай файловете, започващи с точка" #: winecfg.rc:265 @@ -13106,7 +13117,9 @@ msgstr "Изберете Unix директория" #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Скрий допълнителните" #: winecfg.rc:39 @@ -13585,7 +13598,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -14318,6 +14333,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Добави" + #: wordpad.rc:251 #, fuzzy msgid "Remove al&l" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/ca.po wine-staging-1.9.3~ubuntu12.04.1/po/ca.po --- wine-staging-1.9.0~ubuntu12.04.1/po/ca.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/ca.po 2016-02-08 19:32:34.000000000 +0000 @@ -13152,7 +13152,9 @@ "aquelles pestanyes també." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "A&fegeix aplicació..." #: winecfg.rc:160 @@ -13213,9 +13215,9 @@ msgid "&New override for library:" msgstr "Reemplaçament &nou per a la biblioteca:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Afegeix" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13242,7 +13244,9 @@ msgstr "&Nativa (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "In&terna, després Nativa" #: winecfg.rc:212 @@ -13266,19 +13270,25 @@ "es pot editar." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "A&fegeix..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Auto&detecta" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Autodetecta" #: winecfg.rc:241 msgid "&Path:" msgstr "&Camí:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "&Vista avançada" #: winecfg.rc:249 @@ -13298,7 +13308,9 @@ msgstr "&Serial:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "&Mostra els fitxers de punt" #: winecfg.rc:265 @@ -13378,7 +13390,9 @@ msgstr "Seleccioneu el directori de destinació d'Unix, si us plau." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "&Vista bàsica" #: winecfg.rc:39 @@ -13840,7 +13854,11 @@ msgstr "Error de configuració" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" "La mida de la memòria intermèdia de pantalla ha de ser major o igual al de " "la finestra" @@ -14549,6 +14567,10 @@ msgid "Tab stops" msgstr "Aturades de tabulador" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Afegeix" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "&Elimina tots" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/cs.po wine-staging-1.9.3~ubuntu12.04.1/po/cs.po --- wine-staging-1.9.0~ubuntu12.04.1/po/cs.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/cs.po 2016-02-08 19:32:34.000000000 +0000 @@ -12931,7 +12931,9 @@ "celého systému nebo nastavení každé aplikace zvlášť." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "Přid&at aplikaci..." #: winecfg.rc:160 @@ -12991,9 +12993,9 @@ msgid "&New override for library:" msgstr "&Nové nastavení pro knihovnu:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "Přid&at" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13020,7 +13022,9 @@ msgstr "&Nativní (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "V&estavěná pak nativní" #: winecfg.rc:212 @@ -13046,19 +13050,25 @@ "diskových jednotek." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "Přid&at..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Auto&detekce" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Autodetekce" #: winecfg.rc:241 msgid "&Path:" msgstr "&Cesta:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Zobrazit rozšířené &možnosti" #: winecfg.rc:249 @@ -13078,7 +13088,9 @@ msgstr "&Sériové číslo:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Zo&brazit soubory s tečkou na začátku názvu" #: winecfg.rc:265 @@ -13160,7 +13172,9 @@ msgstr "Vyberte, prosím, cílový unixový adresář." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Schovat rozšířené &možnosti" #: winecfg.rc:39 @@ -13637,7 +13651,11 @@ msgstr "Chyba nastavení" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "Zásobník obrazovky musí být větší nebo stejně velký jako zásobník okna" #: wineconsole.rc:37 @@ -14342,6 +14360,10 @@ msgid "Tab stops" msgstr "Zarážky" +#: wordpad.rc:247 +msgid "&Add" +msgstr "Přid&at" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "&Odebrat vše" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/da.po wine-staging-1.9.3~ubuntu12.04.1/po/da.po --- wine-staging-1.9.0~ubuntu12.04.1/po/da.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/da.po 2016-02-08 19:32:34.000000000 +0000 @@ -13201,7 +13201,9 @@ "faneblade." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Tilføj program..." #: winecfg.rc:160 @@ -13261,9 +13263,9 @@ msgid "&New override for library:" msgstr "&Nye overstyringer for bibliotek:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Tilføj" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13290,7 +13292,9 @@ msgstr "Ind&født (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Indb&ygget derefter indfødt" #: winecfg.rc:212 @@ -13316,11 +13320,15 @@ "ikke redigeres." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Tilføj..." #: winecfg.rc:238 -msgid "Auto&detect" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" msgstr "Auto&detekter" #: winecfg.rc:241 @@ -13328,7 +13336,9 @@ msgstr "&Sti:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Vis &avanceret" #: winecfg.rc:249 @@ -13348,7 +13358,9 @@ msgstr "Se&riel:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Vis &dot filer" #: winecfg.rc:265 @@ -13430,7 +13442,9 @@ msgstr "Vælg venligst Unix mappen." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Skjul &avanceret" #: winecfg.rc:39 @@ -13906,7 +13920,11 @@ msgstr "Konfigurationfejl" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "Skærm buffer størrelsen, skal være større eller lig med vinduet" #: wineconsole.rc:37 @@ -14623,6 +14641,10 @@ msgid "Tab stops" msgstr "Tabulatorstop" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Tilføj" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Fjern a&lle" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/de.po wine-staging-1.9.3~ubuntu12.04.1/po/de.po --- wine-staging-1.9.0~ubuntu12.04.1/po/de.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/de.po 2016-02-08 19:32:34.000000000 +0000 @@ -5,7 +5,7 @@ "Project-Id-Version: Wine\n" "Report-Msgid-Bugs-To: http://bugs.winehq.org\n" "POT-Creation-Date: N/A\n" -"PO-Revision-Date: 2015-12-07 00:44+0100\n" +"PO-Revision-Date: 2016-01-11 12:42+0100\n" "Last-Translator: Julian Rüger\n" "Language-Team: German\n" "Language: de\n" @@ -1042,7 +1042,7 @@ #: comdlg32.rc:148 msgid "Font size has to be a number." -msgstr "" +msgstr "Die Schriftgröße muss eine Zahl sein." #: comdlg32.rc:83 oleview.rc:98 msgid "Ready" @@ -13126,7 +13126,9 @@ "Einstellungen in diesen Reitern vornehmen können." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "Anw. &hinzufügen..." #: winecfg.rc:160 @@ -13187,9 +13189,9 @@ msgid "&New override for library:" msgstr "&Neue Überschreibung für:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Festlegen" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13216,7 +13218,9 @@ msgstr "&Native (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Bui<in dann Native" #: winecfg.rc:212 @@ -13240,19 +13244,25 @@ "nicht bearbeitet werden." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Hinzufügen..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "&Automatisch" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Automatisch" #: winecfg.rc:241 msgid "&Path:" msgstr "&Pfad:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "&Erweitert" #: winecfg.rc:249 @@ -13272,7 +13282,9 @@ msgstr "S&erien-Nr.:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "D&ot-Dateien anzeigen" #: winecfg.rc:265 @@ -13352,7 +13364,9 @@ msgstr "Bitte wählen Sie das Unix-Zielverzeichnis." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "&Erweitert ausblenden" #: winecfg.rc:39 @@ -13816,7 +13830,11 @@ msgstr "Konfigurationsfehler" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" "Die Größe des Zeichenpuffers muss mindestens der Fenstergröße entsprechen" @@ -14524,6 +14542,10 @@ msgid "Tab stops" msgstr "Tabstoppposition" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Festlegen" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "&Alle löschen" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/el.po wine-staging-1.9.3~ubuntu12.04.1/po/el.po --- wine-staging-1.9.0~ubuntu12.04.1/po/el.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/el.po 2016-02-08 19:32:34.000000000 +0000 @@ -12635,7 +12635,7 @@ #: winecfg.rc:159 #, fuzzy -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "Επιλογές" #: winecfg.rc:160 @@ -12695,8 +12695,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -12725,7 +12725,7 @@ msgstr "" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -12748,11 +12748,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12760,7 +12760,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -12780,8 +12780,9 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "" +#, fuzzy +msgid "&Show dot files" +msgstr "Λεπτομέρειες" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -12863,7 +12864,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13330,7 +13331,9 @@ msgstr "Επιλογές" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -14023,6 +14026,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/en.po wine-staging-1.9.3~ubuntu12.04.1/po/en.po --- wine-staging-1.9.0~ubuntu12.04.1/po/en.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/en.po 2016-02-08 19:32:34.000000000 +0000 @@ -13034,8 +13034,8 @@ "or per-application settings in those tabs as well." #: winecfg.rc:159 -msgid "&Add application..." -msgstr "&Add application..." +msgid "Add appli&cation..." +msgstr "Add appli&cation..." #: winecfg.rc:160 msgid "&Remove application" @@ -13095,9 +13095,9 @@ msgid "&New override for library:" msgstr "&New override for library:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Add" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "A&dd" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13124,8 +13124,8 @@ msgstr "&Native (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" -msgstr "Bui<in then Native" +msgid "Buil&tin then Native" +msgstr "Buil&tin then Native" #: winecfg.rc:212 msgid "Nati&ve then Builtin" @@ -13148,20 +13148,20 @@ "edited." #: winecfg.rc:236 -msgid "&Add..." -msgstr "&Add..." +msgid "A&dd..." +msgstr "A&dd..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Auto&detect" +msgid "Aut&odetect" +msgstr "Aut&odetect" #: winecfg.rc:241 msgid "&Path:" msgstr "&Path:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" -msgstr "Show &Advanced" +msgid "Show Advan&ced" +msgstr "Show Advan&ced" #: winecfg.rc:249 msgid "De&vice:" @@ -13180,8 +13180,8 @@ msgstr "S&erial:" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "Show &dot files" +msgid "&Show dot files" +msgstr "&Show dot files" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -13260,8 +13260,8 @@ msgstr "Select the Unix target directory, please." #: winecfg.rc:37 -msgid "Hide &Advanced" -msgstr "Hide &Advanced" +msgid "Hide Advan&ced" +msgstr "Hide Advan&ced" #: winecfg.rc:39 msgid "(No Theme)" @@ -13721,8 +13721,10 @@ msgstr "Configuration error" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" -msgstr "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." +msgstr "The size of the screen buffer must be greater than or equal to the size of the window." #: wineconsole.rc:37 msgid "Each character is %1!u! pixels wide and %2!u! pixels high" @@ -14427,6 +14429,10 @@ msgid "Tab stops" msgstr "Tab stops" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Add" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Remove al&l" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/en_US.po wine-staging-1.9.3~ubuntu12.04.1/po/en_US.po --- wine-staging-1.9.0~ubuntu12.04.1/po/en_US.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/en_US.po 2016-02-08 19:32:34.000000000 +0000 @@ -13034,8 +13034,8 @@ "or per-application settings in those tabs as well." #: winecfg.rc:159 -msgid "&Add application..." -msgstr "&Add application..." +msgid "Add appli&cation..." +msgstr "Add appli&cation..." #: winecfg.rc:160 msgid "&Remove application" @@ -13095,9 +13095,9 @@ msgid "&New override for library:" msgstr "&New override for library:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Add" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "A&dd" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13124,8 +13124,8 @@ msgstr "&Native (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" -msgstr "Bui<in then Native" +msgid "Buil&tin then Native" +msgstr "Buil&tin then Native" #: winecfg.rc:212 msgid "Nati&ve then Builtin" @@ -13148,20 +13148,20 @@ "edited." #: winecfg.rc:236 -msgid "&Add..." -msgstr "&Add..." +msgid "A&dd..." +msgstr "A&dd..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Auto&detect" +msgid "Aut&odetect" +msgstr "Aut&odetect" #: winecfg.rc:241 msgid "&Path:" msgstr "&Path:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" -msgstr "Show &Advanced" +msgid "Show Advan&ced" +msgstr "Show Advan&ced" #: winecfg.rc:249 msgid "De&vice:" @@ -13180,8 +13180,8 @@ msgstr "S&erial:" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "Show &dot files" +msgid "&Show dot files" +msgstr "&Show dot files" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -13260,8 +13260,8 @@ msgstr "Select the Unix target directory, please." #: winecfg.rc:37 -msgid "Hide &Advanced" -msgstr "Hide &Advanced" +msgid "Hide Advan&ced" +msgstr "Hide Advan&ced" #: winecfg.rc:39 msgid "(No Theme)" @@ -13721,8 +13721,10 @@ msgstr "Configuration error" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" -msgstr "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." +msgstr "The size of the screen buffer must be greater than or equal to the size of the window." #: wineconsole.rc:37 msgid "Each character is %1!u! pixels wide and %2!u! pixels high" @@ -14427,6 +14429,10 @@ msgid "Tab stops" msgstr "Tab stops" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Add" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Remove al&l" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/eo.po wine-staging-1.9.3~ubuntu12.04.1/po/eo.po --- wine-staging-1.9.0~ubuntu12.04.1/po/eo.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/eo.po 2016-02-08 19:32:34.000000000 +0000 @@ -12524,7 +12524,9 @@ "permesi, ke vi ŝanĝu agordaĵojn tutsisteme aŭ ĉiuprograme." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Aldoni programon..." #: winecfg.rc:160 @@ -12582,9 +12584,9 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Aldoni" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -12611,7 +12613,9 @@ msgstr "&Indiĝena (Vindozo)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "&Post ena indiĝena" #: winecfg.rc:212 @@ -12635,11 +12639,13 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Aldoni..." #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12647,7 +12653,9 @@ msgstr "&Vojo:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Montri &Altnivele" #: winecfg.rc:249 @@ -12667,7 +12675,9 @@ msgstr "&Seria:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Montri &punktajn dosierojn" #: winecfg.rc:265 @@ -12749,8 +12759,10 @@ msgstr "Bonvolu elekti la celan dosierujon." #: winecfg.rc:37 -msgid "Hide &Advanced" -msgstr "" +#, fuzzy +#| msgid "Advanced" +msgid "Hide Advan&ced" +msgstr "Altnivela" #: winecfg.rc:39 msgid "(No Theme)" @@ -13212,7 +13224,11 @@ msgstr "Eraro de agordado" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" "Ekran-bufra grandeco devas esti pli granda aŭ egala ol fenestr-bufra tiu" @@ -13901,6 +13917,10 @@ msgid "Tab stops" msgstr "Tabaj celoj" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Aldoni" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Forigi ĉion" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/es.po wine-staging-1.9.3~ubuntu12.04.1/po/es.po --- wine-staging-1.9.0~ubuntu12.04.1/po/es.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/es.po 2016-02-08 19:32:34.000000000 +0000 @@ -13291,7 +13291,9 @@ "cambiar la configuración global o la configuración por aplicación." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Añadir aplicación..." #: winecfg.rc:160 @@ -13352,9 +13354,9 @@ msgid "&New override for library:" msgstr "&Nueva sustitución de librería:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Añadir" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13381,7 +13383,9 @@ msgstr "&Nativa (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "I&nterna y luego nativa" #: winecfg.rc:212 @@ -13407,19 +13411,25 @@ "se ha podido editar." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Añadir..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Auto&detectar" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Autodetectar" #: winecfg.rc:241 msgid "&Path:" msgstr "&Ruta:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Mostrar &avanzado" #: winecfg.rc:249 @@ -13439,7 +13449,9 @@ msgstr "&Nº serie:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Mostrar archivos &punto" #: winecfg.rc:265 @@ -13521,7 +13533,9 @@ msgstr "Por favor, seleccione el directorio Unix de destino." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Ocultar &avanzado" #: winecfg.rc:39 @@ -13997,7 +14011,11 @@ msgstr "Error de configuración" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" "El tamaño del búfer de la pantalla debe ser mayor o igual que el de la " "ventana" @@ -14718,6 +14736,10 @@ msgid "Tab stops" msgstr "Fin de la tabulación" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Añadir" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "&Quitar todo" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/fa.po wine-staging-1.9.3~ubuntu12.04.1/po/fa.po --- wine-staging-1.9.0~ubuntu12.04.1/po/fa.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/fa.po 2016-02-08 19:32:34.000000000 +0000 @@ -12638,7 +12638,7 @@ msgstr "" #: winecfg.rc:159 -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "" #: winecfg.rc:160 @@ -12697,8 +12697,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -12730,7 +12730,7 @@ msgstr "ذخیره &به نام..." #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -12754,11 +12754,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12766,7 +12766,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -12786,7 +12786,7 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" +msgid "&Show dot files" msgstr "" #: winecfg.rc:265 @@ -12869,7 +12869,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13336,7 +13336,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -14055,6 +14057,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/fi.po wine-staging-1.9.3~ubuntu12.04.1/po/fi.po --- wine-staging-1.9.0~ubuntu12.04.1/po/fi.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/fi.po 2016-02-08 19:32:34.000000000 +0000 @@ -13010,7 +13010,7 @@ "järjestelmän laajuiset ja sovelluskohtaiset asetukset." #: winecfg.rc:159 -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Lisää sovellus..." #: winecfg.rc:160 @@ -13071,8 +13071,8 @@ msgid "&New override for library:" msgstr "&Uusi ohitus kirjastolle:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "&Lisää" #: winecfg.rc:197 @@ -13100,12 +13100,12 @@ msgstr "&Natiivi (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "S&isäinen, sitten natiivi" #: winecfg.rc:212 msgid "Nati&ve then Builtin" -msgstr "Natiivi, sitten sisäinen" +msgstr "Na&tiivi, sitten sisäinen" #: winecfg.rc:220 msgid "Select Drive Letter" @@ -13122,24 +13122,24 @@ msgstr "Levyasemien hallintaan ei saatu yhteyttä. Asemia ei voi muokata." #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "&Lisää..." #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "&Hae automaattisesti" #: winecfg.rc:241 msgid "&Path:" -msgstr "&Polku:" +msgstr "P&olku:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" -msgstr "Nä&ytä lisäasetukset" +msgid "Show Advan&ced" +msgstr "Näytä lisä&asetukset" #: winecfg.rc:249 msgid "De&vice:" -msgstr "Lai&te:" +msgstr "La&ite:" #: winecfg.rc:251 msgid "Bro&wse..." @@ -13151,11 +13151,11 @@ #: winecfg.rc:255 msgid "S&erial:" -msgstr "&Sarjanumero:" +msgstr "Sarjanumer&o:" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "Näytä p&istetiedostot" +msgid "&Show dot files" +msgstr "N&äytä pistetiedostot" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -13234,8 +13234,8 @@ msgstr "Valitse unix-kohdekansio." #: winecfg.rc:37 -msgid "Hide &Advanced" -msgstr "&Piilota lisäasetukset" +msgid "Hide Advan&ced" +msgstr "Piilota lisä&asetukset" #: winecfg.rc:39 msgid "(No Theme)" @@ -13695,8 +13695,10 @@ msgstr "Virhe asetuksissa" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" -msgstr "Näytön puskurin on oltava suurempi tai yhtä suuri kuin ikkunan" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." +msgstr "Näyttöpuskurin on oltava vähintään ikkunan kokoinen" #: wineconsole.rc:37 msgid "Each character is %1!u! pixels wide and %2!u! pixels high" @@ -14398,6 +14400,10 @@ msgid "Tab stops" msgstr "Sarkainkohdat" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Lisää" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Poista &kaikki" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/fr.po wine-staging-1.9.3~ubuntu12.04.1/po/fr.po --- wine-staging-1.9.0~ubuntu12.04.1/po/fr.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/fr.po 2016-02-08 19:32:34.000000000 +0000 @@ -5,7 +5,7 @@ "Project-Id-Version: Wine\n" "Report-Msgid-Bugs-To: http://bugs.winehq.org\n" "POT-Creation-Date: N/A\n" -"PO-Revision-Date: 2015-10-03 11:45+0100\n" +"PO-Revision-Date: 2016-04-02 12:50+0100\n" "Last-Translator: Frédéric Delanoy \n" "Language-Team: French\n" "Language: fr\n" @@ -1045,7 +1045,7 @@ #: comdlg32.rc:148 msgid "Font size has to be a number." -msgstr "" +msgstr "La taille de police doit être un nombre." #: comdlg32.rc:83 oleview.rc:98 msgid "Ready" @@ -8632,58 +8632,44 @@ msgstr "Wine" #: winemac.rc:33 -#, fuzzy -#| msgid "Hide" msgid "Hide %@" -msgstr "Cacher" +msgstr "Cacher %@" #: winemac.rc:35 -#, fuzzy -#| msgid "Other" msgid "Hide Others" -msgstr "Autre" +msgstr "Cacher les autres" #: winemac.rc:36 -#, fuzzy -#| msgid "Show" msgid "Show All" -msgstr "Afficher" +msgstr "Tout afficher" #: winemac.rc:37 msgid "Quit %@" -msgstr "" +msgstr "Quitter %@" #: winemac.rc:38 msgid "Quit" -msgstr "" +msgstr "Quitter" #: winemac.rc:40 -#, fuzzy -#| msgid "&Window" msgid "Window" -msgstr "&Fenêtre" +msgstr "Fenêtre" #: winemac.rc:41 -#, fuzzy -#| msgid "&Minimize" msgid "Minimize" -msgstr "&Réduire" +msgstr "Réduire" #: winemac.rc:42 -#, fuzzy -#| msgid "Zoom in" msgid "Zoom" -msgstr "Zoom avant" +msgstr "Zoom" #: winemac.rc:43 msgid "Enter Full Screen" -msgstr "" +msgstr "Plein écran" #: winemac.rc:44 -#, fuzzy -#| msgid "&Bring To Front" msgid "Bring All to Front" -msgstr "Toujours &visible" +msgstr "Tout amener à l'avant-plan" #: wineps.rc:31 msgid "Paper Si&ze:" @@ -13117,7 +13103,7 @@ "\n" "Options :\n" " --help\t Afficher ces informations.\n" -" --list\t Lister toutes les applications installées dans ce préfix " +" --list\t Lister toutes les applications installées dans ce préfixe " "Wine.\n" " --remove {GUID} Désinstaller l'application spécifiée.\n" "\t\t Utilisez « --list » pour déterminer le GUID de l'application.\n" @@ -13210,8 +13196,8 @@ "onglets." #: winecfg.rc:159 -msgid "&Add application..." -msgstr "&Ajouter une application..." +msgid "Add appli&cation..." +msgstr "Ajouter une appli&cation..." #: winecfg.rc:160 msgid "&Remove application" @@ -13272,9 +13258,9 @@ msgid "&New override for library:" msgstr "&Nouveau remplacement pour :" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "A&jouter" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "Ajou&ter" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13301,7 +13287,7 @@ msgstr "&native (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "i&ntégrée puis native" #: winecfg.rc:212 @@ -13325,24 +13311,24 @@ "n'a pu être éditée." #: winecfg.rc:236 -msgid "&Add..." -msgstr "&Ajouter..." +msgid "A&dd..." +msgstr "Ajo&uter..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "&Détection automatique" +msgid "Aut&odetect" +msgstr "Aut&o-détection" #: winecfg.rc:241 msgid "&Path:" msgstr "&Chemin :" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" -msgstr "Afficher les dé&tails" +msgid "Show Advan&ced" +msgstr "Afficher les &détails" #: winecfg.rc:249 msgid "De&vice:" -msgstr "&Périphérique :" +msgstr "Périp&hérique :" #: winecfg.rc:251 msgid "Bro&wse..." @@ -13350,15 +13336,15 @@ #: winecfg.rc:253 msgid "&Label:" -msgstr "É&tiquette :" +msgstr "Ét&iquette :" #: winecfg.rc:255 msgid "S&erial:" -msgstr "N° de &série :" +msgstr "N° de sé&rie :" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "Montrer les fichiers cachés" +msgid "&Show dot files" +msgstr "&Montrer les fichiers cachés" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -13437,8 +13423,8 @@ msgstr "Veuillez sélectionner le répertoire Unix cible." #: winecfg.rc:37 -msgid "Hide &Advanced" -msgstr "Cacher les dé&tails" +msgid "Hide Advan&ced" +msgstr "Cacher les &détails" #: winecfg.rc:39 msgid "(No Theme)" @@ -13901,7 +13887,11 @@ msgstr "Erreur de configuration" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" "La taille du tampon écran doit être plus grande ou égale à celle du tampon " "de la fenêtre" @@ -14612,6 +14602,10 @@ msgid "Tab stops" msgstr "Taquets de tabulation" +#: wordpad.rc:247 +msgid "&Add" +msgstr "A&jouter" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Supprimer &tous" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/he.po wine-staging-1.9.3~ubuntu12.04.1/po/he.po --- wine-staging-1.9.0~ubuntu12.04.1/po/he.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/he.po 2016-02-08 19:32:34.000000000 +0000 @@ -13021,7 +13021,7 @@ #: winecfg.rc:159 #, fuzzy -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "יישום" #: winecfg.rc:160 @@ -13084,9 +13084,9 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "הו&ספה" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13118,7 +13118,7 @@ #: winecfg.rc:211 #, fuzzy -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "מובנה, טבעי" #: winecfg.rc:212 @@ -13144,12 +13144,12 @@ #: winecfg.rc:236 #, fuzzy -msgid "&Add..." +msgid "A&dd..." msgstr "הו&ספה" #: winecfg.rc:238 #, fuzzy -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "זיהוי אוטומטי" #: winecfg.rc:241 @@ -13159,7 +13159,7 @@ #: winecfg.rc:248 winecfg.rc:38 #, fuzzy -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "הצגת אפשרויות מ&תקדמות" #: winecfg.rc:249 @@ -13181,7 +13181,7 @@ #: winecfg.rc:258 #, fuzzy -msgid "Show &dot files" +msgid "&Show dot files" msgstr "אין עוד קבצים\n" #: winecfg.rc:265 @@ -13273,7 +13273,7 @@ #: winecfg.rc:37 #, fuzzy -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "ה&סתרת האפשרויות המתקדמות" #: winecfg.rc:39 @@ -13817,7 +13817,11 @@ msgstr "שגיאת תצוגה" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "גודל מאגר המסך חייב להיות גדול או שווה לזה של החלון" #: wineconsole.rc:37 @@ -14535,6 +14539,10 @@ msgid "Tab stops" msgstr "טאבי עצירה" +#: wordpad.rc:247 +msgid "&Add" +msgstr "הו&ספה" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "הסרת ה&כול" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/hi.po wine-staging-1.9.3~ubuntu12.04.1/po/hi.po --- wine-staging-1.9.0~ubuntu12.04.1/po/hi.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/hi.po 2016-02-08 19:32:34.000000000 +0000 @@ -12429,7 +12429,7 @@ msgstr "" #: winecfg.rc:159 -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "" #: winecfg.rc:160 @@ -12487,8 +12487,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -12517,7 +12517,7 @@ msgstr "" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -12539,11 +12539,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12551,7 +12551,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -12571,7 +12571,7 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" +msgid "&Show dot files" msgstr "" #: winecfg.rc:265 @@ -12651,7 +12651,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13102,7 +13102,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -13794,6 +13796,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/hr.po wine-staging-1.9.3~ubuntu12.04.1/po/hr.po --- wine-staging-1.9.0~ubuntu12.04.1/po/hr.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/hr.po 2016-02-08 19:32:34.000000000 +0000 @@ -12739,7 +12739,9 @@ "promjene ili za podešavanje aplikacija u tim istim tabovima." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Dodaj aplikaciju..." #: winecfg.rc:160 @@ -12799,9 +12801,9 @@ msgid "&New override for library:" msgstr "&Novo nadjačavanje biblioteke:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Dodaj" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -12828,7 +12830,9 @@ msgstr "&Nativno (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Ugrađe&no pa nativno" #: winecfg.rc:212 @@ -12854,19 +12858,25 @@ "može izmijeniti." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Dodaj..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Auto&detektiraj" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Autodetektiraj" #: winecfg.rc:241 msgid "&Path:" msgstr "&Putanja:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Pokaži &napredno" #: winecfg.rc:249 @@ -12886,7 +12896,9 @@ msgstr "S&erijski:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Prikaži &dot datoteke" #: winecfg.rc:265 @@ -12968,7 +12980,9 @@ msgstr "Molimo izaberite Unix glavni direktorij." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Sakrij &napredno" #: winecfg.rc:39 @@ -13444,7 +13458,9 @@ msgstr "Pogreška konfiguracije" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -14142,6 +14158,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Dodaj" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "&Ukloni sve" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/hu.po wine-staging-1.9.3~ubuntu12.04.1/po/hu.po --- wine-staging-1.9.0~ubuntu12.04.1/po/hu.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/hu.po 2016-02-08 19:32:34.000000000 +0000 @@ -13199,7 +13199,9 @@ "is." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Alkalmazás hozzáadás..." #: winecfg.rc:160 @@ -13260,9 +13262,9 @@ msgid "&New override for library:" msgstr "Új felülbírálás könyvtárhoz:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "Hozzá&adás" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13289,7 +13291,9 @@ msgstr "&Natív (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Beépítet&t, natív" #: winecfg.rc:212 @@ -13315,11 +13319,14 @@ "szerkeszteni." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "Hozzá&ad..." #: winecfg.rc:238 -msgid "Auto&detect" +#, fuzzy +msgid "Aut&odetect" msgstr "Automata &felismerés" #: winecfg.rc:241 @@ -13327,7 +13334,9 @@ msgstr "&Útvonal:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Haladó >>" #: winecfg.rc:249 @@ -13347,7 +13356,9 @@ msgstr "S&orozatszám:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Rejtett fájlok megjelenítése" #: winecfg.rc:265 @@ -13429,7 +13440,9 @@ msgstr "Kérem válasszon unix célkönyvtárat." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Haladó <<" #: winecfg.rc:39 @@ -13906,7 +13919,11 @@ msgstr "Beállítási hiba" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" "Képernyő pufferméretnek nagyobbnak egy egyenlőnek kell lennie az ablakénál" @@ -14623,6 +14640,10 @@ msgid "Tab stops" msgstr "Tab sorrend" +#: wordpad.rc:247 +msgid "&Add" +msgstr "Hozzá&adás" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Az összes &eltávolítása" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/it.po wine-staging-1.9.3~ubuntu12.04.1/po/it.po --- wine-staging-1.9.0~ubuntu12.04.1/po/it.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/it.po 2016-02-08 19:32:34.000000000 +0000 @@ -13294,7 +13294,9 @@ "quelle schede." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Aggiungi applicazione..." #: winecfg.rc:160 @@ -13355,9 +13357,9 @@ msgid "&New override for library:" msgstr "&Nuova sostituzione per la libreria:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Aggiungi" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13384,7 +13386,9 @@ msgstr "&Nativa (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "In&tegrata poi nativa" #: winecfg.rc:212 @@ -13410,11 +13414,14 @@ "non può essere modificata." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "Aggiungi..." #: winecfg.rc:238 -msgid "Auto&detect" +#, fuzzy +msgid "Aut&odetect" msgstr "&Rileva automaticamente" #: winecfg.rc:241 @@ -13422,7 +13429,9 @@ msgstr "&Percorso:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Mostra controlli &avanzati" #: winecfg.rc:249 @@ -13442,7 +13451,9 @@ msgstr "Numero &seriale:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Mostra file &dot" #: winecfg.rc:265 @@ -13524,7 +13535,9 @@ msgstr "Seleziona la cartella Unix desiderata, prego." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Nascondi controlli &avanzati" #: winecfg.rc:39 @@ -14001,7 +14014,11 @@ msgstr "Errore di configurazione" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" "Il buffer dello schermo deve essere uguale o più grande di quello della " "finestra" @@ -14717,6 +14734,10 @@ msgid "Tab stops" msgstr "Punti di fermata delle tabulazioni" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Aggiungi" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Rimuovi &tutti" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/ja.po wine-staging-1.9.3~ubuntu12.04.1/po/ja.po --- wine-staging-1.9.0~ubuntu12.04.1/po/ja.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/ja.po 2016-02-08 19:32:34.000000000 +0000 @@ -13022,8 +13022,8 @@ "体の設定や 個別アプリケーションの設定の変更が行えます。" #: winecfg.rc:159 -msgid "&Add application..." -msgstr "アプリケーションを追加(&A)..." +msgid "Add appli&cation..." +msgstr "アプリケーションを追加(&C)..." #: winecfg.rc:160 msgid "&Remove application" @@ -13082,9 +13082,9 @@ msgid "&New override for library:" msgstr "ライブラリの新規オーバーライド(&N):" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "追加(&A)" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "追加(&D)" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13111,8 +13111,8 @@ msgstr "ネイティブ版(Windows)(&N)" #: winecfg.rc:211 -msgid "Bui<in then Native" -msgstr "内蔵版後にネイティブ版(&L)" +msgid "Buil&tin then Native" +msgstr "内蔵版後にネイティブ版(&T)" #: winecfg.rc:212 msgid "Nati&ve then Builtin" @@ -13134,20 +13134,20 @@ "マウント マネージャへの接続に失敗したため、ドライブ設定は変更できません。" #: winecfg.rc:236 -msgid "&Add..." -msgstr "追加(&A)..." +msgid "A&dd..." +msgstr "追加(&D)..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "自動検出(&D)" +msgid "Aut&odetect" +msgstr "自動検出(&O)" #: winecfg.rc:241 msgid "&Path:" msgstr "パス(&P):" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" -msgstr "詳細を表示(&A)" +msgid "Show Advan&ced" +msgstr "詳細を表示(&C)" #: winecfg.rc:249 msgid "De&vice:" @@ -13166,8 +13166,8 @@ msgstr "シリアル番号(&E):" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "ドット ファイルを表示する" +msgid "&Show dot files" +msgstr "ドット ファイルを表示する(&S)" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -13246,8 +13246,8 @@ msgstr "Unix の対象ディレクトリを選択してください。" #: winecfg.rc:37 -msgid "Hide &Advanced" -msgstr "詳細を隠す(&A)" +msgid "Hide Advan&ced" +msgstr "詳細を隠す(&C)" #: winecfg.rc:39 msgid "(No Theme)" @@ -13710,7 +13710,11 @@ msgstr "構成エラー" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" "スクリーン バッファ サイズはウィンドウ バッファ サイズ以上にしてください" @@ -14414,6 +14418,10 @@ msgid "Tab stops" msgstr "タブの停止位置" +#: wordpad.rc:247 +msgid "&Add" +msgstr "追加(&A)" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "すべて削除(&L)" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/ko.po wine-staging-1.9.3~ubuntu12.04.1/po/ko.po --- wine-staging-1.9.0~ubuntu12.04.1/po/ko.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/ko.po 2016-02-08 19:32:34.000000000 +0000 @@ -13263,8 +13263,8 @@ "수 있도록 라이브러리 및 그래픽 탭에 연결되어 있습니다." #: winecfg.rc:159 -msgid "&Add application..." -msgstr "응용프로그램 추가(&A)..." +msgid "Add appli&cation..." +msgstr "응용프로그램 추가(&C)..." #: winecfg.rc:160 msgid "&Remove application" @@ -13323,9 +13323,9 @@ msgid "&New override for library:" msgstr "새로 덮어쓸 라이브러리(&N):" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "더하기(&A)" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "더하기(&D)" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13352,8 +13352,8 @@ msgstr "네이티브(&N)(Win)" #: winecfg.rc:211 -msgid "Bui<in then Native" -msgstr "내장, 네이티브(&L)" +msgid "Buil&tin then Native" +msgstr "내장, 네이티브(&T)" #: winecfg.rc:212 msgid "Nati&ve then Builtin" @@ -13377,20 +13377,20 @@ "연결 관리자가 연결하는 데 실패함, 이 드라이브 설정을 수정될 수 없습니다." #: winecfg.rc:236 -msgid "&Add..." -msgstr "추가(&A)..." +msgid "A&dd..." +msgstr "추가(&D)..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "자동찾기(&D)" +msgid "Aut&odetect" +msgstr "자동찾기(&O)" #: winecfg.rc:241 msgid "&Path:" msgstr "경로(&P):" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" -msgstr "추가옵션 보이기(&A)" +msgid "Show Advan&ced" +msgstr "추가옵션 보이기(&C)" #: winecfg.rc:249 msgid "De&vice:" @@ -13409,8 +13409,8 @@ msgstr "시리얼(&E):" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "숨은 파일 보이기(&D)" +msgid "&Show dot files" +msgstr "숨은 파일 보이기(&S)" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -13491,8 +13491,8 @@ msgstr "유닉스 목적 폴더를 선택하십시오." #: winecfg.rc:37 -msgid "Hide &Advanced" -msgstr "추가옵션 숨기기(&A)" +msgid "Hide Advan&ced" +msgstr "추가옵션 숨기기(&C)" #: winecfg.rc:39 msgid "(No Theme)" @@ -13967,7 +13967,11 @@ msgstr "설정 오류" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "스크린 버퍼 크기는 반드시 창보다 같거나 커야합니다" #: wineconsole.rc:37 @@ -14671,6 +14675,10 @@ msgid "Tab stops" msgstr "탭 정지" +#: wordpad.rc:247 +msgid "&Add" +msgstr "더하기(&A)" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "모두 지우기(&L)" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/lt.po wine-staging-1.9.3~ubuntu12.04.1/po/lt.po --- wine-staging-1.9.0~ubuntu12.04.1/po/lt.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/lt.po 2016-02-08 19:32:34.000000000 +0000 @@ -13050,7 +13050,9 @@ "atskirai." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Pridėti programą..." #: winecfg.rc:160 @@ -13110,9 +13112,9 @@ msgid "&New override for library:" msgstr "&Naujas nustelbimas bibliotekai:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Pridėti" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13139,7 +13141,9 @@ msgstr "&Sava („Windows“)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Į&taisyta, po to sava" #: winecfg.rc:212 @@ -13163,19 +13167,25 @@ "redaguojama." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Pridėti..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Automatiškai &aptikti" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Automatiškai aptikti" #: winecfg.rc:241 msgid "&Path:" msgstr "&Kelias:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Rodyti papil&domas" #: winecfg.rc:249 @@ -13195,7 +13205,9 @@ msgstr "N&umeris:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Rodyti &failus su tašku" #: winecfg.rc:265 @@ -13275,7 +13287,9 @@ msgstr "Išrinkite Unix paskirties aplanką." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Slėpti papil&domas" #: winecfg.rc:39 @@ -13737,7 +13751,11 @@ msgstr "Konfigūracijos klaida" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "Ekrano buferio dydis turi būti didesnis arba lygus lango buferiui" #: wineconsole.rc:37 @@ -14442,6 +14460,10 @@ msgid "Tab stops" msgstr "Tabuliavimo pozicija" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Pridėti" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Pašalinti &visas" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/ml.po wine-staging-1.9.3~ubuntu12.04.1/po/ml.po --- wine-staging-1.9.0~ubuntu12.04.1/po/ml.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/ml.po 2016-02-08 19:32:34.000000000 +0000 @@ -12429,7 +12429,7 @@ msgstr "" #: winecfg.rc:159 -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "" #: winecfg.rc:160 @@ -12487,8 +12487,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -12517,7 +12517,7 @@ msgstr "" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -12539,11 +12539,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12551,7 +12551,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -12571,7 +12571,7 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" +msgid "&Show dot files" msgstr "" #: winecfg.rc:265 @@ -12651,7 +12651,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13102,7 +13102,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -13794,6 +13796,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/nb_NO.po wine-staging-1.9.3~ubuntu12.04.1/po/nb_NO.po --- wine-staging-1.9.0~ubuntu12.04.1/po/nb_NO.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/nb_NO.po 2016-02-08 19:32:34.000000000 +0000 @@ -13107,7 +13107,9 @@ "innstillinger for hele systemet eller enkelte programmer der også." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "Legg til progr&am..." #: winecfg.rc:160 @@ -13168,9 +13170,9 @@ msgid "&New override for library:" msgstr "Ny overstyring for bibliotek:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Legg til" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13197,7 +13199,9 @@ msgstr "I&nnfødt (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "&Innebygget så innfødt" #: winecfg.rc:212 @@ -13221,19 +13225,25 @@ "redigeres." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Legg til..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "&Automatisk" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Finn automatisk" #: winecfg.rc:241 msgid "&Path:" msgstr "&Sti:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Avansert visning" #: winecfg.rc:249 @@ -13253,7 +13263,9 @@ msgstr "S&erienummer:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Vis .-filer" #: winecfg.rc:265 @@ -13335,7 +13347,9 @@ msgstr "Velg Unix-målkatalogen." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Enkel visning" #: winecfg.rc:39 @@ -13808,7 +13822,11 @@ msgstr "Konfigurasjonsfeil" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "Skjermens hurtigminnestørrelse må være større eller lik vinduets" #: wineconsole.rc:37 @@ -14513,6 +14531,10 @@ msgid "Tab stops" msgstr "Tabulatorstopp" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Legg til" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Fjern all&e" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/nl.po wine-staging-1.9.3~ubuntu12.04.1/po/nl.po --- wine-staging-1.9.0~ubuntu12.04.1/po/nl.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/nl.po 2016-02-08 19:32:34.000000000 +0000 @@ -13258,7 +13258,9 @@ "maken." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "Toepassing toevoegen..." #: winecfg.rc:160 @@ -13320,9 +13322,9 @@ msgid "&New override for library:" msgstr "Nieuwe override voor dll:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Toevoegen" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13349,7 +13351,9 @@ msgstr "Wi&ndows (MSWindows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Bui<in dan Native" #: winecfg.rc:212 @@ -13375,19 +13379,25 @@ "worden bewerkt." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Toevoegen..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "&Automatisch instellen" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "&Automatisch detecteren" #: winecfg.rc:241 msgid "&Path:" msgstr "&Pad:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Toon uitgebreid" #: winecfg.rc:249 @@ -13407,7 +13417,9 @@ msgstr "S&erienummer:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Toon \".\" bestanden" #: winecfg.rc:265 @@ -13489,7 +13501,9 @@ msgstr "Selecteer de Unix doelmap a.u.b." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Verberg uitgebreid" #: winecfg.rc:39 @@ -13967,7 +13981,11 @@ msgstr "Configuratiefout" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "De schermbuffer moet groter dan of gelijk zijn aan de vensterbuffer" #: wineconsole.rc:37 @@ -14679,6 +14697,10 @@ msgid "Tab stops" msgstr "Tab-einden" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Toevoegen" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Verwijder al&len" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/or.po wine-staging-1.9.3~ubuntu12.04.1/po/or.po --- wine-staging-1.9.0~ubuntu12.04.1/po/or.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/or.po 2016-02-08 19:32:34.000000000 +0000 @@ -12429,7 +12429,7 @@ msgstr "" #: winecfg.rc:159 -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "" #: winecfg.rc:160 @@ -12487,8 +12487,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -12517,7 +12517,7 @@ msgstr "" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -12539,11 +12539,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12551,7 +12551,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -12571,7 +12571,7 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" +msgid "&Show dot files" msgstr "" #: winecfg.rc:265 @@ -12651,7 +12651,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13102,7 +13102,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -13794,6 +13796,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/pa.po wine-staging-1.9.3~ubuntu12.04.1/po/pa.po --- wine-staging-1.9.0~ubuntu12.04.1/po/pa.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/pa.po 2016-02-08 19:32:34.000000000 +0000 @@ -12429,7 +12429,7 @@ msgstr "" #: winecfg.rc:159 -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "" #: winecfg.rc:160 @@ -12487,8 +12487,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -12517,7 +12517,7 @@ msgstr "" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -12539,11 +12539,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12551,7 +12551,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -12571,7 +12571,7 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" +msgid "&Show dot files" msgstr "" #: winecfg.rc:265 @@ -12651,7 +12651,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13102,7 +13102,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -13794,6 +13796,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/pl.po wine-staging-1.9.3~ubuntu12.04.1/po/pl.po --- wine-staging-1.9.0~ubuntu12.04.1/po/pl.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/pl.po 2016-02-08 19:32:34.000000000 +0000 @@ -13097,7 +13097,9 @@ "również dotyczą wszystkich aplikacji lub tylko wybranej." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Dodaj aplikację..." #: winecfg.rc:160 @@ -13158,9 +13160,9 @@ msgid "&New override for library:" msgstr "&Nowa reguła dla biblioteki:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "Dod&aj" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13187,7 +13189,9 @@ msgstr "Tylko &natywna (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Preferuj w&budowaną" #: winecfg.rc:212 @@ -13211,19 +13215,25 @@ "zmienić ustawień napędu." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "Dod&aj..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Wykryj &samoczynnie" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Wykryj samoczynnie" #: winecfg.rc:241 msgid "&Path:" msgstr "&Ścieżka:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Opcje z&aawansowane >>" #: winecfg.rc:249 @@ -13243,7 +13253,9 @@ msgstr "Numer s&eryjny:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Pokazuj pliki zaczynające się od kropki" #: winecfg.rc:265 @@ -13323,7 +13335,9 @@ msgstr "Proszę wybrać docelowy katalog Uniksowy." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Ukryj z&aawansowane <<" #: winecfg.rc:39 @@ -13785,7 +13799,11 @@ msgstr "Błąd ustawiania" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "Wielkość bufora ekranu musi być większa niż wielkość bufora okna" #: wineconsole.rc:37 @@ -14491,6 +14509,10 @@ msgid "Tab stops" msgstr "Pozycje tabulatorów" +#: wordpad.rc:247 +msgid "&Add" +msgstr "Dod&aj" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Usuń &wszystkie" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/pt_BR.po wine-staging-1.9.3~ubuntu12.04.1/po/pt_BR.po --- wine-staging-1.9.0~ubuntu12.04.1/po/pt_BR.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/pt_BR.po 2016-02-08 19:32:34.000000000 +0000 @@ -13109,7 +13109,9 @@ "configurações globais ou por aplicativo também nessas abas." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Adicionar aplicativo..." #: winecfg.rc:160 @@ -13170,9 +13172,9 @@ msgid "&New override for library:" msgstr "&Nova substituição para a biblioteca:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Adicionar" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13199,7 +13201,9 @@ msgstr "&Nativa (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "E&mbutida depois Nativa" #: winecfg.rc:212 @@ -13223,19 +13227,25 @@ "não pôde ser alterada." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Adicionar..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Auto &Detectar" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Auto detectar" #: winecfg.rc:241 msgid "&Path:" msgstr "&Caminho:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "&Avançado" #: winecfg.rc:249 @@ -13255,7 +13265,9 @@ msgstr "&Serial:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "&Mostrar arquivos com ponto" #: winecfg.rc:265 @@ -13335,7 +13347,9 @@ msgstr "Por favor, selecione o diretório Unix alvo." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "&Ocultar" #: winecfg.rc:39 @@ -13797,7 +13811,11 @@ msgstr "Erro de configuração" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "Tamanho do buffer de tela deve ser maior ou igual ao da janela" #: wineconsole.rc:37 @@ -14502,6 +14520,10 @@ msgid "Tab stops" msgstr "Marcas de tabulação" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Adicionar" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Remover &todos" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/pt_PT.po wine-staging-1.9.3~ubuntu12.04.1/po/pt_PT.po --- wine-staging-1.9.0~ubuntu12.04.1/po/pt_PT.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/pt_PT.po 2016-02-08 19:32:34.000000000 +0000 @@ -13085,7 +13085,9 @@ "definições por aplicação ou no sistema também nessas abas." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Adicionar aplicação..." #: winecfg.rc:160 @@ -13146,9 +13148,9 @@ msgid "&New override for library:" msgstr "&Nova substituição para:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Adicionar" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13175,7 +13177,9 @@ msgstr "&Nativa (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "E&mbutida depois Nativa" #: winecfg.rc:212 @@ -13201,19 +13205,25 @@ "ser editada." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Adicionar..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Auto&detectar" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Auto detectar" #: winecfg.rc:241 msgid "&Path:" msgstr "&Localização:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "&Avançado" #: winecfg.rc:249 @@ -13233,7 +13243,9 @@ msgstr "Nº S&erie:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Mostrar &ficheiros com pontos" #: winecfg.rc:265 @@ -13315,7 +13327,9 @@ msgstr "Por favor, seleccione o directório Unix de destino." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "&Ocultar" #: winecfg.rc:39 @@ -13790,7 +13804,11 @@ msgstr "Erro de configuração" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "O tamanho do 'buffer' do ecrã deve ser maior ou igual ao da janela" #: wineconsole.rc:37 @@ -14498,6 +14516,10 @@ msgid "Tab stops" msgstr "Marca de tabulação" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Adicionar" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Remover &todos" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/rm.po wine-staging-1.9.3~ubuntu12.04.1/po/rm.po --- wine-staging-1.9.0~ubuntu12.04.1/po/rm.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/rm.po 2016-02-08 19:32:34.000000000 +0000 @@ -12517,8 +12517,9 @@ msgstr "" #: winecfg.rc:159 -msgid "&Add application..." -msgstr "" +#, fuzzy +msgid "Add appli&cation..." +msgstr "&Annotaziun..." #: winecfg.rc:160 #, fuzzy @@ -12577,8 +12578,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -12609,7 +12610,7 @@ msgstr "" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -12632,11 +12633,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12644,7 +12645,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -12664,7 +12665,7 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" +msgid "&Show dot files" msgstr "" #: winecfg.rc:265 @@ -12747,7 +12748,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13201,7 +13202,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -13898,6 +13901,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 #, fuzzy msgid "Remove al&l" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/ro.po wine-staging-1.9.3~ubuntu12.04.1/po/ro.po --- wine-staging-1.9.0~ubuntu12.04.1/po/ro.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/ro.po 2016-02-08 19:32:34.000000000 +0000 @@ -13297,7 +13297,9 @@ "aplicație în această subfereastră." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Adaugă o aplicație..." #: winecfg.rc:160 @@ -13357,9 +13359,9 @@ msgid "&New override for library:" msgstr "Suprascriere nouă pentru librăria:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Adaugă" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13386,7 +13388,9 @@ msgstr "&Native (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Bui<in apoi Native" #: winecfg.rc:212 @@ -13412,19 +13416,25 @@ "fi schimbată." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Adaugă..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "&Detectează" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Detectează automat" #: winecfg.rc:241 msgid "&Path:" msgstr "&Calea:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Afișează opțiunile a&vansate" #: winecfg.rc:249 @@ -13444,7 +13454,9 @@ msgstr "N&umăr de serie:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Afișează &fișierele ascunse" #: winecfg.rc:265 @@ -13526,7 +13538,9 @@ msgstr "Selectați dosarul destinație unix." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Ascunde opțiunile a&vansate" #: winecfg.rc:39 @@ -14003,7 +14017,11 @@ msgstr "Eroare de configurare" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" "Mărimea memoriei tampon a ecranului trebuie să fie egală sau mai mare decât " "cea a ferestrei" @@ -14708,6 +14726,10 @@ msgid "Tab stops" msgstr "Spațiere tab" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Adaugă" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "E&limină tot" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/ru.po wine-staging-1.9.3~ubuntu12.04.1/po/ru.po --- wine-staging-1.9.0~ubuntu12.04.1/po/ru.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/ru.po 2016-02-08 19:32:34.000000000 +0000 @@ -5,7 +5,7 @@ "Project-Id-Version: Wine\n" "Report-Msgid-Bugs-To: http://bugs.winehq.org\n" "POT-Creation-Date: N/A\n" -"PO-Revision-Date: 2015-12-23 01:22+0300\n" +"PO-Revision-Date: 2016-01-26 15:30+0300\n" "Last-Translator: Nikolay Sivov \n" "Language-Team: Russian\n" "Language: ru\n" @@ -13041,7 +13041,7 @@ "приложения, так и глобально." #: winecfg.rc:159 -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Добавить приложение..." #: winecfg.rc:160 @@ -13101,9 +13101,9 @@ msgid "&New override for library:" msgstr "Новое замещение для библиотеки:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Установить" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "&Добавить" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13127,15 +13127,15 @@ #: winecfg.rc:210 msgid "&Native (Windows)" -msgstr "С&торонняя (Windows)" +msgstr "&Сторонняя (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" -msgstr "В&строенная, затем сторонняя" +msgid "Buil&tin then Native" +msgstr "Вс&троенная, затем сторонняя" #: winecfg.rc:212 msgid "Nati&ve then Builtin" -msgstr "Ст&оронняя, затем встроенная" +msgstr "Сто&ронняя, затем встроенная" #: winecfg.rc:220 msgid "Select Drive Letter" @@ -13154,11 +13154,11 @@ "редактироваться." #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "&Добавить..." #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "&Автоопределение" #: winecfg.rc:241 @@ -13166,8 +13166,8 @@ msgstr "&Путь:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" -msgstr "&Дополнительно" +msgid "Show Advan&ced" +msgstr "До&полнительно" #: winecfg.rc:249 msgid "De&vice:" @@ -13186,8 +13186,8 @@ msgstr "Сер. &номер:" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "Показывать файлы, начинающиеся с точки" +msgid "&Show dot files" +msgstr "Показывать файлы, начинающиеся с &точки" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -13266,8 +13266,8 @@ msgstr "Выберите целевой каталог в системе." #: winecfg.rc:37 -msgid "Hide &Advanced" -msgstr "Скрыть дополнительные" +msgid "Hide Advan&ced" +msgstr "&Скрыть доп. настройки" #: winecfg.rc:39 msgid "(No Theme)" @@ -13728,7 +13728,11 @@ msgstr "Ошибка настройки" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "Размер буфера экрана должен быть не менее буфера окна" #: wineconsole.rc:37 @@ -14433,6 +14437,10 @@ msgid "Tab stops" msgstr "Позиции табуляции" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Установить" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Очистить &все" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/sk.po wine-staging-1.9.3~ubuntu12.04.1/po/sk.po --- wine-staging-1.9.0~ubuntu12.04.1/po/sk.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/sk.po 2016-02-08 19:32:34.000000000 +0000 @@ -12693,7 +12693,9 @@ "alebo pre konkrétnu aplikáciu nastavenia v týchto kartách." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Pridať aplikáciu..." #: winecfg.rc:160 @@ -12754,9 +12756,9 @@ msgid "&New override for library:" msgstr "&Nové prepísanie pre knižnicu:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Pridať" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -12783,7 +12785,9 @@ msgstr "&Natívne (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Vst&avané potom natívne" #: winecfg.rc:212 @@ -12806,11 +12810,14 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Pridať..." #: winecfg.rc:238 -msgid "Auto&detect" +#, fuzzy +msgid "Aut&odetect" msgstr "Automatická &detekcia" #: winecfg.rc:241 @@ -12818,7 +12825,9 @@ msgstr "&Cesta:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Ukáž &pokročilé" #: winecfg.rc:249 @@ -12838,8 +12847,9 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "" +#, fuzzy +msgid "&Show dot files" +msgstr "&Detaily" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -12921,8 +12931,10 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" -msgstr "" +#, fuzzy +#| msgid "Advanced" +msgid "Hide Advan&ced" +msgstr "Pokročilý" #: winecfg.rc:39 msgid "(No Theme)" @@ -13386,7 +13398,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -14091,6 +14105,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Pridať" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Odstrániť &všetko" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/sl.po wine-staging-1.9.3~ubuntu12.04.1/po/sl.po --- wine-staging-1.9.0~ubuntu12.04.1/po/sl.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/sl.po 2016-02-08 19:32:34.000000000 +0000 @@ -13227,7 +13227,9 @@ "posamezne programe." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Dodaj program ..." #: winecfg.rc:160 @@ -13288,9 +13290,9 @@ msgid "&New override for library:" msgstr "&Nov prepis za knjižnico:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Dodaj" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13317,7 +13319,9 @@ msgstr "&Izvorna (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Vgra&jena, izvorna" #: winecfg.rc:212 @@ -13343,11 +13347,14 @@ "nastavitev pogonov ne bo mogoče urejati." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Dodaj ..." #: winecfg.rc:238 -msgid "Auto&detect" +#, fuzzy +msgid "Aut&odetect" msgstr "&Samodejno zaznaj" #: winecfg.rc:241 @@ -13355,7 +13362,9 @@ msgstr "&Pot:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Pokaži &napredno" #: winecfg.rc:249 @@ -13375,7 +13384,9 @@ msgstr "Zapor&edna št.:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Pokaži &datoteke s piko" #: winecfg.rc:265 @@ -13457,7 +13468,9 @@ msgstr "Izberite ciljno mapo Unix." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Skrij &napredno" #: winecfg.rc:39 @@ -13934,7 +13947,11 @@ msgstr "Napaka nastavitve" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "Velikost zaslonskega medpomnilnika mora biti večja ali enaka okenskemu" #: wineconsole.rc:37 @@ -14652,6 +14669,10 @@ msgid "Tab stops" msgstr "Položaji tabulatorja" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Dodaj" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Odstrani v&se" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/sr_RS@cyrillic.po wine-staging-1.9.3~ubuntu12.04.1/po/sr_RS@cyrillic.po --- wine-staging-1.9.0~ubuntu12.04.1/po/sr_RS@cyrillic.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/sr_RS@cyrillic.po 2016-02-08 19:32:34.000000000 +0000 @@ -13155,7 +13155,7 @@ #: winecfg.rc:159 #, fuzzy -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "програм" #: winecfg.rc:160 @@ -13218,8 +13218,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -13252,7 +13252,7 @@ msgstr "&Прозор" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -13276,11 +13276,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -13288,7 +13288,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -13313,8 +13313,9 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "" +#, fuzzy +msgid "&Show dot files" +msgstr "&Детаљи" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -13401,7 +13402,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13904,7 +13905,9 @@ msgstr "Грешка у радњама" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -14655,6 +14658,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 #, fuzzy msgid "Remove al&l" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/sr_RS@latin.po wine-staging-1.9.3~ubuntu12.04.1/po/sr_RS@latin.po --- wine-staging-1.9.0~ubuntu12.04.1/po/sr_RS@latin.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/sr_RS@latin.po 2016-02-08 19:32:34.000000000 +0000 @@ -13305,7 +13305,9 @@ "podešavanje aplikacija u istim tabovima." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Dodaj aplikaciju..." #: winecfg.rc:160 @@ -13368,9 +13370,9 @@ msgid "&New override for library:" msgstr "&Novo podešavanje biblioteke:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Dodaj" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13398,7 +13400,9 @@ msgstr "&Native (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Bui<in pa Native" #: winecfg.rc:212 @@ -13424,11 +13428,14 @@ "izmeniti." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Dodaj..." #: winecfg.rc:238 -msgid "Auto&detect" +#, fuzzy +msgid "Aut&odetect" msgstr "Auto&matski" #: winecfg.rc:241 @@ -13436,7 +13443,9 @@ msgstr "&Putanja:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Pokaži &Napredno" #: winecfg.rc:249 @@ -13456,7 +13465,9 @@ msgstr "S&erijski:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Prikaži &dot fajlove" #: winecfg.rc:265 @@ -13541,7 +13552,9 @@ msgstr "Izaberite unix glavni direktorijum, molim." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Sakrij &Napredno" #: winecfg.rc:39 @@ -14044,7 +14057,9 @@ msgstr "Greška u radnjama" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -14798,6 +14813,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Dodaj" + #: wordpad.rc:251 #, fuzzy msgid "Remove al&l" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/sv.po wine-staging-1.9.3~ubuntu12.04.1/po/sv.po --- wine-staging-1.9.0~ubuntu12.04.1/po/sv.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/sv.po 2016-02-08 19:32:34.000000000 +0000 @@ -12913,7 +12913,9 @@ "program." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Lägg till program..." #: winecfg.rc:160 @@ -12974,9 +12976,9 @@ msgid "&New override for library:" msgstr "&Ny åsidosättning för bibliotek:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "Lägg &till" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13003,7 +13005,9 @@ msgstr "&Ursprunglig (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Inb&yggd sedan Ursprunglig" #: winecfg.rc:212 @@ -13027,19 +13031,25 @@ "Enhetskonfigurationen kan inte redigeras." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Lägg till..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Upptäck aut&omatiskt" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Upptäck automatiskt" #: winecfg.rc:241 msgid "&Path:" msgstr "&Sökväg:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Visa &avancerat" #: winecfg.rc:249 @@ -13059,7 +13069,9 @@ msgstr "S&erienr:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Visa &punktfiler" #: winecfg.rc:265 @@ -13139,7 +13151,9 @@ msgstr "Välj unix-målkatalog, tack." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Dölj &avancerat" #: winecfg.rc:39 @@ -13600,7 +13614,9 @@ msgstr "Konfigurationsfel" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -14305,6 +14321,10 @@ msgid "Tab stops" msgstr "Tabbstopp" +#: wordpad.rc:247 +msgid "&Add" +msgstr "Lägg &till" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Ta bort a&lla" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/te.po wine-staging-1.9.3~ubuntu12.04.1/po/te.po --- wine-staging-1.9.0~ubuntu12.04.1/po/te.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/te.po 2016-02-08 19:32:34.000000000 +0000 @@ -12429,7 +12429,7 @@ msgstr "" #: winecfg.rc:159 -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "" #: winecfg.rc:160 @@ -12487,8 +12487,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -12517,7 +12517,7 @@ msgstr "" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -12539,11 +12539,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12551,7 +12551,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -12571,7 +12571,7 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" +msgid "&Show dot files" msgstr "" #: winecfg.rc:265 @@ -12651,7 +12651,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13102,7 +13102,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -13794,6 +13796,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/th.po wine-staging-1.9.3~ubuntu12.04.1/po/th.po --- wine-staging-1.9.0~ubuntu12.04.1/po/th.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/th.po 2016-02-08 19:32:34.000000000 +0000 @@ -12678,7 +12678,7 @@ msgstr "" #: winecfg.rc:159 -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "" #: winecfg.rc:160 @@ -12737,8 +12737,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -12767,7 +12767,7 @@ msgstr "" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -12791,11 +12791,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12803,7 +12803,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -12823,8 +12823,9 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "" +#, fuzzy +msgid "&Show dot files" +msgstr "รายละเอียด" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -12907,7 +12908,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13373,7 +13374,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -14091,6 +14094,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/tr.po wine-staging-1.9.3~ubuntu12.04.1/po/tr.po --- wine-staging-1.9.0~ubuntu12.04.1/po/tr.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/tr.po 2016-02-08 19:32:34.000000000 +0000 @@ -13057,7 +13057,9 @@ "çapındaki veya uygulamaya özel ayarları yapmanıza izin verir." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "Uygulama &Ekle..." #: winecfg.rc:160 @@ -13118,9 +13120,9 @@ msgid "&New override for library:" msgstr "Kitaplık için yeni öncelik:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Ekle" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13147,7 +13149,9 @@ msgstr "&Doğal (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "Önce Yer&leşik sonra Doğal" #: winecfg.rc:212 @@ -13170,11 +13174,15 @@ "Bağlama yöneticisine bağlanılamadı, sürücü yapılandırması düzenlenemiyor." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Ekle..." #: winecfg.rc:238 -msgid "Auto&detect" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" msgstr "Otomatik &Algıla" #: winecfg.rc:241 @@ -13182,7 +13190,9 @@ msgstr "&Yol:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Gelişmiş Ayarlar" #: winecfg.rc:249 @@ -13202,7 +13212,9 @@ msgstr "S&eri No:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Noktayla başlayan dosyaları göster" #: winecfg.rc:265 @@ -13282,7 +13294,9 @@ msgstr "Lütfen Unix hedef dizinini seçin." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Temel Ayarlar" #: winecfg.rc:39 @@ -13745,7 +13759,11 @@ msgstr "Yapılandırma hatası" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "Ekran tamponu en az pencereninki kadar büyük olmalıdır" #: wineconsole.rc:37 @@ -14447,6 +14465,10 @@ msgid "Tab stops" msgstr "Sekme durmaları" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Ekle" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Tümünü &kaldır" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/uk.po wine-staging-1.9.3~ubuntu12.04.1/po/uk.po --- wine-staging-1.9.0~ubuntu12.04.1/po/uk.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/uk.po 2016-02-08 19:32:34.000000000 +0000 @@ -13122,7 +13122,9 @@ "цих вкладках як для окремої програми, так і глобально." #: winecfg.rc:159 -msgid "&Add application..." +#, fuzzy +#| msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Додати програму..." #: winecfg.rc:160 @@ -13182,9 +13184,9 @@ msgid "&New override for library:" msgstr "&Нове заміщення для бібліотеки:" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "&Додати" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13211,7 +13213,9 @@ msgstr "&Стороння (Windows)" #: winecfg.rc:211 -msgid "Bui<in then Native" +#, fuzzy +#| msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "В&будована, потім стороння" #: winecfg.rc:212 @@ -13235,19 +13239,25 @@ "редагуватися." #: winecfg.rc:236 -msgid "&Add..." +#, fuzzy +#| msgid "&Add..." +msgid "A&dd..." msgstr "&Додати..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "Автови&значення" +#, fuzzy +#| msgid "Autodetect" +msgid "Aut&odetect" +msgstr "Автовизначення" #: winecfg.rc:241 msgid "&Path:" msgstr "&Шлях:" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +#, fuzzy +#| msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "Показати &Додаткове" #: winecfg.rc:249 @@ -13267,7 +13277,9 @@ msgstr "&Сер.ном:" #: winecfg.rc:258 -msgid "Show &dot files" +#, fuzzy +#| msgid "Show &dot files" +msgid "&Show dot files" msgstr "Показати &файли, що починаються з крапки" #: winecfg.rc:265 @@ -13347,7 +13359,9 @@ msgstr "Будь ласка, виберіть цільову теку Unix." #: winecfg.rc:37 -msgid "Hide &Advanced" +#, fuzzy +#| msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "Сховати &Додаткове" #: winecfg.rc:39 @@ -13809,7 +13823,11 @@ msgstr "Помилка конфігурації" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "Розмір буфера екрану повинен бути не менший буфера вікна" #: wineconsole.rc:37 @@ -14513,6 +14531,10 @@ msgid "Tab stops" msgstr "Позиції табуляції" +#: wordpad.rc:247 +msgid "&Add" +msgstr "&Додати" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "Видалити в&се" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/wa.po wine-staging-1.9.3~ubuntu12.04.1/po/wa.po --- wine-staging-1.9.0~ubuntu12.04.1/po/wa.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/wa.po 2016-02-08 19:32:34.000000000 +0000 @@ -12587,7 +12587,7 @@ #: winecfg.rc:159 #, fuzzy -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "&Options" #: winecfg.rc:160 @@ -12646,8 +12646,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -12677,7 +12677,7 @@ msgstr "Å dfait di &Wine..." #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -12700,11 +12700,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12712,7 +12712,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -12732,7 +12732,7 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" +msgid "&Show dot files" msgstr "" #: winecfg.rc:265 @@ -12816,7 +12816,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13278,7 +13278,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -13997,6 +13999,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 #, fuzzy msgid "Remove al&l" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/wine.pot wine-staging-1.9.3~ubuntu12.04.1/po/wine.pot --- wine-staging-1.9.0~ubuntu12.04.1/po/wine.pot 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/wine.pot 2016-02-08 19:32:34.000000000 +0000 @@ -12363,7 +12363,7 @@ msgstr "" #: winecfg.rc:159 -msgid "&Add application..." +msgid "Add appli&cation..." msgstr "" #: winecfg.rc:160 @@ -12421,8 +12421,8 @@ msgid "&New override for library:" msgstr "" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" +#: winecfg.rc:196 +msgid "A&dd" msgstr "" #: winecfg.rc:197 @@ -12450,7 +12450,7 @@ msgstr "" #: winecfg.rc:211 -msgid "Bui<in then Native" +msgid "Buil&tin then Native" msgstr "" #: winecfg.rc:212 @@ -12472,11 +12472,11 @@ msgstr "" #: winecfg.rc:236 -msgid "&Add..." +msgid "A&dd..." msgstr "" #: winecfg.rc:238 -msgid "Auto&detect" +msgid "Aut&odetect" msgstr "" #: winecfg.rc:241 @@ -12484,7 +12484,7 @@ msgstr "" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" +msgid "Show Advan&ced" msgstr "" #: winecfg.rc:249 @@ -12504,7 +12504,7 @@ msgstr "" #: winecfg.rc:258 -msgid "Show &dot files" +msgid "&Show dot files" msgstr "" #: winecfg.rc:265 @@ -12584,7 +12584,7 @@ msgstr "" #: winecfg.rc:37 -msgid "Hide &Advanced" +msgid "Hide Advan&ced" msgstr "" #: winecfg.rc:39 @@ -13033,7 +13033,9 @@ msgstr "" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "" #: wineconsole.rc:37 @@ -13713,6 +13715,10 @@ msgid "Tab stops" msgstr "" +#: wordpad.rc:247 +msgid "&Add" +msgstr "" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/zh_CN.po wine-staging-1.9.3~ubuntu12.04.1/po/zh_CN.po --- wine-staging-1.9.0~ubuntu12.04.1/po/zh_CN.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/zh_CN.po 2016-02-08 19:32:34.000000000 +0000 @@ -12513,11 +12513,11 @@ #: winecfg.rc:144 msgid "&Owner:" -msgstr "姓名:" +msgstr "姓名(&O):" #: winecfg.rc:146 msgid "Organi&zation:" -msgstr "组织(_Z):" +msgstr "组织(&Z):" #: winecfg.rc:154 msgid "Application settings" @@ -12533,8 +12533,8 @@ "示”标签页中作不同的设置。" #: winecfg.rc:159 -msgid "&Add application..." -msgstr "增加程序设置(&A)..." +msgid "Add appli&cation..." +msgstr "增加程序设置(&C)..." #: winecfg.rc:160 msgid "&Remove application" @@ -12593,9 +12593,9 @@ msgid "&New override for library:" msgstr "新增函数库顶替(&N):" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "添加(&A)" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "添加(&D)" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -12622,8 +12622,8 @@ msgstr "原装(Windows)(&N)" #: winecfg.rc:211 -msgid "Bui<in then Native" -msgstr "内建先于原装(&L)" +msgid "Buil&tin then Native" +msgstr "内建先于原装(&T)" #: winecfg.rc:212 msgid "Nati&ve then Builtin" @@ -12644,20 +12644,20 @@ msgstr "无法连接到挂载管理器。不能修改驱动器配置。" #: winecfg.rc:236 -msgid "&Add..." -msgstr "添加(&A)..." +msgid "A&dd..." +msgstr "添加(&D)..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "自动侦测(&D)" +msgid "Aut&odetect" +msgstr "自动侦测(&O)" #: winecfg.rc:241 msgid "&Path:" msgstr "路径(&P):" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" -msgstr "显示高级选项(&A)" +msgid "Show Advan&ced" +msgstr "显示高级选项(&C)" #: winecfg.rc:249 msgid "De&vice:" @@ -12676,8 +12676,8 @@ msgstr "序列号(&E):" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "显示隐藏文件(&D)" +msgid "&Show dot files" +msgstr "显示隐藏文件(&S)" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -12756,8 +12756,8 @@ msgstr "请选择目标 Unix 文件夹。" #: winecfg.rc:37 -msgid "Hide &Advanced" -msgstr "隐藏高级选项(&A)" +msgid "Hide Advan&ced" +msgstr "隐藏高级选项(&C)" #: winecfg.rc:39 msgid "(No Theme)" @@ -13218,7 +13218,11 @@ msgstr "配置错误" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "屏幕缓冲区大小必须不小于窗口" #: wineconsole.rc:37 @@ -13917,6 +13921,10 @@ msgid "Tab stops" msgstr "制表位宽度" +#: wordpad.rc:247 +msgid "&Add" +msgstr "添加(&A)" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "全部删除(&R)" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/po/zh_TW.po wine-staging-1.9.3~ubuntu12.04.1/po/zh_TW.po --- wine-staging-1.9.0~ubuntu12.04.1/po/zh_TW.po 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/po/zh_TW.po 2016-02-08 19:32:34.000000000 +0000 @@ -13140,8 +13140,8 @@ "到這個分頁, 除了調整預設設定, 也能調整個別程式的設定。" #: winecfg.rc:159 -msgid "&Add application..." -msgstr "新增程式設定(&A)..." +msgid "Add appli&cation..." +msgstr "新增程式設定(&C)..." #: winecfg.rc:160 msgid "&Remove application" @@ -13200,9 +13200,9 @@ msgid "&New override for library:" msgstr "新增函式庫覆載(&N):" -#: winecfg.rc:196 wordpad.rc:247 -msgid "&Add" -msgstr "新增(&A)" +#: winecfg.rc:196 +msgid "A&dd" +msgstr "新增(&D)" #: winecfg.rc:197 msgid "Existing &overrides:" @@ -13229,8 +13229,8 @@ msgstr "原生(Windows)(&N)" #: winecfg.rc:211 -msgid "Bui<in then Native" -msgstr "內建先於原生(&L)" +msgid "Buil&tin then Native" +msgstr "內建先於原生(&T)" #: winecfg.rc:212 msgid "Nati&ve then Builtin" @@ -13253,20 +13253,20 @@ msgstr "連線到掛載管理員時失敗,無法編輯磁碟組態。" #: winecfg.rc:236 -msgid "&Add..." -msgstr "加入(&A)..." +msgid "A&dd..." +msgstr "加入(&D)..." #: winecfg.rc:238 -msgid "Auto&detect" -msgstr "自動偵測(&D)" +msgid "Aut&odetect" +msgstr "自動偵測(&O)" #: winecfg.rc:241 msgid "&Path:" msgstr "路徑(&P):" #: winecfg.rc:248 winecfg.rc:38 -msgid "Show &Advanced" -msgstr "顯示進階選項(&A)" +msgid "Show Advan&ced" +msgstr "顯示進階選項(&C)" #: winecfg.rc:249 msgid "De&vice:" @@ -13285,8 +13285,8 @@ msgstr "序號(&E):" #: winecfg.rc:258 -msgid "Show &dot files" -msgstr "顯示隱藏檔案(&D)" +msgid "&Show dot files" +msgstr "顯示隱藏檔案(&S)" #: winecfg.rc:265 msgid "Driver diagnostics" @@ -13367,8 +13367,8 @@ msgstr "請選擇 Unix 資料夾。" #: winecfg.rc:37 -msgid "Hide &Advanced" -msgstr "隱藏進階選項(&A)" +msgid "Hide Advan&ced" +msgstr "隱藏進階選項(&C)" #: winecfg.rc:39 msgid "(No Theme)" @@ -13843,7 +13843,11 @@ msgstr "組態錯誤" #: wineconsole.rc:42 -msgid "Screen buffer size must be greater or equal to the window's one" +#, fuzzy +#| msgid "Screen buffer size must be greater or equal to the window's one" +msgid "" +"The size of the screen buffer must be greater than or equal to the size of " +"the window." msgstr "螢幕緩衝區大小必須大於或等於視窗緩衝區" #: wineconsole.rc:37 @@ -14542,6 +14546,10 @@ msgid "Tab stops" msgstr "定位停點" +#: wordpad.rc:247 +msgid "&Add" +msgstr "新增(&A)" + #: wordpad.rc:251 msgid "Remove al&l" msgstr "全部刪除(&L)" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/programs/cmd/tests/test_builtins.cmd.exp wine-staging-1.9.3~ubuntu12.04.1/programs/cmd/tests/test_builtins.cmd.exp --- wine-staging-1.9.0~ubuntu12.04.1/programs/cmd/tests/test_builtins.cmd.exp 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/programs/cmd/tests/test_builtins.cmd.exp 2016-02-08 19:32:34.000000000 +0000 @@ -1207,7 +1207,7 @@ --- a batch file can delete itself file correctly deleted --- a batch file can alter itself -@todo_wine@bar +bar ---------- Testing copy Passed: Found expected dummy.file Passed: Found expected dir1\file1 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/programs/cmd/wcmdmain.c wine-staging-1.9.3~ubuntu12.04.1/programs/cmd/wcmdmain.c --- wine-staging-1.9.0~ubuntu12.04.1/programs/cmd/wcmdmain.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/programs/cmd/wcmdmain.c 2016-02-08 19:32:34.000000000 +0000 @@ -1364,7 +1364,7 @@ if (cmdList && (*cmdList)->pipeFile[0] != 0x00) { WINE_TRACE("Input coming from %s\n", wine_dbgstr_w((*cmdList)->pipeFile)); h = CreateFileW((*cmdList)->pipeFile, GENERIC_READ, - FILE_SHARE_READ, &sa, OPEN_EXISTING, + FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL); if (h == INVALID_HANDLE_VALUE) { WCMD_print_error (); @@ -1425,8 +1425,8 @@ } else { WCHAR *param = WCMD_parameter(p, 0, NULL, FALSE, FALSE); - h = CreateFileW(param, GENERIC_WRITE, 0, &sa, creationDisposition, - FILE_ATTRIBUTE_NORMAL, NULL); + h = CreateFileW(param, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, + &sa, creationDisposition, FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) { WCMD_print_error (); heap_free(cmd); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/programs/explorer/explorer.c wine-staging-1.9.3~ubuntu12.04.1/programs/explorer/explorer.c --- wine-staging-1.9.0~ubuntu12.04.1/programs/explorer/explorer.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/programs/explorer/explorer.c 2016-02-08 19:32:34.000000000 +0000 @@ -682,6 +682,7 @@ static const WCHAR arg_root[] = {'/','r','o','o','t',','}; static const WCHAR arg_select[] = {'/','s','e','l','e','c','t',','}; static const WCHAR arg_desktop[] = {'/','d','e','s','k','t','o','p'}; + static const WCHAR arg_desktop_quotes[] = {'"','/','d','e','s','k','t','o','p'}; LPWSTR p = commandline; @@ -716,6 +717,12 @@ p += sizeof(arg_desktop)/sizeof(WCHAR); manage_desktop( p ); /* the rest of the command line is handled by desktop mode */ } + /* workaround for Worms Armageddon that hardcodes a /desktop option with quotes */ + else if (strncmpW(p, arg_desktop_quotes, sizeof(arg_desktop_quotes)/sizeof(WCHAR))==0) + { + p += sizeof(arg_desktop_quotes)/sizeof(WCHAR); + manage_desktop( p ); /* the rest of the command line is handled by desktop mode */ + } else { /* left over command line is generally the path to be opened */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/programs/oleview/typelib.c wine-staging-1.9.3~ubuntu12.04.1/programs/oleview/typelib.c --- wine-staging-1.9.0~ubuntu12.04.1/programs/oleview/typelib.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/programs/oleview/typelib.c 2016-02-08 19:32:34.000000000 +0000 @@ -616,7 +616,7 @@ } bstrParamNames = HeapAlloc(GetProcessHeap(), 0, - sizeof(BSTR*)*(pFuncDesc->cParams+1)); + sizeof(BSTR)*(pFuncDesc->cParams+1)); if(FAILED(ITypeInfo_GetNames(pTypeInfo, pFuncDesc->memid, bstrParamNames, pFuncDesc->cParams+1, &namesNo))) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/programs/winecfg/winecfg.rc wine-staging-1.9.3~ubuntu12.04.1/programs/winecfg/winecfg.rc --- wine-staging-1.9.0~ubuntu12.04.1/programs/winecfg/winecfg.rc 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/programs/winecfg/winecfg.rc 2016-02-08 19:32:34.000000000 +0000 @@ -33,8 +33,8 @@ IDS_TAB_DLLS "Libraries" IDS_TAB_DRIVES "Drives" IDS_CHOOSE_PATH "Select the Unix target directory, please." - IDS_HIDE_ADVANCED "Hide &Advanced" - IDS_SHOW_ADVANCED "Show &Advanced" + IDS_HIDE_ADVANCED "Hide Advan&ced" + IDS_SHOW_ADVANCED "Show Advan&ced" IDS_NOTHEME "(No Theme)" IDS_TAB_GRAPHICS "Graphics" IDS_TAB_DESKTOP_INTEGRATION "Desktop Integration" @@ -155,7 +155,7 @@ IDC_STATIC,15,15,227,45 CONTROL "",IDC_APP_LISTVIEW,"SysListView32",WS_BORDER | WS_TABSTOP | LVS_LIST | LVS_SINGLESEL | LVS_SHOWSELALWAYS, 15,60,230,110 - PUSHBUTTON "&Add application...",IDC_APP_ADDAPP, 15,174,112,14 + PUSHBUTTON "Add appli&cation...",IDC_APP_ADDAPP, 15,174,112,14 PUSHBUTTON "&Remove application",IDC_APP_REMOVEAPP, 133,174,112,14 LTEXT "&Windows Version:",IDC_STATIC,17,196,80,8 COMBOBOX IDC_WINVER,100,194,145,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP @@ -192,7 +192,7 @@ ,IDC_STATIC,16,16,228,32 LTEXT "&New override for library:",IDC_STATIC,16,58,220,8 COMBOBOX IDC_DLLCOMBO,16,68,140,14,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP | CBS_SORT | CBS_LOWERCASE - PUSHBUTTON "&Add",IDC_DLLS_ADDDLL, 164,68,82,13 + PUSHBUTTON "A&dd",IDC_DLLS_ADDDLL, 164,68,82,13 LTEXT "Existing &overrides:",IDC_STATIC,16,86,100,8 LISTBOX IDC_DLLS_LIST,16,96,140,112,WS_BORDER | WS_TABSTOP | WS_VSCROLL PUSHBUTTON "&Edit...",IDC_DLLS_EDITDLL,164,96,82,14 @@ -207,7 +207,7 @@ GROUPBOX "Load order",IDC_STATIC,8,4,144,66 CONTROL "&Builtin (Wine)",IDC_RAD_BUILTIN,"Button", BS_AUTORADIOBUTTON | WS_GROUP,16,14,125,10 CONTROL "&Native (Windows)",IDC_RAD_NATIVE,"Button", BS_AUTORADIOBUTTON,16,24,125,10 - CONTROL "Bui<in then Native",IDC_RAD_BUILTIN_NATIVE,"Button", BS_AUTORADIOBUTTON,16,34,125,10 + CONTROL "Buil&tin then Native",IDC_RAD_BUILTIN_NATIVE,"Button", BS_AUTORADIOBUTTON,16,34,125,10 CONTROL "Nati&ve then Builtin",IDC_RAD_NATIVE_BUILTIN,"Button", BS_AUTORADIOBUTTON,16,44,125,10 CONTROL "&Disable",IDC_RAD_DISABLE,"Button", BS_AUTORADIOBUTTON,16,54,125,10 DEFPUSHBUTTON "OK",IDOK,8,74,45,14,WS_GROUP @@ -232,9 +232,9 @@ LTEXT "Failed to connect to the mount manager, the drive configuration cannot be edited.", IDC_STATIC_MOUNTMGR_ERROR, 15,30,190,76 CONTROL "",IDC_LIST_DRIVES,"SysListView32",LVS_REPORT | LVS_AUTOARRANGE | LVS_ALIGNLEFT | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP, 15,18,232,76 - PUSHBUTTON "&Add...",IDC_BUTTON_ADD,15,98,53,14 + PUSHBUTTON "A&dd...",IDC_BUTTON_ADD,15,98,53,14 PUSHBUTTON "&Remove",IDC_BUTTON_REMOVE,72,98,53,14 - PUSHBUTTON "Auto&detect",IDC_BUTTON_AUTODETECT,146,98,100,14 + PUSHBUTTON "Aut&odetect",IDC_BUTTON_AUTODETECT,146,98,100,14 /* editing drive details */ LTEXT "&Path:",IDC_STATIC_PATH,15,123,42,9 @@ -244,7 +244,7 @@ LTEXT "&Type:",IDC_STATIC_TYPE,15,138,42,10 COMBOBOX IDC_COMBO_TYPE,59,135,77,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Show &Advanced",IDC_BUTTON_SHOW_HIDE_ADVANCED,146,135,100,13 + PUSHBUTTON "Show Advan&ced",IDC_BUTTON_SHOW_HIDE_ADVANCED,146,135,100,13 LTEXT "De&vice:",IDC_STATIC_DEVICE,15,153,42,9 EDITTEXT IDC_EDIT_DEVICE,59,150,122,13,ES_AUTOHSCROLL | WS_TABSTOP PUSHBUTTON "Bro&wse...",IDC_BUTTON_BROWSE_DEVICE,186,150,60,13 @@ -254,7 +254,7 @@ LTEXT "S&erial:",IDC_STATIC_SERIAL,15,183,42,12 EDITTEXT IDC_EDIT_SERIAL,59,180,78,13,ES_AUTOHSCROLL | WS_TABSTOP - CONTROL "Show &dot files",IDC_SHOW_DOT_FILES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,205,230,8 + CONTROL "&Show dot files",IDC_SHOW_DOT_FILES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,205,230,8 END IDD_AUDIOCFG DIALOG 0, 0, 260, 220 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/programs/wineconsole/dialog.c wine-staging-1.9.3~ubuntu12.04.1/programs/wineconsole/dialog.c --- wine-staging-1.9.0~ubuntu12.04.1/programs/wineconsole/dialog.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/programs/wineconsole/dialog.c 2016-02-08 19:32:34.000000000 +0000 @@ -190,12 +190,15 @@ hFont = (HFONT)GetWindowLongPtrW(hWnd, 0); if (hFont) { + COLORREF bkcolor; WCHAR ascii[] = {'A','S','C','I','I',':',' ','a','b','c','X','Y','Z','\0'}; WCHAR buf[256]; int len; hOldFont = SelectObject(ps.hdc, hFont); - SetBkColor(ps.hdc, WCUSER_ColorMap[GetWindowLongW(GetDlgItem(di->hDlg, IDC_FNT_COLOR_BK), 0)]); + bkcolor = WCUSER_ColorMap[GetWindowLongW(GetDlgItem(di->hDlg, IDC_FNT_COLOR_BK), 0)]; + FillRect(ps.hdc, &ps.rcPaint, CreateSolidBrush(bkcolor)); + SetBkColor(ps.hdc, bkcolor); SetTextColor(ps.hdc, WCUSER_ColorMap[GetWindowLongW(GetDlgItem(di->hDlg, IDC_FNT_COLOR_FG), 0)]); len = LoadStringW(GetModuleHandleW(NULL), IDS_FNT_PREVIEW, buf, sizeof(buf) / sizeof(buf[0])); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/programs/wineconsole/wineconsole.c wine-staging-1.9.3~ubuntu12.04.1/programs/wineconsole/wineconsole.c --- wine-staging-1.9.0~ubuntu12.04.1/programs/wineconsole/wineconsole.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/programs/wineconsole/wineconsole.c 2016-02-08 19:32:34.000000000 +0000 @@ -424,11 +424,15 @@ if (strcmpiW(data->curcfg.face_name, cfg->face_name) || data->curcfg.cell_width != cfg->cell_width || data->curcfg.cell_height != cfg->cell_height || data->curcfg.font_weight != cfg->font_weight) { + RECT r; data->fnSetFont(data, cfg->face_name, cfg->cell_height, cfg->font_weight); + SystemParametersInfoW(SPI_GETWORKAREA, 0, &r, 0); SERVER_START_REQ(set_console_output_info) { req->handle = wine_server_obj_handle( data->hConOut ); - req->mask = SET_CONSOLE_OUTPUT_INFO_FONT; + req->mask = SET_CONSOLE_OUTPUT_INFO_MAX_SIZE | SET_CONSOLE_OUTPUT_INFO_FONT; + req->max_width = (r.right - r.left) / cfg->cell_width; + req->max_height = (r.bottom - r.top - GetSystemMetrics(SM_CYCAPTION)) / cfg->cell_height; req->font_width = cfg->cell_width; req->font_height = cfg->cell_height; wine_server_call( req ); @@ -437,7 +441,12 @@ } if (data->curcfg.def_attr != cfg->def_attr) { + DWORD screen_size, written; + COORD top_left = {0,0}; + data->curcfg.def_attr = cfg->def_attr; + screen_size = cfg->win_width * (cfg->win_height + 1); + FillConsoleOutputAttribute(data->hConOut, cfg->def_attr, screen_size, top_left, &written); SetConsoleTextAttribute(data->hConOut, cfg->def_attr); } /* now let's look at the window / sb size changes... diff -Nru wine-staging-1.9.0~ubuntu12.04.1/programs/wineconsole/wineconsole.rc wine-staging-1.9.3~ubuntu12.04.1/programs/wineconsole/wineconsole.rc --- wine-staging-1.9.0~ubuntu12.04.1/programs/wineconsole/wineconsole.rc 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/programs/wineconsole/wineconsole.rc 2016-02-08 19:32:34.000000000 +0000 @@ -38,7 +38,7 @@ IDS_DLG_TIT_DEFAULT, "Setup - Default settings" IDS_DLG_TIT_CURRENT, "Setup - Current settings" IDS_DLG_TIT_ERROR, "Configuration error" -IDS_DLG_ERR_SBWINSIZE, "Screen buffer size must be greater or equal to the window's one" +IDS_DLG_ERR_SBWINSIZE, "The size of the screen buffer must be greater than or equal to the size of the window." IDS_CMD_INVALID_EVENT_ID "wineconsole: Couldn't parse event id\n" IDS_CMD_INVALID_BACKEND "wineconsole: Invalid backend\n" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/programs/winefile/winefile.c wine-staging-1.9.3~ubuntu12.04.1/programs/winefile/winefile.c --- wine-staging-1.9.0~ubuntu12.04.1/programs/winefile/winefile.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/programs/winefile/winefile.c 2016-02-08 19:32:34.000000000 +0000 @@ -1634,9 +1634,10 @@ static const WCHAR shell32_dll[] = {'S','H','E','L','L','3','2','.','D','L','L',0}; void (WINAPI *pRunFileDlgAW )(HWND, HICON, LPWSTR, LPWSTR, LPWSTR, DWORD); HMODULE hshell = GetModuleHandleW( shell32_dll ); + HICON hIcon = LoadIconW(Globals.hInstance, MAKEINTRESOURCEW(IDI_WINEFILE)); pRunFileDlgAW = (void*)GetProcAddress(hshell, (LPCSTR)61); - if (pRunFileDlgAW) pRunFileDlgAW( hwnd, 0, NULL, NULL, NULL, RFF_NODEFAULT); + if (pRunFileDlgAW) pRunFileDlgAW( hwnd, hIcon, NULL, NULL, NULL, RFF_NODEFAULT); } static INT_PTR CALLBACK DestinationDlgProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam) @@ -4213,7 +4214,7 @@ wcChild.cbClsExtra = 0; wcChild.cbWndExtra = 0; wcChild.hInstance = hinstance; - wcChild.hIcon = 0; + wcChild.hIcon = LoadIconW(hinstance, MAKEINTRESOURCEW(IDI_WINEFILE)); wcChild.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW); wcChild.hbrBackground = 0; wcChild.lpszMenuName = 0; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/README.md wine-staging-1.9.3~ubuntu12.04.1/README.md --- wine-staging-1.9.0~ubuntu12.04.1/README.md 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/README.md 2016-02-08 20:07:32.000000000 +0000 @@ -8,308 +8,93 @@ they are integrated into the main branch. More information about Wine Staging can also be found on our website [wine-staging.com](http://wine-staging.com). -Although we are reviewing and testing all patches carefully before adding them, -you may encounter additional bugs, which are not present in the development -branch. Do not hesitate to report such issues at winehq.org, so they can be -fixed before the feature gets integrated. - - -How to install and use Wine Staging ------------------------------------ - -Ready-to-use packages for Wine Staging are available for a variety -of different Linux distributions directly for download. Just follow the -instructions available on the -[Wiki](https://github.com/wine-compholio/wine-staging/wiki/Installation). - -When using Wine Staging there are a few differences compared to regular -Wine. The main difference is that it is not sufficient to type `wine` to -run it, but instead you will have to type `/opt/wine-staging/bin/wine`. -Besides that there are also some other differences, for example additional -configuration options to tweak performance, which are not available in regular -Wine. All those differences are also documented on the -[Wiki](https://github.com/wine-compholio/wine-staging/wiki/Usage). - - -Included bug fixes and improvements ------------------------------------ - -**Bug fixes and features in Wine Staging 1.9.0 [269]:** - -*Note: The following list only contains features and bug fixes which are not -yet available in vanilla Wine. They are removed from the list as soon as they -are included upstream. The list also includes features and fixes from previous -releases, take a look at the -[changelog](https://github.com/wine-compholio/wine-staging/blob/master/staging/changelog) -for more details.* - -* Add IDragSourceHelper stub interface ([Wine Bug #24699](https://bugs.winehq.org/show_bug.cgi?id=24699)) -* Add IHTMLLocation::hash property's getter implementation ([Wine Bug #32967](https://bugs.winehq.org/show_bug.cgi?id=32967)) -* Add a ProfileList\ registry subkey ([Wine Bug #15670](https://bugs.winehq.org/show_bug.cgi?id=15670)) -* Add implementation for comctl32.PROPSHEET_InsertPage. ([Wine Bug #25625](https://bugs.winehq.org/show_bug.cgi?id=25625)) -* Add implementation for mfplat.MFTEnum ([Wine Bug #39309](https://bugs.winehq.org/show_bug.cgi?id=39309)) -* Add implementation for mfplat.MFTRegister ([Wine Bug #37811](https://bugs.winehq.org/show_bug.cgi?id=37811)) -* Add implementation for msidb commandline tool -* Add implementation for shlwapi.AssocGetPerceivedType -* Add nvapi stubs required for GPU PhysX support -* Add performance library registry keys needed by MS SQL Server Management Studio Express 2008 R2 ([Wine Bug #33661](https://bugs.winehq.org/show_bug.cgi?id=33661)) -* Add semi-stub for FileFsVolumeInformation information class ([Wine Bug #21466](https://bugs.winehq.org/show_bug.cgi?id=21466)) -* Add shell32 placeholder icons to match offsets with Windows ([Wine Bug #30185](https://bugs.winehq.org/show_bug.cgi?id=30185)) -* Add stub dlls required for MSVC 2015 runtime library (Windows 10) -* Add stub for D3DXComputeNormalMap -* Add stub for D3DXFrameFind ([Wine Bug #38334](https://bugs.winehq.org/show_bug.cgi?id=38334)) -* Add stub for NtSetLdtEntries/ZwSetLdtEntries ([Wine Bug #26268](https://bugs.winehq.org/show_bug.cgi?id=26268)) -* Add stub for SetCoalescableTimer ([Wine Bug #39509](https://bugs.winehq.org/show_bug.cgi?id=39509)) -* Add stub for ntoskrnl.ExAcquireResourceExclusiveLite -* Add stub for ntoskrnl.ExDeleteResourceLite -* Add stub for ntoskrnl.ExReleaseResourceForThread -* Add stub for ntoskrnl.KeWaitForMultipleObjects ([Wine Bug #32186](https://bugs.winehq.org/show_bug.cgi?id=32186)) -* Add stub for ntoskrnl.Mm{Map,Unmap}LockedPages -* Add stub for ntoskrnl.PsRemoveLoadImageNotifyRoutine -* Add stub for wininet.ParseX509EncodedCertificateForListBoxEntry ([Wine Bug #29842](https://bugs.winehq.org/show_bug.cgi?id=29842)) -* Add stub for winscard.SCardListReadersA/W ([Wine Bug #26978](https://bugs.winehq.org/show_bug.cgi?id=26978)) -* Add stub for winspool.SetPrinterW level 8 ([Wine Bug #24645](https://bugs.winehq.org/show_bug.cgi?id=24645)) -* Add stub for winsta.WinStationEnumerateW ([Wine Bug #38102](https://bugs.winehq.org/show_bug.cgi?id=38102)) -* Add stub kernel32.FreeUserPhysicalPages ([Wine Bug #39543](https://bugs.winehq.org/show_bug.cgi?id=39543)) -* Add stubbed ISWbemSecurity interfaces in wbemdisp -* Add stubs for D3DXCreateAnimationController interface -* Add stubs for additional wininet options in InternetSetOption -* Add support for CopyFileEx progress callback ([Wine Bug #22692](https://bugs.winehq.org/show_bug.cgi?id=22692)) -* Add support for GTK3 theming -* Add support for GetPropValue to PulseAudio backend -* Add support for hiding wine version information from applications ([Wine Bug #38656](https://bugs.winehq.org/show_bug.cgi?id=38656)) -* Add support for process specific debug channels -* Add wined3d detection for GeForce GT 425M ([Wine Bug #35054](https://bugs.winehq.org/show_bug.cgi?id=35054)) -* Adobe Reader needs ITextSelection_fnGetDuplicate implementation -* Allow non-nullterminated string as working directory in kernel32.create_startup_info -* Allow selection of audio device for PulseAudio backend -* Allow special characters in pipe names ([Wine Bug #28995](https://bugs.winehq.org/show_bug.cgi?id=28995)) -* Allow to cancel a file operation via progress callback ([Wine Bug #22690](https://bugs.winehq.org/show_bug.cgi?id=22690)) -* Allow to edit winecfg library override by double clicking -* Allow to open files/directories without any access rights in order to query attributes -* Allow to override number of quality levels for D3DMULTISAMPLE_NONMASKABLE. ([Wine Bug #12652](https://bugs.winehq.org/show_bug.cgi?id=12652)) -* Allow to set debug registers separately in NtSetContextThread ([Wine Bug #39454](https://bugs.winehq.org/show_bug.cgi?id=39454)) -* Allow to set pixel format for desktop window -* Allow to specify default display frequency in registry -* Also send WM_CAPTURECHANGE when capture has not changed ([Wine Bug #13683](https://bugs.winehq.org/show_bug.cgi?id=13683)) -* Always use 64-bit registry view on WOW64 setups -* Anno 1602 installer depends on Windows 98 behavior of SHFileOperationW ([Wine Bug #37916](https://bugs.winehq.org/show_bug.cgi?id=37916)) -* Assign a drive serial number during prefix creation/update ([Wine Bug #17823](https://bugs.winehq.org/show_bug.cgi?id=17823)) -* Audio stuttering and performance drops in multiple applications ([Wine Bug #30639](https://bugs.winehq.org/show_bug.cgi?id=30639)) -* Avoid corruption of caret when SetCaretPos() is called -* Avoid crashing when broken app tries to release surface although refcount is zero ([Wine Bug #18477](https://bugs.winehq.org/show_bug.cgi?id=18477)) -* Avoid race-conditions in NtReadFile() operations with write watches. -* Avoid race-conditions of async WSARecv() operations with write watches. -* Avoid race-conditions with write watches in WS2_async_accept. -* Basic handling of write watches triggered while we're on the signal stack. -* Basic support for CUDA -* Black & White needs DXTn software decoding support ([Wine Bug #14939](https://bugs.winehq.org/show_bug.cgi?id=14939)) -* CPU-Z fails to start because GetLogicalProcessorInformationEx returns FALSE -* Calculate msvcrt exponential math operations with higher precision ([Wine Bug #37149](https://bugs.winehq.org/show_bug.cgi?id=37149)) -* Catch invalid memory accesses in imagehlp.CheckSumMappedFile -* Check IsWoW64Process before calling Wow64 functions in UNIXFS_get_unix_path -* Check architecture before trying to load libraries ([Wine Bug #38021](https://bugs.winehq.org/show_bug.cgi?id=38021)) -* Check handle type for HSPFILEQ handles ([Wine Bug #12332](https://bugs.winehq.org/show_bug.cgi?id=12332)) -* Codepage conversion should fail when destination length is < 0 -* CompareString should abort on first non-matching character ([Wine Bug #37556](https://bugs.winehq.org/show_bug.cgi?id=37556)) -* Create Microsoft\Windows\Themes directory during Wineprefix creation ([Wine Bug #34910](https://bugs.winehq.org/show_bug.cgi?id=34910)) -* Create stub files for system32/drivers/etc/{services,hosts,networks,protocol} ([Wine Bug #12076](https://bugs.winehq.org/show_bug.cgi?id=12076)) -* CreateProcess does not prioritize the working directory over the system search path ([Wine Bug #23934](https://bugs.winehq.org/show_bug.cgi?id=23934)) -* D3DCompileShader should filter specific warning messages ([Wine Bug #33770](https://bugs.winehq.org/show_bug.cgi?id=33770)) -* Do not allow interruption of system APC in server_select ([Wine Bug #14697](https://bugs.winehq.org/show_bug.cgi?id=14697)) -* Do not allow to deallocate thread stack for current thread -* Do not fail when a used context is passed to wglShareLists ([Wine Bug #11436](https://bugs.winehq.org/show_bug.cgi?id=11436)) -* Do not hold reference on parent process in wineserver ([Wine Bug #37087](https://bugs.winehq.org/show_bug.cgi?id=37087)) -* Do not signal threads until they are really gone -* Do not use unixfs for devices without mountpoint -* Do not wait for hook thread startup in IDirectInput8::Initialize ([Wine Bug #21403](https://bugs.winehq.org/show_bug.cgi?id=21403)) -* Ensure NtProtectVirtualMemory and NtCreateSection are on separate pages ([Wine Bug #33162](https://bugs.winehq.org/show_bug.cgi?id=33162)) -* Ensure default route IP addresses are returned first in gethostbyname ([Wine Bug #22819](https://bugs.winehq.org/show_bug.cgi?id=22819)) -* Exception during start of fr-043 caused by missing DXTn support ([Wine Bug #37391](https://bugs.winehq.org/show_bug.cgi?id=37391)) -* Export additional OpenAL32 functions ([Wine Bug #38972](https://bugs.winehq.org/show_bug.cgi?id=38972)) -* Expose PKEY_AudioEndpoint_PhysicalSpeakers device property in PulseAudio driver -* Fake success in IViewObject::Draw stub ([Wine Bug #30611](https://bugs.winehq.org/show_bug.cgi?id=30611)) -* Fake success in kernel32.SetFileCompletionNotificationModes ([Wine Bug #38960](https://bugs.winehq.org/show_bug.cgi?id=38960)) -* Fallback to default comspec when %COMSPEC% is not set -* Fallback to system ping command when CAP_NET_RAW is not available ([Wine Bug #8332](https://bugs.winehq.org/show_bug.cgi?id=8332)) -* Fix broken textures in XIII Century: Death or Glory ([Wine Bug #25419](https://bugs.winehq.org/show_bug.cgi?id=25419)) -* Fix calculation of listbox size when horizontal scrollbar is present ([Wine Bug #38142](https://bugs.winehq.org/show_bug.cgi?id=38142)) -* Fix caps lock state issues with multiple processes ([Wine Bug #35907](https://bugs.winehq.org/show_bug.cgi?id=35907)) -* Fix comparison of punctuation characters in lstrcmp ([Wine Bug #10767](https://bugs.winehq.org/show_bug.cgi?id=10767)) -* Fix condition mask handling in RtlVerifyVersionInfo ([Wine Bug #36143](https://bugs.winehq.org/show_bug.cgi?id=36143)) -* Fix crash in Space Rangers2 caused by missing DXTn support ([Wine Bug #24983](https://bugs.winehq.org/show_bug.cgi?id=24983)) -* Fix crash of winedevice when relocation entry crosses page boundary ([Wine Bug #28254](https://bugs.winehq.org/show_bug.cgi?id=28254)) -* Fix detection of case-insensitive systems in MSYS2 -* Fix device paths in HKLM\SYSTEM\MountedDevices ([Wine Bug #38235](https://bugs.winehq.org/show_bug.cgi?id=38235)) -* Fix error handling in DeferWindowPos when passing an invalid HWND ([Wine Bug #23187](https://bugs.winehq.org/show_bug.cgi?id=23187)) -* Fix font loading in Capella ([Wine Bug #12377](https://bugs.winehq.org/show_bug.cgi?id=12377)) -* Fix for ConnectNamedPort return value in overlapped mode ([Wine Bug #16550](https://bugs.winehq.org/show_bug.cgi?id=16550)) -* Fix for programs leaking wndproc slots ([Wine Bug #32451](https://bugs.winehq.org/show_bug.cgi?id=32451)) -* Fix graphical corruption in FarCry 3 with NVIDIA drivers ([Wine Bug #35062](https://bugs.winehq.org/show_bug.cgi?id=35062)) -* Fix handling of ANSI NTLM credentials ([Wine Bug #37063](https://bugs.winehq.org/show_bug.cgi?id=37063)) -* Fix handling of empty section and key name for profile files. ([Wine Bug #8036](https://bugs.winehq.org/show_bug.cgi?id=8036)) -* Fix handling of invert_y in DrawTextExW ([Wine Bug #22109](https://bugs.winehq.org/show_bug.cgi?id=22109)) -* Fix handling of window attributes for WS_EX_LAYERED | WS_EX_COMPOSITED ([Wine Bug #37876](https://bugs.winehq.org/show_bug.cgi?id=37876)) -* Fix implementation of msvcrt.close when stdout == stderr -* Fix issue causing applications to report magic loopback address instead of real IP ([Wine Bug #37271](https://bugs.winehq.org/show_bug.cgi?id=37271)) -* Fix issues with dragging layers between images in Adobe Photoshop 7.0 ([Wine Bug #12007](https://bugs.winehq.org/show_bug.cgi?id=12007)) -* Fix multithreading issues with fullscreen clipping ([Wine Bug #38087](https://bugs.winehq.org/show_bug.cgi?id=38087)) -* Fix possible leak of explorer.exe processes and implement proper desktop refcounting -* Fix possible segfault in pulse_rd_loop of PulseAudio backend -* Fix race-condition when threads are killed during shutdown -* Fix return value of ScrollWindowEx for invisible windows ([Wine Bug #37706](https://bugs.winehq.org/show_bug.cgi?id=37706)) -* Fix scaling behaviour of images and mipmap levels in IDirect3DTexture2_Load (needed for example by Prezzie Hunt) -* Fix texture corruption in CSI: Fatal Conspiracy ([Wine Bug #33768](https://bugs.winehq.org/show_bug.cgi?id=33768)) -* Fix the initialization of combined DACLs when the new DACL is empty ([Wine Bug #38423](https://bugs.winehq.org/show_bug.cgi?id=38423)) -* Fix unintentional leaks with ntdll internals -* Fix wrong colors in Wolfenstein (2009) ([Wine Bug #34692](https://bugs.winehq.org/show_bug.cgi?id=34692)) -* Fix wrong defition of ntoskrnl.IoReleaseCancelSpinLock function. -* Fix wrong version of ID3DXEffect interface for d3dx9_24 -* Fix wrong version of ID3DXEffect interface for d3dx9_25 ([Wine Bug #25138](https://bugs.winehq.org/show_bug.cgi?id=25138)) -* GetMessage should remove already seen messages with higher priority ([Wine Bug #28884](https://bugs.winehq.org/show_bug.cgi?id=28884)) -* GetMonitorInfo returns the same name for all monitors ([Wine Bug #37709](https://bugs.winehq.org/show_bug.cgi?id=37709)) -* GetSecurityInfo returns NULL DACL for process object ([Wine Bug #15980](https://bugs.winehq.org/show_bug.cgi?id=15980)) -* Globally invalidate key state on changes in other threads ([Wine Bug #29871](https://bugs.winehq.org/show_bug.cgi?id=29871)) -* Graphical issues in Inquisitor ([Wine Bug #32490](https://bugs.winehq.org/show_bug.cgi?id=32490)) -* Ignore socket type for protocol IPPROTO_IPV6 in getaddrinfo -* Implement AMStream GetMultiMediaStream functions ([Wine Bug #37090](https://bugs.winehq.org/show_bug.cgi?id=37090)) -* Implement D3DXGetShaderOutputSemantics -* Implement DDENUMSURFACES_CANBECREATED in IDirectDraw7::EnumSurfaces ([Wine Bug #17233](https://bugs.winehq.org/show_bug.cgi?id=17233)) -* Implement FileNamesInformation class support for NtQueryDirectoryFile -* Implement FolderImpl_Items and stubbed FolderItems interface -* Implement ID3DXEffect::FindNextValidTechnique ([Wine Bug #34101](https://bugs.winehq.org/show_bug.cgi?id=34101)) -* Implement SystemHandleInformation info class -* Implement a Courier New replacement font ([Wine Bug #20456](https://bugs.winehq.org/show_bug.cgi?id=20456)) -* Implement a Microsoft Yahei replacement font ([Wine Bug #13829](https://bugs.winehq.org/show_bug.cgi?id=13829)) -* Implement a Times New Roman replacement font ([Wine Bug #32342](https://bugs.winehq.org/show_bug.cgi?id=32342)) -* Implement additional stub functions in authz.dll -* Implement an Arial replacement font ([Wine Bug #32323](https://bugs.winehq.org/show_bug.cgi?id=32323)) -* Implement default homepage button in inetcpl.cpl -* Implement dinput device property DIPROP_USERNAME ([Wine Bug #39667](https://bugs.winehq.org/show_bug.cgi?id=39667)) -* Implement enumeration of sound devices and basic properties to dxdiagn ([Wine Bug #32613](https://bugs.winehq.org/show_bug.cgi?id=32613)) -* Implement exclusive mode in PulseAudio backend ([Wine Bug #37042](https://bugs.winehq.org/show_bug.cgi?id=37042)) -* Implement general tab for file property dialog -* Implement hal.KeQueryPerformanceCounter ([Wine Bug #39500](https://bugs.winehq.org/show_bug.cgi?id=39500)) -* Implement locking and synchronization of key states ([Wine Bug #31899](https://bugs.winehq.org/show_bug.cgi?id=31899)) -* Implement marshalling for TKIND_COCLASS ([Wine Bug #19016](https://bugs.winehq.org/show_bug.cgi?id=19016)) -* Implement mscoree._CorValidateImage for mono runtime ([Wine Bug #38662](https://bugs.winehq.org/show_bug.cgi?id=38662)) -* Implement ntoskrnl driver testing framework. -* Implement ntoskrnl.KeInitializeMutex -* Implement proper handling of CLI .NET images in Wine library loader ([Wine Bug #38661](https://bugs.winehq.org/show_bug.cgi?id=38661)) -* Implement shell32 NewMenu class with new folder item ([Wine Bug #24812](https://bugs.winehq.org/show_bug.cgi?id=24812)) -* Implement special handling for calling GetChildContainer with an empty string ([Wine Bug #38014](https://bugs.winehq.org/show_bug.cgi?id=38014)) -* Implement stub for ProcessQuotaLimits info class -* Implement stub for hid.HidP_TranslateUsagesToI8042ScanCodes ([Wine Bug #39447](https://bugs.winehq.org/show_bug.cgi?id=39447)) -* Implement stub for ntoskrnl.IoGetAttachedDeviceReference -* Implement stub for ntoskrnl.KeDelayExecutionThread. -* Implement stubless proxies on x86_64 ([Wine Bug #26768](https://bugs.winehq.org/show_bug.cgi?id=26768)) -* Implement stubs for ntoskrnl.Ex{Acquire,Release}FastMutexUnsafe -* Implement stubs for ntoskrnl.ObReferenceObjectByPointer and ntoskrnl.ObDereferenceObject -* Implement support for "Purist Mode" (override for all dlls) -* Improve INetFwAuthorizedApplication::get_ProcessImageFileName stub -* Improve ReadDataAvailable handling in FilePipeLocalInformation class -* Improve detection of symbol charset for old truetype fonts ([Wine Bug #33117](https://bugs.winehq.org/show_bug.cgi?id=33117)) -* Improve startup performance by delaying font initialization -* Improve stub for AEV_GetVolumeRange ([Wine Bug #35658](https://bugs.winehq.org/show_bug.cgi?id=35658)) -* Improve stub for ID3DXEffectImpl_CloneEffect -* Improve stub for NtQueryEaFile -* Improve stubs for AEV_{Get,Set}MasterVolumeLevel -* Improve stubs for AEV_{Get,Set}Mute -* Improve stubs for dxgi MakeWindowAssociation and GetWindowAssociation -* Improvement for heap allocation performance -* Initial implementation of wusa.exe (MSU package installer) ([Wine Bug #26757](https://bugs.winehq.org/show_bug.cgi?id=26757)) -* Initialize *lpcDevices in RasEnumDevicesA ([Wine Bug #30378](https://bugs.winehq.org/show_bug.cgi?id=30378)) -* Initialize System\CurrentControlSet\Control\TimeZoneInformation registry keys -* Jedi Knight: Dark Forces II crashes with winmm set to native ([Wine Bug #37983](https://bugs.winehq.org/show_bug.cgi?id=37983)) -* Lego Stunt Rally requires DXTn software de/encoding support ([Wine Bug #25486](https://bugs.winehq.org/show_bug.cgi?id=25486)) -* MSYS2 expects correct handling of WRITECOPY memory protection ([Wine Bug #35561](https://bugs.winehq.org/show_bug.cgi?id=35561)) -* Make ddraw1 and ddraw_surface1 vtable as writable ([Wine Bug #39534](https://bugs.winehq.org/show_bug.cgi?id=39534)) -* Make it possible to change media center / tablet pc status ([Wine Bug #18732](https://bugs.winehq.org/show_bug.cgi?id=18732)) -* Map EXDEV error code to STATUS_NOT_SAME_DEVICE -* MediaCoder needs CUDA for video encoding ([Wine Bug #37664](https://bugs.winehq.org/show_bug.cgi?id=37664)) -* Multiple applications need EnumDisplayDevicesW implementation ([Wine Bug #34978](https://bugs.winehq.org/show_bug.cgi?id=34978)) -* Need for Speed 3 installer requires devices in HKEY_DYN_DATA ([Wine Bug #7115](https://bugs.winehq.org/show_bug.cgi?id=7115)) -* Only set SFGAO_HASSUBFOLDER when there are really subfolders ([Wine Bug #24851](https://bugs.winehq.org/show_bug.cgi?id=24851)) -* Other Pipelight-specific enhancements -* Pass MOUSEHOOKSTRUCTEX struct to mouse hook callback ([Wine Bug #38314](https://bugs.winehq.org/show_bug.cgi?id=38314)) -* Port Royale doesn't display ocean correctly ([Wine Bug #17913](https://bugs.winehq.org/show_bug.cgi?id=17913)) -* Prevent window managers from grouping all wine programs together ([Wine Bug #32699](https://bugs.winehq.org/show_bug.cgi?id=32699)) -* Process APC calls before starting process -* Properly close sockets when WSACleanup is called ([Wine Bug #18670](https://bugs.winehq.org/show_bug.cgi?id=18670)) -* Properly handle multiple registry notifications per key -* Properly implement GetLargestConsoleWindowSize ([Wine Bug #10919](https://bugs.winehq.org/show_bug.cgi?id=10919)) -* Properly implement imagehlp.ImageLoad and ImageUnload ([Wine Bug #23455](https://bugs.winehq.org/show_bug.cgi?id=23455)) -* Properly initialize caps->dwZBufferBitDepths in ddraw7_GetCaps ([Wine Bug #27002](https://bugs.winehq.org/show_bug.cgi?id=27002)) -* Properly render themed buttons when they are pressed ([Wine Bug #37584](https://bugs.winehq.org/show_bug.cgi?id=37584)) -* Reduced SetTimer minimum value from 10 ms to 5 ms (improves Silverlight framerates) -* Refresh MDI menus when DefMDIChildProc(WM_SETTEXT) is called ([Wine Bug #21855](https://bugs.winehq.org/show_bug.cgi?id=21855)) -* Report correct ObjectName for NamedPipe wineserver objects -* Return STATUS_INVALID_DEVICE_REQUEST when trying to call NtReadFile on directory -* Return WN_NOT_CONNECTED from WNetGetUniversalName REMOTE_NAME_INFO_LEVEL stub ([Wine Bug #39452](https://bugs.winehq.org/show_bug.cgi?id=39452)) -* Return a valid mesh in D3DXCreateTeapot ([Wine Bug #36884](https://bugs.winehq.org/show_bug.cgi?id=36884)) -* Return correct IMediaSeeking stream positions in quartz -* Return correct values for GetThreadTimes function ([Wine Bug #20230](https://bugs.winehq.org/show_bug.cgi?id=20230)) -* Return dummy ID3DXSkinInfo interface when skinning info not present ([Wine Bug #33904](https://bugs.winehq.org/show_bug.cgi?id=33904)) -* Return fake device type when systemroot is located on virtual disk ([Wine Bug #36546](https://bugs.winehq.org/show_bug.cgi?id=36546)) -* Return proper status codes when NtReadFile/NtWriteFile is called on closed (but not disconnected) pipe -* SHFileOperation with FO_MOVE should create new directory on Vista+ ([Wine Bug #25207](https://bugs.winehq.org/show_bug.cgi?id=25207)) -* SHMapHandle should not set error when NULL is passed as hShared -* SO_CONNECT_TIME returns the appropriate time -* Send WM_PAINT event during dialog creation ([Wine Bug #35652](https://bugs.winehq.org/show_bug.cgi?id=35652)) -* Set EOF on file which has a memory mapping should fail -* Set NamedPipeState to FILE_PIPE_CLOSING_STATE on broken pipe in NtQueryInformationFile -* Share source of d3dx9_36 with d3dx9_33 to avoid Wine DLL forwards ([Wine Bug #21817](https://bugs.winehq.org/show_bug.cgi?id=21817)) -* Show unmounted devices in winecfg and allow changing the unix path -* Silence repeated FIXME message in surface_cpu_blt -* Silence repeated LocaleNameToLCID/LCIDToLocaleName unsupported flags FIXMEs ([Wine Bug #30076](https://bugs.winehq.org/show_bug.cgi?id=30076)) -* Skip unknown item when decoding a CMS certificate ([Wine Bug #34388](https://bugs.winehq.org/show_bug.cgi?id=34388)) -* Software support for Environmental Audio Extensions (EAX) -* Start SERVICE_FILE_SYSTEM_DRIVER services with winedevice ([Wine Bug #35824](https://bugs.winehq.org/show_bug.cgi?id=35824)) -* Super Mario 3: Mario Forever fails to load keyboard mapping from profile files. ([Wine Bug #18099](https://bugs.winehq.org/show_bug.cgi?id=18099)) -* Support for AllocateAndGetTcpExTableFromStack ([Wine Bug #34372](https://bugs.winehq.org/show_bug.cgi?id=34372)) -* Support for BindImageEx ([Wine Bug #3591](https://bugs.winehq.org/show_bug.cgi?id=3591)) -* Support for CSMT (command stream) to increase graphic performance ([Wine Bug #11674](https://bugs.winehq.org/show_bug.cgi?id=11674)) -* Support for CUDA GPU video decoding -* Support for D3DXGetShaderInputSemantics ([Wine Bug #22682](https://bugs.winehq.org/show_bug.cgi?id=22682)) -* Support for DDS file format in D3DXSaveTextureToFileInMemory ([Wine Bug #26898](https://bugs.winehq.org/show_bug.cgi?id=26898)) -* Support for DOS hidden/system file attributes ([Wine Bug #9158](https://bugs.winehq.org/show_bug.cgi?id=9158)) -* Support for FileFsFullSizeInformation information class -* Support for GetFinalPathNameByHandle ([Wine Bug #34851](https://bugs.winehq.org/show_bug.cgi?id=34851)) -* Support for H264 DXVA2 GPU video decoding through vaapi -* Support for ID3DXFont::DrawTextA/W ([Wine Bug #24754](https://bugs.winehq.org/show_bug.cgi?id=24754)) -* Support for ID3DXSkinInfoImpl_UpdateSkinnedMesh ([Wine Bug #32572](https://bugs.winehq.org/show_bug.cgi?id=32572)) -* Support for Junction Points ([Wine Bug #12401](https://bugs.winehq.org/show_bug.cgi?id=12401)) -* Support for KF_FLAG_DEFAULT_PATH in SHGetKnownFolderPath ([Wine Bug #30385](https://bugs.winehq.org/show_bug.cgi?id=30385)) -* Support for MPEG2 DXVA2 GPU video decoding through vaapi -* Support for NVIDIA video encoder library (nvencodeapi) -* Support for NtQuerySection ([Wine Bug #37338](https://bugs.winehq.org/show_bug.cgi?id=37338)) -* Support for SHCreateSessionKey ([Wine Bug #35630](https://bugs.winehq.org/show_bug.cgi?id=35630)) -* Support for WTSEnumerateProcessesW ([Wine Bug #29903](https://bugs.winehq.org/show_bug.cgi?id=29903)) -* Support for extra large and jumbo icon lists in shell32 ([Wine Bug #24721](https://bugs.winehq.org/show_bug.cgi?id=24721)) -* Support for inherited file ACLs -* Support for linux priority levels for faster performance -* Support for loader dll redirections -* Support for named pipe message mode (Linux only) ([Wine Bug #17195](https://bugs.winehq.org/show_bug.cgi?id=17195)) -* Support for pasting HTML from Unix applications ([Wine Bug #7372](https://bugs.winehq.org/show_bug.cgi?id=7372)) -* Support for process ACLs ([Wine Bug #22006](https://bugs.winehq.org/show_bug.cgi?id=22006)) -* Support for setcap on wine-preloader ([Wine Bug #26256](https://bugs.winehq.org/show_bug.cgi?id=26256)) -* Support for shell32 file operation progress dialog -* Support for stored file ACLs ([Wine Bug #33576](https://bugs.winehq.org/show_bug.cgi?id=33576)) -* SysAllocStringByteLen should align terminating null WCHAR -* Tumblebugs 2 requires DXTn software encoding support ([Wine Bug #29586](https://bugs.winehq.org/show_bug.cgi?id=29586)) -* Update a XIM candidate position when cursor location changes ([Wine Bug #30938](https://bugs.winehq.org/show_bug.cgi?id=30938)) -* Use GLX_MESA_query_renderer extension to get more exact GPU infos -* Use NVX_GPU_MEMORY_INFO extension for more exact video memory accounting on NVIDIA graphic cards -* Use POSIX implementation to enumerate directory content on FreeBSD ([Wine Bug #35397](https://bugs.winehq.org/show_bug.cgi?id=35397)) -* Use actual program name if available to describe PulseAudio streams -* Use manual relay for RunDLL_CallEntry16 in shell32 ([Wine Bug #23033](https://bugs.winehq.org/show_bug.cgi?id=23033)) -* Use video memory for rendering targets if possible ([Wine Bug #34906](https://bugs.winehq.org/show_bug.cgi?id=34906)) -* Use wrapper functions for syscalls to appease Chromium sandbox (32-bit) ([Wine Bug #39403](https://bugs.winehq.org/show_bug.cgi?id=39403)) -* Voobly expects correct handling of WRITECOPY memory protection ([Wine Bug #29384](https://bugs.winehq.org/show_bug.cgi?id=29384)) -* Wine ignores IDF_CHECKFIRST flag in SetupPromptForDisk ([Wine Bug #20465](https://bugs.winehq.org/show_bug.cgi?id=20465)) -* Workaround for shlwapi URLs with relative paths -* Workaround installation bug of IE7 caused by version bump -* XEMBED support for embedding Wine windows inside Linux applications -* eRacer Demo doesn't correctly display text ([Wine Bug #29598](https://bugs.winehq.org/show_bug.cgi?id=29598)) -* ntdll is missing WinSqm[Start|End]Session implementation ([Wine Bug #31971](https://bugs.winehq.org/show_bug.cgi?id=31971)) +Installation +------------ +Ready-to-use packages for Wine Staging are available for a variety of Linux +distributions and for Mac OS X. Just follow the +[installation instructions](https://github.com/wine-compholio/wine-staging/wiki/Installation) +for your operating system. + +On most distributions the `wine-staging` package is installed to +`/opt/wine-staging`, such that multiple Wine versions can be installed in +parallel. If this is the case for your distribution, you will have to type +`/opt/wine-staging/bin/wine` instead of just `wine`. The same also applies for +other wine-specific programs like `winecfg`. To learn more about how to use +Wine Staging, please take a look at the +[usage instructions](https://github.com/wine-compholio/wine-staging/wiki/Usage). + +Reporting bugs +-------------- + +Since WineConf 2015 Wine Staging is an official part of WineHQ, which means you +can report problems directly at https://bugs.winehq.org/. Most of the time bugs +found in Wine Staging also turn out to be present in the development branch, so +its recommended to open your bug in the "Wine" product, unless you are sure its +really "Wine Staging" specific. For problems with our binary packages, please +also open a bug report there. + +Building +-------- + +Wine Staging is maintained as a set of patches which has to be applied on top of +the development branch. In order to build Wine Staging, the first step is to +setup a build environment for Wine, including all required dependencies. A lot +of information about that is collected in the +[WineHQ Wiki](http://wiki.winehq.org/BuildingWine). + +In order to apply all Wine Staging patches it is recommended to use the +`patchinstall.sh` utility which takes care of applying all patches in the +correct order. For reference, the possible commandline arguments are: + +``` +Usage: ./patchinstall.sh [DESTDIR=path] [--all] [-W patchset] [patchset ...] + +Autogenerated script to apply all Wine Staging patches on your Wine +source tree. + +Configuration: + DESTDIR=path Specify the path to the wine source tree + --all Select all patches + --force-autoconf Run autoreconf and tools/make_requests after each patch + --help Display this help and exit + --no-autoconf Do not run autoreconf and tools/make_requests + --no-patchlist Do not apply patchlist (needed for 'wine --patches') + --upstream-commit Print the upstream Wine commit SHA1 and exit + --version Show version information and exit + -W patchset Exclude a specific patchset + +Backends: + --backend=patch Use regular 'patch' utility to apply patches (default) + --backend=epatch Use 'epatch' to apply patches (Gentoo only) + --backend=git-am Use 'git am' to apply patches + --backend=git-apply Use 'git apply' to apply patches + --backend=stg Import the patches using stacked git +``` + +If you want to apply *all* patches with the `patch` utility, the commandline +should look similar to this: +``` +./patches/patchinstall.sh DESTDIR="/path/to/wine" --all +``` + +Before you proceed with the compilation, please make sure that you installed all +additional build dependencies required for the Wine Staging features you are +interested in (check output of `./configure`). More information about building +Wine Staging, optional build dependencies, and hints for packagers are collected +in our [Wiki](https://github.com/wine-compholio/wine-staging/wiki/Packaging). + +Contributing +------------ + +Wine Staging mainly concentrates on experimental features and patches which are +difficult to get into the development branch. If you have a very simple bug fix +including tests, there is usually no need to send it to Wine Staging. You can +directly contribute it to the +[development branch](http://wiki.winehq.org/SubmittingPatches). However, if you +already tried that without success, or are working on such a complex area that +you do not really think its ready for inclusion, you might want to submit it to +our Staging tree. Please open a patch submission request on +[bugs.wine-staging.com](https://bugs.wine-staging.com/) including the patch. +More information is also available in our +[Wiki](https://github.com/wine-compholio/wine-staging/wiki/Contributing). diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/async.c wine-staging-1.9.3~ubuntu12.04.1/server/async.c --- wine-staging-1.9.0~ubuntu12.04.1/server/async.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/async.c 2016-02-08 19:32:34.000000000 +0000 @@ -65,6 +65,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ async_destroy /* destroy */ @@ -98,6 +100,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ async_queue_destroy /* destroy */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/atom.c wine-staging-1.9.3~ubuntu12.04.1/server/atom.c --- wine-staging-1.9.0~ubuntu12.04.1/server/atom.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/atom.c 2016-02-08 19:32:34.000000000 +0000 @@ -87,6 +87,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ atom_table_destroy /* destroy */ @@ -382,12 +384,11 @@ /* add a global atom */ DECL_HANDLER(add_atom) { - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); struct atom_table *table = get_table( req->table, 1 ); if (table) { - get_req_unicode_str( &name ); reply->atom = add_atom( table, &name ); release_object( table ); } @@ -407,12 +408,11 @@ /* find a global atom */ DECL_HANDLER(find_atom) { - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); struct atom_table *table = get_table( req->table, 0 ); if (table) { - get_req_unicode_str( &name ); reply->atom = find_atom( table, &name ); release_object( table ); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/change.c wine-staging-1.9.3~ubuntu12.04.1/server/change.c --- wine-staging-1.9.0~ubuntu12.04.1/server/change.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/change.c 2016-02-08 19:32:34.000000000 +0000 @@ -166,6 +166,8 @@ dir_get_sd, /* get_sd */ dir_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ dir_destroy /* destroy */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/class.c wine-staging-1.9.3~ubuntu12.04.1/server/class.c --- wine-staging-1.9.0~ubuntu12.04.1/server/class.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/class.c 2016-02-08 19:32:34.000000000 +0000 @@ -150,10 +150,9 @@ DECL_HANDLER(create_class) { struct window_class *class; - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); atom_t atom; - get_req_unicode_str( &name ); if (name.len) { atom = add_global_atom( NULL, &name ); @@ -197,10 +196,9 @@ DECL_HANDLER(destroy_class) { struct window_class *class; - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); atom_t atom = req->atom; - get_req_unicode_str( &name ); if (name.len) atom = find_global_atom( NULL, &name ); if (!(class = find_class( current->process, atom, req->instance ))) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/clipboard.c wine-staging-1.9.3~ubuntu12.04.1/server/clipboard.c --- wine-staging-1.9.0~ubuntu12.04.1/server/clipboard.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/clipboard.c 2016-02-08 19:32:34.000000000 +0000 @@ -65,6 +65,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ no_destroy /* destroy */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/completion.c wine-staging-1.9.3~ubuntu12.04.1/server/completion.c --- wine-staging-1.9.0~ubuntu12.04.1/server/completion.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/completion.c 2016-02-08 19:32:34.000000000 +0000 @@ -72,6 +72,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ completion_destroy /* destroy */ @@ -102,9 +104,7 @@ struct completion *completion = (struct completion *) obj; assert( obj->ops == &completion_ops ); - fprintf( stderr, "Completion " ); - dump_object_name( &completion->obj ); - fprintf( stderr, " (%u packets pending)\n", completion->depth ); + fprintf( stderr, "Completion depth=%u", completion->depth ); } static struct object_type *completion_get_type( struct object *obj ) @@ -130,7 +130,9 @@ return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); } -static struct completion *create_completion( struct directory *root, const struct unicode_str *name, unsigned int attr, unsigned int concurrent ) +static struct completion *create_completion( struct directory *root, const struct unicode_str *name, + unsigned int attr, unsigned int concurrent, + const struct security_descriptor *sd ) { struct completion *completion; @@ -140,6 +142,9 @@ { list_init( &completion->queue ); completion->depth = 0; + if (sd) default_set_sd( &completion->obj, sd, + OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ); } } @@ -174,17 +179,15 @@ { struct completion *completion; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; + const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); - reply->handle = 0; + if (!objattr) return; - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; - - if ( (completion = create_completion( root, &name, req->attributes, req->concurrent )) != NULL ) + if ((completion = create_completion( root, &name, objattr->attributes, req->concurrent, sd ))) { - reply->handle = alloc_handle( current->process, completion, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, completion, req->access, objattr->attributes ); release_object( completion ); } @@ -194,23 +197,10 @@ /* open a completion */ DECL_HANDLER(open_completion) { - struct completion *completion; - struct unicode_str name; - struct directory *root = NULL; - - reply->handle = 0; - - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; - - if ( (completion = open_object_dir( root, &name, req->attributes, &completion_ops )) != NULL ) - { - reply->handle = alloc_handle( current->process, completion, req->access, req->attributes ); - release_object( completion ); - } + struct unicode_str name = get_req_unicode_str(); - if (root) release_object( root ); + reply->handle = open_object( current->process, req->rootdir, req->access, + &completion_ops, &name, req->attributes ); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/console.c wine-staging-1.9.3~ubuntu12.04.1/server/console.c --- wine-staging-1.9.0~ubuntu12.04.1/server/console.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/console.c 2016-02-08 19:32:34.000000000 +0000 @@ -84,6 +84,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ console_input_destroy /* destroy */ @@ -116,6 +118,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ console_input_events_destroy /* destroy */ @@ -168,6 +172,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ screen_buffer_destroy /* destroy */ @@ -1018,13 +1024,6 @@ } if (req->mask & SET_CONSOLE_OUTPUT_INFO_MAX_SIZE) { - /* can only be done by renderer */ - if (current->process->console != screen_buffer->input) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - screen_buffer->max_width = req->max_width; screen_buffer->max_height = req->max_height; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/debugger.c wine-staging-1.9.3~ubuntu12.04.1/server/debugger.c --- wine-staging-1.9.0~ubuntu12.04.1/server/debugger.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/debugger.c 2016-02-08 19:32:34.000000000 +0000 @@ -81,6 +81,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ debug_event_destroy /* destroy */ @@ -105,6 +107,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ debug_ctx_destroy /* destroy */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/device.c wine-staging-1.9.3~ubuntu12.04.1/server/device.c --- wine-staging-1.9.0~ubuntu12.04.1/server/device.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/device.c 2016-02-08 19:32:34.000000000 +0000 @@ -78,6 +78,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ irp_call_destroy /* destroy */ @@ -112,6 +114,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ device_manager_destroy /* destroy */ @@ -151,6 +155,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ device_open_file, /* open_file */ no_close_handle, /* close_handle */ device_destroy /* destroy */ @@ -197,6 +203,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ device_file_close_handle, /* close_handle */ device_file_destroy /* destroy */ @@ -314,11 +322,7 @@ static void device_dump( struct object *obj, int verbose ) { - struct device *device = (struct device *)obj; - - fprintf( stderr, "Device " ); - dump_object_name( &device->obj ); - fputc( '\n', stderr ); + fputs( "Device\n", stderr ); } static struct object_type *device_get_type( struct object *obj ) @@ -712,7 +716,7 @@ DECL_HANDLER(create_device) { struct device *device; - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); struct device_manager *manager; struct directory *root = NULL; @@ -720,7 +724,6 @@ 0, &device_manager_ops ))) return; - get_req_unicode_str( &name ); if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) { release_object( manager ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/directory.c wine-staging-1.9.3~ubuntu12.04.1/server/directory.c --- wine-staging-1.9.0~ubuntu12.04.1/server/directory.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/directory.c 2016-02-08 19:32:34.000000000 +0000 @@ -64,6 +64,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ no_destroy /* destroy */ @@ -97,6 +99,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ directory_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ directory_destroy /* destroy */ @@ -108,11 +112,7 @@ static void object_type_dump( struct object *obj, int verbose ) { - assert( obj->ops == &object_type_ops ); - - fputs( "Object type ", stderr ); - dump_object_name( obj ); - fputc( '\n', stderr ); + fputs( "Object type\n", stderr ); } static struct object_type *object_type_get_type( struct object *obj ) @@ -124,11 +124,7 @@ static void directory_dump( struct object *obj, int verbose ) { - assert( obj->ops == &directory_ops ); - - fputs( "Directory ", stderr ); - dump_object_name( obj ); - fputc( '\n', stderr ); + fputs( "Directory\n", stderr ); } static struct object_type *directory_get_type( struct object *obj ) @@ -181,6 +177,20 @@ return NULL; } +int directory_link_name( struct object *obj, struct object_name *name, struct object *parent ) +{ + struct directory *dir = (struct directory *)parent; + + if (parent->ops != &directory_ops) + { + set_error( STATUS_OBJECT_TYPE_MISMATCH ); + return 0; + } + namespace_add( dir->entries, name ); + name->parent = grab_object( parent ); + return 1; +} + static void directory_destroy( struct object *obj ) { struct directory *dir = (struct directory *)obj; @@ -189,7 +199,8 @@ } static struct directory *create_directory( struct directory *root, const struct unicode_str *name, - unsigned int attr, unsigned int hash_size ) + unsigned int attr, unsigned int hash_size, + const struct security_descriptor *sd ) { struct directory *dir; @@ -199,8 +210,10 @@ if (!(dir->entries = create_namespace( hash_size ))) { release_object( dir ); - dir = NULL; + return NULL; } + if (sd) default_set_sd( &dir->obj, sd, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ); } return dir; } @@ -310,15 +323,7 @@ return obj; } - /* ATM we can't insert objects into anything else but directories */ - if (obj->ops != &directory_ops) - set_error( STATUS_OBJECT_TYPE_MISMATCH ); - else - { - struct directory *dir = (struct directory *)obj; - if ((new_obj = create_object( dir->entries, ops, &new_name, &dir->obj ))) - clear_error(); - } + if ((new_obj = create_object( obj, ops, &new_name ))) clear_error(); release_object( obj ); return new_obj; @@ -377,6 +382,8 @@ static const WCHAR dir_objtypeW[] = {'O','b','j','e','c','t','T','y','p','e','s'}; static const WCHAR dir_sessionsW[] = {'S','e','s','s','i','o','n','s'}; static const WCHAR dir_kernelW[] = {'K','e','r','n','e','l','O','b','j','e','c','t','s'}; + static const WCHAR dir_windowsW[] = {'W','i','n','d','o','w','s'}; + static const WCHAR dir_winstationsW[] = {'W','i','n','d','o','w','S','t','a','t','i','o','n','s'}; static const struct unicode_str dir_global_str = {dir_globalW, sizeof(dir_globalW)}; static const struct unicode_str dir_driver_str = {dir_driverW, sizeof(dir_driverW)}; static const struct unicode_str dir_device_str = {dir_deviceW, sizeof(dir_deviceW)}; @@ -387,6 +394,8 @@ static const struct unicode_str dir_objtype_str = {dir_objtypeW, sizeof(dir_objtypeW)}; static const struct unicode_str dir_sessions_str = {dir_sessionsW, sizeof(dir_sessionsW)}; static const struct unicode_str dir_kernel_str = {dir_kernelW, sizeof(dir_kernelW)}; + static const struct unicode_str dir_windows_str = {dir_windowsW, sizeof(dir_windowsW)}; + static const struct unicode_str dir_winstations_str = {dir_winstationsW, sizeof(dir_winstationsW)}; /* symlinks */ static const WCHAR link_dosdevW[] = {'D','o','s','D','e','v','i','c','e','s'}; @@ -435,24 +444,27 @@ }; static const struct unicode_str keyed_event_crit_sect_str = {keyed_event_crit_sectW, sizeof(keyed_event_crit_sectW)}; - struct directory *dir_driver, *dir_device, *dir_global, *dir_basenamed, *dir_sessions, *dir_kernel; + struct directory *dir_driver, *dir_device, *dir_global, *dir_basenamed, *dir_sessions, *dir_kernel, *dir_windows, *dir_winstation; struct symlink *link_dosdev, *link_global1, *link_global2, *link_local, *link_nul, *link_pipe, *link_mailslot, *link_0, *link_session; struct keyed_event *keyed_event; unsigned int i; - root_directory = create_directory( NULL, NULL, 0, HASH_SIZE ); - dir_driver = create_directory( root_directory, &dir_driver_str, 0, HASH_SIZE ); - dir_device = create_directory( root_directory, &dir_device_str, 0, HASH_SIZE ); - dir_objtype = create_directory( root_directory, &dir_objtype_str, 0, HASH_SIZE ); - dir_sessions = create_directory( root_directory, &dir_sessions_str, 0, HASH_SIZE ); - dir_kernel = create_directory( root_directory, &dir_kernel_str, 0, HASH_SIZE ); + root_directory = create_directory( NULL, NULL, 0, HASH_SIZE, NULL ); + dir_driver = create_directory( root_directory, &dir_driver_str, 0, HASH_SIZE, NULL ); + dir_device = create_directory( root_directory, &dir_device_str, 0, HASH_SIZE, NULL ); + dir_objtype = create_directory( root_directory, &dir_objtype_str, 0, HASH_SIZE, NULL ); + dir_sessions = create_directory( root_directory, &dir_sessions_str, 0, HASH_SIZE, NULL ); + dir_kernel = create_directory( root_directory, &dir_kernel_str, 0, HASH_SIZE, NULL ); + dir_windows = create_directory( root_directory, &dir_windows_str, 0, HASH_SIZE, NULL ); + dir_winstation = create_directory( dir_windows, &dir_winstations_str, 0, HASH_SIZE, NULL ); make_object_static( &root_directory->obj ); make_object_static( &dir_driver->obj ); make_object_static( &dir_objtype->obj ); + make_object_static( &dir_winstation->obj ); - dir_global = create_directory( NULL, &dir_global_str, 0, HASH_SIZE ); + dir_global = create_directory( NULL, &dir_global_str, 0, HASH_SIZE, NULL ); /* use a larger hash table for this one since it can contain a lot of objects */ - dir_basenamed = create_directory( NULL, &dir_basenamed_str, 0, 37 ); + dir_basenamed = create_directory( NULL, &dir_basenamed_str, 0, 37, NULL ); /* devices */ create_named_pipe_device( dir_device, &named_pipe_str ); @@ -460,15 +472,15 @@ create_unix_device( dir_device, &null_str, "/dev/null" ); /* symlinks */ - link_dosdev = create_symlink( root_directory, &link_dosdev_str, 0, &dir_global_str ); - link_global1 = create_symlink( dir_global, &link_global_str, 0, &dir_global_str ); - link_global2 = create_symlink( dir_basenamed, &link_global_str, 0, &dir_basenamed_str ); - link_local = create_symlink( dir_basenamed, &link_local_str, 0, &dir_basenamed_str ); - link_nul = create_symlink( dir_global, &link_nul_str, 0, &dir_null_str ); - link_pipe = create_symlink( dir_global, &link_pipe_str, 0, &dir_named_pipe_str ); - link_mailslot = create_symlink( dir_global, &link_mailslot_str, 0, &dir_mailslot_str ); - link_0 = create_symlink( dir_sessions, &link_0_str, 0, &dir_basenamed_str ); - link_session = create_symlink( dir_basenamed, &link_session_str, 0, &link_sessions_str ); + link_dosdev = create_symlink( root_directory, &link_dosdev_str, 0, &dir_global_str, NULL ); + link_global1 = create_symlink( dir_global, &link_global_str, 0, &dir_global_str, NULL ); + link_global2 = create_symlink( dir_basenamed, &link_global_str, 0, &dir_basenamed_str, NULL ); + link_local = create_symlink( dir_basenamed, &link_local_str, 0, &dir_basenamed_str, NULL ); + link_nul = create_symlink( dir_global, &link_nul_str, 0, &dir_null_str, NULL ); + link_pipe = create_symlink( dir_global, &link_pipe_str, 0, &dir_named_pipe_str, NULL ); + link_mailslot = create_symlink( dir_global, &link_mailslot_str, 0, &dir_mailslot_str, NULL ); + link_0 = create_symlink( dir_sessions, &link_0_str, 0, &dir_basenamed_str, NULL ); + link_session = create_symlink( dir_basenamed, &link_session_str, 0, &link_sessions_str, NULL ); make_object_static( (struct object *)link_dosdev ); make_object_static( (struct object *)link_global1 ); make_object_static( (struct object *)link_global2 ); @@ -494,22 +506,22 @@ release_object( dir_basenamed ); release_object( dir_sessions ); release_object( dir_kernel ); + release_object( dir_windows ); } /* create a directory object */ DECL_HANDLER(create_directory) { struct unicode_str name; - struct directory *dir, *root = NULL; + struct directory *dir, *root; + const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); - reply->handle = 0; - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; + if (!objattr) return; - if ((dir = create_directory( root, &name, req->attributes, HASH_SIZE ))) + if ((dir = create_directory( root, &name, objattr->attributes, HASH_SIZE, sd ))) { - reply->handle = alloc_handle( current->process, dir, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, dir, req->access, objattr->attributes ); release_object( dir ); } @@ -519,20 +531,10 @@ /* open a directory object */ DECL_HANDLER(open_directory) { - struct unicode_str name; - struct directory *dir, *root = NULL; - - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; + struct unicode_str name = get_req_unicode_str(); - if ((dir = open_object_dir( root, &name, req->attributes, &directory_ops ))) - { - reply->handle = alloc_handle( current->process, &dir->obj, req->access, req->attributes ); - release_object( dir ); - } - - if (root) release_object( root ); + reply->handle = open_object( current->process, req->rootdir, req->access, + &directory_ops, &name, req->attributes ); } /* get a directory entry by index */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/event.c wine-staging-1.9.3~ubuntu12.04.1/server/event.c --- wine-staging-1.9.0~ubuntu12.04.1/server/event.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/event.c 2016-02-08 19:32:34.000000000 +0000 @@ -65,6 +65,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ no_destroy /* destroy */ @@ -96,6 +98,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ no_destroy /* destroy */ @@ -153,10 +157,8 @@ { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); - fprintf( stderr, "Event manual=%d signaled=%d ", + fprintf( stderr, "Event manual=%d signaled=%d\n", event->manual_reset, event->signaled ); - dump_object_name( &event->obj ); - fputc( '\n', stderr ); } static struct object_type *event_get_type( struct object *obj ) @@ -230,11 +232,7 @@ static void keyed_event_dump( struct object *obj, int verbose ) { - struct keyed_event *event = (struct keyed_event *)obj; - assert( obj->ops == &keyed_event_ops ); - fprintf( stderr, "Keyed event " ); - dump_object_name( &event->obj ); - fputc( '\n', stderr ); + fputs( "Keyed event\n", stderr ); } static struct object_type *keyed_event_get_type( struct object *obj ) @@ -286,27 +284,20 @@ { struct event *event; struct unicode_str name; - struct directory *root = NULL; - const struct object_attributes *objattr = get_req_data(); + struct directory *root; const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); - reply->handle = 0; - - if (!objattr_is_valid( objattr, get_req_data_size() )) - return; - - sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL; - objattr_get_name( objattr, &name ); + if (!objattr) return; - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) - return; - - if ((event = create_event( root, &name, req->attributes, req->manual_reset, req->initial_state, sd ))) + if ((event = create_event( root, &name, objattr->attributes, + req->manual_reset, req->initial_state, sd ))) { if (get_error() == STATUS_OBJECT_NAME_EXISTS) - reply->handle = alloc_handle( current->process, event, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, event, req->access, objattr->attributes ); else - reply->handle = alloc_handle_no_access_check( current->process, event, req->access, req->attributes ); + reply->handle = alloc_handle_no_access_check( current->process, event, + req->access, objattr->attributes ); release_object( event ); } @@ -316,21 +307,10 @@ /* open a handle to an event */ DECL_HANDLER(open_event) { - struct unicode_str name; - struct directory *root = NULL; - struct event *event; - - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; - - if ((event = open_object_dir( root, &name, req->attributes, &event_ops ))) - { - reply->handle = alloc_handle( current->process, &event->obj, req->access, req->attributes ); - release_object( event ); - } + struct unicode_str name = get_req_unicode_str(); - if (root) release_object( root ); + reply->handle = open_object( current->process, req->rootdir, req->access, + &event_ops, &name, req->attributes ); } /* do an event operation */ @@ -375,23 +355,19 @@ { struct keyed_event *event; struct unicode_str name; - struct directory *root = NULL; - const struct object_attributes *objattr = get_req_data(); + struct directory *root; const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); - if (!objattr_is_valid( objattr, get_req_data_size() )) return; - - sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL; - objattr_get_name( objattr, &name ); - - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; + if (!objattr) return; - if ((event = create_keyed_event( root, &name, req->attributes, sd ))) + if ((event = create_keyed_event( root, &name, objattr->attributes, sd ))) { if (get_error() == STATUS_OBJECT_NAME_EXISTS) - reply->handle = alloc_handle( current->process, event, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, event, req->access, objattr->attributes ); else - reply->handle = alloc_handle_no_access_check( current->process, event, req->access, req->attributes ); + reply->handle = alloc_handle_no_access_check( current->process, event, + req->access, objattr->attributes ); release_object( event ); } if (root) release_object( root ); @@ -400,17 +376,8 @@ /* open a handle to a keyed event */ DECL_HANDLER(open_keyed_event) { - struct unicode_str name; - struct directory *root = NULL; - struct keyed_event *event; + struct unicode_str name = get_req_unicode_str(); - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) return; - - if ((event = open_object_dir( root, &name, req->attributes, &keyed_event_ops ))) - { - reply->handle = alloc_handle( current->process, &event->obj, req->access, req->attributes ); - release_object( event ); - } - if (root) release_object( root ); + reply->handle = open_object( current->process, req->rootdir, req->access, + &keyed_event_ops, &name, req->attributes ); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/fd.c wine-staging-1.9.3~ubuntu12.04.1/server/fd.c --- wine-staging-1.9.0~ubuntu12.04.1/server/fd.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/fd.c 2016-02-08 19:32:34.000000000 +0000 @@ -209,6 +209,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ fd_destroy /* destroy */ @@ -246,6 +248,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ device_destroy /* destroy */ @@ -282,6 +286,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ inode_destroy /* destroy */ @@ -320,6 +326,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ no_destroy /* destroy */ @@ -1952,7 +1960,7 @@ if (signaled) wake_up( fd->user, 0 ); } -/* set or clear the fd signaled state */ +/* check if fd is signaled */ int is_fd_signaled( struct fd *fd ) { return fd->signaled; @@ -2384,11 +2392,10 @@ /* open a file object */ DECL_HANDLER(open_file_object) { - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); struct directory *root = NULL; struct object *obj, *result; - get_req_unicode_str( &name ); if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) { if (get_error() != STATUS_OBJECT_TYPE_MISMATCH) return; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/file.c wine-staging-1.9.3~ubuntu12.04.1/server/file.c --- wine-staging-1.9.0~ubuntu12.04.1/server/file.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/file.c 2016-02-08 19:32:34.000000000 +0000 @@ -91,6 +91,8 @@ file_get_sd, /* get_sd */ file_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ file_open_file, /* open_file */ fd_close_handle, /* close_handle */ file_destroy /* destroy */ @@ -686,17 +688,16 @@ { struct object *file; struct fd *root_fd = NULL; - const struct object_attributes *objattr = get_req_data(); + struct unicode_str unicode_name; const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &unicode_name, NULL ); const char *name; data_size_t name_len; - reply->handle = 0; + if (!objattr) return; - if (!objattr_is_valid( objattr, get_req_data_size() )) - return; /* name is transferred in the unix codepage outside of the objattr structure */ - if (objattr->name_len) + if (unicode_name.len) { set_error( STATUS_INVALID_PARAMETER ); return; @@ -712,16 +713,13 @@ if (!root_fd) return; } - sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL; - - name = (const char *)get_req_data() + sizeof(*objattr) + objattr->sd_len; - name_len = get_req_data_size() - sizeof(*objattr) - objattr->sd_len; + name = get_req_data_after_objattr( objattr, &name_len ); reply->handle = 0; if ((file = create_file( root_fd, name, name_len, req->access, req->sharing, req->create, req->options, req->attrs, sd ))) { - reply->handle = alloc_handle( current->process, file, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, file, req->access, objattr->attributes ); release_object( file ); } if (root_fd) release_object( root_fd ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/handle.c wine-staging-1.9.3~ubuntu12.04.1/server/handle.c --- wine-staging-1.9.0~ubuntu12.04.1/server/handle.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/handle.c 2016-02-08 19:32:34.000000000 +0000 @@ -130,6 +130,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ handle_table_destroy /* destroy */ @@ -153,6 +155,7 @@ if (!entry->ptr) continue; fprintf( stderr, " %04x: %p %08x ", index_to_handle(i), entry->ptr, entry->access ); + dump_object_name( entry->ptr ); entry->ptr->ops->dump( entry->ptr, 0 ); } } @@ -570,21 +573,28 @@ } /* open a new handle to an existing object */ -obj_handle_t open_object( const struct namespace *namespace, const struct unicode_str *name, - const struct object_ops *ops, unsigned int access, unsigned int attr ) +obj_handle_t open_object( struct process *process, obj_handle_t parent, unsigned int access, + const struct object_ops *ops, const struct unicode_str *name, + unsigned int attributes ) { obj_handle_t handle = 0; - struct object *obj = find_object( namespace, name, attr ); - if (obj) + struct directory *root = NULL; + struct object *obj; + + if (name->len >= 65534) { - if (ops && obj->ops != ops) - set_error( STATUS_OBJECT_TYPE_MISMATCH ); - else - handle = alloc_handle( current->process, obj, access, attr ); + set_error( STATUS_OBJECT_NAME_INVALID ); + return 0; + } + + if (parent && !(root = get_directory_obj( process, parent, 0 ))) return 0; + + if ((obj = open_object_dir( root, name, attributes, ops ))) + { + handle = alloc_handle( process, obj, access, attributes ); release_object( obj ); } - else - set_error( STATUS_OBJECT_NAME_NOT_FOUND ); + if (root) release_object( root ); return handle; } @@ -745,3 +755,59 @@ release_object( obj ); } + +struct enum_handle_info +{ + unsigned int count; + struct handle_info *handle; +}; + +static int enum_handles( struct process *process, void *user ) +{ + struct enum_handle_info *info = user; + struct handle_table *table = process->handles; + struct handle_entry *entry; + struct handle_info *handle; + unsigned int i; + + if (!table) + return 0; + + for (i = 0, entry = table->entries; i <= table->last; i++, entry++) + { + if (!entry->ptr) continue; + if (!info->handle) + { + info->count++; + continue; + } + assert( info->count ); + handle = info->handle++; + handle->owner = process->id; + handle->handle = index_to_handle(i); + handle->access = entry->access & ~RESERVED_ALL; + info->count--; + } + + return 0; +} + +DECL_HANDLER(get_system_handles) +{ + struct enum_handle_info info; + struct handle_info *handle; + data_size_t max_handles = get_reply_max_size() / sizeof(*handle); + + info.handle = NULL; + info.count = 0; + enum_processes( enum_handles, &info ); + reply->count = info.count; + + if (max_handles < info.count) + set_error( STATUS_BUFFER_TOO_SMALL ); + else if ((handle = set_reply_data_size( info.count * sizeof(*handle) ))) + { + info.handle = handle; + enum_processes( enum_handles, &info ); + } +} diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/handle.h wine-staging-1.9.3~ubuntu12.04.1/server/handle.h --- wine-staging-1.9.0~ubuntu12.04.1/server/handle.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/handle.h 2016-02-08 19:32:34.000000000 +0000 @@ -44,8 +44,9 @@ extern unsigned int get_handle_access( struct process *process, obj_handle_t handle ); extern obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, struct process *dst, unsigned int access, unsigned int attr, unsigned int options ); -extern obj_handle_t open_object( const struct namespace *namespace, const struct unicode_str *name, - const struct object_ops *ops, unsigned int access, unsigned int attr ); +extern obj_handle_t open_object( struct process *process, obj_handle_t parent, unsigned int access, + const struct object_ops *ops, const struct unicode_str *name, + unsigned int attr ); extern obj_handle_t find_inherited_handle( struct process *process, const struct object_ops *ops ); extern obj_handle_t enumerate_handles( struct process *process, const struct object_ops *ops, unsigned int *index ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/hook.c wine-staging-1.9.3~ubuntu12.04.1/server/hook.c --- wine-staging-1.9.0~ubuntu12.04.1/server/hook.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/hook.c 2016-02-08 19:32:34.000000000 +0000 @@ -88,6 +88,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ hook_table_destroy /* destroy */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/mailslot.c wine-staging-1.9.3~ubuntu12.04.1/server/mailslot.c --- wine-staging-1.9.0~ubuntu12.04.1/server/mailslot.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/mailslot.c 2016-02-08 19:32:34.000000000 +0000 @@ -66,6 +66,7 @@ static void mailslot_dump( struct object*, int ); static struct fd *mailslot_get_fd( struct object * ); static unsigned int mailslot_map_access( struct object *obj, unsigned int access ); +static int mailslot_link_name( struct object *obj, struct object_name *name, struct object *parent ); static struct object *mailslot_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); static void mailslot_destroy( struct object * ); @@ -85,6 +86,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + mailslot_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ mailslot_open_file, /* open_file */ fd_close_handle, /* close_handle */ mailslot_destroy /* destroy */ @@ -138,6 +141,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ mail_writer_destroy /* destroy */ @@ -192,6 +197,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ mailslot_device_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ mailslot_device_open_file, /* open_file */ fd_close_handle, /* close_handle */ mailslot_device_destroy /* destroy */ @@ -254,6 +261,20 @@ return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); } +static int mailslot_link_name( struct object *obj, struct object_name *name, struct object *parent ) +{ + struct mailslot_device *dev = (struct mailslot_device *)parent; + + if (parent->ops != &mailslot_device_ops) + { + set_error( STATUS_OBJECT_NAME_INVALID ); + return 0; + } + namespace_add( dev->mailslots, name ); + name->parent = grab_object( parent ); + return 1; +} + static struct object *mailslot_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ) { @@ -325,8 +346,7 @@ static void mailslot_device_dump( struct object *obj, int verbose ) { - assert( obj->ops == &mailslot_device_ops ); - fprintf( stderr, "Mail slot device\n" ); + fputs( "Mailslot device\n", stderr ); } static struct object_type *mailslot_device_get_type( struct object *obj ) @@ -395,15 +415,19 @@ static struct mailslot *create_mailslot( struct directory *root, const struct unicode_str *name, unsigned int attr, - int max_msgsize, timeout_t read_timeout ) + int max_msgsize, timeout_t read_timeout, + const struct security_descriptor *sd ) { struct object *obj; struct unicode_str new_name; - struct mailslot_device *dev; struct mailslot *mailslot; int fds[2]; - if (!name || !name->len) return alloc_object( &mailslot_ops ); + if (!name || !name->len) + { + mailslot = alloc_object( &mailslot_ops ); + goto init; + } if (!(obj = find_object_dir( root, name, attr, &new_name ))) { @@ -424,17 +448,10 @@ return NULL; } - if (obj->ops != &mailslot_device_ops) - { - set_error( STATUS_OBJECT_NAME_INVALID ); - release_object( obj ); - return NULL; - } - - dev = (struct mailslot_device *)obj; - mailslot = create_object( dev->mailslots, &mailslot_ops, &new_name, NULL ); - release_object( dev ); + mailslot = create_object( obj, &mailslot_ops, &new_name ); + release_object( obj ); +init: if (!mailslot) return NULL; mailslot->fd = NULL; @@ -442,6 +459,8 @@ mailslot->max_msgsize = max_msgsize; mailslot->read_timeout = read_timeout; list_init( &mailslot->writers ); + if (sd) default_set_sd( &mailslot->obj, sd, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ); if (!socketpair( PF_UNIX, SOCK_DGRAM, 0, fds )) { @@ -507,17 +526,26 @@ { struct mailslot *mailslot; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; + const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); - reply->handle = 0; - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; + if (!objattr) return; + + if (!name.len) /* mailslots need a root directory even without a name */ + { + if (!objattr->rootdir) + { + set_error( STATUS_OBJECT_PATH_SYNTAX_BAD ); + return; + } + else if (!(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; + } - if ((mailslot = create_mailslot( root, &name, req->attributes, req->max_msgsize, - req->read_timeout ))) + if ((mailslot = create_mailslot( root, &name, objattr->attributes, req->max_msgsize, + req->read_timeout, sd ))) { - reply->handle = alloc_handle( current->process, mailslot, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, mailslot, req->access, objattr->attributes ); release_object( mailslot ); } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/mapping.c wine-staging-1.9.3~ubuntu12.04.1/server/mapping.c --- wine-staging-1.9.0~ubuntu12.04.1/server/mapping.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/mapping.c 2016-02-08 19:32:34.000000000 +0000 @@ -91,6 +91,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ mapping_destroy /* destroy */ @@ -604,12 +606,10 @@ struct mapping *mapping = (struct mapping *)obj; assert( obj->ops == &mapping_ops ); fprintf( stderr, "Mapping size=%08x%08x prot=%08x fd=%p header_size=%08x base=%08lx " - "shared_file=%p ", + "shared_file=%p\n", (unsigned int)(mapping->size >> 32), (unsigned int)mapping->size, mapping->protect, mapping->fd, mapping->header_size, (unsigned long)mapping->base, mapping->shared_file ); - dump_object_name( &mapping->obj ); - fputc( '\n', stderr ); } static struct object_type *mapping_get_type( struct object *obj ) @@ -663,27 +663,20 @@ { struct object *obj; struct unicode_str name; - struct directory *root = NULL; - const struct object_attributes *objattr = get_req_data(); + struct directory *root; const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); - reply->handle = 0; + if (!objattr) return; - if (!objattr_is_valid( objattr, get_req_data_size() )) - return; - - sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL; - objattr_get_name( objattr, &name ); - - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) - return; - - if ((obj = create_mapping( root, &name, req->attributes, req->size, req->protect, req->file_handle, sd ))) + if ((obj = create_mapping( root, &name, objattr->attributes, + req->size, req->protect, req->file_handle, sd ))) { if (get_error() == STATUS_OBJECT_NAME_EXISTS) - reply->handle = alloc_handle( current->process, obj, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, obj, req->access, objattr->attributes ); else - reply->handle = alloc_handle_no_access_check( current->process, obj, req->access, req->attributes ); + reply->handle = alloc_handle_no_access_check( current->process, obj, + req->access, objattr->attributes ); release_object( obj ); } @@ -693,21 +686,10 @@ /* open a handle to a mapping */ DECL_HANDLER(open_mapping) { - struct unicode_str name; - struct directory *root = NULL; - struct mapping *mapping; + struct unicode_str name = get_req_unicode_str(); - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; - - if ((mapping = open_object_dir( root, &name, req->attributes, &mapping_ops ))) - { - reply->handle = alloc_handle( current->process, &mapping->obj, req->access, req->attributes ); - release_object( mapping ); - } - - if (root) release_object( root ); + reply->handle = open_object( current->process, req->rootdir, req->access, + &mapping_ops, &name, req->attributes ); } /* get a mapping information */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/mutex.c wine-staging-1.9.3~ubuntu12.04.1/server/mutex.c --- wine-staging-1.9.0~ubuntu12.04.1/server/mutex.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/mutex.c 2016-02-08 19:32:34.000000000 +0000 @@ -68,6 +68,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ mutex_destroy /* destroy */ @@ -138,9 +140,7 @@ { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops ); - fprintf( stderr, "Mutex count=%u owner=%p ", mutex->count, mutex->owner ); - dump_object_name( &mutex->obj ); - fputc( '\n', stderr ); + fprintf( stderr, "Mutex count=%u owner=%p\n", mutex->count, mutex->owner ); } static struct object_type *mutex_get_type( struct object *obj ) @@ -210,27 +210,19 @@ { struct mutex *mutex; struct unicode_str name; - struct directory *root = NULL; - const struct object_attributes *objattr = get_req_data(); + struct directory *root; const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); - reply->handle = 0; + if (!objattr) return; - if (!objattr_is_valid( objattr, get_req_data_size() )) - return; - - sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL; - objattr_get_name( objattr, &name ); - - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) - return; - - if ((mutex = create_mutex( root, &name, req->attributes, req->owned, sd ))) + if ((mutex = create_mutex( root, &name, objattr->attributes, req->owned, sd ))) { if (get_error() == STATUS_OBJECT_NAME_EXISTS) - reply->handle = alloc_handle( current->process, mutex, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, mutex, req->access, objattr->attributes ); else - reply->handle = alloc_handle_no_access_check( current->process, mutex, req->access, req->attributes ); + reply->handle = alloc_handle_no_access_check( current->process, mutex, + req->access, objattr->attributes ); release_object( mutex ); } @@ -240,21 +232,10 @@ /* open a handle to a mutex */ DECL_HANDLER(open_mutex) { - struct unicode_str name; - struct directory *root = NULL; - struct mutex *mutex; - - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; + struct unicode_str name = get_req_unicode_str(); - if ((mutex = open_object_dir( root, &name, req->attributes, &mutex_ops ))) - { - reply->handle = alloc_handle( current->process, &mutex->obj, req->access, req->attributes ); - release_object( mutex ); - } - - if (root) release_object( root ); + reply->handle = open_object( current->process, req->rootdir, req->access, + &mutex_ops, &name, req->attributes ); } /* release a mutex */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/named_pipe.c wine-staging-1.9.3~ubuntu12.04.1/server/named_pipe.c --- wine-staging-1.9.0~ubuntu12.04.1/server/named_pipe.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/named_pipe.c 2016-02-08 19:32:34.000000000 +0000 @@ -112,6 +112,7 @@ static void named_pipe_dump( struct object *obj, int verbose ); static unsigned int named_pipe_map_access( struct object *obj, unsigned int access ); +static int named_pipe_link_name( struct object *obj, struct object_name *name, struct object *parent ); static struct object *named_pipe_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); static void named_pipe_destroy( struct object *obj ); @@ -131,6 +132,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + named_pipe_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ named_pipe_open_file, /* open_file */ no_close_handle, /* close_handle */ named_pipe_destroy /* destroy */ @@ -160,6 +163,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ pipe_server_destroy /* destroy */ @@ -202,6 +207,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ pipe_client_destroy /* destroy */ @@ -248,6 +255,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ named_pipe_device_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ named_pipe_device_open_file, /* open_file */ fd_close_handle, /* close_handle */ named_pipe_device_destroy /* destroy */ @@ -269,11 +278,7 @@ static void named_pipe_dump( struct object *obj, int verbose ) { - struct named_pipe *pipe = (struct named_pipe *) obj; - assert( obj->ops == &named_pipe_ops ); - fprintf( stderr, "Named pipe " ); - dump_object_name( &pipe->obj ); - fprintf( stderr, "\n" ); + fputs( "Named pipe\n", stderr ); } static unsigned int named_pipe_map_access( struct object *obj, unsigned int access ) @@ -443,8 +448,7 @@ static void named_pipe_device_dump( struct object *obj, int verbose ) { - assert( obj->ops == &named_pipe_device_ops ); - fprintf( stderr, "Named pipe device\n" ); + fputs( "Named pipe device\n", stderr ); } static struct object_type *named_pipe_device_get_type( struct object *obj ) @@ -698,14 +702,8 @@ return (struct named_pipe *)obj; } - if (obj->ops != &named_pipe_device_ops) - set_error( STATUS_OBJECT_NAME_INVALID ); - else - { - struct named_pipe_device *dev = (struct named_pipe_device *)obj; - if ((pipe = create_object( dev->pipes, &named_pipe_ops, &new_name, NULL ))) - clear_error(); - } + if ((pipe = create_object( obj, &named_pipe_ops, &new_name ))) + clear_error(); release_object( obj ); return pipe; @@ -783,6 +781,20 @@ return NULL; } +static int named_pipe_link_name( struct object *obj, struct object_name *name, struct object *parent ) +{ + struct named_pipe_device *dev = (struct named_pipe_device *)parent; + + if (parent->ops != &named_pipe_device_ops) + { + set_error( STATUS_OBJECT_NAME_INVALID ); + return 0; + } + namespace_add( dev->pipes, name ); + name->parent = grab_object( parent ); + return 1; +} + static struct object *named_pipe_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ) { @@ -922,9 +934,11 @@ struct named_pipe *pipe; struct pipe_server *server; struct unicode_str name; - struct directory *root = NULL; - const struct object_attributes *objattr = get_req_data(); + struct directory *root; const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); + + if (!objattr) return; if (!req->sharing || (req->sharing & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) || (!(req->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) && (req->flags & NAMED_PIPE_MESSAGE_STREAM_READ))) @@ -933,18 +947,17 @@ return; } - reply->handle = 0; - - if (!objattr_is_valid( objattr, get_req_data_size() )) - return; - - sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL; - objattr_get_name( objattr, &name ); - - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) - return; + if (!name.len) /* pipes need a root directory even without a name */ + { + if (!objattr->rootdir) + { + set_error( STATUS_OBJECT_PATH_SYNTAX_BAD ); + return; + } + else if (!(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; + } - pipe = create_named_pipe( root, &name, req->attributes | OBJ_OPENIF, sd ); + pipe = create_named_pipe( root, &name, objattr->attributes | OBJ_OPENIF, sd ); if (root) release_object( root ); if (!pipe) return; @@ -982,7 +995,7 @@ server = create_pipe_server( pipe, req->options, req->flags ); if (server) { - reply->handle = alloc_handle( current->process, server, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, server, req->access, objattr->attributes ); server->pipe->instances++; if (sd) default_set_sd( &server->obj, sd, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/object.c wine-staging-1.9.3~ubuntu12.04.1/server/object.c --- wine-staging-1.9.0~ubuntu12.04.1/server/object.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/object.c 2016-02-08 19:32:34.000000000 +0000 @@ -40,15 +40,6 @@ #include "security.h" -struct object_name -{ - struct list entry; /* entry in the hash list */ - struct object *obj; /* object owning this name */ - struct object *parent; /* parent object */ - data_size_t len; /* name length in bytes */ - WCHAR name[1]; -}; - struct namespace { unsigned int hash_size; /* size of hash table */ @@ -68,12 +59,14 @@ { struct object *ptr = LIST_ENTRY( p, struct object, obj_list ); fprintf( stderr, "%p:%d: ", ptr, ptr->refcount ); + dump_object_name( ptr ); ptr->ops->dump( ptr, 1 ); } LIST_FOR_EACH( p, &object_list ) { struct object *ptr = LIST_ENTRY( p, struct object, obj_list ); fprintf( stderr, "%p:%d: ", ptr, ptr->refcount ); + dump_object_name( ptr ); ptr->ops->dump( ptr, 1 ); } } @@ -128,6 +121,13 @@ return hash % namespace->hash_size; } +void namespace_add( struct namespace *namespace, struct object_name *ptr ) +{ + int hash = get_name_hash( namespace, ptr->name, ptr->len ); + + list_add_head( &namespace->names[hash], &ptr->entry ); +} + /* allocate a name for an object */ static struct object_name *alloc_name( const struct unicode_str *name ) { @@ -142,26 +142,6 @@ return ptr; } -/* free the name of an object */ -static void free_name( struct object *obj ) -{ - struct object_name *ptr = obj->name; - list_remove( &ptr->entry ); - if (ptr->parent) release_object( ptr->parent ); - free( ptr ); -} - -/* set the name of an existing object */ -static void set_object_name( struct namespace *namespace, - struct object *obj, struct object_name *ptr ) -{ - int hash = get_name_hash( namespace, ptr->name, ptr->len ); - - list_add_head( &namespace->names[hash], &ptr->entry ); - ptr->obj = obj; - obj->name = ptr; -} - /* get the name of an existing object */ const WCHAR *get_object_name( struct object *obj, data_size_t *len ) { @@ -220,8 +200,18 @@ return NULL; } -void *create_object( struct namespace *namespace, const struct object_ops *ops, - const struct unicode_str *name, struct object *parent ) +/* free an object once it has been destroyed */ +void free_object( struct object *obj ) +{ + free( obj->sd ); +#ifdef DEBUG_OBJECTS + list_remove( &obj->obj_list ); + memset( obj, 0xaa, obj->ops->size ); +#endif + free( obj ); +} + +void *create_object( struct object *parent, const struct object_ops *ops, const struct unicode_str *name ) { struct object *obj; struct object_name *name_ptr; @@ -229,15 +219,20 @@ if (!(name_ptr = alloc_name( name ))) return NULL; if ((obj = alloc_object( ops ))) { - set_object_name( namespace, obj, name_ptr ); - if (parent) name_ptr->parent = grab_object( parent ); + if (!obj->ops->link_name( obj, name_ptr, parent )) + { + free_object( obj ); + return NULL; + } + name_ptr->obj = obj; + obj->name = name_ptr; } else free( name_ptr ); return obj; } -void *create_named_object( struct namespace *namespace, const struct object_ops *ops, +void *create_named_object( struct object *parent, struct namespace *namespace, const struct object_ops *ops, const struct unicode_str *name, unsigned int attributes ) { struct object *obj; @@ -263,27 +258,40 @@ } return obj; } - if ((obj = create_object( namespace, ops, name, NULL ))) clear_error(); + if ((obj = create_object( parent, ops, name ))) clear_error(); return obj; } +/* recursive helper for dump_object_name */ +static void dump_name( struct object *obj ) +{ + struct object_name *name = obj->name; + + if (!name) return; + if (name->parent) dump_name( name->parent ); + fputs( "\\\\", stderr ); + dump_strW( name->name, name->len / sizeof(WCHAR), stderr, "[]" ); +} + /* dump the name of an object to stderr */ void dump_object_name( struct object *obj ) { - if (!obj->name) fprintf( stderr, "name=\"\"" ); - else - { - fprintf( stderr, "name=L\"" ); - dump_strW( obj->name->name, obj->name->len/sizeof(WCHAR), stderr, "\"\"" ); - fputc( '\"', stderr ); - } + if (!obj->name) return; + fputc( '[', stderr ); + dump_name( obj ); + fputs( "] ", stderr ); } /* unlink a named object from its namespace, without freeing the object itself */ void unlink_named_object( struct object *obj ) { - if (obj->name) free_name( obj ); + struct object_name *name_ptr = obj->name; + + if (!name_ptr) return; obj->name = NULL; + obj->ops->unlink_name( obj, name_ptr ); + if (name_ptr->parent) release_object( name_ptr->parent ); + free( name_ptr ); } /* mark an object as being stored statically, i.e. only released at shutdown */ @@ -314,14 +322,9 @@ assert( !obj->handle_count ); /* if the refcount is 0, nobody can be in the wait queue */ assert( list_empty( &obj->wait_queue )); + unlink_named_object( obj ); obj->ops->destroy( obj ); - if (obj->name) free_name( obj ); - free( obj->sd ); -#ifdef DEBUG_OBJECTS - list_remove( &obj->obj_list ); - memset( obj, 0xaa, obj->ops->size ); -#endif - free( obj ); + free_object( obj ); } } @@ -541,6 +544,17 @@ return NULL; } +int no_link_name( struct object *obj, struct object_name *name, struct object *parent ) +{ + set_error( STATUS_OBJECT_TYPE_MISMATCH ); + return 0; +} + +void default_unlink_name( struct object *obj, struct object_name *name ) +{ + list_remove( &name->entry ); +} + struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/object.h wine-staging-1.9.3~ubuntu12.04.1/server/object.h --- wine-staging-1.9.0~ubuntu12.04.1/server/object.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/object.h 2016-02-08 19:32:34.000000000 +0000 @@ -83,6 +83,10 @@ int (*set_sd)( struct object *, const struct security_descriptor *, unsigned int ); /* lookup a name if an object has a namespace */ struct object *(*lookup_name)(struct object *, struct unicode_str *,unsigned int); + /* link an object's name into a parent object */ + int (*link_name)(struct object *, struct object_name *, struct object *); + /* unlink an object's name from its parent */ + void (*unlink_name)(struct object *, struct object_name *); /* open a file object to access this object */ struct object *(*open_file)(struct object *, unsigned int access, unsigned int sharing, unsigned int options); @@ -105,6 +109,15 @@ #endif }; +struct object_name +{ + struct list entry; /* entry in the hash list */ + struct object *obj; /* object owning this name */ + struct object *parent; /* parent object */ + data_size_t len; /* name length in bytes */ + WCHAR name[1]; +}; + struct wait_queue_entry { struct list entry; @@ -115,12 +128,13 @@ extern void *mem_alloc( size_t size ); /* malloc wrapper */ extern void *memdup( const void *data, size_t len ); extern void *alloc_object( const struct object_ops *ops ); +extern void namespace_add( struct namespace *namespace, struct object_name *ptr ); extern const WCHAR *get_object_name( struct object *obj, data_size_t *len ); extern WCHAR *get_object_full_name( struct object *obj, data_size_t *ret_len ); extern void dump_object_name( struct object *obj ); -extern void *create_object( struct namespace *namespace, const struct object_ops *ops, - const struct unicode_str *name, struct object *parent ); -extern void *create_named_object( struct namespace *namespace, const struct object_ops *ops, +extern void *create_object( struct object *parent, const struct object_ops *ops, + const struct unicode_str *name ); +extern void *create_named_object( struct object *parent, struct namespace *namespace, const struct object_ops *ops, const struct unicode_str *name, unsigned int attributes ); extern void unlink_named_object( struct object *obj ); extern void make_object_static( struct object *obj ); @@ -143,6 +157,8 @@ extern int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd, unsigned int set_info, struct token *token ); extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes ); +extern int no_link_name( struct object *obj, struct object_name *name, struct object *parent ); +extern void default_unlink_name( struct object *obj, struct object_name *name ); extern struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ); extern int no_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); @@ -217,12 +233,14 @@ extern void *open_object_dir( struct directory *root, const struct unicode_str *name, unsigned int attr, const struct object_ops *ops ); extern struct object_type *get_object_type( const struct unicode_str *name ); +extern int directory_link_name( struct object *obj, struct object_name *name, struct object *parent ); extern void init_directories(void); /* symbolic link functions */ extern struct symlink *create_symlink( struct directory *root, const struct unicode_str *name, - unsigned int attr, const struct unicode_str *target ); + unsigned int attr, const struct unicode_str *target, + const struct security_descriptor *sd ); /* global variables */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/process.c wine-staging-1.9.3~ubuntu12.04.1/server/process.c --- wine-staging-1.9.0~ubuntu12.04.1/server/process.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/process.c 2016-02-08 19:32:34.000000000 +0000 @@ -81,6 +81,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ process_destroy /* destroy */ @@ -129,6 +131,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ startup_info_destroy /* destroy */ @@ -170,6 +174,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ job_close_handle, /* close_handle */ job_destroy /* destroy */ @@ -1538,28 +1544,33 @@ { struct job *job; struct unicode_str name; - struct directory *root = NULL; - const struct object_attributes *objattr = get_req_data(); + struct directory *root; const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); - if (!objattr_is_valid( objattr, get_req_data_size() )) return; + if (!objattr) return; - sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL; - objattr_get_name( objattr, &name ); - - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; - - if ((job = create_job_object( root, &name, req->attributes, sd ))) + if ((job = create_job_object( root, &name, objattr->attributes, sd ))) { if (get_error() == STATUS_OBJECT_NAME_EXISTS) - reply->handle = alloc_handle( current->process, job, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, job, req->access, objattr->attributes ); else - reply->handle = alloc_handle_no_access_check( current->process, job, req->access, req->attributes ); + reply->handle = alloc_handle_no_access_check( current->process, job, + req->access, objattr->attributes ); release_object( job ); } if (root) release_object( root ); } +/* open a job object */ +DECL_HANDLER(open_job) +{ + struct unicode_str name = get_req_unicode_str(); + + reply->handle = open_object( current->process, req->rootdir, req->access, + &job_ops, &name, req->attributes ); +} + /* assign a job object to a process */ DECL_HANDLER(assign_job) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/protocol.def wine-staging-1.9.3~ubuntu12.04.1/server/protocol.def --- wine-staging-1.9.0~ubuntu12.04.1/server/protocol.def 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/protocol.def 2016-02-08 19:32:34.000000000 +0000 @@ -392,9 +392,10 @@ struct object_attributes { - obj_handle_t rootdir; /* root directory */ - data_size_t sd_len; /* length of security_descriptor data. may be 0 */ - data_size_t name_len; /* length of the name string. may be 0 */ + obj_handle_t rootdir; /* root directory */ + unsigned int attributes; /* object attributes */ + data_size_t sd_len; /* length of security_descriptor data. may be 0 */ + data_size_t name_len; /* length of the name string. may be 0 */ /* VARARG(sd,security_descriptor); */ /* VARARG(name,unicode_str); */ }; @@ -1012,7 +1013,6 @@ /* Create an event */ @REQ(create_event) unsigned int access; /* wanted access rights */ - unsigned int attributes; /* object attributes */ int manual_reset; /* manual reset event */ int initial_state; /* initial state of the event */ VARARG(objattr,object_attributes); /* object attributes */ @@ -1048,7 +1048,6 @@ /* Create a keyed event */ @REQ(create_keyed_event) unsigned int access; /* wanted access rights */ - unsigned int attributes; /* object attributes */ VARARG(objattr,object_attributes); /* object attributes */ @REPLY obj_handle_t handle; /* handle to the event */ @@ -1068,7 +1067,6 @@ /* Create a mutex */ @REQ(create_mutex) unsigned int access; /* wanted access rights */ - unsigned int attributes; /* object attributes */ int owned; /* initially owned? */ VARARG(objattr,object_attributes); /* object attributes */ @REPLY @@ -1098,7 +1096,6 @@ /* Create a semaphore */ @REQ(create_semaphore) unsigned int access; /* wanted access rights */ - unsigned int attributes; /* object attributes */ unsigned int initial; /* initial count */ unsigned int max; /* maximum count */ VARARG(objattr,object_attributes); /* object attributes */ @@ -1136,7 +1133,6 @@ /* Create a file */ @REQ(create_file) unsigned int access; /* wanted access rights */ - unsigned int attributes; /* object attributes */ unsigned int sharing; /* sharing flags */ int create; /* file create action */ unsigned int options; /* file options */ @@ -1636,7 +1632,6 @@ /* Create a file mapping */ @REQ(create_mapping) unsigned int access; /* wanted access rights */ - unsigned int attributes; /* object attributes */ unsigned int protect; /* protection flags (see below) */ mem_size_t size; /* mapping size */ obj_handle_t file_handle; /* file handle */ @@ -1825,12 +1820,9 @@ /* Create a registry key */ @REQ(create_key) - obj_handle_t parent; /* handle to the parent key */ unsigned int access; /* desired access rights */ - unsigned int attributes; /* object attributes */ unsigned int options; /* creation options */ - data_size_t namelen; /* length of key name in bytes */ - VARARG(name,unicode_str,namelen); /* key name */ + VARARG(objattr,object_attributes); /* object attributes */ VARARG(class,unicode_str); /* class name */ @REPLY obj_handle_t hkey; /* handle to the created key */ @@ -1924,9 +1916,8 @@ /* Load a registry branch from a file */ @REQ(load_registry) - obj_handle_t hkey; /* root key to load to */ obj_handle_t file; /* file to load from */ - VARARG(name,unicode_str); /* subkey name */ + VARARG(objattr,object_attributes); /* object attributes */ @END @@ -1955,10 +1946,8 @@ /* Create a waitable timer */ @REQ(create_timer) unsigned int access; /* wanted access rights */ - unsigned int attributes; /* object attributes */ - obj_handle_t rootdir; /* root directory */ int manual; /* manual reset */ - VARARG(name,unicode_str); /* object name */ + VARARG(objattr,object_attributes); /* object attributes */ @REPLY obj_handle_t handle; /* handle to the timer */ @END @@ -2372,7 +2361,6 @@ /* Create a named pipe */ @REQ(create_named_pipe) unsigned int access; - unsigned int attributes; /* object attributes */ unsigned int options; unsigned int sharing; unsigned int maxinstances; @@ -2731,6 +2719,7 @@ unsigned int flags; /* window station flags */ unsigned int access; /* wanted access rights */ unsigned int attributes; /* object attributes */ + obj_handle_t rootdir; /* root directory */ VARARG(name,unicode_str); /* object name */ @REPLY obj_handle_t handle; /* handle to the window station */ @@ -2741,6 +2730,7 @@ @REQ(open_winstation) unsigned int access; /* wanted access rights */ unsigned int attributes; /* object attributes */ + obj_handle_t rootdir; /* root directory */ VARARG(name,unicode_str); /* object name */ @REPLY obj_handle_t handle; /* handle to the window station */ @@ -2978,7 +2968,7 @@ int x; /* caret x position */ int y; /* caret y position */ int hide; /* increment for hide count (can be negative to show it) */ - int state; /* caret state (1=on, 0=off, -1=toggle current state) */ + int state; /* caret state (see below) */ @REPLY user_handle_t full_handle; /* handle to the current caret window */ rectangle_t old_rect; /* previous caret rectangle */ @@ -2988,6 +2978,13 @@ #define SET_CARET_POS 0x01 /* set the caret position from x,y */ #define SET_CARET_HIDE 0x02 /* increment the caret hide count */ #define SET_CARET_STATE 0x04 /* set the caret on/off state */ +enum caret_state +{ + CARET_STATE_OFF, /* off */ + CARET_STATE_ON, /* on */ + CARET_STATE_TOGGLE, /* toggle current state */ + CARET_STATE_ON_IF_MOVED /* on if the position differs, unchanged otherwise */ +}; /* Set a window hook */ @@ -3266,14 +3263,28 @@ VARARG(sd,security_descriptor); /* retrieved security descriptor */ @END + +struct handle_info +{ + process_id_t owner; + obj_handle_t handle; + unsigned int access; +}; + +/* Return a list of all opened handles */ +@REQ(get_system_handles) +@REPLY + unsigned int count; /* number of handles */ + VARARG(data,handle_infos); /* array of handle_infos */ +@END + + /* Create a mailslot */ @REQ(create_mailslot) unsigned int access; /* wanted access rights */ - unsigned int attributes; /* object attributes */ - obj_handle_t rootdir; /* root directory */ timeout_t read_timeout; unsigned int max_msgsize; - VARARG(name,unicode_str); /* mailslot name */ + VARARG(objattr,object_attributes); /* object attributes */ @REPLY obj_handle_t handle; /* handle to the mailslot */ @END @@ -3294,9 +3305,7 @@ /* Create a directory object */ @REQ(create_directory) unsigned int access; /* access flags */ - unsigned int attributes; /* object attributes */ - obj_handle_t rootdir; /* root directory */ - VARARG(directory_name,unicode_str); /* Directory name */ + VARARG(objattr,object_attributes); /* object attributes */ @REPLY obj_handle_t handle; /* handle to the directory */ @END @@ -3327,10 +3336,7 @@ /* Create a symbolic link object */ @REQ(create_symlink) unsigned int access; /* access flags */ - unsigned int attributes; /* object attributes */ - obj_handle_t rootdir; /* root directory */ - data_size_t name_len; /* length of the symlink name in bytes */ - VARARG(name,unicode_str,name_len); /* symlink name */ + VARARG(objattr,object_attributes); /* object attributes */ VARARG(target_name,unicode_str); /* target name */ @REPLY obj_handle_t handle; /* handle to the symlink */ @@ -3465,10 +3471,8 @@ /* Create I/O completion port */ @REQ(create_completion) unsigned int access; /* desired access to a port */ - unsigned int attributes; /* object attributes */ unsigned int concurrent; /* max number of concurrent active threads */ - obj_handle_t rootdir; /* root directory */ - VARARG(filename,unicode_str); /* port name */ + VARARG(objattr,object_attributes); /* object attributes */ @REPLY obj_handle_t handle; /* port handle */ @END @@ -3627,11 +3631,21 @@ /* Create a new job object */ @REQ(create_job) unsigned int access; /* wanted access rights */ - unsigned int attributes; /* object attributes */ VARARG(objattr,object_attributes); /* object attributes */ @REPLY obj_handle_t handle; /* handle to the job */ @END + + +/* Open a job object */ +@REQ(open_job) + unsigned int access; /* wanted access rights */ + unsigned int attributes; /* object attributes */ + obj_handle_t rootdir; /* root directory */ + VARARG(name,unicode_str); /* object name */ +@REPLY + obj_handle_t handle; /* handle to the job */ +@END /* Assign a job object to a process */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/queue.c wine-staging-1.9.3~ubuntu12.04.1/server/queue.c --- wine-staging-1.9.0~ubuntu12.04.1/server/queue.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/queue.c 2016-02-08 19:32:34.000000000 +0000 @@ -178,6 +178,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ msg_queue_destroy /* destroy */ @@ -211,6 +213,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ thread_input_destroy /* destroy */ @@ -2581,13 +2585,21 @@ } else { + lparam_t end_id = queue->next_timer_id; + /* find a free id for it */ - do + while (1) { id = queue->next_timer_id; if (--queue->next_timer_id <= 0x100) queue->next_timer_id = 0x7fff; + + if (!find_timer( queue, 0, req->msg, id )) break; + if (queue->next_timer_id == end_id) + { + set_win32_error( ERROR_NO_MORE_USER_HANDLES ); + return; + } } - while (find_timer( queue, 0, req->msg, id )); } } @@ -3039,8 +3051,15 @@ } if (req->flags & SET_CARET_STATE) { - if (req->state == -1) input->caret_state = !input->caret_state; - else input->caret_state = !!req->state; + switch (req->state) + { + case CARET_STATE_OFF: input->caret_state = 0; break; + case CARET_STATE_ON: input->caret_state = 1; break; + case CARET_STATE_TOGGLE: input->caret_state = !input->caret_state; break; + case CARET_STATE_ON_IF_MOVED: + if (req->x != reply->old_rect.left || req->y != reply->old_rect.top) input->caret_state = 1; + break; + } } } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/registry.c wine-staging-1.9.3~ubuntu12.04.1/server/registry.c --- wine-staging-1.9.0~ubuntu12.04.1/server/registry.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/registry.c 2016-02-08 19:32:34.000000000 +0000 @@ -101,7 +101,7 @@ #define MIN_SUBKEYS 8 /* min. number of allocated subkeys per key */ #define MIN_VALUES 8 /* min. number of allocated values per key */ -#define MAX_NAME_LEN 255 /* max. length of a key name */ +#define MAX_NAME_LEN 256 /* max. length of a key name */ #define MAX_VALUE_LEN 16383 /* max. length of a value name */ /* the root of the registry tree */ @@ -166,6 +166,8 @@ key_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ key_close_handle, /* close_handle */ key_destroy /* destroy */ @@ -575,7 +577,7 @@ if (name->len > MAX_NAME_LEN * sizeof(WCHAR)) { - set_error( STATUS_NAME_TOO_LONG ); + set_error( STATUS_INVALID_PARAMETER ); return NULL; } if (parent->last_subkey + 1 == parent->nb_subkeys) @@ -759,7 +761,8 @@ /* create a subkey */ static struct key *create_key( struct key *key, const struct unicode_str *name, const struct unicode_str *class, unsigned int options, - unsigned int access, unsigned int attributes, int *created ) + unsigned int access, unsigned int attributes, + const struct security_descriptor *sd, int *created ) { int index; struct unicode_str token, next; @@ -807,6 +810,9 @@ if (options & REG_OPTION_VOLATILE) key->flags |= KEY_VOLATILE; else key->flags |= KEY_DIRTY; + if (sd) default_set_sd( &key->obj, sd, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ); + if (debug_level > 1) dump_operation( key, NULL, "Create" ); if (class && class->len) { @@ -2021,33 +2027,30 @@ struct key *key = NULL, *parent; struct unicode_str name, class; unsigned int access = req->access; + const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL ); + + if (!objattr) return; if (!is_wow64_thread( current )) access = (access & ~KEY_WOW64_32KEY) | KEY_WOW64_64KEY; - reply->hkey = 0; + class.str = get_req_data_after_objattr( objattr, &class.len ); + class.len = (class.len / sizeof(WCHAR)) * sizeof(WCHAR); - if (req->namelen > get_req_data_size()) - { - set_error( STATUS_INVALID_PARAMETER ); - return; - } - class.str = (const WCHAR *)get_req_data() + req->namelen / sizeof(WCHAR); - class.len = ((get_req_data_size() - req->namelen) / sizeof(WCHAR)) * sizeof(WCHAR); - get_req_path( &name, !req->parent ); - if (name.str > class.str) + if (!objattr->rootdir && name.len >= sizeof(root_name) && + !memicmpW( name.str, root_name, sizeof(root_name)/sizeof(WCHAR) )) { - set_error( STATUS_INVALID_PARAMETER ); - return; + name.str += sizeof(root_name)/sizeof(WCHAR); + name.len -= sizeof(root_name); } - name.len = (class.str - name.str) * sizeof(WCHAR); /* NOTE: no access rights are required from the parent handle to create a key */ - if ((parent = get_parent_hkey_obj( req->parent ))) + if ((parent = get_parent_hkey_obj( objattr->rootdir ))) { if ((key = create_key( parent, &name, &class, req->options, access, - req->attributes, &reply->created ))) + objattr->attributes, sd, &reply->created ))) { - reply->hkey = alloc_handle( current->process, key, access, req->attributes ); + reply->hkey = alloc_handle( current->process, key, access, objattr->attributes ); release_object( key ); } release_object( parent ); @@ -2141,12 +2144,11 @@ DECL_HANDLER(get_key_value) { struct key *key; - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); reply->total = 0; if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE ))) { - get_req_unicode_str( &name ); get_value( key, &name, &reply->type, &reply->total ); release_object( key ); } @@ -2168,11 +2170,10 @@ DECL_HANDLER(delete_key_value) { struct key *key; - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); if ((key = get_hkey_obj( req->hkey, KEY_SET_VALUE ))) { - get_req_unicode_str( &name ); delete_value( key, &name ); release_object( key ); } @@ -2183,6 +2184,10 @@ { struct key *key, *parent; struct unicode_str name; + const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL ); + + if (!objattr) return; if (!thread_single_check_privilege( current, &SeRestorePrivilege )) { @@ -2190,11 +2195,17 @@ return; } - if ((parent = get_parent_hkey_obj( req->hkey ))) + if (!objattr->rootdir && name.len >= sizeof(root_name) && + !memicmpW( name.str, root_name, sizeof(root_name)/sizeof(WCHAR) )) + { + name.str += sizeof(root_name)/sizeof(WCHAR); + name.len -= sizeof(root_name); + } + + if ((parent = get_parent_hkey_obj( objattr->rootdir ))) { int dummy; - get_req_path( &name, !req->hkey ); - if ((key = create_key( parent, &name, NULL, 0, KEY_WOW64_64KEY, 0, &dummy ))) + if ((key = create_key( parent, &name, NULL, 0, KEY_WOW64_64KEY, 0, sd, &dummy ))) { load_registry( key, req->file ); release_object( key ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/request.c wine-staging-1.9.3~ubuntu12.04.1/server/request.c --- wine-staging-1.9.0~ubuntu12.04.1/server/request.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/request.c 2016-02-08 19:32:34.000000000 +0000 @@ -65,6 +65,8 @@ #include "file.h" #include "process.h" +#include "thread.h" +#include "security.h" #define WANT_REQUEST_HANDLERS #include "request.h" @@ -102,6 +104,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ master_socket_destroy /* destroy */ @@ -163,6 +167,59 @@ return current->reply_data; } +/* return object attributes from the current request */ +const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd, + struct unicode_str *name, + struct directory **root ) +{ + static const struct object_attributes empty_attributes; + const struct object_attributes *attr = get_req_data(); + data_size_t size = get_req_data_size(); + + if (root) *root = NULL; + + if (!size) + { + *sd = NULL; + name->len = 0; + return &empty_attributes; + } + + if ((size < sizeof(*attr)) || (size - sizeof(*attr) < attr->sd_len) || + (size - sizeof(*attr) - attr->sd_len < attr->name_len)) + { + set_error( STATUS_ACCESS_VIOLATION ); + return NULL; + } + if (attr->sd_len && !sd_is_valid( (const struct security_descriptor *)(attr + 1), attr->sd_len )) + { + set_error( STATUS_INVALID_SECURITY_DESCR ); + return NULL; + } + if ((attr->name_len & (sizeof(WCHAR) - 1)) || attr->name_len >= 65534) + { + set_error( STATUS_OBJECT_NAME_INVALID ); + return NULL; + } + if (root && attr->rootdir && attr->name_len) + { + if (!(*root = get_directory_obj( current->process, attr->rootdir, 0 ))) return NULL; + } + *sd = attr->sd_len ? (const struct security_descriptor *)(attr + 1) : NULL; + name->len = attr->name_len; + name->str = (const WCHAR *)(attr + 1) + attr->sd_len / sizeof(WCHAR); + return attr; +} + +/* return a pointer to the request data following an object attributes structure */ +const void *get_req_data_after_objattr( const struct object_attributes *attr, data_size_t *len ) +{ + const void *ptr = (const WCHAR *)((const struct object_attributes *)get_req_data() + 1) + + attr->sd_len / sizeof(WCHAR) + attr->name_len / sizeof(WCHAR); + *len = get_req_data_size() - ((const char *)ptr - (const char *)get_req_data()); + return ptr; +} + /* write the remaining part of the reply */ void write_reply( struct thread *thread ) { diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/request.h wine-staging-1.9.3~ubuntu12.04.1/server/request.h --- wine-staging-1.9.0~ubuntu12.04.1/server/request.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/request.h 2016-02-08 19:32:34.000000000 +0000 @@ -46,6 +46,10 @@ extern const char *get_config_dir(void); extern void *set_reply_data_size( data_size_t size ); +extern const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd, + struct unicode_str *name, + struct directory **root ); +extern const void *get_req_data_after_objattr( const struct object_attributes *attr, data_size_t *len ); extern int receive_fd( struct process *process ); extern int send_client_fd( struct process *process, int fd, obj_handle_t handle ); extern void read_request( struct thread *thread ); @@ -74,10 +78,12 @@ } /* get the request vararg as unicode string */ -static inline void get_req_unicode_str( struct unicode_str *str ) +static inline struct unicode_str get_req_unicode_str(void) { - str->str = get_req_data(); - str->len = (get_req_data_size() / sizeof(WCHAR)) * sizeof(WCHAR); + struct unicode_str ret; + ret.str = get_req_data(); + ret.len = (get_req_data_size() / sizeof(WCHAR)) * sizeof(WCHAR); + return ret; } /* get the reply maximum vararg size */ @@ -333,6 +339,7 @@ DECL_HANDLER(set_token_default_dacl); DECL_HANDLER(set_security_object); DECL_HANDLER(get_security_object); +DECL_HANDLER(get_system_handles); DECL_HANDLER(create_mailslot); DECL_HANDLER(set_mailslot_info); DECL_HANDLER(create_directory); @@ -370,6 +377,7 @@ DECL_HANDLER(get_suspend_context); DECL_HANDLER(set_suspend_context); DECL_HANDLER(create_job); +DECL_HANDLER(open_job); DECL_HANDLER(assign_job); DECL_HANDLER(process_in_job); DECL_HANDLER(set_job_limits); @@ -608,6 +616,7 @@ (req_handler)req_set_token_default_dacl, (req_handler)req_set_security_object, (req_handler)req_get_security_object, + (req_handler)req_get_system_handles, (req_handler)req_create_mailslot, (req_handler)req_set_mailslot_info, (req_handler)req_create_directory, @@ -645,6 +654,7 @@ (req_handler)req_get_suspend_context, (req_handler)req_set_suspend_context, (req_handler)req_create_job, + (req_handler)req_open_job, (req_handler)req_assign_job, (req_handler)req_process_in_job, (req_handler)req_set_job_limits, @@ -866,10 +876,9 @@ C_ASSERT( FIELD_OFFSET(struct select_reply, apc_handle) == 56 ); C_ASSERT( sizeof(struct select_reply) == 64 ); C_ASSERT( FIELD_OFFSET(struct create_event_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_event_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_event_request, manual_reset) == 20 ); -C_ASSERT( FIELD_OFFSET(struct create_event_request, initial_state) == 24 ); -C_ASSERT( sizeof(struct create_event_request) == 32 ); +C_ASSERT( FIELD_OFFSET(struct create_event_request, manual_reset) == 16 ); +C_ASSERT( FIELD_OFFSET(struct create_event_request, initial_state) == 20 ); +C_ASSERT( sizeof(struct create_event_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct create_event_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_event_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct event_op_request, handle) == 12 ); @@ -887,8 +896,7 @@ C_ASSERT( FIELD_OFFSET(struct open_event_reply, handle) == 8 ); C_ASSERT( sizeof(struct open_event_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_keyed_event_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_keyed_event_request, attributes) == 16 ); -C_ASSERT( sizeof(struct create_keyed_event_request) == 24 ); +C_ASSERT( sizeof(struct create_keyed_event_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_keyed_event_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_keyed_event_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct open_keyed_event_request, access) == 12 ); @@ -898,8 +906,7 @@ C_ASSERT( FIELD_OFFSET(struct open_keyed_event_reply, handle) == 8 ); C_ASSERT( sizeof(struct open_keyed_event_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_mutex_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_mutex_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_mutex_request, owned) == 20 ); +C_ASSERT( FIELD_OFFSET(struct create_mutex_request, owned) == 16 ); C_ASSERT( sizeof(struct create_mutex_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct create_mutex_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_mutex_reply) == 16 ); @@ -914,10 +921,9 @@ C_ASSERT( FIELD_OFFSET(struct open_mutex_reply, handle) == 8 ); C_ASSERT( sizeof(struct open_mutex_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_semaphore_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_semaphore_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_semaphore_request, initial) == 20 ); -C_ASSERT( FIELD_OFFSET(struct create_semaphore_request, max) == 24 ); -C_ASSERT( sizeof(struct create_semaphore_request) == 32 ); +C_ASSERT( FIELD_OFFSET(struct create_semaphore_request, initial) == 16 ); +C_ASSERT( FIELD_OFFSET(struct create_semaphore_request, max) == 20 ); +C_ASSERT( sizeof(struct create_semaphore_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct create_semaphore_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_semaphore_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct release_semaphore_request, handle) == 12 ); @@ -937,12 +943,11 @@ C_ASSERT( FIELD_OFFSET(struct open_semaphore_reply, handle) == 8 ); C_ASSERT( sizeof(struct open_semaphore_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_file_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_file_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_file_request, sharing) == 20 ); -C_ASSERT( FIELD_OFFSET(struct create_file_request, create) == 24 ); -C_ASSERT( FIELD_OFFSET(struct create_file_request, options) == 28 ); -C_ASSERT( FIELD_OFFSET(struct create_file_request, attrs) == 32 ); -C_ASSERT( sizeof(struct create_file_request) == 40 ); +C_ASSERT( FIELD_OFFSET(struct create_file_request, sharing) == 16 ); +C_ASSERT( FIELD_OFFSET(struct create_file_request, create) == 20 ); +C_ASSERT( FIELD_OFFSET(struct create_file_request, options) == 24 ); +C_ASSERT( FIELD_OFFSET(struct create_file_request, attrs) == 28 ); +C_ASSERT( sizeof(struct create_file_request) == 32 ); C_ASSERT( FIELD_OFFSET(struct create_file_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_file_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct open_file_object_request, access) == 12 ); @@ -1192,8 +1197,7 @@ C_ASSERT( sizeof(struct read_change_request) == 16 ); C_ASSERT( sizeof(struct read_change_reply) == 8 ); C_ASSERT( FIELD_OFFSET(struct create_mapping_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_mapping_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_mapping_request, protect) == 20 ); +C_ASSERT( FIELD_OFFSET(struct create_mapping_request, protect) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_mapping_request, size) == 24 ); C_ASSERT( FIELD_OFFSET(struct create_mapping_request, file_handle) == 32 ); C_ASSERT( sizeof(struct create_mapping_request) == 40 ); @@ -1288,12 +1292,9 @@ C_ASSERT( FIELD_OFFSET(struct write_process_memory_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct write_process_memory_request, addr) == 16 ); C_ASSERT( sizeof(struct write_process_memory_request) == 24 ); -C_ASSERT( FIELD_OFFSET(struct create_key_request, parent) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_key_request, access) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_key_request, attributes) == 20 ); -C_ASSERT( FIELD_OFFSET(struct create_key_request, options) == 24 ); -C_ASSERT( FIELD_OFFSET(struct create_key_request, namelen) == 28 ); -C_ASSERT( sizeof(struct create_key_request) == 32 ); +C_ASSERT( FIELD_OFFSET(struct create_key_request, access) == 12 ); +C_ASSERT( FIELD_OFFSET(struct create_key_request, options) == 16 ); +C_ASSERT( sizeof(struct create_key_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct create_key_reply, hkey) == 8 ); C_ASSERT( FIELD_OFFSET(struct create_key_reply, created) == 12 ); C_ASSERT( sizeof(struct create_key_reply) == 16 ); @@ -1340,9 +1341,8 @@ C_ASSERT( sizeof(struct enum_key_value_reply) == 24 ); C_ASSERT( FIELD_OFFSET(struct delete_key_value_request, hkey) == 12 ); C_ASSERT( sizeof(struct delete_key_value_request) == 16 ); -C_ASSERT( FIELD_OFFSET(struct load_registry_request, hkey) == 12 ); -C_ASSERT( FIELD_OFFSET(struct load_registry_request, file) == 16 ); -C_ASSERT( sizeof(struct load_registry_request) == 24 ); +C_ASSERT( FIELD_OFFSET(struct load_registry_request, file) == 12 ); +C_ASSERT( sizeof(struct load_registry_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct unload_registry_request, hkey) == 12 ); C_ASSERT( sizeof(struct unload_registry_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct save_registry_request, hkey) == 12 ); @@ -1354,10 +1354,8 @@ C_ASSERT( FIELD_OFFSET(struct set_registry_notification_request, filter) == 24 ); C_ASSERT( sizeof(struct set_registry_notification_request) == 32 ); C_ASSERT( FIELD_OFFSET(struct create_timer_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_timer_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_timer_request, rootdir) == 20 ); -C_ASSERT( FIELD_OFFSET(struct create_timer_request, manual) == 24 ); -C_ASSERT( sizeof(struct create_timer_request) == 32 ); +C_ASSERT( FIELD_OFFSET(struct create_timer_request, manual) == 16 ); +C_ASSERT( sizeof(struct create_timer_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct create_timer_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_timer_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct open_timer_request, access) == 12 ); @@ -1579,12 +1577,11 @@ C_ASSERT( FIELD_OFFSET(struct get_irp_result_reply, size) == 8 ); C_ASSERT( sizeof(struct get_irp_result_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, options) == 20 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, sharing) == 24 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, maxinstances) == 28 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, outsize) == 32 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, insize) == 36 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, options) == 16 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, sharing) == 20 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, maxinstances) == 24 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, outsize) == 28 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, insize) == 32 ); C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, timeout) == 40 ); C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, flags) == 48 ); C_ASSERT( sizeof(struct create_named_pipe_request) == 56 ); @@ -1774,11 +1771,13 @@ C_ASSERT( FIELD_OFFSET(struct create_winstation_request, flags) == 12 ); C_ASSERT( FIELD_OFFSET(struct create_winstation_request, access) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_winstation_request, attributes) == 20 ); -C_ASSERT( sizeof(struct create_winstation_request) == 24 ); +C_ASSERT( FIELD_OFFSET(struct create_winstation_request, rootdir) == 24 ); +C_ASSERT( sizeof(struct create_winstation_request) == 32 ); C_ASSERT( FIELD_OFFSET(struct create_winstation_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_winstation_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct open_winstation_request, access) == 12 ); C_ASSERT( FIELD_OFFSET(struct open_winstation_request, attributes) == 16 ); +C_ASSERT( FIELD_OFFSET(struct open_winstation_request, rootdir) == 20 ); C_ASSERT( sizeof(struct open_winstation_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct open_winstation_reply, handle) == 8 ); C_ASSERT( sizeof(struct open_winstation_reply) == 16 ); @@ -2083,12 +2082,13 @@ C_ASSERT( sizeof(struct get_security_object_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_security_object_reply, sd_len) == 8 ); C_ASSERT( sizeof(struct get_security_object_reply) == 16 ); +C_ASSERT( sizeof(struct get_system_handles_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_system_handles_reply, count) == 8 ); +C_ASSERT( sizeof(struct get_system_handles_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_mailslot_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_mailslot_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_mailslot_request, rootdir) == 20 ); -C_ASSERT( FIELD_OFFSET(struct create_mailslot_request, read_timeout) == 24 ); -C_ASSERT( FIELD_OFFSET(struct create_mailslot_request, max_msgsize) == 32 ); -C_ASSERT( sizeof(struct create_mailslot_request) == 40 ); +C_ASSERT( FIELD_OFFSET(struct create_mailslot_request, read_timeout) == 16 ); +C_ASSERT( FIELD_OFFSET(struct create_mailslot_request, max_msgsize) == 24 ); +C_ASSERT( sizeof(struct create_mailslot_request) == 32 ); C_ASSERT( FIELD_OFFSET(struct create_mailslot_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_mailslot_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_mailslot_info_request, handle) == 12 ); @@ -2099,9 +2099,7 @@ C_ASSERT( FIELD_OFFSET(struct set_mailslot_info_reply, max_msgsize) == 16 ); C_ASSERT( sizeof(struct set_mailslot_info_reply) == 24 ); C_ASSERT( FIELD_OFFSET(struct create_directory_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_directory_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_directory_request, rootdir) == 20 ); -C_ASSERT( sizeof(struct create_directory_request) == 24 ); +C_ASSERT( sizeof(struct create_directory_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_directory_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_directory_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct open_directory_request, access) == 12 ); @@ -2116,10 +2114,7 @@ C_ASSERT( FIELD_OFFSET(struct get_directory_entry_reply, name_len) == 8 ); C_ASSERT( sizeof(struct get_directory_entry_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_symlink_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_symlink_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_symlink_request, rootdir) == 20 ); -C_ASSERT( FIELD_OFFSET(struct create_symlink_request, name_len) == 24 ); -C_ASSERT( sizeof(struct create_symlink_request) == 32 ); +C_ASSERT( sizeof(struct create_symlink_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_symlink_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_symlink_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct open_symlink_request, access) == 12 ); @@ -2191,10 +2186,8 @@ C_ASSERT( FIELD_OFFSET(struct get_token_statistics_reply, privilege_count) == 36 ); C_ASSERT( sizeof(struct get_token_statistics_reply) == 40 ); C_ASSERT( FIELD_OFFSET(struct create_completion_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_completion_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_completion_request, concurrent) == 20 ); -C_ASSERT( FIELD_OFFSET(struct create_completion_request, rootdir) == 24 ); -C_ASSERT( sizeof(struct create_completion_request) == 32 ); +C_ASSERT( FIELD_OFFSET(struct create_completion_request, concurrent) == 16 ); +C_ASSERT( sizeof(struct create_completion_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct create_completion_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_completion_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct open_completion_request, access) == 12 ); @@ -2274,10 +2267,15 @@ C_ASSERT( sizeof(struct get_suspend_context_reply) == 8 ); C_ASSERT( sizeof(struct set_suspend_context_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_job_request, access) == 12 ); -C_ASSERT( FIELD_OFFSET(struct create_job_request, attributes) == 16 ); -C_ASSERT( sizeof(struct create_job_request) == 24 ); +C_ASSERT( sizeof(struct create_job_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_job_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_job_reply) == 16 ); +C_ASSERT( FIELD_OFFSET(struct open_job_request, access) == 12 ); +C_ASSERT( FIELD_OFFSET(struct open_job_request, attributes) == 16 ); +C_ASSERT( FIELD_OFFSET(struct open_job_request, rootdir) == 20 ); +C_ASSERT( sizeof(struct open_job_request) == 24 ); +C_ASSERT( FIELD_OFFSET(struct open_job_reply, handle) == 8 ); +C_ASSERT( sizeof(struct open_job_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct assign_job_request, job) == 12 ); C_ASSERT( FIELD_OFFSET(struct assign_job_request, process) == 16 ); C_ASSERT( sizeof(struct assign_job_request) == 24 ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/security.h wine-staging-1.9.3~ubuntu12.04.1/server/security.h --- wine-staging-1.9.0~ubuntu12.04.1/server/security.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/security.h 2016-02-08 19:32:34.000000000 +0000 @@ -139,13 +139,4 @@ return NULL; } -/* determines whether an object_attributes struct is valid in a buffer - * and calls set_error appropriately */ -extern int objattr_is_valid( const struct object_attributes *objattr, data_size_t size ); -static inline void objattr_get_name( const struct object_attributes *objattr, struct unicode_str *name ) -{ - name->len = ((objattr->name_len) / sizeof(WCHAR)) * sizeof(WCHAR); - name->str = (const WCHAR *)objattr + (sizeof(*objattr) + objattr->sd_len) / sizeof(WCHAR); -} - #endif /* __WINE_SERVER_SECURITY_H */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/semaphore.c wine-staging-1.9.3~ubuntu12.04.1/server/semaphore.c --- wine-staging-1.9.0~ubuntu12.04.1/server/semaphore.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/semaphore.c 2016-02-08 19:32:34.000000000 +0000 @@ -65,6 +65,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ no_destroy /* destroy */ @@ -124,9 +126,7 @@ { struct semaphore *sem = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops ); - fprintf( stderr, "Semaphore count=%d max=%d ", sem->count, sem->max ); - dump_object_name( &sem->obj ); - fputc( '\n', stderr ); + fprintf( stderr, "Semaphore count=%d max=%d\n", sem->count, sem->max ); } static struct object_type *semaphore_get_type( struct object *obj ) @@ -178,27 +178,19 @@ { struct semaphore *sem; struct unicode_str name; - struct directory *root = NULL; - const struct object_attributes *objattr = get_req_data(); + struct directory *root; const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); - reply->handle = 0; + if (!objattr) return; - if (!objattr_is_valid( objattr, get_req_data_size() )) - return; - - sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL; - objattr_get_name( objattr, &name ); - - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) - return; - - if ((sem = create_semaphore( root, &name, req->attributes, req->initial, req->max, sd ))) + if ((sem = create_semaphore( root, &name, objattr->attributes, req->initial, req->max, sd ))) { if (get_error() == STATUS_OBJECT_NAME_EXISTS) - reply->handle = alloc_handle( current->process, sem, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, sem, req->access, objattr->attributes ); else - reply->handle = alloc_handle_no_access_check( current->process, sem, req->access, req->attributes ); + reply->handle = alloc_handle_no_access_check( current->process, sem, + req->access, objattr->attributes ); release_object( sem ); } @@ -208,21 +200,10 @@ /* open a handle to a semaphore */ DECL_HANDLER(open_semaphore) { - struct unicode_str name; - struct directory *root = NULL; - struct semaphore *sem; - - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; + struct unicode_str name = get_req_unicode_str(); - if ((sem = open_object_dir( root, &name, req->attributes, &semaphore_ops ))) - { - reply->handle = alloc_handle( current->process, &sem->obj, req->access, req->attributes ); - release_object( sem ); - } - - if (root) release_object( root ); + reply->handle = open_object( current->process, req->rootdir, req->access, + &semaphore_ops, &name, req->attributes ); } /* release a semaphore */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/serial.c wine-staging-1.9.3~ubuntu12.04.1/server/serial.c --- wine-staging-1.9.0~ubuntu12.04.1/server/serial.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/serial.c 2016-02-08 19:32:34.000000000 +0000 @@ -62,12 +62,15 @@ static enum server_fd_type serial_get_fd_type( struct fd *fd ); static void serial_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); +static void serial_reselect_async( struct fd *fd, struct async_queue *queue ); struct serial { struct object obj; struct fd *fd; + struct timeout_user *read_timer; + /* timeout values */ unsigned int readinterval; unsigned int readconst; @@ -100,6 +103,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ serial_destroy /* destroy */ @@ -115,7 +120,7 @@ no_fd_flush, /* flush */ default_fd_ioctl, /* ioctl */ serial_queue_async, /* queue_async */ - default_fd_reselect_async, /* reselect_async */ + serial_reselect_async, /* reselect_async */ default_fd_cancel_async /* cancel_async */ }; @@ -134,6 +139,7 @@ if (!(serial = alloc_object( &serial_ops ))) return NULL; + serial->read_timer = NULL; serial->readinterval = 0; serial->readmult = 0; serial->readconst = 0; @@ -157,6 +163,7 @@ static void serial_destroy( struct object *obj) { struct serial *serial = (struct serial *)obj; + if (serial->read_timer) remove_timeout_user( serial->read_timer ); release_object( serial->fd ); } @@ -203,6 +210,34 @@ } } +static void serial_read_timeout( void *arg ) +{ + struct serial *serial = arg; + + serial->read_timer = NULL; + fd_async_wake_up( serial->fd, ASYNC_TYPE_READ, STATUS_TIMEOUT ); +} + +static void serial_reselect_async( struct fd *fd, struct async_queue *queue ) +{ + struct serial *serial = get_fd_user( fd ); + + if (serial->read_timer) + { + if (!(default_fd_get_poll_events( fd ) & POLLIN)) + { + remove_timeout_user( serial->read_timer ); + serial->read_timer = NULL; + } + } + else if (serial->readinterval && (default_fd_get_poll_events( fd ) & POLLIN)) + { + serial->read_timer = add_timeout_user( (timeout_t)serial->readinterval * -10000, + serial_read_timeout, serial ); + } + default_fd_reselect_async( fd, queue ); +} + DECL_HANDLER(get_serial_info) { struct serial *serial; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/signal.c wine-staging-1.9.3~ubuntu12.04.1/server/signal.c --- wine-staging-1.9.0~ubuntu12.04.1/server/signal.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/signal.c 2016-02-08 19:32:34.000000000 +0000 @@ -74,6 +74,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ handler_destroy /* destroy */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/snapshot.c wine-staging-1.9.3~ubuntu12.04.1/server/snapshot.c --- wine-staging-1.9.0~ubuntu12.04.1/server/snapshot.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/snapshot.c 2016-02-08 19:32:34.000000000 +0000 @@ -68,6 +68,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ snapshot_destroy /* destroy */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/sock.c wine-staging-1.9.3~ubuntu12.04.1/server/sock.c --- wine-staging-1.9.0~ubuntu12.04.1/server/sock.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/sock.c 2016-02-08 19:32:34.000000000 +0000 @@ -153,6 +153,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ fd_close_handle, /* close_handle */ sock_destroy /* destroy */ @@ -995,6 +997,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ ifchange_destroy /* destroy */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/symlink.c wine-staging-1.9.3~ubuntu12.04.1/server/symlink.c --- wine-staging-1.9.0~ubuntu12.04.1/server/symlink.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/symlink.c 2016-02-08 19:32:34.000000000 +0000 @@ -67,6 +67,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ symlink_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ symlink_destroy /* destroy */ @@ -77,11 +79,9 @@ struct symlink *symlink = (struct symlink *)obj; assert( obj->ops == &symlink_ops ); - fprintf( stderr, "Symlink " ); - dump_object_name( obj ); - fprintf( stderr, " -> L\"" ); + fputs( "Symlink target=\"", stderr ); dump_strW( symlink->target, symlink->len / sizeof(WCHAR), stderr, "\"\"" ); - fprintf( stderr, "\"\n" ); + fputs( "\"\n", stderr ); } static struct object_type *symlink_get_type( struct object *obj ) @@ -132,7 +132,8 @@ } struct symlink *create_symlink( struct directory *root, const struct unicode_str *name, - unsigned int attr, const struct unicode_str *target ) + unsigned int attr, const struct unicode_str *target, + const struct security_descriptor *sd ) { struct symlink *symlink; @@ -145,7 +146,13 @@ (get_error() != STATUS_OBJECT_NAME_EXISTS)) { if ((symlink->target = memdup( target->str, target->len ))) + { symlink->len = target->len; + if (sd) + default_set_sd( &symlink->obj, sd, + OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ); + } else { release_object( symlink ); @@ -161,24 +168,18 @@ { struct symlink *symlink; struct unicode_str name, target; - struct directory *root = NULL; + struct directory *root; + const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); - if (req->name_len > get_req_data_size()) - { - set_error( STATUS_INVALID_PARAMETER ); - return; - } - name.str = get_req_data(); - target.str = name.str + req->name_len / sizeof(WCHAR); - name.len = (target.str - name.str) * sizeof(WCHAR); - target.len = ((get_req_data_size() - name.len) / sizeof(WCHAR)) * sizeof(WCHAR); + if (!objattr) return; - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; + target.str = get_req_data_after_objattr( objattr, &target.len ); + target.len = (target.len / sizeof(WCHAR)) * sizeof(WCHAR); - if ((symlink = create_symlink( root, &name, req->attributes, &target ))) + if ((symlink = create_symlink( root, &name, objattr->attributes, &target, sd ))) { - reply->handle = alloc_handle( current->process, symlink, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, symlink, req->access, objattr->attributes ); release_object( symlink ); } @@ -188,21 +189,10 @@ /* open a symbolic link object */ DECL_HANDLER(open_symlink) { - struct unicode_str name; - struct directory *root = NULL; - struct symlink *symlink; + struct unicode_str name = get_req_unicode_str(); - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; - - if ((symlink = open_object_dir( root, &name, req->attributes | OBJ_OPENLINK, &symlink_ops ))) - { - reply->handle = alloc_handle( current->process, &symlink->obj, req->access, req->attributes ); - release_object( symlink ); - } - - if (root) release_object( root ); + reply->handle = open_object( current->process, req->rootdir, req->access, + &symlink_ops, &name, req->attributes | OBJ_OPENLINK ); } /* query a symbolic link object */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/thread.c wine-staging-1.9.3~ubuntu12.04.1/server/thread.c --- wine-staging-1.9.0~ubuntu12.04.1/server/thread.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/thread.c 2016-02-08 19:32:34.000000000 +0000 @@ -117,6 +117,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ thread_apc_destroy /* destroy */ @@ -146,6 +148,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ destroy_thread /* destroy */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/timer.c wine-staging-1.9.3~ubuntu12.04.1/server/timer.c --- wine-staging-1.9.0~ubuntu12.04.1/server/timer.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/timer.c 2016-02-08 19:32:34.000000000 +0000 @@ -72,6 +72,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ timer_destroy /* destroy */ @@ -80,7 +82,7 @@ /* create a timer object */ static struct timer *create_timer( struct directory *root, const struct unicode_str *name, - unsigned int attr, int manual ) + unsigned int attr, int manual, const struct security_descriptor *sd ) { struct timer *timer; @@ -95,6 +97,9 @@ timer->period = 0; timer->timeout = NULL; timer->thread = NULL; + if (sd) default_set_sd( &timer->obj, sd, + OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ); } } return timer; @@ -181,10 +186,8 @@ { struct timer *timer = (struct timer *)obj; assert( obj->ops == &timer_ops ); - fprintf( stderr, "Timer manual=%d when=%s period=%u ", + fprintf( stderr, "Timer manual=%d when=%s period=%u\n", timer->manual, get_timeout_str(timer->when), timer->period ); - dump_object_name( &timer->obj ); - fputc( '\n', stderr ); } static struct object_type *timer_get_type( struct object *obj ) @@ -231,16 +234,15 @@ { struct timer *timer; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; + const struct security_descriptor *sd; + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); - reply->handle = 0; - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; + if (!objattr) return; - if ((timer = create_timer( root, &name, req->attributes, req->manual ))) + if ((timer = create_timer( root, &name, objattr->attributes, req->manual, sd ))) { - reply->handle = alloc_handle( current->process, timer, req->access, req->attributes ); + reply->handle = alloc_handle( current->process, timer, req->access, objattr->attributes ); release_object( timer ); } @@ -250,21 +252,10 @@ /* open a handle to a timer */ DECL_HANDLER(open_timer) { - struct unicode_str name; - struct directory *root = NULL; - struct timer *timer; - - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) - return; - - if ((timer = open_object_dir( root, &name, req->attributes, &timer_ops ))) - { - reply->handle = alloc_handle( current->process, &timer->obj, req->access, req->attributes ); - release_object( timer ); - } + struct unicode_str name = get_req_unicode_str(); - if (root) release_object( root ); + reply->handle = open_object( current->process, req->rootdir, req->access, + &timer_ops, &name, req->attributes ); } /* set a waitable timer */ diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/token.c wine-staging-1.9.3~ubuntu12.04.1/server/token.c --- wine-staging-1.9.0~ubuntu12.04.1/server/token.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/token.c 2016-02-08 19:32:34.000000000 +0000 @@ -158,6 +158,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + no_link_name, /* link_name */ + NULL, /* unlink_name */ no_open_file, /* open_file */ no_close_handle, /* close_handle */ token_destroy /* destroy */ @@ -333,30 +335,6 @@ return TRUE; } - -/* determines whether an object_attributes struct is valid in a buffer - * and calls set_error appropriately */ -int objattr_is_valid( const struct object_attributes *objattr, data_size_t size ) -{ - if ((size < sizeof(*objattr)) || (size - sizeof(*objattr) < objattr->sd_len) || - (size - sizeof(*objattr) - objattr->sd_len < objattr->name_len)) - { - set_error( STATUS_ACCESS_VIOLATION ); - return FALSE; - } - - if (objattr->sd_len) - { - const struct security_descriptor *sd = (const struct security_descriptor *)(objattr + 1); - if (!sd_is_valid( sd, objattr->sd_len )) - { - set_error( STATUS_INVALID_SECURITY_DESCR ); - return FALSE; - } - } - - return TRUE; -} /* maps from generic rights to specific rights as given by a mapping */ static inline void map_generic_mask(unsigned int *mask, const GENERIC_MAPPING *mapping) diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/trace.c wine-staging-1.9.3~ubuntu12.04.1/server/trace.c --- wine-staging-1.9.0~ubuntu12.04.1/server/trace.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/trace.c 2016-02-08 19:32:34.000000000 +0000 @@ -1074,20 +1074,27 @@ const struct object_attributes *objattr = cur_data; fprintf( stderr,"%s{", prefix ); - if (size >= sizeof(struct object_attributes)) + if (size) { const WCHAR *str; - fprintf( stderr, "rootdir=%04x", objattr->rootdir ); - if (objattr->sd_len > size - sizeof(*objattr) || - objattr->name_len > size - sizeof(*objattr) - objattr->sd_len) + + if (size < sizeof(*objattr) || + (size - sizeof(*objattr) < objattr->sd_len) || + (size - sizeof(*objattr) - objattr->sd_len < objattr->name_len)) + { + fprintf( stderr, "***invalid***}" ); + remove_data( size ); return; + } + + fprintf( stderr, "rootdir=%04x,attributes=%08x", objattr->rootdir, objattr->attributes ); dump_inline_security_descriptor( ",sd=", (const struct security_descriptor *)(objattr + 1), objattr->sd_len ); str = (const WCHAR *)objattr + (sizeof(*objattr) + objattr->sd_len) / sizeof(WCHAR); fprintf( stderr, ",name=L\"" ); dump_strW( str, objattr->name_len / sizeof(WCHAR), stderr, "\"\"" ); fputc( '\"', stderr ); remove_data( ((sizeof(*objattr) + objattr->sd_len) / sizeof(WCHAR)) * sizeof(WCHAR) + - objattr->name_len ); + (objattr->name_len / sizeof(WCHAR)) * sizeof(WCHAR) ); } fputc( '}', stderr ); } @@ -1142,6 +1149,23 @@ fputc( '}', stderr ); } +static void dump_varargs_handle_infos( const char *prefix, data_size_t size ) +{ + const struct handle_info *handle; + + fprintf( stderr, "%s{", prefix ); + while (size >= sizeof(*handle)) + { + handle = cur_data; + fprintf( stderr, "{owner=%04x,handle=%04x,access=%08x}", + handle->owner, handle->handle, handle->access ); + size -= sizeof(*handle); + remove_data( sizeof(*handle) ); + if (size) fputc( ',', stderr ); + } + fputc( '}', stderr ); +} + typedef void (*dump_func)( const void *req ); /* Everything below this line is generated automatically by tools/make_requests */ @@ -1479,7 +1503,6 @@ static void dump_create_event_request( const struct create_event_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); fprintf( stderr, ", manual_reset=%d", req->manual_reset ); fprintf( stderr, ", initial_state=%d", req->initial_state ); dump_varargs_object_attributes( ", objattr=", cur_size ); @@ -1523,7 +1546,6 @@ static void dump_create_keyed_event_request( const struct create_keyed_event_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); dump_varargs_object_attributes( ", objattr=", cur_size ); } @@ -1548,7 +1570,6 @@ static void dump_create_mutex_request( const struct create_mutex_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); fprintf( stderr, ", owned=%d", req->owned ); dump_varargs_object_attributes( ", objattr=", cur_size ); } @@ -1584,7 +1605,6 @@ static void dump_create_semaphore_request( const struct create_semaphore_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); fprintf( stderr, ", initial=%08x", req->initial ); fprintf( stderr, ", max=%08x", req->max ); dump_varargs_object_attributes( ", objattr=", cur_size ); @@ -1633,7 +1653,6 @@ static void dump_create_file_request( const struct create_file_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); fprintf( stderr, ", sharing=%08x", req->sharing ); fprintf( stderr, ", create=%d", req->create ); fprintf( stderr, ", options=%08x", req->options ); @@ -2098,7 +2117,6 @@ static void dump_create_mapping_request( const struct create_mapping_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); fprintf( stderr, ", protect=%08x", req->protect ); dump_uint64( ", size=", &req->size ); fprintf( stderr, ", file_handle=%04x", req->file_handle ); @@ -2290,12 +2308,9 @@ static void dump_create_key_request( const struct create_key_request *req ) { - fprintf( stderr, " parent=%04x", req->parent ); - fprintf( stderr, ", access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); + fprintf( stderr, " access=%08x", req->access ); fprintf( stderr, ", options=%08x", req->options ); - fprintf( stderr, ", namelen=%u", req->namelen ); - dump_varargs_unicode_str( ", name=", min(cur_size,req->namelen) ); + dump_varargs_object_attributes( ", objattr=", cur_size ); dump_varargs_unicode_str( ", class=", cur_size ); } @@ -2396,9 +2411,8 @@ static void dump_load_registry_request( const struct load_registry_request *req ) { - fprintf( stderr, " hkey=%04x", req->hkey ); - fprintf( stderr, ", file=%04x", req->file ); - dump_varargs_unicode_str( ", name=", cur_size ); + fprintf( stderr, " file=%04x", req->file ); + dump_varargs_object_attributes( ", objattr=", cur_size ); } static void dump_unload_registry_request( const struct unload_registry_request *req ) @@ -2423,10 +2437,8 @@ static void dump_create_timer_request( const struct create_timer_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); - fprintf( stderr, ", rootdir=%04x", req->rootdir ); fprintf( stderr, ", manual=%d", req->manual ); - dump_varargs_unicode_str( ", name=", cur_size ); + dump_varargs_object_attributes( ", objattr=", cur_size ); } static void dump_create_timer_reply( const struct create_timer_reply *req ) @@ -2861,7 +2873,6 @@ static void dump_create_named_pipe_request( const struct create_named_pipe_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); fprintf( stderr, ", options=%08x", req->options ); fprintf( stderr, ", sharing=%08x", req->sharing ); fprintf( stderr, ", maxinstances=%08x", req->maxinstances ); @@ -3234,6 +3245,7 @@ fprintf( stderr, " flags=%08x", req->flags ); fprintf( stderr, ", access=%08x", req->access ); fprintf( stderr, ", attributes=%08x", req->attributes ); + fprintf( stderr, ", rootdir=%04x", req->rootdir ); dump_varargs_unicode_str( ", name=", cur_size ); } @@ -3246,6 +3258,7 @@ { fprintf( stderr, " access=%08x", req->access ); fprintf( stderr, ", attributes=%08x", req->attributes ); + fprintf( stderr, ", rootdir=%04x", req->rootdir ); dump_varargs_unicode_str( ", name=", cur_size ); } @@ -3838,14 +3851,22 @@ dump_varargs_security_descriptor( ", sd=", cur_size ); } +static void dump_get_system_handles_request( const struct get_system_handles_request *req ) +{ +} + +static void dump_get_system_handles_reply( const struct get_system_handles_reply *req ) +{ + fprintf( stderr, " count=%08x", req->count ); + dump_varargs_handle_infos( ", data=", cur_size ); +} + static void dump_create_mailslot_request( const struct create_mailslot_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); - fprintf( stderr, ", rootdir=%04x", req->rootdir ); dump_timeout( ", read_timeout=", &req->read_timeout ); fprintf( stderr, ", max_msgsize=%08x", req->max_msgsize ); - dump_varargs_unicode_str( ", name=", cur_size ); + dump_varargs_object_attributes( ", objattr=", cur_size ); } static void dump_create_mailslot_reply( const struct create_mailslot_reply *req ) @@ -3869,9 +3890,7 @@ static void dump_create_directory_request( const struct create_directory_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); - fprintf( stderr, ", rootdir=%04x", req->rootdir ); - dump_varargs_unicode_str( ", directory_name=", cur_size ); + dump_varargs_object_attributes( ", objattr=", cur_size ); } static void dump_create_directory_reply( const struct create_directory_reply *req ) @@ -3908,10 +3927,7 @@ static void dump_create_symlink_request( const struct create_symlink_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); - fprintf( stderr, ", rootdir=%04x", req->rootdir ); - fprintf( stderr, ", name_len=%u", req->name_len ); - dump_varargs_unicode_str( ", name=", min(cur_size,req->name_len) ); + dump_varargs_object_attributes( ", objattr=", cur_size ); dump_varargs_unicode_str( ", target_name=", cur_size ); } @@ -4069,10 +4085,8 @@ static void dump_create_completion_request( const struct create_completion_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); fprintf( stderr, ", concurrent=%08x", req->concurrent ); - fprintf( stderr, ", rootdir=%04x", req->rootdir ); - dump_varargs_unicode_str( ", filename=", cur_size ); + dump_varargs_object_attributes( ", objattr=", cur_size ); } static void dump_create_completion_reply( const struct create_completion_reply *req ) @@ -4233,7 +4247,6 @@ static void dump_create_job_request( const struct create_job_request *req ) { fprintf( stderr, " access=%08x", req->access ); - fprintf( stderr, ", attributes=%08x", req->attributes ); dump_varargs_object_attributes( ", objattr=", cur_size ); } @@ -4242,6 +4255,19 @@ fprintf( stderr, " handle=%04x", req->handle ); } +static void dump_open_job_request( const struct open_job_request *req ) +{ + fprintf( stderr, " access=%08x", req->access ); + fprintf( stderr, ", attributes=%08x", req->attributes ); + fprintf( stderr, ", rootdir=%04x", req->rootdir ); + dump_varargs_unicode_str( ", name=", cur_size ); +} + +static void dump_open_job_reply( const struct open_job_reply *req ) +{ + fprintf( stderr, " handle=%04x", req->handle ); +} + static void dump_assign_job_request( const struct assign_job_request *req ) { fprintf( stderr, " job=%04x", req->job ); @@ -4501,6 +4527,7 @@ (dump_func)dump_set_token_default_dacl_request, (dump_func)dump_set_security_object_request, (dump_func)dump_get_security_object_request, + (dump_func)dump_get_system_handles_request, (dump_func)dump_create_mailslot_request, (dump_func)dump_set_mailslot_info_request, (dump_func)dump_create_directory_request, @@ -4538,6 +4565,7 @@ (dump_func)dump_get_suspend_context_request, (dump_func)dump_set_suspend_context_request, (dump_func)dump_create_job_request, + (dump_func)dump_open_job_request, (dump_func)dump_assign_job_request, (dump_func)dump_process_in_job_request, (dump_func)dump_set_job_limits_request, @@ -4773,6 +4801,7 @@ NULL, NULL, (dump_func)dump_get_security_object_reply, + (dump_func)dump_get_system_handles_reply, (dump_func)dump_create_mailslot_reply, (dump_func)dump_set_mailslot_info_reply, (dump_func)dump_create_directory_reply, @@ -4810,6 +4839,7 @@ (dump_func)dump_get_suspend_context_reply, NULL, (dump_func)dump_create_job_reply, + (dump_func)dump_open_job_reply, NULL, NULL, NULL, @@ -5045,6 +5075,7 @@ "set_token_default_dacl", "set_security_object", "get_security_object", + "get_system_handles", "create_mailslot", "set_mailslot_info", "create_directory", @@ -5082,6 +5113,7 @@ "get_suspend_context", "set_suspend_context", "create_job", + "open_job", "assign_job", "process_in_job", "set_job_limits", @@ -5129,6 +5161,7 @@ { "ERROR_INVALID_CURSOR_HANDLE", 0xc0010000 | ERROR_INVALID_CURSOR_HANDLE }, { "ERROR_INVALID_INDEX", 0xc0010000 | ERROR_INVALID_INDEX }, { "ERROR_INVALID_WINDOW_HANDLE", 0xc0010000 | ERROR_INVALID_WINDOW_HANDLE }, + { "ERROR_NO_MORE_USER_HANDLES", 0xc0010000 | ERROR_NO_MORE_USER_HANDLES }, { "ERROR_WINDOW_OF_OTHER_THREAD", 0xc0010000 | ERROR_WINDOW_OF_OTHER_THREAD }, { "FILE_DELETED", STATUS_FILE_DELETED }, { "FILE_IS_A_DIRECTORY", STATUS_FILE_IS_A_DIRECTORY }, diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/user.h wine-staging-1.9.3~ubuntu12.04.1/server/user.h --- wine-staging-1.9.0~ubuntu12.04.1/server/user.h 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/user.h 2016-02-08 19:32:34.000000000 +0000 @@ -49,6 +49,7 @@ struct list desktops; /* list of desktops of this winstation */ struct clipboard *clipboard; /* clipboard information */ struct atom_table *atom_table; /* global atom table */ + struct namespace *desktop_names; /* namespace for desktops of this winstation */ }; struct global_cursor diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/window.c wine-staging-1.9.3~ubuntu12.04.1/server/window.c --- wine-staging-1.9.0~ubuntu12.04.1/server/window.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/window.c 2016-02-08 19:32:34.000000000 +0000 @@ -1884,7 +1884,7 @@ DECL_HANDLER(create_window) { struct window *win, *parent = NULL, *owner = NULL; - struct unicode_str cls_name; + struct unicode_str cls_name = get_req_unicode_str(); atom_t atom; reply->handle = 0; @@ -1904,7 +1904,6 @@ while (!is_desktop_window(owner->parent)) owner = owner->parent; } - get_req_unicode_str( &cls_name ); atom = cls_name.len ? find_global_atom( NULL, &cls_name ) : req->atom; if (!(win = create_window( parent, owner, atom, req->instance ))) return; @@ -2118,11 +2117,10 @@ unsigned int total; user_handle_t *data; data_size_t len; - struct unicode_str cls_name; + struct unicode_str cls_name = get_req_unicode_str(); atom_t atom = req->atom; struct desktop *desktop = NULL; - get_req_unicode_str( &cls_name ); if (cls_name.len && !(atom = find_global_atom( NULL, &cls_name ))) return; if (req->desktop) @@ -2673,12 +2671,11 @@ /* set a window property */ DECL_HANDLER(set_window_property) { - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); struct window *win = get_window( req->window ); if (!win) return; - get_req_unicode_str( &name ); if (name.len) { atom_t atom = add_global_atom( NULL, &name ); @@ -2695,10 +2692,9 @@ /* remove a window property */ DECL_HANDLER(remove_window_property) { - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); struct window *win = get_window( req->window ); - get_req_unicode_str( &name ); if (win) { atom_t atom = name.len ? find_global_atom( NULL, &name ) : req->atom; @@ -2710,10 +2706,9 @@ /* get a window property */ DECL_HANDLER(get_window_property) { - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); struct window *win = get_window( req->window ); - get_req_unicode_str( &name ); if (win) { atom_t atom = name.len ? find_global_atom( NULL, &name ) : req->atom; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/server/winstation.c wine-staging-1.9.3~ubuntu12.04.1/server/winstation.c --- wine-staging-1.9.0~ubuntu12.04.1/server/winstation.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/server/winstation.c 2016-02-08 19:32:34.000000000 +0000 @@ -42,7 +42,6 @@ static struct list winstation_list = LIST_INIT(winstation_list); -static struct namespace *winstation_namespace; static void winstation_dump( struct object *obj, int verbose ); static struct object_type *winstation_get_type( struct object *obj ); @@ -51,6 +50,7 @@ static unsigned int winstation_map_access( struct object *obj, unsigned int access ); static void desktop_dump( struct object *obj, int verbose ); static struct object_type *desktop_get_type( struct object *obj ); +static int desktop_link_name( struct object *obj, struct object_name *name, struct object *parent ); static int desktop_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); static void desktop_destroy( struct object *obj ); static unsigned int desktop_map_access( struct object *obj, unsigned int access ); @@ -70,6 +70,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + directory_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ winstation_close_handle, /* close_handle */ winstation_destroy /* destroy */ @@ -91,6 +93,8 @@ default_get_sd, /* get_sd */ default_set_sd, /* set_sd */ no_lookup_name, /* lookup_name */ + desktop_link_name, /* link_name */ + default_unlink_name, /* unlink_name */ no_open_file, /* open_file */ desktop_close_handle, /* close_handle */ desktop_destroy /* destroy */ @@ -99,21 +103,18 @@ #define DESKTOP_ALL_ACCESS 0x01ff /* create a winstation object */ -static struct winstation *create_winstation( const struct unicode_str *name, unsigned int attr, - unsigned int flags ) +static struct winstation *create_winstation( struct directory *root, const struct unicode_str *name, + unsigned int attr, unsigned int flags ) { struct winstation *winstation; - if (!winstation_namespace && !(winstation_namespace = create_namespace( 7 ))) - return NULL; - if (memchrW( name->str, '\\', name->len / sizeof(WCHAR) )) /* no backslash allowed in name */ { set_error( STATUS_INVALID_PARAMETER ); return NULL; } - if ((winstation = create_named_object( winstation_namespace, &winstation_ops, name, attr ))) + if ((winstation = create_named_object_dir( root, name, attr, &winstation_ops ))) { if (get_error() != STATUS_OBJECT_NAME_EXISTS) { @@ -123,7 +124,13 @@ winstation->atom_table = NULL; list_add_tail( &winstation_list, &winstation->entry ); list_init( &winstation->desktops ); + if (!(winstation->desktop_names = create_namespace( 7 ))) + { + release_object( winstation ); + return NULL; + } } + else clear_error(); } return winstation; } @@ -132,10 +139,8 @@ { struct winstation *winstation = (struct winstation *)obj; - fprintf( stderr, "Winstation flags=%x clipboard=%p atoms=%p ", + fprintf( stderr, "Winstation flags=%x clipboard=%p atoms=%p\n", winstation->flags, winstation->clipboard, winstation->atom_table ); - dump_object_name( &winstation->obj ); - fputc( '\n', stderr ); } static struct object_type *winstation_get_type( struct object *obj ) @@ -157,6 +162,7 @@ list_remove( &winstation->entry ); if (winstation->clipboard) release_object( winstation->clipboard ); if (winstation->atom_table) release_object( winstation->atom_table ); + free( winstation->desktop_names ); } static unsigned int winstation_map_access( struct object *obj, unsigned int access ) @@ -177,32 +183,6 @@ access, &winstation_ops ); } -/* build the full name of a desktop object */ -static WCHAR *build_desktop_name( const struct unicode_str *name, - struct winstation *winstation, struct unicode_str *res ) -{ - const WCHAR *winstation_name; - WCHAR *full_name; - data_size_t winstation_len; - - if (memchrW( name->str, '\\', name->len / sizeof(WCHAR) )) - { - set_error( STATUS_INVALID_PARAMETER ); - return NULL; - } - - if (!(winstation_name = get_object_name( &winstation->obj, &winstation_len ))) - winstation_len = 0; - - res->len = winstation_len + name->len + sizeof(WCHAR); - if (!(full_name = mem_alloc( res->len ))) return NULL; - memcpy( full_name, winstation_name, winstation_len ); - full_name[winstation_len / sizeof(WCHAR)] = '\\'; - memcpy( full_name + winstation_len / sizeof(WCHAR) + 1, name->str, name->len ); - res->str = full_name; - return full_name; -} - /* retrieve a pointer to a desktop object */ struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle, unsigned int access ) { @@ -214,12 +194,8 @@ unsigned int flags, struct winstation *winstation ) { struct desktop *desktop; - struct unicode_str full_str; - WCHAR *full_name; - if (!(full_name = build_desktop_name( name, winstation, &full_str ))) return NULL; - - if ((desktop = create_named_object( winstation_namespace, &desktop_ops, &full_str, attr ))) + if ((desktop = create_named_object( &winstation->obj, winstation->desktop_names, &desktop_ops, name, attr ))) { if (get_error() != STATUS_OBJECT_NAME_EXISTS) { @@ -237,8 +213,8 @@ list_add_tail( &winstation->desktops, &desktop->entry ); list_init( &desktop->hotkeys ); } + else clear_error(); } - free( full_name ); return desktop; } @@ -246,10 +222,8 @@ { struct desktop *desktop = (struct desktop *)obj; - fprintf( stderr, "Desktop flags=%x winstation=%p top_win=%p hooks=%p ", + fprintf( stderr, "Desktop flags=%x winstation=%p top_win=%p hooks=%p\n", desktop->flags, desktop->winstation, desktop->top_window, desktop->global_hooks ); - dump_object_name( &desktop->obj ); - fputc( '\n', stderr ); } static struct object_type *desktop_get_type( struct object *obj ) @@ -259,6 +233,24 @@ return get_object_type( &str ); } +static int desktop_link_name( struct object *obj, struct object_name *name, struct object *parent ) +{ + struct winstation *winstation = (struct winstation *)parent; + + if (parent->ops != &winstation_ops) + { + set_error( STATUS_OBJECT_TYPE_MISMATCH ); + return 0; + } + if (memchrW( name->name, '\\', name->len / sizeof(WCHAR) )) /* no backslash allowed in name */ + { + set_error( STATUS_OBJECT_PATH_SYNTAX_BAD ); + return 0; + } + namespace_add( winstation->desktop_names, name ); + return 1; +} + static int desktop_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) { struct thread *thread; @@ -423,47 +415,31 @@ if (handle) close_handle( thread->process, handle ); } -/* set the reply data from the object name */ -static void set_reply_data_obj_name( struct object *obj, int full_name ) -{ - data_size_t len; - const WCHAR *ptr, *name = get_object_name( obj, &len ); - - /* if there is a backslash return the part of the name after it */ - if (name && !full_name && (ptr = memchrW( name, '\\', len/sizeof(WCHAR) ))) - { - len -= (ptr + 1 - name) * sizeof(WCHAR); - name = ptr + 1; - } - if (name) set_reply_data( name, min( len, get_reply_max_size() )); -} - /* create a window station */ DECL_HANDLER(create_winstation) { struct winstation *winstation; - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); + struct directory *root = NULL; reply->handle = 0; - get_req_unicode_str( &name ); - if ((winstation = create_winstation( &name, req->attributes, req->flags ))) + if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) return; + + if ((winstation = create_winstation( root, &name, req->attributes, req->flags ))) { reply->handle = alloc_handle( current->process, winstation, req->access, req->attributes ); release_object( winstation ); } + if (root) release_object( root ); } /* open a handle to a window station */ DECL_HANDLER(open_winstation) { - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); - get_req_unicode_str( &name ); - if (winstation_namespace) - reply->handle = open_object( winstation_namespace, &name, &winstation_ops, req->access, - req->attributes ); - else - set_error( STATUS_OBJECT_NAME_NOT_FOUND ); + reply->handle = open_object( current->process, req->rootdir, req->access, + &winstation_ops, &name, req->attributes ); } @@ -507,10 +483,9 @@ { struct desktop *desktop; struct winstation *winstation; - struct unicode_str name; + struct unicode_str name = get_req_unicode_str(); reply->handle = 0; - get_req_unicode_str( &name ); if ((winstation = get_process_winstation( current->process, WINSTA_CREATEDESKTOP ))) { if ((desktop = create_desktop( &name, req->attributes, req->flags, winstation ))) @@ -526,9 +501,8 @@ DECL_HANDLER(open_desktop) { struct winstation *winstation; - struct unicode_str name; - - get_req_unicode_str( &name ); + struct object *obj; + struct unicode_str name = get_req_unicode_str(); /* FIXME: check access rights */ if (!req->winsta) @@ -536,19 +510,17 @@ else winstation = (struct winstation *)get_handle_obj( current->process, req->winsta, 0, &winstation_ops ); - if (winstation) - { - struct unicode_str full_str; - WCHAR *full_name; + if (!winstation) return; - if ((full_name = build_desktop_name( &name, winstation, &full_str ))) - { - reply->handle = open_object( winstation_namespace, &full_str, &desktop_ops, req->access, - req->attributes ); - free( full_name ); - } - release_object( winstation ); + if ((obj = find_object( winstation->desktop_names, &name, req->attributes ))) + { + assert( obj->ops == &desktop_ops ); + reply->handle = alloc_handle( current->process, obj, req->access, req->attributes ); + release_object( obj ); } + else set_error( STATUS_OBJECT_NAME_NOT_FOUND ); + + release_object( winstation ); } /* open a handle to current input desktop */ @@ -649,6 +621,7 @@ DECL_HANDLER(set_user_object_info) { struct object *obj; + data_size_t len; if (!(obj = get_handle_obj( current->process, req->handle, 0, NULL ))) return; @@ -672,8 +645,30 @@ release_object( obj ); return; } - if (get_reply_max_size()) - set_reply_data_obj_name( obj, (req->flags & SET_USER_OBJECT_GET_FULL_NAME) != 0 ); + if (obj->ops == &desktop_ops && get_reply_max_size() && (req->flags & SET_USER_OBJECT_GET_FULL_NAME)) + { + struct desktop *desktop = (struct desktop *)obj; + data_size_t winstation_len, desktop_len; + const WCHAR *winstation_name = get_object_name( &desktop->winstation->obj, &winstation_len ); + const WCHAR *desktop_name = get_object_name( obj, &desktop_len ); + WCHAR *full_name; + + if (!winstation_name) winstation_len = 0; + if (!desktop_name) desktop_len = 0; + len = winstation_len + desktop_len + sizeof(WCHAR); + if ((full_name = mem_alloc( len ))) + { + memcpy( full_name, winstation_name, winstation_len ); + full_name[winstation_len / sizeof(WCHAR)] = '\\'; + memcpy( full_name + winstation_len / sizeof(WCHAR) + 1, desktop_name, desktop_len ); + set_reply_data_ptr( full_name, min( len, get_reply_max_size() )); + } + } + else + { + const WCHAR *name = get_object_name( obj, &len ); + if (name) set_reply_data( name, min( len, get_reply_max_size() )); + } release_object( obj ); } @@ -683,15 +678,18 @@ { unsigned int index = 0; struct winstation *winsta; + const WCHAR *name; + data_size_t len; LIST_FOR_EACH_ENTRY( winsta, &winstation_list, struct winstation, entry ) { unsigned int access = WINSTA_ENUMERATE; if (req->index > index++) continue; if (!check_object_access( &winsta->obj, &access )) continue; - set_reply_data_obj_name( &winsta->obj, 0 ); clear_error(); reply->next = index; + if ((name = get_object_name( &winsta->obj, &len ))) + set_reply_data( name, min( len, get_reply_max_size() )); return; } set_error( STATUS_NO_MORE_ENTRIES ); @@ -704,6 +702,8 @@ struct winstation *winstation; struct desktop *desktop; unsigned int index = 0; + const WCHAR *name; + data_size_t len; if (!(winstation = (struct winstation *)get_handle_obj( current->process, req->winstation, WINSTA_ENUMDESKTOPS, &winstation_ops ))) @@ -715,7 +715,8 @@ if (req->index > index++) continue; if (!desktop->obj.name) continue; if (!check_object_access( &desktop->obj, &access )) continue; - set_reply_data_obj_name( &desktop->obj, 0 ); + if ((name = get_object_name( &desktop->obj, &len ))) + set_reply_data( name, min( len, get_reply_max_size() )); release_object( winstation ); clear_error(); reply->next = index; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/staging/changelog wine-staging-1.9.3~ubuntu12.04.1/staging/changelog --- wine-staging-1.9.0~ubuntu12.04.1/staging/changelog 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/staging/changelog 1970-01-01 00:00:00.000000000 +0000 @@ -1,1778 +0,0 @@ -wine-staging (1.9.0) unstable; urgency=low - * Updated patch for x86_64 set_cpu_context implementation and add tests. - * Added patch to align terminating null WCHAR in SysAllocStringByteLen. - * Added patch to avoid corruption of caret when SetCaretPos() is called. - * Added patch to avoid setting error when NULL is passed to SHMapHandle. - * Added patch to check IsWoW64Process before calling Wow64 functions in - UNIXFS_get_unix_path. - * Added patch to pass MOUSEHOOKSTRUCTEX struct to mouse hook callback. - * Added patch to workaround installation bug of IE7 caused by version bump. - * Removed patch to add a stub driver for tdi.sys (accepted upstream). - * Removed patch to implement support for ws2_32.dll.WSAPoll (accepted - upstream). - * Removed patch for setupapi.SetupDiSelectBestCompatDrv stub implementation - (accepted upstream). - * Removed patch for advapi32.RegCreateKeyTransacted[A/W] stubs (accepted - upstream). - -- Sebastian Lackner Mon, 28 Dec 2015 07:52:11 +0100 - -wine-staging (1.8) unstable; urgency=low - * Update nvencodeapi wrapper patchset to version 6.0 and fix Debian - compatibility. - * Added patch to add implementation of wusa.exe (MSU package installer). - -- Sebastian Lackner Mon, 21 Dec 2015 18:31:02 +0100 - -wine-staging (1.8~rc4) unstable; urgency=low - * Updated patch to fix implementation of NtQueryInformationProcess for - ProcessDebugFlags. - * Removed patch to set LastError to 0 in GetSidIdentifierAuthority (accepted - upstream). - * Removed patch to return an error when trying to open a terminated process - (replaced with alternative approach). - * Added patch to avoid holding reference on parent process in wineserver. - * Added patch to fix memory corruption in wineserver (token_duplicate should - not reference the original token). - -- Sebastian Lackner Tue, 15 Dec 2015 00:53:33 +0100 - -wine-staging (1.8~rc3) unstable; urgency=low - * Updated patch for d3dx9_36 DrawText implementation and fixed multiple bugs. - * Removed patch for delayed end of DST in Europe/Istanbul (accepted upstream). - * Removed patch to add partial implementation of ITfThreadMgrEx_ActivateEx - (accepted upstream). - * Removed patch to fix access violation in MSYS2 git when cloning repository - (accepted upstream). - * Removed patch to skip invalid entries in GetPrivateProfileString16 (accepted - upstream). - * Removed patch to show windows version when collecting system info in winedbg - (accepted upstream). - * Added patch to fix possible leak of explorer.exe processes and implement - proper desktop refcounting. - * Added patch to set LastError to 0 in GetSidIdentifierAuthority. - * Added patch to properly implement GetLargestConsoleWindowSize. - * Added patch to fix implementation of NtQueryInformationProcess for - ProcessDebugFlags. - -- Sebastian Lackner Mon, 07 Dec 2015 17:09:58 +0100 - -wine-staging (1.8~rc2) unstable; urgency=low - * Updated patch to commit page when handling stack fault, and add tests. - * Removed patch to revert "prepare GLresources before calling - context_apply_fbo_state" commit. - * Removed patch to set EAX to 0 in Basic_string_wchar_dtor (accepted - upstream). - * Removed patch for IDXGIOutput::GetDesc (fixed upstream). - * Removed patch to fix possible endless loop in regedit when importing - specific files (accepted upstream). - * Removed patch to add NULL pointer check in dibdrv_wglDescribePixelFormat - (accepted upstream). - * Removed patch to enforce that surfaces are flushed after ReleaseDC (fixed - upstream). - * Added patch to implement check for invalid handle type for HSPFILEQ handles. - * Added patch for delayed end of DST in Europe/Istanbul. - * Added patch to skip invalid entries in GetPrivateProfileString16. - * Added patch to send WM_CAPTURECHANGE also when capture has not changed. - * Added patch to silence repeated FIXME message in surface_cpu_blt. - * Added patch to start SERVICE_FILE_SYSTEM_DRIVER services with winedevice. - * Added patch to allow to set debug registers separately in - NtSetContextThread. - * Added patch to ignore socket type for protocol IPPROTO_IPV6 in getaddrinfo. - * Added patch to implement dinput device property DIPROP_USERNAME. - * Added patch to ensure default route IP addresses are returned first in - gethostbyname. - -- Sebastian Lackner Sun, 29 Nov 2015 21:23:16 +0100 - -wine-staging (1.8~rc1) unstable; urgency=low - * Removed patch to allow dinput EnumDevices callback with broken calling - convention (accepted upstream). - * Removed patch to fix required privileges for load_registry and - unload_registry - wineserver call (accepted upstream). - * Added patch to improve detection of symbol charset for old truetype fonts. - * Added patch to change value for WM_MDICALCCHILDSCROLL to 0x003f. - * Added patch to avoid leaking output name in sfnt2fon if specified multiple - times. - * Added patch to fix a possible leak in codeview_dump_symbols. - * Added patch for stub driver tdi.sys. - -- Sebastian Lackner Mon, 23 Nov 2015 07:55:14 +0100 - -wine-staging (1.7.55) unstable; urgency=low - * Added patch to revert "Prepare GL resources before calling - context_apply_fbo_state". - * Added patch to implement support for "Purist Mode" (override for all dlls). - * Added patch for partial implementation of ITfThreadMgrEx_ActivateEx. - * Added patch for stub of hid.HidP_TranslateUsagesToI8042ScanCodes. - * Added patch to properly handle multiple registry notifications per key. - * Added patch for stub of kernel32.FreeUserPhysicalPages. - * Added patch for stubs of advapi32.RegCreateKeyTransacted[A/W]. - * Added patch to fix required privileges for load_registry and unload_registry - wineserver call. - * Added patch to make sure CompareString immediately aborts on first non- - matching character. - * Added patch to implement marshalling for TKIND_COCLASS. - * Added patch to implement stubless proxies on x86_64. - * Added patch to allow dinput EnumDevices callback with broken calling - convention. - * Added patch to allow to set default display frequency in registry (fixes - Wine Staging Bug #609). - * Remove disabled shell32-Quoted_ShellExecute patchset (bug already fixed and - all tests pass). - * Remove disabled reg-Cleanup patchset (only cleanup and not actively - maintained). - * Remove disabled ntdll-FD_Cache patchset (only for PowerPC, no longer - necessary because Wine uses inline cmpxchg64 now when compiling with gcc). - * Removed patch to implement kernel32.GetConsoleFontSize (accepted upstream). - * Removed patch to zero out returned stats when IEnumSTATSTG::Next reaches end - of enumeration (accepted upstream). - * Removed patch for SfcGetNextProtectedFile stub function (accepted upstream). - * Removed patch for SetConsoleKeyShortcuts stub function (accepted upstream). - * Removed various PulseAudio driver patches (accepted upstream). - * Removed patch to protect TVM_GETITEM from invalid item pointers (accepted - upstream). - * Removed patch to ensure that X11 input events handled even without explicit - message loop (accepted upstream). - * Removed patches to fix multiple issues in widl typelib generator (accepted - upstream). - * Removed patch to fix handling of opening read-only files for - FILE_DELETE_ON_CLOSE (accepted upstream). - * Removed patch to fix cursor clip regression / broken raw input in multiple - games (accepted upstream). - * Removed patch for ntoskrnl.ProbeForRead stub (accepted upstream). - -- Sebastian Lackner Sun, 15 Nov 2015 18:40:25 +0100 - -wine-staging (1.7.54) unstable; urgency=low - * Updated server-FileEndOfFileInformation patchset, growing a memory mapped - file should still work. - * Added patch to use wrapper function for consolidation callback during - unwinding. - * Added patch to implement stub for ProcessQuotaLimits info class. - * Added patch to release capture before sending WM_COMMAND. - * Added patch to block interruption of system APC in server_select. - * Added patch to implement FileNamesInformation class support for - NtQueryDirectoryFile. - * Added patch for implementation of additional HSTRING functions. - * Added patches for memory allocation cleanup in gdiplus functions. - * Added patch to implement hal.KeQueryPerformanceCounter. - * Added patch to fix build failure (introduced by makefile rewrite). - * Added patch to pass '-read_only_relocs suppress' to the linker on OSX and - enable patchset to use Nt* function wrappers. - * Added patch to use close_handle instead of NtClose for internal memory - management functions. - * Added patch to improve INetFwAuthorizedApplication::get_ProcessImageFileName - stub. - * Added patch for SetCoalescableTimer stub function. - * Added patch for SfcGetNextProtectedFile stub function. - * Added patch to zero out returned stats when IEnumSTATSTG::Next reaches end - of enumeration. - * Added patch to fix multiple issues in widl typelib generation. - * Added patch for SetConsoleKeyShortcuts stub function. - * Added patch to implement kernel32.GetConsoleFontSize. - * Added patch to implement SystemHandleInformation info class. - * Removed patch to implement kernel32.GetPhysicallyInstalledSystemMemory - (accepted upstream). - * Partially removed patches for ws2_32 TransmitFile (accepted upstream). - * Removed patch to fix NULL dereference in ICSeqCompressFrameStart (fixed - upstream). - * Removed patch to return default palette entries from GetSystemPaletteEntries - for non-palette-based devices (accepted upstream). - * Removed patch to use wrapper function for consolidate callback during - unwinding on x86_64 (accepted upstream). - * Removed patch to release capture before sending WM_COMMAND (accepted - upstream). - * Removed patch to avoid check for signaled object after user APC in - server_select (accepted upstream). - * Removed patch to implement combase.WindowsSubstring function (accepted - upstream). - * Removed patch to fix build failure (identical patch committed upstream). - * Removed patch for vcruntime120 dll (accepted upstream). - -- Sebastian Lackner Sun, 01 Nov 2015 00:14:59 +0100 - -wine-staging (1.7.53) unstable; urgency=low - * Added patch to implement support for msiexec /passive command line option. - * Added patch to implement stub for DSPROPSETID_EAX20_ListenerProperties. - * Added patch to show windows version when collecting system info in winedbg. - * Added patch to implement DSPROPSETID_EAX20_ListenerProperties stub. - * Added patch to implement DSPROPSETID_EAX20_BufferProperties stub. - * Added patch to fix handling of wait interrupted by User APC. - * Added patch to use wrapper functions for syscalls to appease Chromium - sandbox (32-bit Linux only). - * Added patch to fix the initialization of combined DACLs when the new DACL is - empty. - * Added patch to implement comctl32.PROPSHEET_InsertPage. - * Added patch to return WN_NOT_CONNECTED from WNetGetUniversalName - REMOTE_NAME_INFO_LEVEL stub. - * Added patch to always use 64-bit registry view on WOW64 setups. - * Added patch to implement kernel32.GetPhysicallyInstalledSystemMemory. - * Added patch to delay signaling threads until they are really gone (fixes - Wine Staging Bug #473). - * Removed patch to mark RegOpenKeyExA, RegCloseKey and RegQueryValueExA as - hotpatchable (accepted upstream). - * Removed patch to mark BitBlt and StretchDIBits as hotpatchable (accepted - upstream). - * Removed patch to mark WritePrivateProfileStringA as hotpatchable (accepted - upstream). - * Removed patch to implement ws2_32.InetPtonW function (accepted upstream). - * Removed patch to pass cookie by reference to msvcrt_local_unwind4 in - _seh_longjmp_unwind4 (accepted upstream). - * Removed patch to implement LoadIconMetric (accepted upstream). - * Removed patch to correctly parse double quotes in msi token values (accepted - upstream). - * Removed patch to ignore width/height passed to edit control in WM_SIZE - message (accepted upstream). - * Removed patch to silence repeated wbemprox "timeout not supported" fixme - (fixed upstream). - * Removed patch to add support for /passive command line option to msiexec - (fixed upstream). - * Removed patch to return a dummy BIOS name in Win32_BIOS (accepted upstream). - * Removed patch to implement empty enumerator for IWiaDevMgr::EnumDeviceInfo - (accepted upstream). - * Removed patch to translate flags in LaunchINFSectionW (accepted upstream). - * Removed patch to return success when trying to disable proxy, although no - proxy is set (accepted upstream). - * Partially removed patches for ws2_32 TransmitFile (accepted upstream). - -- Sebastian Lackner Mon, 19 Oct 2015 06:08:07 +0200 - -wine-staging (1.7.52) unstable; urgency=low - * Added patch to return STATUS_INVALID_DEVICE_REQUEST when trying to call - NtReadFile on directory. - * Added patch to ignore higher bits in selector for ThreadDescriptorTableEntry - info query. - * Added patch to ensure codepage conversion fails when destination length is - smaller than zero. - * Added patches for msidb commandline utility (to read and write *.msi files). - * Added patch to implement semi-stub for d3d8 swapchain effect - D3DSWAPEFFECT_COPY_VSYNC. - * Added patch to reduce stack usage of virtual memory functions. - * Added patch to fix calculation of listbox size when horizontal scrollbar is - present. - * Added patch to ignore width/height passed to edit control in WM_SIZE - message. - * Added patch to refresh MDI menus when DefMDIChildProc(WM_SETTEXT) is called. - * Added patch to protect TVM_GETITEM from invalid item pointers. - * Added patch to avoid using GdipAlloc and GdipFree in internal gdiplus - functions. - * Added patch to implement additional stub functions in authz.dll. - * Added patch to avoid waiting for hook thread startup in - IDirectInput8::Initialize. - * Added patch to pass cookie by reference to msvcrt_local_unwind4 in - _seh_longjmp_unwind4. - * Added patch to mark RegOpenKeyExA, RegCloseKey and RegQueryValueExA as - hotpatchable. - * Added patch to mark BitBlt and StretchDIBits as hotpatchable. - * Added patch to mark WritePrivateProfileStringA as hotpatchable. - * Added patch to make ddraw1 and ddraw_surface1 vtable as writable. - * Added patch for implementation of mfplat.MFTEnum. - * Added patch to implement ws2_32.InetPtonA/W functions. - * Added patch to fix random crashes of Cygwin/MSYS2 for some compilers. - * Added patch to correctly parse double quotes in the msi token values. - * Removed patch to fix possible memory leak in netprofm init_networks (fixed - upstream). - * Removed patch for stub of dwmapi.DwmUpdateThumbnailProperties (accepted - upstream). - * Removed patch free RPC parameters allocated by application before anything - else (fixed upstream). - * Removed patch to try harder to get the host name address in getaddrinfo - (accepted upstream). - * Rempved patch to use proper glyph names in wineps driver (accepted - upstream). - * Removed patches with stubs for d3dx10_43.D3DX10CreateEffectFromFileA/W - (accepted upstream). - * Removed patch to ignore higher bits in selector for - ThreadDescriptorTableEntry info query (accepted upstream). - * Removed patch to avoid deprecation warning for OpenCL 1.2 APIs (accepted - upstream). - * Removed patch to forward exitcode from child process in wineconsole - (accepted upstream). - * Removed patch to fix failure to create anonymous file mapping after failed - open_fd server call (accepted upstream). - * Removed patch to implement semi-stub for d3d8 swapchain effect - D3DSWAPEFFECT_COPY_VSYNC (identical patch accepted upstream). - * Removed patch to implement {Set,Get}ThreadGroupAffinity and related ntdll - functions (accepted upstream). - * Removed patch to return STATUS_OBJECT_NAME_INVALID in - wine_nt_to_unix_file_name for paths that only contain a prefix (accepted - upstream). - * Removed patch to implement support for non-blocking SIO_ADDRESS_LIST_CHANGE - requests (accepted upstream). - -- Sebastian Lackner Sat, 03 Oct 2015 22:15:47 +0200 - -wine-staging (1.7.51) unstable; urgency=low - * Update patchset for CSMT (commandstream multithreading), to keep in sync - with upstream repository. - * Added patch to fix bug in wineserver debug_children inheritance (fixes Wine - Staging Bug #525). - * Added patch to fix access violation in MSYS2 git when when cloning - repository (fixes Wine Staging Bug #348). - * Added patch to return a dummy BIOS name in Win32_BIOS record (fixes Wine - Staging Bug #528). - * Added patch to fix compile failure in d3d11 with recent versions of gcc. - * Added patch to map EXDEV error code to STATUS_NOT_SAME_DEVICE (fixes Wine - Staging Bug #536). - * Added patch to fix failure to create anonymous file mapping after failed - open_fd server call (fixes Wine Staging Bug #538). - * Added patch to fix error handling in DeferWindowPos when passing an invalid - HWND. - * Added patch to allow non-nullterminated string as working directory in - kernel32.create_startup_info (fixes Wine Staging Bug #543). - * Added patch with stub for winspool.SetPrinterW level 8. - * Added patch to translate flags in LaunchINFSectionW. - * Added patch to fix SHFileOperation with FO_MOVE on Vista+ (should create - non-existent subdirectories). - * Added patch to silence repeated crypt32.CryptUnprotectMemory FIXMEs. - * Added patch to fallback to default comspec when %COMSPEC% is not set (fixes - Wine Staging Bug #449). - * Added patch to create Microsoft\Windows\Themes directory during Wineprefix - creation. - * Added patch to avoid deprecation warning for OpenCL 1.2 APIs. - * Added patch to implement FolderImpl_Items and stubbed FolderItems interface. - * Added patch for stub of dwmapi.DwmUpdateThumbnailProperties. - * Added patch to use proper glyph names in wineps driver (which fixes a bug - related to copying text from generated PDF files). - * Added patch to properly close sockets when WSACleanup is called. - * Added patch to implement {Set,Get}ThreadGroupAffinity and related ntdll - functions. - * Added patch to properly render themed buttons when they are pressed. - * Added patch to fix possible memory leak in netprofm init_networks. - * Added patch to properly initialize caps->dwZBufferBitDepths in - ddraw7_GetCaps. - * Added patch to for IHTMLLocation::hash property's getter implementation. - * Removed patch to fix bug in wineserver debug_children inheritance (accepted - upstream). - * Removed patch to use helper function for NtWaitForMultipleObjects and - NtWaitForSingleObject (accepted upstream). - * Removed patch to fix test failure in kernel32/thread tests (fixed upstream). - * Removed patch to use request->server->name when processing cookies - (identical patch accepted upstream). - * Removed patch to set Host header in HttpSendRequest instead of - HttpOpenRequest (accepted upstream). - * Removed patch to make sure Notepad creates new files immediately (accepted - upstream). - * Partially removed patches for stub dlls required by the MSVC 2015 runtime - library (accepted upstream). - -- Sebastian Lackner Mon, 07 Sep 2015 02:29:55 +0200 - -wine-staging (1.7.50) unstable; urgency=low - * Updated GTK3 patchset to fix "division by zero" exception errors (fixes Wine - Staging Bug #523). - * Add patch to implement remaining OpenMP locking functions. - * Added various patches for imagehlp cleanup (fixes Wine Staging Bug #502). - * Added patch to fix implementation of ntdll.MapViewOfSection. - * Added patch to implement enumeration of sound devices and basic properties - to dxdiagn. - * Added patch to implement special handling for calling GetChildContainer with - an empty string. - * Added patch for shell32 IDragSourceHelper stub interface. - * Added patch to improve startup performance by delaying font initialization - (fixes Wine Staging Bug #401). - * Added patch to set SFGAO_HASSUBFOLDER only when there are really subfolders. - * Added patch to fix multiple uninitialized memory issues in wineserver. - * Added patch to implement shell32 NewMenu class with new folder item. - * Added patch to report correct ObjectName for NamedPipe wineserver objects - (fixes Wine Staging Bug #363). - * Added patch fix detection of case-insensitive systems in MSYS2. - * Added patch to fix implementation of krnl386.exe16.GetTempDrive. - * Added patch for forward/backward compatibility of previous format of high - precision registry timestamps. - * Added patch to use a helper function for NtWaitForMultipleObjects and - NtWaitForSingleObject. - * Added patch to block deallocation of thread stack for current thread (fixes - Wine Staging Bug #241). - * Added patch to reject setting EOF on memory mapped files (fixes Wine Staging - Bug #471). - * Added patch to fix implementation of msvcrt.close when stdout == stderr - (fixes Wine Staging Bug #485). - * Added patch to return STATUS_OBJECT_NAME_INVALID in - wine_nt_to_unix_file_name for paths that only contain a prefix. - * Added patch to make sure Notepad creates new files immediately. - * Added patch to return a valid mesh in D3DXCreateTeapot. - * Removed patch to move security cookie initialization from memory management - to loader (accepted upstream). - * Removed patches for stub of D3DCompileFromFile and D3DCompile2 (accepted - upstream). - * Removed patch to fix multiple uninitialized memory issues in wineserver. - * Removed patch fix implementation of ntdll.NtMapViewOfSection (accepted - upstream). - * Removed patches to implement additional vcomp functions (accepted upstream). - * Removed patch to store registry timestamps with nanoseconds precision (fixed - upstream). - * Removed patch to ensure winhttp raw request headers are terminated with - double \r\n (accepted upstream). - * Removed compatibility patchset for deprecated ACL string format. The format - was changed in version 1.7.25, released about one year ago. - * Removed patches for FileDispositionInformation and FileRenameInformation - (accepted upstream). - -- Sebastian Lackner Sun, 23 Aug 2015 02:10:01 +0200 - -wine-staging (1.7.49) unstable; urgency=low - * Added patch to improve stubs for dxgi MakeWindowAssociation and - GetWindowAssociation. - * Added patch for stub dlls required by the MSVC 2015 runtime library. - * Added patch with stubs for additional wininet options in InternetSetOption - (fixes Wine Staging Bug #443). - * Added patch to implement stub for vcomp._vcomp_flush. - * Added patch to fix leak and use-after-free in winecfg theming - implementation. - * Added patch to move cookie initialization code from memory management to - loader. - * Added patch to fake success in IViewObject::Draw stub. - * Added patch to fix possible integer overflow in VarR4FromDec. - * Added patch to make sure Winhttp raw request headers are terminated using - double \r\n. - * Added patch for native GTK3 theming support by Ivan Akulinchev. - * Removed patch to avoid race-conditions with long running threadpool tasks - (accepted upstream). - * Removed patch to add support for ThreadQuerySetWin32StartAddress info class - (accepted upstream). - * Removed patch to fix security cookie handling for UPX compressed executables - (accepted upstream). - * Removed patch to force creation of MachineGuid registry key during creation - of Wineprefix (accepted upstream). - * Removed patch to add stub for D3DXComputeNormals (fixed upstream). - * Removed patch to add stub for D3DXTessellateNPatches (accepted upstream). - * Removed patch to improve stub for NtQueryInformationJobObject (accepted - upstream). - * Removed patch to avoid OpenCL deprecation warnings (accepted upstream). - * Removed patch for implementation of dbghelp.UnDecorateSymbolNameW (accepted - upstream). - * Removed patch for dynamic work scheduling in vcomp.dll (accepted upstream). - * Removed patch to send WM_DROPFILES only when OLE dnd fails (accepted - upstream). - -- Sebastian Lackner Sun, 09 Aug 2015 22:03:07 +0200 - -wine-staging (1.7.48) unstable; urgency=low - * Update patches for d3dx9_36.D3DXGetShader{Input,Output}Semantics and add - additional tests. - * Update patchset to query GPU infos with GLX_MESA_query_renderer extension - (fixes a regression with broken MESA versions). - * Update vcomp patchset and add implementation for various atomic functions. - * Updated CSMT patchset to fix crash in Path of Exile after character - selection (fixes Wine Staging Bug #451). - * Added patch to forward exitcode from child process when in wineconsole. - * Added patch to check architecture before trying to load libraries. - * Added patch to share source of d3dx9_36 with d3dx9_33 to avoid Wine DLL - forwards. - * Added patch with stubs for d3dx10_43.D3DX10CreateEffectFromFileA/W. - * Added patch to silence repeated LocaleNameToLCID/LCIDToLocaleName - unsupported flags FIXMEs. - * Added patches to improve security cookie handling. - * Added patches to implement ThreadQuerySetWin32StartAddress info class. - * Added patch to fake success in kernel32.SetFileCompletionNotificationModes. - * Added patch to export additional OpenAL32 functions. - * Added patch to return dummy ID3DXSkinInfo interface when skinning info not - present. - * Added patch to store registry timestamps with nanoseconds precision. - * Added patch to implement AMStream GetMultiMediaStream functions. - * Added patch with stub for D3DXTessellateNPatches. - * Added patch with stubs for D3DCompile2 and D3DCompileFromFile. - * Added patch to implement dbghelp.UnDecorateSymbolNameW. - * Added patch to add wined3d detection of GeForce GT 425M. - * Added patch to use video memory for rendering targets if possible. - * Added patch to avoid race-conditions with long running threadpool tasks. - * Removed patch to allow to enable/disable InsertMode in wineconsole settings - (accepted upstream). - * Removed patch to improve IoGetDeviceObjectPointer stub to appease SecuROM - 5.x (accepted upstream). - * Removed patch to forward GIF encoder requests to Windowscodecs (accepted - upstream). - * Removed patch to ignore garbage after decoding gif lines (accepted - upstream). - * Removed patch to increase buffer size in widl/typegen.c (accepted upstream). - * Removed patch to revert security cookie changes in loader (fixed upstream). - * Removed patch to add support 8bpp grayscale TIFF images with 8bpp alpha - channel (accepted upstream). - * Partrially removed patches for vcomp implementation (accepted upstream). - -- Sebastian Lackner Wed, 29 Jul 2015 21:11:07 +0200 - -wine-staging (1.7.47) unstable; urgency=low - * Added patch to silence repeated winhttp "no support on this platform" - message. - * Added patch to silence repeated wbemprox "timeout not supported" fixme. - * Added patch to increase buffer size in widl/typegen.c to avoid buffer - overflow. - * Revert security cookie patch causing regression in multiple applications. - * Added patch to use GLX_MESA_query_renderer extension to get more exact GPU - infos. - * Added initial set of patches for multithreaded vcomp implementation. - * Added patch to avoid dereferencing NULL pointer for fonts without VDMX. - * Removed patch to implement kernel32.GetNumaProcessorNode (accepted - upstream). - * Removed patch to initialize *end with NULL on failure in msvcrt.strtod - (accepted upstream). - * Removed patchset for new Threadpool implementation (accepted upstream). - * Partially removed patches for RtlDecompressBuffer implementation (accepted - upstream). - -- Sebastian Lackner Sun, 12 Jul 2015 04:12:43 +0200 - -wine-staging (1.7.46) unstable; urgency=low - * Add reference to upstream bug report for various patchsets. - * Added patch to improve IoGetDeviceObjectPointer stub to appease SecuROM 5.x. - * Added patch to globally invalidate key state on changes in other threads. - * Added patch to fix possible use-after-free in wineserver device IPR code. - * Added patch to fix wineserver crash when pipe server object is destroyed - before client (fixes Wine Staging Bug #393). - * Added patches to improve crosscompiling Wine for other platforms. - * Added patch to improve output of '--check-libs' on OSX. - * Added patch to implement general tab for file property dialog. - * Added patch to initialize *lpcDevices in RasEnumDevicesA. - * Improved nvcuda-CUDA_Support patchset to search for dylib on OSX. - * Improved wined3d-DXTn patchset to search for dylib on OSX. - * Updated kernel32-GetVolumePathName to fix several test failures. - * Updated ntoskrnl-Emulator patchset to implement emulation of MOVZX - instruction on x86_64. - * Updated patchset ntdll-WRITECOPY to be compatible with OSX (fixes Wine - Staging Bug #399). - * Disable patch to avoid crash when NULL pointer is passed to atof / strtod - functions (fixed upstream). - * Removed patch for implementation of GdipCreateRegionRgnData (accepted - upstream). - * Removed patch to fix output buffer size for IOCTL_DVD_READ_STRUCTURE - requests (accepted upstream). - * Removed patch to add stub for kernel32.SetFileCompletionNotificationModes - (accepted upstream). - * Removed patch to use random names when caching very long urls in wininet - (accepted upstream). - * Removed patch to fix link notification conditions for riched20 (accepted - upstream). - * Removed patch to emulate access to USER_SHARE_DATA on x86_64 (accepted - upstream). - * Removed patch to fix possible use-after-free in wineserver device IPR code - (accepted upstream). - * Removed patches to implement GetVolumePathName (accepted upstream). - * Removed patch for advapi32.GetWindowsAccountDomainSid (accepted upstream). - * Removed patch for stub implementation of fltlib.FilterLoad (accepted - upstream). - * Removed patch for AT_ROUND_TO_PAGE support in NtMapViewOfSection (accepted - upstream). - * Removed patch to fix linking against libunwind on Linux (fixed upstream). - -- Sebastian Lackner Sun, 28 Jun 2015 18:20:36 +0200 - -wine-staging (1.7.45) unstable; urgency=low - * Add reference to upstream bug report for various patchsets. - * Updated server-Key_State patchset to fix a test failure in - comctl32/listview. - * Updated shell32-Icons patchset to fix a test failure in comctl32/imagelist. - * Updated shlwapi-AssocGetPerceivedType patchset to fix error checking for - RegGetValueW. - * Updated patch to fix opening clipboard from multiple threads (partially - fixed upstream). - * Updated patchset for ObjectTypeInformation and fix typename for various - additional wineserver object types. - * Added patches for FileRenameInformation support (fixes Wine Staging Bug - #296). - * Added additional tests for behaviour of opening readonly files. - * Added patch to fix opening a readonly file with FILE_WRITE_ATTRIBUTES access - (fixes Wine Staging Bug #298). - * Added patch to silence test failures in ntdll/directory tests. - * Added patches for support of FileLinkInformation (fixes Wine Staging Bug - #297). - * Added patch to restore original error code in rpcrt4 when ReadFile fails - with ERROR_MORE_DATA. - * Added patch to set NamedPipeState to FILE_PIPE_CLOSING_STATE on broken pipe - in NtQueryInformationFile. - * Added patch to allow setting pixel format for desktop window. - * Added patch to set a proper caption for shell32 Run dialog (by Jared - Smudde). - * Added patch to support AT_ROUND_TO_PAGE flag in NtMapViewOfSection (fixes - Wine Staging Bug 347). - * Added patches to fix error code for ReadFile/WriteFile on closed pipe (fixes - Wine Staging Bug #348). - * Added patch to initialize - System\CurrentControlSet\Control\TimeZoneInformation registry keys. - * Added patch to implement default homepage button in inetcpl.cpl. - * Added patch to fix link notification conditions for riched20. - * Added patch to fix endless loop in regedit when importing files with very - long lines. - * Added patch to improve stubs for NtQueryEaFile. - * Added patch for semi-stub of FileFsVolumeInformation information class. - * Added patch to use NVX_GPU_MEMORY_INFO extension for more exact video memory - accounting on NVIDIA graphic cards. - * Added patch to fix handling of periodic advice timers causing high CPU - usage. - * Added patch to forward GIF encoder requests to windowscodecs. - * Added patch to ensure console InsertMode changes take effect immediately. - * Added patch to send WM_DROPFILES only when OLE dnd fails. - * Added patch with stub for winscard.SCardListReadersA/W. - * Added patch to implement fallback to system ping command when CAP_NET_RAW is - not available. - * Added patch to properly check existence of libunwind before linking against - it. - * Added patch to implement advapi32.GetWindowsAccountDomainSid. - * Removed patch to handle '\r' as whitespace in wbemprox queries (accepted - upstream). - * Removed patch to make sure OpenClipboard with current owner doesn't fail - (accepted upstream). - * Removed patch to add IEnumString stub interface for ACLShellSource (fixed - upstream). - * Removed patch to fix NULL pointer dereference in get_frame_by_name - (identical patch accepted upstream). - * Removed patch to output winedbg system information also to the terminal - (accepted upstream). - * Removed patch to fix handling of periodic advice timers causing high CPU - usage (accepted upstream). - * Removed revert path to fix broken rendering in various games (fixed - upstream). - * Removed patch to set a valid linker version in winebuild (accepted - upstream). - * Removed patch to fix wrong return value in directmusic (accepted upstream). - * Removed patch to implement support for GetSystemTimes (accepted upstream). - * Removed patch to implement file disposition class in - SetFileInformationByHandle (accepted upstream). - * Removed patch to make additional ddraw functions hotpatchable (accepted - upstream). - -- Sebastian Lackner Sun, 14 Jun 2015 00:38:15 +0200 - -wine-staging (1.7.44) unstable; urgency=low - * Added patch to handle '\r' as whitespace in wbemprox queries. - * Added patch with stubbed ISWbemSecurity interfaces in wbemdisp. - * Added patch with shell32 placeholder icons to match offsets with Windows. - * Added patch to assign a drive serial number during prefix creation/update. - * Added patch for support of ws2_32.dll.WSAPoll. - * Added patch to allow to enable/disable InsertMode in wineconsole settings. - * Added patch for stub of iphlpapi.ConvertInterfaceLuidToGuid. - * Added patch to use random names when caching very long urls (fixes Wine - Staging Bug #266). - * Added patch to fix crash in Gothic 1/2 with builtin directmusic caused by - wrong return value. - * Added patch to return fake device type when systemroot is located on virtual - disk (improves compatibility when wineprefix is on tmpfs). - * Added patch to fix NULL pointer dereference in get_frame_by_name. - * Added patch to fix handling of opening a file with RootDirectory pointing to - a file handle. - * Added patch to output winedbg system information also to the terminal, not - only to dialog. - * Added patch to allow hiding wine version information from applications. - * Added patch to fix scaling behaviour of images and mipmap levels in - IDirect3DTexture2_Load. - * Added patchset to fix various upstream issues detected by Coverity. - * Added patch to avoid using unixfs for devices without mountpoint. - * Revert upstream patch which causes broken rendering in various games. - * Removed patch to reset device state in SysKeyboard*Impl_Acquire (accepted - upstream). - * Removed patch to avoid creating thread queues for foreign threads in - attach_thread_input (accepted upstream). - * Removed patch to fix access violation when calling GetStringTypeW with NULL - src (accepted upstream). - * Removed patch to return correct device type for CD devices without medium - (accepted upstream). - * Removed patch to fix memory leak in wininet cookie handling (accepted - upstream). - * Removed patch to allocate fake hWnd for wineconsole curses backend (accepted - upstream). - * Removed patch to dirtify vertex shader on transformed update (accepted - upstream). - * Removed patch to avoid appending duplicate NULL characters when importing - keys with regedit (accepted upstream). - * Removed patch to implement kernel32.GetSystemTimePreciseAsFileTime (accepted - upstream). - * Removed various patches containing tests (accepted upstream). - * Removed patches for advapi32.ImpersonateAnonymousToken (accepted upstream). - * Removed patches for Win32_SystemEnclosure support (accepted upstream). - * Removed patch with tests for CoWaitForMultipleHandles and WM_QUIT (accepted - upstream). - * Removed patches for AtlIPersistPropertyBag_Save stub (accepted upstream). - * Removed patches to set last error when GetRawInputDeviceList fails (accepted - upstream). - * Removed patches for \Device\Null driver (fixed upstream with alternative - solution). - * Removed patches for semi-stub of GetFileVersionInfo[Size]ExA/W (fixed - upstream). - * Partially removed patches for ITextFont/ITextPara implementation (fixed - upstream). - -- Sebastian Lackner Sun, 31 May 2015 04:43:28 +0200 - -wine-staging (1.7.43) unstable; urgency=low - * Disable patchset shell32-Default_Folder_ACLs (fixes Wine Staging Bug #265). - * Updated patch to calculate msvcrt exponential math operations with higher - precision (fixes Wine Staging Bug #268). - * Updated patchset for CopyFileEx improvements, fix testfailures in - kernel32/file and add additional tests. - * Updated patch to emulate \Device\Null using /dev/null, use a proper device - driver. - * Added patch to wait before reusing recently freed memory (fixes Wine Staging - Bug #269 and #199). - * Added patch to improve ReadDataAvailable handling in - FilePipeLocalInformation class. - * Added patch with tests for shlwapi.AssocGetPerceivedType. - * Added patch with stub for atl80.AtlIPersistPropertyBag_Save. - * Added patch to return default palette entries from GetSystemPaletteEntries - for non-palette-based devices. - * Added patch with stub for winsta.WinStationEnumerateW. - * Added patch to implement support for ObjectTypeInformation class support in - NtQueryObject. - * Added patch to fix error handling in OpenSCManagerW (fixes testfailure in - advapi32/service tests when named pipe messagemode is available). - * Added patch to fix leak of async handle in pipe_server_flush. - * Added patch to dirtify vertex shader on transformed update, fixes graphical - corruption. - * Added patch to use POSIX implementation to enumerate directory content on - FreeBSD. - * Added patch for stub of fltlib.FilterLoad. - * Added patch to implement shlwapi.AssocGetPerceivedType. - * Added patch to avoid creating foreign thread queues for attach_thread_input - requests. - * Added patch with IEnumString stub interface for ACLShellSource. - * Added patch to create stub files for - system32/drivers/etc/{services,hosts,networks,protocol}. - * Added patch to allocate fake hWnd for wineconsole curses backend. - * Added patch to implement kernel32.GetSystemTimePreciseAsFileTime. - * Added patch with tests for - imagehlp.{ImageLoad,ImageUnload,GetImageUnusedHeaderBytes}. - * Added patch to fix memory leak in wininet.HTTP_InsertCookies. - * Added patches for additional tests of wininet cookie/header/authentication - handling, in preparation of various cleanup patches. - * Added patch to add HTTP Host header in HttpSendRequest instead of - HttpOpenRequest. - * Added various additional fixes for wininet header handling. - * Added patch to free RPC parameters allocated by application before anything - else. - * Added patch with stub for kernel32.SetFileCompletionNotificationModes (for - Steam in Win7 mode). - * Added patch to skip unknown item when decoding a CMS certificate. - * Removed patch to use lockfree implementation for FD cache (accepted - upstream). - * Removed patch to properly handle closing sockets during a select call - (accepted upstream). - * Removed patches to fix behaviour of VirtualProtect / NtProtectVirtualMemory - (accepted upstream). - -- Sebastian Lackner Sat, 16 May 2015 22:57:29 +0200 - -wine-staging (1.7.42) unstable; urgency=low - * Added patch with stub for advapi32.ImpersonateAnonymousToken (fixes Wine - Staging Bug #254). - * Added patch to implement FileFsFullSizeInformation information class. - * Added patch to update timezone information in wine.inf. - * Added patch to fix check for texture levels in - wined3d_device_update_texture. - * Added patch to ignore garbage after decoding gif lines. - * Added patch to fix various issues related to advapi32.LookupAccountSidA. - * Added patch with stub for d3d11.D3D11CreateDeviceAndSwapChain. - * Added patch with stub for D3DXFrameFind. - * Added patch to return failure in NtProtectVirtualMemory when last argument - is omitted. - * Added patch to emulate \Device\Null using /dev/null. - * Added patch to make sure OpenClipboard with current owner doesn't fail. - * Added patch to create HKLM\Software\Microsoft\Cryptography\MachineGuid - registry key. - * Removed patch to avoid crash when trying to bind mshtml event scripts to - window (fixed upstream). - * Removed patch for stub of ntdll.WinSqmIsOptedIn (fixed upstream). - * Removed patch to fix issues with invalid console handles for new processes - (accepted upstream). - * Removed patches to fix timezone information (accepted upstream). - * Removed patch to recognize localhost as local machine in wbemprox (accepted - upstream). - * Partially removed patches to fix handling of opening read-only files for - FILE_DELETE_ON_CLOSE (accepted upstream). - -- Sebastian Lackner Sun, 03 May 2015 22:01:51 +0200 - -wine-staging (1.7.41) unstable; urgency=low - * Updated server-PeekMessage patchset to reset message filter in - accept_hardware_message call (fixes Wine Staging Bug #211). - * Updated ntdll-FileDispositionInformation patchset to block deleting mapped - files (by Qian Hong, fixes Wine Staging Bug #228). - * Various improvements to the ACL patchsets. - * Disable DXVA2 controls in winecfg when support is not compiled in. - * Added patch to enable/disable EAX support via winecfg. - * Added patch with stub for setupapi.SetupDiSetDeviceInstallParamsW. - * Added first part of patchset containing various improvements for - LsaLookupSids. - * Added patch to calculate msvcrt exponential math operations with higher - precision. - * Added patch to fix regression caused by blacklisting supported OpenGL - extensions. - * Added patch to reset device state in SysKeyboard*Impl_Acquire. - * Added patch to properly handle closing sockets during a select call. - * Added patch for support of process specific debug channels. - * Added patch to recognize localhost as local machine in wbemprox. - * Added patch to implement support for wbemprox Win32_SystemEnclosure table. - * Added patch to fix handling of opening read-only files for - FILE_DELETE_ON_CLOSE. - * Added patch for implementation of mfplat.MFTRegister. - * Added patch for stub of ntdll.WinSqmIsOptedIn. - * Added patch for ProfileList\ registry subkey. - * Added patch to avoid crash when trying to bind mshtml event scripts to - window. - * Added tests for RtlIpv6AddressToString and RtlIpv6AddressToStringEx. - * Removed patches to fix invalid memory access in get_registry_locale_info - (accepted upstream). - * Removed patches to avoid repeated FIXMEs in PsLookupProcessByProcessId stub - (accepted upstream). - * Removed patches to return more context attributes in - schan_InitializeSecurityContextW (accepted upstream). - * Removed patches to allow NULL pointer as keystate in ToUnicodeEx (accepted - upstream). - * Removed patches to avoid returning an error in WS_select when EINTR happens - during timeout (accepted upstream). - * Partially remove advapi32-Revert_DACL patches. - * Removed additional patches for job object support (accepted upstream). - * Removed patchset to invalidate the key state cache after calling LL hooks - (accepted upstream). - * Removed patches for PowerRequest stub functions (accepted upstream). - * Removed patch to fix compatibility with gnutls28 (accepted upstream). - * Removed patch to increase wineconsole commandline buffer size (fixed - upstream). - -- Sebastian Lackner Sun, 19 Apr 2015 01:16:43 +0200 - -wine-staging (1.7.40) unstable; urgency=low - * Update dsound fast mixer patchset to use integer math. - * Various improvements to Debian packaging files, pull request #310. - * Added patch with stubs for Power[Set|Clear]Request. - * Added patch to avoid spam of FIXME messages for PsLookupProcessByProcessId - stub. - * Added patch to implement empty enumerator for IWiaDevMgr::EnumDeviceInfo. - * Added patch to fix handling of ANSI NTLM credentials. - * Added patch to fix compatibility of Uplay with gnutls28. - * Added patches for Environmental Audio Extensions (EAX), pull request #311 - from Mark Harmstone. - * Added patch to fix return value of WS_select in case of EINTR during - timeout. - * Added patch to fix calculation of 3D sound source. - * Added patch for stub of fltmgr.sys (filter manager driver). - * Added patch to return correct device type for cd devices without medium. - * Added patch to fix device paths in HKLM\SYSTEM\MountedDevices. - * Added patch to show unmounted devices in winecfg and allow changing the unix - path. - * Added patch for support of 8bpp grayscale TIFF images with 8bpp alpha - channel (replaces previous stub). - * Added patch to implement support for linux priority levels (by Joakim - Hernberg, various modifications by Sebastian Lackner). - * Added patch to implement mscoree._CorValidateImage for mono runtime. - * Added patch to implement proper handling of CLI .NET images in Wine library - loader. - * Added patch to stub ntoskrnl.PsRemoveLoadImageNotifyRoutine - * Added patch to fix invalid memory access in get_registry_locale_info. - * Added patch to allow to open files/directories without any access rights in - order to query attributes. - * Added patch to implement DDENUMSURFACES_CANBECREATED in - IDirectDraw7::EnumSurfaces and fix some bugs. - * Added patch to ignore unsupported job object restrictions. - * Added patch to allow NULL pointer as keystate argument in ToUnicodeEx. - * Added patch with stub for setupapi.SetupDiSelectBestCompatDrv. - * Removed patch to fix regression causing black screen on startup (accepted - upstream). - * Removed patch to fix edge cases in TOOLTIPS_GetTipText (fixed upstream). - * Removed patch for IConnectionPoint/INetworkListManagerEvents stub interface - (accepted upstream). - * Removed patch to fix race-condition when closing browseui IProcessDialog - (accepted upstream). - * Removed patch with tests for GetFinalPathNameByHandleA/W (accepted - upstream). - * Removed patch to emulate 'mov Eb, Gb' instruction on x86 processor - architecture (accepted upstream). - * Removed patches for Setup*Log() functions (accepted upstream). - * Removed tests for job objects (accepted upstream). - * Removed patch to fix various bugs in RtlUnwindEx on x86_64 (accepted - upstream). - * Partially removed patches for job objects (accepted upstream). - -- Sebastian Lackner Sun, 05 Apr 2015 01:28:45 +0200 - -wine-staging (1.7.39) unstable; urgency=low - * Fix a build failure on MacOS caused by using of strndup in the server- - Inherited_ACLs patchset. - * Update patchset for ntdll-RtlUnwindEx to fix an issue with dwarf handling - (fixes Wine Staging Bug #170). - * Updated patchset for dinput-Events to be compatible with more games (fixes - Wine Staging Bug #149). - * Added patch for tests of RtlIpv6StringToAddress, - RtlIpv{4,6}StringToAddressEx (by Mark Jansen). - * Added patch to fix multithreading issues with fullscreen clipping. - * Added patch with tests for VerQueryValueA (by Mark Jansen). - * Added patch to implement proper locking of keystate and synchronization with - desktop thread. - * Added patch to implement better stub function for - NtQueryInformationJobObject. - * Added patch to avoid crash in d3d9 tests by skipping when texture/surface - creation fails. - * Added patch to fix wrong version of ID3DXEffect interface for d3dx9_24. - * Added patch to fix wrong version of ID3DXEffect interface for d3dx9_25. - * Added patch to allow to query for d3dx9_26 specific ID3DXEffect interface. - * Added patch to modify GetMessage to return already seen messages with higher - priority. - * Added patch to silence repeated 'Unhandled blend factor 0' FIXME messages. - * Added patch for stub of PowerCreateRequest. - * Added patch to invalidate key state cache globally after calling LL hooks. - * Added patch to fix Wine Staging Bug #162 - Caesar III demo installer - crashes. - * Added patch to fix wrong return values of - RtlFindActivationContextSectionString for NULL data (by Mark Jansen). - * Added patch to implement _ismbckata and _mbctohira, moreover fix wrong - return value of _ismbckata. - * Added patch to improve stub for ID3DXEffectImpl_CloneEffect. - * Added patch with additional tests for server-PeekMessage. - * Added patch to only zero the buffer up 32767 bytes in GetTempPathW. - * Added patches to implement shared memory wineserver communication for - various user32 functions. - * Added patch to implement combase.WindowsSubstring function. - * Added patch with stub for - wininet.ParseX509EncodedCertificateForListBoxEntry. - * Added patch to allow to edit winecfg library override by double clicking. - * Added patch to fix regression causing too dark/missing textures in several - games. - * Added patch to fix regression causing black screen on startup. - * Added patch to implement SetupLogError[A|W] and Setup[Open|Close]Log. - * Added patches to get rid of wineserver call for GetActiveWindow, GetFocus, - GetCapture. - * Removed patch to avoid hardcoded values for sizeof(GUID) (accepted - upstream). - * Removed patches for SLGetWindowsInformationDWORD (accepted upstream). - * Removed patches for _ismbckata and _mbctohira (fixed upstream). - * Removed patches to fix wrong return values of - RtlFindActivationContextSectionString for NULL data (accepted upstream). - * Removed patch for server-PeekMessage tests (accepted upstream). - * Removed patch to only zero the buffer up 32767 bytes in GetTempPathW - (accepted upstream). - * Removed first patch of series ws2_32_WriteWatches (accepted upstream). - -- Sebastian Lackner Sun, 22 Mar 2015 04:05:46 +0100 - -wine-staging (1.7.38) unstable; urgency=low - * Various improvements to patchupdate.py. - * Various improvements to dxva2 vaapi support. - * Long overdue update to the TransmitFile patches. - * Disabled patchset for reg.exe cleanup (partially accepted upstream). - * Added patch to report the correct refresh rates for some NVIDIA cards. - * Added patch to mark DllCanUnloadNow and DllGetClassObject as private (by - Amine Khaldi, wine-patched/pull/3). - * Added patch to skip Wine specific __wine_check_for_events calls in ReactOS - (by Amine Khaldi, wine-patched/pull/4). - * Added patch to declare pDirectInputCreateEx in a MSVC compatible way (by - Amine Khaldi, wine-patched/pull/5). - * Added patch to complete and properly pack DNS_HEADER structure (by Amine - Khaldi, wine-patched/pull/6). - * Added patch to fix race-condition when threads are killed during shutdown. - * Added patch to avoid deadlock by using _exit() in NtTerminateProcess. - * Added patch to fallback to global key state for threads without a queue. - * Added patch to implement SetFileInformationByHandle. - * Added patch for CopyFileEx progress callback and cancellation support. - * Added first set of patches for job objects (by Andrew Cook). - * Added patch for stub of gdiplus.GdipCreateEffect. - * Added patches for ntoskrnl.ProbeFor{Read,Write}. - * Added patch for support of shell32 file operation progress dialog. - * Added patch for basic implementation of job objects. - * Added patch to display animations for SHFileOperation progress dialog. - * Added patch to enforce that surfaces are flushed after ReleaseDC. - * Added patch to implement IProgressDialog::SetAnimation. - * Added patch in order to allow to override number of quality levels for - D3DMULTISAMPLE_NONMASKABLE. - * Added patch for job object completion support. - * Added patch to properly track handle count of wineserver objects. - * Added patch to implement JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE. - * Added patch to implement PROGDLG_AUTOTIME for IProgressDialog. - * Added patch to implement support for NULL job handles in IsProcessInJob. - * Added patch to implement support for waiting on job object. - * Added patch to fix crash in clip_cursor_notify caused by uninitialized TLS. - * Added patches to make various functions in d3d8 / ddraw hotpatchable - (required for fraps). - * Added patch to make GetLogicalProcessorInformationEx a stub which returns - TRUE. - * Added patches to fix race-condition when closing browseui IProcessDialog. - * Added patch to avoid unloading msctf library while textservices are - activated. - * Added patch to correct DDSCAPS2 and DDSURFACEDESC2 structure (by Amine - Khaldi, wine-patched/pull/7). - * Added patch to fix crash when trying to switch back to a 16-bit stack. - * Added patches to improve performance by reusing old async IO structure if - possible. - * Added patch to increase wineconsole commandline buffer size. - * Added patch to replace hardcoded values with sizeof(GUID) for d3dxof. - * Added patch to implement cuModuleLoad wrapper function. - * Added patch to process APC calls before starting process. - * Removed patch to properly call DriverUnload when unloading device drivers - (accepted upstream). - * Removed patch to allow Accept-Encoding for HTTP/1.0 in wininet (accepted - upstream). - * Removed patch to declare pDirectInputCreateEx in a MSVC compatible way - (accepted upstream). - * Removed patch to limit cross thread access to ImmSet* functions (accepted - upstream). - * Removed patch to fix arguments for OSMesaMakeCurrent when using 16 bit - formats (accepted upstream). - * Removed patch to fix memory leak in - ApplicationAssociationRegistration_QueryCurrentDefault (accepted upstream). - * Removed patch to complete and properly pack DNS_HEADER structure (accepted - upstream). - * Removed patch to avoid accessing stack below ESP when restoring thread - context (accepted upstream). - * Removed patch to fix mouse jittering in Planetside 2 (accepted upstream). - * Removed patch to handle write watches while we're on the signal stack - (accepted upstream). - * Removed patch with tests for NtQueryLicenseKey (accepted upstream). - * Removed patch to fix crash when trying to switch back to a 16-bit stack - (accepted upstream). - * Removed patch to fix definition of SECTION_BASIC_INFORMATION and - SECTION_IMAGE_INFORMATION (accepted upstream). - * Removed patch to add library override instead of closing winecfg when - pressing ENTER (accepted upstream). - * Removed patch to fix init of LONGLONG variable with a negative value in TGA - decoder (accepted upstream). - * Removed patch to fix parameters for ConvertToIndexedBlendedMesh stub - (accepted upstream). - -- Sebastian Lackner Sat, 07 Mar 2015 23:09:11 +0100 - -wine-staging (1.7.37) unstable; urgency=low - * Fix a TRACE line in the iphlpapi-TCP_Table patchset. - * Fix an issue in the d3dx9_36-GetShaderSemantics patchset. - * Update patchset for RtlUnwindEx on x86_64 and fix a second bug. - * Updated patch for DXTn support to avoid libtxc_dxtn as compile time - dependency. - * Added patch to avoid race-conditions in NtReadFile() operations with write - watches. - * Added patch to avoid race-conditions with write watches in WS2_async_accept. - * Added patch to implement D3DXGetShaderOutputSemantics. - * Added patch to implement basic handling of write watches while we're on the - signal stack. - * Added patch to add stub for ntoskrnl.ExAcquireResourceExclusiveLite. - * Added patch to add stub for ntoskrnl.ExReleaseResourceForThread. - * Added patch to add stub for ntoskrnl.ExDeleteResourceLite. - * Added patch to avoid accessing stack below ESP when restoring thread - context. - * Added patch to implement - IApplicationAssociationRegistration::QueryCurrentDefault. - * Added patch to improve stubs for AEV_{Get,Set}MasterVolumeLevel. - * Added patch to improve stubs for AEV_{Get,Set}Mute. - * Added patch to implement semi-stub for GetFileVersionInfoSizeExA/W. - * Added patch to implement semi-stub for GetFileVersionInfoExA/W. - * Added patch to ignore unsupported alpha channels in TIFF decoder. - * Added patch to add stub for ntoskrnl.Mm{Map,Unmap}LockedPages. - * Added patch to implement ntoskrnl.KeInitializeMutex. - * Added patch for support of non-blocking SIO_ADDRESS_LIST_CHANGE requests. - * Added patch for MPEG2/H264 DXVA2 video decoding through vaapi. - * Removed patches for UTF7 support (accepted upstream). - * Removed patches for SIO_ADDRESS_LIST_CHANGE ioctl (accepted upstream). - * Removed patch for IApplicationAssociationRegistration::QueryCurrentDefault - (accepted upstream). - * Removed patch for IDirectPlayVoiceClient::GetCompressionTypes (accepted - upstream). - -- Sebastian Lackner Sun, 22 Feb 2015 06:58:09 +0100 - -wine-staging (1.7.36) unstable; urgency=low - * Fix an incompatibility of patchinstall.sh with non-bash shells under - specific situations. - * Improve dinput-Events patch to be compatible with applications which do not - explicitly poll for input. - * Added patch to properly call DriverUnload when unloading device drivers. - * Added patch to fix check for end_frame in RtlUnwindEx on x86_64. - * Added patch to fix mouse jittering in Planetside 2. - * Added patch to implement additional stubs for vcomp dlls. - * Added patchset to implement Vista+ threadpool functions for work / timers. - * Added patchset for Vista+ threadpool wait objects. - * Added patch to fix crash in Jedi Knight: Dark Forces II when winmm is set to - native. - * Added patch to fix arguments for OSMesaMakeCurrent when using 16 bit - formats. - * Added patch to add library override instead of closing winecfg when pressing - ENTER over the combobox. - * Added patchset for various improvements and cleanup of reg.exe. - * Added patch to add performance library registry keys needed by MS SQL Server - Management Studio Express 2008 R2. - * Added patch to implement NVIDIA video encoder library (nvencodeapi). - * Added patch to make nvcuda.dll compatible with CUDA 7.0. - * Added patch to implement stub for ntoskrnl.IoGetAttachedDeviceReference. - * Added patch to implement stubs for - ntoskrnl.Ex{Acquire,Release}FastMutexUnsafe. - * Added patch to implement stubs for ntoskrnl.ObReferenceObjectByPointer and - ntoskrnl.ObDereferenceObject. - * Added patch to implement stub for ntoskrnl.KeDelayExecutionThread. - * Added patch to improve various ntoskrnl stub functions. - * Added patch to fix wrong defition of ntoskrnl.IoReleaseCancelSpinLock - function. - * Added patch to improve stub for AEV_GetVolumeRange. - * Removed patch to add additional tests for SLGetWindowsInformationDWORD - (accepted upstream). - * Removed patch to avoid filling KdHelp structure for usermode applications - (accepted upstream). - -- Sebastian Lackner Sun, 08 Feb 2015 19:14:24 +0100 - -wine-staging (1.7.35) unstable; urgency=low - * Add stub for KeWaitForMultipleObjects. - * Add support for patchinstall.sh parameters '--no-patchlist' and '--no- - autoconf'. - * Add support for Gentoo epatch backend to patchinstall.sh. - * Fix compile warnings on x86_64 in several patchsets. - * Automatically enable fallback method to apply patches when running from - inside of a git subdirectory. - * Synchronize CSMT patchset with https://github.com/stefand/wine. - * Several improvements to make nvcuvid (CUDA video decoding) better compatible - with x86_64. - * Properly wrap CUDA stream callbacks by forwarding them to a separate worker - thread. - * Added patch to quote program name in ShellExecute[Ex] when it contains - spaces. - * Added patch to implement support for DDS file format in - D3DXSaveTextureToFileInMemory. - * Added patch to avoid appending duplicate NULL character when importing keys - with regedit. - * Added patch for IConnectionPoint/INetworkListManagerEvents stub interface. - * Added patch to fix init of LONGLONG variable with a negative value in TGA - decoder. - * Added patch to implement stubs for D3DXCreateAnimationController interface. - * Added patch to implement semi-stub for - IDirectPlayVoiceClient::GetCompressionTypes. - * Added patch to fix cursor clip regression / broken raw input in multiple - games. - * Added patches to implement ntoskrnl driver testing framework. - * Added patch to fix handling of window attributes for WS_EX_LAYERED | - WS_EX_COMPOSITED. - * Removed patch to fix RandR on some broken nVidia systems (accepted - upstream). - * Removed patch to set last error on success in WSARecv (accepted upstream). - * Removed patch to fix handling of subdirectory in FtpFindFirstFile (accepted - upstream). - * Removed patch to initialize irp.Tail.Overlay.OriginalFileObject with stub - file object (accepted upstream). - * Removed patch to fix incorrect behaviour of PathIsDirectoryEmptyW (accepted - upstream). - * Removed patch to store IOCS data in a property instead of GWLP_USERDATA - (accepted upstream). - * Removed patch to fix color key regression (fixed upstream). - -- Sebastian Lackner Sat, 24 Jan 2015 16:03:35 +0100 - -wine-staging (1.7.34-1) unstable; urgency=low - * Debian/Ubuntu specific package dependency fix (no changes for other - distros). - -- Sebastian Lackner Sun, 11 Jan 2015 19:14:09 +0100 - -wine-staging (1.7.34) unstable; urgency=low - * Huge rewrite of patchupdate.py, deprecation of Makefile based way to apply - patches. - * Rename debian package from 'wine-compholio' to 'wine-staging' and provide - compatibility package. - * Avoid duplicate wined3d specfile by adding PARENTSPEC Makefile argument. - * Fix issue in DOS Attributes patch which broke ./configure on systems with - alternative shells. - * Fix issue in user32-WndProc patch which caused crashes for some 16-bit apps. - * Fix issue in ws2_32-WriteWatches patch which can cause exceptions on the - signal stack. - * Fix issue with invalid handles being incorrect when a new process is - created. - * Update DXTn patches to better handle when libtxc_dxtn is missing or support - is not compiled in. - * Added patch for WSARecv to call SetLastError on success. - * Added patch for CreateProcess to prioritize the working directory over the - system search path. - * Added patch with stubs for WinSqm[Start|End]Session. - * Added patch to fix handling of subdirectory in FtpFindFirstFile. - * Added patch to return proper charcount for GetLocaleInfo with - LOCALE_IFIRSTDAYOFWEEK. - * Added patch to ensure X11 input events are handled even without explicit - message loop. - * Added test for server-Unexpected_Wakeup patch. - * Added patch for stub of ntdll.RtlSetHeapInformation. - * Added patch for IDXGIOutput::GetDesc. - * Added patch for ID3DXEffect::FindNextValidTechnique. - * Added patch with stub for D3DXComputeTangentFrameEx. - * Added patch with stub for D3DXIntersect. - * Added test for RtlIpv4StringToAddressExA. - * Added patch for support of SLGetWindowsInformationDWORD. - * Added patch to expect the correct buffer size for different - IOCTL_DVD_READ_STRUCTURE requests. - * Added patch to use actual program name if available to describe PulseAudio - streams. - * Added patch to try harder to get the host name address in getaddrinfo(). - * Added patch to fix invalid usage of RegOpenKeyExW in msdmo. - * Added patch to add support for named pipe message mode. - * Added patch to avoid calling IDirect3DDevice7_DrawIndexedPrimitive if there - is no primitive. - * Added patch to fix access violation when calling GetStringTypeW with NULL - src. - * Added patch for ID3DXFont::DrawTextA/W support. - * Added patch to fix parameters for ConvertToIndexedBlendedMesh stub. - * Added patch for basic CUDA support. - * Added patches for D3DXComputeNormals and D3DXComputeNormalMap. - * Added patch for nvapi stubs (required for GPU PhysX support). - * Added patch to fix NULL dereference in ICSeqCompressFrameStart. - * Added patch to implement support for CUDA GPU video decoding. - * Added patch to fix color key regression causing pink rectangles around text. - * Rebased winepulse-Pulseaudio_Support patches to latest version from - http://repo.or.cz/w/wine/multimedia.git. - * Removed patch to emulate write to CR4 register (accepted upstream). - * Removed patch with stub for KeSetSystemAffinityThread (accepted upstream). - * Removed patch to implement combase HSTRING objects (accepted upstream). - * Removed patch to add fake ProductId to registry (accepted upstream). - * Removed patch to implement stubs for MFStartup and MFShutdown (accepted - upstream). - * Removed patch to implement shlwapi.StrCatChainW (accepted upstream). - * Removed patch to implement semi-stub for psapi/kernel32 - K32EnumProcessModulesEx (accepted upstream). - * Removed patch to return proper charcount for GetLocaleInfo with - LOCALE_IFIRSTDAYOFWEEK (accepted upstream). - * Removed patch to export SHILCreateFromPath by name (accepted upstream). - * Removed patch for stub of ntdll.RtlSetHeapInformation (accepted upstream). - * Removed patch for wine64 support on FreeBSD (accepted upstream). - * Removed patch for IoCsqInitialize (accepted upstream). - * Removed patch to fix invalid usage of RegOpenKeyExW in msdmo (fixed - upstream). - * Removed patch to reallocate buffer when adding records to AVI files (fixed - upstream). - * Partially removed patches for ntdll DOS attributes (accepted upstream). - * Partially removed patches for UTF7 support (accepted upstream). - -- Sebastian Lackner Sat, 10 Jan 2015 22:22:01 +0100 - -wine-compholio (1.7.33) unstable; urgency=low - * Various improvements of patchupdate.py. - * Added patches for wined3d CSMT (command stream) support. - * Added additional tests for VerifyVersionInfoA. - * Added patch to fix condition handling in RtlVerifyVersionInfo. - * Added patch to set last error when GetRawInputDeviceList fails. - * Added patch to fix possible segfault in pulse_rd_loop of PulseAudio backend. - * Added patch to implement support for GetPropValue to PulseAudio backend. - * Added patch to implement shlwapi.StrCatChainW. - * Added patch to allow Accept-Encoding for HTTP/1.0 in wininet. - * Added patch for combase HSTRING objects. - * Added patch to implement stubs for MFStartup and MFShutdown. - * Added patch for additional tests of CoWaitForMultipleHandles with WM_QUIT. - * Added patch to fix return value of ScrollWindowEx for invisible windows. - * Added patch to ignore unsupported flags for CoInternetSetFeatureEnabled. - * Added patch to provide named entry point shell32.SHILCreateFromPath for - vista apps. - * Added patch to reallocate buffer when adding records to AVI files. - * Added patch to implement support for loader dll redirections. - * Added patch to add winecfg Staging tab. - * Removed patch to fix copy and paste errors in ws2_32 tests (accepted - upstream). - * Removed patch to fix ordering of IP addresses by metric if two addresses - have the same metric (accepted upstream). - * Removed patch to reset data->pWintrustData->u.pFile->hFile after closing - handle (accepted upstream). - * Removed patch to simplify implementation of ws32 get_poll_results (accepted - upstream). - * Removed patch to fix passing of unicode environment from msvcrt to - CreateProcessW (accepted upstream). - * Removed patches for api-ms-win-core-* stub dlls (accepted upstream). - -- Sebastian Lackner Mon, 15 Dec 2014 00:53:01 +0100 - -wine-compholio (1.7.32) unstable; urgency=low - * Various optimizations of patchupdate.py. - * Update patch for SO_CONNECT_TIME and adding better tests. - * Update patch for FD Cache and use faster method on x86_64. - * Added patch to ensure dbghelp always checks for debug symbols in BINDIR. - * Added patch for pulseaudio exclusive mode support. - * Added patch to take abs() of vertex z coordinate as FFP fog coordinate. - * Added patch to ensure ShowWindow avoids interthread no-op messages. - * Added patch to avoid race-conditions of async WSARecv() operations with - write watches. - * Added patch to fix issues with write watches when using Exagear. - * Added patch to avoid failure because of missing ptrace support for Exagear. - * Added patch to automatically detect if tests are running under Wine. - * Added patch to avoid sending unexpected wakeup with uninitialized cookie - value. - * Added patch to fix issues with dragging layers between images in Adobe - Photoshop 7.0. - * Added patch to ensure wintrust resets data->pWintrustData->u.pFile->hFile - after closing handle. - * Added patch to add additional format conversions for DXT1 and DXT3. - * Added patch to implement stubs for additional api-ms-win-core-* dlls. - * Added patch to fix copy and paste error recently introduced in ws2_32 tests. - * Added patch to change bug reporting URL in winedbg. - * Added patch to implement semi-stub for psapi/kernel32 - K32EnumProcessModulesEx. - * Added patch to fix ordering of IP addresses by metric if two addresses have - the same metric. - * Added patch to fix handling of empty section and key name for profile files. - * Added patch to fix passing of unicode environment from msvcrt to - CreateProcessW. - * Removed patch to close server fd is there is no space in thread inflight fd - list (accepted upstream). - * Removed patch to fix bugs in StrStr functions (accepted upstream). - * Removed patches to avoid sending messages in FindWindowExW (accepted - upstream). - * Removed patch to fix implementation ofCoWaitForMultipleHandles (accepted - upstream). - * Removed patch to avoid interthread no-op messages in ShowWindow (accepted - upstream). - * Removed patches to take abs() of vertex z coordinate as FFP fog coordinate - (fixed upstream). - * Removed patch to fix detection of gnutls on Ubuntu 14.10 (accepted - upstream). - -- Sebastian Lackner Sun, 30 Nov 2014 15:22:49 +0100 - -wine-compholio (1.7.31) unstable; urgency=low - * Improve output of 'wine --patches' and simplify syntax of definition files. - * Update kernel32-GetSystemTimes patches. - * Improve style for ntdll-Fix_Alignment patches. - * Added possibility to temporarily disable patches to patch system. - * Added patch to allow selecting specific audio device for PulseAudio backend. - * Added patch with stub for NtSetLdtEntries/ZwSetLdtEntries. - * Added patch to prevent processing message events for - CoWaitForMultipleHandles when APC calls are queued. - * Added patch with stub for KeSetSystemAffinityThread. - * Added patch to implement DXTn support for d3dx9_36. - * Added patch to return correct values for GetThreadTimes. - * Added patch to align texture dimensions to block size for compressed - textures. - * Added patch with stub for IoCsqInitialize. - * Added patch with stubs for vectored continue handler functions. - * Added patch to fix wglDescribePixelFormat when NULL is passed as pixel - format descriptor. - * Added patch to allow NULL pointer for optional arguments of - D3DXIntersectTri. - * Added patch to fix crash of winedevice when relocation entry crosses page - boundary. - * Added patch to emulate 'mov Eb, Gb' instruction on x86 processor - architecture. - * Added patch to emulate access to KI_USER_SHARED_DATA kernel page on x86_64. - * Added patch to initialize irp.Tail.Overlay.OriginalFileObject with stub file - object. - * Added patch to implement emulation of SIDT instruction when using Exagear. - * Added patch to return more context attributes in - schan_InitializeSecurityContextW. - * Added patch to avoid crashing when broken app tries to release surface - although refcount is zero. - * Added patch to avoid sending window messages in FindWindowExW. - * Added patch to fix handling of invert_y in DrawTextExW. - * Added patch to fix implementation of K32GetPerformanceInfo. - * Added patch to close server fd if there is no space in thread inflight fd - list. - * Added patch to avoid failing in d3dx9_mesh_OptimizeInplace because of - unimplemented vertex reordering. - * Added patch to workaround bugs in CompareStringW (triggered by Adobe Flash). - * Removed patch for iphlpapi stub functions (accepted upstream). - * Removed patches for FindFirstFileExW (accepted upstream). - * Removed patches for TLB dependencies lookup in resources (accepted - upstream). - * Removed patches for ws2_32.inet_pton implementation (fixed upstream). - * Removed patch to update properties when applying MSI transforms (fixed - upstream). - * Removed patch to silence repeated GSUB_apply_ChainContext[Subst|Pos] FIXMEs - (accepted upstream). - * Removed patch with additional tests for MsgWaitForMultipleObjectsEx - (accepted upstream). - * Removed patches for D3DXCreatePolygon (accepted upstream). - * Removed patches vor vectored continue handler stubs (accepted upstream). - * Removed patches for K32GetPerformanceInfo (accepted upstream). - * Removed patch for D3DXIntersectTri (accepted upstream). - * Partially removed patches for UTF-7 tests (accepted upstream). - * Partially removed patches for WS_SO_CONNECT_TIME (accepted upstream). - -- Sebastian Lackner Sat, 15 Nov 2014 15:36:38 +0100 - -wine-compholio (1.7.30) unstable; urgency=low - * Fix wrong escaping of quote/slash characters in patchupdater script. - * Added additional conversion functions to DXTn patch. - * Added patch to filter specific warning messages for D3DCompileShader. - * Added patch to implement iphlpapi stub functions. - * Added patch to implement support for pasting HTML from native Unix - applications. - * Added patch to implement RtlDecompressBuffer. - * Added patch to emulate write to CR4 register. - * Added patch for implementation of GdipCreateRegionRgnData. - * Added patch for implementation of D3DXCreatePolygon. - * Added patch for TLB dependencies lookup in resources. - * Added patch to update ProductVersion when applying MSI transforms. - * Added patch for ITextSelection_fnGetDuplicate implementation. - * Removed patch to avoid Clang compiler warning because of unused Vtable - (accepted upstream). - * Removed patch for additional ATL thunks (accepted upstream). - * Removed patch to ímplement IRichEditOle and ITextDocument support for - ITextServices (accepted upstream). - * Removed patch to fix compile errors on Archlinux (fixed upstream). - -- Sebastian Lackner Sun, 02 Nov 2014 00:45:28 +0100 - -wine-compholio (1.7.29) unstable; urgency=low - * Updated DOS Attributes patch to better detect XATTR functions. - * Updated patch for shell32 default folder ACLs. - * Updated NtQuerySection patch. - * Updated patch for WRITECOPY memory protection. - * Added patch to support IDF_CHECKFIRST in SetupPromptForDisk. - * Added patch to fix issues when executing pages with guard page / write watch - permissions. - * Added patch to set return value of basic_string_wchar_dtor to return NULL. - * Added patch for UTF7 encoding/decoding support. - * Added patch to implement ID3DXSkinInfoImpl_UpdateSkinnedMesh. - * Added patch for implementation of D3DXGetShaderInputSemantics. - * Added patch to ensure tests check exact return value of - ParseURLFromOutsideSourceX. - * Added patch for additional ATL thunks. - * Added patch to add partially support for sessionStorage. - * Added patch for implementation of GetNumaProcessorNode. - * Added patch for wine64 support on FreeBSD/PC-BSD. - * Added patch for improved multi monitor support. - * Added patch for implementation of BindImageEx. - * Removed patch to fix issues with drag image in ImageLists (accepted - upstream). - * Removed patch to set ldr.EntryPoint for main executable (accepted upstream). - * Removed patch to implement stubs for [Get|Set]SystemFileCacheSize (accepted - upstream). - * Removed patches for ATL thunk implementation (accepted upstream). - * Partially removed patches for WRITECOPY memory protection (accepted - upstream). - -- Sebastian Lackner Sun, 19 Oct 2014 19:37:21 +0200 - -wine-compholio (1.7.28) unstable; urgency=low - * Added missing recommendation for libtxc-dxtn-s2tc0 on Ubuntu. - * Added patch to fix issues with over-the-spot input method. - * Added patch to fix winemenubuilder desktop icon wine path (when using - multiple wine versions). - * Added patch to support FIND_FIRST_EX_CASE_SENSITIVE flag in - FindFirstFileExW. - * Added patch to send WM_PAINT event during dialog creation. - * Added patch to fix issues when driver dispatch routine returns different - status codes. - * Added several patches for Unity3D Editor. - * Added patch to fix differences between exception handling behaviour in Wine - and Windows. - * Added patch to export ?_BADOFF@std@@3_JB on both i386 and win64. - * Added patch to limit cross thread access to ImmSet* functions. - * Added patch for IRichEditOle and ITextDocument support for ITextServices. - * Added patch to fix implementation of SH*Shared commands. - * Added patch to handle WRITECOPY memory protection properly on i386 (disabled - by default). - * Added patch to fix some issues with write watches / guard page access. - * Added patch to implement NtQuerySection. - * Added patches to make clearly visible, that this is a patched wine version. - * Added patch for FindFirstFileExW level FindExInfoBasic. - * Removed patch to support FIND_FIRST_EX_CASE_SENSITIVE flag in - FindFirstFileExW (accepted upstream). - * Removed patch to fix implementation of SH*Shared commands (accepted - upstream). - * Removed patch to export ?_BADOFF@std@@3_JB on both i386 and win64 (accepted - upstream). - * Partially removed patches for CreateProcess ACLs (accepted upstream). - -- Sebastian Lackner Sat, 04 Oct 2014 04:36:22 +0200 - -wine-compholio (1.7.27) unstable; urgency=low - * Fixed some issues in the patches for GetSystemTimes. - * Added patch to support FIND_FIRST_EX_LARGE_FETCH flag in FindFirstFileExW. - * Added patch to fix deadlock caused by incorrect wrapper of glu - polygon/contour function. - * Added patch to avoid filling out KdHelp for usermode applications. - * Added patch to silence repeated GSUB_apply_ChainContext[Subst|Pos] FIXMEs. - * Added patch to revert wined3d pixelformat changes (causes regression in many - games). - * Added patch to implement software decoding/encoding of DXT1 textures. - * Removed patch to use assembly wrapper for TLS callbacks (accepted upstream). - * Removed patch to fix uninitialized cch struct member in GetMenuItemInfo - (accepted upstream). - * Removed some patches for riched20/IText*-interface (accepted upstream). - * Removed patch to fix deadlock caused by incorrect wrapper of glu functions - (accepted upstream). - * Removed patch for stub of BCryptGetFipsAlgorithmMode (accepted upstream). - -- Sebastian Lackner Sat, 20 Sep 2014 05:52:23 +0200 - -wine-compholio (1.7.26) unstable; urgency=low - * Added new make targets 'series' and 'install-git'. - * Some improvements in the patch system scripts. - * Fixed issues in the winepulse configure script. - * Fixed some issues in patches for Inherited ACLs. - * Fixed some issues in patches for backwards compatibility with old ACL - format. - * Added patch to fix unintentional leaks with ntdll internals. - * Added patch to add support for DOS hidden/system file attributes. - * Added patch to use dynamic linking for libpcap. - * Added patch to fix issues when using setcap on wine executable. - * Added patch to improve heap allocation performance by using more freelists. - * Added patch to fix detection of ncurses on Archlinux (avoids ugly - workarounds at build time). - * Added patch to fix detection of gnutls on Ubuntu 14.10. - * Added patch to use assembly wrapper for TLS callbacks. - * Added patch to fix uninitialized cch struct member in GetMenuItemInfo. - * Removed patch to fix issue with msi/ITERATE_MoveFiles (accepted upstream). - * Removed patch to fix detection of ncurses on Archlinux (accepted upstream). - -- Sebastian Lackner Sun, 07 Sep 2014 23:50:25 +0200 - -wine-compholio (1.7.25) unstable; urgency=low - * Improve generation of README.md on patch update. - * Updated patches for riched20 IText* Interface. - * Fixed some issues in the patches for TransmitFile. - * Fixed some issues in the patches for CreateProcess ACLs. - * Fixed issue with gitapply.sh script on Gentoo systems. - * Added patch with stub for DwmInvalidateIconicBitmaps. - * Added Courier Prime (OFLv1.1) as a Courier New replacement. - * Added patch to implement DOS hidden/system file attributes. - * Added patch to better detect broken nVidia RandR 1.2 support. - * Added patch to set linker version in PE header. - * Added patch to move NtProtectVirtualMemory and NtCreateSection to separate - pages. - * Added patch to fix issues with drag image in ImageLists. - * Added patch with stub for BCryptGetFipsAlgorithmMode. - * Added patch to fix issues with OpenProcess on terminated processes. - * Added patch to fix issues with msi/ITERATE_MoveFiles. - * Added patch to avoid grouping all Wine windows together. - * Added patch to implement KF_FLAG_DEFAULT_PATH for SHGetKnownFolderPath. - * Added patch to implement GetFinalPathNameByHandle. - * Removed patch to update gl_drawable for embedded windows (deprecated). - * Removed patch to return empty D3D hardware flags for RGB device enumeration - (accepted upstream). - * Removed patch with stub for DwmInvalidateIconicBitmaps (accepted upstream). - * Removed patch for SetNamedPipeHandleState implementation (accepted - upstream). - -- Erich E. Hoover Sun, 24 Aug 2014 11:09:58 -0600 - -wine-compholio (1.7.24) unstable; urgency=low - * Various further improvements to the patch system. - * Added patch to implement inet_pton. - * Added patch to implement GetSystemTimes. - * Added patch to implement SHCreateSessionKey. - * Added patch to create directory available on Vista and later. - * Added patch to fix edge cases in TOOLTIPS_GetTipText. - * Added patch to allow special characters in pipe names. - * Added patch with stubs for [Get|Set]SystemFileCacheSize. - * Added patch to implement AllocateAndGetTcpExTableFromStack. - * Added patch to support setting file disposition information. - * Added patch to fix ConnectNamedPort return value in overlapped mode. - * Added patch to store IOCS data in a property instead of GWLP_USERDATA. - * Added patch to return empty D3D hardware flags for HEL device enumeration. - * Added patch to return the appropriate connection time with SO_CONNECT_TIME. - * Added patch to support extra large and jumbo icons. - * Added patch to allow setting tablet / media center status via registry. - * Added patch to use manual redirection for RunDLL_CallEntry16. - * Added patch to set ldr.EntryPoint for main executable. - * Added patch to fix invalid memory access in windowscodecs/PropertyBag. - * Added patch to use a linear resampler when there a large number of dsound - mixing buffers. - * Added patch to fix comparison of punctuation characters in lstrcmp. - * Added patch to workaround programs leaking wndproc splots. - * Added patch to implement ITextRange, ITextFont and ITextPara. - * Removed patch to create Vista directories (accepted upstream). - * Removed strmbase/quartz locking fix patches (accepted upstream). - * Removed windowscodecs/PropertyBag patch (accepted upstream). - -- Erich E. Hoover Fri, 08 Aug 2014 22:06:07 -0600 - -wine-compholio (1.7.23) unstable; urgency=low - * Rewrite of patch system to simplify maintaining large patchsets. - * Fix failing Junction Point test. - * Fix possible race conditions in strmbase/quartz. - * Fix race condition between EndOfStream and Pause. - * Fix issues with Israel Standard Time timezone. - * Add support for Dynamic DST (daylight saving time) information. - * Add some generic hardware in HKEY_DYN_DATA\Config Manager\Enum. - * Return correct IMediaSeeking stream positions in quartz. - * Make sure LICENSE files are included in the Debian packages. - * Downgraded Arial replacement font to Liberation Sans v1.07.3. - * Remove relative Junction Point linking for now (breaks tests). - * Added WenQuanYi Micro Hei (GPLv3) as a Microsoft Yahei replacement. - -- Erich E. Hoover Fri, 25 Jul 2014 21:12:42 -0600 - -wine-compholio (1.7.22) unstable; urgency=low - * Implement passing ACLs to CreateProcess. - * Removed several patches (accepted upstream). - * Added NT4 support to the process ACL tests. - * Implement RegSetKeySecurity on top of NtSetSecurityObject. - * Updated RegSetKeySecurity patch to work with special root keys. - * Add patch for wtsapi32.WTSEnumerateProcessesW function. - * Fix incorrect scaling for DECIMAL values in VarDecAdd. - * Updated main extended attributes patch to include BSD support. - * Return NULL-terminated list of arguments in CommandLineToArgvW. - * Updated main extended attributes patch to include additional data checks. - -- Erich E. Hoover Fri, 11 Jul 2014 13:00:03 -0600 - -wine-compholio (1.7.21) unstable; urgency=low - * Remove several patches (accepted upstream). - -- Sebastian Lackner Fri, 27 Jun 2014 23:08:48 -0600 - -wine-compholio (1.7.20) unstable; urgency=low - * Remove several patches (accepted upstream). - * Fix recommendation for odbc and add libgsm1. - * Disabled gstreamer (broken with glib >= 2.32.0). - * Updated scripts to be compatible with BSD systems. - * Update winepulse patches to latest revision (extracted from 1.7.19). - * Force autoreconf even when timestamp seems to indicate that it is not - necessary. - * Added patches for default security descriptor ownership and DACLs for - processes. - * Added a patch to avoid a race-condition when unloading modules while a hook - is active. - * Add patch to fix issues with Obsidium copy protection. - -- Erich E. Hoover Sat, 14 Jun 2014 18:15:12 +0200 - -wine-compholio (1.7.19-1) unstable; urgency=low - * Added a patch to fix return value for FSCTL_PIPE_WAIT (required for - Unity3D). - * Added a patch to stub TokenAppContainerSid in NtQueryInformationToken - (required for Unity3D). - * Added a patch to optimize the file descriptor cache by using lockfree - algorithms. - * Add additional checks in XATTR patch to ensure wineserver doesn't crash if - data is corrupted. - * Add support for extended attributes on FreeBSD systems. - * Added a patch to fix ntdll/exception test failures on x86_64. - * Allow to change 'strict draw ordering' at runtime. - * Add ability to test if all dynamic libraries are installed with "wine - --check-libs". - * Added a patch to query if direct rendering is enabled via GLX extension. - -- Sebastian Lackner Mon, 02 Jun 2014 23:50:23 +0200 - -wine-compholio (1.7.19) unstable; urgency=low - * Updated SIO_ADDRESS_LIST_CHANGE patches. - -- Erich E. Hoover Tue, 06 May 2014 15:42:32 -0600 - -wine-compholio (1.7.18-1) unstable; urgency=low - * Fix some issues on BSD systems. - * Add additional patches to silence a few FIXMEs. - * Rebase 02-ACL_Extended_Attributes patches. - -- Sebastian Lackner Tue, 13 May 2014 20:47:23 +0200 - -wine-compholio (1.7.18) unstable; urgency=low - * Updated SetTimer patch (10 ms accepted upstream). - -- Erich E. Hoover Fri, 02 May 2014 13:05:13 -0600 - -wine-compholio (1.7.17) unstable; urgency=low - * Split Arial replacement into two patches. - * Removed dynamic unwind patches (accepted upstream). - * Removed linguistic casing patches (accepted upstream). - * ACL data is now stored in binary instead of converting it to ASCII. - -- Erich E. Hoover Fri, 18 Apr 2014 16:03:57 -0600 - -wine-compholio (1.7.16-1) unstable; urgency=low - * Fix build failure caused by dynamic unwind functions. - * Dropped liblcms2-dev dependency for old Ubuntu versions. - -- Sebastian Lackner Sat, 05 Apr 2014 03:48:25 +0200 - -wine-compholio (1.7.16) unstable; urgency=low - * Add stub for RtlInstallFunctionTableCallback. - * Further split out the SIO_ADDRESS_LIST_CHANGE patches. - * Add proper implementation for dynamic unwind functions, removed stub - implementation. - * Fix lcms dependency (Wine requires lcms2 instead of lcms1), add build - dependency to libsane-dev. - -- Erich E. Hoover Fri, 04 Apr 2014 17:27:52 -0600 - -wine-compholio (1.7.15-1) unstable; urgency=low - * Build 64 bit version of Wine. - * First SIO_ADDRESS_LIST_CHANGE patch accepted upstream. - * Added stub dll for DirectX Video Acceleration (dxva2.dll). - * Update DXVA2 patches (additional implementation details, parts accepted - upstream). - -- Erich E. Hoover Tue, 25 Mar 2014 06:08:01 +0100 - -wine-compholio (1.7.15) unstable; urgency=low - * Fixed build dependencies for Debian Sid. - * Fixed free() of a const variable (Bug #1). - * Removed get_dir_unix_fd (no longer used, fixes compiling with "-Werror"). - * Removed 'register user administrative tools shell folder' patch (accepted - upstream). - -- Erich E. Hoover Sun, 23 Mar 2014 12:53:32 +0100 - -wine-compholio (1.7.14) unstable; urgency=low - * Minor updates to the ACL patches. - * Added Liberation Sans (SIL Open Font License) as an Arial replacement. - -- Erich E. Hoover Fri, 07 Mar 2014 13:59:11 -0700 - -wine-compholio (1.7.13-1) unstable; urgency=low - * Fixed a typo in the configure check for extended attributes. - -- Erich E. Hoover Fri, 21 Feb 2014 09:00:00 -0700 - -wine-compholio (1.7.13) unstable; urgency=low - * Added support for inherited file ACLs. - * Further separated the file ACL patches. - * Updated linguistic casing patches to include tests. - * Updated the patch list template to be compatible with 'git am'. - * Moved the patching code out of the debian rules into a Makefile. - * Removed the named pipe security access patch (accepted upstream). - * Explicitly run configure with '--with-xattr' when building debian packages. - * Will now fail on configure when '--with-xattr' is passed and xattr.h cannot - be found. - -- Erich E. Hoover Thu, 20 Feb 2014 18:48:03 -0700 - -wine-compholio (1.7.12-1) unstable; urgency=low - * Fixed PulseAudio patches to apply with 'git am'. - * Fixed PulseAudio driver configure file for upstream Wine 1.7.12. - * Fixed PulseAudio driver pthread dependency for upstream Wine 1.7.12. - -- Erich E. Hoover Fri, 07 Feb 2014 17:52:32 -0700 - -wine-compholio (1.7.12) unstable; urgency=low - * Added new patches to support GetVolumePathName. - -- Erich E. Hoover Fri, 07 Feb 2014 14:57:33 -0700 - -wine-compholio (1.7.11) unstable; urgency=low - * Added SRWLock patch. - * Added new patches to support TransmitFile. - * Added new patches to support Junction Points. - * Moved pipelight-specific patches to a separate folder. - * Removed SRWLock patch included in upstream Wine 1.7.11. - * Reduced SetTimer minimum limitation from 15 ms to 5 ms. - * Added support for security access parameters for named pipes. - * Added WINE_STRICT_DRAW_ORDERING command line environment variable. - * Fixed a path length bug in the ACL inheritance patch (assumed DOS - limitation). - * Added some workarounds for shlwapi url functions not handling relative paths - well. - -- Erich E. Hoover Fri, 17 Jan 2014 12:27:32 -0700 - -wine-compholio (1.7.10) unstable; urgency=low - * Removed monitor enumeration patch included in upstream Wine 1.7.10. - * Updated SIO_ADDRESS_LIST_CHANGE patch with latest proposed version. - * Added new patch to support linux windowlessmode (required for Qt5 browsers). - -- Erich E. Hoover Fri, 03 Jan 2014 12:19:14 -0700 - -wine-compholio (1.7.9) unstable; urgency=low - * Added a new patch for windowless mode for Qt5 browsers. - -- Erich E. Hoover Fri, 27 Dec 2013 12:03:22 -0700 - -wine-compholio (1.7.8-1) unstable; urgency=low - * Fixed several build problems. - -- Erich E. Hoover Sat, 07 Dec 2013 10:49:03 -0700 - -wine-compholio (1.7.8) unstable; urgency=low - * Added PulseAudio support patches. - * Updated SIO_ADDRESS_LIST_CHANGE patches. - * Separated out patches into logical subfolders. - * Updated XEMBED patch to work with latest upstream Wine. - -- Erich E. Hoover Fri, 06 Dec 2013 13:26:24 -0700 - -wine-compholio (1.7.7) unstable; urgency=low - * Remove patches included in upstream Wine 1.7.7. - * Rebase ACL extended attribute patches against upstream Wine 1.7.7. - * Rebase SIO_ADDRESS_LIST_CHANGE patches against upstream Wine 1.7.7. - * Added the ability to return the list of patches with "wine --patches". - * Added a patch to workaround a Silverlight issue with multiple monitors. - -- Erich E. Hoover Fri, 22 Nov 2013 14:24:53 -0700 - -wine-compholio (1.7.6-1) unstable; urgency=low - * Work around a build problem with Wine 1.7.6. - -- Erich E. Hoover Tue, 12 Nov 2013 14:16:16 -0700 - -wine-compholio (1.7.6) unstable; urgency=low - * Rebased VMR7 patches against upstream Wine 1.7.6. - * Rebased SIO_ADDRESS_LIST_CHANGE patches against upstream Wine 1.7.6. - -- Erich E. Hoover Sun, 10 Nov 2013 17:26:30 -0700 - -wine-compholio (1.7.5-1) unstable; urgency=low - * Included new patch to fix running TestOut under Silverlight. - -- Erich E. Hoover Thu, 07 Nov 2013 11:18:23 -0700 - -wine-compholio (1.7.5) unstable; urgency=low - * Rebased changes against upstream Wine 1.7.5. - -- Erich E. Hoover Wed, 30 Oct 2013 08:05:51 -0600 - -wine-compholio (1.7.4-2) unstable; urgency=low - * Updated XEmbed patches from Sebastian Lackner. - -- Erich E. Hoover Mon, 28 Oct 2013 10:00:43 -0600 - -wine-compholio (1.7.4-1) unstable; urgency=low - * Fix an issue with Ubuntu 13.10 post-install behavior. - -- Erich E. Hoover Sun, 13 Oct 2013 15:13:48 -0600 - -wine-compholio (1.7.4) unstable; urgency=low - * Rebased changes against upstream Wine 1.7.4. - -- Erich E. Hoover Sat, 12 Oct 2013 13:30:33 -0600 - -wine-compholio (1.7.3) unstable; urgency=low - * Removed patches already included in upstream Wine 1.7.3. - * Rebased ACL extended attributes patch against upstream Wine 1.7.3. - * Update SIO_ADDRESS_LIST_CHANGE patches to new server-based method. - -- Erich E. Hoover Thu, 03 Oct 2013 15:16:26 -0600 - -wine-compholio (1.7.2) unstable; urgency=low - * Rebased changes against upstream Wine 1.7.2. - -- Erich E. Hoover Mon, 30 Sep 2013 12:21:43 -0600 - -wine-compholio (1.7.1) unstable; urgency=low - * Rebased changes against upstream Wine 1.7.1. - -- Erich E. Hoover Mon, 30 Sep 2013 11:42:34 -0600 - -wine-compholio (1.7.0-7) unstable; urgency=low - * Updated all changed patches and backported upstream commits. - -- Erich E. Hoover Mon, 30 Sep 2013 11:41:43 -0600 - -wine-compholio (1.7.0-6) unstable; urgency=low - * Included fix for Watchever from Andreas Loibl. - -- Erich E. Hoover Fri, 06 Sep 2013 16:33:33 -0600 - -wine-compholio (1.7.0-5) unstable; urgency=low - * Updated patches for LOVEFiLM from Sebastian Lackner and Michael Müller. - -- Erich E. Hoover Fri, 06 Sep 2013 16:33:33 -0600 - -wine-compholio (1.7.0-4) unstable; urgency=low - * Hopefully fixed build script problem. - -- Erich E. Hoover Tue, 27 Aug 2013 09:51:15 -0600 - -wine-compholio (1.7.0-3) unstable; urgency=low - * Added D3D acceleration fix from Michael Müller. - -- Erich E. Hoover Fri, 16 Apr 2010 12:20:00 -0600 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/staging/patchinstall.sh.in wine-staging-1.9.3~ubuntu12.04.1/staging/patchinstall.sh.in --- wine-staging-1.9.0~ubuntu12.04.1/staging/patchinstall.sh.in 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/staging/patchinstall.sh.in 2016-02-08 20:07:32.000000000 +0000 @@ -2,7 +2,7 @@ # # Script to automatically install all Wine Staging patches # -# Copyright (C) 2015 Sebastian Lackner +# Copyright (C) 2015-2016 Sebastian Lackner # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -26,16 +26,15 @@ echo "Usage: ./patchinstall.sh [DESTDIR=path] [--all] [-W patchset] [patchset ...]" echo "" echo "Autogenerated script to apply all Wine Staging patches on your Wine" - echo "source tree. This script replaces and enhances the old method of" - echo "using a Makefile." + echo "source tree." echo "" echo "Configuration:" echo " DESTDIR=path Specify the path to the wine source tree" echo " --all Select all patches" echo " --force-autoconf Run autoreconf and tools/make_requests after each patch" echo " --help Display this help and exit" - echo " --no-patchlist Do not apply patchlist (needed for 'wine --patches')" echo " --no-autoconf Do not run autoreconf and tools/make_requests" + echo " --no-patchlist Do not apply patchlist (needed for 'wine --patches')" echo " --upstream-commit Print the upstream Wine commit SHA1 and exit" echo " --version Show version information and exit" echo " -W patchset Exclude a specific patchset" @@ -52,14 +51,14 @@ # Get the upstream commit sha upstream_commit() {{ - echo "{latest_wine_commit}" + echo "{upstream_commit}" }} # Show version information version() {{ - echo "Wine Staging {latest_staging_version}" - echo "Copyright (C) 2014-2015 the Wine Staging project authors." + echo "{staging_version}" + echo "Copyright (C) 2014-2016 the Wine Staging project authors." echo "" echo "Patchset to be applied on upstream Wine:" echo " commit $(upstream_commit)" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/staging/patchupdate.py wine-staging-1.9.3~ubuntu12.04.1/staging/patchupdate.py --- wine-staging-1.9.0~ubuntu12.04.1/staging/patchupdate.py 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/staging/patchupdate.py 2016-02-08 20:07:32.000000000 +0000 @@ -1,9 +1,9 @@ #!/usr/bin/python2 # -*- coding: utf-8 -*- # -# Automatic patch dependency checker and apply script/README.md generator. +# Automatic patch dependency checker and apply script generator. # -# Copyright (C) 2014-2015 Sebastian Lackner +# Copyright (C) 2014-2016 Sebastian Lackner # Copyright (C) 2015 Michael Müller # # This library is free software; you can redistribute it and/or @@ -46,29 +46,24 @@ _devnull = open(os.devnull, 'wb') # Cached information to speed up patch dependency checks -latest_wine_commit = None -latest_staging_version = None -cached_patch_result = {} +upstream_commit = None class config(object): path_cache = ".patchupdate.cache" path_config = os.path.expanduser("~/.config/patchupdate.conf") path_patches = "patches" - path_changelog = "staging/changelog" + path_version = "staging/VERSION" path_wine = "staging/wine" path_template_script = "staging/patchinstall.sh.in" path_script = "patches/patchinstall.sh" - path_template_README_md = "staging/README.md.in" - path_README_md = "README.md" - path_IfDefined = "9999-IfDefined.patch" bugtracker_url = "https://bugs.winehq.org/xmlrpc.cgi" bugtracker_defaultcc = ["michael@fds-team.de", "sebastian@fds-team.de", - "erich.e.hoover@wine-staging.com"] + "erich.e.hoover@wine-staging.com", "dmitry@baikal.ru"] bugtracker_user = None bugtracker_pass = None @@ -148,31 +143,19 @@ def _parse_int(val, default=0): """Parse an integer or boolean value.""" - r = re.match("^[0-9]+$", val) - if r: + if re.match("^[0-9]+$", val): return int(val) try: return {'true': 1, 'yes': 1, 'false': 0, 'no': 0}[val.lower()] - except AttributeError: + except KeyError: return default -def _read_changelog(): - """Read information from changelog.""" - with open(config.path_changelog) as fp: - for line in fp: - r = re.match("^([a-zA-Z0-9][^(]*)\((.*)\) ([^;]*)", line) - if r: yield (r.group(1).strip(), r.group(2).strip(), r.group(3).strip()) - -def _latest_staging_version(only_released=False): - """Get version number of the latest release / unreleased version.""" - for package, version, distro in _read_changelog(): - version = version.replace("~rc", "-rc") - if distro.lower() != "unreleased": - return version - elif not only_released: - return "%s (unreleased)" % version +def _staging_version(): + """Get the current version number of Wine Staging.""" + with open(config.path_version) as fp: + return fp.read().strip() -def _latest_wine_commit(commit=None): +def _upstream_commit(commit=None): """Get latest wine commit.""" if not os.path.isdir(config.path_wine): raise PatchUpdaterError("Please create a symlink to the wine repository in %s" % config.path_wine) @@ -181,73 +164,43 @@ assert len(commit) == 40 and commit == commit.lower() return commit -def enum_directories(revision, path): - """Enumerate all subdirectories of 'path' at a specific revision.""" +def enum_patchsets(path): + """Return a sorted list of all subdirectories of path.""" dirs = [] + for name in os.listdir(path): + directory = os.path.join(path, name) + if not os.path.isdir(directory): + continue + dirs.append((name, directory)) + return sorted(dirs) - if path[0:2] == "./": - path = path[2:] - elif path[0] == "/": - raise RuntimeError("Expected relative path, not an absolute path") - - if revision is None: - for name in os.listdir(path): - if name in [".", ".."]: continue - directory = os.path.join(path, name) - if not os.path.isdir(directory): - continue - dirs.append((name, directory)) - else: - filename = "%s:%s" % (revision, path) - try: - content = subprocess.check_output(["git", "show", filename], stderr=_devnull) - except subprocess.CalledProcessError as e: - if e.returncode != 128: raise - return [] # ignore error - lines = content.split("\n") - if not lines[0].startswith("tree ") or lines[1] != "": - raise RuntimeError("Unexpected output from 'git show %s'" % filename) - for name in lines[2:]: - if name == "" or name[-1] != "/": continue - name = name[:-1] - dirs.append((name, os.path.join(path, name))) - - return dirs - -def read_patchset(revision = None): - """Read information about all patchsets for a specific revision.""" +def load_patchsets(): + """Read information about all patchsets.""" unique_id = itertools.count() all_patches = {} name_to_id = {} categories = {} - # Read in sorted order (to ensure created Makefile doesn't change too much) - for name, directory in sorted(enum_directories(revision, config.path_patches)): + for name, directory in enum_patchsets(config.path_patches): patch = PatchSet(name, directory) - if revision is None: - - # If its the latest revision, then request additional information - if not os.path.isdir(directory): - raise RuntimeError("Unable to open directory %s" % directory) - - # Enumerate .patch files in the given directory, enumerate individual patches and affected files - for f in sorted(os.listdir(directory)): - if not re.match("^[0-9]{4}-.*\\.patch$", f): - continue - if f.startswith(config.path_IfDefined): - continue - if not os.path.isfile(os.path.join(directory, f)): - continue - patch.files.append(f) - for p in patchutils.read_patch(os.path.join(directory, f)): - patch.modified_files.add(p.modified_file) - patch.patches.append(p) - - # No single patch within this directory, ignore it - if len(patch.patches) == 0: - del patch + # Enumerate .patch files in the given directory, enumerate individual patches and affected files + for f in sorted(os.listdir(directory)): + if not re.match("^[0-9]{4}-.*\\.patch$", f): continue + if f.startswith(config.path_IfDefined): + continue + if not os.path.isfile(os.path.join(directory, f)): + continue + patch.files.append(f) + for p in patchutils.read_patch(os.path.join(directory, f)): + patch.modified_files.add(p.modified_file) + patch.patches.append(p) + + # No single patch within this directory, ignore it + if len(patch.patches) == 0: + del patch + continue i = next(unique_id) all_patches[i] = patch @@ -255,15 +208,11 @@ # Now read the definition files in a second step for i, patch in all_patches.iteritems(): + filename = os.path.join(os.path.join(config.path_patches, patch.name), "definition") try: - filename = os.path.join(os.path.join(config.path_patches, patch.name), "definition") - if revision is None: - with open(filename) as fp: - content = fp.read() - else: - filename = "%s:%s" % (revision, filename) - content = subprocess.check_output(["git", "show", filename], stderr=_devnull) - except (IOError, subprocess.CalledProcessError): + with open(filename) as fp: + content = fp.read() + except IOError: continue # Skip this definition file for line in content.split("\n"): @@ -310,16 +259,17 @@ elif key == "ifdefined": patch.ifdefined = val - elif revision is None: + else: print "WARNING: Ignoring unknown command in definition file %s: %s" % (filename, line) # If patch is not disabled then finally add it to the category - if not patch.disabled: - for category in patch.categories: - if not categories.has_key(category): - categories[category] = set() - categories[category].add(i) + if patch.disabled: + continue + for category in patch.categories: + if not categories.has_key(category): + categories[category] = set() + categories[category].add(i) # Add virtual targets for all the categories for category, indices in categories.iteritems(): @@ -366,7 +316,7 @@ def get_wine_file(filename): """Return the content of a file.""" - entry = "%s:%s" % (latest_wine_commit, filename) + entry = "%s:%s" % (upstream_commit, filename) result = tempfile.NamedTemporaryFile() try: content = subprocess.check_call(["git", "show", entry], cwd=config.path_wine, \ @@ -405,14 +355,11 @@ def _resolve(depends): for i in sorted(depends): - # Check for disabled patch - if all_patches[i].disabled: + if all_patches[i].disabled: # Check for disabled patch raise PatchUpdaterError("Encountered dependency on disabled patchset %s" % all_patches[i].name) - # Dependencies already resolved - if all_patches[i].verify_resolved > 0: + if all_patches[i].verify_resolved > 0: # Dependencies already resolved continue - # Detect circular dependency - if all_patches[i].verify_resolved < 0: + if all_patches[i].verify_resolved < 0: # Detect circular dependency raise PatchUpdaterError("Circular dependency while trying to resolve %s" % all_patches[i].name) # Recusively resolve dependencies @@ -532,7 +479,7 @@ fp.write("\n") depends = resolve_dependencies(enabled_patches, i) - for f in patch.modified_files: + for f in sorted(patch.modified_files): # Reconstruct the state after applying the dependencies original = get_wine_file(f) @@ -633,11 +580,14 @@ unique_hash = m.digest() # Skip checks if it matches the information from the cache - try: - if dependency_cache[filename] == unique_hash: + # For backwards compatibility, convert string entries to list + if dependency_cache.has_key(filename): + if not isinstance(dependency_cache[filename], list): + dependency_cache[filename] = [dependency_cache[filename]] + if unique_hash in dependency_cache[filename]: + dependency_cache[filename].append(unique_hash) + dependency_cache[filename].remove(unique_hash) continue - except KeyError: - pass # Show a progress bar while applying the patches - this task might take some time chunk_size = 20 @@ -680,8 +630,11 @@ (filename, ", ".join([all_patches[i].name for i in failed]))) progress.update(k) - # Update the dependency cache - dependency_cache[filename] = unique_hash + # Update the dependency cache, store max 10 entries per file + if not dependency_cache.has_key(filename): + dependency_cache[filename] = [] + dependency_cache[filename].append(unique_hash) + dependency_cache[filename] = dependency_cache[filename][-10:] # Delete outdated cache information for filename in dependency_cache.keys(): @@ -790,8 +743,8 @@ with open(config.path_template_script) as template_fp: template = template_fp.read() with open(config.path_script, "w") as fp: - fp.write(template.format(latest_staging_version=_latest_staging_version(), - latest_wine_commit=latest_wine_commit, + fp.write(template.format(staging_version=_staging_version(), + upstream_commit=upstream_commit, patch_helpers="".join(lines_helpers).rstrip("\n"), patch_resolver="".join(lines_resolver).rstrip("\n"), patch_apply="".join(lines_apply).rstrip("\n"))) @@ -799,100 +752,6 @@ # Add changes to git subprocess.call(["git", "add", config.path_script]) -def generate_markdown(all_patches, release_patches): - """Generate README.md including information about specific patches and bugfixes.""" - - def _format_bug(mode, bugid, bugname): - if mode < 0: bugname = "~~%s~~" % bugname - if bugid is None: return "* %s" % bugname - return "* %s ([Wine Bug #%d](https://bugs.winehq.org/show_bug.cgi?id=%d))" % \ - (bugname, bugid, bugid) #, short_desc.replace("\\", "\\\\").replace("\"", "\\\"")) - - all_fixes = {} - - # Get fixes for current version - for _, patch in all_patches.iteritems(): - for sync, bugid, bugname in patch.fixes: - key = bugid if bugid is not None else bugname - all_fixes[key] = [1, bugid, bugname] - - # Compare with fixes for last release - for _, patch in release_patches.iteritems(): - for sync, bugid, bugname in patch.fixes: - if bugid is not None and all_fixes.has_key(bugid): - all_fixes[bugid][0] = 0 - elif all_fixes.has_key(bugname): - all_fixes[bugname][0] = 0 - elif bugid is None: - for k, v in all_fixes.iteritems(): - if v[2] != bugname: continue - if v[1] is None: continue - all_fixes[v[1]][0] = 0 - break - else: - all_fixes[bugname] = [-1, None, bugname] - else: - all_fixes[bugid] = [-1, bugid, bugname] - - # Generate lists for all new and old fixes - new_fixes = [(mode, bugid, bugname) for dummy, (mode, bugid, bugname) in - all_fixes.iteritems() if mode > 0] - old_fixes = [(mode, bugid, bugname) for dummy, (mode, bugid, bugname) in - all_fixes.iteritems() if mode <= 0] - - # List of old fixes is not available when releasing a new version - if len(old_fixes) == 0: - old_fixes = new_fixes - new_fixes = [] - - # Generate information for current version - lines = [] - if len(new_fixes): - lines.append("**Bug fixes and features included in the next upcoming release [%d]:**" % len(new_fixes)) - lines.append("") - for mode, bugid, bugname in sorted(new_fixes, key=lambda x: x[2]): - lines.append(_format_bug(mode, bugid, bugname)) - lines.append("") - lines.append("") - lines.append("**Bug fixes and features in Wine Staging %s [%d]:**" % (latest_staging_version, len(old_fixes))) - lines.append("") - lines.append("*Note: The following list only contains features and bug fixes which are not") - lines.append("yet available in vanilla Wine. They are removed from the list as soon as they") - lines.append("are included upstream. The list also includes features and fixes from previous") - lines.append("releases, take a look at the") - lines.append("[changelog](https://github.com/wine-compholio/wine-staging/blob/master/staging/changelog)") - lines.append("for more details.*") - lines.append("") - for mode, bugid, bugname in sorted(old_fixes, key=lambda x: x[2]): - lines.append(_format_bug(mode, bugid, bugname)) - - # Update README.md - with open(config.path_template_README_md) as template_fp: - template = template_fp.read() - with open(config.path_README_md, "w") as fp: - fp.write(template.format(fixes="\n".join(lines))) - - # Add changes to git - subprocess.call(["git", "add", config.path_README_md]) - -def wrap_changelog(): - - lines = [] - with open(config.path_changelog) as fp: - for line in fp: - if line.startswith(" *") and len(line.rstrip("\n")) > 80: - wrapped = textwrap.wrap(line[3:].strip(), 80 - 4) - lines.append(" * %s\n" % "\n ".join(wrapped)) - else: - lines.append(line) - - with open(config.path_changelog, "w") as fp: - for line in lines: - fp.write(line) - - # Add changes to git - subprocess.call(["git", "add", config.path_changelog]) - if __name__ == "__main__": @@ -907,7 +766,7 @@ raise argparse.ArgumentTypeError("not a valid commit hash") return commit - parser = argparse.ArgumentParser(description="Automatic patch dependency checker and apply script/README.md generator.") + parser = argparse.ArgumentParser(description="Automatic patch dependency checker and apply script generator.") parser.add_argument('--skip-checks', action='store_true', help="Skip dependency checks") parser.add_argument('--commit', type=_check_commit_hash, help="Use given commit hash instead of HEAD") parser.add_argument('--sync-bugs', action='store_true', help="Update bugs in bugtracker (requires admin rights)") @@ -927,14 +786,8 @@ config.bugtracker_pass = None try: - - # Get information about Wine and Staging version - latest_wine_commit = _latest_wine_commit(args.commit) - latest_staging_version = _latest_staging_version(only_released=True) - - # Read current and release patches - all_patches = read_patchset() - release_patches = read_patchset(revision="v%s" % latest_staging_version) + upstream_commit = _upstream_commit(args.commit) + all_patches = load_patchsets() # Check bugzilla check_bug_status(all_patches, sync_bugs=args.sync_bugs) @@ -942,8 +795,6 @@ # Update autogenerated files generate_ifdefined(all_patches, skip_checks=args.skip_checks) generate_script(all_patches, skip_checks=args.skip_checks) - generate_markdown(all_patches, release_patches) - wrap_changelog() except PatchUpdaterError as e: print "" diff -Nru wine-staging-1.9.0~ubuntu12.04.1/staging/patchutils.py wine-staging-1.9.3~ubuntu12.04.1/staging/patchutils.py --- wine-staging-1.9.0~ubuntu12.04.1/staging/patchutils.py 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/staging/patchutils.py 2016-02-08 20:07:32.000000000 +0000 @@ -2,7 +2,7 @@ # # Python functions to read, split and apply patches. # -# Copyright (C) 2014 Sebastian Lackner +# Copyright (C) 2014-2016 Sebastian Lackner # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -19,6 +19,7 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA # +import cStringIO as StringIO import collections import difflib import email.header @@ -85,11 +86,15 @@ i -= len(buf) class _FileReader(object): - def __init__(self, filename): + def __init__(self, filename, content=None): self.filename = filename - self.fp = open(self.filename) self.peeked = None + if content is not None: + self.fp = StringIO.StringIO(content) + else: + self.fp = open(filename) + def close(self): self.fp.close() @@ -128,7 +133,7 @@ tmp, self.peeked = self.peeked, None return tmp[1] -def read_patch(filename): +def read_patch(filename, content=None): """Iterates over all patches contained in a file, and returns PatchObject objects.""" def _read_single_patch(fp, header, oldname=None, newname=None): @@ -297,6 +302,8 @@ if r is not None: return subject, int(r.group(2)) r = re.match("^(.*)\\(%s\\)$" % version, subject, re.IGNORECASE) if r is not None: return r.group(1).strip(), int(r.group(3)) + r = re.match("^(.*)\\[%s\\]$" % version, subject, re.IGNORECASE) + if r is not None: return r.group(1).strip(), int(r.group(3)) r = re.match("^(.*)[.,] +%s$" % version, subject, re.IGNORECASE) if r is not None: return r.group(1).strip(), int(r.group(3)) r = re.match("^([^:]+) %s: (.*)$" % version, subject, re.IGNORECASE) @@ -308,7 +315,7 @@ return subject, 1 header = {} - with _FileReader(filename) as fp: + with _FileReader(filename, content) as fp: while True: line = fp.peek() if line is None: @@ -379,90 +386,89 @@ os.unlink(result.name) raise -def generate_ifdef_patch(original, patched, ifdef): - """Generate a patch which adds #ifdef where necessary to keep both the original and patched version.""" - - def _preprocess_source(fp): - """Simple C preprocessor to determine where we can safely add #ifdef instructions.""" +def _preprocess_source(fp): + """Simple C preprocessor to determine where we can safely add #ifdef instructions.""" - _re_state0 = re.compile("(\"|/[/*])") - _re_state1 = re.compile("(\\\"|\")") - _re_state2 = re.compile("\\*/") - - # We need to read the original file, and figure out where lines can be splitted - lines = [] - original.seek(0) - for line in original: - lines.append(line.rstrip("\n")) - - split = set([0]) - state = 0 - - i = 0 - while i < len(lines): - - # Read a full line (and handle line continuation) - line = lines[i] + _re_state0 = re.compile("(\"|/[/*])") + _re_state1 = re.compile("(\\\\\"|\\\\\\\\|\")") + _re_state2 = re.compile("\\*/") + + # We need to read the original file, and figure out where lines can be splitted + lines = [] + for line in fp: + lines.append(line.rstrip("\n")) + + split = set([0]) + state = 0 + + i = 0 + while i < len(lines): + + # Read a full line (and handle line continuation) + line = lines[i] + i += 1 + while line.endswith("\\"): + if i >= len(lines): + raise CParserError("Unexpected end of file.") + line = line[:-1] + lines[i] i += 1 - while line.endswith("\\"): - if i >= len(lines): - raise CParserError("Unexpected end of file.") - line = line[:-1] + lines[i] - i += 1 - - # To find out where we can add our #ifdef tags we use a simple - # statemachine. This allows finding the beginning of a multiline - # instruction or comment. - j = 0 - while True: - # State 0: No context - if state == 0: - match = _re_state0.search(line, j) - if match is None: break - - if match.group(0) == "\"": - state = 1 # Begin of string - elif match.group(0) == "/*": - state = 2 # Begin of comment - elif match.group(0) == "//": - break # Rest of the line is a comment, which can be safely ignored - else: - assert 0 + # To find out where we can add our #ifdef tags we use a simple + # statemachine. This allows finding the beginning of a multiline + # instruction or comment. + j = 0 + while True: + + # State 0: No context + if state == 0: + match = _re_state0.search(line, j) + if match is None: break - # State 1: Inside of string - elif state == 1: - match = _re_state1.search(line, j) - if match is None: - raise CParserError("Line ended in the middle of a string.") - - if match.group(0) == "\"": - state = 0 # End of string - elif match.group(0) != "\\\"": - assert 0 - - # State 2: Multiline comment - elif state == 2: - match = _re_state2.search(line, j) - if match is None: break + if match.group(0) == "\"": + state = 1 # Begin of string + elif match.group(0) == "/*": + state = 2 # Begin of comment + elif match.group(0) == "//": + break # Rest of the line is a comment, which can be safely ignored + else: + assert 0 - if match.group(0) == "*/": - state = 0 # End of comment - else: - assert 0 + # State 1: Inside of string + elif state == 1: + match = _re_state1.search(line, j) + if match is None: + raise CParserError("Line ended in the middle of a string.") + + if match.group(0) == "\"": + state = 0 # End of string + elif match.group(0) != "\\\"" and match.group(0) != "\\\\": + assert 0 + + # State 2: Multiline comment + elif state == 2: + match = _re_state2.search(line, j) + if match is None: break + if match.group(0) == "*/": + state = 0 # End of comment else: - raise CParserError("Internal state error.") - j = match.end() + assert 0 - # Only in state 0 (no context) we can split here - if state == 0: - split.add(i) + else: + raise CParserError("Internal state error.") + j = match.end() + + # Only in state 0 (no context) we can split here + if state == 0: + split.add(i) + + # Ensure that the last comment is properly terminated + if state != 0: + raise CParserError("Unexpected end of file.") + return lines, split - # Ensure that the last comment is properly terminated - if state != 0: - raise CParserError("Unexpected end of file.") - return lines, split +def generate_ifdef_patch(original, patched, ifdef): + """Generate a patch which adds #ifdef where necessary to keep both the original and patched version.""" # # The basic of idea of this algorithm is as following: @@ -482,6 +488,7 @@ raise PatchDiffError("Failed to compute diff (exitcode %d)." % exitcode) # Preprocess the original C source + original.seek(0) lines, split = _preprocess_source(original) # Parse the created diff file @@ -565,8 +572,10 @@ # If this is the first hunk, then check if we have to extend it at the beginning if len(hunks) == 0: + assert srcpos == dstpos while srcpos > 0 and srcpos not in split: srcpos -= 1 + dstpos -= 1 srcdata.insert(0, lines[srcpos]) dstdata.insert(0, lines[srcpos]) hunks.append((srcpos, dstpos, srcdata, dstdata)) @@ -601,8 +610,8 @@ prev_dstdata.append(lines[prev_endpos]) prev_endpos += 1 assert prev_dstpos + len(prev_dstdata) == dstpos - hunks[-1][2] += srcdata - hunks[-1][3] += dstdata + prev_srcdata.extend(srcdata) + prev_dstdata.extend(dstdata) # Ready with this hunk pass diff -Nru wine-staging-1.9.0~ubuntu12.04.1/staging/README.md.in wine-staging-1.9.3~ubuntu12.04.1/staging/README.md.in --- wine-staging-1.9.0~ubuntu12.04.1/staging/README.md.in 2015-12-28 19:12:30.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/staging/README.md.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -What is Wine Staging? ---------------------- - -**Wine Staging** is the testing area of winehq.org. It contains bug fixes and -features, which have not been integrated into the development branch yet. The -idea of Wine Staging is to provide experimental features faster to end users and -to give developers the possibility to discuss and improve their patches before -they are integrated into the main branch. More information about Wine Staging -can also be found on our website [wine-staging.com](http://wine-staging.com). - -Although we are reviewing and testing all patches carefully before adding them, -you may encounter additional bugs, which are not present in the development -branch. Do not hesitate to report such issues at winehq.org, so they can be -fixed before the feature gets integrated. - - -How to install and use Wine Staging ------------------------------------ - -Ready-to-use packages for Wine Staging are available for a variety -of different Linux distributions directly for download. Just follow the -instructions available on the -[Wiki](https://github.com/wine-compholio/wine-staging/wiki/Installation). - -When using Wine Staging there are a few differences compared to regular -Wine. The main difference is that it is not sufficient to type `wine` to -run it, but instead you will have to type `/opt/wine-staging/bin/wine`. -Besides that there are also some other differences, for example additional -configuration options to tweak performance, which are not available in regular -Wine. All those differences are also documented on the -[Wiki](https://github.com/wine-compholio/wine-staging/wiki/Usage). - - -Included bug fixes and improvements ------------------------------------ - -{fixes} - diff -Nru wine-staging-1.9.0~ubuntu12.04.1/staging/VERSION wine-staging-1.9.3~ubuntu12.04.1/staging/VERSION --- wine-staging-1.9.0~ubuntu12.04.1/staging/VERSION 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/staging/VERSION 2016-02-08 20:07:32.000000000 +0000 @@ -0,0 +1 @@ +Wine Staging 1.9.3 diff -Nru wine-staging-1.9.0~ubuntu12.04.1/tools/make_announce wine-staging-1.9.3~ubuntu12.04.1/tools/make_announce --- wine-staging-1.9.0~ubuntu12.04.1/tools/make_announce 1970-01-01 00:00:00.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/tools/make_announce 2016-02-08 19:32:34.000000000 +0000 @@ -0,0 +1,172 @@ +#!/usr/bin/perl -w +# +# Update the ANNOUNCE file for a new release. +# +# Usage: make_announce [new_version] +# +# Copyright 2016 Alexandre Julliard +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA +# + +use strict; +use locale; +use POSIX; +use Text::CSV::Encoded; +binmode STDOUT, ':utf8'; + +sub unescape($) +{ + my $str = shift; + $str =~ s/"/\"/g; + $str =~ s/'/\'/g; + $str =~ s/&/&/g; + $str =~ s/<//g; + $str =~ s/@/\@/g; + return $str; +} + +# update a file if changed +sub update_file($) +{ + my $file = shift; + if (!(-f $file) || system "cmp $file $file.new >/dev/null") + { + rename "$file.new", "$file"; + print "$file updated\n"; + } + else + { + unlink "$file.new"; + } +} + +# determine the current version number +sub get_current_version() +{ + my $version; + + open VERSION, " =~ /Wine version (\S+)/) { $version = $1; } + close VERSION; + die "failed to parse VERSION" unless $version; + return $version; +} + +# retrieve a list of bugs with the specified filter +sub get_bugs($) +{ + my $filter = shift; + my $csv = Text::CSV::Encoded->new({ encoding_in => "utf-8", encoding_out => "utf-8" }); + my %bugs; + + open QUERY, "-|" or exec "wget", "-qO-", "https://bugs.winehq.org/buglist.cgi?columnlist=short_desc&query_format=advanced&ctype=csv&$filter" + or die "cannot query bug list"; + ; # skip header line + while () + { + next unless $csv->parse($_); + my ($id, $descr) = $csv->fields(); + $bugs{$id} = $descr; + } + close QUERY; + return %bugs; +} + +# retrieve the current list of authors +sub get_authors() +{ + my %authors; + + open AUTHORS, "; # skip header line + while () + { + chomp; + next if /^$/; + $authors{$_} = 1; + } + close AUTHORS; + return %authors; +} + +# determine the version number + +my $old = get_current_version(); +my $new = $ARGV[0]; +unless ($new) +{ + if ($old =~ /^([0-9]+)\.([0-9]+)$/) { $new = "$1.$2.1"; } + elsif ($old =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)$/) { $new = "$1.$2." . ($3 + 1); } + elsif ($old =~ /^([0-9]+)\.([0-9]+)-rc([0-9]+)$/) { $new = "$1.$2-rc" . ($3 + 1); } + else { die "unknown version format $old"; } +} + +print "Updating files for release $new\n"; + +(my $reldir = $new) =~ s/^([0-9]+\.[0-9]+).*/$1/; +my $is_stable = ($new =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)$/) && !($2 % 2); # stable releases have an even minor number +my $filter = "product=Wine&resolution=FIXED&" . ($is_stable ? "target_milestone=$reldir.x" : "bug_status=RESOLVED"); + +my %bugs = get_bugs( $filter ); +my %authors = get_authors(); + +# update the ANNOUNCE file + +open ANNOUNCE, "ANNOUNCE.new" or die "cannot create ANNOUNCE.new"; +while () +{ + last if /^------------------/; + s!http://mirrors.ibiblio.org/wine/source/.*!http://mirrors.ibiblio.org/wine/source/$reldir/wine-$new.tar.bz2!; + s!http://dl.winehq.org/wine/source/.*!http://dl.winehq.org/wine/source/$reldir/wine-$new.tar.bz2!; + print NEW $_; +} + +print NEW "----------------------------------------------------------------\n\n"; +printf NEW "Bugs fixed in %s (total %u):\n\n", $new, scalar( keys %bugs ); +foreach my $id (sort {$a <=> $b} keys %bugs) +{ + printf NEW " %6d %s\n", $id, unescape( $bugs{$id} ); +} + +print NEW "\n----------------------------------------------------------------\n\n"; +print NEW "Changes since $old:\n\n"; + +open LOG, "-|" or exec "git", "shortlog", "wine-$old..HEAD" or die "cannot run git shortlog"; +while () +{ + if (/^(\S.*)\s\(\d+\):$/) { $authors{$1} = 1; } + print NEW $_; +} +close LOG; + +while () { last if /^--$/; } +print NEW "--\n"; +while () { print NEW $_; } + +close ANNOUNCE; +close NEW; +update_file( "ANNOUNCE" ); + +# update the AUTHORS file + +setlocale( LC_COLLATE, "en_US.UTF-8" ); + +open AUTHORS, ">AUTHORS.new" or die "cannot create AUTHORS.new"; +print AUTHORS "Wine is available thanks to the work of:\n\n", join( "\n", sort keys %authors ), "\n"; +close AUTHORS; +update_file( "AUTHORS" ); diff -Nru wine-staging-1.9.0~ubuntu12.04.1/tools/makedep.c wine-staging-1.9.3~ubuntu12.04.1/tools/makedep.c --- wine-staging-1.9.0~ubuntu12.04.1/tools/makedep.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/tools/makedep.c 2016-02-08 19:32:34.000000000 +0000 @@ -156,6 +156,7 @@ struct strarray scripts; struct strarray appmode; struct strarray imports; + struct strarray subdirs; struct strarray delayimports; struct strarray extradllflags; struct strarray install_lib; @@ -175,6 +176,7 @@ const char *importlib; int use_msvcrt; int is_win16; + struct makefile **submakes; }; static struct makefile *top_makefile; @@ -189,7 +191,7 @@ static FILE *output_file; static const char Usage[] = - "Usage: makedep [options] directories\n" + "Usage: makedep [options] [directories]\n" "Options:\n" " -R from to Compute the relative path between two directories\n" " -fxxx Store output in file 'xxx' (default: Makefile)\n"; @@ -2023,7 +2025,7 @@ /******************************************************************* * output_sources */ -static struct strarray output_sources( const struct makefile *make, struct strarray *testlist_files ) +static struct strarray output_sources( const struct makefile *make ) { struct incl_file *source; unsigned int i, j; @@ -2734,7 +2736,6 @@ strarray_add( &phony_targets, "check" ); strarray_add( &phony_targets, "test" ); strarray_add( &phony_targets, "testclean" ); - *testlist_files = strarray_replace_extension( &ok_files, ".ok", "" ); } for (i = 0; i < make->programs.count; i++) @@ -2842,11 +2843,29 @@ strarray_add( &phony_targets, obj_dir_path( make, "clean" )); } - if (make->top_obj_dir) + if (make->subdirs.count) { - output( "depend:\n" ); - output( "\t@cd %s && $(MAKE) %s\n", make->top_obj_dir, base_dir_path( make, "depend" )); - strarray_add( &phony_targets, "depend" ); + struct strarray makefile_deps = empty_strarray; + struct strarray distclean_files = empty_strarray; + + for (i = 0; i < make->subdirs.count; i++) + { + strarray_add( &makefile_deps, top_dir_path( make, base_dir_path( make->submakes[i], + strmake ( "%s.in", output_makefile_name )))); + strarray_add( &distclean_files, base_dir_path( make->submakes[i], output_makefile_name )); + if (!make->src_dir) + strarray_add( &distclean_files, base_dir_path( make->submakes[i], ".gitignore" )); + if (make->submakes[i]->testdll) + strarray_add( &distclean_files, base_dir_path( make->submakes[i], "testlist.c" )); + } + output( "Makefile:" ); + output_filenames( makefile_deps ); + output( "\n" ); + output( "distclean::\n"); + output( "\trm -f" ); + output_filenames( distclean_files ); + output( "\n" ); + strarray_add( &phony_targets, "distclean" ); } if (phony_targets.count) @@ -2952,9 +2971,19 @@ /******************************************************************* * output_testlist */ -static void output_testlist( const char *dest, struct strarray files ) +static void output_testlist( const struct makefile *make ) { - int i; + const char *dest = base_dir_path( make, "testlist.c" ); + struct strarray files = empty_strarray; + struct incl_file *source; + unsigned int i; + + LIST_FOR_EACH_ENTRY( source, &make->sources, struct incl_file, entry ) + { + if (source->file->flags & FLAG_GENERATED) continue; + if (!strendswith( source->name, ".c" )) continue; + strarray_add( &files, replace_extension( source->name, ".c", "" )); + } output_file = create_temp_file( dest ); @@ -3013,7 +3042,10 @@ output( "# Automatically generated by make depend; DO NOT EDIT!!\n\n" ); output( "all:\n\n" ); for (i = 0; i < vars->count; i += 2) + { + if (!strcmp( vars->str[i], "SUBDIRS" )) continue; /* not inherited */ output( "%s = %s\n", vars->str[i], get_make_variable( make, vars->str[i] )); + } output( "\n" ); } @@ -3023,9 +3055,11 @@ */ static void output_dependencies( const struct makefile *make ) { - struct strarray targets, testlist_files = empty_strarray, ignore_files = empty_strarray; + static const char separator[] = "### Dependencies"; + struct strarray targets, ignore_files = empty_strarray; char buffer[1024]; FILE *src_file; + int found = 0; output_file_name = base_dir_path( make, output_makefile_name ); output_file = create_temp_file( output_file_name ); @@ -3033,12 +3067,16 @@ /* copy the contents of the source makefile */ src_file = open_input_makefile( make ); - while (fgets( buffer, sizeof(buffer), src_file )) + while (fgets( buffer, sizeof(buffer), src_file ) && !found) + { if (fwrite( buffer, 1, strlen(buffer), output_file ) != strlen(buffer)) fatal_perror( "write" ); + found = !strncmp( buffer, separator, strlen(separator) ); + } if (fclose( src_file )) fatal_perror( "close" ); input_file_name = NULL; - targets = output_sources( make, &testlist_files ); + if (!found) output( "\n%s (everything below this line is auto-generated; DO NOT EDIT!!)\n", separator ); + targets = output_sources( make ); fclose( output_file ); output_file = NULL; @@ -3046,11 +3084,12 @@ strarray_add( &ignore_files, ".gitignore" ); strarray_add( &ignore_files, "Makefile" ); - if (testlist_files.count) strarray_add( &ignore_files, "testlist.c" ); + if (make->testdll) + { + output_testlist( make ); + strarray_add( &ignore_files, "testlist.c" ); + } strarray_addall( &ignore_files, targets ); - - if (testlist_files.count) - output_testlist( base_dir_path( make, "testlist.c" ), testlist_files ); if (!make->src_dir && make->base_dir) output_gitignore( base_dir_path( make, ".gitignore" ), ignore_files ); @@ -3059,9 +3098,9 @@ /******************************************************************* - * update_makefile + * load_sources */ -static void update_makefile( const char *path ) +static void load_sources( struct makefile *make ) { static const char *source_vars[] = { @@ -3084,9 +3123,6 @@ unsigned int i; struct strarray value; struct incl_file *file; - struct makefile *make; - - make = parse_makefile( path, NULL ); if (root_src_dir) { @@ -3161,8 +3197,6 @@ } LIST_FOR_EACH_ENTRY( file, &make->includes, struct incl_file, entry ) parse_file( make, file, 0 ); - - output_dependencies( make ); } @@ -3250,11 +3284,6 @@ exit( 0 ); } - if (argc <= 1) - { - fprintf( stderr, "%s", Usage ); - exit( 1 ); - } atexit( cleanup_files ); signal( SIGTERM, exit_on_signal ); signal( SIGINT, exit_on_signal ); @@ -3294,6 +3323,30 @@ if (!tools_ext) tools_ext = ""; if (!man_ext) man_ext = "3w"; - for (i = 1; i < argc; i++) update_makefile( argv[i] ); + if (argc == 1) + { + top_makefile->subdirs = get_expanded_make_var_array( top_makefile, "SUBDIRS" ); + top_makefile->submakes = xmalloc( top_makefile->subdirs.count * sizeof(*top_makefile->submakes) ); + + for (i = 0; i < top_makefile->subdirs.count; i++) + top_makefile->submakes[i] = parse_makefile( top_makefile->subdirs.str[i], NULL ); + + load_sources( top_makefile ); + for (i = 0; i < top_makefile->subdirs.count; i++) + load_sources( top_makefile->submakes[i] ); + + for (i = 0; i < top_makefile->subdirs.count; i++) + output_dependencies( top_makefile->submakes[i] ); + + output_dependencies( top_makefile ); + return 0; + } + + for (i = 1; i < argc; i++) + { + struct makefile *make = parse_makefile( argv[i], NULL ); + load_sources( make ); + output_dependencies( make ); + } return 0; } diff -Nru wine-staging-1.9.0~ubuntu12.04.1/tools/make_specfiles wine-staging-1.9.3~ubuntu12.04.1/tools/make_specfiles --- wine-staging-1.9.0~ubuntu12.04.1/tools/make_specfiles 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/tools/make_specfiles 2016-02-08 19:32:34.000000000 +0000 @@ -262,6 +262,10 @@ "api-ms-win-core-winrt-l1-1-0", "api-ms-win-core-winrt-string-l1-1-0", ], + [ + "bthprops.cpl", + "irprops.cpl", + ], ); my $update_flags = 0; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/tools/winebuild/utils.c wine-staging-1.9.3~ubuntu12.04.1/tools/winebuild/utils.c --- wine-staging-1.9.0~ubuntu12.04.1/tools/winebuild/utils.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/tools/winebuild/utils.c 2016-02-08 19:32:34.000000000 +0000 @@ -64,6 +64,9 @@ { "x86_64", CPU_x86_64 }, { "powerpc", CPU_POWERPC }, { "arm", CPU_ARM }, + { "armv5", CPU_ARM }, + { "armv6", CPU_ARM }, + { "armv7", CPU_ARM }, { "arm64", CPU_ARM64 }, { "aarch64", CPU_ARM64 }, }; diff -Nru wine-staging-1.9.0~ubuntu12.04.1/tools/winegcc/winegcc.c wine-staging-1.9.3~ubuntu12.04.1/tools/winegcc/winegcc.c --- wine-staging-1.9.0~ubuntu12.04.1/tools/winegcc/winegcc.c 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/tools/winegcc/winegcc.c 2016-02-08 19:32:34.000000000 +0000 @@ -160,7 +160,11 @@ { "x86_64", CPU_x86_64 }, { "powerpc", CPU_POWERPC }, { "arm", CPU_ARM }, - { "aarch64", CPU_ARM64 } + { "armv5", CPU_ARM }, + { "armv6", CPU_ARM }, + { "armv7", CPU_ARM }, + { "arm64", CPU_ARM64 }, + { "aarch64", CPU_ARM64 }, }; static const struct diff -Nru wine-staging-1.9.0~ubuntu12.04.1/VERSION wine-staging-1.9.3~ubuntu12.04.1/VERSION --- wine-staging-1.9.0~ubuntu12.04.1/VERSION 2015-12-28 18:59:20.000000000 +0000 +++ wine-staging-1.9.3~ubuntu12.04.1/VERSION 2016-02-08 19:32:34.000000000 +0000 @@ -1 +1 @@ -Wine version 1.9.0 +Wine version 1.9.3