summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Pranaitis <jens@chaox.net>2010-08-04 16:19:27 +0200
committerJens Pranaitis <jens@chaox.net>2010-08-04 16:19:27 +0200
commitea1cc5950e90cccf8ecb3883a617ff5ba51826e4 (patch)
tree69f2926c708df62f9f7a7729a7fb1c78b38cf44e
parentremoved pidgin with icq fix, as 2.7.2 was now released including the fix (diff)
downloadjensp-ea1cc5950e90cccf8ecb3883a617ff5ba51826e4.tar.gz
jensp-ea1cc5950e90cccf8ecb3883a617ff5ba51826e4.tar.bz2
jensp-ea1cc5950e90cccf8ecb3883a617ff5ba51826e4.zip
added wine 1.3.0 with dib engine
-rw-r--r--app-emulation/wine/Manifest8
-rw-r--r--app-emulation/wine/files/wine-1.1.15-winegcc.patch55
-rw-r--r--app-emulation/wine/files/wine-1.3.0-dib-engine.patch16184
-rw-r--r--app-emulation/wine/wine-1.3.0.ebuild207
4 files changed, 16454 insertions, 0 deletions
diff --git a/app-emulation/wine/Manifest b/app-emulation/wine/Manifest
new file mode 100644
index 0000000..daaf92c
--- /dev/null
+++ b/app-emulation/wine/Manifest
@@ -0,0 +1,8 @@
+AUX wine-1.1.15-winegcc.patch 1550 RMD160 086fbdd7dbe5da98c3457f00cb30705150d58b1f SHA1 0aa5a9d0947e15af9fe103797a0c993cbb3eedab SHA256 fcf4a0578774d817b8de094abae85e370683a77805a59efe6c5f7b8b87935de9
+AUX wine-1.3.0-dib-engine.patch 562412 RMD160 cf5b67b207e47f9ee88fb205cbd8560c856d5124 SHA1 f9f6282b6ae4e6327b99f9230c9e3a865badfcd4 SHA256 2006945d32af61c6ce92bcc6e639de92cb5d7de36318195c3f014a099634acbc
+DIST wine-1.3.0.tar.bz2 17764429 RMD160 6ce5c89179f211e74e19dfab57f5a999ca225369 SHA1 955c8cbf6fe85de179e9b6c8bea9940363166e51 SHA256 b4c6edb68a255be39013ff30c330d838e6143786f1fc13ccf9edfd52f0ac5510
+DIST wine_gecko-1.0.0-x86.cab 8119486 RMD160 57618dbffa7b7226dcd44f86c3c569ab8a5ff938 SHA1 afa22c52bca4ca77dcb9edb3c9936eb23793de01 SHA256 7ddf697677506fb164c52771864e32dd69a359ed855b2efbc51340de2376c99c
+DIST winepulse-0.35-configure.ac.patch 2826 RMD160 e419d43667be01af9b24a0e46822c41572a6ff9d SHA1 4943381128fd9555280884e2bb5867be4a8731d9 SHA256 837bffaaddb6b7b0a474c7262a57f12e250e135cf6228dde1a22849f66de1250
+DIST winepulse-0.36.patch 101815 RMD160 9a20076436a7e49c317bc624dd71b61c93acddff SHA1 aa6a4c9d4619f8452aad8c457c879769cab8f8fc SHA256 7508b171bfecb461ecb464426cb4bcd9c3ff77645b787fcbf61e27dd34fe1b05
+DIST winepulse-0.38-winecfg.patch 13088 RMD160 e7aa8f91c20b6d706fc12e11677440f19890f4c7 SHA1 55b785636d2982f19e0634b26eafffbe46b79c60 SHA256 051ef1cb5598c319152ad28b85733927a711b45e0bfa92f0b0b2331588f5894e
+EBUILD wine-1.3.0.ebuild 5610 RMD160 4eb50f43fd2dd04456309087b09e340000fda094 SHA1 793fa966a9f7308f04691bd531ff9b7b2b1f4b98 SHA256 9261699043b1db1e996bad178fb18345fa6521e88d7d9017ee9d573b41f34726
diff --git a/app-emulation/wine/files/wine-1.1.15-winegcc.patch b/app-emulation/wine/files/wine-1.1.15-winegcc.patch
new file mode 100644
index 0000000..6e5bb22
--- /dev/null
+++ b/app-emulation/wine/files/wine-1.1.15-winegcc.patch
@@ -0,0 +1,55 @@
+http://bugs.gentoo.org/260726
+
+--- wine-1.1.15/tools/winegcc/winegcc.c
++++ wine-1.1.15/tools/winegcc/winegcc.c
+@@ -215,10 +215,13 @@
+ strarray* files;
+ };
+
++#undef FORCE_POINTER_SIZE
+ #ifdef __i386__
+ static const enum target_cpu build_cpu = CPU_x86;
++#define FORCE_POINTER_SIZE
+ #elif defined(__x86_64__)
+ static const enum target_cpu build_cpu = CPU_x86_64;
++#define FORCE_POINTER_SIZE
+ #elif defined(__sparc__)
+ static const enum target_cpu build_cpu = CPU_SPARC;
+ #elif defined(__ALPHA__)
+@@ -968,6 +971,9 @@
+ opts.linker_args = strarray_alloc();
+ opts.compiler_args = strarray_alloc();
+ opts.winebuild_args = strarray_alloc();
++#ifdef FORCE_POINTER_SIZE
++ opts.force_pointer_size = sizeof(size_t);
++#endif
+
+ /* determine the processor type */
+ if (strendswith(argv[0], "winecpp")) opts.processor = proc_cpp;
+--- wine-1.1.15/tools/winebuild/main.c
++++ wine-1.1.15/tools/winebuild/main.c
+@@ -50,10 +50,13 @@
+ int link_ext_symbols = 0;
+ int force_pointer_size = 0;
+
++#undef FORCE_POINTER_SIZE
+ #ifdef __i386__
+ enum target_cpu target_cpu = CPU_x86;
++#define FORCE_POINTER_SIZE
+ #elif defined(__x86_64__)
+ enum target_cpu target_cpu = CPU_x86_64;
++#define FORCE_POINTER_SIZE
+ #elif defined(__sparc__)
+ enum target_cpu target_cpu = CPU_SPARC;
+ #elif defined(__ALPHA__)
+@@ -574,6 +577,10 @@
+ signal( SIGTERM, exit_on_signal );
+ signal( SIGINT, exit_on_signal );
+
++#ifdef FORCE_POINTER_SIZE
++ force_pointer_size = sizeof(size_t);
++#endif
++
+ output_file = stdout;
+ argv = parse_options( argc, argv, spec );
+
diff --git a/app-emulation/wine/files/wine-1.3.0-dib-engine.patch b/app-emulation/wine/files/wine-1.3.0-dib-engine.patch
new file mode 100644
index 0000000..9b3051c
--- /dev/null
+++ b/app-emulation/wine/files/wine-1.3.0-dib-engine.patch
@@ -0,0 +1,16184 @@
+diff -Nru a/configure.ac b/configure.ac
+--- a/configure.ac 2010-07-30 19:43:56.000000000 +0200
++++ b/configure.ac 2010-08-04 16:08:44.348222017 +0200
+@@ -2655,6 +2655,7 @@
+ WINE_CONFIG_DLL(winecoreaudio.drv)
+ WINE_CONFIG_LIB(winecrt0)
+ WINE_CONFIG_DLL(wined3d,,[wined3d])
++WINE_CONFIG_DLL(winedib.drv)
+ WINE_CONFIG_DLL(wineesd.drv)
+ WINE_CONFIG_DLL(winejack.drv)
+ WINE_CONFIG_DLL(winejoystick.drv)
+diff -Nru a/configure.ac.orig b/configure.ac.orig
+--- a/configure.ac.orig 1970-01-01 01:00:00.000000000 +0100
++++ b/configure.ac.orig 2010-07-30 19:43:56.000000000 +0200
+@@ -0,0 +1,2832 @@
++dnl Process this file with autoconf to produce a configure script.
++dnl Original author: Michael Patra
++dnl See ChangeLog file for detailed change history.
++
++m4_define(WINE_VERSION,regexp(m4_include(VERSION),[version \([-.0-9A-Za-z]+\)],[\1]))
++
++dnl autoconf versions before 2.59d don't handle multi-line subst variables correctly
++AC_PREREQ(2.59d)
++AC_INIT([Wine],[WINE_VERSION],[wine-devel@winehq.org],[wine],[http://www.winehq.org])
++AC_CONFIG_SRCDIR(server/atom.c)
++AC_CONFIG_HEADERS(include/config.h)
++AC_CONFIG_AUX_DIR(tools)
++
++dnl autoconf versions before 2.63b don't have AS_VAR_APPEND or AS_VAR_IF
++m4_ifdef([AS_VAR_APPEND],,[as_fn_append () { eval $[1]=\$$[1]\$[2]; }
++AC_DEFUN([AS_VAR_APPEND],[as_fn_append $1 $2])])dnl
++m4_ifdef([AS_VAR_IF],,[AC_DEFUN([AS_VAR_IF],
++[AS_LITERAL_IF([$1],
++ [AS_IF([test "x$$1" = x""$2], [$3], [$4])],
++ [eval as_val=\$$1
++ AS_IF([test "x$as_val" = x""$2], [$3], [$4])])])])dnl
++dnl autoconf versions before 2.64 don't have AC_PACKAGE_URL
++m4_ifdef([AC_PACKAGE_URL],,
++ [AC_DEFINE([PACKAGE_URL], ["http://www.winehq.org"], [Define to the home page for this package.])
++ AC_SUBST([PACKAGE_URL], ["http://www.winehq.org"])])dnl
++
++dnl **** Command-line arguments ****
++
++AC_ARG_ENABLE(win16, AS_HELP_STRING([--disable-win16],[do not include Win16 support]))
++AC_ARG_ENABLE(win64, AS_HELP_STRING([--enable-win64],[build a Win64 emulator on AMD64 (won't run Win32 binaries)]))
++AC_ARG_ENABLE(tests, AS_HELP_STRING([--disable-tests],[do not build the regression tests]))
++AC_ARG_ENABLE(maintainer-mode, AS_HELP_STRING([--enable-maintainer-mode],[enable maintainer-specific build rules]))
++
++AC_ARG_WITH(alsa, AS_HELP_STRING([--without-alsa],[do not use the Alsa sound support]),
++ [if test "x$withval" = "xno"; then ac_cv_header_sys_asoundlib_h=no; ac_cv_header_alsa_asoundlib_h=no; fi])
++AC_ARG_WITH(audioio, AS_HELP_STRING([--without-audioio],[do not use the AudioIO sound support]),
++ [if test "x$withval" = "xno"; then ac_cv_header_libaudioio_h=no; fi])
++AC_ARG_WITH(capi, AS_HELP_STRING([--without-capi],[do not use CAPI (ISDN support)]),
++ [if test "x$withval" = "xno"; then ac_cv_header_capi20_h=no; ac_cv_header_linux_capi_h=no; fi])
++AC_ARG_WITH(cms, AS_HELP_STRING([--without-cms],[do not use CMS (color management support)]),
++ [if test "x$withval" = "xno"; then ac_cv_header_lcms_h=no; ac_cv_header_lcms_lcms_h=no; fi])
++AC_ARG_WITH(coreaudio, AS_HELP_STRING([--without-coreaudio],[do not use the CoreAudio sound support]),
++ [if test "x$withval" = "xno"; then ac_cv_header_CoreAudio_CoreAudio_h=no; fi])
++AC_ARG_WITH(cups, AS_HELP_STRING([--without-cups],[do not use CUPS]))
++AC_ARG_WITH(curses, AS_HELP_STRING([--without-curses],[do not use (n)curses]),
++ [if test "x$withval" = "xno"; then ac_cv_header_ncurses_h=no; ac_cv_header_curses_h=no; fi])
++AC_ARG_WITH(esd, AS_HELP_STRING([--without-esd],[do not use the EsounD sound support]))
++AC_ARG_WITH(fontconfig,AS_HELP_STRING([--without-fontconfig],[do not use fontconfig]),
++ [if test "x$withval" = "xno"; then ac_cv_header_fontconfig_fontconfig_h=no; fi])
++AC_ARG_WITH(freetype, AS_HELP_STRING([--without-freetype],[do not use the FreeType library]))
++AC_ARG_WITH(gphoto, AS_HELP_STRING([--without-gphoto],[do not use gphoto (Digital Camera support)]))
++AC_ARG_WITH(glu, AS_HELP_STRING([--without-glu],[do not use the GLU library]),
++ [if test "x$withval" = "xno"; then ac_cv_header_GL_glu_h=no; fi])
++AC_ARG_WITH(gnutls, AS_HELP_STRING([--without-gnutls],[do not use GnuTLS (schannel support)]))
++AC_ARG_WITH(gsm, AS_HELP_STRING([--without-gsm],[do not use libgsm (GSM 06.10 codec support)]),
++ [if test "x$withval" = "xno"; then ac_cv_header_gsm_h=no; ac_cv_header_gsm_gsm_h=no; fi])
++AC_ARG_WITH(hal, AS_HELP_STRING([--without-hal],[do not use HAL (dynamic device support)]))
++AC_ARG_WITH(jack, AS_HELP_STRING([--without-jack],[do not use the Jack sound support]),
++ [if test "x$withval" = "xno"; then ac_cv_header_jack_jack_h=no; fi])
++AC_ARG_WITH(jpeg, AS_HELP_STRING([--without-jpeg],[do not use JPEG]),
++ [if test "x$withval" = "xno"; then ac_cv_header_jpeglib_h=no; fi])
++AC_ARG_WITH(ldap, AS_HELP_STRING([--without-ldap],[do not use LDAP]),
++ [if test "x$withval" = "xno"; then ac_cv_header_ldap_h=no; ac_cv_header_lber_h=no; fi])
++AC_ARG_WITH(mpg123, AS_HELP_STRING([--without-mpg123],[do not use the mpg123 library]),
++ [if test "x$withval" = "xno"; then ac_cv_header_mpg123_h=no; fi])
++AC_ARG_WITH(nas, AS_HELP_STRING([--without-nas],[do not use the NAS sound support]),
++ [if test "x$withval" = "xno"; then ac_cv_header_audio_audiolib_h=no; fi])
++AC_ARG_WITH(openal, AS_HELP_STRING([--without-openal],[do not use OpenAL]),
++ [if test "x$withval" = "xno"; then ac_cv_header_AL_al_h=no; ac_cv_header_OpenAL_al_h=no; fi])
++AC_ARG_WITH(opengl, AS_HELP_STRING([--without-opengl],[do not use OpenGL]))
++AC_ARG_WITH(openssl, AS_HELP_STRING([--without-openssl],[do not use OpenSSL]),
++ [if test "x$withval" = "xno"; then ac_cv_header_openssl_err_h=no; ac_cv_header_openssl_ssl_h=no; fi])
++AC_ARG_WITH(oss, AS_HELP_STRING([--without-oss],[do not use the OSS sound support]),
++ [if test "x$withval" = "xno"; then ac_cv_header_soundcard_h=no; ac_cv_header_sys_soundcard_h=no; ac_cv_header_machine_soundcard_h=no; fi])
++AC_ARG_WITH(png, AS_HELP_STRING([--without-png],[do not use PNG]),
++ [if test "x$withval" = "xno"; then ac_cv_header_png_h=no; fi])
++AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthread library]),
++ [if test "x$withval" = "xno"; then ac_cv_header_pthread_h=no; fi])
++AC_ARG_WITH(sane, AS_HELP_STRING([--without-sane],[do not use SANE (scanner support)]))
++AC_ARG_WITH(tiff, AS_HELP_STRING([--without-tiff],[do not use TIFF]),
++ [if test "x$withval" = "xno"; then ac_cv_header_tiffio_h=no; fi])
++AC_ARG_WITH(v4l, AS_HELP_STRING([--without-v4l],[do not use v4l1 (v4l support)]))
++AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]),
++ [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi])
++AC_ARG_WITH(xcursor, AS_HELP_STRING([--without-xcursor],[do not use the Xcursor extension]),
++ [if test "x$withval" = "xno"; then ac_cv_header_X11_Xcursor_Xcursor_h=no; fi])
++AC_ARG_WITH(xinerama, AS_HELP_STRING([--without-xinerama],[do not use Xinerama (multi-monitor support)]),
++ [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xinerama_h=no; fi])
++AC_ARG_WITH(xinput, AS_HELP_STRING([--without-xinput],[do not use the Xinput extension]),
++ [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_XInput_h=no; fi])
++AC_ARG_WITH(xml, AS_HELP_STRING([--without-xml],[do not use XML]))
++AC_ARG_WITH(xrandr, AS_HELP_STRING([--without-xrandr],[do not use Xrandr (resolution changes)]),
++ [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xrandr_h=no; fi])
++AC_ARG_WITH(xrender, AS_HELP_STRING([--without-xrender],[do not use the Xrender extension]),
++ [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xrender_h=no; fi])
++AC_ARG_WITH(xshape, AS_HELP_STRING([--without-xshape],[do not use the Xshape extension]),
++ [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_shape_h=no; fi])
++AC_ARG_WITH(xshm, AS_HELP_STRING([--without-xshm],[do not use XShm (shared memory extension)]),
++ [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_XShm_h=no; fi])
++AC_ARG_WITH(xslt, AS_HELP_STRING([--without-xslt],[do not use XSLT]))
++AC_ARG_WITH(xxf86vm, AS_HELP_STRING([--without-xxf86vm],[do not use XFree video mode extension]),
++ [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_xf86vmode_h=no; ac_cv_header_X11_extensions_xf86vmproto_h=no; fi])
++
++AC_ARG_WITH(wine-tools,AS_HELP_STRING([--with-wine-tools=DIR],[use Wine tools from directory DIR]))
++AC_ARG_WITH(wine64, AS_HELP_STRING([--with-wine64=DIR],[use the 64-bit Wine in DIR for a Wow64 build]))
++
++AC_CANONICAL_HOST
++
++dnl check for out of tree build with unclean source tree
++case "$srcdir" in
++ .) ;;
++ *) if test -f "$srcdir/Makefile" -o -f "$srcdir/include/config.h"; then
++ AC_MSG_ERROR([you are building out of the source tree, but the source tree contains object files.
++You need to run 'make distclean' in the source tree first.])
++ fi ;;
++esac
++
++dnl **** Check for some programs ****
++
++AC_PROG_MAKE_SET
++AC_PROG_CC
++AC_PROG_CXX
++dnl We can't use AC_PROG_CPP for winegcc, it uses by default $(CC) -E
++AC_CHECK_TOOL(CPPBIN,cpp,cpp)
++AC_DEFINE_UNQUOTED(EXEEXT,["$ac_exeext"],[Define to the file extension for executables.])
++
++case $host in
++ *-darwin*)
++ if test "x$enable_win64" = "xyes"
++ then
++ CC="$CC -m64"
++ CXX="$CXX -m64"
++ LD="${LD:-ld} -arch x86_64"
++ AS="${AS:-as} -arch x86_64"
++ host_cpu="x86_64"
++ notice_platform="64-bit "
++ AC_SUBST(TARGETFLAGS,"-m64")
++ else
++ CC="$CC -m32"
++ CXX="$CXX -m32"
++ LD="${LD:-ld} -arch i386"
++ AS="${AS:-as} -arch i386"
++ host_cpu="i386"
++ notice_platform="32-bit "
++ AC_SUBST(TARGETFLAGS,"-m32")
++ enable_win16=${enable_win16:-yes}
++ fi
++ ;;
++ x86_64*)
++ if test "x$enable_win64" != "xyes" -a "$cross_compiling" != "yes"
++ then
++ CC="$CC -m32"
++ CXX="$CXX -m32"
++ AC_MSG_CHECKING([whether $CC works])
++ AC_LINK_IFELSE(AC_LANG_PROGRAM(),AC_MSG_RESULT([yes]),
++ [AC_MSG_RESULT([no])
++ AC_MSG_ERROR([Cannot build a 32-bit program, you need to install 32-bit development libraries.])])
++ LD="${LD:-ld} -m elf_i386"
++ AS="${AS:-as} --32"
++ host_cpu="i386"
++ notice_platform="32-bit "
++ AC_SUBST(TARGETFLAGS,"-m32")
++ enable_win16=${enable_win16:-yes}
++ else
++ if test "x${GCC}" = "xyes"
++ then
++ AC_MSG_CHECKING([whether $CC supports __builtin_ms_va_list])
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>]], [[void func(__builtin_ms_va_list *args);]])],
++ [AC_MSG_RESULT([yes])],
++ [AC_MSG_RESULT([no])
++ AC_MSG_ERROR([You need gcc >= 4.4 to build Wine as 64-bit.])])
++ fi
++ AC_SUBST(TARGETFLAGS,"-m64")
++ fi
++ ;;
++ *-mingw32*|*-cygwin*)
++ enable_win16=${enable_win16:-no}
++ CFLAGS="$CFLAGS -D_WIN32"
++ ;;
++ i[[3456789]]86*)
++ enable_win16=${enable_win16:-yes}
++ ;;
++esac
++
++dnl enable_win16 defaults to yes on x86, to no on other CPUs
++enable_win16=${enable_win16:-no}
++
++dnl Disable winetest too if tests are disabled
++enable_winetest=${enable_winetest:-$enable_tests}
++
++dnl Some special cases for the wow64 build
++if test -n "$with_wine64"
++then
++ if test "x$enable_win64" = "xyes"
++ then
++ AC_MSG_ERROR([--enable-win64 and --with-wine64 are mutually exclusive.
++--enable-win64 should be used in the 64-bit build tree, --with-wine64 in the 32-bit Wow64 build tree.])
++ fi
++ AC_SUBST([WOW64_DISABLE],[\#])
++ enable_fonts=${enable_fonts:-no}
++ enable_server=${enable_server:-no}
++ enable_tools=${enable_tools:-no}
++elif test "x$enable_win64" = "xyes"
++then
++ test "x$libdir" != "x\${exec_prefix}/lib" || libdir="\${exec_prefix}/lib64"
++fi
++
++AC_CACHE_CHECK([for the directory containing the Wine tools], wine_cv_toolsdir,
++ [wine_cv_toolsdir="$with_wine_tools"
++ if test -z "$with_wine_tools"; then
++ if test "$cross_compiling" = "yes"; then
++ AC_MSG_ERROR([you must use the --with-wine-tools option when cross-compiling.])
++ elif test -n "$with_wine64"; then
++ wine_cv_toolsdir="$with_wine64"
++ fi
++ fi
++ if test -z "$wine_cv_toolsdir"; then
++ wine_cv_toolsdir="\$(TOPOBJDIR)"
++ elif test -d "$wine_cv_toolsdir/tools/winebuild"; then
++ case "$wine_cv_toolsdir" in
++ /*) ;;
++ *) wine_cv_toolsdir="\$(TOPOBJDIR)/$wine_cv_toolsdir" ;;
++ esac
++ else
++ AC_MSG_ERROR([could not find Wine tools in $wine_cv_toolsdir])
++ fi])
++AC_SUBST(TOOLSDIR,$wine_cv_toolsdir)
++if test -n "$host_alias" -a "$host_alias" != "$build_alias"
++then
++ AC_SUBST(TARGETFLAGS,"-b $host_alias $TARGETFLAGS")
++fi
++
++dnl Check for flex
++AC_CHECK_PROGS(FLEX,flex,none)
++if test "$FLEX" = "none"
++then
++ AC_MSG_ERROR([no suitable flex found. Please install the 'flex' package.])
++fi
++AC_MSG_CHECKING([whether flex is recent enough])
++cat >conftest.l <<EOF
++%top{
++#include "prediluvian.h"
++}
++%%
++EOF
++if $FLEX -t conftest.l >/dev/null 2>&AS_MESSAGE_LOG_FD
++then
++ AC_MSG_RESULT([yes])
++else
++ AC_MSG_RESULT([no])
++ AC_MSG_ERROR([Your flex version is too old. Please install flex version 2.5.33 or newer.])
++fi
++
++dnl Check for bison
++AC_CHECK_PROGS(BISON,bison,none)
++if test "$BISON" = "none"
++then
++ AC_MSG_ERROR([no suitable bison found. Please install the 'bison' package.])
++fi
++
++AC_CHECK_TOOLS(AR,[ar gar],ar)
++AC_SUBST(ARFLAGS,rc)
++AC_PROG_RANLIB
++AC_CHECK_TOOL(STRIP,strip,strip)
++AC_PROG_LN_S
++AC_PROG_EGREP
++AC_PATH_PROG(LDCONFIG, ldconfig, true, [/sbin /usr/sbin $PATH])
++AC_PROG_INSTALL
++dnl Prepend src dir to install path dir if it's a relative path
++case "$INSTALL" in
++ [[\\/$]]* | ?:[[\\/]]* ) ;;
++ *) INSTALL="\\\$(TOPSRCDIR)/$INSTALL" ;;
++esac
++
++dnl Check for lint
++AC_CHECK_PROGS(LINT, lclint lint)
++if test "$LINT" = "lint"
++then
++ LINTFLAGS="$LINTFLAGS -errchk=%all,no%longptr64 -errhdr=%user -Ncheck=macro -Nlevel=4"
++ dnl LINTFLAGS='-D_SIZE_T "-Dsize_t=unsigned long" -errchk=longptr64'
++fi
++AC_SUBST(LINT)
++AC_SUBST(LINTFLAGS)
++
++dnl Check for various programs
++AC_CHECK_PROGS(FONTFORGE, fontforge, false)
++AC_CHECK_PROGS(PKG_CONFIG, pkg-config, false)
++AC_CHECK_PROGS(RSVG, rsvg, false)
++AC_CHECK_PROGS(CONVERT, convert, false)
++AC_CHECK_PROGS(ICOTOOL, icotool, false)
++
++if test "x$enable_maintainer_mode" != "xyes"
++then
++ AC_SUBST([MAINTAINER_MODE],[\#])
++else
++ if test "$FONTFORGE" = "false"; then WINE_WARNING([fontforge is missing, fonts can't be rebuilt.]); fi
++ if test "$RSVG" = "false"; then WINE_WARNING([rsvg is missing, icons can't be rebuilt.]); fi
++
++ dnl Check the imagemagick version
++ if test "$CONVERT" = false
++ then
++ WINE_WARNING([imagemagick is missing, icons can't be rebuilt.])
++ else
++ AC_MSG_CHECKING([for recent enough imagemagick])
++ convert_version=`convert --version | head -n1`
++ if test "x$convert_version" != "x"
++ then
++ convert_version_major=`expr "$convert_version" : '.* \([[0-9]]*\)\.[[0-9]]*'`
++ convert_version_minor=`expr "$convert_version" : '.* [[0-9]]*\.\([[0-9]]*\)'`
++ if test "$convert_version_major" -eq 6 -a "$convert_version_minor" -lt 6
++ then
++ CONVERT=false
++ WINE_WARNING([imagemagick version 6.6 or newer is needed to rebuild icons.])
++ fi
++ fi
++ if test "$CONVERT" = false
++ then
++ AC_MSG_RESULT([no ($convert_version_major.$convert_version_minor)])
++ else
++ AC_MSG_RESULT([yes ($convert_version_major.$convert_version_minor)])
++ fi
++ fi
++
++ dnl Check the icotool version
++ if test "$ICOTOOL" = false
++ then
++ WINE_WARNING([icotool is missing, icons can't be rebuilt.])
++ else
++ AC_MSG_CHECKING([for recent enough icotool])
++ icotool_version=`icotool --version | head -n1`
++ if test "x$icotool_version" != "x"
++ then
++ icotool_version_major=`expr "$icotool_version" : '.* \([[0-9]]*\)\.[[0-9]]*'`
++ icotool_version_minor=`expr "$icotool_version" : '.* [[0-9]]*\.\([[0-9]]*\)'`
++ if test "$icotool_version_major" -eq 0 -a "$icotool_version_minor" -lt 29
++ then
++ ICOTOOL=false
++ WINE_WARNING([icotool version 0.29.0 or newer is needed to rebuild icons.])
++ fi
++ fi
++ if test "$ICOTOOL" = false
++ then
++ AC_MSG_RESULT([no ($icotool_version_major.$icotool_version_minor)])
++ else
++ AC_MSG_RESULT([yes ($icotool_version_major.$icotool_version_minor)])
++ fi
++ fi
++
++fi
++
++case $host_cpu in
++ *i[[3456789]]86*)
++ AC_PATH_PROG(PRELINK, prelink, false, [/sbin /usr/sbin $PATH])
++ ;;
++esac
++
++dnl **** Check for some libraries ****
++
++dnl Check for -li386 for NetBSD and OpenBSD
++AC_CHECK_LIB(i386,i386_set_ldt)
++dnl Check for -lossaudio for NetBSD
++AC_CHECK_LIB(ossaudio,_oss_ioctl)
++
++AC_SUBST(XLIB,"")
++AC_SUBST(OPENGL_LIBS,"")
++
++dnl **** Check for header files ****
++
++AC_SYS_LARGEFILE()
++
++AC_CHECK_HEADERS(\
++ AL/al.h \
++ AudioToolbox/AudioConverter.h \
++ AudioUnit/AudioUnit.h \
++ Carbon/Carbon.h \
++ CoreAudio/CoreAudio.h \
++ DiskArbitration/DiskArbitration.h \
++ IOKit/IOKitLib.h \
++ IOKit/hid/IOHIDLib.h \
++ OpenAL/al.h \
++ alias.h \
++ alsa/asoundlib.h \
++ arpa/inet.h \
++ arpa/nameser.h \
++ asm/types.h \
++ capi20.h \
++ curses.h \
++ direct.h \
++ dirent.h \
++ dlfcn.h \
++ elf.h \
++ float.h \
++ fnmatch.h \
++ fontconfig/fontconfig.h \
++ getopt.h \
++ grp.h \
++ gsm.h \
++ gsm/gsm.h \
++ ieeefp.h \
++ inet/mib2.h \
++ io.h \
++ jack/jack.h \
++ jpeglib.h \
++ kstat.h \
++ lber.h \
++ lcms.h \
++ lcms/lcms.h \
++ ldap.h \
++ libaudioio.h \
++ link.h \
++ linux/cdrom.h \
++ linux/compiler.h \
++ linux/hdreg.h \
++ linux/input.h \
++ linux/ioctl.h \
++ linux/joystick.h \
++ linux/major.h \
++ linux/param.h \
++ linux/serial.h \
++ linux/types.h \
++ linux/ucdrom.h \
++ mach-o/nlist.h \
++ mach/mach.h \
++ mach/machine.h \
++ machine/cpu.h \
++ machine/limits.h \
++ machine/soundcard.h \
++ machine/sysarch.h \
++ mntent.h \
++ mpg123.h \
++ ncurses.h \
++ netdb.h \
++ netinet/in.h \
++ netinet/in_systm.h \
++ netinet/tcp.h \
++ netinet/tcp_fsm.h \
++ openssl/err.h \
++ openssl/ssl.h \
++ png.h \
++ poll.h \
++ port.h \
++ process.h \
++ pthread.h \
++ pwd.h \
++ regex.h \
++ sched.h \
++ scsi/scsi.h \
++ scsi/scsi_ioctl.h \
++ scsi/sg.h \
++ soundcard.h \
++ stdbool.h \
++ stdint.h \
++ strings.h \
++ stropts.h \
++ sys/asoundlib.h \
++ sys/cdio.h \
++ sys/elf32.h \
++ sys/epoll.h \
++ sys/errno.h \
++ sys/event.h \
++ sys/exec_elf.h \
++ sys/filio.h \
++ sys/inotify.h \
++ sys/ioctl.h \
++ sys/ipc.h \
++ sys/limits.h \
++ sys/link.h \
++ sys/mman.h \
++ sys/modem.h \
++ sys/msg.h \
++ sys/mtio.h \
++ sys/param.h \
++ sys/poll.h \
++ sys/prctl.h \
++ sys/protosw.h \
++ sys/ptrace.h \
++ sys/resource.h \
++ sys/scsiio.h \
++ sys/shm.h \
++ sys/signal.h \
++ sys/socket.h \
++ sys/socketvar.h \
++ sys/sockio.h \
++ sys/soundcard.h \
++ sys/statvfs.h \
++ sys/strtio.h \
++ sys/syscall.h \
++ sys/tihdr.h \
++ sys/time.h \
++ sys/timeout.h \
++ sys/times.h \
++ sys/uio.h \
++ sys/un.h \
++ sys/utsname.h \
++ sys/vm86.h \
++ sys/wait.h \
++ syscall.h \
++ termios.h \
++ tiffio.h \
++ unistd.h \
++ utime.h \
++ valgrind/memcheck.h \
++ valgrind/valgrind.h \
++ zlib.h
++)
++AC_HEADER_STAT()
++
++dnl **** Checks for headers that depend on other ones ****
++
++AC_CHECK_HEADERS([sys/mount.h sys/statfs.h sys/sysctl.h sys/user.h sys/vfs.h],,,
++ [#include <sys/types.h>
++ #ifdef HAVE_SYS_PARAM_H
++ # include <sys/param.h>
++ #endif])
++
++AC_CHECK_HEADERS(\
++ netinet/ip.h \
++ net/if.h \
++ net/if_arp.h \
++ net/if_dl.h \
++ net/if_types.h \
++ net/route.h \
++ netinet/if_ether.h \
++ netinet/if_inarp.h \
++ netinet/in_pcb.h \
++ netinet/ip_icmp.h \
++ netinet/ip_var.h \
++ netinet/udp.h \
++ netipx/ipx.h \
++,,,[#include <sys/types.h>
++ #ifdef HAVE_SYS_SOCKET_H
++ # include <sys/socket.h>
++ #endif
++ #ifdef HAVE_SYS_SOCKETVAR_H
++ # include <sys/socketvar.h>
++ #endif
++ #ifdef HAVE_NET_ROUTE_H
++ # include <net/route.h>
++ #endif
++ #ifdef HAVE_NETINET_IN_H
++ # include <netinet/in.h>
++ #endif
++ #ifdef HAVE_NETINET_IN_SYSTM_H
++ # include <netinet/in_systm.h>
++ #endif
++ #ifdef HAVE_NET_IF_H
++ # include <net/if.h>
++ #endif
++ #ifdef HAVE_NETINET_IP_H
++ # include <netinet/ip.h>
++ #endif])
++
++AC_CHECK_HEADERS([netinet/tcp_timer.h netinet/udp_var.h netinet/icmp_var.h netinet/tcp_var.h ],,,
++ [#include <sys/types.h>
++ #ifdef HAVE_ALIAS_H
++ # include <alias.h>
++ #endif
++ #ifdef HAVE_SYS_SOCKET_H
++ # include <sys/socket.h>
++ #endif
++ #ifdef HAVE_SYS_SOCKETVAR_H
++ # include <sys/socketvar.h>
++ #endif
++ #ifdef HAVE_SYS_TIMEOUT_H
++ # include <sys/timeout.h>
++ #endif
++ #ifdef HAVE_NETINET_IN_H
++ # include <netinet/in.h>
++ #endif
++ #ifdef HAVE_NETINET_IN_SYSTM_H
++ # include <netinet/in_systm.h>
++ #endif
++ #ifdef HAVE_NETINET_IP_H
++ # include <netinet/ip.h>
++ #endif
++ #ifdef HAVE_NETINET_IP_VAR_H
++ # include <netinet/ip_var.h>
++ #endif
++ #ifdef HAVE_NETINET_IP_ICMP_H
++ # include <netinet/ip_icmp.h>
++ #endif
++ #ifdef HAVE_NETINET_UDP_H
++ # include <netinet/udp.h>
++ #endif
++ #ifdef HAVE_NETINET_TCP_H
++ # include <netinet/tcp.h>
++ #endif
++ #ifdef HAVE_NETINET_TCP_TIMER_H
++ #include <netinet/tcp_timer.h>
++ #endif])
++
++AC_CHECK_HEADERS([linux/ipx.h linux/irda.h],,,
++ [#include <sys/types.h>
++ #ifdef HAVE_ASM_TYPES_H
++ # include <asm/types.h>
++ #endif
++ #ifdef HAVE_SYS_SOCKET_H
++ # include <sys/socket.h>
++ #endif
++ #ifdef HAVE_LINUX_TYPES_H
++ # include <linux/types.h>
++ #endif])
++
++AC_CHECK_HEADERS([mach-o/dyld_images.h],,,
++ [#ifdef HAVE_STDBOOL_H
++ # include <stdbool.h>
++ #endif
++ #ifdef HAVE_STDINT_H
++ # include <stdint.h>
++ #endif])
++
++AC_CHECK_HEADERS([resolv.h],,,
++ [#include <sys/types.h>
++ #ifdef HAVE_SYS_SOCKET_H
++ # include <sys/socket.h>
++ #endif
++ #ifdef HAVE_NETINET_IN_H
++ # include <netinet/in.h>
++ #endif
++ #ifdef HAVE_ARPA_NAMESER_H
++ # include <arpa/nameser.h>
++ #endif])
++
++AC_CHECK_HEADERS([ifaddrs.h],,,[#include <sys/types.h>])
++
++AC_CHECK_HEADERS(ucontext.h,,,[#include <signal.h>])
++
++AC_CHECK_HEADERS([sys/thr.h],,,
++[#include <sys/types.h>
++#ifdef HAVE_UCONTEXT_H
++#include <ucontext.h>
++#endif])
++
++AC_CHECK_HEADERS([pthread_np.h],,,
++[#ifdef HAVE_PTHREAD_H
++#include <pthread.h>
++#endif])
++
++AC_CHECK_HEADERS([linux/videodev.h],,,
++[#ifdef HAVE_SYS_TIME_H
++#include <sys/time.h>
++#endif
++#include <sys/types.h>
++#ifdef HAVE_ASM_TYPES_H
++#include <asm/types.h>
++#endif])
++
++dnl Check for broken kernel header that doesn't define __user
++AC_CHECK_HEADERS([linux/capi.h],,,[#define __user])
++
++dnl **** Check for working dll ****
++
++AC_SUBST(DLLEXT,"")
++AC_SUBST(DLLFLAGS,"-D_REENTRANT")
++AC_SUBST(LDSHARED,"")
++AC_SUBST(LDDLLFLAGS,"")
++AC_SUBST(LIBEXT,"so")
++AC_SUBST(IMPLIBEXT,"def")
++AC_SUBST(LDRPATH_INSTALL,"")
++AC_SUBST(LDRPATH_LOCAL,"")
++STATIC_IMPLIBEXT="def.a"
++WINE_PATH_LDD
++
++case $host_os in
++ cygwin*|mingw32*)
++ AC_CHECK_TOOL(DLLTOOL,dlltool,false)
++ AC_CHECK_TOOL(DLLWRAP,dllwrap,false)
++ if test "$DLLWRAP" = "false"; then
++ LIBEXT="a"
++ else
++ dnl FIXME - check whether dllwrap works correctly...
++ LIBEXT="dll"
++ fi
++ IMPLIBEXT="a"
++ STATIC_IMPLIBEXT="a"
++ dnl Disable modules that can't be used on Windows
++ enable_iphlpapi=${enable_iphlpapi:-no}
++ enable_kernel32=${enable_kernel32:-no}
++ enable_msvcrt=${enable_msvcrt:-no}
++ enable_ntdll=${enable_ntdll:-no}
++ enable_ws2_32=${enable_ws2_32:-no}
++ enable_loader=${enable_loader:-no}
++ enable_server=${enable_server:-no}
++ dnl Disable dependencies that are not useful on Windows
++ with_x=${with_x:-no}
++ with_pthread=${with_pthread:-no}
++ ;;
++ darwin*|macosx*)
++ DLLEXT=".so"
++ LIBEXT="dylib"
++ DLLFLAGS="$DLLFLAGS -fPIC"
++ LDDLLFLAGS="-bundle -multiply_defined suppress"
++ LIBWINE_LDFLAGS="-multiply_defined suppress"
++ LDSHARED="\$(CC) -dynamiclib"
++ STRIP="$STRIP -x"
++ LDRPATH_LOCAL="&& install_name_tool -change @executable_path/\`\$(RELPATH) \$(bindir) \$(libdir)\`/libwine.1.dylib @executable_path/\$(TOPOBJDIR)/libs/wine/libwine.1.dylib \$@ || \$(RM) \$@"
++ dnl declare needed frameworks
++ AC_SUBST(SECURITYLIB,"-framework Security -framework CoreFoundation")
++ AC_SUBST(COREFOUNDATIONLIB,"-framework CoreFoundation")
++ AC_SUBST(IOKITLIB,"-framework IOKit -framework CoreFoundation")
++ AC_SUBST(LDEXECFLAGS,["-image_base 0x7bf00000 -Wl,-segaddr,WINE_DOS,0x00000000,-segaddr,WINE_SHAREDHEAP,0x7f000000"])
++ if test "$ac_cv_header_DiskArbitration_DiskArbitration_h" = "yes"
++ then
++ dnl DiskArbitration API is not public on Darwin < 8.0, use it only if header found
++ AC_SUBST(DISKARBITRATIONLIB,"-framework DiskArbitration -framework CoreFoundation")
++ fi
++ if test "$ac_cv_header_CoreAudio_CoreAudio_h" = "yes" -a "$ac_cv_header_AudioUnit_AudioUnit_h" = "yes"
++ then
++ dnl CoreServices needed by AudioUnit
++ AC_SUBST(COREAUDIO,"-framework CoreAudio -framework AudioUnit -framework CoreServices -framework AudioToolbox -framework CoreMIDI")
++ fi
++ if test "$ac_cv_header_OpenAL_al_h" = "yes"
++ then
++ AC_SUBST(FRAMEWORK_OPENAL,"-framework OpenAL")
++ AC_DEFINE_UNQUOTED(HAVE_OPENAL,1,[Define to 1 if OpenAL is available])
++ ac_cv_lib_openal=yes
++ fi
++ if test "$ac_cv_header_IOKit_hid_IOHIDLib_h" = "yes"
++ then
++ ac_save_LIBS="$LIBS"
++ LIBS="$LIBS $IOKITLIB"
++ AC_CHECK_FUNCS(IOHIDManagerCreate)
++ LIBS="$ac_save_LIBS"
++ fi
++ case $host_cpu in
++ *powerpc*)
++ LDDLLFLAGS="$LDDLLFLAGS -read_only_relocs warning" dnl FIXME
++ ;;
++ esac
++ dnl Enable quartz driver on Mac OS X
++ if test "$ac_cv_header_Carbon_Carbon_h" = "yes"
++ then
++ AC_SUBST(CARBONLIB,"-framework Carbon")
++ enable_winequartz_drv=${enable_winequartz_drv:-yes}
++ fi
++ dnl Check for Xcode 3.x broken 16-bit support
++ if test "x$enable_win16" = "xyes"
++ then
++ AC_MSG_CHECKING([whether 16-bit code can be built correctly])
++ AC_RUN_IFELSE(AC_LANG_PROGRAM([[asm(".text\n"
++ "bad:\tnop;nop\n"
++ "good:\tnop;nop\n\t"
++ ".globl _testfunc\n"
++ "_testfunc:\tcallw good");
++ extern void testfunc();]],
++ [[unsigned short *p = (unsigned short *)testfunc;
++ return p[[0]] != 0xe866 || p[[1]] != 0xfffa]]),
++ AC_MSG_RESULT(yes),
++ [AC_MSG_RESULT(no)
++ AC_MSG_ERROR([Xcode 3.x cannot build 16-bit code correctly. Use --disable-win16 if you don't need 16-bit support.])],
++ AC_MSG_RESULT([[cross-compiling, assuming yes]]))
++ fi
++ ;;
++ *)
++ DLLFLAGS="$DLLFLAGS -fPIC"
++ DLLEXT=".so"
++ AC_CACHE_CHECK([whether we can build a GNU style ELF dll], ac_cv_c_dll_gnuelf,
++ [WINE_TRY_SHLIB_FLAGS([-fPIC -shared -Wl,-Bsymbolic],
++ ac_cv_c_dll_gnuelf="yes",ac_cv_c_dll_gnuelf="no")])
++ if test "$ac_cv_c_dll_gnuelf" = "yes"
++ then
++ LDSHARED="\$(CC) -shared"
++ LDDLLFLAGS="-shared -Wl,-Bsymbolic"
++ WINE_TRY_CFLAGS([-fPIC -shared -Wl,-soname,confest.so.1],
++ [LDSHARED="\$(CC) -shared \$(SONAME:%=-Wl,-soname,%)"],
++ [WINE_TRY_CFLAGS([-fPIC -shared -Wl,-h,confest.so.1],
++ [LDSHARED="\$(CC) -shared \$(SONAME:%=-Wl,-h,%)"])])
++
++ WINE_TRY_CFLAGS([-fPIC -shared -Wl,-Bsymbolic,-z,defs], [LDDLLFLAGS="$LDDLLFLAGS,-z,defs"])
++
++ WINE_TRY_CFLAGS([-fPIC -shared -Wl,-Bsymbolic,-init,__wine_spec_init,-fini,__wine_spec_fini],
++ [LDDLLFLAGS="$LDDLLFLAGS,-init,__wine_spec_init,-fini,__wine_spec_fini"])
++
++ echo '{ global: *; };' >conftest.map
++ WINE_TRY_CFLAGS([-fPIC -shared -Wl,--version-script=conftest.map],
++ [LDSHARED="$LDSHARED \$(VERSCRIPT:%=-Wl,--version-script=%)"])
++ rm -f conftest.map
++
++ WINE_TRY_CFLAGS([-fPIC -Wl,--export-dynamic],
++ [AC_SUBST(LDEXECFLAGS,["-Wl,--export-dynamic"])])
++
++ WINE_TRY_CFLAGS([-fPIC -Wl,--rpath,\$ORIGIN/../lib],
++ [LDRPATH_INSTALL="-Wl,--rpath,\\\$\$ORIGIN/\`\$(RELPATH) \$(bindir) \$(libdir)\`"
++ LDRPATH_LOCAL="-Wl,--rpath,\\\$\$ORIGIN/\$(TOPOBJDIR)/libs/wine"],
++ [WINE_TRY_CFLAGS([-fPIC -Wl,-R,\$ORIGIN/../lib],
++ [LDRPATH_INSTALL="-Wl,-R,\\\$\$ORIGIN/\`\$(RELPATH) \$(bindir) \$(libdir)\`"
++ LDRPATH_LOCAL="-Wl,-R,\\\$\$ORIGIN/\$(TOPOBJDIR)/libs/wine"])])
++
++ WINE_TRY_CFLAGS([-Wl,--enable-new-dtags],
++ [LDRPATH_INSTALL="$LDRPATH_INSTALL -Wl,--enable-new-dtags"])
++
++ case $host_cpu in
++ *i[[3456789]]86* | x86_64)
++ WINE_TRY_CFLAGS([-Wl,--section-start,.interp=0x7bf00400],
++ [LDEXECFLAGS="$LDEXECFLAGS -Wl,--section-start,.interp=0x7bf00400"])
++ ;;
++ esac
++
++ else
++ AC_CACHE_CHECK(whether we can build a UnixWare (Solaris) dll, ac_cv_c_dll_unixware,
++ [WINE_TRY_SHLIB_FLAGS([-fPIC -Wl,-G,-h,conftest.so.1.0,-B,symbolic],
++ ac_cv_c_dll_unixware="yes",ac_cv_c_dll_unixware="no")])
++ if test "$ac_cv_c_dll_unixware" = "yes"
++ then
++ LDSHARED="\$(CC) -Wl,-G \$(SONAME:%=-Wl,-h,%)"
++ LDDLLFLAGS="-Wl,-G,-B,symbolic"
++
++ else
++ AC_CACHE_CHECK(whether we can build an HP-UX dll, ac_cv_c_dll_hpux,
++ [WINE_TRY_SHLIB_FLAGS([-shared], ac_cv_c_dll_hpux="yes", ac_cv_c_dll_hpux="no")])
++ if test "$ac_cv_c_dll_hpux" = "yes"
++ then
++ LIBEXT="sl"
++ DLLEXT=".sl"
++ LDDLLFLAGS="-shared -fPIC"
++ LDSHARED="\$(CC) -shared"
++ fi
++ fi
++ fi
++ ;;
++esac
++
++enable_winequartz_drv=${enable_winequartz_drv:-no}
++
++if test "$LIBEXT" = "a"; then
++ AC_MSG_ERROR(
++[could not find a way to build shared libraries.
++It is currently not possible to build Wine without shared library
++(.so) support to allow transparent switch between .so and .dll files.
++If you are using Linux, you will need a newer binutils.]
++)
++fi
++
++dnl Check for cross compiler to build test programs
++AC_SUBST([CROSSTEST_DISABLE],[\#])
++if test "$cross_compiling" = "no" -a "x$enable_tests" != xno -a "$LIBEXT" != "dll"
++then
++ WINE_CHECK_MINGW_PROG(CROSSCC,gcc,false)
++ if test "$CROSSCC" != "false"
++ then
++ CROSSTEST_DISABLE=""
++ set x $CROSSCC
++ shift
++ target=""
++ while test $# -ge 1
++ do
++ case "$1" in
++ *-gcc) target=`expr "$1" : '\(.*\)-gcc'` ;;
++ esac
++ shift
++ done
++ if test -n "$target"
++ then
++ AC_SUBST(CROSSTARGET,"$target")
++ fi
++ fi
++fi
++
++dnl **** Check for pthread ****
++
++if test "$ac_cv_header_pthread_h" = "yes"
++then
++ AC_CHECK_LIB(pthread,pthread_create,[AC_SUBST(LIBPTHREAD,"-lpthread")])
++fi
++WINE_ERROR_WITH(pthread,[test "x$LIBPTHREAD" = "x"],[pthread ${notice_platform}development files not found.
++Wine cannot support threads without libpthread.])
++
++dnl **** Check for X11 ****
++
++AC_PATH_XTRA
++
++if test "$have_x" = "yes"
++then
++ XLIB="-lX11"
++ ac_save_CPPFLAGS="$CPPFLAGS"
++ CPPFLAGS="$CPPFLAGS $X_CFLAGS"
++
++ WINE_CHECK_SONAME(X11,XCreateWindow,,,[$X_LIBS $X_EXTRA_LIBS])
++ WINE_CHECK_SONAME(Xext,XextCreateExtension,[XLIB="-lXext $XLIB"],,[$X_LIBS -lX11 $X_EXTRA_LIBS])
++
++ dnl *** All of the following tests require X11/Xlib.h
++ AC_CHECK_HEADERS([X11/Xlib.h \
++ X11/XKBlib.h \
++ X11/Xutil.h \
++ X11/Xcursor/Xcursor.h \
++ X11/extensions/shape.h \
++ X11/extensions/XInput.h \
++ X11/extensions/XShm.h \
++ X11/extensions/Xcomposite.h \
++ X11/extensions/Xinerama.h \
++ X11/extensions/Xrandr.h \
++ X11/extensions/Xrender.h \
++ X11/extensions/xf86vmode.h \
++ X11/extensions/xf86vmproto.h],,,
++[#ifdef HAVE_X11_XLIB_H
++# include <X11/Xlib.h>
++#endif
++#ifdef HAVE_X11_XUTIL_H
++# include <X11/Xutil.h>
++#endif])
++
++ dnl *** Check for X keyboard extension
++ if test "$ac_cv_header_X11_XKBlib_h" = "yes"
++ then
++ AC_CHECK_LIB(X11, XkbQueryExtension,
++ AC_DEFINE(HAVE_XKB, 1, [Define if you have the XKB extension]),,
++ $X_LIBS $XLIB $X_EXTRA_LIBS)
++ fi
++
++ dnl *** Check for X cursor
++ if test "$ac_cv_header_X11_Xcursor_Xcursor_h" = "yes"
++ then
++ WINE_CHECK_SONAME(Xcursor,XcursorImageLoadCursor,,,[$X_LIBS $XLIB $X_EXTRA_LIBS])
++ fi
++ WINE_NOTICE_WITH(xcursor,[test "x$ac_cv_lib_soname_Xcursor" = "x"],
++ [libxcursor ${notice_platform}development files not found, the Xcursor extension won't be supported.])
++
++ dnl *** Check for X input extension
++ if test "$ac_cv_header_X11_extensions_XInput_h" = "yes"
++ then
++ WINE_CHECK_SONAME(Xi,XOpenDevice,,,[$X_LIBS $XLIB $X_EXTRA_LIBS])
++ fi
++ WINE_NOTICE_WITH(xinput,[test "x$ac_cv_lib_soname_Xi" = "x"],
++ [libxi ${notice_platform}development files not found, the Xinput extension won't be supported.])
++
++ dnl *** Check for X Shm extension
++ if test "$ac_cv_header_X11_extensions_XShm_h" = "yes"
++ then
++ AC_CHECK_LIB(Xext, XShmQueryExtension,
++ AC_DEFINE(HAVE_LIBXXSHM, 1, [Define if you have the X Shm extension]),,
++ $X_LIBS $XLIB $X_EXTRA_LIBS)
++ fi
++ WINE_NOTICE_WITH(xshm,[test "$ac_cv_lib_Xext_XShmQueryExtension" != "yes"],
++ [XShm ${notice_platform}development files not found, X Shared Memory won't be supported.])
++
++ dnl *** Check for X shape extension
++ if test "$ac_cv_header_X11_extensions_shape_h" = "yes"
++ then
++ AC_CHECK_LIB(Xext,XShapeQueryExtension,
++ AC_DEFINE(HAVE_LIBXSHAPE, 1, [Define if you have the X Shape extension]),,
++ $X_LIBS $XLIB $X_EXTRA_LIBS)
++ fi
++ WINE_NOTICE_WITH(xshape,[test "$ac_cv_lib_Xext_XShapeQueryExtension" != "yes"],
++ [XShape ${notice_platform}development files not found, XShape won't be supported.])
++
++ dnl *** Check for XFree86 VMODE extension
++ if test "$ac_cv_header_X11_extensions_xf86vmode_h" = "yes" -o "$ac_cv_header_X11_extensions_xf86vmproto_h" = "yes"
++ then
++ WINE_CHECK_SONAME(Xxf86vm,XF86VidModeQueryExtension,,,[$X_LIBS $XLIB $X_EXTRA_LIBS])
++ fi
++ WINE_NOTICE_WITH(xxf86vm,[test "x$ac_cv_lib_soname_Xxf86vm" = "x"],
++ [libXxf86vm ${notice_platform}development files not found, XFree86 Vidmode won't be supported.])
++
++ dnl *** Check for Transform functions in Xrender
++ if test "$ac_cv_header_X11_extensions_Xrender_h" = "yes" -a "x$ac_cv_lib_soname_X11" != "x" -a "x$ac_cv_lib_soname_Xext" != "x"
++ then
++ WINE_CHECK_SONAME(Xrender,XRenderQueryExtension,
++ [AC_CHECK_LIB(Xrender,XRenderSetPictureTransform,
++ [AC_DEFINE(HAVE_XRENDERSETPICTURETRANSFORM, 1,
++ [Define if Xrender has the XRenderSetPictureTransform function])],,
++ [$X_LIBS $XLIB $X_EXTRA_LIBS])],,[$X_LIBS $XLIB $X_EXTRA_LIBS])
++
++ fi
++ WINE_WARNING_WITH(xrender,[test "x$ac_cv_lib_soname_Xrender" = "x"],
++ [libxrender ${notice_platform}development files not found, XRender won't be supported.])
++
++ dnl *** Check for X RandR extension
++ if test "$ac_cv_header_X11_extensions_Xrandr_h" = "yes" -a "x$ac_cv_lib_soname_Xrender" != "x"
++ then
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <X11/Xlib.h>
++#include <X11/extensions/Xrandr.h>]], [[static typeof(XRRSetScreenConfigAndRate) * func;]])],
++ [WINE_CHECK_SONAME(Xrandr,XRRQueryExtension,,,[$X_LIBS $XLIB $X_EXTRA_LIBS])])
++ fi
++ WINE_NOTICE_WITH(xrandr,[test "x$ac_cv_lib_soname_Xrandr" = "x"],
++ [libxrandr ${notice_platform}development files not found, XRandr won't be supported.])
++
++ dnl *** Check for Xinerama extension
++ if test "$ac_cv_header_X11_extensions_Xinerama_h" = "yes"
++ then
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <X11/Xlib.h>
++#include <X11/extensions/Xinerama.h>]], [[static typeof(XineramaQueryScreens) * func;]])],
++ [WINE_CHECK_SONAME(Xinerama,XineramaQueryScreens,,,[$X_LIBS $XLIB $X_EXTRA_LIBS])])
++ fi
++ WINE_NOTICE_WITH(xinerama,[test "x$ac_cv_lib_soname_Xinerama" = "x"],
++ [libxinerama ${notice_platform}development files not found, multi-monitor setups won't be supported.])
++
++ dnl *** Check for X Composite extension
++ if test "$ac_cv_header_X11_extensions_Xcomposite_h" = "yes"
++ then
++ WINE_CHECK_SONAME(Xcomposite,XCompositeRedirectWindow,,,[$X_LIBS $XLIB $X_EXTRA_LIBS])
++ fi
++ WINE_NOTICE_WITH(xcomposite,[test "x$ac_cv_lib_soname_Xcomposite" = "x"],
++ [libxcomposite ${notice_platform}development files not found, Xcomposite won't be supported.])
++
++ dnl *** Check for XICCallback struct
++ AC_CHECK_MEMBERS([XICCallback.callback],,,
++[#ifdef HAVE_X11_XLIB_H
++#include <X11/Xlib.h>
++#endif])
++
++ dnl *** End of X11/Xlib.h check
++
++ dnl Check for the presence of OpenGL
++ opengl_msg=""
++ if test "x$with_opengl" != "xno"
++ then
++ AC_CHECK_HEADERS(GL/gl.h GL/glx.h GL/glu.h,,,
++[#ifdef HAVE_GL_GLX_H
++# include <GL/glx.h>
++#endif])
++ if test "$ac_cv_header_GL_gl_h" = "yes" -a "$ac_cv_header_GL_glx_h" = "yes"
++ then
++ dnl Check for some problems due to old Mesa versions
++ AC_CACHE_CHECK([for up-to-date OpenGL version], wine_cv_opengl_header_version_OK,
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <GL/gl.h>]], [[GLenum test = GL_UNSIGNED_SHORT_5_6_5;]])],
++ [wine_cv_opengl_header_version_OK="yes"],
++ [wine_cv_opengl_header_version_OK="no"]))
++
++ if test "$wine_cv_opengl_header_version_OK" = "yes"
++ then
++ dnl Check for the presence of the library
++ WINE_CHECK_SONAME(GL,glXCreateContext,
++ [OPENGL_LIBS="-lGL"
++ AC_DEFINE(HAVE_OPENGL, 1, [Define if OpenGL is present on the system])],
++ [WINE_CHECK_SONAME(GL,glXCreateContext,
++ [OPENGL_LIBS="-Xlinker -dylib_file -Xlinker /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib -lGL"
++ AC_DEFINE(HAVE_OPENGL, 1, [Define if OpenGL is present on the system])],
++ [if test -f /usr/X11R6/lib/libGL.a
++ then
++ opengl_msg="/usr/X11R6/lib/libGL.a is present on your system.
++This probably prevents linking to OpenGL. Try deleting the file and restarting configure."
++ else
++ opengl_msg="No OpenGL library found on this system."
++ fi],
++ $X_LIBS $XLIB -lm $X_EXTRA_LIBS -dylib_file /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib)],
++ $X_LIBS $XLIB -lm $X_EXTRA_LIBS)
++ if test "$ac_cv_header_GL_glu_h" = "yes"
++ then
++ WINE_CHECK_SONAME(GLU,gluLookAt,,,[$OPENGL_LIBS $X_LIBS $X_PRE_LIBS $XLIB -lm $X_EXTRA_LIBS])
++ fi
++ WINE_NOTICE_WITH(glu,[test "x$ac_cv_lib_soname_GLU" = "x"],
++ [libGLU ${notice_platform}development files not found, GLU won't be supported.])
++ else
++ opengl_msg="Old Mesa headers detected. Consider upgrading your Mesa libraries."
++ fi
++ else
++ opengl_msg="OpenGL development headers not found."
++ fi
++ test -n "$opengl_msg" && enable_opengl32=${enable_opengl32:-no}
++ test "x$ac_cv_lib_soname_GLU" = "x" && enable_glu32=${enable_glu32:-no}
++ else
++ enable_opengl32=${enable_opengl32:-no}
++ enable_glu32=${enable_glu32:-no}
++ fi
++ WINE_WARNING_WITH(opengl,[test -n "$opengl_msg"],[$opengl_msg
++OpenGL and Direct3D won't be supported.])
++
++ dnl **** Check for NAS ****
++ AC_SUBST(NASLIBS,"")
++ AC_CHECK_HEADERS(audio/audiolib.h,
++ [AC_CHECK_HEADERS(audio/soundlib.h,,,[#include <audio/audiolib.h>])
++ AC_CHECK_LIB(audio,AuCreateFlow,
++ [AC_DEFINE(HAVE_NAS,1,[Define if you have NAS including devel headers])
++ AC_CHECK_LIB(Xau,XauGetBestAuthByAddr,
++ [NASLIBS="-lXau -laudio -lXt $X_LIBS $XLIB $X_EXTRA_LIBS"],
++ [NASLIBS="-laudio -lXt $X_LIBS $XLIB $X_EXTRA_LIBS"],
++ [$X_LIBS])
++ ],,
++ [-lXt $X_LIBS $XLIB $X_EXTRA_LIBS])])
++
++ CPPFLAGS="$ac_save_CPPFLAGS"
++else
++ XLIB=""
++ X_CFLAGS=""
++ X_LIBS=""
++ enable_winex11_drv=${enable_winex11_drv:-no}
++ enable_opengl32=${enable_opengl32:-no}
++ enable_glu32=${enable_glu32:-no}
++fi
++WINE_ERROR_WITH(x,[test "x$XLIB" = "x"],[X ${notice_platform}development files not found. Wine will be built
++without X support, which probably isn't what you want. You will need to install
++${notice_platform}development packages of Xlib/Xfree86 at the very least.])
++
++dnl **** Check for libxml2 ****
++
++AC_SUBST(XML2LIBS,"")
++AC_SUBST(XML2INCL,"")
++AC_SUBST(XSLTINCL,"")
++if test "x$with_xml" != "xno"
++then
++ ac_save_CPPFLAGS="$CPPFLAGS"
++ if test "$PKG_CONFIG" != "false"
++ then
++ ac_xml_libs="`$PKG_CONFIG --libs libxml-2.0 2>/dev/null`"
++ ac_xml_cflags="`$PKG_CONFIG --cflags libxml-2.0 2>/dev/null`"
++ else
++ ac_xml_libs="`xml2-config --libs 2>/dev/null`"
++ ac_xml_cflags="`xml2-config --cflags 2>/dev/null`"
++ fi
++ CPPFLAGS="$CPPFLAGS $ac_xml_cflags"
++ AC_CHECK_HEADERS(libxml/parser.h,
++ [AC_CHECK_LIB(xml2, xmlParseMemory,
++ [AC_DEFINE(HAVE_LIBXML2, 1, [Define if you have the libxml2 library])
++ XML2LIBS="$ac_xml_libs"
++ XML2INCL="$ac_xml_cflags"],,$ac_xml_libs)
++ AC_CHECK_LIB(xml2, xmlReadMemory,
++ [AC_DEFINE(HAVE_XMLREADMEMORY,1,[Define if libxml2 has the xmlReadMemory function])],,$ac_xml_libs)
++ AC_CHECK_LIB(xml2, xmlNewDocPI,
++ [AC_DEFINE(HAVE_XMLNEWDOCPI,1,[Define if libxml2 has the xmlNewDocPI function])],,$ac_xml_libs)
++ ])
++ CPPFLAGS="$ac_save_CPPFLAGS"
++fi
++WINE_WARNING_WITH(xml,[test "$ac_cv_lib_xml2_xmlParseMemory" != "yes"],
++ [libxml2 ${notice_platform}development files not found, XML won't be supported.])
++
++if test "x$with_xslt" != "xno"
++then
++ if test "$PKG_CONFIG" != "false"
++ then
++ ac_xslt_libs="`$PKG_CONFIG --libs libxslt 2>/dev/null`"
++ ac_xslt_cflags="`$PKG_CONFIG --cflags libxslt 2>/dev/null`"
++ else
++ ac_xslt_libs="`xslt-config --libs 2>/dev/null`"
++ ac_xslt_cflags="`xslt-config --cflags 2>/dev/null`"
++ fi
++ ac_save_CPPFLAGS="$CPPFLAGS"
++ CPPFLAGS="$CPPFLAGS $ac_xslt_cflags"
++ AC_CHECK_HEADERS([libxslt/pattern.h libxslt/transform.h],,,
++ [#ifdef HAVE_LIBXSLT_PATTERN_H
++# include <libxslt/pattern.h>
++#endif])
++ CPPFLAGS="$ac_save_CPPFLAGS"
++ if test "$ac_cv_header_libxslt_transform_h" = "yes"
++ then
++ WINE_CHECK_SONAME(xslt,xsltCompilePattern,
++ [XSLTINCL="$ac_xslt_cflags"],,[$ac_xslt_libs])
++ fi
++fi
++WINE_WARNING_WITH(xslt,[test "x$ac_cv_lib_soname_xslt" = "x"],
++ [libxslt ${notice_platform}development files not found, xslt won't be supported.])
++
++dnl **** Check for libhal ****
++AC_SUBST(HALINCL,"")
++if test "x$with_hal" != "xno"
++then
++ ac_save_CPPFLAGS="$CPPFLAGS"
++ if test "$PKG_CONFIG" != "false"
++ then
++ ac_hal_libs="`$PKG_CONFIG --libs hal 2>/dev/null`"
++ ac_hal_cflags="`$PKG_CONFIG --cflags hal 2>/dev/null`"
++ CPPFLAGS="$CPPFLAGS $ac_hal_cflags"
++ fi
++ AC_CHECK_HEADERS([dbus/dbus.h hal/libhal.h])
++ if test "$ac_cv_header_dbus_dbus_h" = "yes" -a "$ac_cv_header_hal_libhal_h" = "yes"
++ then
++ AC_CHECK_LIB(dbus-1, dbus_connection_close,
++ [WINE_CHECK_SONAME(hal, libhal_ctx_new,
++ [HALINCL="$ac_hal_cflags"],,[$ac_hal_libs])],,[$ac_hal_libs])
++ fi
++ CPPFLAGS="$ac_save_CPPFLAGS"
++fi
++WINE_NOTICE_WITH(hal,[test "x$ac_cv_lib_soname_hal" = "x" -a "x$ac_cv_header_DiskArbitration_DiskArbitration_h" != "xyes"],
++ [libhal/libdbus ${notice_platform}development files not found, no dynamic device support.])
++
++dnl **** Check for libgnutls ****
++if test "x$with_gnutls" != "xno"
++then
++ ac_save_CPPFLAGS="$CPPFLAGS"
++ if test "$PKG_CONFIG" != "false"
++ then
++ ac_gnutls_libs="`$PKG_CONFIG --libs gnutls 2>/dev/null`"
++ ac_gnutls_cflags="`$PKG_CONFIG --cflags gnutls 2>/dev/null`"
++ CPPFLAGS="$CPPFLAGS $ac_gnutls_cflags"
++ fi
++ AC_CHECK_HEADER(gnutls/gnutls.h,
++ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <gnutls/gnutls.h>]], [[typeof(gnutls_mac_get_key_size) *pfunc;]])],
++ [WINE_CHECK_SONAME(gnutls,gnutls_global_init,
++ [AC_SUBST(GNUTLSINCL,"$ac_gnutls_cflags")],,[$ac_gnutls_libs])])])
++ CPPFLAGS="$ac_save_CPPFLAGS"
++fi
++WINE_NOTICE_WITH(gnutls,[test "x$ac_cv_lib_soname_gnutls" = "x"],
++ [libgnutls ${notice_platform}development files not found, no schannel support.])
++
++dnl **** Check which curses lib to use ***
++CURSESLIBS=""
++if test "$ac_cv_header_ncurses_h" = "yes"
++then
++ WINE_CHECK_SONAME(ncurses,waddch,[CURSESLIBS="-lncurses"])
++elif test "$ac_cv_header_curses_h" = "yes"
++then
++ WINE_CHECK_SONAME(curses,waddch,[CURSESLIBS="-lcurses"])
++fi
++ac_save_LIBS="$LIBS"
++LIBS="$LIBS $CURSESLIBS"
++AC_CHECK_FUNCS(mousemask)
++LIBS="$ac_save_LIBS"
++WINE_NOTICE_WITH(curses,[test "x$ac_cv_lib_soname_curses$ac_cv_lib_soname_ncurses" = "x"],
++ [lib(n)curses ${notice_platform}development files not found, curses won't be supported.])
++
++dnl **** Check for SANE ****
++if test "x$with_sane" != "xno"
++then
++ ac_save_CPPFLAGS="$CPPFLAGS"
++ AC_CHECK_PROG(sane_devel,sane-config,sane-config,no)
++ if test "$sane_devel" != "no"
++ then
++ ac_sane_incl="`$sane_devel --cflags`"
++ ac_sane_libs="`$sane_devel --ldflags`"
++ CPPFLAGS="$CPPFLAGS $ac_sane_incl"
++ fi
++ AC_CHECK_HEADER(sane/sane.h,
++ [WINE_CHECK_SONAME(sane,sane_init,[AC_SUBST(SANEINCL,"$ac_sane_incl")],,[$ac_sane_libs])])
++ CPPFLAGS="$ac_save_CPPFLAGS"
++fi
++WINE_NOTICE_WITH(sane,[test "x$ac_cv_lib_soname_sane" = "x"],
++ [libsane ${notice_platform}development files not found, scanners won't be supported.])
++
++dnl **** Check for libv4l1 ****
++if test "x$with_v4l" != "xno"
++then
++ WINE_CHECK_SONAME(v4l1,v4l1_open,,,)
++fi
++WINE_NOTICE_WITH(v4l,[test "x$ac_cv_lib_soname_v4l1" = "x"],
++ [libv4l ${notice_platform}development files not found.])
++
++dnl **** Check for libgphoto2 ****
++if test "x$with_gphoto" != "xno"
++then
++ ac_save_CPPFLAGS="$CPPFLAGS"
++ AC_CHECK_PROG(gphoto2_devel,gphoto2-config,gphoto2-config,no)
++ AC_CHECK_PROG(gphoto2port_devel,gphoto2-port-config,gphoto2-port-config,no)
++ if test "$gphoto2_devel" != "no" -a "$gphoto2port_devel" != "no"
++ then
++ ac_gphoto2_incl="`$gphoto2_devel --cflags` `$gphoto2port_devel --cflags`"
++ ac_gphoto2_libs=""
++ for i in `$gphoto2_devel --libs` `$gphoto2port_devel --libs`
++ do
++ case "$i" in
++ -L/usr/lib|-L/usr/lib64) ;;
++ -L*|-l*) ac_gphoto2_libs="$ac_gphoto2_libs $i";;
++ esac
++ done
++ CPPFLAGS="$CPPFLAGS $ac_gphoto2_incl"
++ fi
++ ac_gphoto2_libs=${ac_gphoto2_libs:-"-lgphoto2"}
++ AC_CHECK_HEADER(gphoto2-camera.h,
++ [AC_CHECK_LIB(gphoto2,gp_camera_new,
++ [AC_DEFINE(HAVE_GPHOTO2, 1, [Define if we have libgphoto2 development environment])
++ AC_SUBST(GPHOTO2LIBS,"$ac_gphoto2_libs")
++ AC_SUBST(GPHOTO2INCL,"$ac_gphoto2_incl")],,
++ [$ac_gphoto2_libs])])
++ CPPFLAGS="$ac_save_CPPFLAGS"
++fi
++WINE_NOTICE_WITH(gphoto,[test "$ac_cv_lib_gphoto2_gp_camera_new" != "yes"],
++ [libgphoto2 ${notice_platform}development files not found, digital cameras won't be supported.])
++
++
++dnl **** Check for resolver library ***
++AC_SUBST(RESOLVLIBS,"")
++if test "$ac_cv_header_resolv_h" = "yes"
++then
++ ac_save_LIBS="$LIBS"
++ LIBS="$LIBS -lresolv"
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#ifdef HAVE_NETINET_IN_H
++#include <netinet/in.h>
++#endif
++#include <resolv.h>]],[[res_init();]])],
++ [AC_DEFINE(HAVE_RESOLV, 1, [Define if you have the resolver library and header])
++ RESOLVLIBS="-lresolv"])
++ LIBS="$ac_save_LIBS"
++fi
++
++dnl **** Check for LittleCMS ***
++AC_SUBST(LCMSLIBS,"")
++if test "$ac_cv_header_lcms_h" = "yes" -o "$ac_cv_header_lcms_lcms_h" = "yes"
++then
++ AC_CHECK_LIB(lcms, cmsOpenProfileFromFile,
++ [AC_DEFINE(HAVE_LCMS, 1, [Define if you have the LittleCMS development environment])
++ LCMSLIBS="-llcms"])
++fi
++WINE_NOTICE_WITH(cms,[test "$ac_cv_lib_lcms_cmsOpenProfileFromFile" != "yes"],
++ [liblcms ${notice_platform}development files not found, Color Management won't be supported.])
++
++dnl **** Check for FreeType 2 ****
++if test "x$with_freetype" != "xno"
++then
++ AC_CHECK_PROGS(ft_devel,[freetype-config freetype2-config],no)
++ if test "$ft_devel" != "no"
++ then
++ ac_freetype_incl=`$ft_devel --cflags`
++ ac_freetype_libs=`$ft_devel --libs`
++ fi
++ ac_freetype_libs=${ac_freetype_libs:-"-lfreetype"}
++ WINE_CHECK_SONAME(freetype,FT_Init_FreeType,[ft_lib=yes],[ft_lib=no],[$ac_freetype_libs])
++ if test "$ft_lib" = "yes"
++ then
++ ac_save_CPPFLAGS="$CPPFLAGS"
++ CPPFLAGS="$ac_freetype_incl $CPPFLAGS"
++ AC_CHECK_HEADERS(ft2build.h \
++ freetype/freetype.h \
++ freetype/ftglyph.h \
++ freetype/fttypes.h \
++ freetype/tttables.h \
++ freetype/ftsnames.h \
++ freetype/ttnameid.h \
++ freetype/ftoutln.h \
++ freetype/ftwinfnt.h \
++ freetype/ftmodapi.h \
++ freetype/ftlcdfil.h \
++ freetype/internal/sfnt.h,,,
++ [#ifdef HAVE_FT2BUILD_H
++ # include <ft2build.h>
++ #endif])
++ AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <ft2build.h>
++ #include <freetype/fttrigon.h>]])],[AC_DEFINE(HAVE_FREETYPE_FTTRIGON_H, 1,
++ [Define if you have the <freetype/fttrigon.h> header file.])
++ wine_cv_fttrigon=yes],[wine_cv_fttrigon=no])
++ AC_CHECK_TYPES(FT_TrueTypeEngineType,,,[#include <freetype/ftmodapi.h>])
++ ac_save_CFLAGS="$CFLAGS"
++ CFLAGS="$CFLAGS $ac_freetype_libs"
++ AC_CHECK_FUNCS(FT_Load_Sfnt_Table)
++ CFLAGS="$ac_save_CFLAGS"
++ CPPFLAGS="$ac_save_CPPFLAGS"
++ dnl Check that we have at least freetype/freetype.h
++ if test "$ac_cv_header_freetype_freetype_h" = "yes" -a "$wine_cv_fttrigon" = "yes"
++ then
++ AC_DEFINE(HAVE_FREETYPE, 1, [Define if FreeType 2 is installed])
++ AC_SUBST(FREETYPELIBS,"$ac_freetype_libs")
++ AC_SUBST(FREETYPEINCL,"$ac_freetype_incl")
++ fi
++ fi
++fi
++WINE_ERROR_WITH(freetype,[test "x$FREETYPELIBS" = "x"],[FreeType ${notice_platform}development files not found. Fonts will not be built.])
++test "x$FREETYPELIBS" = "x" && enable_fonts=${enable_fonts:-no}
++
++dnl **** Check for parport (currently Linux only) ****
++AC_CACHE_CHECK([for parport header/ppdev.h], ac_cv_c_ppdev,
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef HAVE_SYS_IOCTL_H
++# include <sys/ioctl.h>
++#endif
++#include <linux/ppdev.h>]], [[ioctl (1,PPCLAIM,0)]])],
++ [ac_cv_c_ppdev="yes"],[ac_cv_c_ppdev="no"]))
++if test "$ac_cv_c_ppdev" = "yes"
++then
++ AC_DEFINE(HAVE_PPDEV, 1, [Define if we can use ppdev.h for parallel port access])
++fi
++
++dnl **** Check for pthread functions ****
++WINE_CHECK_LIB_FUNCS(\
++ pthread_attr_get_np \
++ pthread_getattr_np \
++ pthread_get_stackaddr_np \
++ pthread_get_stacksize_np,
++ [$LIBPTHREAD])
++
++dnl **** Check for zlib ****
++if test "$ac_cv_header_zlib_h" = "yes"
++then
++ AC_CHECK_LIB(z,inflate,[AC_DEFINE(HAVE_ZLIB,1,[Define to 1 if you have the `z' library (-lz).])
++ AC_SUBST(ZLIB,"-lz")])
++fi
++
++dnl **** Check for EsounD ****
++if test "x$with_esd" != xno
++then
++ save_CFLAGS="$CFLAGS"
++ AC_PATH_PROG(ESDCONFIG, esd-config, no)
++ if test "x$ESDCONFIG" != "xno"
++ then
++ ac_esd_incl=""
++ for i in `$ESDCONFIG --cflags`
++ do
++ case "$i" in
++ -I*) ac_esd_incl="$ac_esd_incl $i";;
++ esac
++ done
++ ac_esd_libs=`$ESDCONFIG --libs`
++ CFLAGS="$CFLAGS $ac_esd_incl"
++ fi
++ ac_esd_libs=${ac_esd_libs:-"-lesd"}
++ AC_CHECK_HEADER(esd.h,
++ [AC_CHECK_LIB(esd,esd_open_sound,
++ [AC_SUBST(ESDINCL, "$ac_esd_incl")
++ AC_SUBST(ESDLIBS, "$ac_esd_libs")
++ AC_DEFINE(HAVE_ESD, 1, [Define if you have EsounD sound server])],,
++ [$ac_esd_libs])])
++ CFLAGS="$save_CFLAGS"
++fi
++
++dnl **** Check for ALSA 1.x ****
++AC_SUBST(ALSALIBS,"")
++if test "$ac_cv_header_sys_asoundlib_h" = "yes" -o "$ac_cv_header_alsa_asoundlib_h" = "yes"
++then
++ AC_CHECK_LIB(asound,snd_pcm_hw_params_get_access,
++ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef HAVE_ALSA_ASOUNDLIB_H
++#include <alsa/asoundlib.h>
++#elif defined(HAVE_SYS_ASOUNDLIB_H)
++#include <sys/asoundlib.h>
++#endif]], [[int ret = snd_pcm_hw_params_get_access(NULL, NULL)]])],
++ [AC_DEFINE(HAVE_ALSA,1,[Define if you have ALSA 1.x including devel headers])
++ ALSALIBS="-lasound"],[])])
++fi
++
++dnl **** Check for libaudioio (which can be used to get solaris audio support) ****
++AC_SUBST(AUDIOIOLIBS,"")
++if test "$ac_cv_header_libaudioio_h" = "yes"
++then
++ AC_CHECK_LIB(audioio,AudioIOGetVersion,
++ [AUDIOIOLIBS="-laudioio"
++ AC_DEFINE(HAVE_LIBAUDIOIO, 1, [Define if you have libaudioIO])])
++fi
++
++dnl **** Check for capi4linux ****
++
++if test "$ac_cv_header_capi20_h" = "yes" -a "$ac_cv_header_linux_capi_h" = "yes"
++then
++ WINE_CHECK_SONAME(capi20,capi20_register)
++fi
++WINE_NOTICE_WITH(capi,[test "x$ac_cv_lib_soname_capi20" = "x"],
++ [libcapi20 ${notice_platform}development files not found, ISDN won't be supported.])
++
++dnl **** Check for cups ****
++AC_SUBST(CUPSINCL,"")
++if test "x$with_cups" != "xno"
++then
++ ac_save_CPPFLAGS="$CPPFLAGS"
++ ac_cups_cflags=`cups-config --cflags 2>/dev/null`
++ ac_cups_libs=`cups-config --ldflags 2>/dev/null`
++ CPPFLAGS="$CPPFLAGS $ac_cups_cflags"
++ AC_CHECK_HEADERS(cups/cups.h,
++ [WINE_CHECK_SONAME(cups,cupsGetDefault,
++ [CUPSINCL="$ac_cups_cflags"],,
++ [$ac_cups_libs])])
++ CPPFLAGS="$ac_save_CPPFLAGS"
++fi
++WINE_NOTICE_WITH(cups,[test "x$ac_cv_lib_soname_cups" = "x"],
++ [libcups ${notice_platform}development files not found, CUPS won't be supported.])
++
++dnl **** Check for jack ****
++if test "$ac_cv_header_jack_jack_h" = "yes"
++then
++ WINE_CHECK_SONAME(jack,jack_client_new,,,,[[libjack-*[[0-9.]]*]])
++fi
++
++dnl **** Check for fontconfig ****
++if test "$ac_cv_header_fontconfig_fontconfig_h" = "yes"
++then
++ WINE_CHECK_SONAME(fontconfig,FcInit)
++elif test -n "$X_CFLAGS" -a "x$with_fontconfig" != "xno"
++then
++ dnl fontconfig is in the X directory on Mac OS X
++ ac_save_CPPFLAGS="$CPPFLAGS"
++ CPPFLAGS="$CPPFLAGS $X_CFLAGS"
++ $as_unset ac_cv_header_fontconfig_fontconfig_h
++ AC_CHECK_HEADERS([fontconfig/fontconfig.h])
++ CPPFLAGS="$ac_save_CPPFLAGS"
++ if test "$ac_cv_header_fontconfig_fontconfig_h" = "yes"
++ then
++ AC_SUBST(FONTCONFIGINCL,"$X_CFLAGS")
++ WINE_CHECK_SONAME(fontconfig,FcInit,,,[$X_LIBS])
++ fi
++fi
++WINE_NOTICE_WITH(fontconfig,[test "x$ac_cv_lib_soname_fontconfig" = "x"],
++ [fontconfig ${notice_platform}development files not found, fontconfig won't be supported.])
++
++dnl **** Check for SSL ****
++if test "$ac_cv_header_openssl_err_h" = "yes" -a "$ac_cv_header_openssl_ssl_h" = "yes"
++then
++ WINE_CHECK_SONAME(ssl,SSL_library_init)
++ WINE_CHECK_SONAME(crypto,BIO_new_socket)
++fi
++WINE_WARNING_WITH(openssl,[test "x$ac_cv_lib_soname_ssl" = "x" -o "x$ac_cv_lib_soname_crypto" = "x"],
++ [OpenSSL ${notice_platform}development files not found, SSL won't be supported.])
++
++dnl **** Check for gsm codec ****
++if test "$ac_cv_header_gsm_h" = "yes" -o "$ac_cv_header_gsm_gsm_h" = "yes"
++then
++ WINE_CHECK_SONAME(gsm,gsm_create)
++fi
++WINE_NOTICE_WITH(gsm,[test "x$ac_cv_lib_soname_gsm" = "x"],
++ [libgsm ${notice_platform}development files not found, gsm 06.10 codec won't be supported.])
++
++dnl **** Check for libjpeg ****
++if test "$ac_cv_header_jpeglib_h" = "yes"
++then
++ WINE_CHECK_SONAME(jpeg,jpeg_start_decompress)
++fi
++WINE_WARNING_WITH(jpeg,[test "x$ac_cv_lib_soname_jpeg" = "x"],
++ [libjpeg ${notice_platform}development files not found, JPEG won't be supported.])
++
++dnl **** Check for libpng ****
++if test "$ac_cv_header_png_h" = "yes"
++then
++ WINE_CHECK_SONAME(png,png_create_read_struct,,,-lm -lz,[[libpng[[0-9]]*]])
++ AC_CHECK_LIB(png,png_set_expand_gray_1_2_4_to_8,
++ [AC_DEFINE(HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8,1,[Define to 1 if libpng has the png_set_expand_gray_1_2_4_to_8 function.])]
++ ,,-lm -lz)
++elif test -n "$X_CFLAGS" -a "x$with_png" != "xno"
++then
++ dnl libpng is in the X directory on Mac OS X
++ ac_save_CPPFLAGS="$CPPFLAGS"
++ CPPFLAGS="$CPPFLAGS $X_CFLAGS"
++ $as_unset ac_cv_header_png_h
++ AC_CHECK_HEADERS([png.h])
++ CPPFLAGS="$ac_save_CPPFLAGS"
++ if test "$ac_cv_header_png_h" = "yes"
++ then
++ AC_SUBST(PNGINCL,"$X_CFLAGS")
++ WINE_CHECK_SONAME(png,png_create_read_struct,,,[$X_LIBS -lm -lz],[[libpng[[0-9]]*]])
++ AC_CHECK_LIB(png,png_set_expand_gray_1_2_4_to_8,
++ [AC_DEFINE(HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8,1)],,[$X_LIBS -lm -lz])
++ fi
++fi
++WINE_WARNING_WITH(png,[test "x$ac_cv_lib_soname_png" = "x"],
++ [libpng ${notice_platform}development files not found, PNG won't be supported.])
++
++dnl **** Check for libtiff ****
++if test "$ac_cv_header_tiffio_h" = "yes"
++then
++ WINE_CHECK_SONAME(tiff,TIFFClientOpen)
++fi
++WINE_NOTICE_WITH(tiff,[test "x$ac_cv_lib_soname_tiff" = "x"],
++ [libtiff ${notice_platform}development files not found, TIFF won't be supported.])
++
++dnl **** Check for mpg123 ****
++if test "$ac_cv_header_mpg123_h" = "yes"
++then
++ AC_CHECK_LIB(mpg123,mpg123_feed,[AC_SUBST(LIBMPG123,"-lmpg123")])
++fi
++WINE_NOTICE_WITH(mpg123,[test "x$ac_cv_lib_mpg123_mpg123_feed" != xyes -a x"$ac_cv_header_CoreAudio_CoreAudio_h" != xyes],
++ [libmpg123 ${notice_platform}development files not found (or too old), mp3 codec won't be supported.])
++test "x$ac_cv_lib_mpg123_mpg123_feed" = xyes -o "x$ac_cv_header_AudioToolbox_AudioConverter_h" = xyes || enable_winemp3_acm=${enable_winemp3_acm:-no}
++
++dnl **** Check for OpenAL 1.1 ****
++if test "$ac_cv_header_AL_al_h" = "yes"
++then
++ WINE_CHECK_SONAME(openal,alGetSource3i,[AC_SUBST(LIBOPENAL,"-lopenal")
++ ac_cv_lib_openal=yes
++ AC_DEFINE_UNQUOTED(HAVE_OPENAL,1,[Define to 1 if OpenAL is available])],,)
++fi
++WINE_NOTICE_WITH(openal,[test "x$ac_cv_lib_openal" != xyes],
++ [libopenal ${notice_platform}development files not found (or too old), OpenAL won't be supported.])
++test "x$ac_cv_lib_openal" = xyes || enable_openal32=${enable_openal32:-no}
++
++dnl **** Check for libkstat ****
++if test "$ac_cv_header_kstat_h" = "yes"
++then
++ AC_CHECK_LIB(kstat,kstat_open,
++ [AC_DEFINE(HAVE_LIBKSTAT, 1, [Define to 1 if you have the `kstat' library (-lkstat).])
++ AC_SUBST(LIBKSTAT,"-lkstat")])
++fi
++
++dnl **** Check for libodbc ****
++WINE_CHECK_SONAME(odbc,SQLConnect,,[AC_DEFINE_UNQUOTED(SONAME_LIBODBC,["libodbc.$LIBEXT"])])
++
++dnl **** Check for any sound system ****
++if test "x$ALSALIBS$AUDIOIOLIBS$COREAUDIO$NASLIBS$ESDLIBS$ac_cv_lib_soname_jack" = "x" -a \
++ "$ac_cv_header_sys_soundcard_h" != "yes" -a \
++ "$ac_cv_header_machine_soundcard_h" != "yes" -a \
++ "$ac_cv_header_soundcard_h" != "yes" -a \
++ "x$with_alsa$with_audioio$with_coreaudio$with_nas$with_esd$with_jack$with_oss" != xnonononononono
++then
++ WINE_WARNING([No sound system was found. Windows applications will be silent.])
++fi
++
++dnl **** Check for gcc specific options ****
++
++AC_SUBST(EXTRACFLAGS,"")
++if test "x${GCC}" = "xyes"
++then
++ EXTRACFLAGS="-Wall -pipe"
++
++ dnl Check for strength-reduce bug
++ AC_CACHE_CHECK( [for gcc strength-reduce bug], ac_cv_c_gcc_strength_bug,
++ AC_RUN_IFELSE([AC_LANG_PROGRAM([[int L[[4]] = {0,1,2,3};]],
++[[static int Array[[3]];
++ unsigned int B = 3;
++ int i;
++ for(i=0; i<B; i++) Array[[i]] = i - 3;
++ for(i=0; i<4 - 1; i++) L[[i]] = L[[i + 1]];
++ L[[i]] = 4;
++ return (Array[[1]] != -2 || L[[2]] != 3)]])],
++ [ac_cv_c_gcc_strength_bug="no"],[ac_cv_c_gcc_strength_bug="yes"],[ac_cv_c_gcc_strength_bug="yes"]) )
++ if test "$ac_cv_c_gcc_strength_bug" = "yes"
++ then
++ EXTRACFLAGS="$EXTRACFLAGS -fno-strength-reduce"
++ fi
++
++ dnl Check for some compiler flags
++ WINE_TRY_CFLAGS([-fno-builtin],[AC_SUBST(BUILTINFLAG,"-fno-builtin")])
++ WINE_TRY_CFLAGS([-fno-strict-aliasing])
++ WINE_TRY_CFLAGS([-Wdeclaration-after-statement])
++ WINE_TRY_CFLAGS([-Wstrict-prototypes])
++ WINE_TRY_CFLAGS([-Wtype-limits])
++ WINE_TRY_CFLAGS([-Wwrite-strings])
++
++ dnl Check for noisy string.h
++ saved_CFLAGS="$CFLAGS"
++ CFLAGS="$CFLAGS -Wpointer-arith -Werror"
++ AC_CACHE_CHECK([for broken string.h that generates warnings], ac_cv_c_string_h_warnings,
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <string.h>]], [[]])],[ac_cv_c_string_h_warnings=no],[ac_cv_c_string_h_warnings=yes]))
++ CFLAGS="$saved_CFLAGS"
++ if test "$ac_cv_c_string_h_warnings" = "no"
++ then
++ EXTRACFLAGS="$EXTRACFLAGS -Wpointer-arith"
++ fi
++
++ dnl Fortify enables unused result warnings on a gazillion functions, making it useless
++ saved_CFLAGS="$CFLAGS"
++ CFLAGS="$CFLAGS -Werror"
++ AC_CACHE_CHECK([for broken unused result warnings], ac_cv_c_unused_result_warnings,
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>]], [[write(2,"a",1)]])],[ac_cv_c_unused_result_warnings=no],[ac_cv_c_unused_result_warnings=yes]))
++ CFLAGS="$saved_CFLAGS"
++ if test "$ac_cv_c_unused_result_warnings" = "yes"
++ then
++ WINE_TRY_CFLAGS([-Wno-unused-result])
++ fi
++
++ dnl Enable -Werror for maintainer mode
++ if test "x$enable_maintainer_mode" = "xyes"
++ then
++ WINE_TRY_CFLAGS([-Werror])
++ fi
++
++ dnl Check for ms_hook_prologue support
++ saved_CFLAGS="$CFLAGS"
++ CFLAGS="$CFLAGS -Werror"
++ AC_CACHE_CHECK([for ms_hook_prologue attribute], ac_cv_have_ms_hook_prologue,
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int __attribute__((__ms_hook_prologue__)) test(void) { return 0; }]])],
++ [ac_cv_have_ms_hook_prologue="yes"],[ac_cv_have_ms_hook_prologue="no"]))
++ CFLAGS="$saved_CFLAGS"
++ if test "$ac_cv_have_ms_hook_prologue" = "yes"
++ then
++ AC_DEFINE(DECLSPEC_HOTPATCH, [__attribute__((__ms_hook_prologue__))],
++ [Define to a function attribute for Microsoft hotpatch assembly prefix.])
++ else
++ AC_DEFINE(DECLSPEC_HOTPATCH, [/* */])
++ fi
++fi
++
++dnl **** Check for underscore on external symbols ****
++
++AC_CACHE_CHECK([whether external symbols need an underscore prefix], ac_cv_c_extern_prefix,
++ WINE_TRY_ASM_LINK([".globl _ac_test\n_ac_test:\t.long 0"],
++ [extern int ac_test;],
++ [if (ac_test) return 1],
++ ac_cv_c_extern_prefix="yes",ac_cv_c_extern_prefix="no"))
++
++case $host_cpu in
++ *i[[3456789]]86*)
++ AC_CACHE_CHECK([whether external symbols need stdcall decoration], ac_cv_c_stdcall_suffix,
++ WINE_TRY_ASM_LINK(["jmp _ac_test@4"],
++[#ifndef _MSC_VER
++#define __stdcall __attribute__((__stdcall__))
++#endif
++int __stdcall ac_test(int i) { return i; }],
++ [if (ac_test(1)) return 1],
++ ac_cv_c_stdcall_suffix="yes",ac_cv_c_stdcall_suffix="no")) ;;
++ *) ac_cv_c_stdcall_suffix="no" ;;
++esac
++
++AH_TEMPLATE(__ASM_NAME,[Define to a macro to generate an assembly name from a C symbol])
++if test "$ac_cv_c_extern_prefix" = "yes"
++then
++ AC_DEFINE([__ASM_NAME(name)], ["_" name])
++ asm_name_prefix="_"
++else
++ AC_DEFINE([__ASM_NAME(name)], [name])
++ asm_name_prefix=""
++fi
++
++AH_TEMPLATE(__ASM_STDCALL,[Define to a macro to generate an stdcall suffix])
++if test "$ac_cv_c_stdcall_suffix" = "yes"
++then
++ AC_DEFINE([__ASM_STDCALL(args)],["@" #args])
++else
++ AC_DEFINE([__ASM_STDCALL(args)],[""])
++fi
++
++dnl **** Check how to define a function in assembly code ****
++
++AC_CACHE_CHECK([how to define a function in assembly code], ac_cv_asm_func_def,
++ WINE_TRY_ASM_LINK(
++ ["\t.globl _ac_test\n\t.def _ac_test; .scl 2; .type 32; .endef\n_ac_test:\t.long 0"],,,
++ ac_cv_asm_func_def=".def",
++ [WINE_TRY_ASM_LINK(["\t.globl _ac_test\n\t.type _ac_test,@function\n_ac_test:\t.long 0"],,,
++ ac_cv_asm_func_def=".type @function",
++ [WINE_TRY_ASM_LINK(["\t.globl _ac_test\n\t.type _ac_test,2\n_ac_test:\t.long 0"],,,
++ ac_cv_asm_func_def=".type 2",
++ ac_cv_asm_func_def="unknown")])]))
++
++AH_TEMPLATE(__ASM_FUNC,[Define to a macro to generate an assembly function directive])
++case "$ac_cv_asm_func_def" in
++ ".def")
++ AC_DEFINE([__ASM_FUNC(name)], [".def " __ASM_NAME(name) "; .scl 2; .type 32; .endef"])
++ asm_func_header=".def $asm_name_prefix\" #name suffix \"; .scl 2; .type 32; .endef" ;;
++ ".type @function")
++ AC_DEFINE([__ASM_FUNC(name)], [".type " __ASM_NAME(name) ",@function"])
++ asm_func_header=".type $asm_name_prefix\" #name suffix \",@function" ;;
++ ".type 2")
++ AC_DEFINE([__ASM_FUNC(name)], [".type " __ASM_NAME(name) ",2"])
++ asm_func_header=".type $asm_name_prefix\" #name suffix \",2" ;;
++ *)
++ AC_DEFINE([__ASM_FUNC(name)], [""])
++ asm_func_header="" ;;
++esac
++
++AC_CACHE_CHECK([whether asm() works outside of functions], ac_cv_c_asm_outside_funcs,
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[asm(".text\n\t.long 0");]],)],
++ ac_cv_c_asm_outside_funcs="yes",ac_cv_c_asm_outside_funcs="no"))
++
++AC_CACHE_CHECK([whether .previous is supported in assembly code], ac_cv_c_dot_previous,
++ WINE_TRY_ASM_LINK([".text\nac_test:\t.long 0\n\t.previous"],,,
++ ac_cv_c_dot_previous="yes",ac_cv_c_dot_previous="no"))
++
++AC_CACHE_CHECK([whether CFI directives are supported in assembly code], ac_cv_c_cfi_support,
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[asm(".text\nac_test:\t.cfi_startproc\n\t.long 0\n\t.cfi_endproc");]])],
++ ac_cv_c_cfi_support="yes",ac_cv_c_cfi_support="no"))
++
++asm_func_header=".globl $asm_name_prefix\" #name suffix \"\\n\\t$asm_func_header\\n$asm_name_prefix\" #name suffix \":\\n\\t"
++asm_func_trailer=""
++if test "$ac_cv_c_dot_previous" = "yes"
++then
++ asm_func_trailer="\\n\\t.previous"
++fi
++if test "$ac_cv_c_cfi_support" = "yes"
++then
++ asm_func_header="$asm_func_header.cfi_startproc\\n\\t"
++ asm_func_trailer="\\n\\t.cfi_endproc$asm_func_trailer"
++ AC_DEFINE([__ASM_CFI(str)],[str],[Define to a macro to output a .cfi assembly pseudo-op])
++ AC_SUBST([UNWINDFLAGS],[-fasynchronous-unwind-tables])
++else
++ AC_DEFINE([__ASM_CFI(str)],[""])
++fi
++
++asm_func_code="$asm_func_header\" code \"$asm_func_trailer"
++
++AH_TEMPLATE(__ASM_DEFINE_FUNC,[Define to a macro to define an assembly function])
++if test "$ac_cv_c_asm_outside_funcs" = "yes"
++then
++ AC_DEFINE_UNQUOTED([__ASM_DEFINE_FUNC(name,suffix,code)],[asm(".text\n\t.align 4\n\t$asm_func_code");])
++else
++ AC_DEFINE_UNQUOTED([__ASM_DEFINE_FUNC(name,suffix,code)],[void __asm_dummy_##name(void) { asm(".text\n\t.align 4\n\t$asm_func_code"); }])
++fi
++AC_DEFINE([__ASM_GLOBAL_FUNC(name,code)],[__ASM_DEFINE_FUNC(name,"",code)],
++ [Define to a macro to generate an assembly function with C calling convention])
++AC_DEFINE([__ASM_STDCALL_FUNC(name,args,code)],[__ASM_DEFINE_FUNC(name,__ASM_STDCALL(args),code)],
++ [Define to a macro to generate an assembly function with stdcall calling convention])
++
++dnl **** Platform-specific checks ****
++
++AC_SUBST(LDPATH,"")
++case $build_os in
++ cygwin*|mingw32*)
++ AC_SUBST(TOOLSEXT,".exe")
++ LDPATH="PATH=\"\$(TOOLSDIR)/libs/wine:\$\$PATH\""
++ ;;
++ darwin*|macosx*)
++ ;;
++ *)
++ LDPATH="LD_LIBRARY_PATH=\"\$(TOOLSDIR)/libs/wine:\$\$LD_LIBRARY_PATH\""
++ ;;
++esac
++
++dnl Mingw needs explicit msvcrt for linking libwine and winsock for wininet
++case $host_os in
++ mingw32*)
++ AC_SUBST(CRTLIBS,"-lmsvcrt")
++ AC_SUBST(SOCKETLIBS,"-L\$(TOPOBJDIR)/dlls/ws2_32 -lws2_32")
++ ;;
++esac
++
++AC_SUBST(MAIN_BINARY,"wine")
++test "x$enable_win64" != "xyes" || MAIN_BINARY="wine64"
++
++case $host_cpu in
++ *i[[3456789]]86*)
++ case $host_os in
++ linux*)
++ AC_SUBST(EXTRA_BINARIES,"wine-preloader") ;;
++ esac
++ ;;
++esac
++
++dnl **** Check for functions ****
++
++ac_save_CFLAGS="$CFLAGS"
++CFLAGS="$CFLAGS $BUILTINFLAG"
++AC_CHECK_FUNCS(\
++ _pclose \
++ _popen \
++ _snprintf \
++ _spawnvp \
++ _strdup \
++ _stricmp \
++ _strnicmp \
++ _strtoi64 \
++ _strtoui64 \
++ _vsnprintf \
++ asctime_r \
++ chsize \
++ dlopen \
++ epoll_create \
++ ffs \
++ finite \
++ fnmatch \
++ fork \
++ fpclass \
++ fstatfs \
++ fstatvfs \
++ ftruncate \
++ futimes \
++ futimesat \
++ getdirentries \
++ getopt_long \
++ getpagesize \
++ getpwuid \
++ gettid \
++ gettimeofday \
++ getuid \
++ kqueue \
++ lstat \
++ memmove \
++ mmap \
++ pclose \
++ pipe2 \
++ poll \
++ popen \
++ port_create \
++ prctl \
++ pread \
++ pwrite \
++ readdir \
++ readlink \
++ sched_setaffinity \
++ sched_yield \
++ select \
++ setproctitle \
++ setrlimit \
++ settimeofday \
++ sigaltstack \
++ sigprocmask \
++ snprintf \
++ spawnvp \
++ statfs \
++ statvfs \
++ strcasecmp \
++ strdup \
++ strerror \
++ strncasecmp \
++ strtold \
++ strtoll \
++ strtoull \
++ symlink \
++ tcgetattr \
++ thr_kill2 \
++ timegm \
++ usleep \
++ vsnprintf \
++ wait4 \
++ waitpid \
++)
++CFLAGS="$ac_save_CFLAGS"
++
++dnl Check for -ldl
++if test "$ac_cv_func_dlopen" = no
++then
++ AC_CHECK_LIB(dl,dlopen,[AC_DEFINE(HAVE_DLOPEN,1) AC_SUBST(LIBDL,"-ldl")])
++fi
++WINE_CHECK_LIB_FUNCS(dladdr,[$LIBDL])
++
++dnl Check for -lpoll for Mac OS X/Darwin
++if test "$ac_cv_func_poll" = no
++then
++ AC_CHECK_LIB(poll,poll,[AC_DEFINE(HAVE_POLL,1) AC_SUBST(LIBPOLL,"-lpoll")])
++fi
++
++dnl Check for -lnsl for Solaris
++AC_SEARCH_LIBS(gethostbyname, nsl)
++
++dnl Check for -lsocket for Solaris
++AC_SEARCH_LIBS(connect, socket)
++
++dnl Check for -lresolv for Solaris
++AC_SEARCH_LIBS(inet_aton, resolv)
++
++dnl **** Check for functions which may rely on -lsocket on Solaris.
++AC_CHECK_FUNCS(\
++ getaddrinfo \
++ getnameinfo \
++ getnetbyname \
++ getprotobyname \
++ getprotobynumber \
++ getservbyport \
++ inet_network \
++ inet_ntop \
++ inet_pton \
++ sendmsg \
++ socketpair \
++)
++
++dnl **** Check for OpenLDAP ***
++AC_SUBST(LDAPLIBS,"")
++if test "$ac_cv_header_ldap_h" = "yes" -a "$ac_cv_header_lber_h" = "yes"
++then
++ AC_CHECK_TYPE(LDAPSortKey,
++ [AC_CHECK_LIB(ldap_r, ldap_initialize,
++ [AC_CHECK_LIB(lber, ber_init,
++ [AC_DEFINE(HAVE_LDAP, 1, [Define if you have the OpenLDAP development environment])
++ LDAPLIBS="-lldap_r -llber"],,
++ [$LIBPTHREAD])],,
++ [$LIBPTHREAD])],,
++ [#include <ldap.h>])
++ WINE_CHECK_LIB_FUNCS(\
++ ldap_count_references \
++ ldap_first_reference \
++ ldap_next_reference \
++ ldap_parse_reference \
++ ldap_parse_sort_control \
++ ldap_parse_sortresponse_control \
++ ldap_parse_vlv_control \
++ ldap_parse_vlvresponse_control,
++ [$LDAPLIBS $LIBPTHREAD])
++fi
++WINE_NOTICE_WITH(ldap,[test "x$LDAPLIBS" = "x"],
++ [libldap (OpenLDAP) ${notice_platform}development files not found, LDAP won't be supported.])
++
++AC_CACHE_CHECK([whether mkdir takes only one argument],
++ wine_cv_one_arg_mkdir,
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/stat.h>]],[[mkdir("foo");]])],
++ [wine_cv_one_arg_mkdir=yes],[wine_cv_one_arg_mkdir=no]))
++if test "$wine_cv_one_arg_mkdir" = "yes"
++then
++ AC_DEFINE(HAVE_ONE_ARG_MKDIR, 1, [Define if mkdir takes only one argument])
++fi
++
++dnl **** Check for types ****
++
++AC_C_CONST
++AC_C_INLINE
++AC_CHECK_TYPES([mode_t, off_t, pid_t, size_t, ssize_t, long long, fsblkcnt_t, fsfilcnt_t])
++AC_CHECK_TYPES([sigset_t],,,[#include <sys/types.h>
++#include <signal.h>])
++AC_CHECK_TYPES([request_sense],,,[#include <linux/cdrom.h>])
++
++AC_CHECK_TYPES([struct xinpgen],,,
++[#include <sys/types.h>
++#ifdef HAVE_SYS_SOCKET_H
++#include <sys/socket.h>
++#endif
++#ifdef HAVE_SYS_SOCKETVAR_H
++#include <sys/socketvar.h>
++#endif
++#ifdef HAVE_NET_ROUTE_H
++#include <net/route.h>
++#endif
++#ifdef HAVE_NETINET_IN_H
++#include <netinet/in.h>
++#endif
++#ifdef HAVE_NETINET_IN_SYSTM_H
++#include <netinet/in_systm.h>
++#endif
++#ifdef HAVE_NETINET_IP_H
++#include <netinet/ip.h>
++#endif
++#ifdef HAVE_NETINET_IN_PCB_H
++#include <netinet/in_pcb.h>
++#endif])
++
++AC_CHECK_MEMBERS([struct ff_effect.direction],,,
++[#ifdef HAVE_LINUX_INPUT_H
++#include <linux/input.h>
++#endif])
++
++AC_CACHE_CHECK([for sigaddset],wine_cv_have_sigaddset,
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>]], [[sigset_t set; sigaddset(&set,SIGTERM);]])],[wine_cv_have_sigaddset=yes],[wine_cv_have_sigaddset=no]))
++if test "$wine_cv_have_sigaddset" = "yes"
++then
++ AC_DEFINE(HAVE_SIGADDSET, 1, [Define if sigaddset is supported])
++fi
++
++
++AC_CACHE_CHECK([whether we can use re-entrant gethostbyname_r Linux style],
++ wine_cv_linux_gethostbyname_r_6,
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <netdb.h>]],[[
++ char *name=0;
++ struct hostent he;
++ struct hostent *result;
++ char *buf=0;
++ int bufsize=0;
++ int res,errnr;
++ char *addr=0;
++ int addrlen=0;
++ int addrtype=0;
++ res=gethostbyname_r(name,&he,buf,bufsize,&result,&errnr);
++ res=gethostbyaddr_r(addr, addrlen, addrtype,&he,buf,bufsize,&result,&errnr);
++ ]])],[wine_cv_linux_gethostbyname_r_6=yes],[wine_cv_linux_gethostbyname_r_6=no
++ ])
++ )
++ if test "$wine_cv_linux_gethostbyname_r_6" = "yes"
++ then
++ AC_DEFINE(HAVE_LINUX_GETHOSTBYNAME_R_6, 1,
++ [Define if Linux-style gethostbyname_r and gethostbyaddr_r are available])
++ fi
++
++if test "$ac_cv_header_linux_joystick_h" = "yes"
++then
++ AC_CACHE_CHECK([whether linux/joystick.h uses the Linux 2.2+ API],
++ wine_cv_linux_joystick_22_api,
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
++ #include <sys/ioctl.h>
++ #include <sys/types.h>
++ #include <linux/joystick.h>
++
++ struct js_event blub;
++ #if !defined(JS_EVENT_AXIS) || !defined(JS_EVENT_BUTTON)
++ #error "no 2.2 header"
++ #endif
++ ]], [[/*empty*/]])],[wine_cv_linux_joystick_22_api=yes],[wine_cv_linux_joystick_22_api=no])
++ )
++ if test "$wine_cv_linux_joystick_22_api" = "yes"
++ then
++ AC_DEFINE(HAVE_LINUX_22_JOYSTICK_API, 1,
++ [Define if <linux/joystick.h> defines the Linux 2.2 joystick API])
++ fi
++fi
++
++dnl **** FIXME: what about mixed cases, where we need two of them? ***
++
++dnl Check for statfs members
++AC_CHECK_MEMBERS([struct statfs.f_bfree, struct statfs.f_bavail, struct statfs.f_frsize, struct statfs.f_ffree, struct statfs.f_favail, struct statfs.f_namelen],,,
++[#include <sys/types.h>
++#ifdef HAVE_SYS_PARAM_H
++# include <sys/param.h>
++#endif
++#ifdef HAVE_SYS_MOUNT_H
++# include <sys/mount.h>
++#endif
++#ifdef HAVE_SYS_VFS_H
++# include <sys/vfs.h>
++#endif
++#ifdef HAVE_SYS_STATFS_H
++# include <sys/statfs.h>
++#endif])
++
++AC_CHECK_MEMBERS([struct statvfs.f_blocks],,,
++[#ifdef HAVE_SYS_STATVFS_H
++#include <sys/statvfs.h>
++#endif])
++
++dnl Check for socket structure members
++AC_CHECK_MEMBERS([struct msghdr.msg_accrights, struct sockaddr.sa_len, struct sockaddr_un.sun_len],,,
++[#include <sys/types.h>
++#ifdef HAVE_SYS_SOCKET_H
++# include <sys/socket.h>
++#endif
++#ifdef HAVE_SYS_UN_H
++# include <sys/un.h>
++#endif])
++
++dnl Check for scsireq_t and sg_io_hdr_t members
++AC_CHECK_MEMBERS([scsireq_t.cmd, sg_io_hdr_t.interface_id],,,
++[#include <sys/types.h>
++#ifdef HAVE_SCSI_SG_H
++#include <scsi/sg.h>
++#endif])
++
++dnl Check for siginfo_t members
++AC_CHECK_MEMBERS([siginfo_t.si_fd],,,[#include <signal.h>])
++
++dnl Check for struct mtget members
++AC_CHECK_MEMBERS([struct mtget.mt_blksiz, struct mtget.mt_gstat, struct mtget.mt_blkno],,,
++[#include <sys/types.h>
++#ifdef HAVE_SYS_MTIO_H
++#include <sys/mtio.h>
++#endif])
++
++dnl Check for struct option
++AC_CHECK_MEMBERS([struct option.name],,,
++[#ifdef HAVE_GETOPT_H
++#include <getopt.h>
++#endif])
++
++dnl Check for stat.st_blocks and ns-resolved times
++AC_CHECK_MEMBERS([struct stat.st_blocks,struct stat.st_mtim,struct stat.st_ctim,struct stat.st_atim])
++
++dnl Check for sin6_scope_id
++AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_scope_id],,,
++[#ifdef HAVE_SYS_TYPES_H
++#include <sys/types.h>
++#endif
++#ifdef HAVE_NETINET_IN_H
++#include <netinet/in.h>
++#endif])
++
++dnl Check for ns_msg ptr member
++AC_CHECK_MEMBERS([ns_msg._msg_ptr],,,
++[#ifdef HAVE_SYS_TYPES_H
++#include <sys/types.h>
++#endif
++#ifdef HAVE_NETINET_IN_H
++# include <netinet/in.h>
++#endif
++#ifdef HAVE_ARPA_NAMESER_H
++# include <arpa/nameser.h>
++#endif])
++
++dnl Check for struct icmpstat.icps_outhist
++AC_CHECK_MEMBERS([struct icmpstat.icps_outhist],,,
++[#ifdef HAVE_SYS_TYPES_H
++#include <sys/types.h>
++#endif
++#ifdef HAVE_ALIAS_H
++#include <alias.h>
++#endif
++#ifdef HAVE_SYS_SOCKET_H
++#include <sys/socket.h>
++#endif
++#ifdef HAVE_SYS_SOCKETVAR_H
++#include <sys/socketvar.h>
++#endif
++#ifdef HAVE_SYS_TIMEOUT_H
++#include <sys/timeout.h>
++#endif
++#ifdef HAVE_NETINET_IN_H
++#include <netinet/in.h>
++#endif
++#ifdef HAVE_NETINET_IN_SYSTM_H
++#include <netinet/in_systm.h>
++#endif
++#ifdef HAVE_NETINET_IP_H
++#include <netinet/ip.h>
++#endif
++#ifdef HAVE_NETINET_IP_VAR_H
++#include <netinet/ip_var.h>
++#endif
++#ifdef HAVE_NETINET_IP_ICMP_H
++#include <netinet/ip_icmp.h>
++#endif
++#ifdef HAVE_NETINET_ICMP_VAR
++#include <netinet/icmp_var.h>
++#endif])
++
++dnl Check for struct ifreq.ifr_hwaddr
++AC_CHECK_MEMBERS([struct ifreq.ifr_hwaddr],,,
++[#ifdef HAVE_SYS_TYPES_H
++#include <sys/types.h>
++#endif
++#ifdef HAVE_NET_IF_H
++# include <net/if.h>
++#endif])
++
++dnl Check for the external timezone variables timezone and daylight
++AC_CACHE_CHECK([for timezone variable], ac_cv_have_timezone,
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]], [[timezone = 1]])],[ac_cv_have_timezone="yes"],[ac_cv_have_timezone="no"]))
++if test "$ac_cv_have_timezone" = "yes"
++then
++ AC_DEFINE(HAVE_TIMEZONE, 1, [Define if you have the timezone variable])
++fi
++AC_CACHE_CHECK([for daylight variable], ac_cv_have_daylight,
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]], [[daylight = 1]])],[ac_cv_have_daylight="yes"],[ac_cv_have_daylight="no"]))
++if test "$ac_cv_have_daylight" = "yes"
++then
++ AC_DEFINE(HAVE_DAYLIGHT, 1, [Define if you have the daylight variable])
++fi
++
++dnl Check for isinf
++AC_CACHE_CHECK([for isinf], ac_cv_have_isinf,
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>]], [[float f = 0.0; int i=isinf(f)]])],[ac_cv_have_isinf="yes"],[ac_cv_have_isinf="no"]))
++if test "$ac_cv_have_isinf" = "yes"
++then
++ AC_DEFINE(HAVE_ISINF, 1, [Define to 1 if you have the `isinf' function.])
++fi
++
++dnl Check for isnan
++AC_CACHE_CHECK([for isnan], ac_cv_have_isnan,
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>]], [[float f = 0.0; int i=isnan(f)]])],[ac_cv_have_isnan="yes"],[ac_cv_have_isnan="no"]))
++if test "$ac_cv_have_isnan" = "yes"
++then
++ AC_DEFINE(HAVE_ISNAN, 1, [Define to 1 if you have the `isnan' function.])
++fi
++
++dnl *** check for the need to define platform-specific symbols
++
++case $host_cpu in
++ *i[[3456789]]86*) WINE_CHECK_DEFINE([__i386__]) ;;
++ *x86_64*) WINE_CHECK_DEFINE([__x86_64__]) ;;
++ *alpha*) WINE_CHECK_DEFINE([__ALPHA__]) ;;
++ *sparc*) WINE_CHECK_DEFINE([__sparc__]) ;;
++ *powerpc*) WINE_CHECK_DEFINE([__powerpc__]) ;;
++esac
++
++case $host_vendor in
++ *sun*) WINE_CHECK_DEFINE([__sun__]) ;;
++esac
++
++dnl **** Generate output files ****
++
++AH_TOP([#ifndef WINE_CROSSTEST
++#define __WINE_CONFIG_H])
++AH_BOTTOM([#endif /* WINE_CROSSTEST */])
++
++AC_CONFIG_COMMANDS([include/stamp-h], [echo timestamp > include/stamp-h])
++
++WINE_CONFIG_SYMLINK(dlls/wineps.drv/generic.ppd)
++WINE_CONFIG_SYMLINK(fonts/marlett.ttf,,enable_fonts)
++WINE_CONFIG_SYMLINK(fonts/symbol.ttf,,enable_fonts)
++WINE_CONFIG_SYMLINK(fonts/tahoma.ttf,,enable_fonts)
++WINE_CONFIG_SYMLINK(fonts/tahomabd.ttf,,enable_fonts)
++WINE_CONFIG_SYMLINK(tools/l_intl.nls)
++WINE_CONFIG_SYMLINK(wine,tools/winewrapper)
++
++WINE_CONFIG_EXTRA_DIR(dlls/gdi32/enhmfdrv)
++WINE_CONFIG_EXTRA_DIR(dlls/gdi32/mfdrv)
++WINE_CONFIG_EXTRA_DIR(dlls/kernel32/nls)
++WINE_CONFIG_EXTRA_DIR(dlls/user32/resources)
++WINE_CONFIG_EXTRA_DIR(dlls/wineps.drv/data)
++WINE_CONFIG_EXTRA_DIR(include/wine)
++
++WINE_CONFIG_MAKERULES([Make.rules],[MAKE_RULES])
++WINE_CONFIG_MAKERULES([Maketest.rules],[MAKE_TEST_RULES],[Make.rules])
++WINE_CONFIG_MAKERULES([dlls/Makedll.rules],[MAKE_DLL_RULES],[Make.rules])
++WINE_CONFIG_MAKERULES([dlls/Makeimplib.rules],[MAKE_IMPLIB_RULES],[Make.rules])
++WINE_CONFIG_MAKERULES([programs/Makeprog.rules],[MAKE_PROG_RULES],[Make.rules])
++
++WINE_CONFIG_DLL(acledit)
++WINE_CONFIG_DLL(aclui,,[aclui])
++WINE_CONFIG_DLL(activeds,,[activeds])
++WINE_CONFIG_DLL(actxprxy)
++WINE_CONFIG_LIB(adsiid)
++WINE_CONFIG_DLL(advapi32,,[advapi32])
++WINE_CONFIG_TEST(dlls/advapi32/tests)
++WINE_CONFIG_DLL(advpack,,[advpack])
++WINE_CONFIG_TEST(dlls/advpack/tests)
++WINE_CONFIG_DLL(amstream)
++WINE_CONFIG_TEST(dlls/amstream/tests)
++WINE_CONFIG_DLL(appwiz.cpl)
++WINE_CONFIG_DLL(atl,,[atl])
++WINE_CONFIG_TEST(dlls/atl/tests)
++WINE_CONFIG_DLL(authz)
++WINE_CONFIG_DLL(avicap32,,[avicap32])
++WINE_CONFIG_DLL(avifil32,,[avifil32])
++WINE_CONFIG_TEST(dlls/avifil32/tests)
++WINE_CONFIG_DLL(avifile.dll16,enable_win16)
++WINE_CONFIG_DLL(avrt,,[avrt])
++WINE_CONFIG_DLL(bcrypt)
++WINE_CONFIG_DLL(browseui)
++WINE_CONFIG_TEST(dlls/browseui/tests)
++WINE_CONFIG_DLL(cabinet,,[cabinet])
++WINE_CONFIG_TEST(dlls/cabinet/tests)
++WINE_CONFIG_DLL(capi2032,,[capi2032])
++WINE_CONFIG_DLL(cards,,[cards])
++WINE_CONFIG_DLL(cfgmgr32,,[cfgmgr32])
++WINE_CONFIG_DLL(clusapi,,[clusapi])
++WINE_CONFIG_DLL(comcat)
++WINE_CONFIG_TEST(dlls/comcat/tests)
++WINE_CONFIG_DLL(comctl32,,[comctl32])
++WINE_CONFIG_TEST(dlls/comctl32/tests)
++WINE_CONFIG_DLL(comdlg32,,[comdlg32])
++WINE_CONFIG_TEST(dlls/comdlg32/tests)
++WINE_CONFIG_DLL(comm.drv16,enable_win16)
++WINE_CONFIG_DLL(commdlg.dll16,enable_win16)
++WINE_CONFIG_DLL(compobj.dll16,enable_win16)
++WINE_CONFIG_DLL(compstui,,[compstui])
++WINE_CONFIG_DLL(credui,,[credui])
++WINE_CONFIG_TEST(dlls/credui/tests)
++WINE_CONFIG_DLL(crtdll,,[crtdll])
++WINE_CONFIG_DLL(crypt32,,[crypt32])
++WINE_CONFIG_TEST(dlls/crypt32/tests)
++WINE_CONFIG_DLL(cryptdlg)
++WINE_CONFIG_DLL(cryptdll,,[cryptdll])
++WINE_CONFIG_DLL(cryptnet,,[cryptnet])
++WINE_CONFIG_TEST(dlls/cryptnet/tests)
++WINE_CONFIG_DLL(cryptui,,[cryptui])
++WINE_CONFIG_TEST(dlls/cryptui/tests)
++WINE_CONFIG_DLL(ctapi32)
++WINE_CONFIG_DLL(ctl3d.dll16,enable_win16)
++WINE_CONFIG_DLL(ctl3d32,,[ctl3d32])
++WINE_CONFIG_DLL(ctl3dv2.dll16,enable_win16)
++WINE_CONFIG_DLL(d3d10,,[d3d10])
++WINE_CONFIG_TEST(dlls/d3d10/tests)
++WINE_CONFIG_DLL(d3d10core,,[d3d10core])
++WINE_CONFIG_TEST(dlls/d3d10core/tests)
++WINE_CONFIG_DLL(d3d8,,[d3d8])
++WINE_CONFIG_TEST(dlls/d3d8/tests)
++WINE_CONFIG_DLL(d3d9,,[d3d9])
++WINE_CONFIG_TEST(dlls/d3d9/tests)
++WINE_CONFIG_DLL(d3dim,,[d3dim])
++WINE_CONFIG_DLL(d3drm,,[d3drm])
++WINE_CONFIG_TEST(dlls/d3drm/tests)
++WINE_CONFIG_DLL(d3dx9_24)
++WINE_CONFIG_DLL(d3dx9_25)
++WINE_CONFIG_DLL(d3dx9_26)
++WINE_CONFIG_DLL(d3dx9_27)
++WINE_CONFIG_DLL(d3dx9_28)
++WINE_CONFIG_DLL(d3dx9_29)
++WINE_CONFIG_DLL(d3dx9_30)
++WINE_CONFIG_DLL(d3dx9_31)
++WINE_CONFIG_DLL(d3dx9_32)
++WINE_CONFIG_DLL(d3dx9_33)
++WINE_CONFIG_DLL(d3dx9_34)
++WINE_CONFIG_DLL(d3dx9_35)
++WINE_CONFIG_DLL(d3dx9_36,,[d3dx9])
++WINE_CONFIG_TEST(dlls/d3dx9_36/tests)
++WINE_CONFIG_DLL(d3dx9_37)
++WINE_CONFIG_DLL(d3dx9_38)
++WINE_CONFIG_DLL(d3dx9_39)
++WINE_CONFIG_DLL(d3dx9_40)
++WINE_CONFIG_DLL(d3dx9_41)
++WINE_CONFIG_DLL(d3dx9_42)
++WINE_CONFIG_DLL(d3dxof,,[d3dxof])
++WINE_CONFIG_TEST(dlls/d3dxof/tests)
++WINE_CONFIG_DLL(dbghelp,,[dbghelp])
++WINE_CONFIG_DLL(dciman32,,[dciman32])
++WINE_CONFIG_DLL(ddeml.dll16,enable_win16)
++WINE_CONFIG_DLL(ddraw,,[ddraw])
++WINE_CONFIG_TEST(dlls/ddraw/tests)
++WINE_CONFIG_DLL(ddrawex)
++WINE_CONFIG_TEST(dlls/ddrawex/tests)
++WINE_CONFIG_DLL(devenum)
++WINE_CONFIG_DLL(dinput,,[dinput],[data_formats.c])
++WINE_CONFIG_TEST(dlls/dinput/tests)
++WINE_CONFIG_DLL(dinput8,,[dinput8])
++WINE_CONFIG_DLL(dispdib.dll16,enable_win16)
++WINE_CONFIG_DLL(dispex)
++WINE_CONFIG_TEST(dlls/dispex/tests)
++WINE_CONFIG_DLL(display.drv16,enable_win16)
++WINE_CONFIG_DLL(dmband)
++WINE_CONFIG_DLL(dmcompos)
++WINE_CONFIG_DLL(dmime)
++WINE_CONFIG_DLL(dmloader)
++WINE_CONFIG_TEST(dlls/dmloader/tests)
++WINE_CONFIG_DLL(dmscript)
++WINE_CONFIG_DLL(dmstyle)
++WINE_CONFIG_DLL(dmsynth)
++WINE_CONFIG_DLL(dmusic)
++WINE_CONFIG_DLL(dmusic32,,[dmusic32])
++WINE_CONFIG_DLL(dnsapi,,[dnsapi])
++WINE_CONFIG_TEST(dlls/dnsapi/tests)
++WINE_CONFIG_DLL(dplay,,[dplay])
++WINE_CONFIG_DLL(dplayx,,[dplayx])
++WINE_CONFIG_TEST(dlls/dplayx/tests)
++WINE_CONFIG_DLL(dpnaddr)
++WINE_CONFIG_DLL(dpnet,,[dpnet])
++WINE_CONFIG_DLL(dpnhpast)
++WINE_CONFIG_DLL(dpnlobby)
++WINE_CONFIG_DLL(dpwsockx)
++WINE_CONFIG_DLL(drmclien)
++WINE_CONFIG_DLL(dsound,,[dsound])
++WINE_CONFIG_TEST(dlls/dsound/tests)
++WINE_CONFIG_DLL(dssenh)
++WINE_CONFIG_DLL(dswave)
++WINE_CONFIG_DLL(dwmapi,,[dwmapi])
++WINE_CONFIG_DLL(dxdiagn)
++WINE_CONFIG_TEST(dlls/dxdiagn/tests)
++WINE_CONFIG_LIB(dxerr8)
++WINE_CONFIG_LIB(dxerr9)
++WINE_CONFIG_DLL(dxgi,,[dxgi])
++WINE_CONFIG_TEST(dlls/dxgi/tests)
++WINE_CONFIG_LIB(dxguid)
++WINE_CONFIG_DLL(faultrep)
++WINE_CONFIG_DLL(fltlib)
++WINE_CONFIG_DLL(fusion)
++WINE_CONFIG_TEST(dlls/fusion/tests)
++WINE_CONFIG_DLL(fwpuclnt)
++WINE_CONFIG_DLL(gameux)
++WINE_CONFIG_DLL(gdi.exe16,enable_win16)
++WINE_CONFIG_DLL(gdi32,,[gdi32])
++WINE_CONFIG_TEST(dlls/gdi32/tests)
++WINE_CONFIG_DLL(gdiplus,,[gdiplus])
++WINE_CONFIG_TEST(dlls/gdiplus/tests)
++WINE_CONFIG_DLL(glu32,,[glu32])
++WINE_CONFIG_DLL(gphoto2.ds)
++WINE_CONFIG_DLL(gpkcsp)
++WINE_CONFIG_DLL(hal)
++WINE_CONFIG_DLL(hhctrl.ocx)
++WINE_CONFIG_DLL(hid,,[hid])
++WINE_CONFIG_DLL(hlink,,[hlink])
++WINE_CONFIG_TEST(dlls/hlink/tests)
++WINE_CONFIG_DLL(hnetcfg)
++WINE_CONFIG_DLL(httpapi)
++WINE_CONFIG_DLL(iccvid)
++WINE_CONFIG_DLL(icmp)
++WINE_CONFIG_DLL(ifsmgr.vxd,enable_win16)
++WINE_CONFIG_DLL(imaadp32.acm)
++WINE_CONFIG_DLL(imagehlp,,[imagehlp])
++WINE_CONFIG_TEST(dlls/imagehlp/tests)
++WINE_CONFIG_DLL(imm.dll16,enable_win16)
++WINE_CONFIG_DLL(imm32,,[imm32])
++WINE_CONFIG_TEST(dlls/imm32/tests)
++WINE_CONFIG_DLL(inetcomm,,[inetcomm])
++WINE_CONFIG_TEST(dlls/inetcomm/tests)
++WINE_CONFIG_DLL(inetmib1)
++WINE_CONFIG_TEST(dlls/inetmib1/tests)
++WINE_CONFIG_DLL(infosoft)
++WINE_CONFIG_TEST(dlls/infosoft/tests)
++WINE_CONFIG_DLL(initpki)
++WINE_CONFIG_DLL(inkobj)
++WINE_CONFIG_DLL(inseng)
++WINE_CONFIG_DLL(iphlpapi,,[iphlpapi])
++WINE_CONFIG_TEST(dlls/iphlpapi/tests)
++WINE_CONFIG_DLL(itircl)
++WINE_CONFIG_DLL(itss)
++WINE_CONFIG_TEST(dlls/itss/tests)
++WINE_CONFIG_DLL(jscript)
++WINE_CONFIG_TEST(dlls/jscript/tests)
++WINE_CONFIG_DLL(kernel32,,[kernel32])
++WINE_CONFIG_TEST(dlls/kernel32/tests)
++WINE_CONFIG_DLL(keyboard.drv16,enable_win16)
++WINE_CONFIG_DLL(krnl386.exe16,enable_win16,[kernel])
++WINE_CONFIG_DLL(loadperf,,[loadperf])
++WINE_CONFIG_DLL(localspl)
++WINE_CONFIG_TEST(dlls/localspl/tests)
++WINE_CONFIG_DLL(localui)
++WINE_CONFIG_TEST(dlls/localui/tests)
++WINE_CONFIG_DLL(lz32,,[lz32])
++WINE_CONFIG_TEST(dlls/lz32/tests)
++WINE_CONFIG_DLL(lzexpand.dll16,enable_win16)
++WINE_CONFIG_DLL(mapi32,,[mapi32])
++WINE_CONFIG_TEST(dlls/mapi32/tests)
++WINE_CONFIG_DLL(mapistub)
++WINE_CONFIG_DLL(mciavi32)
++WINE_CONFIG_DLL(mcicda)
++WINE_CONFIG_DLL(mciqtz32)
++WINE_CONFIG_DLL(mciseq)
++WINE_CONFIG_DLL(mciwave)
++WINE_CONFIG_DLL(midimap)
++WINE_CONFIG_DLL(mlang,,[mlang])
++WINE_CONFIG_TEST(dlls/mlang/tests)
++WINE_CONFIG_DLL(mmdevapi)
++WINE_CONFIG_TEST(dlls/mmdevapi/tests)
++WINE_CONFIG_DLL(mmdevldr.vxd,enable_win16)
++WINE_CONFIG_DLL(mmsystem.dll16,enable_win16)
++WINE_CONFIG_DLL(monodebg.vxd,enable_win16)
++WINE_CONFIG_DLL(mountmgr.sys)
++WINE_CONFIG_DLL(mouse.drv16,enable_win16)
++WINE_CONFIG_DLL(mpr,,[mpr])
++WINE_CONFIG_DLL(mprapi,,[mprapi])
++WINE_CONFIG_DLL(msacm.dll16,enable_win16)
++WINE_CONFIG_DLL(msacm32.drv)
++WINE_CONFIG_DLL(msacm32,,[msacm32])
++WINE_CONFIG_TEST(dlls/msacm32/tests)
++WINE_CONFIG_DLL(msadp32.acm)
++WINE_CONFIG_DLL(mscat32)
++WINE_CONFIG_DLL(mscms,,[mscms])
++WINE_CONFIG_TEST(dlls/mscms/tests)
++WINE_CONFIG_DLL(mscoree)
++WINE_CONFIG_DLL(msctf)
++WINE_CONFIG_TEST(dlls/msctf/tests)
++WINE_CONFIG_DLL(msdaps)
++WINE_CONFIG_DLL(msdmo,,[msdmo])
++WINE_CONFIG_DLL(msftedit)
++WINE_CONFIG_DLL(msg711.acm)
++WINE_CONFIG_DLL(msgsm32.acm)
++WINE_CONFIG_DLL(mshtml.tlb)
++WINE_CONFIG_DLL(mshtml,,[mshtml])
++WINE_CONFIG_TEST(dlls/mshtml/tests)
++WINE_CONFIG_DLL(msi,,[msi])
++WINE_CONFIG_TEST(dlls/msi/tests)
++WINE_CONFIG_DLL(msimg32,,[msimg32])
++WINE_CONFIG_DLL(msimtf)
++WINE_CONFIG_DLL(msisip)
++WINE_CONFIG_DLL(msisys.ocx)
++WINE_CONFIG_DLL(msnet32)
++WINE_CONFIG_DLL(msrle32)
++WINE_CONFIG_DLL(mssign32)
++WINE_CONFIG_DLL(mssip32)
++WINE_CONFIG_DLL(mstask)
++WINE_CONFIG_TEST(dlls/mstask/tests)
++WINE_CONFIG_DLL(msvcirt)
++WINE_CONFIG_DLL(msvcp90)
++WINE_CONFIG_TEST(dlls/msvcp90/tests)
++WINE_CONFIG_DLL(msvcr100)
++WINE_CONFIG_DLL(msvcr70,,[msvcr70])
++WINE_CONFIG_DLL(msvcr71,,[msvcr71])
++WINE_CONFIG_DLL(msvcr80)
++WINE_CONFIG_DLL(msvcr90)
++WINE_CONFIG_TEST(dlls/msvcr90/tests)
++WINE_CONFIG_DLL(msvcrt,,[msvcrt])
++WINE_CONFIG_TEST(dlls/msvcrt/tests)
++WINE_CONFIG_DLL(msvcrt20,,[msvcrt20])
++WINE_CONFIG_DLL(msvcrt40,,[msvcrt40])
++WINE_CONFIG_DLL(msvcrtd,,[msvcrtd])
++WINE_CONFIG_TEST(dlls/msvcrtd/tests)
++WINE_CONFIG_DLL(msvfw32,,[msvfw32])
++WINE_CONFIG_TEST(dlls/msvfw32/tests)
++WINE_CONFIG_DLL(msvidc32)
++WINE_CONFIG_DLL(msvideo.dll16,enable_win16)
++WINE_CONFIG_DLL(mswsock,,[mswsock])
++WINE_CONFIG_DLL(msxml3)
++WINE_CONFIG_TEST(dlls/msxml3/tests)
++WINE_CONFIG_DLL(msxml4)
++WINE_CONFIG_DLL(nddeapi,,[nddeapi])
++WINE_CONFIG_DLL(netapi32,,[netapi32])
++WINE_CONFIG_TEST(dlls/netapi32/tests)
++WINE_CONFIG_DLL(newdev,,[newdev])
++WINE_CONFIG_DLL(ntdll,,[ntdll])
++WINE_CONFIG_TEST(dlls/ntdll/tests)
++WINE_CONFIG_DLL(ntdsapi,,[ntdsapi])
++WINE_CONFIG_TEST(dlls/ntdsapi/tests)
++WINE_CONFIG_DLL(ntoskrnl.exe,,[ntoskrnl.exe])
++WINE_CONFIG_DLL(ntprint)
++WINE_CONFIG_TEST(dlls/ntprint/tests)
++WINE_CONFIG_DLL(objsel)
++WINE_CONFIG_DLL(odbc32,,[odbc32])
++WINE_CONFIG_DLL(odbccp32,,[odbccp32])
++WINE_CONFIG_TEST(dlls/odbccp32/tests)
++WINE_CONFIG_DLL(ole2.dll16,enable_win16)
++WINE_CONFIG_DLL(ole2conv.dll16,enable_win16)
++WINE_CONFIG_DLL(ole2disp.dll16,enable_win16)
++WINE_CONFIG_DLL(ole2nls.dll16,enable_win16)
++WINE_CONFIG_DLL(ole2prox.dll16,enable_win16)
++WINE_CONFIG_DLL(ole2thk.dll16,enable_win16)
++WINE_CONFIG_DLL(ole32,,[ole32])
++WINE_CONFIG_TEST(dlls/ole32/tests)
++WINE_CONFIG_DLL(oleacc,,[oleacc])
++WINE_CONFIG_TEST(dlls/oleacc/tests)
++WINE_CONFIG_DLL(oleaut32,,[oleaut32])
++WINE_CONFIG_TEST(dlls/oleaut32/tests)
++WINE_CONFIG_DLL(olecli.dll16,enable_win16)
++WINE_CONFIG_DLL(olecli32,,[olecli32])
++WINE_CONFIG_DLL(oledb32)
++WINE_CONFIG_TEST(dlls/oledb32/tests)
++WINE_CONFIG_DLL(oledlg,,[oledlg])
++WINE_CONFIG_DLL(olepro32,,[olepro32])
++WINE_CONFIG_DLL(olesvr.dll16,enable_win16)
++WINE_CONFIG_DLL(olesvr32,,[olesvr32])
++WINE_CONFIG_DLL(olethk32)
++WINE_CONFIG_DLL(openal32)
++WINE_CONFIG_DLL(opengl32,,[opengl32])
++WINE_CONFIG_TEST(dlls/opengl32/tests)
++WINE_CONFIG_DLL(pdh,,[pdh])
++WINE_CONFIG_TEST(dlls/pdh/tests)
++WINE_CONFIG_DLL(pidgen)
++WINE_CONFIG_DLL(powrprof,,[powrprof])
++WINE_CONFIG_DLL(printui)
++WINE_CONFIG_DLL(propsys,,[propsys])
++WINE_CONFIG_TEST(dlls/propsys/tests)
++WINE_CONFIG_DLL(psapi,,[psapi])
++WINE_CONFIG_TEST(dlls/psapi/tests)
++WINE_CONFIG_DLL(pstorec)
++WINE_CONFIG_DLL(qcap)
++WINE_CONFIG_DLL(qedit)
++WINE_CONFIG_TEST(dlls/qedit/tests)
++WINE_CONFIG_DLL(qmgr)
++WINE_CONFIG_TEST(dlls/qmgr/tests)
++WINE_CONFIG_DLL(qmgrprxy)
++WINE_CONFIG_DLL(quartz,,[quartz])
++WINE_CONFIG_TEST(dlls/quartz/tests)
++WINE_CONFIG_DLL(query)
++WINE_CONFIG_DLL(rasapi16.dll16,enable_win16)
++WINE_CONFIG_DLL(rasapi32,,[rasapi32])
++WINE_CONFIG_TEST(dlls/rasapi32/tests)
++WINE_CONFIG_DLL(rasdlg,,[rasdlg])
++WINE_CONFIG_DLL(resutils,,[resutils])
++WINE_CONFIG_DLL(riched20,,[riched20])
++WINE_CONFIG_TEST(dlls/riched20/tests)
++WINE_CONFIG_DLL(riched32)
++WINE_CONFIG_TEST(dlls/riched32/tests)
++WINE_CONFIG_DLL(rpcrt4,,[rpcrt4])
++WINE_CONFIG_TEST(dlls/rpcrt4/tests)
++WINE_CONFIG_DLL(rsabase)
++WINE_CONFIG_DLL(rsaenh,,[rsaenh])
++WINE_CONFIG_TEST(dlls/rsaenh/tests)
++WINE_CONFIG_DLL(rtutils,,[rtutils])
++WINE_CONFIG_DLL(samlib)
++WINE_CONFIG_DLL(sane.ds)
++WINE_CONFIG_DLL(sccbase)
++WINE_CONFIG_DLL(schannel)
++WINE_CONFIG_TEST(dlls/schannel/tests)
++WINE_CONFIG_DLL(secur32,,[secur32])
++WINE_CONFIG_TEST(dlls/secur32/tests)
++WINE_CONFIG_DLL(security)
++WINE_CONFIG_DLL(sensapi,,[sensapi])
++WINE_CONFIG_DLL(serialui,,[serialui])
++WINE_CONFIG_TEST(dlls/serialui/tests)
++WINE_CONFIG_DLL(setupapi,,[setupapi])
++WINE_CONFIG_TEST(dlls/setupapi/tests)
++WINE_CONFIG_DLL(setupx.dll16,enable_win16)
++WINE_CONFIG_DLL(sfc,,[sfc])
++WINE_CONFIG_DLL(sfc_os,,[sfc_os])
++WINE_CONFIG_DLL(shdoclc)
++WINE_CONFIG_DLL(shdocvw,,[shdocvw])
++WINE_CONFIG_TEST(dlls/shdocvw/tests)
++WINE_CONFIG_DLL(shell.dll16,enable_win16)
++WINE_CONFIG_DLL(shell32,,[shell32])
++WINE_CONFIG_TEST(dlls/shell32/tests)
++WINE_CONFIG_DLL(shfolder,,[shfolder])
++WINE_CONFIG_DLL(shlwapi,,[shlwapi])
++WINE_CONFIG_TEST(dlls/shlwapi/tests)
++WINE_CONFIG_DLL(slbcsp)
++WINE_CONFIG_DLL(slc,,[slc])
++WINE_CONFIG_DLL(snmpapi,,[snmpapi])
++WINE_CONFIG_TEST(dlls/snmpapi/tests)
++WINE_CONFIG_DLL(softpub)
++WINE_CONFIG_DLL(sound.drv16,enable_win16)
++WINE_CONFIG_DLL(spoolss,,[spoolss])
++WINE_CONFIG_TEST(dlls/spoolss/tests)
++WINE_CONFIG_DLL(stdole2.tlb)
++WINE_CONFIG_DLL(stdole32.tlb)
++WINE_CONFIG_DLL(sti,,[sti])
++WINE_CONFIG_TEST(dlls/sti/tests)
++WINE_CONFIG_DLL(storage.dll16,enable_win16)
++WINE_CONFIG_DLL(stress.dll16,enable_win16)
++WINE_CONFIG_LIB(strmiids)
++WINE_CONFIG_DLL(svrapi)
++WINE_CONFIG_DLL(sxs)
++WINE_CONFIG_DLL(system.drv16,enable_win16)
++WINE_CONFIG_DLL(t2embed)
++WINE_CONFIG_DLL(tapi32,,[tapi32])
++WINE_CONFIG_DLL(toolhelp.dll16,enable_win16)
++WINE_CONFIG_DLL(traffic)
++WINE_CONFIG_DLL(twain.dll16,enable_win16)
++WINE_CONFIG_DLL(twain_32)
++WINE_CONFIG_TEST(dlls/twain_32/tests)
++WINE_CONFIG_DLL(typelib.dll16,enable_win16)
++WINE_CONFIG_DLL(unicows,,[unicows])
++WINE_CONFIG_DLL(updspapi)
++WINE_CONFIG_DLL(url,,[url])
++WINE_CONFIG_DLL(urlmon,,[urlmon])
++WINE_CONFIG_TEST(dlls/urlmon/tests)
++WINE_CONFIG_DLL(usbd.sys,,[usbd.sys])
++WINE_CONFIG_DLL(user.exe16,enable_win16)
++WINE_CONFIG_DLL(user32,,[user32])
++WINE_CONFIG_TEST(dlls/user32/tests)
++WINE_CONFIG_DLL(userenv,,[userenv])
++WINE_CONFIG_TEST(dlls/userenv/tests)
++WINE_CONFIG_DLL(usp10,,[usp10])
++WINE_CONFIG_TEST(dlls/usp10/tests)
++WINE_CONFIG_LIB(uuid)
++WINE_CONFIG_DLL(uxtheme,,[uxtheme])
++WINE_CONFIG_TEST(dlls/uxtheme/tests)
++WINE_CONFIG_DLL(vdhcp.vxd,enable_win16)
++WINE_CONFIG_DLL(vdmdbg,,[vdmdbg])
++WINE_CONFIG_DLL(ver.dll16,enable_win16)
++WINE_CONFIG_DLL(version,,[version])
++WINE_CONFIG_TEST(dlls/version/tests)
++WINE_CONFIG_DLL(vmm.vxd,enable_win16)
++WINE_CONFIG_DLL(vnbt.vxd,enable_win16)
++WINE_CONFIG_DLL(vnetbios.vxd,enable_win16)
++WINE_CONFIG_DLL(vtdapi.vxd,enable_win16)
++WINE_CONFIG_DLL(vwin32.vxd,enable_win16)
++WINE_CONFIG_DLL(w32skrnl,enable_win16)
++WINE_CONFIG_DLL(w32sys.dll16,enable_win16)
++WINE_CONFIG_DLL(wbemprox)
++WINE_CONFIG_DLL(wiaservc)
++WINE_CONFIG_DLL(win32s16.dll16,enable_win16)
++WINE_CONFIG_DLL(win87em.dll16,enable_win16)
++WINE_CONFIG_DLL(winaspi.dll16,enable_win16)
++WINE_CONFIG_DLL(windebug.dll16,enable_win16)
++WINE_CONFIG_DLL(windowscodecs,,[windowscodecs])
++WINE_CONFIG_TEST(dlls/windowscodecs/tests)
++WINE_CONFIG_DLL(winealsa.drv)
++WINE_CONFIG_DLL(wineaudioio.drv)
++WINE_CONFIG_DLL(winecoreaudio.drv)
++WINE_CONFIG_LIB(winecrt0)
++WINE_CONFIG_DLL(wined3d,,[wined3d])
++WINE_CONFIG_DLL(wineesd.drv)
++WINE_CONFIG_DLL(winejack.drv)
++WINE_CONFIG_DLL(winejoystick.drv)
++WINE_CONFIG_DLL(winemapi)
++WINE_CONFIG_DLL(winemp3.acm)
++WINE_CONFIG_DLL(winenas.drv)
++WINE_CONFIG_DLL(wineoss.drv)
++WINE_CONFIG_DLL(wineps.drv)
++WINE_CONFIG_DLL(wineps16.drv16,enable_win16)
++WINE_CONFIG_DLL(winequartz.drv)
++WINE_CONFIG_DLL(winex11.drv)
++WINE_CONFIG_DLL(wing.dll16,enable_win16)
++WINE_CONFIG_DLL(wing32)
++WINE_CONFIG_DLL(winhttp,,[winhttp])
++WINE_CONFIG_TEST(dlls/winhttp/tests)
++WINE_CONFIG_DLL(wininet,,[wininet])
++WINE_CONFIG_TEST(dlls/wininet/tests)
++WINE_CONFIG_DLL(winmm,,[winmm])
++WINE_CONFIG_TEST(dlls/winmm/tests)
++WINE_CONFIG_DLL(winnls.dll16,enable_win16)
++WINE_CONFIG_DLL(winnls32,,[winnls32])
++WINE_CONFIG_DLL(winscard,,[winscard])
++WINE_CONFIG_DLL(winsock.dll16,enable_win16)
++WINE_CONFIG_DLL(winspool.drv,,[winspool])
++WINE_CONFIG_TEST(dlls/winspool.drv/tests)
++WINE_CONFIG_DLL(wintab.dll16,enable_win16)
++WINE_CONFIG_DLL(wintab32,,[wintab32])
++WINE_CONFIG_TEST(dlls/wintab32/tests)
++WINE_CONFIG_DLL(wintrust,,[wintrust])
++WINE_CONFIG_TEST(dlls/wintrust/tests)
++WINE_CONFIG_DLL(wldap32,,[wldap32])
++WINE_CONFIG_TEST(dlls/wldap32/tests)
++WINE_CONFIG_DLL(wmi)
++WINE_CONFIG_DLL(wmiutils)
++WINE_CONFIG_DLL(wnaspi32,,[wnaspi32])
++WINE_CONFIG_DLL(wow32,enable_win16,[wow32])
++WINE_CONFIG_DLL(ws2_32,,[ws2_32])
++WINE_CONFIG_TEST(dlls/ws2_32/tests)
++WINE_CONFIG_DLL(wsock32,,[wsock32])
++WINE_CONFIG_DLL(wtsapi32,,[wtsapi32])
++WINE_CONFIG_DLL(wuapi)
++WINE_CONFIG_DLL(wuaueng)
++WINE_CONFIG_DLL(xinput1_1)
++WINE_CONFIG_DLL(xinput1_2)
++WINE_CONFIG_DLL(xinput1_3,,[xinput])
++WINE_CONFIG_TEST(dlls/xinput1_3/tests)
++WINE_CONFIG_DLL(xinput9_1_0)
++WINE_CONFIG_DLL(xmllite)
++WINE_CONFIG_TEST(dlls/xmllite/tests)
++WINE_CONFIG_MAKEFILE([documentation])
++WINE_CONFIG_MAKEFILE([fonts])
++WINE_CONFIG_MAKEFILE([include])
++WINE_CONFIG_MAKEFILE([libs/port])
++WINE_CONFIG_MAKEFILE([libs/wine])
++WINE_CONFIG_MAKEFILE([libs/wpp])
++WINE_CONFIG_MAKEFILE([loader])
++WINE_CONFIG_PROGRAM(attrib,install)
++WINE_CONFIG_PROGRAM(cacls,install)
++WINE_CONFIG_PROGRAM(clock,install)
++WINE_CONFIG_PROGRAM(cmd,install)
++WINE_CONFIG_TEST(programs/cmd/tests)
++WINE_CONFIG_PROGRAM(cmdlgtst)
++WINE_CONFIG_PROGRAM(control,install)
++WINE_CONFIG_PROGRAM(dxdiag,install)
++WINE_CONFIG_PROGRAM(eject,install)
++WINE_CONFIG_PROGRAM(expand,install)
++WINE_CONFIG_PROGRAM(explorer,install)
++WINE_CONFIG_PROGRAM(extrac32,install)
++WINE_CONFIG_PROGRAM(hh,install)
++WINE_CONFIG_PROGRAM(icinfo,install)
++WINE_CONFIG_PROGRAM(iexplore,install)
++WINE_CONFIG_PROGRAM(lodctr,install)
++WINE_CONFIG_PROGRAM(mshta,install)
++WINE_CONFIG_PROGRAM(msiexec,installbin)
++WINE_CONFIG_PROGRAM(net,install)
++WINE_CONFIG_PROGRAM(ngen,install)
++WINE_CONFIG_PROGRAM(notepad,installbin)
++WINE_CONFIG_PROGRAM(oleview,install)
++WINE_CONFIG_PROGRAM(ping,install)
++WINE_CONFIG_PROGRAM(progman,install)
++WINE_CONFIG_PROGRAM(reg,install)
++WINE_CONFIG_PROGRAM(regedit,installbin)
++WINE_CONFIG_PROGRAM(regsvr32,installbin)
++WINE_CONFIG_PROGRAM(rpcss,install)
++WINE_CONFIG_PROGRAM(rundll.exe16,install,enable_win16)
++WINE_CONFIG_PROGRAM(rundll32,install)
++WINE_CONFIG_PROGRAM(sc,install)
++WINE_CONFIG_PROGRAM(secedit,install)
++WINE_CONFIG_PROGRAM(services,install)
++WINE_CONFIG_PROGRAM(spoolsv,install)
++WINE_CONFIG_PROGRAM(start,install)
++WINE_CONFIG_PROGRAM(svchost,install)
++WINE_CONFIG_PROGRAM(taskmgr,install)
++WINE_CONFIG_PROGRAM(termsv,install)
++WINE_CONFIG_PROGRAM(uninstaller,install)
++WINE_CONFIG_PROGRAM(unlodctr,install)
++WINE_CONFIG_PROGRAM(view)
++WINE_CONFIG_PROGRAM(wineboot,installbin)
++WINE_CONFIG_PROGRAM(winebrowser,install)
++WINE_CONFIG_PROGRAM(winecfg,installbin)
++WINE_CONFIG_PROGRAM(wineconsole,installbin)
++WINE_CONFIG_PROGRAM(winedbg,installbin)
++WINE_CONFIG_PROGRAM(winedevice,install)
++WINE_CONFIG_PROGRAM(winefile,installbin)
++WINE_CONFIG_PROGRAM(winemenubuilder,install)
++WINE_CONFIG_PROGRAM(winemine,installbin)
++WINE_CONFIG_PROGRAM(winepath,installbin)
++WINE_CONFIG_PROGRAM(winetest)
++WINE_CONFIG_PROGRAM(winevdm,install,enable_win16)
++WINE_CONFIG_PROGRAM(winhelp.exe16,install,enable_win16)
++WINE_CONFIG_PROGRAM(winhlp32,install)
++WINE_CONFIG_PROGRAM(winoldap.mod16,install,enable_win16)
++WINE_CONFIG_PROGRAM(winver,install)
++WINE_CONFIG_PROGRAM(wordpad,install)
++WINE_CONFIG_PROGRAM(write,install)
++WINE_CONFIG_PROGRAM(wscript,install)
++WINE_CONFIG_PROGRAM(xcopy,install)
++WINE_CONFIG_MAKEFILE([server])
++WINE_CONFIG_TOOL(tools)
++WINE_CONFIG_TOOL(tools/widl)
++WINE_CONFIG_TOOL(tools/winebuild)
++WINE_CONFIG_TOOL(tools/winedump)
++WINE_CONFIG_TOOL(tools/winegcc)
++WINE_CONFIG_TOOL(tools/wmc)
++WINE_CONFIG_TOOL(tools/wrc)
++dnl End of auto-generated output commands
++
++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 && return
++$ALL_MAKEFILE_DEPENDS
++_WINE_EOF
++ AS_ERROR([could not create Makefile])
++}])
++
++AC_CONFIG_FILES([Make.tmp:Makefile.in])
++
++dnl Some final makefile rules
++
++if test -n "$with_wine64"
++then
++WINE_APPEND_RULE([ALL_MAKEFILE_DEPENDS],
++[all: fonts server $with_wine64/loader/wine
++fonts server:
++ \$(RM) \$[@] && \$(LN_S) $with_wine64/\$[@] \$[@]
++$with_wine64/loader/wine:
++ \$(RM) \$[@] && \$(LN_S) $ac_pwd/loader/wine \$[@]
++clean::
++ \$(RM) fonts server $with_wine64/loader/wine])
++fi
++
++WINE_APPEND_RULE([ALL_MAKEFILE_DEPENDS],
++[uninstall::
++ -rmdir \$(DESTDIR)\$(datadir)/wine \$(DESTDIR)\$(fakedlldir) \$(DESTDIR)\$(dlldir)])
++
++AC_OUTPUT
++
++if test "$no_create" = "yes"
++then
++ exit 0
++fi
++
++WINE_PRINT_MESSAGES
++
++echo "
++$as_me: Finished. Do '${ac_make}' to compile Wine.
++" >&AS_MESSAGE_FD
++
++dnl Local Variables:
++dnl comment-start: "dnl "
++dnl comment-end: ""
++dnl comment-start-skip: "\\bdnl\\b\\s *"
++dnl compile-command: "autoreconf --warnings=all"
++dnl End:
+diff -Nru a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
+--- a/dlls/gdi32/driver.c 2010-07-30 19:43:56.000000000 +0200
++++ b/dlls/gdi32/driver.c 2010-08-04 16:08:44.337222017 +0200
+@@ -3,6 +3,7 @@
+ *
+ * Copyright 1994 Bob Amstadt
+ * Copyright 1996, 2001 Alexandre Julliard
++ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+@@ -25,6 +26,7 @@
+ #include <stdarg.h>
+ #include <string.h>
+ #include <stdio.h>
++#include <stdlib.h>
+ #include "windef.h"
+ #include "winbase.h"
+ #include "winreg.h"
+@@ -213,6 +215,104 @@
+
+
+ /**********************************************************************
++ * Load_Dib_Driver
++ *
++ * Check if we want the DIB engine and try to load it
++ */
++static HMODULE Load_Dib_Driver(void)
++{
++ HMODULE module;
++
++ static const char *winedib_drv = "winedib.drv";
++
++ /* we do want use DIB Engine ? */
++ BOOL driverRequired = TRUE;
++
++ /* already checked env/registry for DIB driver ? */
++ BOOL envChecked = FALSE;
++
++ char *winedib;
++ char buffer[10];
++
++ /* environment variable WINEDIB takes precedence */
++ if( (winedib = getenv("WINEDIB")) != NULL)
++ {
++ if(!strcasecmp(winedib, "ON") ||
++ !strcasecmp(winedib, "TRUE") ||
++ !strcasecmp(winedib, "ENABLE") ||
++ !strcasecmp(winedib, "ENABLED")
++ )
++ {
++ TRACE("DIB Engine enabled by environment\n");
++ envChecked = TRUE;
++ driverRequired = TRUE;
++ }
++ else if(!strcasecmp(winedib, "OFF") ||
++ !strcasecmp(winedib, "FALSE") ||
++ !strcasecmp(winedib, "DISABLE") ||
++ !strcasecmp(winedib, "DISABLED")
++ )
++ {
++ TRACE("DIB Engine disabled by environment\n");
++ envChecked = TRUE;
++ driverRequired = FALSE;
++ }
++ else
++ ERR("Bad WINEDIB environment variable\n");
++ }
++
++ /* no WINEDIB environment var found or wrong value, we check registry */
++ if(!envChecked)
++ {
++ HKEY hkey;
++ buffer[0] = 0;
++ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\DIB Engine", &hkey ))
++ {
++ DWORD type, count = sizeof(buffer);
++ RegQueryValueExA( hkey, "Enable", 0, &type, (LPBYTE) buffer, &count );
++ RegCloseKey( hkey );
++ }
++ if(*buffer)
++ {
++ /* registry value found, must be Y or y to enable driver, N or n to disable */
++ if(!strncasecmp(buffer, "Y", 1))
++ {
++ TRACE("DIB Engine enabled by registry\n");
++ envChecked = TRUE;
++ driverRequired = TRUE;
++ }
++ else if(!strncasecmp(buffer, "N", 1))
++ {
++ TRACE("DIB Engine disabled by registry\n");
++ envChecked = TRUE;
++ driverRequired = FALSE;
++ }
++ }
++ }
++
++ /* none of above, we assume we don't want to use engine */
++ if(!envChecked)
++ {
++ TRACE("DIB Engine disabled by default\n");
++ envChecked = TRUE;
++ driverRequired = FALSE;
++ }
++
++ /* if DIB Engine is required, try to load it
++ * otherwise just return NULL module */
++ if(driverRequired)
++ {
++ if( (module = LoadLibraryA( winedib_drv )) != 0)
++ TRACE("Succesfully loaded DIB Engine\n");
++ else
++ ERR("Couldn't load DIB Engine\n");
++ return module;
++ }
++ else
++ return 0;
++}
++
++/**********************************************************************
+ * DRIVER_get_display_driver
+ *
+ * Special case for loading the display driver: get the name from the config file
+@@ -225,25 +325,32 @@
+ HKEY hkey;
+
+ if (display_driver) return &display_driver->funcs; /* already loaded */
++
++ /* check at first if DIB engine is present and if we want
++ * to use it */
++ if( (module = Load_Dib_Driver()) == 0)
++ {
++ /* no DIB Engine loaded, just load normal display driver */
++
++ strcpy( buffer, "x11" ); /* default value */
++ /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
++ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey ))
++ {
++ DWORD type, count = sizeof(buffer);
++ RegQueryValueExA( hkey, "Graphics", 0, &type, (LPBYTE) buffer, &count );
++ RegCloseKey( hkey );
++ }
+
+- strcpy( buffer, "x11" ); /* default value */
+- /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
+- if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey ))
+- {
+- DWORD type, count = sizeof(buffer);
+- RegQueryValueExA( hkey, "Graphics", 0, &type, (LPBYTE) buffer, &count );
+- RegCloseKey( hkey );
+- }
+-
+- name = buffer;
+- while (name)
+- {
+- next = strchr( name, ',' );
+- if (next) *next++ = 0;
++ name = buffer;
++ while (name)
++ {
++ next = strchr( name, ',' );
++ if (next) *next++ = 0;
+
+- snprintf( libname, sizeof(libname), "wine%s.drv", name );
+- if ((module = LoadLibraryA( libname )) != 0) break;
+- name = next;
++ snprintf( libname, sizeof(libname), "wine%s.drv", name );
++ if ((module = LoadLibraryA( libname )) != 0) break;
++ name = next;
++ }
+ }
+
+ if (!(driver = create_driver( module )))
+diff -Nru a/dlls/gdi32/driver.c.orig b/dlls/gdi32/driver.c.orig
+--- a/dlls/gdi32/driver.c.orig 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/gdi32/driver.c.orig 2010-07-30 19:43:56.000000000 +0200
+@@ -0,0 +1,698 @@
++/*
++ * Graphics driver management functions
++ *
++ * Copyright 1994 Bob Amstadt
++ * Copyright 1996, 2001 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
++ */
++
++#include "config.h"
++#include "wine/port.h"
++
++#include <stdarg.h>
++#include <string.h>
++#include <stdio.h>
++#include "windef.h"
++#include "winbase.h"
++#include "winreg.h"
++#include "ddrawgdi.h"
++#include "wine/winbase16.h"
++
++#include "gdi_private.h"
++#include "wine/unicode.h"
++#include "wine/list.h"
++#include "wine/debug.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(driver);
++
++struct graphics_driver
++{
++ struct list entry;
++ HMODULE module; /* module handle */
++ DC_FUNCTIONS funcs;
++};
++
++static struct list drivers = LIST_INIT( drivers );
++static struct graphics_driver *display_driver;
++
++static CRITICAL_SECTION driver_section;
++static CRITICAL_SECTION_DEBUG critsect_debug =
++{
++ 0, 0, &driver_section,
++ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
++ 0, 0, { (DWORD_PTR)(__FILE__ ": driver_section") }
++};
++static CRITICAL_SECTION driver_section = { &critsect_debug, -1, 0, 0, 0, 0 };
++
++/**********************************************************************
++ * create_driver
++ *
++ * Allocate and fill the driver structure for a given module.
++ */
++static struct graphics_driver *create_driver( HMODULE module )
++{
++ struct graphics_driver *driver;
++
++ if (!(driver = HeapAlloc( GetProcessHeap(), 0, sizeof(*driver)))) return NULL;
++ driver->module = module;
++
++ /* fill the function table */
++ if (module)
++ {
++#define GET_FUNC(name) driver->funcs.p##name = (void*)GetProcAddress( module, #name )
++ GET_FUNC(AbortDoc);
++ GET_FUNC(AbortPath);
++ GET_FUNC(AlphaBlend);
++ GET_FUNC(AngleArc);
++ GET_FUNC(Arc);
++ GET_FUNC(ArcTo);
++ GET_FUNC(BeginPath);
++ GET_FUNC(BitBlt);
++ GET_FUNC(ChoosePixelFormat);
++ GET_FUNC(Chord);
++ GET_FUNC(CloseFigure);
++ GET_FUNC(CreateBitmap);
++ GET_FUNC(CreateDC);
++ GET_FUNC(CreateDIBSection);
++ GET_FUNC(DeleteBitmap);
++ GET_FUNC(DeleteDC);
++ GET_FUNC(DescribePixelFormat);
++ GET_FUNC(DeviceCapabilities);
++ GET_FUNC(Ellipse);
++ GET_FUNC(EndDoc);
++ GET_FUNC(EndPage);
++ GET_FUNC(EndPath);
++ GET_FUNC(EnumDeviceFonts);
++ GET_FUNC(ExcludeClipRect);
++ GET_FUNC(ExtDeviceMode);
++ GET_FUNC(ExtEscape);
++ GET_FUNC(ExtFloodFill);
++ GET_FUNC(ExtSelectClipRgn);
++ GET_FUNC(ExtTextOut);
++ GET_FUNC(FillPath);
++ GET_FUNC(FillRgn);
++ GET_FUNC(FlattenPath);
++ GET_FUNC(FrameRgn);
++ GET_FUNC(GdiComment);
++ GET_FUNC(GetBitmapBits);
++ GET_FUNC(GetCharWidth);
++ GET_FUNC(GetDIBColorTable);
++ GET_FUNC(GetDIBits);
++ GET_FUNC(GetDeviceCaps);
++ GET_FUNC(GetDeviceGammaRamp);
++ GET_FUNC(GetICMProfile);
++ GET_FUNC(GetNearestColor);
++ GET_FUNC(GetPixel);
++ GET_FUNC(GetPixelFormat);
++ GET_FUNC(GetSystemPaletteEntries);
++ GET_FUNC(GetTextExtentExPoint);
++ GET_FUNC(GetTextMetrics);
++ GET_FUNC(IntersectClipRect);
++ GET_FUNC(InvertRgn);
++ GET_FUNC(LineTo);
++ GET_FUNC(MoveTo);
++ GET_FUNC(ModifyWorldTransform);
++ GET_FUNC(OffsetClipRgn);
++ GET_FUNC(OffsetViewportOrg);
++ GET_FUNC(OffsetWindowOrg);
++ GET_FUNC(PaintRgn);
++ GET_FUNC(PatBlt);
++ GET_FUNC(Pie);
++ GET_FUNC(PolyBezier);
++ GET_FUNC(PolyBezierTo);
++ GET_FUNC(PolyDraw);
++ GET_FUNC(PolyPolygon);
++ GET_FUNC(PolyPolyline);
++ GET_FUNC(Polygon);
++ GET_FUNC(Polyline);
++ GET_FUNC(PolylineTo);
++ GET_FUNC(RealizeDefaultPalette);
++ GET_FUNC(RealizePalette);
++ GET_FUNC(Rectangle);
++ GET_FUNC(ResetDC);
++ GET_FUNC(RestoreDC);
++ GET_FUNC(RoundRect);
++ GET_FUNC(SaveDC);
++ GET_FUNC(ScaleViewportExt);
++ GET_FUNC(ScaleWindowExt);
++ GET_FUNC(SelectBitmap);
++ GET_FUNC(SelectBrush);
++ GET_FUNC(SelectClipPath);
++ GET_FUNC(SelectFont);
++ GET_FUNC(SelectPalette);
++ GET_FUNC(SelectPen);
++ GET_FUNC(SetArcDirection);
++ GET_FUNC(SetBitmapBits);
++ GET_FUNC(SetBkColor);
++ GET_FUNC(SetBkMode);
++ GET_FUNC(SetDCBrushColor);
++ GET_FUNC(SetDCPenColor);
++ GET_FUNC(SetDIBColorTable);
++ GET_FUNC(SetDIBits);
++ GET_FUNC(SetDIBitsToDevice);
++ GET_FUNC(SetDeviceClipping);
++ GET_FUNC(SetDeviceGammaRamp);
++ GET_FUNC(SetMapMode);
++ GET_FUNC(SetMapperFlags);
++ GET_FUNC(SetPixel);
++ GET_FUNC(SetPixelFormat);
++ GET_FUNC(SetPolyFillMode);
++ GET_FUNC(SetROP2);
++ GET_FUNC(SetRelAbs);
++ GET_FUNC(SetStretchBltMode);
++ GET_FUNC(SetTextAlign);
++ GET_FUNC(SetTextCharacterExtra);
++ GET_FUNC(SetTextColor);
++ GET_FUNC(SetTextJustification);
++ GET_FUNC(SetViewportExt);
++ GET_FUNC(SetViewportOrg);
++ GET_FUNC(SetWindowExt);
++ GET_FUNC(SetWindowOrg);
++ GET_FUNC(SetWorldTransform);
++ GET_FUNC(StartDoc);
++ GET_FUNC(StartPage);
++ GET_FUNC(StretchBlt);
++ GET_FUNC(StretchDIBits);
++ GET_FUNC(StrokeAndFillPath);
++ GET_FUNC(StrokePath);
++ GET_FUNC(SwapBuffers);
++ GET_FUNC(UnrealizePalette);
++ GET_FUNC(WidenPath);
++
++ /* OpenGL32 */
++ GET_FUNC(wglCreateContext);
++ GET_FUNC(wglCreateContextAttribsARB);
++ GET_FUNC(wglDeleteContext);
++ GET_FUNC(wglGetProcAddress);
++ GET_FUNC(wglGetPbufferDCARB);
++ GET_FUNC(wglMakeContextCurrentARB);
++ GET_FUNC(wglMakeCurrent);
++ GET_FUNC(wglSetPixelFormatWINE);
++ GET_FUNC(wglShareLists);
++ GET_FUNC(wglUseFontBitmapsA);
++ GET_FUNC(wglUseFontBitmapsW);
++#undef GET_FUNC
++ }
++ else memset( &driver->funcs, 0, sizeof(driver->funcs) );
++
++ return driver;
++}
++
++
++/**********************************************************************
++ * DRIVER_get_display_driver
++ *
++ * Special case for loading the display driver: get the name from the config file
++ */
++const DC_FUNCTIONS *DRIVER_get_display_driver(void)
++{
++ struct graphics_driver *driver;
++ char buffer[MAX_PATH], libname[32], *name, *next;
++ HMODULE module = 0;
++ HKEY hkey;
++
++ if (display_driver) return &display_driver->funcs; /* already loaded */
++
++ strcpy( buffer, "x11" ); /* default value */
++ /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
++ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey ))
++ {
++ DWORD type, count = sizeof(buffer);
++ RegQueryValueExA( hkey, "Graphics", 0, &type, (LPBYTE) buffer, &count );
++ RegCloseKey( hkey );
++ }
++
++ name = buffer;
++ while (name)
++ {
++ next = strchr( name, ',' );
++ if (next) *next++ = 0;
++
++ snprintf( libname, sizeof(libname), "wine%s.drv", name );
++ if ((module = LoadLibraryA( libname )) != 0) break;
++ name = next;
++ }
++
++ if (!(driver = create_driver( module )))
++ {
++ MESSAGE( "Could not create graphics driver '%s'\n", buffer );
++ FreeLibrary( module );
++ ExitProcess(1);
++ }
++ if (InterlockedCompareExchangePointer( (void **)&display_driver, driver, NULL ))
++ {
++ /* somebody beat us to it */
++ FreeLibrary( driver->module );
++ HeapFree( GetProcessHeap(), 0, driver );
++ }
++ return &display_driver->funcs;
++}
++
++
++/**********************************************************************
++ * DRIVER_load_driver
++ */
++const DC_FUNCTIONS *DRIVER_load_driver( LPCWSTR name )
++{
++ HMODULE module;
++ struct graphics_driver *driver, *new_driver;
++ static const WCHAR displayW[] = { 'd','i','s','p','l','a','y',0 };
++ static const WCHAR display1W[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
++
++ /* display driver is a special case */
++ if (!strcmpiW( name, displayW ) || !strcmpiW( name, display1W )) return DRIVER_get_display_driver();
++
++ if ((module = GetModuleHandleW( name )))
++ {
++ if (display_driver && display_driver->module == module) return &display_driver->funcs;
++ EnterCriticalSection( &driver_section );
++ LIST_FOR_EACH_ENTRY( driver, &drivers, struct graphics_driver, entry )
++ {
++ if (driver->module == module) goto done;
++ }
++ LeaveCriticalSection( &driver_section );
++ }
++
++ if (!(module = LoadLibraryW( name ))) return NULL;
++
++ if (!(new_driver = create_driver( module )))
++ {
++ FreeLibrary( module );
++ return NULL;
++ }
++
++ /* check if someone else added it in the meantime */
++ EnterCriticalSection( &driver_section );
++ LIST_FOR_EACH_ENTRY( driver, &drivers, struct graphics_driver, entry )
++ {
++ if (driver->module != module) continue;
++ FreeLibrary( module );
++ HeapFree( GetProcessHeap(), 0, new_driver );
++ goto done;
++ }
++ driver = new_driver;
++ list_add_head( &drivers, &driver->entry );
++ TRACE( "loaded driver %p for %s\n", driver, debugstr_w(name) );
++done:
++ LeaveCriticalSection( &driver_section );
++ return &driver->funcs;
++}
++
++
++/*****************************************************************************
++ * DRIVER_GetDriverName
++ *
++ */
++BOOL DRIVER_GetDriverName( LPCWSTR device, LPWSTR driver, DWORD size )
++{
++ static const WCHAR displayW[] = { 'd','i','s','p','l','a','y',0 };
++ static const WCHAR devicesW[] = { 'd','e','v','i','c','e','s',0 };
++ static const WCHAR display1W[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
++ static const WCHAR empty_strW[] = { 0 };
++ WCHAR *p;
++
++ /* display is a special case */
++ if (!strcmpiW( device, displayW ) ||
++ !strcmpiW( device, display1W ))
++ {
++ lstrcpynW( driver, displayW, size );
++ return TRUE;
++ }
++
++ size = GetProfileStringW(devicesW, device, empty_strW, driver, size);
++ if(!size) {
++ WARN("Unable to find %s in [devices] section of win.ini\n", debugstr_w(device));
++ return FALSE;
++ }
++ p = strchrW(driver, ',');
++ if(!p)
++ {
++ WARN("%s entry in [devices] section of win.ini is malformed.\n", debugstr_w(device));
++ return FALSE;
++ }
++ *p = 0;
++ TRACE("Found %s for %s\n", debugstr_w(driver), debugstr_w(device));
++ return TRUE;
++}
++
++
++/***********************************************************************
++ * GdiConvertToDevmodeW (GDI32.@)
++ */
++DEVMODEW * WINAPI GdiConvertToDevmodeW(const DEVMODEA *dmA)
++{
++ DEVMODEW *dmW;
++ WORD dmW_size, dmA_size;
++
++ dmA_size = dmA->dmSize;
++
++ /* this is the minimal dmSize that XP accepts */
++ if (dmA_size < FIELD_OFFSET(DEVMODEA, dmFields))
++ return NULL;
++
++ if (dmA_size > sizeof(DEVMODEA))
++ dmA_size = sizeof(DEVMODEA);
++
++ dmW_size = dmA_size + CCHDEVICENAME;
++ if (dmA_size >= FIELD_OFFSET(DEVMODEA, dmFormName) + CCHFORMNAME)
++ dmW_size += CCHFORMNAME;
++
++ dmW = HeapAlloc(GetProcessHeap(), 0, dmW_size + dmA->dmDriverExtra);
++ if (!dmW) return NULL;
++
++ MultiByteToWideChar(CP_ACP, 0, (const char*) dmA->dmDeviceName, -1,
++ dmW->dmDeviceName, CCHDEVICENAME);
++ /* copy slightly more, to avoid long computations */
++ memcpy(&dmW->dmSpecVersion, &dmA->dmSpecVersion, dmA_size - CCHDEVICENAME);
++
++ if (dmA_size >= FIELD_OFFSET(DEVMODEA, dmFormName) + CCHFORMNAME)
++ {
++ if (dmA->dmFields & DM_FORMNAME)
++ MultiByteToWideChar(CP_ACP, 0, (const char*) dmA->dmFormName, -1,
++ dmW->dmFormName, CCHFORMNAME);
++ else
++ dmW->dmFormName[0] = 0;
++
++ if (dmA_size > FIELD_OFFSET(DEVMODEA, dmLogPixels))
++ memcpy(&dmW->dmLogPixels, &dmA->dmLogPixels, dmA_size - FIELD_OFFSET(DEVMODEA, dmLogPixels));
++ }
++
++ if (dmA->dmDriverExtra)
++ memcpy((char *)dmW + dmW_size, (const char *)dmA + dmA_size, dmA->dmDriverExtra);
++
++ dmW->dmSize = dmW_size;
++
++ return dmW;
++}
++
++
++/*****************************************************************************
++ * @ [GDI32.100]
++ *
++ * This should thunk to 16-bit and simply call the proc with the given args.
++ */
++INT WINAPI GDI_CallDevInstall16( FARPROC16 lpfnDevInstallProc, HWND hWnd,
++ LPSTR lpModelName, LPSTR OldPort, LPSTR NewPort )
++{
++ FIXME("(%p, %p, %s, %s, %s)\n", lpfnDevInstallProc, hWnd, lpModelName, OldPort, NewPort );
++ return -1;
++}
++
++/*****************************************************************************
++ * @ [GDI32.101]
++ *
++ * This should load the correct driver for lpszDevice and calls this driver's
++ * ExtDeviceModePropSheet proc.
++ *
++ * Note: The driver calls a callback routine for each property sheet page; these
++ * pages are supposed to be filled into the structure pointed to by lpPropSheet.
++ * The layout of this structure is:
++ *
++ * struct
++ * {
++ * DWORD nPages;
++ * DWORD unknown;
++ * HPROPSHEETPAGE pages[10];
++ * };
++ */
++INT WINAPI GDI_CallExtDeviceModePropSheet16( HWND hWnd, LPCSTR lpszDevice,
++ LPCSTR lpszPort, LPVOID lpPropSheet )
++{
++ FIXME("(%p, %s, %s, %p)\n", hWnd, lpszDevice, lpszPort, lpPropSheet );
++ return -1;
++}
++
++/*****************************************************************************
++ * @ [GDI32.102]
++ *
++ * This should load the correct driver for lpszDevice and call this driver's
++ * ExtDeviceMode proc.
++ *
++ * FIXME: convert ExtDeviceMode to unicode in the driver interface
++ */
++INT WINAPI GDI_CallExtDeviceMode16( HWND hwnd,
++ LPDEVMODEA lpdmOutput, LPSTR lpszDevice,
++ LPSTR lpszPort, LPDEVMODEA lpdmInput,
++ LPSTR lpszProfile, DWORD fwMode )
++{
++ WCHAR deviceW[300];
++ WCHAR bufW[300];
++ char buf[300];
++ HDC hdc;
++ DC *dc;
++ INT ret = -1;
++
++ TRACE("(%p, %p, %s, %s, %p, %s, %d)\n",
++ hwnd, lpdmOutput, lpszDevice, lpszPort, lpdmInput, lpszProfile, fwMode );
++
++ if (!lpszDevice) return -1;
++ if (!MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, deviceW, 300)) return -1;
++
++ if(!DRIVER_GetDriverName( deviceW, bufW, 300 )) return -1;
++
++ if (!WideCharToMultiByte(CP_ACP, 0, bufW, -1, buf, 300, NULL, NULL)) return -1;
++
++ if (!(hdc = CreateICA( buf, lpszDevice, lpszPort, NULL ))) return -1;
++
++ if ((dc = get_dc_ptr( hdc )))
++ {
++ if (dc->funcs->pExtDeviceMode)
++ ret = dc->funcs->pExtDeviceMode( buf, hwnd, lpdmOutput, lpszDevice, lpszPort,
++ lpdmInput, lpszProfile, fwMode );
++ release_dc_ptr( dc );
++ }
++ DeleteDC( hdc );
++ return ret;
++}
++
++/****************************************************************************
++ * @ [GDI32.103]
++ *
++ * This should load the correct driver for lpszDevice and calls this driver's
++ * AdvancedSetupDialog proc.
++ */
++INT WINAPI GDI_CallAdvancedSetupDialog16( HWND hwnd, LPSTR lpszDevice,
++ LPDEVMODEA devin, LPDEVMODEA devout )
++{
++ TRACE("(%p, %s, %p, %p)\n", hwnd, lpszDevice, devin, devout );
++ return -1;
++}
++
++/*****************************************************************************
++ * @ [GDI32.104]
++ *
++ * This should load the correct driver for lpszDevice and calls this driver's
++ * DeviceCapabilities proc.
++ *
++ * FIXME: convert DeviceCapabilities to unicode in the driver interface
++ */
++DWORD WINAPI GDI_CallDeviceCapabilities16( LPCSTR lpszDevice, LPCSTR lpszPort,
++ WORD fwCapability, LPSTR lpszOutput,
++ LPDEVMODEA lpdm )
++{
++ WCHAR deviceW[300];
++ WCHAR bufW[300];
++ char buf[300];
++ HDC hdc;
++ DC *dc;
++ INT ret = -1;
++
++ TRACE("(%s, %s, %d, %p, %p)\n", lpszDevice, lpszPort, fwCapability, lpszOutput, lpdm );
++
++ if (!lpszDevice) return -1;
++ if (!MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, deviceW, 300)) return -1;
++
++ if(!DRIVER_GetDriverName( deviceW, bufW, 300 )) return -1;
++
++ if (!WideCharToMultiByte(CP_ACP, 0, bufW, -1, buf, 300, NULL, NULL)) return -1;
++
++ if (!(hdc = CreateICA( buf, lpszDevice, lpszPort, NULL ))) return -1;
++
++ if ((dc = get_dc_ptr( hdc )))
++ {
++ if (dc->funcs->pDeviceCapabilities)
++ ret = dc->funcs->pDeviceCapabilities( buf, lpszDevice, lpszPort,
++ fwCapability, lpszOutput, lpdm );
++ release_dc_ptr( dc );
++ }
++ DeleteDC( hdc );
++ return ret;
++}
++
++
++/************************************************************************
++ * Escape [GDI32.@]
++ */
++INT WINAPI Escape( HDC hdc, INT escape, INT in_count, LPCSTR in_data, LPVOID out_data )
++{
++ INT ret;
++ POINT *pt;
++
++ switch (escape)
++ {
++ case ABORTDOC:
++ return AbortDoc( hdc );
++
++ case ENDDOC:
++ return EndDoc( hdc );
++
++ case GETPHYSPAGESIZE:
++ pt = out_data;
++ pt->x = GetDeviceCaps( hdc, PHYSICALWIDTH );
++ pt->y = GetDeviceCaps( hdc, PHYSICALHEIGHT );
++ return 1;
++
++ case GETPRINTINGOFFSET:
++ pt = out_data;
++ pt->x = GetDeviceCaps( hdc, PHYSICALOFFSETX );
++ pt->y = GetDeviceCaps( hdc, PHYSICALOFFSETY );
++ return 1;
++
++ case GETSCALINGFACTOR:
++ pt = out_data;
++ pt->x = GetDeviceCaps( hdc, SCALINGFACTORX );
++ pt->y = GetDeviceCaps( hdc, SCALINGFACTORY );
++ return 1;
++
++ case NEWFRAME:
++ return EndPage( hdc );
++
++ case SETABORTPROC:
++ return SetAbortProc( hdc, (ABORTPROC)in_data );
++
++ case STARTDOC:
++ {
++ DOCINFOA doc;
++ char *name = NULL;
++
++ /* in_data may not be 0 terminated so we must copy it */
++ if (in_data)
++ {
++ name = HeapAlloc( GetProcessHeap(), 0, in_count+1 );
++ memcpy( name, in_data, in_count );
++ name[in_count] = 0;
++ }
++ /* out_data is actually a pointer to the DocInfo structure and used as
++ * a second input parameter */
++ if (out_data) doc = *(DOCINFOA *)out_data;
++ else
++ {
++ doc.cbSize = sizeof(doc);
++ doc.lpszOutput = NULL;
++ doc.lpszDatatype = NULL;
++ doc.fwType = 0;
++ }
++ doc.lpszDocName = name;
++ ret = StartDocA( hdc, &doc );
++ HeapFree( GetProcessHeap(), 0, name );
++ if (ret > 0) ret = StartPage( hdc );
++ return ret;
++ }
++
++ case QUERYESCSUPPORT:
++ {
++ const INT *ptr = (const INT *)in_data;
++ if (in_count < sizeof(INT)) return 0;
++ switch(*ptr)
++ {
++ case ABORTDOC:
++ case ENDDOC:
++ case GETPHYSPAGESIZE:
++ case GETPRINTINGOFFSET:
++ case GETSCALINGFACTOR:
++ case NEWFRAME:
++ case QUERYESCSUPPORT:
++ case SETABORTPROC:
++ case STARTDOC:
++ return TRUE;
++ }
++ break;
++ }
++ }
++
++ /* if not handled internally, pass it to the driver */
++ return ExtEscape( hdc, escape, in_count, in_data, 0, out_data );
++}
++
++
++/******************************************************************************
++ * ExtEscape [GDI32.@]
++ *
++ * Access capabilities of a particular device that are not available through GDI.
++ *
++ * PARAMS
++ * hdc [I] Handle to device context
++ * nEscape [I] Escape function
++ * cbInput [I] Number of bytes in input structure
++ * lpszInData [I] Pointer to input structure
++ * cbOutput [I] Number of bytes in output structure
++ * lpszOutData [O] Pointer to output structure
++ *
++ * RETURNS
++ * Success: >0
++ * Not implemented: 0
++ * Failure: <0
++ */
++INT WINAPI ExtEscape( HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData,
++ INT cbOutput, LPSTR lpszOutData )
++{
++ INT ret = 0;
++ DC * dc = get_dc_ptr( hdc );
++ if (dc)
++ {
++ if (dc->funcs->pExtEscape)
++ ret = dc->funcs->pExtEscape( dc->physDev, nEscape, cbInput, lpszInData, cbOutput, lpszOutData );
++ release_dc_ptr( dc );
++ }
++ return ret;
++}
++
++
++/*******************************************************************
++ * DrawEscape [GDI32.@]
++ *
++ *
++ */
++INT WINAPI DrawEscape(HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData)
++{
++ FIXME("DrawEscape, stub\n");
++ return 0;
++}
++
++/*******************************************************************
++ * NamedEscape [GDI32.@]
++ */
++INT WINAPI NamedEscape( HDC hdc, LPCWSTR pDriver, INT nEscape, INT cbInput, LPCSTR lpszInData,
++ INT cbOutput, LPSTR lpszOutData )
++{
++ FIXME("(%p, %s, %d, %d, %p, %d, %p)\n",
++ hdc, wine_dbgstr_w(pDriver), nEscape, cbInput, lpszInData, cbOutput,
++ lpszOutData);
++ return 0;
++}
++
++/*******************************************************************
++ * DdQueryDisplaySettingsUniqueness [GDI32.@]
++ * GdiEntry13 [GDI32.@]
++ */
++ULONG WINAPI DdQueryDisplaySettingsUniqueness(VOID)
++{
++ static int warn_once;
++
++ if (!warn_once++)
++ FIXME("stub\n");
++ return 0;
++}
+diff -Nru a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c
+--- a/dlls/winedib.drv/bitblt.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/bitblt.c 2010-08-04 16:08:44.791222017 +0200
+@@ -0,0 +1,970 @@
++/*
++ * DIBDRV bit-blit operations
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++void CheckMapping(const char *func, const char *s, DIBDRVPHYSDEV *physDev)
++{
++ int a, b;
++
++ if(!physDev)
++ return;
++
++ a=10;b=20;
++ _DIBDRV_Position_ws2ds(physDev, &a, &b);
++ if(a != 10 || b != 20)
++ FIXME("%s:%s:Position(10, 20) translated to(%d, %d)\n", func, s, a, b);
++ a=10;b=20;
++ _DIBDRV_Sizes_ws2ds(physDev, &a, &b);
++ if(a != 10 || b != 20)
++ FIXME("%s:%s:sizes (10, 20) translated to(%d, %d)\n", func, s, a, b);
++}
++
++static inline void intSwap(int *a, int *b)
++{
++ int tmp;
++ tmp = *a;
++ *a = *b;
++ *b = tmp;
++}
++
++static inline void setRect(RECT *r, int x1, int y1, int x2, int y2)
++{
++ r->left = x1;
++ r->top = y1;
++ r->right = x2;
++ r->bottom = y2;
++}
++
++static inline void setPoint(POINT *p, int x, int y)
++{
++ p->x = x;
++ p->y = y;
++}
++
++static inline void setSize(SIZE *sz, int cx, int cy)
++{
++ sz->cx = cx;
++ sz->cy = cy;
++}
++
++/* clips a source and destination areas to their respective clip rectangles
++ returning both source and dest modified; result is TRUE if clipping
++ leads to a non null rectangle, FALSE otherwise */
++static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT*dstClip)
++{
++ int xs1, ys1, xs2, ys2;
++ int xsc1, ysc1, xsc2, ysc2;
++ int xd1, yd1, xd2, yd2;
++ int xdc1, ydc1, xdc2, ydc2;
++ int w, h, dx, dy;
++
++ /* extract sizes */
++ w = sz->cx; h = sz->cy;
++
++ /* if sizes null or negative, just return false */
++ if(w <= 0 || h <= 0)
++ return FALSE;
++
++ /* extract dest area data */
++ xd1 = pd->x;
++ yd1 = pd->y;
++ xd2 = xd1 + w;
++ yd2 = yd1 + h;
++
++ /* extract source data */
++ xs1 = ps->x;
++ ys1 = ps->y;
++ xs2 = xs1 + w;
++ ys2 = ys1 + h;
++
++ /* if source clip area is not null, do first clipping on it */
++ if(srcClip)
++ {
++ /* extract source clipping area */
++ xsc1 = srcClip->left;
++ ysc1 = srcClip->top;
++ xsc2 = srcClip->right;
++ ysc2 = srcClip->bottom;
++
++ /* order clip area rectangle points */
++ if(xsc1 > xsc2) intSwap(&xsc1, &xsc2);
++ if(ysc1 > ysc2) intSwap(&ysc1, &ysc2);
++
++ /* clip on source clipping start point */
++ if(xs1 < xsc1) { dx = xsc1 - xs1; w -= dx; xd1 += dx; xs1 = xsc1; }
++ if(ys1 < ysc1) { dy = ysc1 - ys1; h -= dy; yd1 += dy; ys1 = ysc1; }
++
++ /* clip on source clipping end point */
++ if(xs2 > xsc2) { dx = xs2 - xsc2; w -= dx; xd2 -= dx; xs2 = xsc2; }
++ if(ys2 > ysc2) { dy = ys2 - ysc2; h -= dy; yd2 -= dy; ys2 = ysc2; }
++
++ /* if already zero area, return false */
++ if(w <= 0 || h <= 0)
++ return FALSE;
++ }
++ /* now do clipping on destination area */
++ if(dstClip)
++ {
++ /* extract destination clipping area */
++ xdc1 = dstClip->left;
++ ydc1 = dstClip->top;
++ xdc2 = dstClip->right;
++ ydc2 = dstClip->bottom;
++
++ /* order clip area rectangle points */
++ if(xdc1 > xdc2) intSwap(&xdc1, &xdc2);
++ if(ydc1 > ydc2) intSwap(&ydc1, &ydc2);
++
++ /* clip on dest clipping start point */
++ if(xd1 < xdc1) { dx = xdc1 - xd1; w -= dx; xs1 += dx; xd1 = xdc1; }
++ if(yd1 < ydc1) { dy = ydc1 - yd1; h -= dy; ys1 += dy; yd1 = ydc1; }
++
++ /* clip on dest clipping end point */
++ if(xd2 > xdc2) { dx = xd2 - xdc2; w -= dx; xs2 -= dx; xd2 = xdc2; }
++ if(yd2 > ydc2) { dy = yd2 - ydc2; h -= dy; ys2 -= dy; yd2 = ydc2; }
++
++ /* if already zero area, return false */
++ if(w <= 0 || h <= 0)
++ return FALSE;
++ }
++
++ /* sets clipped/translated points and sizes and returns TRUE */
++ ps->x = xs1; ps->y = ys1;
++ pd->x = xd1; pd->y = yd1;
++ sz->cx = w; sz->cy = h;
++
++ return TRUE;
++
++}
++
++
++/* clips a source and destination areas to their respective clip rectangles
++ returning both source and dest modified; result is TRUE if clipping
++ leads to a non null rectangle, FALSE otherwise */
++static BOOL StretchBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *szSrc, SIZE *szDst, RECT*srcClip, RECT*dstClip)
++{
++ int xs1, ys1, xs2, ys2;
++ int xsc1, ysc1, xsc2, ysc2;
++ int xd1, yd1, xd2, yd2;
++ int xdc1, ydc1, xdc2, ydc2;
++ int ws, hs, wd, hd, dx, dy;
++ int mulh, divh, mulv, divv;
++
++ /* extract sizes */
++ ws = szSrc->cx; hs = szSrc->cy;
++ wd = szDst->cx; hd = szDst->cy;
++
++ /* if sizes null or negative, just return false */
++ /* FIXME : add support for mirror stretch */
++ if(ws <= 0 || hs <= 0 || wd <= 0 || hd <= 0)
++ return FALSE;
++
++ /* stores scaling factors from source rect to dest one */
++ mulh = wd; divh = ws;
++ mulv = hd; divv = hs;
++
++ /* extract dest area data */
++ xd1 = pd->x;
++ yd1 = pd->y;
++ xd2 = xd1 + wd;
++ yd2 = yd1 + hd;
++
++ /* extract source data */
++ xs1 = ps->x;
++ ys1 = ps->y;
++ xs2 = xs1 + ws;
++ ys2 = ys1 + hs;
++
++ /* if source clip area is not null, do first clipping on it */
++ if(srcClip)
++ {
++ /* extract source clipping area */
++ xsc1 = srcClip->left;
++ ysc1 = srcClip->top;
++ xsc2 = srcClip->right;
++ ysc2 = srcClip->bottom;
++
++ /* order clip area rectangle points */
++ if(xsc1 > xsc2) intSwap(&xsc1, &xsc2);
++ if(ysc1 > ysc2) intSwap(&ysc1, &ysc2);
++
++ /* clip on source clipping start point */
++ if(xs1 < xsc1) { dx = xsc1 - xs1; ws -= dx; xd1 += MulDiv(dx, mulh, divh); xs1 = xsc1; }
++ if(ys1 < ysc1) { dy = ysc1 - ys1; hs -= dy; yd1 += MulDiv(dy, mulv, divv); ys1 = ysc1; }
++
++ /* clip on source clipping end point */
++ if(xs2 > xsc2) { dx = xs2 - xsc2; ws -= dx; xd2 -= MulDiv(dx, mulh, divh); xs2 = xsc2; }
++ if(ys2 > ysc2) { dy = ys2 - ysc2; hs -= dy; yd2 -= MulDiv(dy, mulv, divv); ys2 = ysc2; }
++
++ /* if already zero area, return false */
++ if(ws <= 0 || hs <= 0)
++ return FALSE;
++ wd = xd2 - xd1;
++ hd = yd2 - yd1;
++ }
++ /* now do clipping on destination area */
++
++ if(dstClip)
++ {
++ /* extract destination clipping area */
++ xdc1 = dstClip->left;
++ ydc1 = dstClip->top;
++ xdc2 = dstClip->right;
++ ydc2 = dstClip->bottom;
++
++ /* order clip area rectangle points */
++ if(xdc1 > xdc2) intSwap(&xdc1, &xdc2);
++ if(ydc1 > ydc2) intSwap(&ydc1, &ydc2);
++
++ /* clip on dest clipping start point */
++ if(xd1 < xdc1) { dx = xdc1 - xd1; wd -= dx; xs1 += MulDiv(dx, divh, mulh); xd1 = xdc1; }
++ if(yd1 < ydc1) { dy = ydc1 - yd1; hd -= dy; ys1 += MulDiv(dy, divv, mulv); yd1 = ydc1; }
++
++ /* clip on dest clipping end point */
++ if(xd2 > xdc2) { dx = xd2 - xdc2; wd -= dx; xs2 -= MulDiv(dx, divh, mulh); xd2 = xdc2; }
++ if(yd2 > ydc2) { dy = yd2 - ydc2; hd -= dy; ys2 -= MulDiv(dy, divv, mulv); yd2 = ydc2; }
++
++ /* if already zero area, return false */
++ if(wd <= 0 || hd <= 0)
++ return FALSE;
++
++ ws = xs2 - xs1;
++ hs = ys2 - ys1;
++ }
++
++ /* sets clipped/translated points and sizes and returns TRUE */
++ ps->x = xs1; ps->y = ys1;
++ pd->x = xd1; pd->y = yd1;
++ szSrc->cx = ws; szSrc->cy = hs;
++ szDst->cx = wd; szDst->cy = hd;
++
++ return TRUE;
++
++}
++
++/***********************************************************************
++ * _DIBDRV_InternalAlphaBlend
++ */
++BOOL _DIBDRV_InternalAlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT widthDst, INT heightDst,
++ DIBDRVPHYSDEV *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
++ BLENDFUNCTION blendfn)
++{
++ BOOL res;
++ POINT pd, ps;
++ SIZE szSrc, szDst;
++ int iRec;
++ RECT dstClip, srcClip;
++
++ /* converts to device spaces */
++ _DIBDRV_Position_ws2ds(physDevDst, &xDst, &yDst);
++ _DIBDRV_Sizes_ws2ds(physDevDst, &widthDst, &heightDst);
++ _DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc);
++ _DIBDRV_Sizes_ws2ds(physDevSrc, &widthSrc, &heightSrc);
++
++ /* from tests, it seems that coords out of phys spaces are not allowed */
++ if(xDst < 0 || yDst < 0 || xSrc < 0 || ySrc < 0 ||
++ xDst + widthDst > physDevDst->physBitmap->width ||
++ yDst + heightDst > physDevDst->physBitmap->height ||
++ xSrc + widthSrc > physDevSrc->physBitmap->width ||
++ ySrc + heightSrc > physDevSrc->physBitmap->height)
++ {
++ SetLastError(ERROR_INVALID_PARAMETER);
++ return FALSE;
++ }
++
++ /* first clip on physical DC sizes */
++ setPoint(&pd, xDst, yDst);
++ setPoint(&ps, xSrc, ySrc);
++ setSize(&szDst, widthDst, heightDst);
++ setSize(&szSrc, widthSrc, heightSrc);
++ setRect(&dstClip, 0, 0, physDevDst->physBitmap->width, physDevDst->physBitmap->height);
++ setRect(&srcClip, 0, 0, physDevSrc->physBitmap->width, physDevSrc->physBitmap->height);
++ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, &dstClip);
++ if(!res)
++ return TRUE;
++ xDst = pd.x; yDst = pd.y;
++ xSrc = ps.x; ySrc = ps.y;
++ widthDst = szDst.cx; heightDst = szDst.cy;
++ widthSrc = szSrc.cx; heightSrc = szSrc.cy;
++
++ /* then, do blitting for each dest clip area (no clipping on source) */
++ res = FALSE;
++ for(iRec = 0; iRec < physDevDst->regionRectCount; iRec++)
++ {
++ RECT *r = physDevDst->regionRects + iRec;
++ setRect(&dstClip, r->left, r->top, r->right, r->bottom);
++ setPoint(&pd, xDst, yDst);
++ setPoint(&ps, xSrc, ySrc);
++ setSize(&szDst, widthDst, heightDst);
++ setSize(&szSrc, widthSrc, heightSrc);
++ if(!StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip))
++ continue;
++ if(physDevDst->physBitmap->funcs->AlphaBlend(physDevDst, pd.x, pd.y, szDst.cx, szDst.cy,
++ physDevSrc, ps.x, ps.y, szSrc.cx, szSrc.cy, blendfn))
++ res = TRUE;
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_AlphaBlend
++ */
++BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT widthDst, INT heightDst,
++ DIBDRVPHYSDEV *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
++ BLENDFUNCTION blendfn)
++{
++ BOOL res;
++
++ POINT pd = {xDst, yDst};
++ SIZE szDst = {widthDst, heightDst};
++
++CheckMapping(__FUNCTION__, "DEST", physDevDst);
++CheckMapping(__FUNCTION__, "SOURCE",physDevSrc);
++
++ MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d\n",
++ physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(physDevDst->physBitmap) : "",
++ xDst, yDst, widthDst, heightDst,
++ physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(physDevSrc->physBitmap) : "",
++ xSrc, ySrc, widthSrc, heightSrc));
++
++ /* if sizes are null or negative, or source positions are negatives, returns false */
++ if(widthSrc <= 0 || heightSrc <= 0 ||
++ widthDst <= 0 || heightDst <= 0)
++ {
++ res = FALSE;
++ SetLastError(ERROR_INVALID_PARAMETER);
++ goto fin;
++ }
++
++ /* source sould be a 32 bit DIB */
++ if(!physDevSrc)
++ {
++ FIXME("Null source bitmap -- shouldn't happen\n");
++ res = FALSE;
++ goto fin;
++ }
++ else if(!physDevSrc->hasDIB)
++ {
++ FIXME("DDB source bitmap still not supported\n");
++ res = FALSE;
++ goto fin;
++ }
++
++ if(physDevDst->hasDIB)
++ {
++ /* DIB section selected in dest DC, use DIB Engine */
++ MAYBE(TRACE("Blending DIB->DIB\n"));
++ res = _DIBDRV_InternalAlphaBlend(physDevDst, xDst, yDst, widthDst, heightDst,
++ physDevSrc, xSrc, ySrc, widthSrc, heightSrc, blendfn);
++ }
++ else
++ {
++ /* DDB selected on dest DC -- must double-convert */
++ HBITMAP tmpDIB, stock;
++ HDC tmpDC;
++
++ MAYBE(TRACE("Blending DIB->DDB\n"));
++
++ /* we should anyways convert dest to physical coordinates here before processing
++ in order to check its consistency -- source coords will be converted/clipped later
++ As we do a conversion to a temporary DIB for destination, we don't care about it */
++ _DIBDRV_Position_ws2ds(physDevDst, &pd.x, &pd.y);
++ _DIBDRV_Sizes_ws2ds(physDevDst, &szDst.cx, &szDst.cy);
++
++ /* test shows that negatives origins are not allowed */
++ if(pd.x < 0 || pd.y < 0)
++ {
++ SetLastError(ERROR_INVALID_PARAMETER);
++ res = FALSE;
++ goto fin;
++ }
++
++ /* converts dest DDB onto a temporary DIB -- just the needed part */
++ /* WARNING -- that one could fail if rectangle on dest id out of range */
++ tmpDIB = _DIBDRV_ConvertDevDDBtoDIB(physDevDst->hdc, physDevSrc->hdc, xDst, yDst, widthDst, heightDst);
++ if(!tmpDIB)
++ {
++ ERR("Couldn't convert dest DDB to DIB\n");
++ res = FALSE;
++ goto fin;
++ }
++
++ /* selects the temporary DIB into a temporary DC */
++ tmpDC = CreateCompatibleDC(physDevDst->hdc);
++ if(!tmpDC)
++ {
++ ERR("Couldn't create temporary DC\n");
++ DeleteObject(tmpDIB);
++ res = FALSE;
++ goto fin;
++ }
++ stock = SelectObject(tmpDC, tmpDIB);
++ if(!stock)
++ {
++ ERR("Couldn't select temporary DIB into temporary DC\n");
++ DeleteDC(tmpDC);
++ DeleteObject(tmpDIB);
++ res = FALSE;
++ goto fin;
++ }
++
++ /* blends source DIB onto temp DIB and re-blits onto dest DC */
++ res = GdiAlphaBlend(tmpDC, 0, 0, szDst.cx, szDst.cy, physDevSrc->hdc, xSrc, ySrc, widthSrc, heightSrc, blendfn);
++ if(!res)
++ MAYBE(TRACE("AlphaBlend failed\n"));
++ else
++ res = BitBlt(physDevDst->hdc, xDst, yDst, widthDst, heightDst, tmpDC, 0, 0, SRCCOPY);
++
++ /* frees resources */
++ SelectObject(tmpDC, stock);
++ DeleteDC(tmpDC);
++ DeleteObject(tmpDIB);
++ }
++fin:
++ return res;
++}
++
++/***********************************************************************
++ * _DIBDRV_InternalBitBlt
++ */
++BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT width, INT height, DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, DWORD rop )
++{
++ BOOL res;
++ POINT pd, ps;
++ SIZE sz;
++ int iRec;
++ RECT dstClip, srcClip;
++
++ /* converts to device spaces */
++ _DIBDRV_Position_ws2ds(physDevDst, &xDst, &yDst);
++ _DIBDRV_Sizes_ws2ds(physDevDst, &width, &height);
++ if(physDevSrc)
++ _DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc);
++
++ /* first clip on physical DC sizes */
++ setPoint(&pd, xDst, yDst);
++ setPoint(&ps, xSrc, ySrc);
++ setSize(&sz, width, height);
++ setRect(&dstClip, 0, 0, physDevDst->physBitmap->width, physDevDst->physBitmap->height);
++
++ if(physDevSrc)
++ {
++ setRect(&srcClip, 0, 0, physDevSrc->physBitmap->width, physDevSrc->physBitmap->height);
++ res = BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, &dstClip);
++ }
++ else
++ res = BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip);
++ if(!res)
++ return TRUE;
++ xDst = pd.x; yDst = pd.y;
++ xSrc = ps.x; ySrc = ps.y;
++ width = sz.cx; height = sz.cy;
++
++ /* then, do blitting for each dest clip area (no clipping on source) */
++ res = TRUE;
++ for(iRec = 0; iRec < physDevDst->regionRectCount; iRec++)
++ {
++ RECT *r = physDevDst->regionRects + iRec;
++ setRect(&dstClip, r->left, r->top, r->right, r->bottom);
++ setPoint(&pd, xDst, yDst);
++ setPoint(&ps, xSrc, ySrc);
++ setSize(&sz, width, height);
++ if(!BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip))
++ continue;
++ if(!physDevDst->physBitmap->funcs->BitBlt(physDevDst, pd.x, pd.y, sz.cx, sz.cy, physDevSrc, ps.x, ps.y, rop))
++ res = FALSE;
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_BitBlt */
++BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT width, INT height, DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, DWORD rop )
++{
++ BOOL res;
++ int dummy;
++ int devXSrc, devWidth;
++ int devYSrc, devHeight, zeroYSrc;
++
++// CheckMapping(__FUNCTION__, "DEST", physDevDst);
++// CheckMapping(__FUNCTION__, "SOURCE",physDevSrc);
++ MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, width:%d, height:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, rop:%08x\n",
++ physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(physDevDst->physBitmap) : "",
++ xDst, yDst, width, height,
++ physDevSrc, physDevSrc ? (physDevSrc->hasDIB ? "DIB-" : "DDB"): "---", physDevSrc && physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(physDevSrc->physBitmap) : "",
++ xSrc, ySrc, rop));
++
++ if(physDevDst->hasDIB)
++ {
++ /* DIB section selected in dest DC, use DIB Engine */
++
++ if(!physDevSrc || physDevSrc->hasDIB)
++ {
++ /* source is null or has a DIB, no need to convert anyting */
++ res = _DIBDRV_InternalBitBlt(physDevDst, xDst, yDst, width, height, physDevSrc, xSrc, ySrc, rop);
++ }
++ else
++ {
++ /* source is a DDB, must convert it to DIB */
++
++ /* we must differentiate from 2 cases :
++ 1) source DC is a memory DC
++ 2) source DC is a device DC */
++ if(GetObjectType(physDevSrc->hdc) == OBJ_MEMDC)
++ {
++ /* memory DC */
++ HBITMAP dib, ddb;
++
++ ddb = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
++ if(!ddb)
++ {
++ ERR("Couldn't select out DDB from source HDC\n");
++ res = 0;
++ goto noBlt1;
++ }
++
++ /* we need device coordinates for ySrc and height, as the conversion
++ functions operates directly on bitmap without the hdc */
++ devYSrc = ySrc;
++ _DIBDRV_Position_ws2ds(physDevSrc, &dummy, &devYSrc);
++ devHeight = height;
++ _DIBDRV_Sizes_ws2ds(physDevSrc, &dummy, &devHeight);
++
++ dib = _DIBDRV_ConvertDDBtoDIB(physDevSrc->hdc, ddb, devYSrc, devHeight);
++ if(!dib)
++ {
++ ERR("Failed converting source DDB to DIB\n");
++ SelectObject(physDevSrc->hdc, ddb);
++ res = 0;
++ goto noBlt1;
++ }
++ SelectObject(physDevSrc->hdc, dib);
++
++ /* we need to convert the '0' starting position on converted bitmap tp the world
++ space of bitmap's hdc */
++ zeroYSrc = 0;
++ _DIBDRV_Position_ds2ws(physDevSrc, &dummy, &zeroYSrc);
++ res = _DIBDRV_InternalBitBlt(physDevDst, xDst, yDst, width, height, physDevSrc, xSrc, zeroYSrc, rop);
++ SelectObject(physDevSrc->hdc, ddb);
++ DeleteObject(dib);
++ noBlt1:
++ ;
++ }
++ else
++ {
++ /* device DC */
++ HBITMAP dib, stock;
++ HDC memHdc;
++
++ /* we need device coordinates for ySrc and height, as the conversion
++ functions operates directly on bitmap without the hdc */
++ devXSrc = xSrc;
++ devYSrc = ySrc;
++ _DIBDRV_Position_ws2ds(physDevSrc, &devXSrc, &devYSrc);
++ devWidth = width;
++ devHeight = height;
++ _DIBDRV_Sizes_ws2ds(physDevSrc, &devWidth, &devHeight);
++
++ dib = _DIBDRV_ConvertDevDDBtoDIB(physDevSrc->hdc, physDevDst->hdc, devXSrc, devYSrc, devWidth, devHeight);
++ if(!dib)
++ {
++ ERR("Failed converting source DDB tp DIB for device DC\n");
++ res = 0;
++ goto noBlt2;
++ }
++ memHdc = CreateCompatibleDC(physDevDst->hdc);
++ if(!memHdc)
++ {
++ ERR("Failed creating temporary memory DC\n");
++ DeleteObject(dib);
++ res = 0;
++ goto noBlt2;
++ }
++ stock = SelectObject(memHdc, dib);
++ if(!stock)
++ {
++ ERR("Failed selecting converted DIB into temporary memory DC\n");
++ DeleteObject(dib);
++ DeleteDC(memHdc);
++ res = 0;
++ goto noBlt2;
++ }
++ res = BitBlt(physDevDst->hdc, xDst, yDst, width, height, memHdc, 0, 0, rop);
++
++ SelectObject(memHdc, stock);
++ DeleteObject(dib);
++ DeleteDC(memHdc);
++ noBlt2:
++ ;
++ }
++ }
++ }
++ else /* dest is a DDB */
++ {
++ /* DDB selected on dest DC, use X11 Driver */
++ if(!physDevSrc || !physDevSrc->hasDIB)
++ {
++ /* source is null or has also a DDB, no need to convert anything */
++ if(_DIBDRV_GetDisplayDriver()->pBitBlt)
++ res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
++ physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, ySrc, rop);
++ else
++ res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
++ physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, ySrc, width, height, rop);
++ }
++ else
++ {
++ /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */
++ HBITMAP dib, ddb;
++ dib = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
++ if(!dib)
++ {
++ ERR("Couldn't select out DIB from source HDC\n");
++ res = 0;
++ goto noBlt3;
++ }
++
++ /* we need device coordinates for ySrc and height, as the conversion
++ functions operates directly on bitmap without the hdc */
++ devYSrc = ySrc;
++ _DIBDRV_Position_ws2ds(physDevSrc, &dummy, &devYSrc);
++ devHeight = height;
++ _DIBDRV_Sizes_ws2ds(physDevSrc, &dummy, &devHeight);
++
++ ddb = _DIBDRV_ConvertDIBtoDDB(physDevSrc->hdc, dib, devYSrc, devHeight);
++ if(!ddb)
++ {
++ ERR("Failed converting source DIB to DDB\n");
++ SelectObject(physDevSrc->hdc, dib);
++ res = 0;
++ goto noBlt3;
++ }
++ SelectObject(physDevSrc->hdc, ddb);
++
++ /* we need to convert the '0' starting position on converted bitmap tp the world
++ space of bitmap's hdc */
++ zeroYSrc = 0;
++ _DIBDRV_Position_ds2ws(physDevSrc, &dummy, &zeroYSrc);
++
++ if(_DIBDRV_GetDisplayDriver()->pBitBlt)
++ res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
++ physDevSrc->X11PhysDev, xSrc, zeroYSrc, rop);
++ else
++ res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
++ physDevSrc->X11PhysDev, xSrc, zeroYSrc, width, height, rop);
++ SelectObject(physDevSrc->hdc, dib);
++ DeleteObject(ddb);
++noBlt3:
++ ;
++ }
++ }
++ return res;
++}
++
++/***********************************************************************
++ * _DIBDRV_InternalStretchBlt
++ */
++BOOL _DIBDRV_InternalStretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT widthDst, INT heightDst, DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop )
++{
++ BOOL res;
++ POINT pd, ps;
++ SIZE szSrc, szDst;
++ int iRec;
++ RECT dstClip, srcClip;
++
++ /* converts to device spaces */
++ _DIBDRV_Position_ws2ds(physDevDst, &xDst, &yDst);
++ _DIBDRV_Sizes_ws2ds(physDevDst, &widthDst, &heightDst);
++ if(physDevSrc)
++ {
++ _DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc);
++ _DIBDRV_Sizes_ws2ds(physDevSrc, &widthSrc, &heightSrc);
++ }
++
++ /* first clip on physical DC sizes */
++ setPoint(&pd, xDst, yDst);
++ setPoint(&ps, xSrc, ySrc);
++ setSize(&szDst, widthDst, heightDst);
++ setSize(&szSrc, widthSrc, heightSrc);
++ setRect(&dstClip, 0, 0, physDevDst->physBitmap->width, physDevDst->physBitmap->height);
++ if(physDevSrc)
++ {
++ setRect(&srcClip, 0, 0, physDevSrc->physBitmap->width, physDevSrc->physBitmap->height);
++ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, &dstClip);
++ }
++ else
++ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip);
++ if(!res)
++ return FALSE;
++ xDst = pd.x; yDst = pd.y;
++ xSrc = ps.x; ySrc = ps.y;
++ widthDst = szDst.cx; heightDst = szDst.cy;
++ widthSrc = szSrc.cx; heightSrc = szSrc.cy;
++
++ /* then, do blitting for each dest clip area (no clipping on source) */
++ res = FALSE;
++ for(iRec = 0; iRec < physDevDst->regionRectCount; iRec++)
++ {
++ RECT *r = physDevDst->regionRects + iRec;
++ setRect(&dstClip, r->left, r->top, r->right, r->bottom);
++ setPoint(&pd, xDst, yDst);
++ setPoint(&ps, xSrc, ySrc);
++ setSize(&szDst, widthDst, heightDst);
++ setSize(&szSrc, widthSrc, heightSrc);
++ if(!StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip))
++ continue;
++ if(physDevDst->physBitmap->funcs->StretchBlt(physDevDst, pd.x, pd.y, szDst.cx, szDst.cy,
++ physDevSrc, ps.x, ps.y, szSrc.cx, szSrc.cy, rop))
++ res = TRUE;
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_StretchBlt
++ */
++BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT widthDst, INT heightDst,
++ DIBDRVPHYSDEV *physDevSrc, INT xSrc, INT ySrc,
++ INT widthSrc, INT heightSrc, DWORD rop )
++{
++ BOOL res;
++ int dummy;
++ int devXSrc, devWidthSrc;
++ int devYSrc, devHeightSrc, zeroYSrc;
++
++ /* if source and dest sizes match, just call BitBlt(), it's faster */
++ if(!physDevSrc || (widthDst == widthSrc && heightDst == heightSrc))
++ return DIBDRV_BitBlt(physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, rop);
++
++CheckMapping(__FUNCTION__, "DEST", physDevDst);
++CheckMapping(__FUNCTION__, "SOURCE",physDevSrc);
++ MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d, rop:%08x\n",
++ physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(physDevDst->physBitmap) : "",
++ xDst, yDst, widthDst, heightDst,
++ physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(physDevSrc->physBitmap) : "",
++ xSrc, ySrc, widthSrc, heightSrc, rop));
++
++ if(physDevDst->hasDIB)
++ {
++ /* DIB section selected in dest DC, use DIB Engine */
++
++ if(!physDevSrc || physDevSrc->hasDIB)
++ {
++ /* source is null or has a DIB, no need to convert anyting */
++ res = _DIBDRV_InternalStretchBlt(physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, widthSrc, heightSrc, rop);
++ }
++ else
++ {
++ /* source is a DDB, must convert it to DIB */
++
++ /* we must differentiate from 2 cases :
++ 1) source DC is a memory DC
++ 2) source DC is a device DC */
++ if(GetObjectType(physDevSrc->hdc) == OBJ_MEMDC)
++ {
++ /* memory DC */
++ HBITMAP dib, ddb;
++
++ ddb = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
++ if(!ddb)
++ {
++ ERR("Couldn't select out DDB from source HDC\n");
++ res = 0;
++ goto noBlt1;
++ }
++
++ /* we need device coordinates for ySrc and height, as the conversion
++ functions operates directly on bitmap without the hdc */
++ devYSrc = ySrc;
++ _DIBDRV_Position_ws2ds(physDevSrc, &dummy, &devYSrc);
++ devHeightSrc = heightSrc;
++ _DIBDRV_Sizes_ws2ds(physDevSrc, &dummy, &devHeightSrc);
++
++ dib = _DIBDRV_ConvertDDBtoDIB(physDevSrc->hdc, ddb, devYSrc, devHeightSrc);
++ if(!dib)
++ {
++ ERR("Failed converting source DDB to DIB\n");
++ SelectObject(physDevSrc->hdc, ddb);
++ res = 0;
++ goto noBlt1;
++ }
++ SelectObject(physDevSrc->hdc, dib);
++
++
++ /* we need to convert the '0' starting position on converted bitmap tp the world
++ space of bitmap's hdc */
++ zeroYSrc = 0;
++ _DIBDRV_Position_ds2ws(physDevSrc, &dummy, &zeroYSrc);
++
++ res = _DIBDRV_InternalStretchBlt(physDevDst, xDst, yDst, widthDst, heightDst,
++ physDevSrc, xSrc, zeroYSrc, widthSrc, heightSrc, rop);
++ SelectObject(physDevSrc->hdc, ddb);
++ DeleteObject(dib);
++ noBlt1:
++ ;
++ }
++ else
++ {
++ /* device DC */
++ HBITMAP dib, stock;
++ HDC memHdc;
++
++ /* we need device coordinates for ySrc and height, as the conversion
++ functions operates directly on bitmap without the hdc */
++ devXSrc = xSrc;
++ devYSrc = ySrc;
++ _DIBDRV_Position_ws2ds(physDevSrc, &devXSrc, &devYSrc);
++ devWidthSrc = widthSrc;
++ devHeightSrc = heightSrc;
++ _DIBDRV_Sizes_ws2ds(physDevSrc, &devWidthSrc, &devHeightSrc);
++
++ dib = _DIBDRV_ConvertDevDDBtoDIB(physDevSrc->hdc, physDevDst->hdc, devXSrc, devYSrc, devWidthSrc, devHeightSrc);
++ if(!dib)
++ {
++ ERR("Failed converting source DDB tp DIB for device DC\n");
++ res = 0;
++ goto noBlt2;
++ }
++ memHdc = CreateCompatibleDC(physDevDst->hdc);
++ if(!memHdc)
++ {
++ ERR("Failed creating temporary memory DC\n");
++ DeleteObject(dib);
++ res = 0;
++ goto noBlt2;
++ }
++ stock = SelectObject(memHdc, dib);
++ if(!stock)
++ {
++ ERR("Failed selecting converted DIB into temporary memory DC\n");
++ DeleteObject(dib);
++ DeleteDC(memHdc);
++ res = 0;
++ goto noBlt2;
++ }
++ res = StretchBlt(physDevDst->hdc, xDst, yDst, widthDst, heightDst, memHdc, 0, 0, widthSrc, widthDst, rop);
++
++ SelectObject(memHdc, stock);
++ DeleteObject(dib);
++ DeleteDC(memHdc);
++ noBlt2:
++ ;
++ }
++ }
++ }
++ else /* dest is a DDB */
++ {
++ /* DDB selected on dest DC, use X11 Driver */
++ if(!physDevSrc || !physDevSrc->hasDIB)
++ {
++ /* source is null or has also a DDB, no need to convert anything */
++ res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst,
++ physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, ySrc, widthSrc, heightSrc, rop);
++ }
++ else
++ {
++ /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */
++ HBITMAP dib, ddb;
++
++ dib = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
++ if(!dib)
++ {
++ ERR("Couldn't select out DIB from source HDC\n");
++ res = 0;
++ goto noBlt3;
++ }
++
++ /* we need device coordinates for ySrc and height, as the conversion
++ functions operates directly on bitmap without the hdc */
++ devYSrc = ySrc;
++ _DIBDRV_Position_ws2ds(physDevSrc, &dummy, &devYSrc);
++ devHeightSrc = heightSrc;
++ _DIBDRV_Sizes_ws2ds(physDevSrc, &dummy, &devHeightSrc);
++
++ ddb = _DIBDRV_ConvertDIBtoDDB(physDevSrc->hdc, dib, devYSrc, devHeightSrc);
++ if(!ddb)
++ {
++ ERR("Failed converting source DIB to DDB\n");
++ SelectObject(physDevSrc->hdc, dib);
++ res = 0;
++ goto noBlt3;
++ }
++ if(!SelectObject(physDevSrc->hdc, ddb))
++ {
++ ERR("Failed to select converted DDB into source HDC\n");
++ SelectObject(physDevSrc->hdc, dib);
++ DeleteObject(ddb);
++ res = 0;
++ goto noBlt3;
++ }
++
++ /* we need to convert the '0' starting position on converted bitmap tp the world
++ space of bitmap's hdc */
++ zeroYSrc = 0;
++ _DIBDRV_Position_ds2ws(physDevSrc, &dummy, &zeroYSrc);
++ res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst,
++ physDevSrc->X11PhysDev, xSrc, zeroYSrc, widthSrc, heightSrc, rop);
++ SelectObject(physDevSrc->hdc, dib);
++ DeleteObject(ddb);
++noBlt3:
++ ;
++ }
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_PatBlt
++ */
++BOOL DIBDRV_PatBlt( DIBDRVPHYSDEV *physDev, INT left, INT top, INT width, INT height, DWORD rop )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, width:%d, height:%d, rop:%06x\n", physDev, left, top, width, height, rop));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - use BitBlt by now\n"));
++ res = DIBDRV_BitBlt(physDev, left, top, width, height, NULL, 0, 0, rop);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ if(_DIBDRV_GetDisplayDriver()->pPatBlt)
++ res = _DIBDRV_GetDisplayDriver()->pPatBlt(physDev->X11PhysDev, left, top, width, height, rop);
++ else
++ res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDev->X11PhysDev, left, top, width, height, 0, left, top, width, height, rop);
++ }
++ return res;
++}
+diff -Nru a/dlls/winedib.drv/bitmap.c b/dlls/winedib.drv/bitmap.c
+--- a/dlls/winedib.drv/bitmap.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/bitmap.c 2010-08-04 16:08:44.650222017 +0200
+@@ -0,0 +1,166 @@
++/*
++ * DIB driver bitmap objects
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++
++/****************************************************************************
++ * SelectBitmap (WINEDIB.DRV.@)
++ */
++HBITMAP DIBDRV_SelectBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap )
++{
++ DIBSECTION dibSection;
++ HBITMAP res;
++
++ MAYBE(TRACE("physDev:%p, hbitmap:%p\n", physDev, hbitmap));
++
++ /* try to get the DIBSECTION data from the bitmap */
++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) != sizeof(DIBSECTION))
++ {
++ /* not a DIB section, sets it on physDev and use X11 behaviour */
++
++ physDev->hasDIB = FALSE;
++ physDev->physBitmap = NULL;
++ res = _DIBDRV_GetDisplayDriver()->pSelectBitmap(physDev->X11PhysDev, hbitmap);
++ if(res)
++ physDev->hbitmap = hbitmap;
++ }
++ else
++ {
++ /* it's a DIB section, sets it on physDev and use DIB Engine behaviour */
++
++ /* sets the physical bitmap */
++ if((physDev->physBitmap = _BITMAPLIST_Get(hbitmap)) != NULL)
++ {
++ physDev->hasDIB = TRUE;
++ physDev->hbitmap = hbitmap;
++ MAYBE(TRACE("physDev->physBitmap:%p(%s)\n", physDev->physBitmap, _DIBDRVBITMAP_GetFormatName(physDev->physBitmap)));
++ res = hbitmap;
++ }
++ else
++ {
++ ERR("Physical bitmap %p not found in internal list\n", hbitmap);
++ physDev->hbitmap = GetStockObject(DEFAULT_BITMAP);
++ physDev->hasDIB = FALSE;
++ res = 0;
++ }
++ }
++ return res;
++}
++
++/****************************************************************************
++ * DIBDRV_CreateBitmap
++ */
++BOOL DIBDRV_CreateBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, LPVOID bmBits )
++{
++ DIBSECTION dibSection;
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, hbitmap:%p, bmBits:%p\n", physDev, hbitmap, bmBits));
++
++ /* try to get the DIBSECTION data from the bitmap */
++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) == sizeof(BITMAP))
++ {
++ /* not a DIB section, use X11 behaviour */
++ res = _DIBDRV_GetDisplayDriver()->pCreateBitmap(physDev->X11PhysDev, hbitmap, bmBits);
++ }
++ else
++ {
++ /* it's a DIB section, use DIB Engine behaviour - should not happen, but.... */
++ ERR("CreateBitmap() called for a DIB section - shouldn't happen\n");
++ res = TRUE;
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_DeleteBitmap
++ */
++BOOL DIBDRV_DeleteBitmap( HBITMAP hbitmap )
++{
++ DIBSECTION dibSection;
++ DIBDRVBITMAP *bmp;
++ BOOL res;
++
++ MAYBE(TRACE("hbitmap:%p\n", hbitmap));
++
++ /* try to get the DIBSECTION data from the bitmap */
++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) != sizeof(DIBSECTION))
++ {
++ /* not a DIB section, use X11 behaviour */
++ res = _DIBDRV_GetDisplayDriver()->pDeleteBitmap(hbitmap);
++ }
++ else
++ {
++ /* it's a DIB section, use DIB Engine behaviour */
++
++ /* do not try to delete stock objects */
++ if(hbitmap == GetStockObject(DEFAULT_BITMAP))
++ res = TRUE;
++
++ /* locates and frees the physical bitmap */
++ else if((bmp = _BITMAPLIST_Remove(hbitmap)) != NULL)
++ {
++ _DIBDRVBITMAP_Free(bmp);
++ res = TRUE;
++ }
++ else
++ {
++ ERR("Physical bitmap %p not found in internal list\n", hbitmap);
++ res = FALSE;
++ }
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_GetBitmapBits
++ */
++LONG DIBDRV_GetBitmapBits( HBITMAP hbitmap, void *buffer, LONG count )
++{
++ LONG res;
++
++ MAYBE(TRACE("hbitmap:%p, buffer:%p, count:%d\n", hbitmap, buffer, count));
++
++ /* GetBitmapBits is only valid for DDBs, so use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetBitmapBits(hbitmap, buffer, count);
++
++ return res;
++}
++
++/******************************************************************************
++ * DIBDRV_SetBitmapBits
++ */
++LONG DIBDRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count )
++{
++ LONG res;
++
++ MAYBE(TRACE("hbitmap:%p, bits:%p, count:%d\n", hbitmap, bits, count));
++
++ /* SetBitmapBits is only valid for DDBs, so use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSetBitmapBits(hbitmap, bits, count);
++
++ return res;
++}
+diff -Nru a/dlls/winedib.drv/bitmaplist.c b/dlls/winedib.drv/bitmaplist.c
+--- a/dlls/winedib.drv/bitmaplist.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/bitmaplist.c 2010-08-04 16:08:44.653222017 +0200
+@@ -0,0 +1,168 @@
++/*
++ * DIBDRV in-memory bitmap list
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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
++ */
++
++/* this modules manages association between HBITMAP handles and DIBDRVBITMAP
++ * physical bitmap objects. Needed mostly to get palettes from DIBs without
++ * resorting to GetDIBColorTable() or GETDIBits(), which are DC dependent.
++ * It makes also much easier (and faster) many bitmap operations */
++
++#include "config.h"
++#include "wine/port.h"
++
++#include "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++static CRITICAL_SECTION BITMAPLIST_CritSection;
++static CRITICAL_SECTION_DEBUG critsect_debug =
++{
++ 0, 0, &BITMAPLIST_CritSection,
++ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
++ 0, 0, { (DWORD_PTR)(__FILE__ ": BITMAPLIST_CritSection") }
++};
++static CRITICAL_SECTION BITMAPLIST_CritSection = { &critsect_debug, -1, 0, 0, 0, 0 };
++
++typedef struct _BITMAPLIST_NODE
++{
++ HBITMAP hbmp;
++ DIBDRVBITMAP *bmp;
++ UINT refCount;
++ struct _BITMAPLIST_NODE *prev, *next;
++
++} BITMAPLIST_NODE;
++
++/* the list */
++static BITMAPLIST_NODE *DIBDRV_BITMAPLIST;
++
++/* initializes bitmap list -- to be called at process attach */
++void _BITMAPLIST_Init(void)
++{
++ DIBDRV_BITMAPLIST = NULL;
++}
++
++/* terminates bitmap list -- to be called at process detach */
++void _BITMAPLIST_Terminate(void)
++{
++ BITMAPLIST_NODE *curNode, *nextNode;
++
++ EnterCriticalSection(&BITMAPLIST_CritSection);
++
++ /* frees all stored bitmaps, if any left */
++ curNode = DIBDRV_BITMAPLIST;
++ while(curNode)
++ {
++ nextNode = curNode->next;
++ ERR("Unfreed DIB found, handle is %p\n", curNode->hbmp);
++ HeapFree(GetProcessHeap(), 0, curNode);
++ curNode = nextNode;
++ }
++ DIBDRV_BITMAPLIST = NULL;
++ LeaveCriticalSection(&BITMAPLIST_CritSection);
++ DeleteCriticalSection(&BITMAPLIST_CritSection);
++}
++
++/* scan list for a DIB -- returns node containing it */
++static BITMAPLIST_NODE *GetNode(HBITMAP hbmp)
++{
++ BITMAPLIST_NODE *node = DIBDRV_BITMAPLIST;
++ while(node)
++ {
++ if(node->hbmp == hbmp)
++ return node;
++ node = node->next;
++ }
++ return NULL;
++}
++
++/* adds a DIB to the list - it adds it on top, as
++ usually most recently created DIBs are used first */
++BOOL _BITMAPLIST_Add(HBITMAP hbmp, DIBDRVBITMAP *bmp)
++{
++ BITMAPLIST_NODE *existNode, *node;
++
++ EnterCriticalSection(&BITMAPLIST_CritSection);
++
++ /* checks if already there */
++ node = NULL;
++ existNode = GetNode(hbmp);
++ if(!existNode)
++ {
++ node = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPLIST_NODE));
++ if(!node)
++ ERR("HeapAlloc failed\n");
++ else
++ {
++ node->next = DIBDRV_BITMAPLIST;
++ node->prev = NULL;
++ DIBDRV_BITMAPLIST = node;
++ if(node->next)
++ node->next->prev = node;
++ node->hbmp = hbmp;
++ node->bmp = bmp;
++ }
++ }
++ LeaveCriticalSection(&BITMAPLIST_CritSection);
++ return !existNode && node;
++}
++
++/* removes a DIB from the list */
++DIBDRVBITMAP *_BITMAPLIST_Remove(HBITMAP hbmp)
++{
++ BITMAPLIST_NODE *node;
++ DIBDRVBITMAP *bmp;
++
++ /* checks if already there */
++ EnterCriticalSection(&BITMAPLIST_CritSection);
++ node = GetNode(hbmp);
++ if(node)
++ {
++ if(node->prev)
++ node->prev->next = node->next;
++ else
++ DIBDRV_BITMAPLIST = node->next;
++ if(node->next)
++ node->next->prev = node->prev;
++ }
++ LeaveCriticalSection(&BITMAPLIST_CritSection);
++ if(node)
++ {
++ bmp = node->bmp;
++ HeapFree(GetProcessHeap(), 0, node);
++ }
++ else
++ bmp = NULL;
++ return bmp;
++}
++
++/* scans list for a DIB */
++DIBDRVBITMAP *_BITMAPLIST_Get(HBITMAP hbmp)
++{
++ BITMAPLIST_NODE *node;
++ DIBDRVBITMAP *bmp;
++
++ EnterCriticalSection(&BITMAPLIST_CritSection);
++ node = GetNode(hbmp);
++ if(!node)
++ bmp = NULL;
++ else
++ bmp = node->bmp;
++ LeaveCriticalSection(&BITMAPLIST_CritSection);
++ return bmp;
++}
+diff -Nru a/dlls/winedib.drv/clipping.c b/dlls/winedib.drv/clipping.c
+--- a/dlls/winedib.drv/clipping.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/clipping.c 2010-08-04 16:08:44.574222017 +0200
+@@ -0,0 +1,79 @@
++/*
++ * DIBDRV clipping functions
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/***********************************************************************
++ * DIBDRV_SetDeviceClipping
++ */
++void DIBDRV_SetDeviceClipping( DIBDRVPHYSDEV *physDev, HRGN vis_rgn, HRGN clip_rgn )
++{
++ RGNDATA *data;
++ DWORD size;
++ int iRect;
++
++ MAYBE(TRACE("physDev:%p, vis_rgn:%p, clip_rgn:%p\n", physDev, vis_rgn, clip_rgn));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++
++ CombineRgn( physDev->region, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
++
++ /* get region rectangles */
++ if(!(size = GetRegionData(physDev->region, 0, NULL)))
++ return;
++ data = HeapAlloc(GetProcessHeap(), 0, size);
++ if (!GetRegionData(physDev->region, size, data))
++ {
++ HeapFree( GetProcessHeap(), 0, data );
++ return;
++ }
++
++ /* frees any previous regions rectangles in DC */
++ if(physDev->regionData)
++ HeapFree(GetProcessHeap(), 0, physDev->regionData);
++
++ /* sets the rectangles on physDev */
++ physDev->regionData = data;
++ physDev->regionRects = (RECT *)data->Buffer;
++ physDev->regionRectCount = data->rdh.nCount;
++
++ if(TRACE_ON(dibdrv))
++ {
++ TRACE("Region dump : %d rectangles\n", physDev->regionRectCount);
++ for(iRect = 0; iRect < physDev->regionRectCount; iRect++)
++ {
++ RECT *r = physDev->regionRects + iRect;
++ TRACE("Rect #%03d, x1:%4d, y1:%4d, x2:%4d, y2:%4d\n", iRect, r->left, r->top, r->right, r->bottom);
++ }
++ }
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, vis_rgn, clip_rgn);
++ }
++}
+diff -Nru a/dlls/winedib.drv/convert.c b/dlls/winedib.drv/convert.c
+--- a/dlls/winedib.drv/convert.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/convert.c 2010-08-04 16:08:44.765222017 +0200
+@@ -0,0 +1,303 @@
++/*
++ * DIB Engine conversion routines
++ * Converts DDB <--> DIB
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++#include "winuser.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/***********************************************************************
++ * Creates DDB that is compatible with source hdc.
++ * hdc is the HDC on where the DIB MUST be selected in
++ * srcBmp is the source DIB
++ * startScan and scanLines specify the portion of DIB to convert
++ * in order to avoid unneeded conversion of large DIBs on blitting
++ *
++ * NOTE : the srcBmp DIB MUST NOT be selected in any DC */
++HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines )
++{
++ DIBSECTION ds;
++ BITMAPINFO *bmi;
++ HBITMAP hBmp = NULL;
++
++ int dibWidth, dibHeight;
++ BOOL topDown;
++ void *bits;
++ int stride;
++ UINT colorUsed;
++ int bitFields;
++ HDC tmpHdc;
++ HBITMAP tmpBmp;
++ int res;
++ DIBDRVBITMAP *physBitmap;
++
++ /* gets DIBSECTION data from source DIB */
++ if(GetObjectW(srcBmp, sizeof(DIBSECTION), &ds) != sizeof(DIBSECTION))
++ {
++ ERR("Couldn't get DIBSECTION data\n");
++ return 0;
++ }
++
++ /* gets DIB info */
++ dibWidth = ds.dsBmih.biWidth;
++ dibHeight = ds.dsBmih.biHeight;
++ bits = ds.dsBm.bmBits;
++ stride = ((dibWidth * ds.dsBmih.biBitCount +31) &~31) / 8;
++
++ /* get physical bitmap -- needed for topdown flag */
++ if( (physBitmap = _BITMAPLIST_Get(srcBmp)) == NULL)
++ {
++ ERR("Couldn't retrieve physical bitmap\n");
++ return 0;
++ }
++ topDown = physBitmap->topdown;
++
++ /* adjust bits to point at needed starting stripe */
++ if(topDown)
++ /* top-down DIB */
++ bits = (BYTE *)bits + startScan * stride;
++ else
++ bits = (BYTE *)bits + (dibHeight - startScan - scanLines) * stride;
++
++ /* if requested part is out of source bitmap, returns 0 */
++ if(startScan >= dibHeight)
++ return 0;
++ if(startScan + scanLines >= dibHeight)
++ scanLines = dibHeight - startScan;
++
++ /* gets the size of DIB palette and bitfields, if any */
++ bitFields = 0;
++ colorUsed = 0;
++ if(ds.dsBmih.biCompression == BI_BITFIELDS)
++ bitFields = 3;
++ else if(ds.dsBmih.biBitCount <= 8)
++ {
++ colorUsed = ds.dsBmih.biClrUsed;
++ if(!colorUsed)
++ colorUsed = 1 << ds.dsBmih.biBitCount;
++ }
++
++ /* builds the needed BITMAPINFOHEADER */
++ bmi = HeapAlloc( GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER)+
++ sizeof(RGBQUAD)*colorUsed + sizeof(DWORD) * bitFields );
++ if (!bmi)
++ {
++ ERR("HeapAlloc failed\n");
++ return 0;
++ }
++
++ /* copy the header part */
++ memcpy( &bmi->bmiHeader, &ds.dsBmih, sizeof(BITMAPINFOHEADER) );
++
++ /* gets the color table part, if any */
++ if(colorUsed)
++ {
++ /* create a temporary DC, GetDIBColorTable() requests that
++ the DIB is selected in a DC.... */
++ if(!(tmpHdc = CreateCompatibleDC(hdc)))
++ {
++ ERR("Couldn't create the temporary HDC\n");
++ HeapFree(GetProcessHeap(), 0, bmi);
++ return 0;
++ }
++ /* selects the DIB into the temporary DC */
++ if( !(tmpBmp = SelectObject(tmpHdc, srcBmp)))
++ {
++ ERR("Couldn't select source DIB into temporary DC\n");
++ DeleteDC(tmpHdc);
++ HeapFree(GetProcessHeap(), 0, bmi);
++ return 0;
++ }
++ if(!GetDIBColorTable(tmpHdc, 0, colorUsed, bmi->bmiColors))
++ ERR("GetDIBColorTable failed\n");
++ SelectObject(tmpHdc, tmpBmp);
++ DeleteDC(tmpHdc);
++
++ }
++
++ /* fill the bitfields part, if any */
++ if(bitFields)
++ memcpy(bmi->bmiColors, ds.dsBitfields, 3 * sizeof(DWORD));
++
++ /* adjust dib size for SetDIBits, as it needs it to reverse top-down dibs
++ it must be set to the number of scanLines to transfer */
++ bmi->bmiHeader.biHeight = topDown ? -scanLines : scanLines;
++
++ /* creates destination compatible bitmap */
++ tmpHdc = GetDC(NULL);
++ hBmp = CreateCompatibleBitmap(tmpHdc, dibWidth, scanLines);
++ ReleaseDC(NULL, tmpHdc);
++ if(!hBmp)
++ {
++ ERR("CreateCompatibleBitmap failed\n");
++ HeapFree( GetProcessHeap(), 0, bmi );
++ return 0;
++ }
++
++ /* copies the requested scan lines from DIB to DDB */
++ /* FIXME : still no support for RLE packed DIBs */
++ res = SetDIBits( hdc, hBmp, 0, scanLines, bits, bmi, DIB_RGB_COLORS );
++ HeapFree( GetProcessHeap(), 0, bmi );
++ if(!res)
++ {
++ ERR("SetDIBits failed\n");
++ DeleteObject( hBmp );
++ return 0;
++ }
++
++ return hBmp;
++}
++
++/***********************************************************************
++ * Creates DIB that is compatible with the target hdc.
++ * startScan and scanLines specify the portion of DDB to convert
++ * in order to avoid unneeded conversion of large DDBs on blitting
++ *
++ * NOTE : the srcBmp DDB MUST NOT be selected in any DC */
++HBITMAP _DIBDRV_ConvertDDBtoDIB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines )
++{
++ HBITMAP hBmp = NULL;
++ BITMAP bitmap;
++ BITMAPINFO *bi;
++ void *bits = NULL;
++
++ if (!GetObjectW( srcBmp, sizeof(bitmap), &bitmap ))
++ {
++ ERR("Couldn't retrieve source bitmap\n");
++ return 0;
++ }
++
++ if(startScan + scanLines >= bitmap.bmHeight)
++ scanLines = bitmap.bmHeight - startScan;
++
++ bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) /* + 256 * sizeof(RGBQUAD) */);
++ if (!bi)
++ {
++ ERR("HeapAlloc failed\n");
++ return 0;
++ }
++
++ bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
++ bi->bmiHeader.biWidth = bitmap.bmWidth;
++ bi->bmiHeader.biHeight = scanLines;
++ bi->bmiHeader.biPlanes = bitmap.bmPlanes;
++ bi->bmiHeader.biBitCount = 32;
++ bi->bmiHeader.biCompression = BI_RGB;
++ bi->bmiHeader.biSizeImage = 0;
++
++ /* No need to get the color table or the color masks
++ as we're requesting a 32 bit rgba DIB */
++
++ /* Create bitmap and fill in bits */
++ hBmp = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
++ if(!hBmp)
++ {
++ ERR("Failed to create DIB section\n");
++ HeapFree( GetProcessHeap(), 0, bi );
++ return 0;
++ }
++ if (bits)
++ {
++ if(!GetDIBits(hdc, srcBmp, startScan, scanLines, bits, bi, DIB_RGB_COLORS))
++ {
++ ERR("GetDIBits failed\n");
++ DeleteObject( hBmp );
++ HeapFree( GetProcessHeap(), 0, bi );
++ return 0;
++ }
++ }
++ else
++ {
++ ERR("CreateDibSection couldn't allocate DIB bits\n");
++ DeleteObject( hBmp );
++ HeapFree( GetProcessHeap(), 0, bi );
++ return 0;
++ }
++ HeapFree( GetProcessHeap(), 0, bi );
++ return hBmp;
++}
++
++/***********************************************************************
++ * BITBLT_ConvertDevDDBtoDIB
++ *
++ * Creates DIB that is compatible with the target hdc for a device (non memory) source DC */
++HBITMAP _DIBDRV_ConvertDevDDBtoDIB( HDC hdcSrc, HDC hdcDst, int xSrc, int ySrc, int width, int height )
++{
++ HBITMAP bmp, dib;
++ HDC memHDC = NULL;
++
++ /* at first, we create a compatible DC and a bitmap with needed sizes */
++ memHDC = CreateCompatibleDC(hdcSrc);
++ if(!memHDC)
++ {
++ ERR("CreateCompatibleDC failed\n");
++ return 0;
++ }
++ bmp = CreateCompatibleBitmap(hdcSrc, width, height);
++ if(!bmp)
++ {
++ ERR("CreateCompatibleBitmap failed\n");
++ DeleteDC(memHDC);
++ return 0;
++ }
++
++ /* select the newly created DDB into the temporary DC */
++ bmp = SelectObject(memHDC, bmp);
++ if(!bmp)
++ {
++ ERR("Failed selecting DDB into temporary DC\n");
++ DeleteObject(bmp);
++ DeleteDC(memHDC);
++ return 0;
++ }
++
++ /* next, we blit pixels from device to the compatible bitmap */
++ if(!BitBlt(memHDC, 0, 0, width, height, hdcSrc, xSrc, ySrc, SRCCOPY))
++ {
++ ERR("BitBlt failed\n");
++ DeleteObject(bmp);
++ DeleteDC(memHDC);
++ return 0;
++ }
++
++ /* select out the DDB from the temporary DC */
++ bmp = SelectObject(memHDC, bmp);
++ DeleteDC(memHDC);
++ if(!bmp)
++ {
++ ERR("Failed selecting DDB out temporary DC\n");
++ DeleteObject(bmp);
++ return 0;
++ }
++
++ /*now we can convert the bitmap to a DIB */
++ dib = _DIBDRV_ConvertDDBtoDIB( hdcDst, bmp, 0, height );
++ if(!dib)
++ FIXME("ConvertDDBtoDIB failed\n");
++
++ /* free resources and return the created dib */
++ DeleteObject(bmp);
++ return dib;
++}
+diff -Nru a/dlls/winedib.drv/dc.c b/dlls/winedib.drv/dc.c
+--- a/dlls/winedib.drv/dc.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/dc.c 2010-08-04 16:08:44.656222017 +0200
+@@ -0,0 +1,427 @@
++/*
++ * DIB driver initialization functions
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++
++/* some screen caps */
++static unsigned int screen_width;
++static unsigned int screen_height;
++static unsigned int screen_bpp;
++static unsigned int screen_depth;
++static RECT virtual_screen_rect;
++
++/* a few dynamic device caps */
++static int log_pixels_x; /* pixels per logical inch in x direction */
++static int log_pixels_y; /* pixels per logical inch in y direction */
++static int horz_size; /* horz. size of screen in millimeters */
++static int vert_size; /* vert. size of screen in millimeters */
++static int palette_size;
++static int device_init_done;
++
++/* NOTE :
++ Removing TC_RA_ABLE avoids bitmapped fonts, so FT_Face is always non-NULL
++ UPDATE : remove TC_RA_ABLE seems unneeded
++ Adding TC_VA_ABLE forces to use gdi fonts always, so we can get an FT_Face
++*/
++unsigned int text_caps = (TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
++ TC_CR_ANY | TC_SA_DOUBLE | TC_SA_INTEGER |
++ TC_SA_CONTIN | TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE | TC_VA_ABLE);
++ /* X11R6 adds TC_SF_X_YINDEP, Xrender adds TC_VA_ABLE */
++
++
++static const WCHAR dpi_key_name[] = {'S','o','f','t','w','a','r','e','\\','F','o','n','t','s','\0'};
++static const WCHAR dpi_value_name[] = {'L','o','g','P','i','x','e','l','s','\0'};
++
++/******************************************************************************
++ * get_dpi
++ *
++ * get the dpi from the registry
++ */
++static DWORD get_dpi( void )
++{
++ DWORD dpi = 96;
++ HKEY hkey;
++
++ if (RegOpenKeyW(HKEY_CURRENT_CONFIG, dpi_key_name, &hkey) == ERROR_SUCCESS)
++ {
++ DWORD type, size, new_dpi;
++
++ size = sizeof(new_dpi);
++ if(RegQueryValueExW(hkey, dpi_value_name, NULL, &type, (void *)&new_dpi, &size) == ERROR_SUCCESS)
++ {
++ if(type == REG_DWORD && new_dpi != 0)
++ dpi = new_dpi;
++ }
++ RegCloseKey(hkey);
++ }
++ return dpi;
++}
++
++/* dummy function for pen/brush drawing primitives initializations */
++static void dummy4(DIBDRVPHYSDEV *physDev, int a, int b, int c) {} ;
++static void dummy5(DIBDRVPHYSDEV *physDev, int a, int b, int c, int d) {} ;
++
++/**********************************************************************
++ * device_init
++ *
++ * Perform initializations needed upon creation of the first device.
++ */
++static void device_init(void)
++{
++ Display *display;
++ Screen *screen;
++
++ /* opens default X11 Display */
++ if( (display = XOpenDisplay(NULL)) == NULL)
++ return;
++
++ /* gets default screen */
++ screen = XDefaultScreenOfDisplay(display);
++
++ /* gets screen sizes */
++ screen_width = XWidthOfScreen(screen);
++ screen_height = XHeightOfScreen(screen);
++
++ /* not sure about these ones... */
++ screen_bpp = XDefaultDepthOfScreen(screen);
++ screen_depth = XPlanesOfScreen(screen);
++ virtual_screen_rect.left = 0;
++ virtual_screen_rect.top = 0;
++ virtual_screen_rect.right = screen_width;
++ virtual_screen_rect.bottom = screen_height;
++
++ /* dummy ? */
++ palette_size = 0;
++
++ /* Initialize device caps */
++ log_pixels_x = log_pixels_y = get_dpi();
++ horz_size = MulDiv( screen_width, 254, log_pixels_x * 10 );
++ vert_size = MulDiv( screen_height, 254, log_pixels_y * 10 );
++
++ device_init_done = TRUE;
++}
++
++/**********************************************************************
++ * DIBDRV_CreateDC
++ */
++BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR device,
++ LPCWSTR output, const DEVMODEW* initData )
++{
++ DIBDRVPHYSDEV *physDev;
++ PHYSDEV X11PhysDev;
++
++ MAYBE(TRACE("hdc:%p, pdev:%p, driver:%s, device:%s, output:%s, initData:%p\n",
++ hdc, pdev, debugstr_w(driver), debugstr_w(device), debugstr_w(output), initData));
++
++ /* allocates physical device */
++ physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIBDRVPHYSDEV) );
++ if (!physDev)
++ return FALSE;
++
++ /* creates X11 physical device */
++ if(!_DIBDRV_GetDisplayDriver()->pCreateDC(hdc, &X11PhysDev, driver, device, output, initData))
++ {
++ HeapFree(GetProcessHeap(), 0, physDev);
++ return FALSE;
++ }
++
++ /* sets X11 Device pointer in DIB Engine device */
++ physDev->X11PhysDev = X11PhysDev;
++
++ /* stores the HDC */
++ physDev->hdc = hdc;
++
++ /* initializes device data (for GetDeviceCaps() )
++ on first DC creation */
++ if (!device_init_done)
++ device_init();
++
++ /* stock bitmap selected on DC creation */
++ physDev->hbitmap = GetStockObject(DEFAULT_BITMAP);
++
++ /* no DIB selected into DC on creation */
++ physDev->hasDIB = FALSE;
++
++ /* initializes the physical bitmap */
++ physDev->physBitmap = NULL;
++
++ /* clears pen and brush */
++ physDev->rop2 = R2_COPYPEN;
++
++ /* clipping region */
++ physDev->region = CreateRectRgn( 0, 0, 0, 0 );
++ physDev->regionData = NULL;
++ physDev->regionRects = NULL;
++ physDev->regionRectCount = 0;
++
++ physDev->backgroundColor = 0;
++ _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->backgroundAnd, &physDev->backgroundXor);
++
++ /* stock pen */
++ physDev->penStyle = PS_NULL;
++ physDev->penColor = 0;
++ physDev->penColorref = 0;
++ _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->penAnd, &physDev->penXor);
++ physDev->penHLine = dummy4;
++ physDev->penVLine = dummy4;
++ physDev->penLine = dummy5;
++ physDev->penPattern = NULL;
++
++ /* stock brush */
++ physDev->brushStyle = BS_NULL;
++ physDev->brushColor = 0x0;
++ physDev->brushColorref = 0x0;
++ _DIBDRV_CalcAndXorMasks(physDev->rop2, 0x0, &physDev->brushAnd, &physDev->brushXor);
++ physDev->brushAnds = NULL;
++ physDev->brushXors = NULL;
++ physDev->brushHLine = dummy4;
++
++ physDev->isBrushBitmap = FALSE;
++ physDev->brushBitmap = NULL;
++ physDev->brushBmpCache = NULL;
++
++ /* text color */
++ physDev->textColor = 0;
++ physDev->textBackground = 0;
++
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ /* text color table for antialiased fonts */
++ memset(physDev->textColorTable, 0, 256);
++#endif
++
++ /* freetype face associated to current DC HFONT */
++ physDev->face = NULL;
++
++ /* sets the result value and returns */
++ *pdev = physDev;
++
++ return TRUE;
++}
++
++/**********************************************************************
++ * DIBDRV_DeleteDC
++ */
++BOOL DIBDRV_DeleteDC( DIBDRVPHYSDEV *physDev )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p\n", physDev));
++
++ /* frees X11 device */
++ res = _DIBDRV_GetDisplayDriver()->pDeleteDC(physDev->X11PhysDev);
++ physDev->X11PhysDev = NULL;
++
++ /* resets physical bitmap */
++ physDev->physBitmap = NULL;
++
++ /* reset brush bitmap */
++ _DIBDRVBITMAP_Free(physDev->brushBitmap);
++ physDev->brushBitmap = NULL;
++ _DIBDRVBITMAP_Free(physDev->brushBmpCache);
++ physDev->brushBmpCache = NULL;
++
++ /* free brush ands and xors */
++ if(physDev->brushAnds)
++ {
++ HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
++ HeapFree(GetProcessHeap(), 0, physDev->brushXors);
++ }
++ physDev->brushAnds = NULL;
++ physDev->brushXors = NULL;
++
++ /* frees clipping region */
++ DeleteObject(physDev->region);
++ if(physDev->regionData)
++ HeapFree(GetProcessHeap(), 0, physDev->regionData);
++ physDev->regionData = NULL;
++ physDev->regionRects = NULL;
++ physDev->regionRectCount = 0;
++
++ /* frees DIB Engine device */
++ HeapFree(GetProcessHeap(), 0, physDev);
++
++ return res;
++}
++
++/**********************************************************************
++ * DIBDRV_ExtEscape
++ */
++INT DIBDRV_ExtEscape( DIBDRVPHYSDEV *physDev, INT escape, INT in_count, LPCVOID in_data,
++ INT out_count, LPVOID out_data )
++{
++ INT res;
++
++ MAYBE(TRACE("physDev:%p, escape:%d, in_count:%d, in_data:%p, out_count:%d, out_data:%p\n",
++ physDev, escape, in_count, in_data, out_count, out_data));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_GetDeviceCaps
++ */
++INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap )
++{
++ INT res;
++
++ MAYBE(TRACE("physDev:%p, cap:%d\n", physDev, cap));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ switch(cap)
++ {
++ case DRIVERVERSION:
++ res = 0x300;
++ break;
++ case TECHNOLOGY:
++ res = DT_RASDISPLAY;
++ break;
++ case HORZSIZE:
++ res = horz_size;
++ break;
++ case VERTSIZE:
++ res = vert_size;
++ break;
++ case HORZRES:
++ res = screen_width;
++ break;
++ case VERTRES:
++ res = screen_height;
++ break;
++ case DESKTOPHORZRES:
++ res = virtual_screen_rect.right - virtual_screen_rect.left;
++ break;
++ case DESKTOPVERTRES:
++ res = virtual_screen_rect.bottom - virtual_screen_rect.top;
++ break;
++ case BITSPIXEL:
++ res = screen_bpp;
++ break;
++ case PLANES:
++ res = 1;
++ break;
++ case NUMBRUSHES:
++ res = -1;
++ break;
++ case NUMPENS:
++ res = -1;
++ break;
++ case NUMMARKERS:
++ res = 0;
++ break;
++ case NUMFONTS:
++ res = 0;
++ break;
++ case NUMCOLORS:
++ /* MSDN: Number of entries in the device's color table, if the device has
++ * a color depth of no more than 8 bits per pixel.For devices with greater
++ * color depths, -1 is returned. */
++ res = (screen_depth > 8) ? -1 : (1 << screen_depth);
++ break;
++ case CURVECAPS:
++ res = (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
++ CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
++ break;
++ case LINECAPS:
++ res = (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
++ LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
++ break;
++ case POLYGONALCAPS:
++ res = (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
++ PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
++ break;
++ case TEXTCAPS:
++ res = text_caps;
++ break;
++ case CLIPCAPS:
++ res = CP_REGION;
++ break;
++ case RASTERCAPS:
++ res = (RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 | RC_DI_BITMAP |
++ RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS |
++ (palette_size ? RC_PALETTE : 0));
++ break;
++ case SHADEBLENDCAPS:
++ res = (SB_GRAD_RECT | SB_GRAD_TRI | SB_CONST_ALPHA | SB_PIXEL_ALPHA);
++ case ASPECTX:
++ case ASPECTY:
++ res = 36;
++ break;
++ case ASPECTXY:
++ res = 51;
++ break;
++ case LOGPIXELSX:
++ res = log_pixels_x;
++ break;
++ case LOGPIXELSY:
++ res = log_pixels_y;
++ break;
++ case CAPS1:
++ FIXME("(%p): CAPS1 is unimplemented, will return 0\n", physDev->hdc );
++ /* please see wingdi.h for the possible bit-flag values that need
++ to be returned. */
++ res = 0;
++ break;
++ case SIZEPALETTE:
++ res = palette_size;
++ break;
++ case NUMRESERVED:
++ case COLORRES:
++ case PHYSICALWIDTH:
++ case PHYSICALHEIGHT:
++ case PHYSICALOFFSETX:
++ case PHYSICALOFFSETY:
++ case SCALINGFACTORX:
++ case SCALINGFACTORY:
++ case VREFRESH:
++ case BLTALIGNMENT:
++ res = 0;
++ break;
++ default:
++ FIXME("(%p): unsupported capability %d, will return 0\n", physDev->hdc, cap );
++ res = 0;
++ break;
++ }
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetDeviceCaps(physDev->X11PhysDev, cap);
++ }
++ return res;
++}
+diff -Nru a/dlls/winedib.drv/dib.c b/dlls/winedib.drv/dib.c
+--- a/dlls/winedib.drv/dib.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/dib.c 2010-08-04 16:08:44.790222017 +0200
+@@ -0,0 +1,460 @@
++/*
++ * DIBDRV device-independent bitmaps
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/* Default 1 BPP palette */
++static DWORD pal1[] =
++{
++ 0x000000,
++ 0xffffff
++};
++
++/* Default 4 BPP palette */
++static DWORD pal4[] =
++{
++ 0x000000,0x800000,0x008000,0x808000,
++ 0x000080,0x800080,0x008080,0x808080,
++ 0xc0c0c0,0xff0000,0x00ff00,0xffff00,
++ 0x0000ff,0xff00ff,0x00ffff,0xffffff
++};
++
++/* Default 8 BPP palette */
++static DWORD pal8[] =
++{
++ 0x000000,0x800000,0x008000,0x808000,0x000080,0x800080,0x008080,0xc0c0c0,0xc0dcc0,0xa6caf0,0x000000,0x000033,0x000066,0x000099,0x0000cc,0x0000ff,
++ 0x003300,0x003333,0x003366,0x003399,0x0033cc,0x0033ff,0x006600,0x006633,0x006666,0x006699,0x0066cc,0x0066ff,0x009900,0x009933,0x009966,0x009999,
++ 0x0099cc,0x0099ff,0x00cc00,0x00cc33,0x00cc66,0x00cc99,0x00cccc,0x00ccff,0x00ff00,0x00ff33,0x00ff66,0x00ff99,0x00ffcc,0x00ffff,0x330000,0x330033,
++ 0x330066,0x330099,0x3300cc,0x3300ff,0x333300,0x333333,0x333366,0x333399,0x3333cc,0x3333ff,0x336600,0x336633,0x336666,0x336699,0x3366cc,0x3366ff,
++ 0x339900,0x339933,0x339966,0x339999,0x3399cc,0x3399ff,0x33cc00,0x33cc33,0x33cc66,0x33cc99,0x33cccc,0x33ccff,0x33ff00,0x33ff33,0x33ff66,0x33ff99,
++ 0x33ffcc,0x33ffff,0x660000,0x660033,0x660066,0x660099,0x6600cc,0x6600ff,0x663300,0x663333,0x663366,0x663399,0x6633cc,0x6633ff,0x666600,0x666633,
++ 0x666666,0x666699,0x6666cc,0x6666ff,0x669900,0x669933,0x669966,0x669999,0x6699cc,0x6699ff,0x66cc00,0x66cc33,0x66cc66,0x66cc99,0x66cccc,0x66ccff,
++ 0x66ff00,0x66ff33,0x66ff66,0x66ff99,0x66ffcc,0x66ffff,0x990000,0x990033,0x990066,0x990099,0x9900cc,0x9900ff,0x993300,0x993333,0x993366,0x993399,
++ 0x9933cc,0x9933ff,0x996600,0x996633,0x996666,0x996699,0x9966cc,0x9966ff,0x999900,0x999933,0x999966,0x999999,0x9999cc,0x9999ff,0x99cc00,0x99cc33,
++ 0x99cc66,0x99cc99,0x99cccc,0x99ccff,0x99ff00,0x99ff33,0x99ff66,0x99ff99,0x99ffcc,0x99ffff,0xcc0000,0xcc0033,0xcc0066,0xcc0099,0xcc00cc,0xcc00ff,
++ 0xcc3300,0xcc3333,0xcc3366,0xcc3399,0xcc33cc,0xcc33ff,0xcc6600,0xcc6633,0xcc6666,0xcc6699,0xcc66cc,0xcc66ff,0xcc9900,0xcc9933,0xcc9966,0xcc9999,
++ 0xcc99cc,0xcc99ff,0xcccc00,0xcccc33,0xcccc66,0xcccc99,0xcccccc,0xccccff,0xccff00,0xccff33,0xccff66,0xccff99,0xccffcc,0xccffff,0xff0000,0xff0033,
++ 0xff0066,0xff0099,0xff00cc,0xff00ff,0xff3300,0xff3333,0xff3366,0xff3399,0xff33cc,0xff33ff,0xff6600,0xff6633,0xff6666,0xff6699,0xff66cc,0xff66ff,
++ 0xff9900,0xff9933,0xff9966,0xff9999,0xff99cc,0xff99ff,0xffcc00,0xffcc33,0xffcc66,0xffcc99,0xffcccc,0xffccff,0xffff00,0xffff33,0xffff66,0xffff99,
++ 0xffffcc,0xffffff,0x050500,0x050501,0x050502,0x050503,0x050504,0x050505,0xe8e8e8,0xe9e9e9,0xeaeaea,0xebebeb,0xececec,0xededed,0xeeeeee,0xefefef,
++ 0xf0f0f0,0xf1f1f1,0xf2f2f2,0xf3f3f3,0xf4f4f4,0xf5f5f5,0xfffbf0,0xa0a0a4,0x808080,0xf00000,0x00ff00,0xffff00,0x0000ff,0xff00ff,0x00ffff,0xffffff
++};
++
++/***********************************************************************
++ * DIBDRV_CreateDIBSection
++ */
++HBITMAP DIBDRV_CreateDIBSection( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap,
++ const BITMAPINFO *bmi, UINT usage )
++{
++ DIBDRVBITMAP *bmp;
++ DIBSECTION ds;
++
++ MAYBE(TRACE("physDev:%p, hbitmap:%p, bmi:%p, usage:%d\n", physDev, hbitmap, bmi, usage));
++
++ /* createDIBSection is only DIB-related, so we just use the engine */
++
++ /* we need bitmap bits */
++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &ds) != sizeof(DIBSECTION))
++ {
++ ERR("Bitmap is not a DIB Section\n");
++ return NULL;
++ }
++
++ /* creates the physical bitmap */
++ if(!(bmp = _DIBDRVBITMAP_CreateFromBitmapinfo(bmi, ds.dsBm.bmBits)))
++ {
++ ERR("_DIBDRVBITMAP_CreateFromBitmapinfo failed\n");
++ return NULL;
++ }
++
++ /* TEMPORARY -- if usage is DIB_PAL_COLOR, sets the palette
++ as ungrabbed, so next call to RealizeDefaultPalette will
++ do it */
++ if(usage == DIB_PAL_COLORS)
++ {
++ FIXME("Do color table grabbing here instead of RealizeDefaultPalette\n");
++ bmp->colorTableGrabbed = FALSE;
++ }
++
++ /* adds it to the internal list */
++ if(!_BITMAPLIST_Add(hbitmap, bmp))
++ {
++ ERR("Couldn't add physical bitmap to list\n");
++ _DIBDRVBITMAP_Free(bmp);
++ return NULL;
++ }
++ return hbitmap;
++}
++
++/***********************************************************************
++ * DIBDRV_GetDIBits
++*/
++INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan,
++ UINT lines, LPVOID bits, BITMAPINFO *info, UINT coloruse )
++{
++ INT res;
++ DIBSECTION ds;
++ DIBDRVBITMAP *sBmp, *dBmp;
++ DWORD *buf;
++ int iLine;
++ int size;
++ int requestedBpp;
++ RGBQUAD *colorTable = NULL;
++
++ MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, info:%p, coloruse:%d\n",
++ physDev, hbitmap, startscan, lines, bits, info, coloruse));
++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &ds) == sizeof(DIBSECTION))
++ {
++ /* GetDIBits reads bits from a DIB, so we should use the engine driver */
++
++ /* for the moment, we don't support startscan != 0 */
++ if(startscan != 0)
++ {
++ FIXME("startscan != 0 still not supported\n");
++ return 0;
++ }
++
++ /* sanity check */
++ size = info->bmiHeader.biSize;
++ if(size != sizeof(BITMAPINFOHEADER) && size != sizeof(BITMAPCOREHEADER))
++ {
++ ERR("Unknown header size %d\n", size);
++ return 0;
++ }
++
++ /* if we wants just the BITMAPINFOHEADER data, do it */
++ if(bits == NULL && info->bmiHeader.biBitCount == 0)
++ {
++ memcpy(&info->bmiHeader, &ds.dsBmih, size);
++ return abs(ds.dsBmih.biHeight);
++ }
++
++ /* source and dest sizes must match */
++ if(info->bmiHeader.biWidth != ds.dsBmih.biWidth || abs(info->bmiHeader.biHeight) != abs(ds.dsBmih.biHeight))
++ {
++ WARN("Source and dest DIBs sizes don't match\n");
++ return 0;
++ }
++
++ /* get requested BPP and check it */
++ requestedBpp = info->bmiHeader.biBitCount;
++ if(requestedBpp != 1 && requestedBpp != 4 &&
++ requestedBpp != 8 && requestedBpp != 16 &&
++ requestedBpp != 24 && requestedBpp != 32)
++ {
++ ERR("Unknown BitCount %d\n", requestedBpp);
++ return 0;
++ }
++
++ /* now we must get (if needed) the color table */
++ if(!(sBmp = _BITMAPLIST_Get(hbitmap)))
++ {
++ ERR("Couldn't retrieve source DIB data\n");
++ return 0;
++ }
++ if(requestedBpp <= 8)
++ {
++ colorTable = (RGBQUAD *)((BYTE *)info + size);
++
++ /* if same color format, just grab the color table */
++ if(requestedBpp == sBmp->bitCount)
++ memcpy(colorTable, sBmp->colorTable, sBmp->colorTableSize);
++ /* otherwise synthesize a new color table */
++ else
++ {
++ switch(requestedBpp)
++ {
++ case 1:
++ memcpy(colorTable, pal1, 2*sizeof(DWORD));
++ break;
++
++ case 4:
++ memcpy(colorTable, pal4, 16*sizeof(DWORD));
++ break;
++
++ case 8:
++ memcpy(colorTable, pal8, 256*sizeof(DWORD));
++ break;
++
++ default:
++ ERR("Unknown requested bith depth %d\n", requestedBpp);
++ return 0;
++ }
++ }
++ }
++
++ /* If we wanted just BITMAPINFO data, we're done */
++ if(!bits)
++ return abs(ds.dsBmih.biHeight);
++
++ /* now it's time to transfer image bits; for this we should create
++ a DIBDRVBITMAP from dest BITMAPINFO data */
++ /* FIXME -- HERE is the place to add support for 'startscan' stuffs */
++ if(!(dBmp = _DIBDRVBITMAP_CreateFromBMIH((BITMAPINFOHEADER *)info, ds.dsBitfields, colorTable, bits)))
++ {
++ ERR("Couldn't create dest DIB\n");
++ return 0;
++ }
++
++ /* now we can do the bit conversion */
++ buf = HeapAlloc(GetProcessHeap(), 0, ds.dsBmih.biWidth * sizeof(RGBQUAD));
++ for(iLine = 0; iLine < lines; iLine++)
++ {
++ sBmp->funcs->GetLine(sBmp, iLine, 0, ds.dsBmih.biWidth, buf);
++ dBmp->funcs->PutLine(dBmp, iLine, 0, ds.dsBmih.biWidth, buf);
++ }
++ HeapFree(GetProcessHeap(), 0, buf);
++ _DIBDRVBITMAP_Free(dBmp);
++ return lines;
++ }
++ else
++ /* GetDIBits reads bits from a DDB, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, info, coloruse);
++
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_SetDIBColorTable
++ */
++UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count,
++ const RGBQUAD *colors )
++{
++ DIBDRVBITMAP *dib = physDev->physBitmap;
++ HBRUSH thisBrush;
++ HPEN thisPen;
++
++ MAYBE(TRACE("physDev:%p, start:%d, count:%d, colors:%p\n", physDev, start, count, colors));
++ /* SetDIBColorTable operates on a DIB, so we use the engine */
++
++ /* if bpp > 8, some error occurred... */
++ if(dib->bitCount > 8)
++ {
++ ERR("Called for BPP > 8\n");
++ return 0;
++ }
++
++ /* if dib hasn't a color table, or has a small one, we must before
++ create/extend it */
++ if(!dib->colorTable)
++ {
++ dib->colorTableSize = (1 << dib->bitCount);
++ dib->colorTable = HeapAlloc(GetProcessHeap(), 0, sizeof(RGBQUAD) * dib->colorTableSize);
++ }
++ else if(dib->colorTableSize < (1 << dib->bitCount))
++ {
++ int newSize = (1 << dib->bitCount);
++ RGBQUAD *newTable = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RGBQUAD) * newSize);
++ memcpy(newTable, dib->colorTable, sizeof(RGBQUAD) * dib->colorTableSize);
++ HeapFree(GetProcessHeap(), 0, dib->colorTable);
++ dib->colorTable = newTable;
++ dib->colorTableSize = newSize;
++ }
++
++ /* sanity check */
++ if(start + count > dib->colorTableSize)
++ {
++ ERR("Out of range setting color table, size is %d, requested is %d\n", dib->colorTableSize, start+count);
++ return 0;
++ }
++ memcpy(dib->colorTable + start, colors, sizeof(RGBQUAD) * count);
++ dib->colorTableGrabbed = TRUE;
++
++ /* for monochrome bitmaps, we need the 'lightest' color */
++ _DIBDRVBITMAP_GetLightestColorIndex(dib);
++
++ /* we should re-select both current pen and brush
++ in order to update colormap-dependent colors */
++ thisBrush = SelectObject(physDev->hdc, GetStockObject(NULL_BRUSH));
++ thisPen = SelectObject(physDev->hdc, GetStockObject(NULL_PEN));
++ SelectObject(physDev->hdc, thisBrush);
++ SelectObject(physDev->hdc, thisPen);
++
++ return TRUE;
++}
++
++/***********************************************************************
++ * DIBDRV_SetDIBits
++ */
++INT DIBDRV_SetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan,
++ UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse )
++{
++ INT res;
++ DIBSECTION ds;
++ DIBDRVBITMAP *sBmp, *dBmp;
++ DWORD *buf;
++ int iLine;
++
++ MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n",
++ physDev, hbitmap, startscan, lines, bits, info, coloruse));
++
++ /* quick fix for wine-1.2-rc1 */
++ if((int)lines < 0)
++ lines = -lines;
++
++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &ds) == sizeof(DIBSECTION))
++ {
++ /* SetDIBits writes bits to a DIB, so we should use the engine driver */
++
++ /* for the moment, we don't support startscan != 0 */
++ if(startscan != 0)
++ {
++ FIXME("startscan != 0 still not supported\n");
++ return 0;
++ }
++
++ /* Creates a DIBDRVBITMAP from source dib */
++ if(!(sBmp = _DIBDRVBITMAP_CreateFromBitmapinfo(info, (LPVOID)bits)))
++ {
++ ERR("_DIBDRVBITMAP_CreateFromBitmapinfo failed\n");
++ return 0;
++ }
++
++ /* get destination physical bitmap */
++ if(!(dBmp = _BITMAPLIST_Get(hbitmap)))
++ {
++ ERR("Couldn't retrieve dest physical bitmap\n");
++ _DIBDRVBITMAP_Free(sBmp);
++ return 0;
++ }
++
++ /* now we can do the bit conversion */
++ buf = HeapAlloc(GetProcessHeap(), 0, ds.dsBmih.biWidth * sizeof(RGBQUAD));
++ for(iLine = 0; iLine < lines; iLine++)
++ {
++ sBmp->funcs->GetLine(sBmp, iLine, 0, ds.dsBmih.biWidth, buf);
++ dBmp->funcs->PutLine(dBmp, iLine, 0, ds.dsBmih.biWidth, buf);
++ }
++ HeapFree(GetProcessHeap(), 0, buf);
++ _DIBDRVBITMAP_Free(sBmp);
++ return lines;
++ }
++ else
++ {
++ /* SetDIBits writes bits to a DDB, so we should use the X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, info, coloruse);
++ }
++ return res;
++}
++
++/*************************************************************************
++ * DIBDRV_SetDIBitsToDevice
++ */
++INT DIBDRV_SetDIBitsToDevice( DIBDRVPHYSDEV *physDev, INT xDst, INT yDst, DWORD cx,
++ DWORD cy, INT xSrc, INT ySrc,
++ UINT startscan, UINT lines, LPCVOID bits,
++ const BITMAPINFO *info, UINT coloruse )
++{
++ int dibHeight, dibWidth;
++ DIBDRVBITMAP *sBmp, *dBmp;
++ int iLine;
++ void *buf;
++
++ MAYBE(TRACE("physDev:%p, xDst:%d, yDst:%d, cx:%x, cy:%x, xSrc:%d, ySrc:%d, startscan:%d, lines:%d, bits:%p, info:%p, coloruse:%d\n",
++ physDev, xDst, yDst, cx, cy, xSrc, ySrc, startscan, lines, bits, info, coloruse));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++
++ /* inverts y on source -- FIXME: check if right with some tests, it seems so */
++// ySrc = abs(info->bmiHeader.biHeight) - ySrc - cy;
++
++ dibHeight = info->bmiHeader.biHeight;
++ dibWidth = info->bmiHeader.biWidth;
++
++ /* sanity check and source clipping on physical sizes */
++ if(startscan >= abs(dibHeight))
++ {
++ ERR("startscan out of range\n");
++ return 0;
++ }
++ if(startscan + lines > abs(dibHeight))
++ lines = abs(dibHeight) - startscan;
++
++ /* adjust height because of startscan */
++ dibHeight += (dibHeight > 0 ? -startscan : startscan);
++
++ if(xSrc >= dibWidth)
++ {
++ ERR("xSrc out of range\n");
++ return 0;
++ }
++ if(xSrc + cx > dibWidth)
++ cx = dibWidth - xSrc;
++ if(ySrc > abs(dibHeight))
++ {
++ ERR("ySrc out of range\n");
++ return 0;
++ }
++ if(ySrc + cy > abs(dibHeight))
++ cy = abs(dibHeight) - ySrc;
++
++ ySrc -= startscan;
++ cy -= startscan;
++ if(cy <= 0)
++ {
++ ERR("Null or negative vertical size\n");
++ return 0;
++ }
++ if(ySrc < 0)
++ {
++ yDst += ySrc;
++ cy += ySrc;
++ ySrc = 0;
++ }
++ if(cy <= 0)
++ {
++ ERR("Null or negative vertical size\n");
++ return 0;
++ }
++
++ /* Creates a DIBDRVBITMAP from source dib */
++ if(!(sBmp = _DIBDRVBITMAP_CreateFromBitmapinfo(info, (LPVOID)bits)))
++ {
++ ERR("_DIBDRVBITMAP_CreateFromBitmapinfo failed\n");
++ return 0;
++ }
++
++ /* get destination physical bitmap */
++ dBmp = physDev->physBitmap;
++
++ /* now we can do the bit conversion */
++ buf = HeapAlloc(GetProcessHeap(), 0, cx * sizeof(RGBQUAD));
++ for(iLine = 0; iLine < cy; iLine++)
++ {
++ sBmp->funcs->GetLine(sBmp, ySrc++, xSrc, cx, buf);
++ dBmp->funcs->PutLine(dBmp, yDst++, xDst, cx, buf);
++ }
++ HeapFree(GetProcessHeap(), 0, buf);
++ _DIBDRVBITMAP_Free(sBmp);
++ return cy;
++ }
++ else
++ {
++ return _DIBDRV_GetDisplayDriver()->pSetDIBitsToDevice(physDev->X11PhysDev, xDst, yDst, cx, cy, xSrc, ySrc,
++ startscan, lines, bits, info, coloruse);
++ }
++}
+diff -Nru a/dlls/winedib.drv/dibdrvbitmap.c b/dlls/winedib.drv/dibdrvbitmap.c
+--- a/dlls/winedib.drv/dibdrvbitmap.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/dibdrvbitmap.c 2010-08-04 16:08:44.766222017 +0200
+@@ -0,0 +1,792 @@
++/*
++ * DIB Engine DIBDRVBITMAP handling
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/* gets human-readable dib format name */
++const char *_DIBDRVBITMAP_GetFormatName(DIBDRVBITMAP const *bmp)
++{
++ if(!bmp)
++ {
++ ERR("Null bitmap\n");
++ return "NULL BITMAP DETECTED";
++ }
++ switch(bmp->format)
++ {
++ case DIBFMT_DIB1:
++ return "DIBFMT_DIB1";
++ case DIBFMT_DIB4:
++ return "DIBFMT_DIB4";
++ case DIBFMT_DIB4_RLE:
++ return "DIBFMT_DIB4_RLE";
++ case DIBFMT_DIB8:
++ return "DIBFMT_DIB8";
++ case DIBFMT_DIB8_RLE:
++ return "DIBFMT_DIB8_RLE";
++ case DIBFMT_DIB16_RGB:
++ return "DIBFMT_DIB_RGB";
++ case DIBFMT_DIB16_BITFIELDS:
++ return "DIBFMT_DIB16_BITFIELDS";
++ case DIBFMT_DIB24:
++ return "DIBFMT_DIB24";
++ case DIBFMT_DIB32_RGB:
++ return "DIBFMT_DIB32_RGB";
++ case DIBFMT_DIB32_BITFIELDS:
++ return "DIBFMT_DIB32_BITFIELDS";
++ case DIBFMT_UNKNOWN:
++ default:
++ return "DIBFMT_UNKNOWN";
++ }
++}
++
++/* calculates shift and length given a bit mask */
++static void CalcShiftAndLen(DWORD mask, int *shift, int *len)
++{
++ int s, l;
++
++ /* FIXME----*/
++ if(mask == 0)
++ {
++ FIXME("color mask == 0 -- problem on init_dib\n");
++ *shift = 0;
++ *len = 0;
++ return;
++ }
++
++ /* calculates bit shift
++ (number of 0's on right of bit field */
++ s = 0;
++ while ((mask & 1) == 0)
++ {
++ mask >>= 1;
++ s++;
++ }
++
++ /* calculates bitfield length
++ (number of 1's in bit field */
++ l = 0;
++ while ((mask & 1) == 1)
++ {
++ mask >>= 1;
++ l++;
++ }
++ *shift = s;
++ *len = l;
++}
++
++/* initializes bit fields from bit masks */
++static void InitBitFields(DIBDRVBITMAP *dib, const DWORD *bit_fields)
++{
++ dib->redMask = bit_fields[0];
++ dib->greenMask = bit_fields[1];
++ dib->blueMask = bit_fields[2];
++ CalcShiftAndLen(dib->redMask, &dib->redShift, &dib->redLen);
++ CalcShiftAndLen(dib->greenMask, &dib->greenShift, &dib->greenLen);
++ CalcShiftAndLen(dib->blueMask, &dib->blueShift, &dib->blueLen);
++}
++
++/* sets/gets bits of a DIBDRVBITMAP taking in account if it's a top down
++ or a bottom-up DIB */
++void _DIBDRVBITMAP_Set_Bits(DIBDRVBITMAP *dib, void *bits, BOOL owns)
++{
++ /* checks whether dib is top-down or bottom-up one */
++ if(dib->stride > 0)
++ {
++ /* top-down dib */
++ dib->bits = bits;
++ }
++ else
++ {
++ /* bottom-up dib */
++ /* data->bits always points to the top-left corner and the stride is -ve */
++ dib->bits = (BYTE*)bits - (dib->height - 1) * dib->stride;
++ }
++ dib->ownsBits = owns;
++}
++
++void *_DIBDRVBITMAP_Get_Bits(DIBDRVBITMAP * dib)
++{
++ /* checks whether dib is top-down or bottom-up one */
++ if(dib->stride > 0)
++ {
++ /* top-down dib */
++ return dib->bits;
++ }
++ else
++ {
++ /* bottom-up dib */
++ /* data->bits always points to the top-left corner and the stride is -ve */
++ return (BYTE*)dib->bits + (dib->height - 1) * dib->stride;
++ }
++}
++
++/* calculates and sets the lightest color for monochrome bitmaps */
++int _DIBDRVBITMAP_GetLightestColorIndex(DIBDRVBITMAP *dib)
++{
++ DWORD foreRed, foreGreen, foreBlue;
++ DWORD backRed, backGreen, backBlue;
++ RGBQUAD *fore, *back;
++
++ /* zero for non-monochrome bitmaps */
++ if(dib->bitCount != 1)
++ return 0;
++ /* just in case color table hasn't been grabbed yet */
++ if(!dib->colorTableGrabbed)
++ return 1;
++ back = dib->colorTable;
++ fore = back + 1;
++ foreRed = fore->rgbRed; foreGreen = fore->rgbGreen; foreBlue = fore->rgbBlue;
++ backRed = back->rgbRed; backGreen = back->rgbGreen; backBlue = back->rgbBlue;
++ if(foreRed*foreRed + foreGreen*foreGreen + foreBlue*foreBlue >
++ backRed*backRed + backGreen*backGreen + backBlue*backBlue)
++ {
++ dib->lightColor = 1;
++ return 1;
++ }
++ dib->lightColor = 0;
++ return 0;
++}
++
++/* initializes dib from a bitmap :
++ dib dib being initialized
++ bi source BITMAPINFOHEADER with required DIB format info
++ bit_fields color masks
++ colorTable color table, if any
++ bits pointer to image data array
++ NOTE : DIBDRVBITMAP doesn't owns bits, but do own color table
++*/
++BOOL _DIBDRVBITMAP_InitFromBMIH(DIBDRVBITMAP *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields,
++ const RGBQUAD *colorTable, void *bits)
++{
++ MAYBE(TRACE("dib=%p, bi=%p, bit_fields=%p, colorTable=%p, bits=%p\n", dib, bi, bit_fields, colorTable, bits));
++
++ /* initializes DIB dimensions and color depth */
++ dib->bitCount = bi->biBitCount;
++ dib->width = bi->biWidth;
++ dib->height = bi->biHeight;
++ dib->stride = ((dib->width * dib->bitCount + 31) >> 3) & ~3;
++
++ /* initializes image data pointer */
++ dib->bits = bits;
++ dib->ownsBits = FALSE;
++
++ /* initializes color table */
++ dib->colorTableSize = 0;
++ dib->colorTable = NULL;
++ dib->colorTableGrabbed = FALSE;
++
++ /* checks whether dib is top-down or bottom-up one */
++ if(dib->height < 0)
++ {
++ /* top-down dib */
++ dib->height = -dib->height;
++ dib->topdown = TRUE;
++ }
++ else
++ {
++ /* bottom-up dib */
++ /* data->bits always points to the top-left corner and the stride is -ve */
++ dib->bits = (BYTE*)dib->bits + (dib->height - 1) * dib->stride;
++ dib->stride = -dib->stride;
++ dib->topdown = FALSE;
++ }
++
++ /* gets and stores bitmap format */
++ switch(dib->bitCount)
++ {
++ case 24:
++ dib->format = DIBFMT_DIB24;
++ dib->funcs = &DIBDRV_funcs_DIB24;
++ break;
++
++ case 32:
++
++ if(bi->biCompression == BI_RGB)
++ {
++ dib->format = DIBFMT_DIB32_RGB;
++ dib->funcs = &DIBDRV_funcs_DIB32_RGB;
++ }
++ else
++ {
++ InitBitFields(dib, bit_fields);
++ dib->format = DIBFMT_DIB32_BITFIELDS;
++ dib->funcs = &DIBDRV_funcs_DIB32_BITFIELDS;
++ }
++ break;
++
++ case 16:
++ if(bi->biCompression == BI_RGB)
++ {
++ dib->format = DIBFMT_DIB16_RGB;
++ dib->funcs = &DIBDRV_funcs_DIB16_RGB;
++ }
++ else
++ {
++ InitBitFields(dib, bit_fields);
++ dib->format = DIBFMT_DIB16_BITFIELDS;
++ dib->funcs = &DIBDRV_funcs_DIB16_BITFIELDS;
++ }
++ break;
++
++ case 8:
++ dib->format = DIBFMT_DIB8;
++ dib->funcs = &DIBDRV_funcs_DIB8;
++ dib->colorTableSize = 256;
++ if(bi->biClrUsed) dib->colorTableSize = bi->biClrUsed;
++ break;
++
++ case 4:
++ dib->format = DIBFMT_DIB4;
++ dib->funcs = &DIBDRV_funcs_DIB4;
++ dib->colorTableSize = 16;
++ if(bi->biClrUsed) dib->colorTableSize = bi->biClrUsed;
++ break;
++
++ case 1:
++ dib->format = DIBFMT_DIB1;
++ dib->funcs = &DIBDRV_funcs_DIB1;
++ dib->colorTableSize = 2;
++ if(bi->biClrUsed) dib->colorTableSize = bi->biClrUsed;
++ break;
++
++ default:
++ dib->format = DIBFMT_UNKNOWN;
++ dib->funcs = NULL;
++ FIXME("bpp %d not supported\n", dib->bitCount);
++ return FALSE;
++ }
++ MAYBE(TRACE("DIB FORMAT : %s\n", _DIBDRVBITMAP_GetFormatName(dib)));
++
++ /* allocates color table and copy it from source, *if* source is
++ not null */
++ if(dib->colorTableSize && colorTable)
++ {
++ if(!(dib->colorTable = HeapAlloc(GetProcessHeap(), 0,
++ dib->colorTableSize * sizeof(dib->colorTable[0]))
++ ))
++ {
++ ERR("HeapAlloc failed\n");
++ return FALSE;
++ }
++ memcpy(dib->colorTable, colorTable,
++ dib->colorTableSize * sizeof(dib->colorTable[0]));
++ dib->colorTableGrabbed = TRUE;
++
++ /* for monochrome bitmaps, we need the 'lightest' color */
++ _DIBDRVBITMAP_GetLightestColorIndex(dib);
++ }
++ else if(!dib->colorTableSize)
++ /* no color table on more than 8 bits/pixel */
++ dib->colorTableGrabbed = TRUE;
++
++ MAYBE(TRACE("END\n"));
++ return TRUE;
++}
++
++DIBDRVBITMAP *_DIBDRVBITMAP_CreateFromBMIH(const BITMAPINFOHEADER *bi, const DWORD *bit_fields,
++ const RGBQUAD *colorTable, void *bits)
++{
++ DIBDRVBITMAP *bmp = _DIBDRVBITMAP_New();
++ if(bmp && !_DIBDRVBITMAP_InitFromBMIH(bmp, bi, bit_fields, colorTable, bits))
++ {
++ _DIBDRVBITMAP_Free(bmp);
++ bmp = NULL;
++ }
++ return bmp;
++}
++
++/* gets a BITMAPINFOHEADER from a soure BITMAPINFO- or BITMAPCORE-header */
++static BITMAPINFOHEADER *GetBitmapInfoHeader(BITMAPINFO const *bmi)
++{
++ BITMAPINFOHEADER *res = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
++
++ int size = bmi->bmiHeader.biSize;
++ if(size >= sizeof(BITMAPINFOHEADER))
++ {
++ memcpy(res, bmi, sizeof(BITMAPINFOHEADER));
++ res->biSize = sizeof(BITMAPINFOHEADER);
++ }
++ else if(size == sizeof(BITMAPCOREHEADER))
++ {
++ BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)bmi;
++ res->biSize = sizeof(BITMAPINFOHEADER);
++ res->biWidth = core->bcWidth;
++ res->biHeight = core->bcHeight;
++ res->biPlanes = core->bcPlanes;
++ res->biBitCount = core->bcBitCount;
++ }
++ else
++ {
++ HeapFree(GetProcessHeap(), 0, res);
++ ERR("Bad/unknown header size %d\n", size);
++ res = NULL;
++ }
++ return res;
++}
++
++BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi, void *bits)
++{
++ static const DWORD bit_fields_DIB32_RGB[3] = {0xff0000, 0x00ff00, 0x0000ff};
++ static const DWORD bit_fields_DIB16_RGB[3] = {0x7c00, 0x03e0, 0x001f};
++ const DWORD *masks = NULL;
++ RGBQUAD *colorTable = NULL;
++ BITMAPINFOHEADER *bi;
++ BYTE *ptr;
++ int num_colors;
++ BOOL res;
++
++ /* gets info header */
++ if(!(bi = GetBitmapInfoHeader(bmi)))
++ return FALSE;
++
++ ptr = (BYTE*)bmi + bmi->bmiHeader.biSize;
++ num_colors = bi->biClrUsed;
++
++ MAYBE(TRACE("dib=%p, bmi=%p\n", dib, bmi));
++
++ if(bi->biCompression == BI_BITFIELDS)
++ {
++ masks = (DWORD *)ptr;
++ ptr += 3 * sizeof(DWORD);
++ }
++ else if(bi->biBitCount == 32)
++ masks = bit_fields_DIB32_RGB;
++ else if(bi->biBitCount == 16)
++ masks = bit_fields_DIB16_RGB;
++
++ if(!num_colors && bi->biBitCount <= 8)
++ num_colors = 1 << bi->biBitCount;
++ if(num_colors)
++ colorTable = (RGBQUAD*)ptr;
++ ptr += num_colors * sizeof(*colorTable);
++
++ res = _DIBDRVBITMAP_InitFromBMIH(dib, bi, masks, colorTable, bits ? bits : ptr);
++ HeapFree(GetProcessHeap(), 0, bi);
++ MAYBE(TRACE("END\n"));
++ return res;
++}
++
++DIBDRVBITMAP *_DIBDRVBITMAP_CreateFromBitmapinfo(const BITMAPINFO *bmi, void *bits)
++{
++ DIBDRVBITMAP *bmp = _DIBDRVBITMAP_New();
++ if(bmp && !_DIBDRVBITMAP_InitFromBitmapinfo(bmp, bmi, bits))
++ {
++ _DIBDRVBITMAP_Free(bmp);
++ bmp = NULL;
++ }
++ return bmp;
++}
++
++/* initializes a DIBRDVBITMAP copying it from a source one
++ Parameters :
++ dib destination DIBDRVBITMAP
++ src source DIBDRVBITMAP
++ copy TRUE->copy source pixel array FALSE->link to source pixel array
++*/
++BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, BOOL copy)
++{
++ MAYBE(TRACE("dib=%p, src=%p, copy=%d\n", dib, src, copy));
++
++ dib->format = src->format;
++ dib->width = src->width;
++ dib->height = src->height;
++ dib->stride = src->stride;
++ dib->bitCount = src->bitCount;
++
++ dib->redMask = src->redMask;
++ dib->greenMask = src->greenMask;
++ dib->blueMask = src->blueMask;
++ dib->redShift = src->redShift;
++ dib->greenShift = src->greenShift;
++ dib->blueShift = src->blueShift;
++ dib->redLen = src->redLen;
++ dib->greenLen = src->greenLen;
++ dib->blueLen = src->blueLen;
++
++ dib->funcs = src->funcs;
++
++ dib->lightColor = src->lightColor;
++
++ dib->topdown = src->topdown;
++
++ if(copy)
++ {
++ int size = dib->height*abs(dib->stride);
++ if(!(dib->bits = HeapAlloc(GetProcessHeap(), 0, size)))
++ {
++ ERR("Failed to allocate bits buffer\n");
++ return FALSE;
++ }
++ dib->ownsBits = TRUE;
++
++ /* check for bottom-up DIB */
++ if(dib->stride < 0)
++ {
++ /* copy the bitmap array */
++ memcpy(dib->bits, (BYTE *)src->bits + (src->height - 1) * src->stride, size);
++
++ dib->bits = (BYTE *)dib->bits - (dib->height-1) * dib->stride;
++ }
++ else
++ {
++ /* copy the bitmap array */
++ memcpy(dib->bits, src->bits, size);
++ }
++ }
++ else
++ {
++ dib->bits = src->bits;
++ dib->ownsBits = FALSE;
++ }
++
++ if(src->colorTable)
++ {
++ dib->colorTable = HeapAlloc(GetProcessHeap(), 0, src->colorTableSize * sizeof(src->colorTable[0]));
++ memcpy(dib->colorTable, src->colorTable, src->colorTableSize * sizeof(src->colorTable[0]));
++ }
++ else
++ dib->colorTable = NULL;
++ dib->colorTableSize = src->colorTableSize;
++ dib->colorTableGrabbed = TRUE;
++ MAYBE(TRACE("END\n"));
++ return TRUE;
++}
++
++
++/* creates a DIBRDVBITMAP copying format info from a source one
++ Parameters :
++ dib destination DIBDRVBITMAP
++ src source DIBDRVBITMAP
++ widht, height sizes of newly created bitmap
++*/
++BOOL _DIBDRVBITMAP_CreateFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, int width, int height)
++{
++ MAYBE(TRACE("dib=%p, src=%p, width=%d, height=%d\n", dib, src, width, height));
++
++ /* grab color and format info from source DIB */
++ if(!_DIBDRVBITMAP_InitFromDibdrvbitmap(dib, src, FALSE))
++ {
++ ERR("Failed grabbing source dib format\n");
++ return FALSE;
++ }
++
++ /* sets up new DIB dimensions */
++ dib->width = width;
++ dib->height = height;
++
++ /* calculates new stride basing of new width */
++ dib->stride = ((width * dib->bitCount +31) &~31) / 8;
++ if(src->stride < 0)
++ dib->stride = -dib->stride;
++ dib->topdown = src->topdown;
++
++ /* allocates bits for newly created DIB */
++ if(!(dib->bits = HeapAlloc(GetProcessHeap(), 0, height*abs(dib->stride))))
++ {
++ ERR("Failed to allocate bits buffer\n");
++ return FALSE;
++ }
++ /* check for bottom-up DIB */
++ if(dib->stride < 0)
++ dib->bits = (BYTE *)dib->bits - (dib->height-1) * dib->stride;
++ dib->ownsBits = TRUE;
++
++ MAYBE(TRACE("END\n"));
++ return TRUE;
++ }
++
++/* Clears a DIBDRVBITMAP structure data
++ WARNING : doesn't free anything */
++void _DIBDRVBITMAP_Clear(DIBDRVBITMAP *bmp)
++{
++ MAYBE(TRACE("bmp=%p\n", bmp));
++
++ if(!bmp)
++ return;
++ bmp->bits = NULL;
++ bmp->ownsBits = FALSE;
++ bmp->colorTable = NULL;
++ bmp->colorTableSize = 0;
++ bmp->colorTableGrabbed = FALSE;
++
++ MAYBE(TRACE("END\n"));
++}
++
++/* allocates a new DIBDTVBITMAP */
++DIBDRVBITMAP *_DIBDRVBITMAP_New(void)
++{
++ DIBDRVBITMAP *bmp = HeapAlloc(GetProcessHeap(), 0, sizeof(DIBDRVBITMAP));
++ if(!bmp)
++ return NULL;
++ _DIBDRVBITMAP_Clear(bmp);
++ return bmp;
++}
++
++/* Frees a DIBDRVBITMAP structure data */
++void _DIBDRVBITMAP_Free(DIBDRVBITMAP *bmp)
++{
++ MAYBE(TRACE("bmp=%p\n", bmp));
++
++ if(!bmp)
++ return;
++ /* frees bits, if needed */
++ if(bmp->bits && bmp->ownsBits)
++ {
++ /* on bottom-up dibs, bits doesn't point to starting
++ of buffer.... bad design choice */
++ if(bmp->stride < 0)
++ bmp->bits = (BYTE *)bmp->bits + bmp->stride * (bmp->height -1);
++ HeapFree(GetProcessHeap(), 0, bmp->bits);
++ }
++ /* frees color table */
++ if(bmp->colorTable)
++ HeapFree(GetProcessHeap(), 0, bmp->colorTable);
++
++ HeapFree(GetProcessHeap(), 0, bmp);
++
++}
++
++
++/* checks whether the format of 2 DIBs are identical
++ it checks the pixel bit count and the color table size
++ and content, if needed */
++BOOL _DIBDRVBITMAP_FormatMatch(const DIBDRVBITMAP *d1, const DIBDRVBITMAP *d2)
++{
++ /* checks at first the format (bit count and color masks) */
++ if(d1->format != d2->format)
++ return FALSE;
++
++ /* formats matches, now checks color tables if needed */
++ switch(d1->format)
++ {
++ case DIBFMT_DIB32_RGB :
++ case DIBFMT_DIB32_BITFIELDS :
++ case DIBFMT_DIB24 :
++ case DIBFMT_DIB16_RGB :
++ case DIBFMT_DIB16_BITFIELDS :
++ return TRUE;
++
++ case DIBFMT_DIB1 :
++ case DIBFMT_DIB4 :
++ /*case DIBFMT_DIB4_RLE :*/
++ case DIBFMT_DIB8 :
++ /*case DIBFMT_DIB8_RLE :*/
++ if(d1->colorTableSize != d2->colorTableSize)
++ return FALSE;
++ return !memcmp(d1->colorTable, d2->colorTable, d1->colorTableSize * sizeof(d1->colorTable[0]));
++
++ default:
++ ERR("Unexpected depth %d\n", d1->bitCount);
++ return FALSE;
++ }
++}
++
++/* convert a given dib into another format given by 'format' parameter */
++BOOL _DIBDRVBITMAP_Convert(DIBDRVBITMAP *dst, const DIBDRVBITMAP *src, const DIBDRVBITMAP *format)
++{
++ int width, height;
++ int iLine;
++ void *buf;
++ BOOL res;
++
++ MAYBE(TRACE("dst=%p, src=%p, format=%p\n", dst, src, format));
++
++ /* free, if needed, destination bitmap */
++ _DIBDRVBITMAP_Free(dst);
++
++ /* if format and source bitmaps format match,
++ just copy source on destination */
++ if(_DIBDRVBITMAP_FormatMatch(src, format))
++ {
++ res = _DIBDRVBITMAP_InitFromDibdrvbitmap(dst, src, TRUE);
++ MAYBE(TRACE("END - Identical formats\n"));
++ return res;
++ }
++
++ /* formats don't match, we create the dest bitmap with same format as format's one
++ but with source's one dimensions */
++ width = src->width;
++ height = src->height;
++ if(!_DIBDRVBITMAP_CreateFromDibdrvbitmap(dst, format, width, height))
++ {
++ ERR("Couldn't create destination bmp\n");
++ return FALSE;
++ }
++
++ /* we now copy/convert from source to dest */
++ if(!(buf = HeapAlloc(GetProcessHeap(), 0, width * 4)))
++ {
++ ERR("HeapAlloc failed\n");
++ return FALSE;
++ }
++
++ for(iLine = 0; iLine < height; iLine++)
++ {
++ src->funcs->GetLine(src, iLine, 0, width, buf);
++ dst->funcs->PutLine(dst, iLine, 0, width, buf);
++ }
++ HeapFree(GetProcessHeap(), 0, buf);
++
++ MAYBE(TRACE("END - different formats\n"));
++ return TRUE;
++}
++
++/* creates a solid-filled DIB of given color and format
++ DIB format is given by 'format' parameter */
++BOOL _DIBDRVBITMAP_CreateSolid(DIBDRVBITMAP *bmp, DIBDRVBITMAP *format, int width, int height, DWORD Color)
++{
++ DWORD *buf, *bufPnt;
++ int i;
++
++ MAYBE(TRACE("bmp=%p, format=%p, width=%d, height=%d, Color=%08x\n", bmp, format, width, height, Color));
++
++ /* swaps color bytes....*/
++ Color = RGB((Color >> 8) & 0xff, (Color >> 16) &0xff, Color &0xff);
++
++ /* creates the destination bitmap */
++ if(!_DIBDRVBITMAP_CreateFromDibdrvbitmap(bmp, format, width, height))
++ {
++ ERR("Couldn't create destination bmp\n");
++ return FALSE;
++ }
++
++ /* creates a temporary line filled with given color */
++ if(!(buf = HeapAlloc(GetProcessHeap(), 0, width * 4)))
++ {
++ ERR("HeapAlloc failed\n");
++ return FALSE;
++ }
++
++ for(i = 0, bufPnt = buf; i < width; i++)
++ *bufPnt++ = Color;
++
++ /* fills the bitmap */
++ for(i = 0; i < height; i++)
++ bmp->funcs->PutLine(bmp, i, 0, width, buf);
++
++ /* frees temporaty line */
++ HeapFree(GetProcessHeap(), 0, buf);
++
++ MAYBE(TRACE("END\n"));
++ return TRUE;
++}
++
++/* expands horizontally a bitmap to reach a minimum size,
++ keeping its width as a multiple of a base width
++ Used to widen brushes in order to optimize blitting */
++BOOL _DIBDRVBITMAP_ExpandHoriz(DIBDRVBITMAP *dib, int baseWidth, int minWidth)
++{
++ BYTE *srcBuf, *dstBuf;
++ int chunkSize;
++ int iLine, iCol;
++ DIBDRVBITMAP tmpDib;
++ void *bits;
++ BOOL ownsBits;
++
++ MAYBE(TRACE("dib=%p, baseWidth=%d, minWidth=%d\n", dib, baseWidth, minWidth));
++
++ /* if dst dib already wide enough, just do nothing */
++ if(dib->width >= minWidth)
++ {
++ MAYBE(TRACE("END - No need to expand\n"));
++ return TRUE;
++ }
++
++ /* source DIB can't be NULL */
++ if(!dib->bits)
++ {
++ ERR("Empty source DIB detected\n");
++ return FALSE;
++ }
++
++ /* round up minWidth to be a multiple of source width */
++ minWidth += (baseWidth - (minWidth % baseWidth));
++
++ /* creates a temporary destination bitmap with required sizes */
++ _DIBDRVBITMAP_Clear(&tmpDib);
++ if(!_DIBDRVBITMAP_CreateFromDibdrvbitmap(&tmpDib, dib, minWidth, dib->height))
++ {
++ ERR("Couldn't create the temporary DIB for brush cache\n");
++ return FALSE;
++ }
++
++ /* if format uses almost 1 byte/pixel, fast copy path */
++ if(dib->bitCount >= 8)
++ {
++ chunkSize = dib->width * dib->bitCount / 8;
++ for(iLine = 0; iLine < dib->height; iLine++)
++ {
++ srcBuf = (BYTE *)dib->bits + iLine * dib->stride;
++ dstBuf = (BYTE *)tmpDib.bits + iLine * tmpDib.stride;
++ for(iCol = 0; iCol < tmpDib.width; iCol += dib->width)
++ {
++ memcpy(dstBuf, srcBuf, chunkSize);
++ dstBuf += chunkSize;
++ }
++ }
++ }
++ /* otherwise slow path -- could be optimized */
++ else
++ {
++ chunkSize = dib->width * 4;
++ /* allocates a line buffer */
++ if(!(srcBuf = HeapAlloc(GetProcessHeap(), 0, tmpDib.width * 4)))
++ {
++ ERR("HeapAlloc failed\n");
++ return FALSE;
++ }
++
++ FIXME("dib:format=%s, funcs=%p, bits=%p, width=%d, height=%d, stride=%d\n",
++ _DIBDRVBITMAP_GetFormatName(dib), dib->funcs, dib->bits, dib->width, dib->height, dib->stride);
++ for(iLine = 0; iLine < dib->height; iLine++)
++ {
++ /* fills the line buffer repeating source's line data */
++ dib->funcs->GetLine(dib, iLine, 0, dib->width, srcBuf);
++ dstBuf = srcBuf + chunkSize;
++ for(iCol = dib->width; iCol < tmpDib.width; iCol += dib->width)
++ {
++ memcpy(dstBuf, srcBuf, chunkSize);
++ dstBuf += chunkSize;
++ }
++ /* stores the line on destination bmp */
++ tmpDib.funcs->PutLine(&tmpDib, iLine, 0, tmpDib.width, srcBuf);
++ }
++ HeapFree(GetProcessHeap(), 0, srcBuf);
++ }
++
++ /* swaps temp DIB and source one */
++ bits = dib->bits;
++ ownsBits = dib->ownsBits;
++ dib->bits = tmpDib.bits;
++ dib->ownsBits = tmpDib.ownsBits;
++ tmpDib.bits = bits;
++ tmpDib.ownsBits = ownsBits;
++
++ /* frees the temporary DIB */
++ _DIBDRVBITMAP_Free(&tmpDib);
++
++ MAYBE(TRACE("END\n"));
++ return TRUE;
++}
+diff -Nru a/dlls/winedib.drv/dibdrv_gdi32.h b/dlls/winedib.drv/dibdrv_gdi32.h
+--- a/dlls/winedib.drv/dibdrv_gdi32.h 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/dibdrv_gdi32.h 2010-08-04 16:08:44.756222017 +0200
+@@ -0,0 +1,168 @@
++/*
++ * GDI structures - grabbed from dlls/gdi32/gdi_private.h
++ * Those are needed to access some opaque gdi32 pointers
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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_DIBDRV_GDI32_H
++#define __WINE_DIBDRV_GDI32_H
++
++
++/* driver function pointers - used here to forward calls to X11 driver when needed */
++typedef struct { int opaque; } *PHYSDEV; /* PHYSDEV is an opaque pointer */
++typedef struct tagDC_FUNCS
++{
++ INT (CDECL *pAbortDoc)(PHYSDEV);
++ BOOL (CDECL *pAbortPath)(PHYSDEV);
++ BOOL (CDECL *pAlphaBlend)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,INT,INT,BLENDFUNCTION);
++ BOOL (CDECL *pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT);
++ BOOL (CDECL *pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
++ BOOL (CDECL *pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
++ BOOL (CDECL *pBeginPath)(PHYSDEV);
++ BOOL (CDECL *pBitBlt)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,DWORD);
++ INT (CDECL *pChoosePixelFormat)(PHYSDEV,const PIXELFORMATDESCRIPTOR *);
++ BOOL (CDECL *pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
++ BOOL (CDECL *pCloseFigure)(PHYSDEV);
++ BOOL (CDECL *pCreateBitmap)(PHYSDEV,HBITMAP,LPVOID);
++ BOOL (CDECL *pCreateDC)(HDC,PHYSDEV *,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*);
++ HBITMAP (CDECL *pCreateDIBSection)(PHYSDEV,HBITMAP,const BITMAPINFO *,UINT);
++ BOOL (CDECL *pDeleteBitmap)(HBITMAP);
++ BOOL (CDECL *pDeleteDC)(PHYSDEV);
++ BOOL (CDECL *pDeleteObject)(PHYSDEV,HGDIOBJ);
++ INT (CDECL *pDescribePixelFormat)(PHYSDEV,INT,UINT,PIXELFORMATDESCRIPTOR *);
++ DWORD (CDECL *pDeviceCapabilities)(LPSTR,LPCSTR,LPCSTR,WORD,LPSTR,LPDEVMODEA);
++ BOOL (CDECL *pEllipse)(PHYSDEV,INT,INT,INT,INT);
++ INT (CDECL *pEndDoc)(PHYSDEV);
++ INT (CDECL *pEndPage)(PHYSDEV);
++ BOOL (CDECL *pEndPath)(PHYSDEV);
++ BOOL (CDECL *pEnumDeviceFonts)(PHYSDEV,LPLOGFONTW,FONTENUMPROCW,LPARAM);
++ INT (CDECL *pExcludeClipRect)(PHYSDEV,INT,INT,INT,INT);
++ INT (CDECL *pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,DWORD);
++ INT (CDECL *pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID);
++ BOOL (CDECL *pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT);
++ INT (CDECL *pExtSelectClipRgn)(PHYSDEV,HRGN,INT);
++ BOOL (CDECL *pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
++ BOOL (CDECL *pFillPath)(PHYSDEV);
++ BOOL (CDECL *pFillRgn)(PHYSDEV,HRGN,HBRUSH);
++ BOOL (CDECL *pFlattenPath)(PHYSDEV);
++ BOOL (CDECL *pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT);
++ BOOL (CDECL *pGdiComment)(PHYSDEV,UINT,CONST BYTE*);
++ LONG (CDECL *pGetBitmapBits)(HBITMAP,void*,LONG);
++ BOOL (CDECL *pGetCharWidth)(PHYSDEV,UINT,UINT,LPINT);
++ BOOL (CDECL *pGetDCOrgEx)(PHYSDEV,LPPOINT);
++ UINT (CDECL *pGetDIBColorTable)(PHYSDEV,UINT,UINT,RGBQUAD*);
++ INT (CDECL *pGetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPVOID,BITMAPINFO*,UINT);
++ INT (CDECL *pGetDeviceCaps)(PHYSDEV,INT);
++ BOOL (CDECL *pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
++ BOOL (CDECL *pGetICMProfile)(PHYSDEV,LPDWORD,LPWSTR);
++ COLORREF (CDECL *pGetNearestColor)(PHYSDEV,COLORREF);
++ COLORREF (CDECL *pGetPixel)(PHYSDEV,INT,INT);
++ INT (CDECL *pGetPixelFormat)(PHYSDEV);
++ UINT (CDECL *pGetSystemPaletteEntries)(PHYSDEV,UINT,UINT,LPPALETTEENTRY);
++ BOOL (CDECL *pGetTextExtentExPoint)(PHYSDEV,LPCWSTR,INT,INT,LPINT,LPINT,LPSIZE);
++ BOOL (CDECL *CDECL pGetTextMetrics)(PHYSDEV,TEXTMETRICW*);
++ INT (CDECL *pIntersectClipRect)(PHYSDEV,INT,INT,INT,INT);
++ BOOL (CDECL *pInvertRgn)(PHYSDEV,HRGN);
++ BOOL (CDECL *pLineTo)(PHYSDEV,INT,INT);
++ BOOL (CDECL *pModifyWorldTransform)(PHYSDEV,const XFORM*,INT);
++ BOOL (CDECL *pMoveTo)(PHYSDEV,INT,INT);
++ INT (CDECL *pOffsetClipRgn)(PHYSDEV,INT,INT);
++ INT (CDECL *pOffsetViewportOrg)(PHYSDEV,INT,INT);
++ INT (CDECL *pOffsetWindowOrg)(PHYSDEV,INT,INT);
++ BOOL (CDECL *pPaintRgn)(PHYSDEV,HRGN);
++ BOOL (CDECL *pPatBlt)(PHYSDEV,INT,INT,INT,INT,DWORD);
++ BOOL (CDECL *pPie)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
++ BOOL (CDECL *pPolyBezier)(PHYSDEV,const POINT*,DWORD);
++ BOOL (CDECL *pPolyBezierTo)(PHYSDEV,const POINT*,DWORD);
++ BOOL (CDECL *pPolyDraw)(PHYSDEV,const POINT*,const BYTE *,DWORD);
++ BOOL (CDECL *pPolyPolygon)(PHYSDEV,const POINT*,const INT*,UINT);
++ BOOL (CDECL *pPolyPolyline)(PHYSDEV,const POINT*,const DWORD*,DWORD);
++ BOOL (CDECL *pPolygon)(PHYSDEV,const POINT*,INT);
++ BOOL (CDECL *pPolyline)(PHYSDEV,const POINT*,INT);
++ BOOL (CDECL *pPolylineTo)(PHYSDEV,const POINT*,INT);
++ UINT (CDECL *pRealizeDefaultPalette)(PHYSDEV);
++ UINT (CDECL *pRealizePalette)(PHYSDEV,HPALETTE,BOOL);
++ BOOL (CDECL *pRectangle)(PHYSDEV,INT,INT,INT,INT);
++ HDC (CDECL *pResetDC)(PHYSDEV,const DEVMODEW*);
++ BOOL (CDECL *pRestoreDC)(PHYSDEV,INT);
++ BOOL (CDECL *pRoundRect)(PHYSDEV,INT,INT,INT,INT,INT,INT);
++ INT (CDECL *pSaveDC)(PHYSDEV);
++ INT (CDECL *pScaleViewportExt)(PHYSDEV,INT,INT,INT,INT);
++ INT (CDECL *pScaleWindowExt)(PHYSDEV,INT,INT,INT,INT);
++ HBITMAP (CDECL *pSelectBitmap)(PHYSDEV,HBITMAP);
++ HBRUSH (CDECL *pSelectBrush)(PHYSDEV,HBRUSH);
++ BOOL (CDECL *pSelectClipPath)(PHYSDEV,INT);
++ HFONT (CDECL *pSelectFont)(PHYSDEV,HFONT,HANDLE);
++ HPALETTE (CDECL *pSelectPalette)(PHYSDEV,HPALETTE,BOOL);
++ HPEN (CDECL *pSelectPen)(PHYSDEV,HPEN);
++ INT (CDECL *pSetArcDirection)(PHYSDEV,INT);
++ LONG (CDECL *pSetBitmapBits)(HBITMAP,const void*,LONG);
++ COLORREF (CDECL *pSetBkColor)(PHYSDEV,COLORREF);
++ INT (CDECL *pSetBkMode)(PHYSDEV,INT);
++ COLORREF (CDECL *pSetDCBrushColor)(PHYSDEV, COLORREF);
++ DWORD (CDECL *pSetDCOrg)(PHYSDEV,INT,INT);
++ COLORREF (CDECL *pSetDCPenColor)(PHYSDEV, COLORREF);
++ UINT (CDECL *pSetDIBColorTable)(PHYSDEV,UINT,UINT,const RGBQUAD*);
++ INT (CDECL *pSetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPCVOID,const BITMAPINFO*,UINT);
++ INT (CDECL *pSetDIBitsToDevice)(PHYSDEV,INT,INT,DWORD,DWORD,INT,INT,UINT,UINT,LPCVOID,
++ const BITMAPINFO*,UINT);
++ VOID (CDECL *pSetDeviceClipping)(PHYSDEV,HRGN,HRGN);
++ BOOL (CDECL *pSetDeviceGammaRamp)(PHYSDEV,LPVOID);
++ INT (CDECL *pSetMapMode)(PHYSDEV,INT);
++ DWORD (CDECL *pSetMapperFlags)(PHYSDEV,DWORD);
++ COLORREF (CDECL *pSetPixel)(PHYSDEV,INT,INT,COLORREF);
++ BOOL (CDECL *pSetPixelFormat)(PHYSDEV,INT,const PIXELFORMATDESCRIPTOR *);
++ INT (CDECL *pSetPolyFillMode)(PHYSDEV,INT);
++ INT (CDECL *pSetROP2)(PHYSDEV,INT);
++ INT (CDECL *pSetRelAbs)(PHYSDEV,INT);
++ INT (CDECL *pSetStretchBltMode)(PHYSDEV,INT);
++ UINT (CDECL *pSetTextAlign)(PHYSDEV,UINT);
++ INT (CDECL *pSetTextCharacterExtra)(PHYSDEV,INT);
++ DWORD (CDECL *pSetTextColor)(PHYSDEV,DWORD);
++ INT (CDECL *pSetTextJustification)(PHYSDEV,INT,INT);
++ INT (CDECL *pSetViewportExt)(PHYSDEV,INT,INT);
++ INT (CDECL *pSetViewportOrg)(PHYSDEV,INT,INT);
++ INT (CDECL *pSetWindowExt)(PHYSDEV,INT,INT);
++ INT (CDECL *pSetWindowOrg)(PHYSDEV,INT,INT);
++ BOOL (CDECL *pSetWorldTransform)(PHYSDEV,const XFORM*);
++ INT (CDECL *pStartDoc)(PHYSDEV,const DOCINFOW*);
++ INT (CDECL *pStartPage)(PHYSDEV);
++ BOOL (CDECL *pStretchBlt)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,INT,INT,DWORD);
++ INT (CDECL *pStretchDIBits)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT,const void *,
++ const BITMAPINFO*,UINT,DWORD);
++ BOOL (CDECL *pStrokeAndFillPath)(PHYSDEV);
++ BOOL (CDECL *pStrokePath)(PHYSDEV);
++ BOOL (CDECL *pSwapBuffers)(PHYSDEV);
++ BOOL (CDECL *pUnrealizePalette)(HPALETTE);
++ BOOL (CDECL *pWidenPath)(PHYSDEV);
++
++ /* OpenGL32 */
++ BOOL (CDECL *pwglCopyContext)(HGLRC, HGLRC, UINT);
++ HGLRC (CDECL *pwglCreateContext)(PHYSDEV);
++ BOOL (CDECL *pwglDeleteContext)(HGLRC);
++ PROC (CDECL *pwglGetProcAddress)(LPCSTR);
++ HDC (CDECL *pwglGetPbufferDCARB)(PHYSDEV, void*);
++ BOOL (CDECL *pwglMakeCurrent)(PHYSDEV, HGLRC);
++ BOOL (CDECL *pwglMakeContextCurrentARB)(PHYSDEV, PHYSDEV, HGLRC);
++ BOOL (CDECL *pwglSetPixelFormatWINE)(PHYSDEV,INT,const PIXELFORMATDESCRIPTOR *);
++ BOOL (CDECL *pwglShareLists)(HGLRC hglrc1, HGLRC hglrc2);
++ BOOL (CDECL *pwglUseFontBitmapsA)(PHYSDEV, DWORD, DWORD, DWORD);
++ BOOL (CDECL *pwglUseFontBitmapsW)(PHYSDEV, DWORD, DWORD, DWORD);
++} DC_FUNCTIONS;
++
++#endif
+diff -Nru a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h
+--- a/dlls/winedib.drv/dibdrv.h 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/dibdrv.h 2010-08-04 16:08:44.765222017 +0200
+@@ -0,0 +1,475 @@
++/*
++ * DIB driver private definitions
++ *
++ * Copyright 2009 Massimo Del Fedele
++ * 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_DIBDRV_H
++#define __WINE_DIBDRV_H
++
++#include <stdarg.h>
++#include <stdlib.h>
++#include <X11/Xlib.h>
++
++#include "windef.h"
++#include "winbase.h"
++#include "winerror.h"
++#include "wingdi.h"
++#include "wine/list.h"
++#include "wine/library.h"
++#include "wine/debug.h"
++#include "wingdi.h"
++#include "winreg.h"
++
++#include "freetype.h"
++
++/* data structures needed to access opaque pointers
++ * defined in gdi32.h */
++#include "dibdrv_gdi32.h"
++
++/* enable this if you want debugging (i.e. TRACEs) output */
++#define DIBDRV_ENABLE_MAYBE
++
++/* enable this if you want antialiased fonts */
++#define DIBDRV_ANTIALIASED_FONTS
++
++/* provide a way to make debugging output appear
++ only once. Usage example:
++ ONCE(FIXME("Some message\n")); */
++#define ONCE(x) \
++{ \
++ static BOOL done = FALSE; \
++ if(!done) \
++ { \
++ done = TRUE; \
++ x; \
++ } \
++}
++
++/* provide a way to make debugging output appear
++ only if enabled here. Can speed up stuffs
++ avoiding long traces.Usage example:
++ MAYBE(TRACE("Some message\n")); */
++#ifdef DIBDRV_ENABLE_MAYBE
++#define MAYBE(x) x
++#else
++#define MAYBE(x)
++#endif
++
++
++/* extra stock object: default 1x1 bitmap for memory DCs
++ grabbed from gdi_private.h */
++#define DEFAULT_BITMAP (STOCK_LAST+1)
++
++struct _DIBDRVBITMAP;
++struct _DIBDRVPHYSDEV;
++typedef struct _DIBDRV_PRIMITIVE_FUNCS
++{
++ /* color to pixel data conversion */
++ DWORD (* ColorToPixel) (const struct _DIBDRVBITMAP *bmp, COLORREF color);
++
++ /* pixel primitives */
++ void* (* GetPixelPointer) (const struct _DIBDRVBITMAP *bmp, int x, int y);
++ void (* SetPixel) ( struct _DIBDRVBITMAP *bmp, int x, int y, DWORD and, DWORD xor);
++ DWORD (* GetPixel) (const struct _DIBDRVBITMAP *bmp, int x, int y);
++
++ /* line drawing primitives */
++ void (* SolidHLine) ( struct _DIBDRVBITMAP *bmp, int x1, int x2, int y, DWORD and, DWORD xor);
++ void (* PatternHLine) ( struct _DIBDRVBITMAP *bmp, int x1, int x2, int y, const void *and, const void *xor, DWORD offset, DWORD count);
++ void (* SolidVLine) ( struct _DIBDRVBITMAP *bmp, int x, int y1, int y2, DWORD and, DWORD xor);
++
++ /* bitmap conversion helpers */
++ BOOL (* GetLine) (const struct _DIBDRVBITMAP *bmp, int line, int startx, int width, void *buf);
++ BOOL (* PutLine) ( struct _DIBDRVBITMAP *bmp, int line, int startx, int width, void *buf);
++
++ /* BitBlt primitives */
++ BOOL (* AlphaBlend) ( struct _DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, int widthDst, int heightDst,
++ const struct _DIBDRVPHYSDEV *physDevSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFn );
++ BOOL (* BitBlt) ( struct _DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, int width, int height,
++ const struct _DIBDRVPHYSDEV *physDevSrc, int xSrc, int ySrc, DWORD rop );
++ BOOL (* StretchBlt) ( struct _DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, int widthDst, int heightDst,
++ const struct _DIBDRVPHYSDEV *physDevSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, DWORD rop );
++
++ /* font drawing helper */
++ void (* FreetypeBlit) ( struct _DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
++
++} DIBDRV_PRIMITIVE_FUNCS;
++
++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_RGB;
++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_BITFIELDS;
++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB24;
++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_RGB;
++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_BITFIELDS;
++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB8;
++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB4;
++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB1;
++
++/* DIB bitmaps formats */
++typedef enum _DIBFORMAT
++{
++ DIBFMT_UNKNOWN = 0,
++ DIBFMT_DIB1 = 1,
++ DIBFMT_DIB4 = 2,
++ DIBFMT_DIB4_RLE = 3,
++ DIBFMT_DIB8 = 4,
++ DIBFMT_DIB8_RLE = 5,
++ DIBFMT_DIB16_RGB = 6,
++ DIBFMT_DIB16_BITFIELDS = 7,
++ DIBFMT_DIB24 = 8,
++ DIBFMT_DIB32_RGB = 9,
++ DIBFMT_DIB32_BITFIELDS = 10
++} DIBFORMAT;
++
++/* DIB driver's generic bitmap structure */
++typedef struct _DIBDRVBITMAP
++{
++ /* bitmap format of dib */
++ DIBFORMAT format;
++
++ /* topdown flag */
++ BOOL topdown;
++
++ /* pointer to top left corner of bitmap */
++ void *bits;
++
++ /* flags indicating if bits array is owned
++ by the bitmap */
++ BOOL ownsBits;
++
++ /* bitmap dimensions */
++ int width;
++ int height;
++
++ /* bitmap stride (== width in bytes) of a bitmap line */
++ /* negative for a bottom-up bitmap */
++ int stride;
++
++ /* number of bits/pixel in bitmap */
++ int bitCount;
++
++ /* calculated numbers for bitfields */
++
++ /* bitfields masks */
++ DWORD redMask, greenMask, blueMask;
++ /* shifting required within a COLORREF's BYTE */
++ int redShift, greenShift, blueShift;
++ /* size of the fields */
++ int redLen, greenLen, blueLen;
++
++ /* color table and its size */
++ RGBQUAD *colorTable;
++ DWORD colorTableSize;
++
++ /* lightest color index, for monochrome bitmaps */
++ int lightColor;
++
++ /* flag indicating that color table has been grabbed */
++ BOOL colorTableGrabbed;
++
++ /* primitive function pointers */
++ DIBDRV_PRIMITIVE_FUNCS *funcs;
++
++} DIBDRVBITMAP;
++
++/* dash patterns */
++typedef struct _DASHPATTERN
++{
++ DWORD count;
++ DWORD dashes[6];
++
++} DASHPATTERN;
++
++/* DIB driver physical device */
++typedef struct _DIBDRVPHYSDEV
++{
++ /* X11 driver physical device */
++ PHYSDEV X11PhysDev;
++
++ /* HDC associated with physDev */
++ HDC hdc;
++
++ /* is a DIB selected into DC ? */
++ BOOL hasDIB;
++
++ /* currently selected HBITMAP */
++ HBITMAP hbitmap;
++
++ /* physical bitmap */
++ DIBDRVBITMAP *physBitmap;
++
++ /* active ROP2 */
++ INT rop2;
++
++ /* clipping region and its rectangles */
++ HRGN region;
++ RGNDATA *regionData;
++ RECT *regionRects;
++ int regionRectCount;
++
++ /* background color and active ROP2 precalculated
++ AND and XOR values for it */
++ COLORREF backgroundColor;
++ DWORD backgroundAnd, backgroundXor;
++
++ /* pen color and active ROP2 precalculated
++ AND and XOR values for it */
++ COLORREF penColorref;
++ DWORD penColor;
++ DWORD penAnd, penXor;
++ const DASHPATTERN *penPattern;
++ DWORD curDash, leftInDash;
++ enum MARKSPACE { mark, space } markSpace;
++
++ /* pen style */
++ UINT penStyle;
++
++ /* pen drawing functions */
++ void (* penHLine) (struct _DIBDRVPHYSDEV *physDev, int x1, int x2, int y);
++ void (* penVLine) (struct _DIBDRVPHYSDEV *physDev, int x, int y1, int y2);
++ void (* penLine) (struct _DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2);
++ void (* brushHLine)(struct _DIBDRVPHYSDEV *physDev, int x1, int x2, int y);
++
++ /* brush color and active ROP2 precalculated
++ AND and XOR values for it */
++ COLORREF brushColorref;
++ DWORD brushColor;
++ DWORD brushAnd, brushXor;
++ DWORD *brushAnds, *brushXors;
++
++ /* brush style */
++ UINT brushStyle;
++
++ /* brush bitmap, if needed, and its converted/resized cache copy */
++ BOOL isBrushBitmap;
++ DIBDRVBITMAP *brushBitmap;
++ DIBDRVBITMAP *brushBmpCache;
++
++ /* text color */
++ COLORREF textColor;
++ COLORREF textBackground;
++
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ /* text color table for antialiased fonts */
++ COLORREF textColorTable[256];
++#endif
++
++ /* freetype face associated to current DC HFONT */
++ FT_Face face;
++
++} DIBDRVPHYSDEV;
++
++
++/* *********************************************************************
++ * DISPLAY DRIVER ACCESS FUNCTIONS
++ * ********************************************************************/
++
++/* LoadDisplayDriver
++ * Loads display driver - partially grabbed from gdi32 */
++DC_FUNCTIONS *_DIBDRV_LoadDisplayDriver(void);
++
++/* FreeDisplayDriver
++ Frees resources allocated by Display driver */
++void _DIBDRV_FreeDisplayDriver(void);
++
++/* GetDisplayDriver
++ Gets a pointer to display drives'function table */
++inline DC_FUNCTIONS *_DIBDRV_GetDisplayDriver(void);
++
++/* *********************************************************************
++ * ROP2 AND OTHER DRAWING RELATED FUNCTIONS
++ * ********************************************************************/
++
++void _DIBDRV_CalcAndXorMasks(INT rop, DWORD color, DWORD *and, DWORD *xor);
++
++inline void _DIBDRV_rop32(DWORD *ptr, DWORD and, DWORD xor);
++inline void _DIBDRV_rop16(WORD *ptr, WORD and, WORD xor);
++inline void _DIBDRV_rop8(BYTE *ptr, BYTE and, BYTE xor);
++
++void _DIBDRV_ResetDashOrigin(DIBDRVPHYSDEV *physDev);
++
++/* *********************************************************************
++ * ROP2 FUNCTIONS
++ * ********************************************************************/
++
++/* the ROP3 operations
++ this is a BIG case block; beware that some
++ commons ROP3 operations will be optimized
++ from inside blt routines */
++DWORD _DIBDRV_ROP3(DWORD p, DWORD s, DWORD d, BYTE rop);
++
++/* *********************************************************************
++ * PHYSICAL BITMAP FUNCTIONS
++ * ********************************************************************/
++
++/* gets human-readable dib format name */
++const char *_DIBDRVBITMAP_GetFormatName(DIBDRVBITMAP const *bmp);
++
++/* sets/gets bits of a DIBDRVBITMAP taking in account if it's a top down
++ or a bottom-up DIB */
++void _DIBDRVBITMAP_Set_Bits(DIBDRVBITMAP *dib, void *bits, BOOL owns);
++void *_DIBDRVBITMAP_Get_Bits(DIBDRVBITMAP *dib);
++
++/* calculates and sets the lightest color for monochrome bitmaps */
++int _DIBDRVBITMAP_GetLightestColorIndex(DIBDRVBITMAP *dib);
++
++/* initialize or create dib from a bitmap :
++ dib dib being initialized
++ bi source BITMAPINFOHEADER with required DIB format info
++ bit_fields color masks
++ color_table color table, if any
++ bits pointer to image data array
++ NOTE : DIBDRVBITMAP doesn't owns bits, but do own color table */
++BOOL _DIBDRVBITMAP_InitFromBMIH(DIBDRVBITMAP *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields,
++ const RGBQUAD *color_table, void *bits);
++DIBDRVBITMAP *_DIBDRVBITMAP_CreateFromBMIH(const BITMAPINFOHEADER *bi, const DWORD *bit_fields,
++ const RGBQUAD *colorTable, void *bits);
++
++BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi, void *bits);
++DIBDRVBITMAP *_DIBDRVBITMAP_CreateFromBitmapinfo(const BITMAPINFO *bmi, void *bits);
++
++/* initializes a DIBRDVBITMAP copying it from a source one
++ Parameters :
++ dib destination DIBDRVBITMAP
++ src source DIBDRVBITMAP
++ copy TRUE->copy source pixel array FALSE->link to source pixel array */
++BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, BOOL copy);
++
++/* creates a DIBRDVBITMAP copying format info from a source one
++ Parameters :
++ dib destination DIBDRVBITMAP
++ src source DIBDRVBITMAP
++ widht, height sizes of newly created bitmap */
++BOOL _DIBDRVBITMAP_CreateFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, int width, int height);
++
++/* allocates a new DIBDTVBITMAP */
++DIBDRVBITMAP *_DIBDRVBITMAP_New(void);
++
++/* Frees and de-allocates a DIBDRVBITMAP structure data */
++void _DIBDRVBITMAP_Free(DIBDRVBITMAP *bmp);
++
++/* Clears a DIBDRVBITMAP structure data
++ WARNING : doesn't free anything */
++void _DIBDRVBITMAP_Clear(DIBDRVBITMAP *bmp);
++
++/* checks whether the format of 2 DIBs are identical
++ it checks the pixel bit count and the color table size
++ and content, if needed */
++BOOL _DIBDRVBITMAP_FormatMatch(const DIBDRVBITMAP *d1, const DIBDRVBITMAP *d2);
++
++/* convert a given dib into another format given by 'format' parameter */
++BOOL _DIBDRVBITMAP_Convert(DIBDRVBITMAP *dst, const DIBDRVBITMAP *src, const DIBDRVBITMAP *format);
++
++/* creates a solid-filled DIB of given color and format
++ DIB format is given by 'format' parameter */
++BOOL _DIBDRVBITMAP_CreateSolid(DIBDRVBITMAP *bmp, DIBDRVBITMAP *format, int width, int height, DWORD Color);
++
++/* expands horizontally a bitmap to reach a minimum size,
++ keeping its width as a multiple of a base width
++ Used to widen brushes in order to optimize blitting */
++BOOL _DIBDRVBITMAP_ExpandHoriz(DIBDRVBITMAP *dib, int baseWidth, int minWidth);
++
++/* *********************************************************************
++ * BITMAP LIST MANAGEMENT FUNCTIONS
++ * ********************************************************************/
++
++/* initializes bitmap list -- to be called at process attach */
++void _BITMAPLIST_Init(void);
++
++/* terminates bitmap list -- to be called at process detach */
++void _BITMAPLIST_Terminate(void);
++
++/* adds a DIB to the list - it adds it on top, as
++ usually most recently created DIBs are used first */
++BOOL _BITMAPLIST_Add(HBITMAP hbmp, DIBDRVBITMAP *bmp);
++
++/* removes a DIB from the list */
++DIBDRVBITMAP *_BITMAPLIST_Remove(HBITMAP hbmp);
++
++/* scans list for a DIB */
++DIBDRVBITMAP *_BITMAPLIST_Get(HBITMAP hbmp);
++
++/* *********************************************************************
++ * DIB <--> DDB CONVERSION ROUTINES
++ * ********************************************************************/
++
++/***********************************************************************
++ * Creates DDB that is compatible with source hdc.
++ * hdc is the HDC on where the DIB MUST be selected in
++ * srcBmp is the source DIB
++ * startScan and scanLines specify the portion of DIB to convert
++ * in order to avoid unneeded conversion of large DIBs on blitting
++ *
++ * NOTE : the srcBmp DIB MUST NOT be selected in any DC */
++HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines );
++
++/***********************************************************************
++ * Creates DIB that is compatible with the target hdc.
++ * startScan and scanLines specify the portion of DDB to convert
++ * in order to avoid unneeded conversion of large DDBs on blitting
++ *
++ * NOTE : the srcBmp DDB MUST NOT be selected in any DC */
++HBITMAP _DIBDRV_ConvertDDBtoDIB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines );
++
++/***********************************************************************
++ * Creates DIB that is compatible with the target hdc for a device (non memory) source DC */
++HBITMAP _DIBDRV_ConvertDevDDBtoDIB( HDC hdcSrc, HDC hdcDst, int xSrc, int ySrc, int width, int height );
++
++/* *********************************************************************
++ * QUERY FUNCTIONS
++ * ********************************************************************/
++
++/***********************************************************************
++ * DIBDRV_GetDeviceCaps */
++INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap );
++
++/* *********************************************************************
++ * GEOMETRIC UTILITIES
++ * ********************************************************************/
++
++/* intersect 2 rectangles (just to not use USER32 one...) */
++BOOL _DIBDRV_IntersectRect(RECT *d, const RECT *s1, const RECT *s2);
++
++/* converts positions from Word space to Device space */
++void _DIBDRV_Position_ws2ds(DIBDRVPHYSDEV *physDev, int *x, int *y);
++void _DIBDRV_Positions_ws2ds(DIBDRVPHYSDEV *physDev, int *x1, int *y1, int *x2, int *y2);
++
++/* converts sizes from Word space to Device space */
++void _DIBDRV_Sizes_ws2ds(DIBDRVPHYSDEV *physDev, int *w, int *h);
++
++/* converts a rectangle form Word space to Device space */
++void _DIBDRV_Rect_ws2ds(DIBDRVPHYSDEV *physDev, const RECT *src, RECT *dst);
++
++/* converts positions from Device space to World space */
++void _DIBDRV_Position_ds2ws(DIBDRVPHYSDEV *physDev, int *x, int *y);
++void _DIBDRV_Positions_ds2ws(DIBDRVPHYSDEV *physDev, int *x1, int *y1, int *x2, int *y2);
++
++/* converts sizes from Device space to World space */
++void _DIBDRV_Sizes_ds2ws(DIBDRVPHYSDEV *physDev, int *w, int *h);
++
++/* *********************************************************************
++ * COLOR UTILITIES
++ * ********************************************************************/
++
++/* maps a colorref to actual color */
++COLORREF _DIBDRV_MapColor(DIBDRVPHYSDEV *physDev, COLORREF color);
++
++/* gets nearest color index in DIB palette of a given colorref */
++DWORD _DIBDRV_GetNearestColorIndex(const DIBDRVBITMAP *dib, COLORREF color);
++
++/* gets nearest color to DIB palette color */
++DWORD _DIBDRV_GetNearestColor(const DIBDRVBITMAP *dib, COLORREF color);
++
++#endif
+diff -Nru a/dlls/winedib.drv/dibdrv_main.c b/dlls/winedib.drv/dibdrv_main.c
+--- a/dlls/winedib.drv/dibdrv_main.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/dibdrv_main.c 2010-08-04 16:08:44.668222017 +0200
+@@ -0,0 +1,67 @@
++/*
++ * DIBDRV initialization code
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/***********************************************************************
++ * DIBDRV initialization routine
++ */
++BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
++{
++ BOOL ret = TRUE;
++
++ switch(reason)
++ {
++ case DLL_PROCESS_ATTACH:
++
++ /* Loads display driver */
++ _DIBDRV_LoadDisplayDriver();
++
++ /* initializes freetype library */
++ if(!_DIBDRV_FreeType_Init())
++ ERR("Couldn't initialize freetype library.\n");
++
++ /* initializes internal bitmap list */
++ _BITMAPLIST_Init();
++
++ break;
++ case DLL_THREAD_DETACH:
++ /* do thread detach */
++ break;
++ case DLL_PROCESS_DETACH:
++
++ /* terminates freetype library */
++ _DIBDRV_FreeType_Terminate();
++
++ /* unloads display driver */
++ _DIBDRV_FreeDisplayDriver();
++
++ /* terminates internal bitmap list */
++ _BITMAPLIST_Terminate();
++
++ break;
++ }
++ return ret;
++}
+diff -Nru a/dlls/winedib.drv/driver.c b/dlls/winedib.drv/driver.c
+--- a/dlls/winedib.drv/driver.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/driver.c 2010-08-04 16:08:44.474222017 +0200
+@@ -0,0 +1,254 @@
++/*
++ * Access to display driver
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++#include <stdio.h>
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/* CreateDriver
++ * Allocate and fill the function pointer structure for a given module. */
++static DC_FUNCTIONS *CreateDriver( HMODULE module )
++{
++ DC_FUNCTIONS *funcs;
++
++ if (!(funcs = HeapAlloc( GetProcessHeap(), 0, sizeof(*funcs))))
++ return NULL;
++
++ /* fill the function table */
++ if (module)
++ {
++#define GET_FUNC(name) funcs->p##name = (void*)GetProcAddress( module, #name )
++ GET_FUNC(AbortDoc);
++ GET_FUNC(AbortPath);
++ GET_FUNC(AlphaBlend);
++ GET_FUNC(AngleArc);
++ GET_FUNC(Arc);
++ GET_FUNC(ArcTo);
++ GET_FUNC(BeginPath);
++ GET_FUNC(BitBlt);
++ GET_FUNC(ChoosePixelFormat);
++ GET_FUNC(Chord);
++ GET_FUNC(CloseFigure);
++ GET_FUNC(CreateBitmap);
++ GET_FUNC(CreateDC);
++ GET_FUNC(CreateDIBSection);
++ GET_FUNC(DeleteBitmap);
++ GET_FUNC(DeleteDC);
++ GET_FUNC(DescribePixelFormat);
++ GET_FUNC(DeviceCapabilities);
++ GET_FUNC(Ellipse);
++ GET_FUNC(EndDoc);
++ GET_FUNC(EndPage);
++ GET_FUNC(EndPath);
++ GET_FUNC(EnumDeviceFonts);
++ GET_FUNC(ExcludeClipRect);
++ GET_FUNC(ExtDeviceMode);
++ GET_FUNC(ExtEscape);
++ GET_FUNC(ExtFloodFill);
++ GET_FUNC(ExtSelectClipRgn);
++ GET_FUNC(ExtTextOut);
++ GET_FUNC(FillPath);
++ GET_FUNC(FillRgn);
++ GET_FUNC(FlattenPath);
++ GET_FUNC(FrameRgn);
++ GET_FUNC(GdiComment);
++ GET_FUNC(GetBitmapBits);
++ GET_FUNC(GetCharWidth);
++ GET_FUNC(GetDCOrgEx);
++ GET_FUNC(GetDIBColorTable);
++ GET_FUNC(GetDIBits);
++ GET_FUNC(GetDeviceCaps);
++ GET_FUNC(GetDeviceGammaRamp);
++ GET_FUNC(GetICMProfile);
++ GET_FUNC(GetNearestColor);
++ GET_FUNC(GetPixel);
++ GET_FUNC(GetPixelFormat);
++ GET_FUNC(GetSystemPaletteEntries);
++ GET_FUNC(GetTextExtentExPoint);
++ GET_FUNC(GetTextMetrics);
++ GET_FUNC(IntersectClipRect);
++ GET_FUNC(InvertRgn);
++ GET_FUNC(LineTo);
++ GET_FUNC(MoveTo);
++ GET_FUNC(ModifyWorldTransform);
++ GET_FUNC(OffsetClipRgn);
++ GET_FUNC(OffsetViewportOrg);
++ GET_FUNC(OffsetWindowOrg);
++ GET_FUNC(PaintRgn);
++ GET_FUNC(PatBlt);
++ GET_FUNC(Pie);
++ GET_FUNC(PolyBezier);
++ GET_FUNC(PolyBezierTo);
++ GET_FUNC(PolyDraw);
++ GET_FUNC(PolyPolygon);
++ GET_FUNC(PolyPolyline);
++ GET_FUNC(Polygon);
++ GET_FUNC(Polyline);
++ GET_FUNC(PolylineTo);
++ GET_FUNC(RealizeDefaultPalette);
++ GET_FUNC(RealizePalette);
++ GET_FUNC(Rectangle);
++ GET_FUNC(ResetDC);
++ GET_FUNC(RestoreDC);
++ GET_FUNC(RoundRect);
++ GET_FUNC(SaveDC);
++ GET_FUNC(ScaleViewportExt);
++ GET_FUNC(ScaleWindowExt);
++ GET_FUNC(SelectBitmap);
++ GET_FUNC(SelectBrush);
++ GET_FUNC(SelectClipPath);
++ GET_FUNC(SelectFont);
++ GET_FUNC(SelectPalette);
++ GET_FUNC(SelectPen);
++ GET_FUNC(SetArcDirection);
++ GET_FUNC(SetBitmapBits);
++ GET_FUNC(SetBkColor);
++ GET_FUNC(SetBkMode);
++ GET_FUNC(SetDCBrushColor);
++ GET_FUNC(SetDCOrg);
++ GET_FUNC(SetDCPenColor);
++ GET_FUNC(SetDIBColorTable);
++ GET_FUNC(SetDIBits);
++ GET_FUNC(SetDIBitsToDevice);
++ GET_FUNC(SetDeviceClipping);
++ GET_FUNC(SetDeviceGammaRamp);
++ GET_FUNC(SetMapMode);
++ GET_FUNC(SetMapperFlags);
++ GET_FUNC(SetPixel);
++ GET_FUNC(SetPixelFormat);
++ GET_FUNC(SetPolyFillMode);
++ GET_FUNC(SetROP2);
++ GET_FUNC(SetRelAbs);
++ GET_FUNC(SetStretchBltMode);
++ GET_FUNC(SetTextAlign);
++ GET_FUNC(SetTextCharacterExtra);
++ GET_FUNC(SetTextColor);
++ GET_FUNC(SetTextJustification);
++ GET_FUNC(SetViewportExt);
++ GET_FUNC(SetViewportOrg);
++ GET_FUNC(SetWindowExt);
++ GET_FUNC(SetWindowOrg);
++ GET_FUNC(SetWorldTransform);
++ GET_FUNC(StartDoc);
++ GET_FUNC(StartPage);
++ GET_FUNC(StretchBlt);
++ GET_FUNC(StretchDIBits);
++ GET_FUNC(StrokeAndFillPath);
++ GET_FUNC(StrokePath);
++ GET_FUNC(SwapBuffers);
++ GET_FUNC(UnrealizePalette);
++ GET_FUNC(WidenPath);
++
++ /* OpenGL32 */
++ GET_FUNC(wglCreateContext);
++ GET_FUNC(wglDeleteContext);
++ GET_FUNC(wglGetProcAddress);
++ GET_FUNC(wglGetPbufferDCARB);
++ GET_FUNC(wglMakeContextCurrentARB);
++ GET_FUNC(wglMakeCurrent);
++ GET_FUNC(wglSetPixelFormatWINE);
++ GET_FUNC(wglShareLists);
++ GET_FUNC(wglUseFontBitmapsA);
++ GET_FUNC(wglUseFontBitmapsW);
++#undef GET_FUNC
++ }
++ else
++ memset( funcs, 0, sizeof(*funcs) );
++
++ /* add it to the list */
++ return funcs;
++}
++
++
++/* LoadDisplayDriver
++ * Loads display driver - partially grabbed from gdi32 */
++static DC_FUNCTIONS *X11DrvFuncs = NULL;
++static HMODULE X11DrvModule = 0;
++DC_FUNCTIONS *_DIBDRV_LoadDisplayDriver(void)
++{
++ char buffer[MAX_PATH], libname[32], *name, *next;
++ HMODULE module = 0;
++ HKEY hkey;
++
++ if (X11DrvFuncs) /* already loaded */
++ return X11DrvFuncs;
++
++ strcpy( buffer, "x11" ); /* default value */
++ /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
++ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey ))
++ {
++ DWORD type, count = sizeof(buffer);
++ RegQueryValueExA( hkey, "Graphics", 0, &type, (LPBYTE) buffer, &count );
++ RegCloseKey( hkey );
++ }
++
++ name = buffer;
++ while (name)
++ {
++ next = strchr( name, ',' );
++ if (next)
++ *next++ = 0;
++
++ snprintf( libname, sizeof(libname), "wine%s.drv", name );
++ if ((module = LoadLibraryA( libname )) != 0)
++ break;
++ name = next;
++ }
++
++ if (!(X11DrvFuncs = CreateDriver(module)))
++ {
++ ERR( "Could not create graphics driver '%s'\n", buffer );
++ FreeLibrary( module );
++ ExitProcess(1);
++ }
++
++ X11DrvModule = module;
++ return X11DrvFuncs;
++}
++
++/* FreeDisplayDriver
++ Frees resources allocated by Display driver */
++void _DIBDRV_FreeDisplayDriver(void)
++{
++ /* frees function table */
++ if(X11DrvFuncs)
++ {
++ HeapFree(GetProcessHeap(), 0, X11DrvFuncs);
++ X11DrvFuncs = 0;
++ }
++ /* and unload the module */
++ if(X11DrvModule)
++ {
++ FreeLibrary(X11DrvModule);
++ X11DrvModule = 0;
++ }
++}
++
++/* GetDisplayDriver
++ Gets a pointer to display drives'function table */
++inline DC_FUNCTIONS *_DIBDRV_GetDisplayDriver(void)
++{
++ return X11DrvFuncs;
++
++}
+diff -Nru a/dlls/winedib.drv/font.c b/dlls/winedib.drv/font.c
+--- a/dlls/winedib.drv/font.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/font.c 2010-08-04 16:08:44.678222017 +0200
+@@ -0,0 +1,280 @@
++/*
++ * DIBDRV font objects
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++
++#if 0
++/* prints out some info about face */
++void PrintFaceInfo(FT_Face face)
++{
++ int i;
++
++ fprintf(stderr, "----------------------------------------------------------\n");
++ fprintf(stderr, "Family name :%s\n", face->family_name);
++ fprintf(stderr, "Style name :%s\n", face->style_name);
++ fprintf(stderr, "Num fixed sizes : %d\n", face->num_fixed_sizes);
++ if(face->num_fixed_sizes)
++ {
++ fprintf(stderr, "Fixed sizes :");
++ for(i = 0; i < face->num_fixed_sizes; i++)
++ fprintf(stderr, " (%d, %d)", face->available_sizes[i].width, face->available_sizes[i].height);
++ fprintf(stderr, "\n");
++ }
++ fprintf(stderr, "Face flags: ");
++ if(face->face_flags & FT_FACE_FLAG_SCALABLE ) fprintf(stderr, "FT_FACE_FLAG_SCALABLE ");
++ if(face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) fprintf(stderr, "FT_FACE_FLAG_FIXED_SIZES ");
++ if(face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) fprintf(stderr, "FT_FACE_FLAG_FIXED_WIDTH ");
++ if(face->face_flags & FT_FACE_FLAG_SFNT ) fprintf(stderr, "FT_FACE_FLAG_SFNT ");
++ if(face->face_flags & FT_FACE_FLAG_HORIZONTAL ) fprintf(stderr, "FT_FACE_FLAG_HORIZONTAL ");
++ if(face->face_flags & FT_FACE_FLAG_VERTICAL ) fprintf(stderr, "FT_FACE_FLAG_VERTICAL ");
++ if(face->face_flags & FT_FACE_FLAG_KERNING ) fprintf(stderr, "FT_FACE_FLAG_KERNING ");
++ if(face->face_flags & FT_FACE_FLAG_FAST_GLYPHS ) fprintf(stderr, "FT_FACE_FLAG_FAST_GLYPHS ");
++ if(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) fprintf(stderr, "FT_FACE_FLAG_MULTIPLE_MASTERS ");
++ if(face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) fprintf(stderr, "FT_FACE_FLAG_GLYPH_NAMES ");
++ if(face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) fprintf(stderr, "FT_FACE_FLAG_EXTERNAL_STREAM ");
++ if(face->face_flags & FT_FACE_FLAG_HINTER ) fprintf(stderr, "FT_FACE_FLAG_HINTER ");
++ if(face->face_flags & FT_FACE_FLAG_CID_KEYED ) fprintf(stderr, "FT_FACE_FLAG_CID_KEYED ");
++ if(face->face_flags & FT_FACE_FLAG_TRICKY ) fprintf(stderr, "FT_FACE_FLAG_TRICKY ");
++ fprintf(stderr, "\n");
++
++ fprintf(stderr, "Style flags: ");
++ if(face->style_flags & FT_STYLE_FLAG_ITALIC) fprintf(stderr, "FT_STYLE_FLAG_ITALIC ");
++ if(face->style_flags & FT_STYLE_FLAG_BOLD) fprintf(stderr, "FT_STYLE_FLAG_BOLD ");
++ fprintf(stderr, "\n");
++ fprintf(stderr, "----------------------------------------------------------\n");
++}
++#endif
++
++
++/**********************************************************************
++ * DIBDRV_SetTextColor
++ */
++COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color )
++{
++ COLORREF res;
++
++ MAYBE(TRACE("physDev:%p, color:%08x\n", physDev, color));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++
++ /* do nothing if color is the same as actual one */
++ if(color == physDev->textColor)
++ return color;
++
++ /* stores old color and sets new one */
++ res = physDev->textColor;
++ physDev->textColor = color;
++
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ /* fills the text color table used on antialiased font display */
++ if(physDev->physBitmap->funcs)
++ {
++ BYTE r, g, b;
++ INT i;
++
++ r = GetRValue(color);
++ g = GetGValue(color);
++ b = GetBValue(color);
++ for(i = 0; i < 256; i++)
++ {
++ physDev->textColorTable[i] = physDev->physBitmap->funcs->ColorToPixel(physDev->physBitmap, RGB(
++ MulDiv(r, i, 255),
++ MulDiv(g, i, 255),
++ MulDiv(b, i, 255)
++ ));
++ }
++ }
++#endif
++
++ /* returns previous text color */
++ return res;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSetTextColor(physDev->X11PhysDev, color);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_SelectFont
++ */
++HFONT DIBDRV_SelectFont( DIBDRVPHYSDEV *physDev, HFONT hfont, GdiFont *gdiFont )
++{
++ HFONT res;
++ FT_Int i;
++ FT_Error error;
++ FT_CharMap charmap = NULL;
++ LOGFONTW lf;
++
++ MAYBE(TRACE("physDev:%p, hfont:%p, gdiFont:%p\n", physDev, hfont, gdiFont));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++
++ /* gets font information */
++ GetObjectW(hfont, sizeof(lf), &lf);
++ MAYBE(TRACE("Font is : '%s'\n", debugstr_w(lf.lfFaceName)));
++
++ /* FIXME: just handles gdifont, don't know if it needs to handle hfont too
++ BTW, still don't know how to get FT_Face from non-gdi font here
++ */
++ if(!gdiFont)
++ {
++ FIXME("No gdi font - unhandled by now.\n");
++ return hfont;
++ }
++
++ physDev->face = gdiFont->ft_face;
++ if(!physDev->face)
++ {
++ FIXME("Error, null Ft_Face\n");
++ return hfont;
++ }
++
++#if 0
++ /* prints out some info about face */
++ if(TRACE_ON(dibdrv)) MAYBE(PrintFaceInfo(physDev->face));
++#endif
++ /* setup the correct charmap.... maybe */
++ for (i = 0; i < physDev->face->num_charmaps; ++i)
++ {
++ if (physDev->face->charmaps[i]->platform_id != TT_PLATFORM_MICROSOFT)
++ continue;
++
++ if (physDev->face->charmaps[i]->encoding_id == TT_MS_ID_UNICODE_CS)
++ {
++ charmap = physDev->face->charmaps[i];
++ break;
++ }
++
++ if (charmap == NULL)
++ {
++ WARN("Selected fallout charmap #%d\n", i);
++ charmap = physDev->face->charmaps[i];
++ }
++ }
++ if (charmap == NULL)
++ {
++ WARN("No Windows character map found\n");
++ charmap = physDev->face->charmaps[0];
++ return 0;
++ }
++
++ error = pFT_Set_Charmap(physDev->face, charmap);
++ if (error != FT_Err_Ok)
++ {
++ ERR("%s returned %i\n", "FT_Set_Charmap", error);
++ return 0;
++ }
++
++ /* we use GDI fonts, so just return false */
++ return 0;
++
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSelectFont(physDev->X11PhysDev, hfont, gdiFont);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_EnumDeviceFonts
++ */
++BOOL DIBDRV_EnumDeviceFonts( DIBDRVPHYSDEV *physDev, LPLOGFONTW plf,
++ FONTENUMPROCW proc, LPARAM lp )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, plf:%p, proc:%p, lp:%lx\n", physDev, plf, proc, lp));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = 0;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pEnumDeviceFonts(physDev->X11PhysDev, plf, proc, lp);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_GetTextMetrics
++ */
++BOOL DIBDRV_GetTextMetrics( DIBDRVPHYSDEV *physDev, TEXTMETRICW *metrics )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, metrics:%p\n", physDev, metrics));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = 0;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetTextMetrics(physDev->X11PhysDev, metrics);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_GetCharWidth
++ */
++BOOL DIBDRV_GetCharWidth( DIBDRVPHYSDEV *physDev, UINT firstChar, UINT lastChar,
++ LPINT buffer )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, firstChar:%d, lastChar:%d, buffer:%pn", physDev, firstChar, lastChar, buffer));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = 0;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetCharWidth(physDev->X11PhysDev, firstChar, lastChar, buffer);
++ }
++ return res;
++}
+diff -Nru a/dlls/winedib.drv/freetype.c b/dlls/winedib.drv/freetype.c
+--- a/dlls/winedib.drv/freetype.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/freetype.c 2010-08-04 16:08:44.580222017 +0200
+@@ -0,0 +1,142 @@
++/*
++ * Truetype font functions
++ *
++ * Copyright 2008 Massimo Del Fedele
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++#define MAKE_FUNCPTR(f) typeof(f) * p##f = NULL;
++MAKE_FUNCPTR(FT_Done_Face)
++MAKE_FUNCPTR(FT_Done_FreeType)
++MAKE_FUNCPTR(FT_Get_Char_Index)
++MAKE_FUNCPTR(FT_Get_Glyph_Name)
++MAKE_FUNCPTR(FT_Get_Sfnt_Name)
++MAKE_FUNCPTR(FT_Get_Sfnt_Name_Count)
++MAKE_FUNCPTR(FT_Get_Sfnt_Table)
++MAKE_FUNCPTR(FT_Init_FreeType)
++MAKE_FUNCPTR(FT_Load_Glyph)
++MAKE_FUNCPTR(FT_Load_Char)
++MAKE_FUNCPTR(FT_Get_Glyph)
++MAKE_FUNCPTR(FT_Glyph_Copy)
++MAKE_FUNCPTR(FT_Glyph_To_Bitmap)
++MAKE_FUNCPTR(FT_Done_Glyph)
++MAKE_FUNCPTR(FT_New_Face)
++MAKE_FUNCPTR(FT_Set_Charmap)
++MAKE_FUNCPTR(FT_Set_Char_Size)
++MAKE_FUNCPTR(FT_Set_Pixel_Sizes)
++MAKE_FUNCPTR(FT_Get_First_Char)
++MAKE_FUNCPTR(FT_Render_Glyph)
++MAKE_FUNCPTR(FT_Glyph_Transform)
++MAKE_FUNCPTR(FT_Bitmap_New)
++MAKE_FUNCPTR(FT_Bitmap_Done)
++MAKE_FUNCPTR(FT_Bitmap_Convert)
++#undef MAKE_FUNCPTR
++
++/* freetype initialization flag */
++static BOOL FreeType_Initialized = FALSE;
++
++/* freetype dll handle */
++static void *ft_handle = NULL;
++
++/* freetype library handle */
++FT_Library DIBDRV_ftLibrary = NULL;
++
++/* initialize freetype library */
++BOOL _DIBDRV_FreeType_Init(void)
++{
++ FT_Int error;
++
++ ft_handle = wine_dlopen(SONAME_LIBFREETYPE, RTLD_NOW, NULL, 0);
++ if(!ft_handle)
++ {
++ WINE_MESSAGE(
++ "Wine cannot find the FreeType font library. To enable Wine to\n"
++ "use TrueType fonts please install a version of FreeType greater than\n"
++ "or equal to 2.0.5.\n"
++ "http://www.freetype.org\n");
++ return FALSE;
++ }
++
++#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(ft_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
++ LOAD_FUNCPTR(FT_Done_Face)
++ LOAD_FUNCPTR(FT_Done_FreeType)
++ LOAD_FUNCPTR(FT_Get_Char_Index)
++ LOAD_FUNCPTR(FT_Get_Glyph_Name)
++ LOAD_FUNCPTR(FT_Get_Sfnt_Name)
++ LOAD_FUNCPTR(FT_Get_Sfnt_Name_Count)
++ LOAD_FUNCPTR(FT_Get_Sfnt_Table)
++ LOAD_FUNCPTR(FT_Init_FreeType)
++ LOAD_FUNCPTR(FT_Load_Glyph)
++ LOAD_FUNCPTR(FT_Load_Char)
++ LOAD_FUNCPTR(FT_Get_Glyph)
++ LOAD_FUNCPTR(FT_Glyph_Copy)
++ LOAD_FUNCPTR(FT_Glyph_To_Bitmap)
++ LOAD_FUNCPTR(FT_Done_Glyph)
++ LOAD_FUNCPTR(FT_New_Face)
++ LOAD_FUNCPTR(FT_Set_Charmap)
++ LOAD_FUNCPTR(FT_Set_Char_Size)
++ LOAD_FUNCPTR(FT_Set_Pixel_Sizes)
++ LOAD_FUNCPTR(FT_Get_First_Char)
++ LOAD_FUNCPTR(FT_Render_Glyph)
++ LOAD_FUNCPTR(FT_Glyph_Transform)
++ LOAD_FUNCPTR(FT_Bitmap_New)
++ LOAD_FUNCPTR(FT_Bitmap_Done)
++ LOAD_FUNCPTR(FT_Bitmap_Convert)
++#undef LOAD_FUNCPTR
++
++ error = pFT_Init_FreeType(&DIBDRV_ftLibrary);
++ if (error != FT_Err_Ok)
++ {
++ ERR("%s returned %i\n", "FT_Init_FreeType", error);
++ wine_dlclose(ft_handle, NULL, 0);
++ return FALSE;
++ }
++
++ /* marks library as initialized */
++ FreeType_Initialized = TRUE;
++
++ return TRUE;
++
++sym_not_found:
++ WINE_MESSAGE(
++ "Wine cannot find certain functions that it needs inside the FreeType\n"
++ "font library. To enable Wine to use TrueType fonts please upgrade\n"
++ "FreeType to at least version 2.0.5.\n"
++ "http://www.freetype.org\n");
++ wine_dlclose(ft_handle, NULL, 0);
++ ft_handle = NULL;
++ return FALSE;
++}
++
++/* terminates freetype library */
++void _DIBDRV_FreeType_Terminate(void)
++{
++ if(!FreeType_Initialized)
++ return;
++
++ /* terminates and unload freetype library */
++ pFT_Done_FreeType(DIBDRV_ftLibrary);
++ wine_dlclose(ft_handle, NULL, 0);
++ ft_handle = NULL;
++ FreeType_Initialized = FALSE;
++
++}
+diff -Nru a/dlls/winedib.drv/freetype.h b/dlls/winedib.drv/freetype.h
+--- a/dlls/winedib.drv/freetype.h 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/freetype.h 2010-08-04 16:08:44.581222017 +0200
+@@ -0,0 +1,190 @@
++/*
++ * Truetype font functions
++ *
++ * Copyright 2008 Massimo Del Fedele
++ * 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_DIBDRV_FREETYPE_H
++#define __WINE_DIBDRV__FREETYPE_H
++
++/* freetype library for font support */
++#ifdef HAVE_FREETYPE
++
++#include <ft2build.h>
++#include FT_FREETYPE_H
++#include FT_GLYPH_H
++#include FT_TRUETYPE_TABLES_H
++#include FT_SFNT_NAMES_H
++#include FT_TRUETYPE_IDS_H
++#include FT_BITMAP_H
++
++/* freetype library handle */
++extern FT_Library DIBDRV_ftLibrary;
++
++/******************************************************************************************/
++/* FREETYPE STUFFS */
++/* grabbed from winex11.drv/freetype.c */
++/******************************************************************************************/
++
++/* This is basically a copy of FT_Bitmap_Size with an extra element added */
++typedef struct {
++ FT_Short height;
++ FT_Short width;
++ FT_Pos size;
++ FT_Pos x_ppem;
++ FT_Pos y_ppem;
++ FT_Short internal_leading;
++} Bitmap_Size;
++
++/* FT_Bitmap_Size gained 3 new elements between FreeType 2.1.4 and 2.1.5
++ So to let this compile on older versions of FreeType we'll define the
++ new structure here. */
++typedef struct {
++ FT_Short height, width;
++ FT_Pos size, x_ppem, y_ppem;
++} My_FT_Bitmap_Size;
++
++struct enum_data
++{
++ ENUMLOGFONTEXW elf;
++ NEWTEXTMETRICEXW ntm;
++ DWORD type;
++};
++
++typedef struct tagFace {
++ struct list entry;
++ WCHAR *StyleName;
++ char *file;
++ void *font_data_ptr;
++ DWORD font_data_size;
++ FT_Long face_index;
++ FONTSIGNATURE fs;
++ FONTSIGNATURE fs_links;
++ DWORD ntmFlags;
++ FT_Fixed font_version;
++ BOOL scalable;
++ Bitmap_Size size; /* set if face is a bitmap */
++ BOOL external; /* TRUE if we should manually add this font to the registry */
++ struct tagFamily *family;
++ /* Cached data for Enum */
++ struct enum_data *cached_enum_data;
++} Face;
++
++typedef struct tagFamily {
++ struct list entry;
++ const WCHAR *FamilyName;
++ struct list faces;
++} Family;
++
++typedef struct {
++ GLYPHMETRICS gm;
++ INT adv; /* These three hold to widths of the unrotated chars */
++ INT lsb;
++ INT bbx;
++ BOOL init;
++} GM;
++
++typedef struct {
++ FLOAT eM11, eM12;
++ FLOAT eM21, eM22;
++} FMAT2;
++
++typedef struct {
++ DWORD hash;
++ LOGFONTW lf;
++ FMAT2 matrix;
++ BOOL can_use_bitmap;
++} FONT_DESC;
++
++typedef struct tagHFONTLIST {
++ struct list entry;
++ HFONT hfont;
++} HFONTLIST;
++
++typedef struct {
++ struct list entry;
++ Face *face;
++ struct tagGdiFont *font;
++} CHILD_FONT;
++
++typedef struct tagGdiFont {
++ struct list entry;
++ GM **gm;
++ DWORD gmsize;
++ struct list hfontlist;
++ OUTLINETEXTMETRICW *potm;
++ DWORD total_kern_pairs;
++ KERNINGPAIR *kern_pairs;
++ struct list child_fonts;
++
++ /* the following members can be accessed without locking, they are never modified after creation */
++ FT_Face ft_face;
++ struct font_mapping *mapping;
++ LPWSTR name;
++ int charset;
++ int codepage;
++ BOOL fake_italic;
++ BOOL fake_bold;
++ BYTE underline;
++ BYTE strikeout;
++ INT orientation;
++ FONT_DESC font_desc;
++ LONG aveWidth, ppem;
++ double scale_y;
++ SHORT yMax;
++ SHORT yMin;
++ DWORD ntmFlags;
++ FONTSIGNATURE fs;
++ struct tagGdiFont *base_font;
++ VOID *GSUB_Table;
++ DWORD cache_num;
++} GdiFont;
++
++/* initialize freetype library */
++BOOL _DIBDRV_FreeType_Init(void);
++
++/* terminates freetype library */
++void _DIBDRV_FreeType_Terminate(void);
++
++#define MAKE_FUNCPTR(f) extern typeof(f) * p##f;
++MAKE_FUNCPTR(FT_Done_Face)
++MAKE_FUNCPTR(FT_Done_FreeType)
++MAKE_FUNCPTR(FT_Get_Char_Index)
++MAKE_FUNCPTR(FT_Get_Glyph_Name)
++MAKE_FUNCPTR(FT_Get_Sfnt_Name)
++MAKE_FUNCPTR(FT_Get_Sfnt_Name_Count)
++MAKE_FUNCPTR(FT_Get_Sfnt_Table)
++MAKE_FUNCPTR(FT_Init_FreeType)
++MAKE_FUNCPTR(FT_Load_Glyph)
++MAKE_FUNCPTR(FT_Load_Char)
++MAKE_FUNCPTR(FT_Get_Glyph)
++MAKE_FUNCPTR(FT_Glyph_Copy)
++MAKE_FUNCPTR(FT_Glyph_To_Bitmap)
++MAKE_FUNCPTR(FT_Done_Glyph)
++MAKE_FUNCPTR(FT_New_Face)
++MAKE_FUNCPTR(FT_Set_Charmap)
++MAKE_FUNCPTR(FT_Set_Char_Size)
++MAKE_FUNCPTR(FT_Set_Pixel_Sizes)
++MAKE_FUNCPTR(FT_Get_First_Char)
++MAKE_FUNCPTR(FT_Render_Glyph)
++MAKE_FUNCPTR(FT_Glyph_Transform)
++MAKE_FUNCPTR(FT_Bitmap_New)
++MAKE_FUNCPTR(FT_Bitmap_Done)
++MAKE_FUNCPTR(FT_Bitmap_Convert)
++#undef MAKE_FUNCPTR
++
++#endif /* HAVE_FREETYPE */
++
++#endif
+diff -Nru a/dlls/winedib.drv/graphics.c b/dlls/winedib.drv/graphics.c
+--- a/dlls/winedib.drv/graphics.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/graphics.c 2010-08-04 16:08:44.739222017 +0200
+@@ -0,0 +1,1059 @@
++/*
++ * DIBDRV implementation of GDI driver graphics functions
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++static inline void OrderInt(int *i1, int *i2)
++{
++ if(*i1 > *i2)
++ {
++ int tmp;
++ tmp = *i1;
++ *i1 = *i2;
++ *i2 = tmp;
++ }
++}
++
++#define LEFT_SIDE 1
++#define TOP_SIDE 2
++#define RIGHT_SIDE 4
++#define BOTTOM_SIDE 8
++
++/* clips a line segment by a rectangular window */
++static inline BYTE outCodes(const POINT *p, const RECT *r)
++{
++ BYTE Code = 0;
++
++ if(p->y < r->top)
++ Code |= TOP_SIDE;
++ else if(p->y >= r->bottom)
++ Code |= BOTTOM_SIDE;
++ if(p->x >= r->right)
++ Code |= RIGHT_SIDE;
++ else if(p->x < r->left)
++ Code |= LEFT_SIDE;
++ return Code;
++}
++
++static BOOL ClipLine(const POINT *p1, const POINT *p2, const RECT *r, POINT *pc1, POINT *pc2)
++{
++ BYTE outCode1,outCode2;
++ int tmp;
++ BYTE tmpCode;
++
++ pc1->x = p1->x; pc1->y = p1->y;
++ pc2->x = p2->x; pc2->y = p2->y;
++ while(TRUE)
++ {
++ outCode1 = outCodes(pc1, r);
++ outCode2 = outCodes(pc2, r);
++ if(outCode1 & outCode2)
++ return FALSE;
++ if(!outCode1 && !outCode2)
++ return TRUE;
++ if(!outCode1)
++ {
++ tmp = pc1->x; pc1->x = pc2->x; pc2->x = tmp;
++ tmp = pc1->y; pc1->y = pc2->y; pc2->y = tmp;
++ tmpCode = outCode1; outCode1 = outCode2; outCode2 = tmpCode;
++ }
++ if(outCode1 & TOP_SIDE)
++ {
++ pc1->x += MulDiv(pc2->x - pc1->x, r->top - pc1->y, pc2->y - pc1->y);
++ pc1->y = r->top;
++ }
++ else if(outCode1 & BOTTOM_SIDE)
++ {
++ pc1->x += MulDiv(pc2->x - pc1->x, r->bottom - 1 - pc1->y, pc2->y - pc1->y);
++ pc1->y = r->bottom - 1;
++ }
++ else if(outCode1 & RIGHT_SIDE)
++ {
++ pc1->y += MulDiv(pc2->y - pc1->y, r->right - 1 - pc1->x, pc2->x - pc1->x);
++ pc1->x = r->right - 1;
++ }
++ else if(outCode1 & LEFT_SIDE)
++ {
++ pc1->y += MulDiv(pc2->y - pc1->y, r->left - pc1->x, pc2->x - pc1->x);
++ pc1->x = r->left;
++ }
++ }
++}
++
++/* Clips a polygon by an horizontal/vertical line
++ which indicates the side :
++*/
++static inline BOOL PointInside(const POINT *p, const RECT *r, BYTE side)
++{
++ switch(side)
++ {
++ case 1: /* left */
++ return p->x >= r->left;
++ case 2: /* top */
++ return p->y >= r->top;
++ case 4: /* right */
++ return p->x < r->right;
++ case 8: /* bottom */
++ return p->y < r->bottom;
++ default:
++ return FALSE;
++ }
++}
++
++static inline void SideIntersect(const POINT *p1, const POINT *p2, const RECT *r, BYTE side, POINT *inters)
++{
++ switch( side )
++ {
++ case LEFT_SIDE: /* left */
++ inters->x = r->left;
++ inters->y = MulDiv(p2->y - p1->y, r->left - p1->x, p2->x - p1->x) + p1->y;
++ break;
++ case TOP_SIDE: /* top */
++ inters->x = MulDiv(p2->x - p1->x, r->top - p1->y, p2->y - p1->y) + p1->x;
++ inters->y = r->top;
++ break;
++ case RIGHT_SIDE: /* right */
++ inters->x = r->right - 1;
++ inters->y = MulDiv(p2->y - p1->y, r->right - 1 - p1->x, p2->x - p1->x) + p1->y;
++ break;
++ case BOTTOM_SIDE: /* bottom */
++ inters->x = MulDiv(p2->x - p1->x, r->bottom - 1 - p1->y, p2->y - p1->y) + p1->x;
++ inters->y = r->bottom - 1;
++ break;
++ default:
++ break;
++ }
++}
++
++
++static BOOL ClipPolygonBySide(const POINT *pt, int count, const RECT *r, BYTE side, POINT **clipped, int *clippedCount)
++{
++ int iPoint;
++ const POINT *p1, *p2;
++ POINT *pOut;
++
++ if(!(*clipped = HeapAlloc(GetProcessHeap(), 0, sizeof(POINT) * count * 2)))
++ return FALSE;
++ pOut = *clipped;
++ *clippedCount = 0;
++
++ p1 = pt + count - 1;
++ p2 = pt;
++ for(iPoint = 0 ; iPoint < count ; iPoint++)
++ {
++ if(PointInside(p2, r, side))
++ {
++ /* point p is "inside" */
++ if(!PointInside(p1, r, side))
++ {
++ /* p is "inside" and s is "outside" */
++ SideIntersect(p2, p1, r, side, pOut++);
++ (*clippedCount)++;
++ }
++ pOut->x = p2->x;
++ pOut->y = p2->y;
++ pOut++;
++ (*clippedCount)++;
++ }
++ else if(PointInside( p1, r, side ))
++ {
++ /* s is "inside" and p is "outside" */
++ SideIntersect(p1, p2, r, side, pOut++);
++ (*clippedCount)++;
++ }
++ p1 = p2++;
++ }
++ return *clippedCount;
++}
++
++
++/* Clips a polygon by a rectangular window - returns a new polygon */
++static BOOL ClipPolygon(const POINT* pt, int count, const RECT *r, POINT **newPt, int *newCount)
++{
++ POINT *pc1, *pc2;
++ int count1, count2;
++ BOOL res;
++
++ if(!ClipPolygonBySide(pt, count, r, LEFT_SIDE, &pc1, &count1))
++ return FALSE;
++ res = ClipPolygonBySide(pc1, count1, r, TOP_SIDE, &pc2, &count2);
++ HeapFree(GetProcessHeap(), 0, pc1);
++ if(!res)
++ return FALSE;
++ res = ClipPolygonBySide(pc2, count2, r, RIGHT_SIDE, &pc1, &count1);
++ HeapFree(GetProcessHeap(), 0, pc2);
++ if(!res)
++ return FALSE;
++ res = ClipPolygonBySide(pc1, count1, r, BOTTOM_SIDE, &pc2, &count2);
++ HeapFree(GetProcessHeap(), 0, pc1);
++ if(!res)
++ return FALSE;
++
++ *newPt = pc2;
++ *newCount = count2;
++ return TRUE;
++}
++
++/* Intersects a line given by 2 points with an horizontal scan line at height y */
++static BOOL ScanLine(const POINT *p1, const POINT *p2, int ys, POINT *pRes)
++{
++ if(!pRes)
++ return FALSE;
++
++ /* if line lies completely over or under scan line, no intersection */
++ if((p1->y < ys && p2->y < ys) || (p1->y >= ys && p2->y >= ys))
++ return FALSE;
++
++ /* if line is parallel to x axis, we consider it not intersecting */
++ if(p1->y == p2->y)
++ return FALSE;
++
++ pRes->x = MulDiv(p2->x - p1->x, ys - p1->y, p2->y - p1->y) + p1->x;
++ pRes->y = ys;
++ return TRUE;
++}
++
++/* Gets an x-ordered list of intersection points of a scanline at position y
++ with a polygon/polyline */
++static BOOL ScanPolygon(const POINT *pt, int count, int ys, POINT **scans, int *scanCount)
++{
++ const POINT *p1, *p2;
++ POINT *pDest;
++ int iPoint;
++ POINT *ps1, *ps2;
++ int i, j, tmp;
++
++ /* if not at least 2 points, nothing to return */
++ if(count < 2)
++ return FALSE;
++
++ /* intersections count is AT MOST 'count'; we don't care to
++ allocate exact memory needed */
++ *scans = HeapAlloc(GetProcessHeap(), 0, sizeof(POINT)*count);
++ if(!*scans)
++ return FALSE;
++
++ /* builds unordered intersections */
++ pDest = *scans;
++ *scanCount = 0;
++ p2 = pt;
++ for(iPoint = 0; iPoint < count-1; iPoint++)
++ {
++ p1 = p2;
++ p2++;
++ if(ScanLine(p1, p2, ys, pDest))
++ {
++ pDest++;
++ (*scanCount)++;
++ }
++ }
++ p1 = p2;
++ p2 = pt;
++ if(ScanLine(p1, p2, ys, pDest))
++ {
++ pDest++;
++ (*scanCount)++;
++ }
++
++ /* now we sort the list -- duped point are left into
++ as they're needed for the scanline fill algorithm */
++ for(i = 0, ps1 = *scans; i < *scanCount -1; i++, ps1++)
++ for(j = i+1, ps2 = ps1+1; j < *scanCount; j++, ps2++)
++ if(ps2->x < ps1->x)
++ {
++ tmp = ps2->x;
++ ps2->x = ps1->x;
++ ps1->x = tmp;
++ tmp = ps2->y;
++ ps2->y = ps1->y;
++ ps1->y = tmp;
++ }
++
++ return TRUE;
++}
++
++/* gets bounding box of a polygon */
++static void PolygonBoundingBox(const POINT *pt, int count, RECT *bBox)
++{
++ const POINT *p;
++ int iPoint;
++
++ bBox->left = MAXLONG; bBox->right = -MAXLONG;
++ bBox->top = MAXLONG; bBox->bottom = -MAXLONG;
++ for(p = pt, iPoint = 0; iPoint < count; iPoint++, p++)
++ {
++ if(p->x < bBox->left ) bBox->left = p->x;
++ if(p->x > bBox->right ) bBox->right = p->x;
++ if(p->y < bBox->top ) bBox->top = p->y;
++ if(p->y > bBox->bottom) bBox->bottom = p->y;
++ }
++}
++
++/* intersect 2 rectangles (just to not use USER32 one...)
++ bottom and tight sides are considered OUTSIDE */
++BOOL _DIBDRV_IntersectRect(RECT *d, const RECT *s1, const RECT *s2)
++{
++ if(s1->right <= s2->left ||
++ s2->right <= s1->left ||
++ s1->bottom <= s2->top ||
++ s2->bottom <= s1->top
++ )
++ return FALSE;
++ d->left = s1->left > s2->left ? s1->left : s2->left;
++ d->top = s1->top > s2->top ? s1->top : s2->top;
++ d->right = s1->right < s2->right ? s1->right : s2->right;
++ d->bottom = s1->bottom < s2->bottom ? s1->bottom : s2->bottom;
++ return TRUE;
++}
++
++/* converts a rectangle form Word space to Device space */
++void _DIBDRV_Rect_ws2ds(DIBDRVPHYSDEV *physDev, const RECT *src, RECT *dst)
++{
++ POINT pts[2];
++ pts[0].x = src->left;
++ pts[0].y = src->top;
++ pts[1].x = src->right;
++ pts[1].y = src->bottom;
++ LPtoDP(physDev->hdc, pts, 2);
++ dst->left = pts[0].x;
++ dst->top = pts[0].y;
++ dst->right = pts[1].x;
++ dst->bottom = pts[1].y;
++}
++
++/* converts positions from Word space to Device space */
++void _DIBDRV_Position_ws2ds(DIBDRVPHYSDEV *physDev, int *x, int *y)
++{
++ POINT p;
++ p.x = *x;
++ p.y = *y;
++ LPtoDP(physDev->hdc, &p, 1);
++ *x = p.x;
++ *y = p.y;
++}
++
++void _DIBDRV_Positions_ws2ds(DIBDRVPHYSDEV *physDev, int *x1, int *y1, int *x2, int *y2)
++{
++ POINT pts[2];
++ pts[0].x = *x1;
++ pts[0].y = *y1;
++ pts[1].x = *x2;
++ pts[1].y = *y2;
++ LPtoDP(physDev->hdc, pts, 2);
++ *x1 = pts[0].x;
++ *y1 = pts[0].y;
++ *x2 = pts[1].x;
++ *y2 = pts[1].y;
++}
++
++/* converts sizes from Word space to Device space */
++void _DIBDRV_Sizes_ws2ds(DIBDRVPHYSDEV *physDev, int *w, int *h)
++{
++ POINT pts[2];
++ pts[0].x = 0;
++ pts[0].y = 0;
++ pts[1].x = *w;
++ pts[1].y = *h;
++ LPtoDP(physDev->hdc, pts, 2);
++ *w = pts[1].x - pts[0].x;
++ *h = pts[1].y - pts[0].y;
++}
++
++/* converts positions from Device space to World space */
++void _DIBDRV_Position_ds2ws(DIBDRVPHYSDEV *physDev, int *x, int *y)
++{
++ POINT p;
++ p.x = *x;
++ p.y = *y;
++ DPtoLP(physDev->hdc, &p, 1);
++ *x = p.x;
++ *y = p.y;
++}
++
++void _DIBDRV_Positions_ds2ws(DIBDRVPHYSDEV *physDev, int *x1, int *y1, int *x2, int *y2)
++{
++ POINT pts[2];
++ pts[0].x = *x1;
++ pts[0].y = *y1;
++ pts[1].x = *x2;
++ pts[1].y = *y2;
++ DPtoLP(physDev->hdc, pts, 2);
++ *x1 = pts[0].x;
++ *y1 = pts[0].y;
++ *x2 = pts[1].x;
++ *y2 = pts[1].y;
++}
++
++/* converts sizes from Device space to World space */
++void _DIBDRV_Sizes_ds2ws(DIBDRVPHYSDEV *physDev, int *w, int *h)
++{
++ POINT pts[2];
++ pts[0].x = 0;
++ pts[0].y = 0;
++ pts[1].x = *w;
++ pts[1].y = *h;
++ DPtoLP(physDev->hdc, pts, 2);
++ *w = pts[1].x - pts[0].x;
++ *h = pts[1].y - pts[0].y;
++}
++
++/***********************************************************************
++ * DIBDRV_Arc
++ */
++BOOL DIBDRV_Arc( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom,
++ int xstart, int ystart, int xend, int yend )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
++ physDev, left, top, right, bottom, xstart, ystart, xend, yend));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pArc(physDev->X11PhysDev, left, top, right, bottom,
++ xstart, ystart, xend, yend);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_Chord
++ */
++BOOL DIBDRV_Chord( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom,
++ int xstart, int ystart, int xend, int yend )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
++ physDev, left, top, right, bottom, xstart, ystart, xend, yend));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pChord(physDev->X11PhysDev, left, top, right, bottom,
++ xstart, ystart, xend, yend);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_Ellipse
++ */
++BOOL DIBDRV_Ellipse( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n",
++ physDev, left, top, right, bottom));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pEllipse(physDev->X11PhysDev, left, top, right, bottom);
++ }
++ return res;
++}
++
++/**********************************************************************
++ * DIBDRV_ExtFloodFill
++ */
++BOOL DIBDRV_ExtFloodFill( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color,
++ UINT fillType )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x, fillType:%d\n",
++ physDev, x, y, color, fillType));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pExtFloodFill(physDev->X11PhysDev, x, y, color, fillType);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_GetDCOrgEx
++ */
++BOOL DIBDRV_GetDCOrgEx( DIBDRVPHYSDEV *physDev, LPPOINT lpp )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, lpp:%p\n", physDev, lpp));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetDCOrgEx(physDev->X11PhysDev, lpp);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_GetPixel
++ */
++COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, int x, int y )
++{
++ COLORREF res;
++
++ MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y));
++
++ if(physDev->hasDIB)
++ {
++ _DIBDRV_Position_ws2ds(physDev, &x, &y);
++ res = physDev->physBitmap->funcs->GetPixel(physDev->physBitmap, x, y);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetPixel(physDev->X11PhysDev, x, y);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_LineTo
++ */
++BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, int x, int y )
++{
++ BOOL res;
++ POINT curPos;
++ RECT *r;
++ int iRec;
++ POINT p1, p2, pc1, pc2;
++
++ MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y));
++
++ if(physDev->hasDIB)
++ {
++ res = FALSE;
++ GetCurrentPositionEx(physDev->hdc, &curPos);
++
++ /* converts position to device space */
++ p1.x = curPos.x; p1.y = curPos.y;
++ p2.x = x; p2.y = y;
++ LPtoDP(physDev->hdc, &p1, 1);
++ LPtoDP(physDev->hdc, &p2, 1);
++
++ /* cycle on all current clipping rectangles */
++ r = physDev->regionRects;
++ for(iRec = 0; iRec < physDev->regionRectCount; iRec++, r++)
++ {
++ _DIBDRV_ResetDashOrigin(physDev);
++
++ /* clipe line on current region area */
++ if(ClipLine(&p1, &p2, r, &pc1, &pc2))
++ {
++ if(pc1.y == pc2.y)
++ physDev->penHLine(physDev, pc1.x, pc2.x, pc1.y);
++ else if(pc1.x == pc2.x)
++ physDev->penVLine(physDev, pc1.x, pc1.y, pc2.y);
++ else
++ physDev->penLine(physDev, pc1.x, pc1.y, pc2.x, pc2.y);
++ res = TRUE;
++ }
++ }
++
++ /* moves current position to next point */
++ MoveToEx(physDev->hdc, x, y, NULL);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pLineTo(physDev->X11PhysDev, x, y);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_PaintRgn
++ */
++BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom);
++BOOL DIBDRV_PaintRgn( DIBDRVPHYSDEV *physDev, HRGN hrgn )
++{
++ BOOL res = FALSE;
++ int i;
++ RECT *rect;
++ RGNDATA *data;
++ int size;
++
++ MAYBE(TRACE("physDev:%p, hrgn:%p\n", physDev, hrgn));
++
++ if(physDev->hasDIB)
++ {
++ /* gets needed region data size */
++ if(!(size = GetRegionData(hrgn, 0, NULL)))
++ goto fin;
++
++ /* allocates buffer and gets actual region data */
++ if(!(data = HeapAlloc(GetProcessHeap(), 0, size)))
++ goto fin;
++ if(!GetRegionData(hrgn, size, data))
++ {
++ HeapFree(GetProcessHeap(), 0, data);
++ goto fin;
++ }
++
++ /* paints the filled rectangles */
++ rect = (RECT *)data->Buffer;
++ for(i = 0; i < data->rdh.nCount; i++)
++ {
++ DIBDRV_Rectangle( physDev, rect->left, rect->top, rect->right, rect->bottom);
++ rect++;
++ }
++ HeapFree( GetProcessHeap(), 0, data );
++ res = TRUE;
++fin:
++ ;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pPaintRgn(physDev->X11PhysDev, hrgn);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_Pie
++ */
++BOOL DIBDRV_Pie( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom,
++ int xstart, int ystart, int xend, int yend )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
++ physDev, left, top, right, bottom, xstart, ystart, xend, yend));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pPie(physDev->X11PhysDev, left, top, right, bottom,
++ xstart, ystart, xend, yend);
++ }
++ return res;
++}
++
++/**********************************************************************
++ * DIBDRV_Polygon
++ */
++BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* ptw, int count )
++{
++ BOOL res;
++ POINT *pt;
++ RECT *r;
++ int iRec;
++ POINT *clipped;
++ int clippedCount;
++ RECT bBox;
++ int ys;
++ POINT *scans;
++ int scanCount, iScan;
++ const POINT *p1, *p2;
++ int iPoint;
++ POINT pc1, pc2;
++
++ MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, ptw, count));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++
++ res = FALSE;
++
++ /* first converts all points to device coords */
++ if(!(pt = HeapAlloc(GetProcessHeap(), 0, sizeof(POINT) * count)))
++ goto fin;
++ memcpy(pt, ptw, sizeof(POINT) * count);
++ LPtoDP(physDev->hdc, pt, count);
++
++ /* cycle on all current clipping rectangles */
++ r = physDev->regionRects;
++ for(iRec = 0; iRec < physDev->regionRectCount; iRec++, r++)
++ {
++ /* filled area */
++ if(ClipPolygon(pt, count, r, &clipped, &clippedCount))
++ {
++ /* gets polygon bounding box -- for ytop and ybottom */
++ PolygonBoundingBox(clipped, clippedCount, &bBox);
++
++ /* gets all ordered intersections of polygon with
++ current scanline */
++ for(ys = bBox.top; ys < bBox.bottom; ys++)
++ {
++ if(ScanPolygon(clipped, clippedCount, ys, &scans, &scanCount))
++ {
++ if(scanCount >= 2)
++ {
++ res = TRUE;
++ p1 = scans;
++ p2 = p1+1;
++ iScan = 0;
++ while(iScan < scanCount - 1)
++ {
++ physDev->brushHLine(physDev, p1->x, p2->x, ys);
++ p1 +=2;
++ p2 +=2;
++ iScan +=2;
++ }
++ }
++ HeapFree(GetProcessHeap(), 0, scans);
++ }
++ }
++ HeapFree(GetProcessHeap(), 0, clipped);
++ }
++
++ /* perimeter -- don't use PolyLine for speed */
++ p2 = pt;
++ for(iPoint = 0; iPoint < count -1; iPoint++)
++ {
++ p1 = p2++;
++ if(ClipLine(p1, p2, r, &pc1, &pc2))
++ {
++ res = TRUE;
++ physDev->penLine(physDev, pc1.x, pc1.y, pc2.x, pc2.y);
++ }
++ }
++ p1 = p2;
++ p2 = pt;
++ if(ClipLine(p1, p2, r, &pc1, &pc2))
++ {
++ res = TRUE;
++ physDev->penLine(physDev, pc1.x, pc1.y, pc2.x, pc2.y);
++ }
++ }
++
++ HeapFree(GetProcessHeap(), 0, pt);
++
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pPolygon(physDev->X11PhysDev, ptw, count);
++ }
++fin:
++ return res;
++}
++
++/**********************************************************************
++ * DIBDRV_Polyline
++ */
++BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* ptw, int count )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, ptw, count));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ POINT *pt;
++ RECT *r;
++ POINT pc1, pc2;
++ int iRec, iPoint;
++
++ if(count < 2)
++ return FALSE;
++ res = FALSE;
++
++ /* first converts all points to device coords */
++ if(!(pt = HeapAlloc(GetProcessHeap(), 0, sizeof(POINT) * count)))
++ return FALSE;
++ memcpy(pt, ptw, sizeof(POINT) * count);
++ LPtoDP(physDev->hdc, pt, count);
++
++ r = physDev->regionRects;
++ for(iRec = 0; iRec < physDev->regionRectCount; iRec++)
++ {
++ const POINT *p2 = pt, *p1;
++ for(iPoint = 0; iPoint < count -1; iPoint++)
++ {
++ p1 = p2++;
++ if(ClipLine(p1, p2, r, &pc1, &pc2))
++ {
++ res = TRUE;
++ physDev->penLine(physDev, pc1.x, pc1.y, pc2.x, pc2.y);
++ }
++ }
++ r++;
++ }
++
++ HeapFree(GetProcessHeap(), 0, pt);
++
++ return res;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pPolyline(physDev->X11PhysDev, ptw, count);
++ }
++ return res;
++}
++
++/**********************************************************************
++ * DIBDRV_PolyPolygon
++ */
++BOOL DIBDRV_PolyPolygon( DIBDRVPHYSDEV *physDev, const POINT* pt, const int* counts, UINT polygons)
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polygons:%d\n", physDev, pt, counts, polygons));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pPolyPolygon(physDev->X11PhysDev, pt, counts, polygons);
++ }
++ return res;
++}
++
++/**********************************************************************
++ * DIBDRV_PolyPolyline
++ */
++BOOL DIBDRV_PolyPolyline( DIBDRVPHYSDEV *physDev, const POINT* pt, const DWORD* counts,
++ DWORD polylines )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polylines:%d\n", physDev, pt, counts, polylines));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pPolyPolyline(physDev->X11PhysDev, pt, counts, polylines);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_Rectangle
++ */
++BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2)
++{
++ BOOL res;
++ int i;
++ RECT rWorld, rDevice, rClipped;
++ RECT *r;
++ int iRec;
++
++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", physDev, x1, y1, x2, y2));
++
++ if(physDev->hasDIB)
++ {
++ res = FALSE;
++
++ OrderInt(&x1, &x2);
++ OrderInt(&y1, &y2);
++
++ /* converts to device space */
++ rWorld.left = x1; rWorld.top = y1; rWorld.right = x2; rWorld.bottom = y2;
++ _DIBDRV_Rect_ws2ds(physDev, &rWorld, &rDevice);
++
++ /* loop on all clip region rectangles */
++ r = physDev->regionRects;
++ for(iRec = 0; iRec < physDev->regionRectCount; iRec++, r++)
++ {
++ /* clips rectangle to current region */
++ if(_DIBDRV_IntersectRect(&rClipped, &rDevice, r))
++ {
++ x1 = rClipped.left; y1 = rClipped.top;
++ x2 = rClipped.right; y2 = rClipped.bottom;
++
++ _DIBDRV_ResetDashOrigin(physDev);
++
++ /* fill the inside, if not null brush */
++ if(physDev->brushStyle != BS_NULL)
++ {
++ if(x2 > x1)
++ for (i = y1; i < y2; i++)
++ physDev->brushHLine(physDev, x1, x2, i);
++ }
++
++ /* draw perimeter, if not null pen */
++ if(physDev->penStyle != PS_NULL)
++ {
++
++ /* particular case where the rectangle
++ degenerates to a line or a point */
++ if(x1 >= x2 - 1)
++ physDev->penVLine(physDev, x1, y1, y2);
++ else if (y1 >= y2 -1)
++ physDev->penHLine(physDev, x1, x2, y1);
++ else
++ {
++ /* Draw the perimeter */
++ physDev->penHLine(physDev, x1 , x2 , y1 );
++ physDev->penHLine(physDev, x1 , x2 , y2 - 1);
++ physDev->penVLine(physDev, x1 , y1 + 1, y2 - 1);
++ physDev->penVLine(physDev, x2 - 1, y1 + 1, y2 - 1);
++ }
++ }
++ res = TRUE;
++ }
++ }
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pRectangle(physDev->X11PhysDev, x1, y1, x2, y2);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_RoundRect
++ */
++BOOL DIBDRV_RoundRect( DIBDRVPHYSDEV *physDev, int left, int top, int right,
++ int bottom, int ell_width, int ell_height )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, ell_width:%d, ell_height:%d\n",
++ physDev, left, top, right, bottom, ell_width, ell_height));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pRoundRect(physDev->X11PhysDev, left, top, right, bottom,
++ ell_width, ell_height);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_SetPixel
++ */
++COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color )
++{
++ COLORREF res;
++ DWORD and, xor;
++
++ MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x\n", physDev, x, y, color));
++
++ if(physDev->hasDIB)
++ {
++ /* get real colorref */
++ color = _DIBDRV_MapColor(physDev, color);
++
++ /* map to pixel color / palette index */
++ color = physDev->physBitmap->funcs->ColorToPixel(physDev->physBitmap, color);
++
++ _DIBDRV_Position_ws2ds(physDev, &x, &y);
++
++ /* gets previous pixel */
++ res = physDev->physBitmap->funcs->GetPixel(physDev->physBitmap, x, y);
++
++ /* calculates AND and XOR from color */
++ _DIBDRV_CalcAndXorMasks(GetROP2(physDev->hdc), color, &and, &xor);
++
++ /* sets the pixel */
++ physDev->physBitmap->funcs->SetPixel(physDev->physBitmap, x, y, and, xor);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSetPixel(physDev->X11PhysDev, x, y, color);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_SetDCOrg
++ */
++DWORD DIBDRV_SetDCOrg( DIBDRVPHYSDEV *physDev, int x, int y )
++{
++ DWORD res;
++
++ MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = 0;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSetDCOrg(physDev->X11PhysDev, x, y);
++ }
++ return res;
++}
+diff -Nru a/dlls/winedib.drv/Makefile.in b/dlls/winedib.drv/Makefile.in
+--- a/dlls/winedib.drv/Makefile.in 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/Makefile.in 2010-08-04 16:08:44.775222017 +0200
+@@ -0,0 +1,40 @@
++TOPSRCDIR = @top_srcdir@
++TOPOBJDIR = ../..
++SRCDIR = @srcdir@
++VPATH = @srcdir@
++EXTRAINCL = @FREETYPEINCL@ @FONTCONFIGINCL@
++EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
++MODULE = winedib.drv
++IMPORTS = user32 gdi32 advapi32 kernel32 ntdll
++
++C_SRCS = \
++ bitblt.c \
++ bitmap.c \
++ bitmaplist.c \
++ clipping.c \
++ convert.c \
++ dc.c \
++ dib.c \
++ dibdrv_main.c \
++ dibdrvbitmap.c \
++ driver.c \
++ font.c \
++ freetype.c \
++ graphics.c \
++ opengl.c \
++ palette.c \
++ pen_brush.c \
++ primitives.c \
++ primitives_bitblt.c \
++ primitives_color.c \
++ primitives_convert.c \
++ primitives_font.c \
++ primitives_line.c \
++ primitives_pixel.c \
++ primitives_rop2.c \
++ primitives_rop3.c \
++ text.c \
++ video.c
++
++@MAKE_DLL_RULES@
++
+diff -Nru a/dlls/winedib.drv/opengl.c b/dlls/winedib.drv/opengl.c
+--- a/dlls/winedib.drv/opengl.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/opengl.c 2010-08-04 16:08:44.478222017 +0200
+@@ -0,0 +1,392 @@
++/*
++ * DIBDRV OpenGL functions
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++#define HPBUFFERARB void *
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++int DIBDRV_ChoosePixelFormat( DIBDRVPHYSDEV *physDev,
++ const PIXELFORMATDESCRIPTOR *ppfd )
++{
++ int res;
++
++ MAYBE(TRACE("physDev:%p, ppfd:%p\n", physDev, ppfd));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pChoosePixelFormat(physDev->X11PhysDev, ppfd);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pChoosePixelFormat(physDev->X11PhysDev, ppfd);
++ }
++ return res;
++}
++
++int DIBDRV_DescribePixelFormat( DIBDRVPHYSDEV *physDev,
++ int iPixelFormat,
++ UINT nBytes,
++ PIXELFORMATDESCRIPTOR *ppfd )
++{
++ int res;
++
++ MAYBE(TRACE("physDev:%p, iPixelFormat:%d, nBytes:%d, ppfd:%p\n", physDev, iPixelFormat, nBytes, ppfd));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pDescribePixelFormat(physDev->X11PhysDev, iPixelFormat, nBytes, ppfd);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pDescribePixelFormat(physDev->X11PhysDev, iPixelFormat, nBytes, ppfd);
++ }
++ return res;
++}
++
++int DIBDRV_GetPixelFormat( DIBDRVPHYSDEV *physDev)
++{
++ int res;
++
++ MAYBE(TRACE("physDev:%p\n", physDev));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pGetPixelFormat(physDev->X11PhysDev);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetPixelFormat(physDev->X11PhysDev);
++ }
++ return res;
++}
++
++BOOL DIBDRV_SetPixelFormat( DIBDRVPHYSDEV *physDev,
++ int iPixelFormat,
++ const PIXELFORMATDESCRIPTOR *ppfd )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pSetPixelFormat(physDev->X11PhysDev, iPixelFormat, ppfd);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSetPixelFormat(physDev->X11PhysDev, iPixelFormat, ppfd);
++ }
++ return res;
++}
++
++BOOL DIBDRV_SwapBuffers( DIBDRVPHYSDEV *physDev )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p\n", physDev));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pSwapBuffers(physDev->X11PhysDev);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSwapBuffers(physDev->X11PhysDev);
++ }
++ return res;
++}
++
++/**
++ * DIBDRV_wglCopyContext
++ *
++ * For OpenGL32 wglCopyContext.
++ */
++BOOL CDECL DIBDRV_wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
++{
++ BOOL res;
++
++ MAYBE(TRACE("hglrcSrc:%p, hglrcDst:%p, mask:%x\n", hglrcSrc, hglrcDst, mask));
++
++ ONCE(FIXME("stub\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglCopyContext(hglrcSrc, hglrcDst, mask);
++
++ return res;
++}
++
++/**
++ * DIBDRV_wglCreateContext
++ *
++ * For OpenGL32 wglCreateContext.
++ */
++HGLRC CDECL DIBDRV_wglCreateContext(DIBDRVPHYSDEV *physDev)
++{
++ HGLRC res;
++
++ MAYBE(TRACE("physDev:%p\n", physDev));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglCreateContext(physDev->X11PhysDev);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pwglCreateContext(physDev->X11PhysDev);
++ }
++ return res;
++}
++
++/**
++ * DIBDRV_wglDeleteContext
++ *
++ * For OpenGL32 wglDeleteContext.
++ */
++BOOL CDECL DIBDRV_wglDeleteContext(HGLRC hglrc)
++{
++ BOOL res;
++
++ MAYBE(TRACE("hglrc:%p\n", hglrc));
++
++ ONCE(FIXME("stub\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglDeleteContext(hglrc);
++ return res;
++}
++
++/**
++ * DIBDRV_wglGetProcAddress
++ *
++ * For OpenGL32 wglGetProcAddress.
++ */
++PROC CDECL DIBDRV_wglGetProcAddress(LPCSTR lpszProc)
++{
++ PROC res;
++
++ MAYBE(TRACE("lpszProc:%p\n", lpszProc));
++
++ ONCE(FIXME("stub\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglGetProcAddress(lpszProc);
++
++ return res;
++}
++
++/**
++ * DIBDRV_wglGetPbufferDCARB
++ *
++ * WGL_ARB_pbuffer: wglGetPbufferDCARB
++ * The function wglGetPbufferDCARB returns a device context for a pbuffer.
++ * Gdi32 implements the part of this function which creates a device context.
++ * This part associates the physDev with the X drawable of the pbuffer.
++ */
++HDC CDECL DIBDRV_wglGetPbufferDCARB(DIBDRVPHYSDEV *physDev, HPBUFFERARB hPbuffer)
++{
++ HDC res;
++
++ MAYBE(TRACE("physDev:%p, hPbuffer:%p\n", physDev, hPbuffer));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglGetPbufferDCARB(physDev->X11PhysDev, hPbuffer);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pwglGetPbufferDCARB(physDev->X11PhysDev, hPbuffer);
++ }
++ return res;
++}
++
++/**
++ * DIBDRV_wglMakeContextCurrentARB
++ *
++ * For OpenGL32 wglMakeContextCurrentARB
++ */
++BOOL CDECL DIBDRV_wglMakeContextCurrentARB(DIBDRVPHYSDEV* pDrawDev, DIBDRVPHYSDEV* pReadDev, HGLRC hglrc)
++{
++ BOOL res;
++
++ MAYBE(TRACE("pDrawDev:%p, pReadDev:%p, hglrc:%p\n", pDrawDev, pReadDev, hglrc));
++
++ if(pDrawDev->hasDIB && pReadDev->hasDIB)
++ {
++ /* DIB section selected both in source and dest DCs, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglMakeContextCurrentARB(pDrawDev->X11PhysDev, pReadDev->X11PhysDev, hglrc);
++ }
++ if(!pDrawDev->hasDIB && !pReadDev->hasDIB)
++ {
++ /* DDB selected both in source and dest DCs, use X11 Driver */
++ res = _DIBDRV_GetDisplayDriver()->pwglMakeContextCurrentARB(pDrawDev->X11PhysDev, pReadDev->X11PhysDev, hglrc);
++ }
++ else if(pDrawDev->hasDIB)
++ {
++ /* DIB selected in pDrawDev, must convert pReadDev to DIB and use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglMakeContextCurrentARB(pDrawDev->X11PhysDev, pReadDev->X11PhysDev, hglrc);
++ }
++ else /* if(pReadDev->hasDIB) */
++ {
++ /* DIB selected in pReadDev, must convert pReadDev to DDB and use X11 Driver */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglMakeContextCurrentARB(pDrawDev->X11PhysDev, pReadDev->X11PhysDev, hglrc);
++ }
++ return res;
++}
++
++/**
++ * DIBDRV_wglMakeCurrent
++ *
++ * For OpenGL32 wglMakeCurrent.
++ */
++BOOL CDECL DIBDRV_wglMakeCurrent(DIBDRVPHYSDEV *physDev, HGLRC hglrc)
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, hglrc:%p\n", physDev, hglrc));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglMakeCurrent(physDev->X11PhysDev, hglrc);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pwglMakeCurrent(physDev->X11PhysDev, hglrc);
++ }
++ return res;
++}
++
++/**
++ * DIBDRV_wglSetPixelFormatWINE
++ *
++ * WGL_WINE_pixel_format_passthrough: wglSetPixelFormatWINE
++ * This is a WINE-specific wglSetPixelFormat which can set the pixel format multiple times.
++ */
++BOOL CDECL DIBDRV_wglSetPixelFormatWINE(DIBDRVPHYSDEV *physDev, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglSetPixelFormatWINE(physDev->X11PhysDev, iPixelFormat, ppfd);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pwglSetPixelFormatWINE(physDev->X11PhysDev, iPixelFormat, ppfd);
++ }
++ return res;
++}
++
++/**
++ * DIBDRV_wglShareLists
++ *
++ * For OpenGL32 wglShareLists.
++ */
++BOOL CDECL DIBDRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2)
++{
++ BOOL res;
++
++ MAYBE(TRACE("hglrc1:%p, hglrc2:%p\n", hglrc1, hglrc2));
++
++ ONCE(FIXME("stub\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglShareLists(hglrc1, hglrc2);
++
++ return res;
++}
++
++/**
++ * DIBDRV_wglUseFontBitmapsA
++ *
++ * For OpenGL32 wglUseFontBitmapsA.
++ */
++BOOL CDECL DIBDRV_wglUseFontBitmapsA(DIBDRVPHYSDEV *physDev, DWORD first, DWORD count, DWORD listBase)
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsA(physDev->X11PhysDev, first, count, listBase);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsA(physDev->X11PhysDev, first, count, listBase);
++ }
++ return res;
++}
++
++/**
++ * DIBDRV_wglUseFontBitmapsW
++ *
++ * For OpenGL32 wglUseFontBitmapsW.
++ */
++BOOL CDECL DIBDRV_wglUseFontBitmapsW(DIBDRVPHYSDEV *physDev, DWORD first, DWORD count, DWORD listBase)
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsW(physDev->X11PhysDev, first, count, listBase);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsW(physDev->X11PhysDev, first, count, listBase);
++ }
++ return res;
++}
+diff -Nru a/dlls/winedib.drv/palette.c b/dlls/winedib.drv/palette.c
+--- a/dlls/winedib.drv/palette.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/palette.c 2010-08-04 16:08:44.691222017 +0200
+@@ -0,0 +1,263 @@
++/*
++ * DIBDRV palette objects
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/* maps a colorref to actual color */
++COLORREF _DIBDRV_MapColor(DIBDRVPHYSDEV *physDev, COLORREF color)
++{
++ WORD index;
++ RGBQUAD *palColor;
++ HPALETTE hPal;
++ PALETTEENTRY paletteEntry;
++
++ switch(color >> 24)
++ {
++ case 0x10 : /* DIBINDEX */
++ MAYBE(TRACE("DIBINDEX Color is %08x\n", color));
++ index = color & 0xffff;
++ if(index >= physDev->physBitmap->colorTableSize)
++ {
++ WARN("DIBINDEX color %d out of range, color table size is %d\n", index, physDev->physBitmap->colorTableSize);
++ return 0;
++ }
++ palColor = physDev->physBitmap->colorTable + index;
++ MAYBE(TRACE("Returning color %08x\n", RGB(palColor->rgbRed, palColor->rgbGreen, palColor->rgbBlue)));
++ return RGB(palColor->rgbRed, palColor->rgbGreen, palColor->rgbBlue);
++
++ case 0x01: /* PALETTEINDEX */
++ MAYBE(TRACE("PALETTEINDEX Color is %08x\n", color));
++ index = color & 0xffff;
++ if(!(hPal = GetCurrentObject(physDev->hdc, OBJ_PAL)))
++ {
++ ERR("Couldn't get palette\n");
++ return 0;
++ }
++ if (!GetPaletteEntries(hPal, index, 1, &paletteEntry))
++ {
++ WARN("PALETTEINDEX(%x) : index %d is out of bounds, assuming black\n", color, index);
++ return 0;
++ }
++ MAYBE(TRACE("Returning color %08x\n", RGB(paletteEntry.peRed, paletteEntry.peGreen, paletteEntry.peBlue)));
++ return RGB(paletteEntry.peRed, paletteEntry.peGreen, paletteEntry.peBlue);
++
++ case 0x02: /* PALETTERGB */
++ return _DIBDRV_GetNearestColor(physDev->physBitmap, color & 0xffffff);
++
++ default:
++ /* RGB color -- we must process special case for monochrome bitmaps */
++ if(physDev->physBitmap->bitCount == 1)
++ {
++ RGBQUAD *back = physDev->physBitmap->colorTable;
++ RGBQUAD *fore = back+1;
++ COLORREF lightColorref, darkColorref;
++
++ /* lightest color is considered to be 'foreground' one, i.e. associated to white color */
++ if(physDev->physBitmap->lightColor == 1)
++ {
++ darkColorref = RGB(back->rgbRed, back->rgbGreen, back->rgbBlue);
++ lightColorref = RGB(fore->rgbRed, fore->rgbGreen, fore->rgbBlue);
++ }
++ else
++ {
++ darkColorref = RGB(fore->rgbRed, fore->rgbGreen, fore->rgbBlue);
++ lightColorref = RGB(back->rgbRed, back->rgbGreen, back->rgbBlue);
++ }
++
++ /* tested on Windows XP -- if present in colortable, maps to corresponding color
++ if not, if white maps to the lightest color, otherwise darkest one. */
++ if(color == lightColorref || color == darkColorref)
++ return color;
++ else if (color == 0x00ffffff)
++ return lightColorref;
++ else
++ return darkColorref;
++ }
++ else
++ return color;
++ }
++}
++
++/***********************************************************************
++ * DIBDRV_RealizePalette
++ */
++UINT DIBDRV_RealizePalette( DIBDRVPHYSDEV *physDev, HPALETTE hpal, BOOL primary )
++{
++ UINT res = 0;
++
++ MAYBE(TRACE("physDev:%p, hpal:%p, primary:%s\n", physDev, hpal, (primary ? "TRUE" : "FALSE")));
++
++ if(physDev && physDev->hasDIB)
++ {
++ /* DIB section selected in, additional (if needed) engine code */
++ ONCE(FIXME("STUB\n"));
++ res = 0;
++ }
++ else
++ {
++ /* we should in any case call X11 function, as UnrealizePalette() doesn't
++ * take a physDev parameter */
++ res = _DIBDRV_GetDisplayDriver()->pRealizePalette(physDev ? physDev->X11PhysDev : NULL, hpal, primary);
++
++ }
++
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_UnrealizePalette
++ */
++BOOL DIBDRV_UnrealizePalette( HPALETTE hpal )
++{
++ BOOL res;
++
++ MAYBE(TRACE("hpal:%p\n", hpal));
++
++ /* we should in any case call X11 function, as UnrealizePalette() doesn't
++ * take a physDev parameter */
++ res = _DIBDRV_GetDisplayDriver()->pUnrealizePalette(hpal);
++
++ /* additional Engine code here, if needed */
++ ONCE(FIXME("STUB\n"));
++
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_GetSystemPaletteEntries
++ */
++UINT DIBDRV_GetSystemPaletteEntries( DIBDRVPHYSDEV *physDev, UINT start, UINT count,
++ LPPALETTEENTRY entries )
++{
++ UINT res;
++
++ MAYBE(TRACE("physDev:%p, start:%d, count:%d, entries:%p\n", physDev, start, count, entries));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = 0;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetSystemPaletteEntries(physDev->X11PhysDev, start, count, entries);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_GetNearestColor
++ */
++COLORREF DIBDRV_GetNearestColor( DIBDRVPHYSDEV *physDev, COLORREF color )
++{
++ COLORREF res;
++
++ MAYBE(TRACE("physDev:%p, color:%x\n", physDev, color));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = 0;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetNearestColor(physDev->X11PhysDev, color);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_RealizeDefaultPalette
++ */
++UINT DIBDRV_RealizeDefaultPalette( DIBDRVPHYSDEV *physDev )
++{
++ UINT res;
++#ifdef DIBDRV_ENABLE_MAYBE
++ int i;
++ RGBQUAD *q;
++#endif
++
++ MAYBE(TRACE("physDev:%p\n", physDev));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ /* HACK - we can't get the dib color table during SelectBitmap since it hasn't
++ been initialized yet. This is called from DC_InitDC so it's a convenient place
++ to grab the color table. */
++ MAYBE(TRACE("Color table size = %d, Color table = %p\n", physDev->physBitmap->colorTableSize, physDev->physBitmap->colorTable));
++ if(!physDev->physBitmap->colorTableGrabbed)
++ {
++ MAYBE(TRACE("Grabbing palette\n"));
++ physDev->physBitmap->colorTable = HeapAlloc(GetProcessHeap(), 0, sizeof(physDev->physBitmap->colorTable[0]) * physDev->physBitmap->colorTableSize);
++ GetDIBColorTable(physDev->hdc, 0, physDev->physBitmap->colorTableSize, physDev->physBitmap->colorTable);
++#ifdef DIBDRV_ENABLE_MAYBE
++ for(i = 0; i < physDev->physBitmap->colorTableSize; i++)
++ {
++ q = physDev->physBitmap->colorTable + i;
++ TRACE(" %03d : R%03d G%03d B%03d\n", i, q->rgbRed, q->rgbGreen, q->rgbBlue);
++ }
++#endif
++ physDev->physBitmap->colorTableGrabbed = TRUE;
++
++ /* for monochrome bitmaps, we need the 'lightest' color */
++ _DIBDRVBITMAP_GetLightestColorIndex(physDev->physBitmap);
++
++ }
++ res = 0;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pRealizeDefaultPalette(physDev->X11PhysDev);
++ }
++ return res;
++}
++
++BOOL DIBDRV_GetICMProfile(DIBDRVPHYSDEV *physDev, LPDWORD lpcbName, LPWSTR lpszFilename)
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, lpcpName:%p, lpszFilename:%p\n", physDev, lpcbName, lpszFilename));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++
++ res = 0;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetICMProfile(physDev->X11PhysDev, lpcbName, lpszFilename);
++ }
++ return res;
++}
+diff -Nru a/dlls/winedib.drv/pen_brush.c b/dlls/winedib.drv/pen_brush.c
+--- a/dlls/winedib.drv/pen_brush.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/pen_brush.c 2010-08-04 16:08:44.761222017 +0200
+@@ -0,0 +1,667 @@
++/*
++ * DIBDRV pen objects
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++
++static const DASHPATTERN dashPatterns[4] =
++{
++ {2, {18, 6}},
++ {2, {3, 3}},
++ {4, {9, 6, 3, 6}},
++ {6, {9, 3, 3, 3, 3, 3}}
++};
++
++static inline void OrderEndPoints(int *s, int *e)
++{
++ if(*s > *e)
++ {
++ int tmp;
++ tmp = *s + 1;
++ *s = *e + 1;
++ *e = tmp;
++ }
++}
++
++static void SolidPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y)
++{
++ OrderEndPoints(&x1, &x2);
++ physDev->physBitmap->funcs->SolidHLine(physDev->physBitmap, x1, x2, y, physDev->penAnd, physDev->penXor);
++}
++
++static void SolidPenVLine(DIBDRVPHYSDEV *physDev, int x, int y1, int y2)
++{
++ OrderEndPoints(&y1, &y2);
++ physDev->physBitmap->funcs->SolidVLine(physDev->physBitmap, x, y1, y2, physDev->penAnd, physDev->penXor);
++}
++
++static void WINAPI SolidPenLineCallback(int x, int y, LPARAM lparam)
++{
++ DIBDRVPHYSDEV *physDev = (DIBDRVPHYSDEV *)lparam;
++
++ physDev->physBitmap->funcs->SetPixel(physDev->physBitmap, x, y, physDev->penAnd, physDev->penXor);
++ return;
++}
++
++static void SolidPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2)
++{
++ LineDDA(x1, y1, x2, y2, SolidPenLineCallback, (LPARAM)physDev);
++}
++
++static inline void GetDashColors(DIBDRVPHYSDEV *physDev, DWORD *and, DWORD *xor)
++{
++ if(physDev->markSpace == mark)
++ {
++ *and = physDev->penAnd;
++ *xor = physDev->penXor;
++ }
++ else if(GetBkMode(physDev->hdc) == OPAQUE)
++ {
++ *and = physDev->backgroundAnd;
++ *xor = physDev->backgroundXor;
++ }
++ else
++ {
++ *and = 0xffffffff;
++ *xor = 0;
++ }
++}
++
++static inline void NextDash(DIBDRVPHYSDEV *physDev)
++{
++ if(physDev->leftInDash != 0)
++ return;
++
++ physDev->curDash++;
++ if(physDev->curDash == physDev->penPattern->count)
++ physDev->curDash = 0;
++ physDev->leftInDash = physDev->penPattern->dashes[physDev->curDash];
++ if(physDev->markSpace == mark)
++ physDev->markSpace = space;
++ else
++ physDev->markSpace = mark;
++}
++
++static void DashedPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y)
++{
++ int x = x1;
++ DWORD and, xor;
++ DWORD dashLen;
++
++ if(x1 <= x2)
++ {
++ while(x != x2)
++ {
++ GetDashColors(physDev, &and, &xor);
++
++ dashLen = physDev->leftInDash;
++ if(x + dashLen > x2)
++ dashLen = x2 - x;
++
++ physDev->physBitmap->funcs->SolidHLine(physDev->physBitmap, x, x + dashLen, y, and, xor);
++ x += dashLen;
++
++ physDev->leftInDash -= dashLen;
++ NextDash(physDev);
++ }
++ }
++ else
++ {
++ while(x != x2)
++ {
++ GetDashColors(physDev, &and, &xor);
++
++ dashLen = physDev->leftInDash;
++ if(x - (int)dashLen < x2)
++ dashLen = x - x2;
++
++ physDev->physBitmap->funcs->SolidHLine(physDev->physBitmap, x - dashLen + 1, x + 1, y, and, xor);
++ x -= dashLen;
++
++ physDev->leftInDash -= dashLen;
++ NextDash(physDev);
++ }
++ }
++}
++
++static void DashedPenVLine(DIBDRVPHYSDEV *physDev, int x, int y1, int y2)
++{
++ int y = y1;
++ DWORD and, xor;
++ DWORD dashLen;
++
++ if(y1 <= y2)
++ {
++ while(y != y2)
++ {
++ GetDashColors(physDev, &and, &xor);
++
++ dashLen = physDev->leftInDash;
++ if(y + dashLen > y2)
++ dashLen = y2 - y;
++
++ physDev->physBitmap->funcs->SolidVLine(physDev->physBitmap, x, y, y + dashLen, and, xor);
++ y += dashLen;
++
++ physDev->leftInDash -= dashLen;
++ NextDash(physDev);
++ }
++ }
++ else
++ {
++ while(y != y2)
++ {
++ GetDashColors(physDev, &and, &xor);
++
++ dashLen = physDev->leftInDash;
++ if(y - (int)dashLen < y2)
++ dashLen = y - y2;
++
++ physDev->physBitmap->funcs->SolidVLine(physDev->physBitmap, x, y - dashLen + 1, y + 1, and, xor);
++ y -= dashLen;
++
++ physDev->leftInDash -= dashLen;
++ NextDash(physDev);
++ }
++ }
++}
++
++static void WINAPI DashedPenLineCallback(int x, int y, LPARAM lparam)
++{
++ DIBDRVPHYSDEV *physDev = (DIBDRVPHYSDEV *)lparam;
++ DWORD and, xor;
++
++ GetDashColors(physDev, &and, &xor);
++
++ physDev->physBitmap->funcs->SetPixel(physDev->physBitmap, x, y, and, xor);
++
++ physDev->leftInDash--;
++ NextDash(physDev);
++
++ return;
++}
++
++static void DashedPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2)
++{
++ LineDDA(x1, y1, x2, y2, DashedPenLineCallback, (LPARAM)physDev);
++}
++
++void _DIBDRV_ResetDashOrigin(DIBDRVPHYSDEV *physDev)
++{
++ physDev->curDash = 0;
++ if(physDev->penPattern)
++ physDev->leftInDash = physDev->penPattern->dashes[0];
++ physDev->markSpace = mark;
++}
++
++#if 0
++/* For 1bpp bitmaps, unless the selected foreground color exactly
++ matches foreground's colortable OR it's the WHITE color,
++ the background color is used -- tested on WinXP */
++static DWORD AdjustFgColor(DIBDRVPHYSDEV *physDev, COLORREF color)
++{
++ RGBQUAD *back = physDev->physBitmap->colorTable;
++ RGBQUAD *fore = physDev->physBitmap->colorTable+1;
++
++ if(
++ fore->rgbRed == GetRValue(color) &&
++ fore->rgbGreen == GetGValue(color) &&
++ fore->rgbBlue == GetBValue(color))
++ return 1;
++ else if(
++ back->rgbRed == GetRValue(color) &&
++ back->rgbGreen == GetGValue(color) &&
++ back->rgbBlue == GetBValue(color))
++ return 0;
++ else if((color & 0x00ffffff) == 0x00ffffff)
++ return 1;
++ else
++ return 0;
++}
++
++static void FixupFgColors1(DIBDRVPHYSDEV *physDev)
++{
++ int rop = GetROP2(physDev->hdc);
++
++ physDev->penColor = AdjustFgColor(physDev, physDev->penColorref);
++ physDev->brushColor = AdjustFgColor(physDev, physDev->brushColorref);
++
++ _DIBDRV_CalcAndXorMasks(rop, physDev->penColor, &physDev->penAnd, &physDev->penXor);
++ _DIBDRV_CalcAndXorMasks(rop, physDev->brushColor, &physDev->brushAnd, &physDev->brushXor);
++ HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
++ HeapFree(GetProcessHeap(), 0, physDev->brushXors);
++ physDev->brushAnds = NULL;
++ physDev->brushXors = NULL;
++}
++#endif
++
++#if 0
++/* For 1bpp bitmaps, unless the selected foreground color exactly
++ matches one of the colors in the colortable, then the color that
++ isn't the bkgnd color is used. */
++static DWORD AdjustFgColor(DIBDRVPHYSDEV *physDev, COLORREF color)
++{
++ RGBQUAD rgb;
++ int i;
++
++ rgb.rgbRed = GetRValue(color);
++ rgb.rgbGreen = GetGValue(color);
++ rgb.rgbBlue = GetBValue(color);
++
++ for(i = 0; i < physDev->physBitmap->colorTableSize; i++)
++ {
++ RGBQUAD *cur = physDev->physBitmap->colorTable + i;
++ if((rgb.rgbRed == cur->rgbRed) && (rgb.rgbGreen == cur->rgbGreen) && (rgb.rgbBlue == cur->rgbBlue))
++ return i;
++ }
++ return ~physDev->backgroundColor & 1;
++}
++
++static void FixupFgColors1(DIBDRVPHYSDEV *physDev)
++{
++ int rop = GetROP2(physDev->hdc);
++
++ physDev->penColor = AdjustFgColor(physDev, physDev->penColorref);
++ physDev->brushColor = AdjustFgColor(physDev, physDev->brushColorref);
++
++ _DIBDRV_CalcAndXorMasks(rop, physDev->penColor, &physDev->penAnd, &physDev->penXor);
++ _DIBDRV_CalcAndXorMasks(rop, physDev->brushColor, &physDev->brushAnd, &physDev->brushXor);
++ HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
++ HeapFree(GetProcessHeap(), 0, physDev->brushXors);
++ physDev->brushAnds = NULL;
++ physDev->brushXors = NULL;
++}
++#endif
++
++static void SolidBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y)
++{
++ OrderEndPoints(&x1, &x2);
++ physDev->physBitmap->funcs->SolidHLine(physDev->physBitmap, x1, x2, y, physDev->brushAnd, physDev->brushXor);
++}
++
++
++static void GenerateMasks(DIBDRVPHYSDEV *physDev, DIBDRVBITMAP *bmp, DWORD **and, DWORD **xor)
++{
++ int rop = GetROP2(physDev->hdc);
++ DWORD *color_ptr, *and_ptr, *xor_ptr;
++ DWORD size = bmp->height * abs(bmp->stride);
++
++ *and = HeapAlloc(GetProcessHeap(), 0, size);
++ *xor = HeapAlloc(GetProcessHeap(), 0, size);
++
++ color_ptr = bmp->bits;
++ and_ptr = *and;
++ xor_ptr = *xor;
++
++ while(size)
++ {
++ _DIBDRV_CalcAndXorMasks(rop, *color_ptr++, and_ptr++, xor_ptr++);
++ size -= 4;
++ }
++}
++
++static void PatternBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y)
++{
++ DWORD *and, *xor, brushY = y % physDev->brushBitmap->height;
++
++ if(!physDev->brushAnds)
++ GenerateMasks(physDev, physDev->brushBitmap, &physDev->brushAnds, &physDev->brushXors);
++
++ OrderEndPoints(&x1, &x2);
++ and = (DWORD *)((char *)physDev->brushAnds + brushY * physDev->brushBitmap->stride);
++ xor = (DWORD *)((char *)physDev->brushXors + brushY * physDev->brushBitmap->stride);
++
++ physDev->physBitmap->funcs->PatternHLine(physDev->physBitmap, x1, x2, y, and, xor, physDev->brushBitmap->width, x1 % physDev->brushBitmap->width);
++}
++
++/* null function for PS_NULL and BS_NULL pen and brush styles */
++void NullPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) {}
++void NullPenVLine(DIBDRVPHYSDEV *physDev, int x, int y1, int y2) {}
++void NullPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2) {}
++void NullBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) {}
++
++/***********************************************************************
++ * DIBDRV_SelectPen
++ */
++HPEN DIBDRV_SelectPen( DIBDRVPHYSDEV *physDev, HPEN hpen )
++{
++ HPEN res;
++ LOGPEN logpen;
++
++ MAYBE(TRACE("physDev:%p, hpen:%p\n", physDev, hpen));
++
++ if(physDev->hasDIB)
++ {
++ GetObjectW(hpen, sizeof(logpen), &logpen);
++
++ physDev->penColorref = logpen.lopnColor;
++ physDev->penColor = physDev->physBitmap->funcs->ColorToPixel(
++ physDev->physBitmap,
++ _DIBDRV_MapColor(physDev, physDev->penColorref));
++
++ _DIBDRV_CalcAndXorMasks(GetROP2(physDev->hdc), physDev->penColor, &physDev->penAnd, &physDev->penXor);
++
++ physDev->penStyle = logpen.lopnStyle;
++ switch(logpen.lopnStyle)
++ {
++ default:
++ ONCE(FIXME("Unhandled pen style %d\n", logpen.lopnStyle));
++ physDev->penStyle = PS_SOLID;
++ /* fall through */
++ case PS_SOLID:
++ physDev->penHLine = SolidPenHLine;
++ physDev->penVLine = SolidPenVLine;
++ physDev->penLine = SolidPenLine;
++ physDev->penPattern = NULL;
++ break;
++
++ case PS_DASH:
++ case PS_DOT:
++ case PS_DASHDOT:
++ case PS_DASHDOTDOT:
++ physDev->penHLine = DashedPenHLine;
++ physDev->penVLine = DashedPenVLine;
++ physDev->penLine = DashedPenLine;
++ physDev->penPattern = &dashPatterns[logpen.lopnStyle - PS_DASH];
++ _DIBDRV_ResetDashOrigin(physDev);
++ break;
++ case PS_NULL:
++ physDev->penHLine = NullPenHLine;
++ physDev->penVLine = NullPenVLine;
++ physDev->penLine = NullPenLine;
++ physDev->penPattern = NULL;
++ break;
++ }
++ res = hpen;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSelectPen(physDev->X11PhysDev, hpen);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_SetDCPenColor
++ */
++COLORREF DIBDRV_SetDCPenColor( DIBDRVPHYSDEV *physDev, COLORREF crColor )
++{
++ COLORREF res;
++
++ MAYBE(TRACE("physDev:%p, crColor:%x\n", physDev, crColor));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = crColor;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSetDCPenColor(physDev->X11PhysDev, crColor);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_SelectBrush
++ */
++HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush )
++{
++ HBRUSH res = hbrush;
++ LOGBRUSH logbrush;
++
++
++ MAYBE(TRACE("physDev:%p, hbrush:%p\n", physDev, hbrush));
++
++ if(physDev->hasDIB)
++ {
++ GetObjectW(hbrush, sizeof(logbrush), &logbrush);
++
++ /* frees any currently selected DIB brush and cache */
++ _DIBDRVBITMAP_Free(physDev->brushBitmap);
++ physDev->brushBitmap = NULL;
++ _DIBDRVBITMAP_Free(physDev->brushBmpCache);
++ physDev->brushBmpCache = NULL;
++ if(physDev->brushAnds)
++ {
++ HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
++ HeapFree(GetProcessHeap(), 0, physDev->brushXors);
++ }
++ physDev->brushAnds = NULL;
++ physDev->brushXors = NULL;
++
++ switch (logbrush.lbStyle)
++ {
++ default:
++ FIXME("Unhandled brush style %d\n", logbrush.lbStyle);
++ physDev->brushColorref = 0;
++ goto solid;
++
++ case BS_SOLID:
++ physDev->brushColorref = logbrush.lbColor;
++ solid:
++ MAYBE(TRACE("SOLID Pattern -- color is %x\n", physDev->brushColorref));
++ physDev->brushStyle = BS_SOLID;
++ physDev->brushHLine = SolidBrushHLine;
++
++ physDev->brushColor = physDev->physBitmap->funcs->ColorToPixel(
++ physDev->physBitmap,
++ _DIBDRV_MapColor(physDev, physDev->brushColorref));
++
++ _DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->brushColor,
++ &physDev->brushAnd, &physDev->brushXor);
++
++ /* set the physDev brush style */
++ physDev->brushStyle = BS_SOLID;
++ physDev->isBrushBitmap = FALSE;
++
++ break;
++
++ case BS_DIBPATTERN8X8:
++ case BS_DIBPATTERN:
++ {
++ DIBDRVBITMAP src;
++ BITMAPINFO *bmi;
++
++ FIXME("DIB Pattern\n");
++
++ /* if no DIB selected in, fallback to null brush */
++ if(!physDev->physBitmap->bits)
++ {
++ physDev->brushColorref = 0;
++ goto solid;
++ }
++
++ /* gets brush DIB's pointer */
++ bmi = GlobalLock((HGLOBAL)logbrush.lbHatch);
++
++ /* initializes a temporary DIB with brush's one */
++ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&src, bmi, NULL))
++ {
++ ERR("Failed to initialize brush DIB\n");
++ res = 0;
++ goto err;
++ }
++
++ /* converts brush bitmap to match currently selected one's format */
++ if(!_DIBDRVBITMAP_Convert(physDev->brushBitmap, &src, physDev->physBitmap))
++ {
++ ERR("Failed to convert brush DIB\n");
++ _DIBDRVBITMAP_Free(&src);
++ res = 0;
++ goto err;
++ }
++
++ /* frees temporary DIB's data */
++ _DIBDRVBITMAP_Free(&src);
++
++ /* use DIB pattern for brush lines */
++ physDev->brushHLine = PatternBrushHLine;
++
++ err:
++ /* frees brush's DIB pointer */
++ GlobalUnlock((HGLOBAL)logbrush.lbHatch);
++
++ break;
++ }
++ case BS_DIBPATTERNPT:
++ FIXME("BS_DIBPATTERNPT not supported\n");
++ physDev->brushColorref = 0;
++ goto solid;
++
++ case BS_HATCHED:
++ FIXME("BS_HATCHED not supported\n");
++ physDev->brushColorref = 0;
++ goto solid;
++
++ case BS_NULL:
++ {
++ MAYBE(TRACE("NULL Pattern\n"));
++ physDev->brushColorref = 0;
++ physDev->brushColor = physDev->physBitmap->funcs->ColorToPixel(
++ physDev->physBitmap,
++ _DIBDRV_MapColor(physDev, 0));
++ physDev->brushHLine = NullBrushHLine;
++ break;
++ }
++
++ case BS_PATTERN:
++ case BS_PATTERN8X8:
++ FIXME("BS_PATTERN not supported\n");
++ physDev->brushColorref = 0;
++ goto solid;
++ }
++
++ MAYBE(TRACE("END\n"));
++ return hbrush;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++
++ /* we must check if a DIB pattern is requested */
++ GetObjectW(hbrush, sizeof(logbrush), &logbrush);
++ switch (logbrush.lbStyle)
++ {
++ case BS_DIBPATTERN8X8:
++ case BS_DIBPATTERN:
++ case BS_DIBPATTERNPT:
++ FIXME("A DIB pattern was requested for a DDB bitmap\n");
++ break;
++
++ case BS_SOLID:
++ case BS_HATCHED:
++ case BS_NULL:
++ case BS_PATTERN:
++ case BS_PATTERN8X8:
++ default:
++ break;
++ }
++ res = _DIBDRV_GetDisplayDriver()->pSelectBrush(physDev->X11PhysDev, hbrush);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_SetDCBrushColor
++ */
++COLORREF DIBDRV_SetDCBrushColor( DIBDRVPHYSDEV *physDev, COLORREF crColor )
++{
++ COLORREF res;
++
++ MAYBE(TRACE("physDev:%p, crColor:%x\n", physDev, crColor));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = crColor;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSetDCBrushColor(physDev->X11PhysDev, crColor);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * SetROP2
++ */
++int DIBDRV_SetROP2( DIBDRVPHYSDEV *physDev, int rop )
++{
++ int prevRop;
++
++ MAYBE(TRACE("physDev:%p, rop:%x\n", physDev, rop));
++
++ prevRop = physDev->rop2;
++ physDev->rop2 = rop;
++
++ if(prevRop != rop)
++ {
++ _DIBDRV_CalcAndXorMasks(rop, physDev->penColor, &physDev->penAnd, &physDev->penXor);
++ _DIBDRV_CalcAndXorMasks(rop, physDev->brushColor, &physDev->brushAnd, &physDev->brushXor);
++ _DIBDRV_CalcAndXorMasks(rop, physDev->backgroundColor, &physDev->backgroundAnd, &physDev->backgroundXor);
++ if(physDev->brushAnds)
++ {
++ HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
++ HeapFree(GetProcessHeap(), 0, physDev->brushXors);
++ }
++ physDev->brushAnds = NULL;
++ physDev->brushXors = NULL;
++ }
++
++ return prevRop;
++ /* note : X11 Driver don't have SetROP2() function exported */
++}
++
++/***********************************************************************
++ * SetBkColor
++ */
++COLORREF DIBDRV_SetBkColor( DIBDRVPHYSDEV *physDev, COLORREF color )
++{
++ COLORREF res;
++
++ MAYBE(TRACE("physDev:%p, color:%x\n", physDev, color));
++
++ if(physDev->hasDIB)
++ {
++ physDev->backgroundColor = _DIBDRV_MapColor(physDev, color);
++ physDev->backgroundColor = physDev->physBitmap->funcs->ColorToPixel(physDev->physBitmap, physDev->backgroundColor);
++
++ _DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->backgroundColor, &physDev->backgroundAnd, &physDev->backgroundXor);
++
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSetBkColor(physDev->X11PhysDev, color);
++ }
++ return res;
++}
+diff -Nru a/dlls/winedib.drv/primitives_bitblt.c b/dlls/winedib.drv/primitives_bitblt.c
+--- a/dlls/winedib.drv/primitives_bitblt.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/primitives_bitblt.c 2010-08-04 16:08:44.792222017 +0200
+@@ -0,0 +1,1401 @@
++/*
++ * DIB Engine BitBlt Primitives
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++static inline COLORREF SwapColors(DWORD c)
++{
++ return ((c & 0x0000ff) << 16) | (c & 0x00ff00) | ((c & 0xff0000) >> 16);
++
++}
++
++/* shrinks a line -- srcWidth >= dstWidth */
++static void ShrinkLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
++{
++ int srcPos, dstPos;
++ int delta;
++
++ srcPos = 0;
++ dstPos = 0;
++ delta = 0;
++ while(dstPos < dstWidth)
++ {
++ *dst++ = *src;
++ while(delta < srcWidth)
++ {
++ srcPos++;
++ src++;
++ delta += dstWidth;
++ }
++ delta -= srcWidth;
++ dstPos++;
++ }
++}
++
++/* expands a line -- srcWidth <= dstWidth */
++static void ExpandLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
++{
++ int srcPos;
++ int delta;
++
++ srcPos = 0;
++ delta = 0;
++ while(srcPos < srcWidth)
++ {
++ while(delta < dstWidth)
++ {
++ *dst++ = *src;
++ delta += srcWidth;
++ }
++ delta -= dstWidth;
++ src++;
++ srcPos++;
++ }
++}
++
++/* stretch a line */
++static void StretchLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
++{
++ if(srcWidth > dstWidth)
++ ShrinkLine(dst, dstWidth, src, srcWidth);
++ else if(srcWidth < dstWidth)
++ ExpandLine(dst, dstWidth, src, srcWidth);
++ else
++ memcpy(dst, src, 4 * srcWidth);
++}
++
++/* premultiply alpha channel on a line by a constant alpha
++ note : it seems that pixels are already premultiplied
++ by alpha channel content */
++static void PemultiplyLine(DWORD *dst, int width, BYTE constAlpha, BOOL hasAlpha)
++{
++ int i = width;
++ BYTE *alphaPnt = (BYTE *)dst + 3;
++
++ /* small optimization for 0 and 255 values of constAlpha */
++
++ /* fully transparent -- just sets all pix to 0 */
++ if(constAlpha == 0)
++ {
++ while(i--)
++ *dst++ = 0;
++ return;
++ }
++
++ /* fully opaque, just do nothing */
++ if(constAlpha == 255)
++ {
++ if(!hasAlpha)
++ while(i--)
++ {
++ *alphaPnt = 0xff;
++ alphaPnt += 4;
++ }
++ return;
++ }
++
++ /* intermediate -- premultiply alpha values */
++ if(hasAlpha)
++ while(i--)
++ {
++ *alphaPnt = MulDiv(*alphaPnt, constAlpha, 255);
++ alphaPnt += 4;
++ }
++ else
++ while(i--)
++ {
++ *alphaPnt = constAlpha;
++ alphaPnt += 4;
++ }
++ return;
++
++}
++
++/* alpha blends a source line onto a destination line
++ preconditions :
++ 1) source and dest widths must be the same
++ 2) source line should be already premultiplied by constant alpha */
++static void BlendLine(DWORD *dst, DWORD *src, int width)
++{
++ int i = width;
++ BYTE *blueDst = (BYTE *)dst;
++ BYTE *greenDst = blueDst + 1;
++ BYTE *redDst = greenDst + 1;
++ BYTE *alphaDst = redDst + 1;
++ BYTE *blueSrc = (BYTE *)src;
++ BYTE *greenSrc = blueSrc + 1;
++ BYTE *redSrc = greenSrc + 1;
++ BYTE *alphaSrc = redSrc + 1;
++ BYTE alpha;
++
++ /* still don't know if it must take in account an eventual dest
++ alpha channel..... */
++ while(i--)
++ {
++ alpha = 255 - *alphaSrc;
++
++ *blueDst = *blueSrc + MulDiv(*blueDst, alpha, 255);
++ *greenDst = *greenSrc + MulDiv(*greenDst, alpha, 255);
++ *redDst = *redSrc + MulDiv(*redDst, alpha, 255);
++ *alphaDst = *alphaSrc + MulDiv(*alphaDst, alpha, 255);
++
++ blueSrc += 4;
++ greenSrc += 4;
++ redSrc += 4;
++ alphaSrc += 4;
++ blueDst += 4;
++ greenDst += 4;
++ redDst += 4;
++ alphaDst += 4;
++ }
++
++}
++
++/* ------------------------------------------------------------*/
++/* ALPHABLEND PRIMITIVES */
++BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFn)
++{
++ /* flags indicating wether source should be stretched */
++ BOOL horStretch = (widthSrc != widthDst);
++ BOOL verStretch = (heightSrc != heightDst);
++
++ /* constant alpha value */
++ BYTE constAlpha = blendFn.SourceConstantAlpha;
++
++ /* checks wether source has alpha channel */
++ BOOL hasAlpha = blendFn.AlphaFormat & AC_SRC_ALPHA;
++
++ /* source and dest bitmaps */
++ const DIBDRVBITMAP *srcBmp = physDevSrc->physBitmap;
++ DIBDRVBITMAP *dstBmp = physDevDst->physBitmap;
++
++ /* source and destination line buffers */
++ DWORD *sBuf = HeapAlloc(GetProcessHeap(), 0, abs(srcBmp->stride));
++ DWORD *dBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
++
++ int ys = ySrc;
++ int yd = yDst;
++ int iLine;
++ int delta;
++
++ /* in order to optimize a bit, we divide the routine in 4 parts,
++ depending on stretching modes */
++ if(!horStretch && !verStretch)
++ {
++ /* simplest case, no stretching needed */
++ MAYBE(TRACE("No stretching\n"));
++ for(iLine = 0; iLine < heightSrc; iLine++, ys++, yd++)
++ {
++ /* load source and dest lines */
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
++
++ /* premultiply source by constant and pixel alpha */
++ PemultiplyLine(sBuf, widthSrc, constAlpha, hasAlpha);
++
++ /* blends source on dest */
++ BlendLine(dBuf, sBuf, widthSrc);
++
++ /* puts dest line back */
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ }
++ }
++ else if (horStretch && !verStretch)
++ {
++ /* just horizontal stretching needed */
++ DWORD *strBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
++ MAYBE(TRACE("Horizontal stretching\n"));
++
++ for(iLine = 0; iLine < heightSrc; iLine++, ys++, yd++)
++ {
++ /* load source and dest lines */
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
++
++ /* stretch source line to match dest one */
++ StretchLine(strBuf, widthDst, sBuf, widthSrc);
++
++ /* premultiply source by constant and pixel alpha */
++ PemultiplyLine(strBuf, widthDst, constAlpha, hasAlpha);
++
++ /* blends source on dest */
++ BlendLine(dBuf, strBuf, widthDst);
++
++ /* puts dest line back */
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ }
++ HeapFree(GetProcessHeap(), 0, strBuf);
++ }
++ else if (!horStretch && verStretch)
++ {
++ /* just vertical stretching needed */
++ MAYBE(TRACE("Vertical stretching\n"));
++
++ if(heightSrc > heightDst)
++ {
++ iLine = 0;
++ delta = 0;
++ while(iLine < heightDst)
++ {
++ /* load source and dest lines */
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
++
++ /* premultiply source by constant and pixel alpha */
++ PemultiplyLine(sBuf, widthSrc, constAlpha, hasAlpha);
++
++ /* blends source on dest */
++ BlendLine(dBuf, sBuf, widthDst);
++
++ /* puts dest line back */
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++
++ while(delta < heightSrc)
++ {
++ ys++;
++ delta += heightDst;
++ }
++ delta -= heightSrc;
++ yd++;
++ iLine++;
++ }
++ }
++ else if(heightSrc < heightDst)
++ {
++ iLine = 0;
++ delta = 0;
++ while(iLine < heightSrc)
++ {
++ /* load source line */
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
++
++ /* premultiply source by constant and pixel alpha */
++ PemultiplyLine(sBuf, widthSrc, constAlpha, hasAlpha);
++
++ while(delta < heightDst)
++ {
++ /* load dest line */
++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
++
++ /* blends source on dest */
++ BlendLine(dBuf, sBuf, widthDst);
++
++ /* puts dest line back */
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ yd++;
++ delta += heightSrc;
++ }
++ delta -= heightDst;
++ ys++;
++ iLine++;
++ }
++ }
++ }
++ else
++ {
++ DWORD *strBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride));
++ /* both stretching needed -- generic case */
++ MAYBE(TRACE("Horizontal and vertical stretching\n"));
++
++ if(heightSrc > heightDst)
++ {
++ iLine = 0;
++ delta = 0;
++ while(iLine < heightDst)
++ {
++ /* load source and dest lines */
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
++
++ /* stretch source line to match dest one */
++ StretchLine(strBuf, widthDst, sBuf, widthSrc);
++
++ /* premultiply source by constant and pixel alpha */
++ PemultiplyLine(strBuf, widthDst, constAlpha, hasAlpha);
++
++ /* blends source on dest */
++ BlendLine(dBuf, strBuf, widthDst);
++
++ /* puts dest line back */
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++
++ while(delta < heightSrc)
++ {
++ ys++;
++ delta += heightDst;
++ }
++ delta -= heightSrc;
++ yd++;
++ iLine++;
++ }
++ }
++ else if(heightSrc < heightDst)
++ {
++ iLine = 0;
++ delta = 0;
++ while(iLine < heightSrc)
++ {
++ /* load source line */
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf);
++
++ /* stretch source line to match dest one */
++ StretchLine(strBuf, widthDst, sBuf, widthSrc);
++
++ /* premultiply source by constant and pixel alpha */
++ PemultiplyLine(strBuf, widthDst, constAlpha, hasAlpha);
++
++ while(delta < heightDst)
++ {
++ /* load dest line */
++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf);
++
++ /* blends source on dest */
++ BlendLine(dBuf, strBuf, widthDst);
++
++ /* puts dest line back */
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ yd++;
++ delta += heightSrc;
++ }
++ delta -= heightDst;
++ ys++;
++ iLine++;
++ }
++ }
++ HeapFree(GetProcessHeap(), 0, strBuf);
++ }
++
++ HeapFree(GetProcessHeap(), 0, sBuf);
++ HeapFree(GetProcessHeap(), 0, dBuf);
++ return TRUE;
++}
++
++/* ------------------------------------------------------------*/
++/* BLITTING PRIMITIVES */
++BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, DWORD rop)
++{
++ int ys, yd;
++ int i;
++ DWORD *dwBuf;
++ DIBDRVBITMAP *dstBmp, *patBmp;
++ const DIBDRVBITMAP *srcBmp;
++ DWORD *wDstPnt, *wSrcPnt, *wPatPnt;
++ BOOL usePat, useSrc, useDst;
++ DWORD patColor;
++ BOOL res = FALSE;
++
++ /* 32 bit RGB source and destination buffer, if needed */
++ DWORD *sBuf = 0, *dBuf = 0, *pBuf = 0;
++
++ /* get elements usage */
++ usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
++ useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
++ useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
++
++ /* sanity check -- MSN messenger crashes without */
++ if(useSrc && !physDevSrc)
++ return FALSE;
++
++ /* gets source, dest and pattern bitmaps, if available */
++ if(usePat && physDevDst->isBrushBitmap)
++ patBmp = physDevDst->brushBmpCache;
++ else
++ patBmp = NULL;
++
++ if(useSrc)
++ srcBmp = physDevSrc->physBitmap;
++ else
++ srcBmp = NULL;
++ dstBmp = physDevDst->physBitmap;
++
++ /* gets pattern color, in case it's needed
++ it's NOT the COLORREF value (colors are swapped
++ NOR the pixel value (it's applied to a 32 BPP BI_RGB */
++ if(usePat)
++ patColor = SwapColors(physDevDst->brushColorref);
++ else
++ patColor = 0;
++
++ /* allocate 32 bit RGB destination buffer */
++ if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, width * 4)))
++ goto error;
++
++ MAYBE(TRACE("dstBmp:%p(%s), xDst:%d, yDst:%d, width:%d, height:%d, srcBmp:%p(%s), xSrc:%d, ySrc:%d, rop:%8x\n",
++ dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, width, height,
++ srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, rop));
++
++ /* some simple ROPs optimizations */
++ switch(rop)
++ {
++ case BLACKNESS:
++ MAYBE(TRACE("BLACKNESS\n"));
++ memset(dBuf, 0x00, width * 4);
++ for(yd = yDst; yd < yDst+height; yd++)
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
++ break;
++
++ case WHITENESS:
++ MAYBE(TRACE("WHITENESS\n"));
++ for(dwBuf = dBuf, i = width; i; i--)
++ *dwBuf++ = 0x00ffffff;
++ for(yd = yDst; yd < yDst+height; yd++)
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
++ break;
++
++ case SRCCOPY:
++ MAYBE(TRACE("SRCCOPY\n"));
++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
++ }
++ break;
++
++ /* fallback for generic ROP operation */
++ default:
++ rop >>= 16;
++ if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
++ {
++ MAYBE(TRACE("BitBlt use: src+dst+pat - pattern brush\n"));
++ if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
++ goto error;
++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
++ goto error;
++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
++ wDstPnt = dBuf;
++ wSrcPnt = sBuf;
++ wPatPnt = pBuf;
++ for(i = width; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
++ }
++ }
++ else if(useSrc && useDst)
++ {
++ if(usePat)
++ MAYBE(TRACE("BitBlt use: src+dst+pat - solid brush\n"));
++ else
++ MAYBE(TRACE("BitBlt use: src+dst\n"));
++ if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
++ goto error;
++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, width, dBuf);
++ wDstPnt = dBuf;
++ wSrcPnt = sBuf;
++ for(i = width; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
++ }
++ }
++ else if(useSrc && usePat && physDevDst->isBrushBitmap)
++ {
++ MAYBE(TRACE("BitBlt use: src+pat -- pattern brush\n"));
++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
++ goto error;
++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
++ wDstPnt = dBuf;
++ wSrcPnt = dBuf;
++ wPatPnt = pBuf;
++ for(i = width; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
++ }
++ }
++ else if(useSrc)
++ {
++ if(usePat)
++ MAYBE(TRACE("BitBlt use: src+pat - solid brush\n"));
++ else
++ MAYBE(TRACE("BitBlt use: src\n"));
++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
++ wDstPnt = dBuf;
++ wSrcPnt = dBuf;
++ for(i = width; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
++ }
++ }
++ else if(useDst && usePat && physDevDst->isBrushBitmap)
++ {
++ MAYBE(TRACE("BitBlt use: dst+pat -- pattern brush\n"));
++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
++ goto error;
++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
++ {
++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
++ wDstPnt = dBuf;
++ wPatPnt = pBuf;
++ for(i = width; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
++ }
++ }
++ else if(useDst)
++ {
++ if(usePat)
++ MAYBE(TRACE("BitBlt use: dst+pat - solid brush\n"));
++ else
++ MAYBE(TRACE("BitBlt use: dst\n"));
++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
++ {
++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
++ wDstPnt = dBuf;
++ for(i = width; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
++ }
++ }
++ else if(usePat && physDevDst->isBrushBitmap)
++ {
++ MAYBE(TRACE("BitBlt use: pat -- pattern brush\n"));
++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
++ goto error;
++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
++ {
++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
++ wDstPnt = dBuf;
++ wPatPnt = pBuf;
++ for(i = width; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
++ }
++ }
++ else if(usePat)
++ {
++ MAYBE(TRACE("BitBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
++ MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
++ MAYBE(TRACE("xDst = %d, yDst = %d, width = %d, height = %d\n", xDst, yDst, width, height));
++ for(yd = yDst; yd < yDst+height; yd++)
++ {
++ wDstPnt = dBuf;
++ for(i = width; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
++ }
++ }
++ else
++ ERR("What happened ?????? \n");
++ break;
++ } /* switch */
++ res = TRUE;
++error:
++ if(sBuf) HeapFree( GetProcessHeap(), 0, sBuf );
++ if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
++ if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
++ return res;
++}
++
++/* ------------------------------------------------------------*/
++/* STRETCHING PRIMITIVES */
++BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop)
++{
++ int ys, yd;
++ int i, delta;
++ DWORD *dwBuf;
++ DIBDRVBITMAP *dstBmp, *patBmp;
++ const DIBDRVBITMAP *srcBmp;
++ DWORD *wDstPnt, *wSrcPnt, *wPatPnt;
++ BOOL usePat, useSrc, useDst;
++ DWORD patColor;
++ BOOL res = FALSE;
++
++ /* 32 bit RGB source and destination buffer, if needed */
++ DWORD *sBufOrig = 0, *sBufStr = 0, *dBuf = 0, *pBuf = 0;
++
++ /* get elements usage */
++ usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
++ useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
++ useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
++
++ /* sanity check -- MSN messenger crashes without */
++ if(useSrc && !physDevSrc)
++ return FALSE;
++
++ /* gets source, dest and pattern bitmaps, if available */
++ if(usePat && physDevDst->isBrushBitmap)
++ patBmp = physDevDst->brushBmpCache;
++ else
++ patBmp = NULL;
++
++ if(useSrc)
++ srcBmp = physDevSrc->physBitmap;
++ else
++ srcBmp = NULL;
++ dstBmp = physDevDst->physBitmap;
++
++ /* gets pattern color, in case it's needed
++ it's NOT the COLORREF value (colors are swapped
++ NOR the pixel value (it's applied to a 32 BPP BI_RGB */
++ if(usePat)
++ patColor = SwapColors(physDevDst->brushColorref);
++ else
++ patColor = 0;
++
++ /* allocate 32 bit RGB destination buffer */
++ if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
++ goto error;
++
++ MAYBE(TRACE("dstBmp:%p(%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, srcBmp:%p(%s), xSrc:%d, ySrc:%d, , widthSrc:%d, heightSrc:%drop:%8x\n",
++ dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, widthDst, heightDst,
++ srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, widthSrc, heightSrc, rop));
++
++ /* some simple ROPs optimizations */
++ switch(rop)
++ {
++ case BLACKNESS:
++ MAYBE(TRACE("BLACKNESS\n"));
++ memset(dBuf, 0x00, widthDst * 4);
++ for(yd = yDst; yd < yDst+heightDst; yd++)
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ break;
++
++ case WHITENESS:
++ MAYBE(TRACE("WHITENESS\n"));
++ for(dwBuf = dBuf, i = widthDst; i; i--)
++ *dwBuf++ = 0x00ffffff;
++ for(yd = yDst; yd < yDst+heightDst; yd++)
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ break;
++
++ case SRCCOPY:
++ MAYBE(TRACE("SRCCOPY\n"));
++ sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4);
++ if(heightSrc > heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(yd < heightDst)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
++ StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ while(delta < heightSrc)
++ {
++ ys++;
++ delta += heightDst;
++ }
++ delta -= heightSrc;
++ yd++;
++ }
++ }
++ else if(heightSrc < heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(ys < heightSrc)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
++ StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
++ while(delta < heightDst)
++ {
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ yd++;
++ delta += heightSrc;
++ }
++ delta -= heightDst;
++ ys++;
++ }
++ }
++ else
++ {
++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
++ StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ }
++ }
++ break;
++
++ /* fallback for generic ROP operation */
++ default:
++ rop >>= 16;
++ if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
++ {
++ MAYBE(TRACE("StretchBlt use: src+dst+pat - pattern brush\n"));
++ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
++ goto error;
++ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
++ goto error;
++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
++ goto error;
++ if(heightSrc > heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(yd < heightDst)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ while(delta < heightSrc)
++ {
++ ys++;
++ delta += heightDst;
++ }
++ delta -= heightSrc;
++ yd++;
++ }
++ }
++ else if(heightSrc < heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(ys < heightSrc)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
++ while(delta < heightDst)
++ {
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ yd++;
++ delta += heightSrc;
++ }
++ delta -= heightDst;
++ ys++;
++ }
++ }
++ else
++ {
++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ }
++ }
++ }
++ else if(useSrc && useDst)
++ {
++ if(usePat)
++ MAYBE(TRACE("StretchBlt use: src+dst+pat - solid brush\n"));
++ else
++ MAYBE(TRACE("StretchBlt use: src+dst\n"));
++ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
++ goto error;
++ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
++ goto error;
++ if(heightSrc > heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(yd < heightDst)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ while(delta < heightSrc)
++ {
++ ys++;
++ delta += heightDst;
++ }
++ delta -= heightSrc;
++ yd++;
++ }
++ }
++ else if(heightSrc < heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(ys < heightSrc)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ while(delta < heightDst)
++ {
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ yd++;
++ delta += heightSrc;
++ }
++ delta -= heightDst;
++ ys++;
++ }
++ }
++ else
++ {
++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ }
++ }
++ }
++ else if(useSrc && usePat && physDevDst->isBrushBitmap)
++ {
++ MAYBE(TRACE("StretchBlt use: src+pat -- pattern brush\n"));
++ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
++ goto error;
++ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
++ goto error;
++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
++ goto error;
++ if(heightSrc > heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(yd < heightDst)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ while(delta < heightSrc)
++ {
++ ys++;
++ delta += heightDst;
++ }
++ delta -= heightSrc;
++ yd++;
++ }
++ }
++ else if(heightSrc < heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(ys < heightSrc)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
++ while(delta < heightDst)
++ {
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ yd++;
++ delta += heightSrc;
++ }
++ delta -= heightDst;
++ ys++;
++ }
++ }
++ else
++ {
++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ }
++ }
++ }
++ else if(useSrc)
++ {
++ if(usePat)
++ MAYBE(TRACE("StretchBlt use: src+pat - solid brush\n"));
++ else
++ MAYBE(TRACE("StretchBlt use: src\n"));
++ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
++ goto error;
++ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
++ goto error;
++ if(heightSrc > heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(yd < heightDst)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ while(delta < heightSrc)
++ {
++ ys++;
++ delta += heightDst;
++ }
++ delta -= heightSrc;
++ yd++;
++ }
++ }
++ else if(heightSrc < heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(ys < heightSrc)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ while(delta < heightDst)
++ {
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ yd++;
++ delta += heightSrc;
++ }
++ delta -= heightDst;
++ ys++;
++ }
++ }
++ else
++ {
++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
++ {
++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
++ wDstPnt = dBuf;
++ wSrcPnt = sBufStr;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ }
++ }
++ }
++ else if(useDst && usePat && physDevDst->isBrushBitmap)
++ {
++ MAYBE(TRACE("StretchBlt use: dst+pat -- pattern brush\n"));
++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
++ goto error;
++ if(heightSrc > heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(yd < heightDst)
++ {
++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
++ wDstPnt = dBuf;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ while(delta < heightSrc)
++ {
++ ys++;
++ delta += heightDst;
++ }
++ delta -= heightSrc;
++ yd++;
++ }
++ }
++ else if(heightSrc < heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(ys < heightSrc)
++ {
++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
++ while(delta < heightDst)
++ {
++ wDstPnt = dBuf;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ yd++;
++ delta += heightSrc;
++ }
++ delta -= heightDst;
++ ys++;
++ }
++ }
++ else
++ {
++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
++ {
++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
++ wDstPnt = dBuf;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ }
++ }
++ }
++ else if(useDst)
++ {
++ if(usePat)
++ MAYBE(TRACE("StretchBlt use: dst+pat - solid brush\n"));
++ else
++ MAYBE(TRACE("StretchBlt use: dst\n"));
++ if(heightSrc > heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(yd < heightDst)
++ {
++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ wDstPnt = dBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ while(delta < heightSrc)
++ {
++ ys++;
++ delta += heightDst;
++ }
++ delta -= heightSrc;
++ yd++;
++ }
++ }
++ else if(heightSrc < heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(ys < heightSrc)
++ {
++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ while(delta < heightDst)
++ {
++ wDstPnt = dBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ yd++;
++ delta += heightSrc;
++ }
++ delta -= heightDst;
++ ys++;
++ }
++ }
++ else
++ {
++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
++ {
++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
++ wDstPnt = dBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ }
++ }
++ }
++ else if(usePat && physDevDst->isBrushBitmap)
++ {
++ MAYBE(TRACE("StretchBlt use: pat -- pattern brush\n"));
++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
++ goto error;
++ if(heightSrc > heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(yd < heightDst)
++ {
++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
++ wDstPnt = dBuf;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ while(delta < heightSrc)
++ {
++ ys++;
++ delta += heightDst;
++ }
++ delta -= heightSrc;
++ yd++;
++ }
++ }
++ else if(heightSrc < heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(ys < heightSrc)
++ {
++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
++ while(delta < heightDst)
++ {
++ wDstPnt = dBuf;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ yd++;
++ delta += heightSrc;
++ }
++ delta -= heightDst;
++ ys++;
++ }
++ }
++ else
++ {
++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
++ {
++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
++ wDstPnt = dBuf;
++ wPatPnt = pBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ }
++ }
++ }
++ else if(usePat)
++ {
++ MAYBE(TRACE("StretchBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
++ MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
++ MAYBE(TRACE("xDst = %d, yDst = %d, widthDst = %d, heightDst = %d\n", xDst, yDst, widthDst, heightDst));
++ if(heightSrc > heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(yd < heightDst)
++ {
++ wDstPnt = dBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ while(delta < heightSrc)
++ {
++ ys++;
++ delta += heightDst;
++ }
++ delta -= heightSrc;
++ yd++;
++ }
++ }
++ else if(heightSrc < heightDst)
++ {
++ ys = 0;
++ yd = 0;
++ delta = 0;
++ while(ys < heightSrc)
++ {
++ while(delta < heightDst)
++ {
++ wDstPnt = dBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
++ yd++;
++ delta += heightSrc;
++ }
++ delta -= heightDst;
++ ys++;
++ }
++ }
++ else
++ {
++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
++ {
++ wDstPnt = dBuf;
++ for(i = widthDst; i > 0 ; i--)
++ {
++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
++ wDstPnt++;
++ }
++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
++ }
++ }
++ }
++ else
++ ERR("What happened ?????? \n");
++ break;
++ } /* switch */
++ res = TRUE;
++error:
++ if(sBufOrig) HeapFree( GetProcessHeap(), 0, sBufOrig );
++ if(sBufStr) HeapFree( GetProcessHeap(), 0, sBufStr );
++ if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
++ if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
++ return res;
++}
+diff -Nru a/dlls/winedib.drv/primitives.c b/dlls/winedib.drv/primitives.c
+--- a/dlls/winedib.drv/primitives.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/primitives.c 2010-08-04 16:08:44.587222017 +0200
+@@ -0,0 +1,286 @@
++/*
++ * DIB Engine Primitives function pointers
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/* ------------------------------------------------------------*/
++/* COLOR FUNCTIONS */
++DWORD _DIBDRV_ColorToPixel32_RGB (const DIBDRVBITMAP *dib, COLORREF color);
++DWORD _DIBDRV_ColorToPixel32_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color);
++DWORD _DIBDRV_ColorToPixel24 (const DIBDRVBITMAP *dib, COLORREF color);
++DWORD _DIBDRV_ColorToPixel16_RGB (const DIBDRVBITMAP *dib, COLORREF color);
++DWORD _DIBDRV_ColorToPixel16_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color);
++DWORD _DIBDRV_ColorToPixelColortable (const DIBDRVBITMAP *dib, COLORREF color);
++
++/* ------------------------------------------------------------*/
++/* PIXEL POINTER READING */
++void *_DIBDRV_GetPixelPointer32(const DIBDRVBITMAP *dib, int x, int y);
++void *_DIBDRV_GetPixelPointer24(const DIBDRVBITMAP *dib, int x, int y);
++void *_DIBDRV_GetPixelPointer16(const DIBDRVBITMAP *dib, int x, int y);
++void *_DIBDRV_GetPixelPointer8 (const DIBDRVBITMAP *dib, int x, int y);
++void *_DIBDRV_GetPixelPointer4 (const DIBDRVBITMAP *dib, int x, int y);
++void *_DIBDRV_GetPixelPointer1 (const DIBDRVBITMAP *dib, int x, int y);
++
++/* ------------------------------------------------------------*/
++/* PIXEL WRITING */
++void _DIBDRV_SetPixel32(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor);
++void _DIBDRV_SetPixel24(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor);
++void _DIBDRV_SetPixel16(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor);
++void _DIBDRV_SetPixel8 (DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor);
++void _DIBDRV_SetPixel4 (DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor);
++void _DIBDRV_SetPixel1 (DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor);
++
++/* ------------------------------------------------------------*/
++/* PIXEL READING */
++DWORD _DIBDRV_GetPixel32_RGB (const DIBDRVBITMAP *dib, int x, int y);
++DWORD _DIBDRV_GetPixel32_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y);
++DWORD _DIBDRV_GetPixel24 (const DIBDRVBITMAP *dib, int x, int y);
++DWORD _DIBDRV_GetPixel16_RGB (const DIBDRVBITMAP *dib, int x, int y);
++DWORD _DIBDRV_GetPixel16_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y);
++DWORD _DIBDRV_GetPixel8 (const DIBDRVBITMAP *dib, int x, int y);
++DWORD _DIBDRV_GetPixel4 (const DIBDRVBITMAP *dib, int x, int y);
++DWORD _DIBDRV_GetPixel1 (const DIBDRVBITMAP *dib, int x, int y);
++
++/* ------------------------------------------------------------*/
++/* HORIZONTAL SOLID LINES */
++void _DIBDRV_SolidHLine32(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
++void _DIBDRV_SolidHLine24(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
++void _DIBDRV_SolidHLine16(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
++void _DIBDRV_SolidHLine8 (DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
++void _DIBDRV_SolidHLine4 (DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
++void _DIBDRV_SolidHLine1 (DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
++
++/* ------------------------------------------------------------*/
++/* HORIZONTAL PATTERN LINES */
++void _DIBDRV_PatternHLine32(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
++void _DIBDRV_PatternHLine24(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
++void _DIBDRV_PatternHLine16(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
++void _DIBDRV_PatternHLine8 (DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
++void _DIBDRV_PatternHLine4 (DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
++void _DIBDRV_PatternHLine1 (DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
++
++/* ------------------------------------------------------------*/
++/* VERTICAL LINES */
++void _DIBDRV_SolidVLine32(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
++void _DIBDRV_SolidVLine24(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
++void _DIBDRV_SolidVLine16(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
++void _DIBDRV_SolidVLine8 (DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
++void _DIBDRV_SolidVLine4 (DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
++void _DIBDRV_SolidVLine1 (DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
++
++/* ----------------------------------------------------------------*/
++/* CONVERT PRIMITIVES */
++/* converts (part of) line of any DIB format from/to DIB32_RGB one */
++BOOL _DIBDRV_GetLine32_RGB (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_GetLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_GetLine24 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_GetLine16_RGB (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_GetLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_GetLine8 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_GetLine4 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_GetLine1 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++
++BOOL _DIBDRV_PutLine32_RGB (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_PutLine32_BITFIELDS(DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_PutLine24 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_PutLine16_RGB (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_PutLine16_BITFIELDS(DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_PutLine8 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_PutLine4 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++BOOL _DIBDRV_PutLine1 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
++
++/* ------------------------------------------------------------*/
++/* BLITTING PRIMITIVES */
++BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, DWORD rop);
++BOOL _DIBDRV_BitBlt_32(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, DWORD rop);
++BOOL _DIBDRV_BitBlt_24(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, DWORD rop);
++BOOL _DIBDRV_BitBlt_16(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, DWORD rop);
++BOOL _DIBDRV_BitBlt_8(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, DWORD rop);
++
++BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
++ INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
++ INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop);
++
++BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, int xDst, int yDst,
++ int widthDst, int heightDst, const DIBDRVPHYSDEV *physDevSrc,
++ int xSrc, int ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFn );
++
++/* ------------------------------------------------------------*/
++/* FREETYPE FONT BITMAP BLITTING */
++void _DIBDRV_freetype_blit_8888 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
++void _DIBDRV_freetype_blit_32_RGB (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
++void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
++void _DIBDRV_freetype_blit_24 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
++void _DIBDRV_freetype_blit_16_RGB (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
++void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
++void _DIBDRV_freetype_blit_8 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
++void _DIBDRV_freetype_blit_4 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
++void _DIBDRV_freetype_blit_1 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp);
++
++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_RGB =
++{
++ _DIBDRV_ColorToPixel32_RGB,
++ _DIBDRV_GetPixelPointer32,
++ _DIBDRV_SetPixel32,
++ _DIBDRV_GetPixel32_RGB,
++ _DIBDRV_SolidHLine32,
++ _DIBDRV_PatternHLine32,
++ _DIBDRV_SolidVLine32,
++ _DIBDRV_GetLine32_RGB,
++ _DIBDRV_PutLine32_RGB,
++ _DIBDRV_AlphaBlend_generic,
++ _DIBDRV_BitBlt_generic,
++ _DIBDRV_StretchBlt_generic,
++ _DIBDRV_freetype_blit_32_RGB
++};
++
++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_BITFIELDS =
++{
++ _DIBDRV_ColorToPixel32_BITFIELDS,
++ _DIBDRV_GetPixelPointer32,
++ _DIBDRV_SetPixel32,
++ _DIBDRV_GetPixel32_BITFIELDS,
++ _DIBDRV_SolidHLine32,
++ _DIBDRV_PatternHLine32,
++ _DIBDRV_SolidVLine32,
++ _DIBDRV_GetLine32_BITFIELDS,
++ _DIBDRV_PutLine32_BITFIELDS,
++ _DIBDRV_AlphaBlend_generic,
++ _DIBDRV_BitBlt_generic,
++ _DIBDRV_StretchBlt_generic,
++ _DIBDRV_freetype_blit_32_BITFIELDS
++};
++
++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB24 =
++{
++ _DIBDRV_ColorToPixel24,
++ _DIBDRV_GetPixelPointer24,
++ _DIBDRV_SetPixel24,
++ _DIBDRV_GetPixel24,
++ _DIBDRV_SolidHLine24,
++ _DIBDRV_PatternHLine24,
++ _DIBDRV_SolidVLine24,
++ _DIBDRV_GetLine24,
++ _DIBDRV_PutLine24,
++ _DIBDRV_AlphaBlend_generic,
++ _DIBDRV_BitBlt_generic,
++ _DIBDRV_StretchBlt_generic,
++ _DIBDRV_freetype_blit_24
++};
++
++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_RGB =
++{
++ _DIBDRV_ColorToPixel16_RGB,
++ _DIBDRV_GetPixelPointer16,
++ _DIBDRV_SetPixel16,
++ _DIBDRV_GetPixel16_RGB,
++ _DIBDRV_SolidHLine16,
++ _DIBDRV_PatternHLine16,
++ _DIBDRV_SolidVLine16,
++ _DIBDRV_GetLine16_RGB,
++ _DIBDRV_PutLine16_RGB,
++ _DIBDRV_AlphaBlend_generic,
++ _DIBDRV_BitBlt_generic,
++ _DIBDRV_StretchBlt_generic,
++ _DIBDRV_freetype_blit_16_RGB
++};
++
++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_BITFIELDS =
++{
++ _DIBDRV_ColorToPixel16_BITFIELDS,
++ _DIBDRV_GetPixelPointer16,
++ _DIBDRV_SetPixel16,
++ _DIBDRV_GetPixel16_BITFIELDS,
++ _DIBDRV_SolidHLine16,
++ _DIBDRV_PatternHLine16,
++ _DIBDRV_SolidVLine16,
++ _DIBDRV_GetLine16_BITFIELDS,
++ _DIBDRV_PutLine16_BITFIELDS,
++ _DIBDRV_AlphaBlend_generic,
++ _DIBDRV_BitBlt_generic,
++ _DIBDRV_StretchBlt_generic,
++ _DIBDRV_freetype_blit_16_BITFIELDS
++};
++
++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB8 =
++{
++ _DIBDRV_ColorToPixelColortable,
++ _DIBDRV_GetPixelPointer8,
++ _DIBDRV_SetPixel8,
++ _DIBDRV_GetPixel8,
++ _DIBDRV_SolidHLine8,
++ _DIBDRV_PatternHLine8,
++ _DIBDRV_SolidVLine8,
++ _DIBDRV_GetLine8,
++ _DIBDRV_PutLine8,
++ _DIBDRV_AlphaBlend_generic,
++ _DIBDRV_BitBlt_generic,
++ _DIBDRV_StretchBlt_generic,
++ _DIBDRV_freetype_blit_8
++};
++
++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB4 =
++{
++ _DIBDRV_ColorToPixelColortable,
++ _DIBDRV_GetPixelPointer4,
++ _DIBDRV_SetPixel4,
++ _DIBDRV_GetPixel4,
++ _DIBDRV_SolidHLine4,
++ _DIBDRV_PatternHLine4,
++ _DIBDRV_SolidVLine4,
++ _DIBDRV_GetLine4,
++ _DIBDRV_PutLine4,
++ _DIBDRV_AlphaBlend_generic,
++ _DIBDRV_BitBlt_generic,
++ _DIBDRV_StretchBlt_generic,
++ _DIBDRV_freetype_blit_4
++};
++
++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB1 =
++{
++ _DIBDRV_ColorToPixelColortable,
++ _DIBDRV_GetPixelPointer1,
++ _DIBDRV_SetPixel1,
++ _DIBDRV_GetPixel1,
++ _DIBDRV_SolidHLine1,
++ _DIBDRV_PatternHLine1,
++ _DIBDRV_SolidVLine1,
++ _DIBDRV_GetLine1,
++ _DIBDRV_PutLine1,
++ _DIBDRV_AlphaBlend_generic,
++ _DIBDRV_BitBlt_generic,
++ _DIBDRV_StretchBlt_generic,
++ _DIBDRV_freetype_blit_1
++};
+diff -Nru a/dlls/winedib.drv/primitives_color.c b/dlls/winedib.drv/primitives_color.c
+--- a/dlls/winedib.drv/primitives_color.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/primitives_color.c 2010-08-04 16:08:44.710222017 +0200
+@@ -0,0 +1,175 @@
++/*
++ * DIB Engine color Primitives
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/* ------------------------------------------------------------*/
++/* BITFIELD HELPERS */
++static inline DWORD PutField32(DWORD field, int shift, int len)
++{
++ shift = shift - (8 - len);
++ if (len <= 8)
++ field &= (((1 << len) - 1) << (8 - len));
++ if (shift < 0)
++ field >>= -shift;
++ else
++ field <<= shift;
++ return field;
++}
++
++static inline WORD PutField16(WORD field, int shift, int len)
++{
++ shift = shift - (8 - len);
++ if (len <= 8)
++ field &= (((1 << len) - 1) << (8 - len));
++ if (shift < 0)
++ field >>= -shift;
++ else
++ field <<= shift;
++ return field;
++}
++
++/* ------------------------------------------------------------*/
++/* COLOR FUNCTIONS */
++DWORD _DIBDRV_ColorToPixel32_RGB(const DIBDRVBITMAP *dib, COLORREF color)
++{
++ return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) );
++}
++
++DWORD _DIBDRV_ColorToPixel32_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color)
++{
++ DWORD r,g,b;
++
++ r = GetRValue(color);
++ g = GetGValue(color);
++ b = GetBValue(color);
++
++ return PutField32(r, dib->redShift, dib->redLen) |
++ PutField32(g, dib->greenShift, dib->greenLen) |
++ PutField32(b, dib->blueShift, dib->blueLen);
++}
++
++DWORD _DIBDRV_ColorToPixel24(const DIBDRVBITMAP *dib, COLORREF color)
++{
++ return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) );
++}
++
++DWORD _DIBDRV_ColorToPixel16_RGB(const DIBDRVBITMAP *dib, COLORREF color)
++{
++ return ( ((color >> 19) & 0x001f) | ((color >> 6) & 0x03e0) | ((color << 7) & 0x7c00) );
++}
++
++DWORD _DIBDRV_ColorToPixel16_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color)
++{
++ DWORD r,g,b;
++
++ r = GetRValue(color);
++ g = GetGValue(color);
++ b = GetBValue(color);
++
++ return PutField16(r, dib->redShift, dib->redLen) |
++ PutField16(g, dib->greenShift, dib->greenLen) |
++ PutField16(b, dib->blueShift, dib->blueLen);
++}
++
++/* gets nearest color to DIB palette color */
++DWORD _DIBDRV_GetNearestColor(const DIBDRVBITMAP *dib, COLORREF color)
++{
++ RGBQUAD *c;
++
++ if(dib->bitCount > 8)
++ return color;
++
++ c = dib->colorTable + _DIBDRV_GetNearestColorIndex(dib, color);
++ return RGB(c->rgbRed, c->rgbGreen, c->rgbBlue);
++
++}
++
++/* gets nearest color index in DIB palette of a given colorref */
++DWORD _DIBDRV_GetNearestColorIndex(const DIBDRVBITMAP *dib, COLORREF color)
++{
++ DWORD r, g, b;
++ int i, best_index = 0;
++ DWORD diff, best_diff = 0xffffffff;
++
++ r = GetRValue(color);
++ g = GetGValue(color);
++ b = GetBValue(color);
++
++ for(i = 0; i < dib->colorTableSize; i++)
++ {
++ RGBQUAD *cur = dib->colorTable + i;
++ diff = (r - cur->rgbRed) * (r - cur->rgbRed)
++ + (g - cur->rgbGreen) * (g - cur->rgbGreen)
++ + (b - cur->rgbBlue) * (b - cur->rgbBlue);
++
++ if(diff == 0)
++ {
++ best_index = i;
++ break;
++ }
++
++ if(diff < best_diff)
++ {
++ best_diff = diff;
++ best_index = i;
++ }
++ }
++ return best_index;
++}
++
++DWORD _DIBDRV_ColorToPixelColortable(const DIBDRVBITMAP *dib, COLORREF color)
++{
++ /* just in case it's being called without color table
++ properly initialized */
++ if(!dib->colorTableGrabbed)
++ return 0;
++
++ color &= 0xffffff;
++
++ /* for monochrome bitmaps, color is :
++ foreground if matching foreground ctable
++ else background if matching background ctable
++ else foreground if 0xffffff
++ else background */
++ if(dib->colorTableSize == 2)
++ {
++ RGBQUAD *back = dib->colorTable;
++ RGBQUAD *fore = dib->colorTable + 1;
++ COLORREF backColorref = RGB(back->rgbRed, back->rgbGreen, back->rgbBlue);
++ COLORREF foreColorref = RGB(fore->rgbRed, fore->rgbGreen, fore->rgbBlue);
++ if(color == foreColorref)
++ return 1;
++ else if(color == backColorref)
++ return 0;
++ else if(color == 0xffffff)
++ return dib->lightColor;
++ else
++ return 0;
++ }
++
++ /* otherwise looks for nearest color in palette */
++ return _DIBDRV_GetNearestColorIndex(dib, color);
++}
+diff -Nru a/dlls/winedib.drv/primitives_convert.c b/dlls/winedib.drv/primitives_convert.c
+--- a/dlls/winedib.drv/primitives_convert.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/primitives_convert.c 2010-08-04 16:08:44.794222017 +0200
+@@ -0,0 +1,607 @@
++/*
++ * DIB Engine conversions Primitives
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++static inline COLORREF SwapColors(DWORD c)
++{
++ return ((c & 0x0000ff) << 16) | (c & 0x00ff00) | ((c & 0xff0000) >> 16);
++
++}
++
++static inline DWORD PlaceField32(BYTE c, int shift, int len)
++{
++ DWORD res = c;
++ if(len < 8)
++ res >>= (8 - len);
++ else
++ res <<= (len - 8);
++ return res << shift;
++}
++
++static inline WORD PlaceField16(BYTE c, int shift, int len)
++{
++ WORD res = c;
++ if(len < 8)
++ res >>= (8 - len);
++ else
++ res <<= (len - 8);
++ return res << shift;
++}
++
++static inline BYTE GetField32(DWORD dwColor, int shift, int len)
++{
++ dwColor = dwColor & (((1 << (len)) - 1) << shift);
++ dwColor = dwColor << (32 - (shift + len)) >> 24;
++ return dwColor;
++}
++
++/* ----------------------------------------------------------------*/
++/* CONVERT PRIMITIVES */
++/* converts (part of) line of any DIB format from/to DIB32_RGB one */
++BOOL _DIBDRV_GetLine32_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ DWORD *src;
++
++#ifdef DIBDRV_CHECK_RANGES
++ /* range check */
++ if(line < 0 || line >= bmp->height)
++ return FALSE;
++ if(startx < 0)
++ {
++ width += startx;
++ dwBuf -= startx;
++ startx = 0;
++ }
++ if(startx + width > bmp->width)
++ width = bmp->width - startx;
++ if(width <= 0)
++ return FALSE;
++#endif
++
++ src = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx);
++ for(; width; width--)
++ *dwBuf++ = *src++;
++ return TRUE;
++}
++
++BOOL _DIBDRV_GetLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ DWORD *src;
++
++#ifdef DIBDRV_CHECK_RANGES
++ /* range check */
++ if(line < 0 || line >= bmp->height)
++ return FALSE;
++ if(startx < 0)
++ {
++ width += startx;
++ bBuf -= 4 * startx;
++ startx = 0;
++ }
++ if(startx + width > bmp->width)
++ width = bmp->width - startx;
++ if(width <= 0)
++ return FALSE;
++#endif
++
++ src = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx);
++ for(; width ; width--)
++ {
++ *dwBuf++ =
++ 0xff000000 |
++ GetField32(*src, bmp->redShift , bmp->redLen ) << 16 |
++ GetField32(*src, bmp->greenShift, bmp->greenLen) << 8 |
++ GetField32(*src, bmp->blueShift , bmp->blueLen );
++ src++;
++ }
++ return TRUE;
++}
++
++BOOL _DIBDRV_GetLine24(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ BYTE *bBuf = (BYTE *)buf;
++ BYTE *src;
++
++#ifdef DIBDRV_CHECK_RANGES
++ /* range check */
++ if(line < 0 || line >= bmp->height)
++ return FALSE;
++ if(startx < 0)
++ {
++ width += startx;
++ bBuf -= 4 * startx;
++ startx = 0;
++ }
++ if(startx + width > bmp->width)
++ width = bmp->width - startx;
++ if(width <= 0)
++ return FALSE;
++#endif
++
++ src = ((BYTE *)bmp->bits + line * bmp->stride + 3 * startx);
++ for(; width ; width--)
++ {
++ *bBuf++ = *src++;
++ *bBuf++ = *src++;
++ *bBuf++ = *src++;
++ *bBuf++ = 0xff;
++ }
++ return TRUE;
++}
++
++BOOL _DIBDRV_GetLine16_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ WORD *src;
++ DWORD b;
++
++#ifdef DIBDRV_CHECK_RANGES
++ /* range check */
++ if(line < 0 || line >= bmp->height)
++ return FALSE;
++ if(startx < 0)
++ {
++ width += startx;
++ dwBuf -= startx;
++ startx = 0;
++ }
++ if(startx + width > bmp->width)
++ width = bmp->width - startx;
++ if(width <= 0)
++ return FALSE;
++#endif
++
++ src = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx);
++ for(; width ; width--)
++ {
++ b = *src++;
++ /* 0RRR|RRGG|GGGB|BBBB */
++ *dwBuf++ = 0xff000000 | ((b & 0x1f) << 3) | ((b & 0x3e0) << 6) | ((b & 0x7c00) << 9);
++ }
++ return TRUE;
++}
++
++BOOL _DIBDRV_GetLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ WORD *src;
++ DWORD b;
++
++#ifdef DIBDRV_CHECK_RANGES
++ /* range check */
++ if(line < 0 || line >= bmp->height)
++ return FALSE;
++ if(startx < 0)
++ {
++ width += startx;
++ dwBuf -= startx;
++ startx = 0;
++ }
++ if(startx + width > bmp->width)
++ width = bmp->width - startx;
++ if(width <= 0)
++ return FALSE;
++#endif
++
++ src = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx);
++ for(; width ; width--)
++ {
++ b = *src++;
++
++ *dwBuf++ =
++ 0xff000000 |
++ ((( b & bmp->blueMask) >> bmp->blueShift ) << ( 8 - bmp->blueLen )) |
++ (((b & bmp->greenMask) >> bmp->greenShift) << (16 - bmp->greenLen)) |
++ (((b & bmp->redMask ) >> bmp->redShift ) << (24 - bmp->redLen ));
++ }
++ return TRUE;
++}
++
++BOOL _DIBDRV_GetLine8(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ BYTE *src;
++
++#ifdef DIBDRV_CHECK_RANGES
++ /* range check */
++ if(line < 0 || line >= bmp->height)
++ return FALSE;
++ if(startx < 0)
++ {
++ width += startx;
++ dwBuf -= startx;
++ startx = 0;
++ }
++ if(startx + width > bmp->width)
++ width = bmp->width - startx;
++ if(width <= 0)
++ return FALSE;
++#endif
++
++ src = ((BYTE *)bmp->bits + line * bmp->stride + startx);
++ for(; width ; width--)
++ *dwBuf++ = 0xff000000 | *((DWORD *)bmp->colorTable + *src++);
++ return TRUE;
++}
++
++BOOL _DIBDRV_GetLine4(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ BYTE *src;
++
++#ifdef DIBDRV_CHECK_RANGES
++ /* range check */
++ if(line < 0 || line >= bmp->height)
++ return FALSE;
++ if(startx < 0)
++ {
++ width += startx;
++ dwBuf -= startx;
++ startx = 0;
++ }
++ if(startx + width > bmp->width)
++ width = bmp->width - startx;
++ if(width <= 0)
++ return FALSE;
++ if(!bmp->colorTable)
++ {
++ ERR("Called with uninitialized color table\n");
++ return FALSE;
++ }
++#endif
++
++ src = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 1));
++ /* if startx is odd, get first nibble */
++ if(startx & 0x01)
++ {
++ *dwBuf++ = 0xff000000 | *((DWORD *)bmp->colorTable + (*src++ & 0x0f));
++ width--;
++ }
++
++ /* then gets all full image bytes */
++ for( ; width > 1 ; width -= 2)
++ {
++ *dwBuf++ = 0xff000000 | *((DWORD *)bmp->colorTable + ((*src >> 4) & 0x0f));
++ *dwBuf++ = 0xff000000 | *((DWORD *)bmp->colorTable + (*src++ & 0x0f));
++ }
++
++ /* last nibble, if any */
++ if(width)
++ *dwBuf++ = 0xff000000 | *((DWORD *)bmp->colorTable + ((*src >> 4) & 0x0f));
++ return TRUE;
++}
++
++BOOL _DIBDRV_GetLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ BYTE *src;
++ BYTE b;
++ char i;
++ DWORD pixOn = 0xff000000 | *((DWORD *)bmp->colorTable + 1);
++ DWORD pixOff = 0xff000000 | *(DWORD *)bmp->colorTable;
++
++#ifdef DIBDRV_CHECK_RANGES
++ /* range check */
++ if(line < 0 || line >= bmp->height)
++ return FALSE;
++ if(startx < 0)
++ {
++ width += startx;
++ dwBuf -= startx;
++ startx = 0;
++ }
++ if(startx + width > bmp->width)
++ width = bmp->width - startx;
++ if(width <= 0)
++ return FALSE;
++#endif
++
++ src = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 3));
++ /* get first partial byte, if any */
++ startx = (8 - (startx & 0x07)) & 0x07;
++ width -= startx;
++ if(startx)
++ {
++ b = *src++ << (8 - startx);
++ while(startx--)
++ {
++ if(b & 0x80)
++ *dwBuf++ = pixOn;
++ else
++ *dwBuf++ = pixOff;
++ b <<= 1;
++ }
++ }
++
++ /* then gets full next bytes */
++ for( ; width > 7 ; width -= 8)
++ {
++ b = *src++;
++ for(i = 0 ; i < 8 ; i++)
++ {
++ if(b & 0x80)
++ *dwBuf++ = pixOn;
++ else
++ *dwBuf++ = pixOff;
++ b <<= 1;
++ }
++ }
++
++ /* last partial byte, if any */
++ if(width > 0)
++ {
++ b = *src;
++ while(width--)
++ {
++ if(b & 0x80)
++ *dwBuf++ = pixOn;
++ else
++ *dwBuf++ = pixOff;
++ b <<= 1;
++ }
++ }
++ return TRUE;
++}
++
++BOOL _DIBDRV_PutLine32_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ DWORD *dst = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx);
++ for(; width; width--)
++ *dst++ = *dwBuf++;
++ return TRUE;
++}
++
++BOOL _DIBDRV_PutLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ DWORD *dst = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx);
++ RGBQUAD *c;
++ for(; width; width--)
++ {
++ c = (RGBQUAD *)dwBuf++;
++ *dst++ =
++ PlaceField32(c->rgbRed , bmp->redShift , bmp->redLen ) |
++ PlaceField32(c->rgbGreen, bmp->greenShift, bmp->greenLen) |
++ PlaceField32(c->rgbBlue , bmp->blueShift , bmp->blueLen );
++ }
++ return TRUE;
++}
++
++BOOL _DIBDRV_PutLine24(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + 3 * startx);
++ DWORD c;
++ for(; width; width--)
++ {
++ c = *dwBuf++;
++ *dst++ = c & 0x000000ff;
++ *dst++ = (c & 0x0000ff00) >> 8;
++ *dst++ = (c & 0x00ff0000) >> 16;
++ }
++ return TRUE;
++}
++
++BOOL _DIBDRV_PutLine16_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ WORD *dst = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx);
++ DWORD c;
++ for(; width; width--)
++ {
++ c = *dwBuf++;
++ *dst++ =
++ /* 0RRR|RRGG|GGGB|BBBB */
++ ((c & 0x000000f8) >> 3) |
++ ((c & 0x0000f800) >> 6) |
++ ((c & 0x00f80000) >> 9);
++ }
++ return TRUE;
++}
++
++BOOL _DIBDRV_PutLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ WORD *dst = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx);
++ DWORD c;
++
++ BYTE bShift = 8 - bmp->blueLen;
++ BYTE gShift = 16 - bmp->greenLen;
++ BYTE rShift = 24 - bmp->redLen;
++ for(; width; width--)
++ {
++ c = *dwBuf++;
++ *dst++ =
++ ((((c & 0x000000ff) >> bShift) << bmp->blueShift) & bmp->blueMask) |
++ ((((c & 0x0000ff00) >> gShift) << bmp->greenShift) & bmp->greenMask) |
++ ((((c & 0x00ff0000) >> rShift) << bmp->redShift) & bmp->redMask);
++ }
++ return TRUE;
++}
++
++BOOL _DIBDRV_PutLine8(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + startx);
++ DWORD c;
++ DWORD last_color = 0xffffffff;
++ int last_index = -1;
++
++ for(; width; width--)
++ {
++ c = *dwBuf++;
++
++ /* slight optimization, as images often have many
++ consecutive pixels with same color */
++ if(last_index == -1 || c != last_color)
++ {
++ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c));
++ last_color = c;
++ }
++ *dst++ = last_index;
++ }
++ return TRUE;
++}
++
++BOOL _DIBDRV_PutLine4(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 1));
++ DWORD c;
++ DWORD last_color = 0xffffffff;
++ int last_index = -1;
++
++ /* if startx is odd, put first nibble */
++ if(startx & 0x01)
++ {
++ c = *dwBuf++;
++
++ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c));
++ last_color = c;
++ *dst = (*dst & 0xf0) | last_index;
++ dst++;
++ width--;
++ }
++
++ /* then gets all full image bytes */
++ for( ; width > 1 ; width -= 2)
++ {
++ c = *dwBuf++;
++
++ /* slight optimization, as images often have many
++ consecutive pixels with same color */
++ if(last_index == -1 || c != last_color)
++ {
++ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c));
++ last_color = c;
++ }
++ *dst = last_index << 4;
++
++ c = *dwBuf++;
++
++ /* slight optimization, as images often have many
++ consecutive pixels with same color */
++ if(last_index == -1 || c != last_color)
++ {
++ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c));
++ last_color = c;
++ }
++ *dst++ |= last_index;
++ }
++
++ /* last nibble, if any */
++ if(width > 0)
++ {
++ c = *dwBuf;
++
++ /* slight optimization, as images often have many
++ consecutive pixels with same color */
++ if(last_index == -1 || c != last_color)
++ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c));
++ *dst = (*dst & 0x0f) | (last_index << 4);
++ }
++ return TRUE;
++}
++
++BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
++{
++ DWORD *dwBuf = (DWORD *)buf;
++ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 3));
++ BYTE b, mask;
++ char i;
++ DWORD c;
++
++ /* get foreground color */
++ DWORD back = *(DWORD *)bmp->colorTable & 0x00ffffff;
++ DWORD fore = *((DWORD *)bmp->colorTable + 1) & 0x00ffffff;
++
++ /* get 'light' color */
++ int lightColor = bmp->lightColor;
++
++ /* put first partial byte, if any */
++ startx &= 0x07;
++ mask = 0x80 >> startx;
++ startx = (8 - startx) & 0x07;
++ if(startx)
++ {
++ width -= startx;
++ b = *dst;
++ while(startx--)
++ {
++ c = *dwBuf++ & 0x00ffffff;
++ if(c == fore)
++ b |= mask;
++ else if(c == back)
++ b &= !mask;
++ else if((c == 0x00ffffff && lightColor) || (c == 0 && !lightColor))
++ b |= mask;
++ else
++ b &= !mask;
++ mask >>= 1;
++ }
++ *dst++ = b;
++ }
++
++ /* then puts full next bytes */
++ for( ; width > 7 ; width -= 8)
++ {
++ b = 0;
++ mask = 0x80;
++ for(i = 0 ; i < 8 ; i++)
++ {
++ c = *dwBuf++ & 0x00ffffff;
++ if(c == fore || (c == 0x00ffffff && c != back && lightColor) || (c == 0 && !lightColor))
++ b |= mask;
++ mask >>= 1;
++ }
++ *dst++ = b;
++ }
++
++ /* last partial byte, if any */
++ if(width > 0)
++ {
++ b = *dst;
++ mask = 0x80;
++ while(width--)
++ {
++ c = *dwBuf++ & 0x00ffffff;
++ if(c == fore)
++ b |= mask;
++ else if(c == back)
++ b &= !mask;
++ else if((c == 0x00ffffff && lightColor) || (c == 0 && !lightColor))
++ b |= mask;
++ else
++ b &= !mask;
++ mask >>= 1;
++ }
++ *dst = b;
++ }
++ return TRUE;
++}
+diff -Nru a/dlls/winedib.drv/primitives_font.c b/dlls/winedib.drv/primitives_font.c
+--- a/dlls/winedib.drv/primitives_font.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/primitives_font.c 2010-08-04 16:08:44.746222017 +0200
+@@ -0,0 +1,432 @@
++/*
++ * DIB Engine Font Primitives
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/* ------------------------------------------------------------*/
++/* FREETYPE FONT BITMAP BLITTING */
++void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
++{
++ /* FIXME : MUST BE OPTIMIZED !!! */
++
++ DIBDRVBITMAP *dib = physDev->physBitmap;
++ int bmpX, bmpY;
++ BYTE *buf;
++ int dibX, dibY;
++ int xMin, xMax, yMin, yMax;
++ DWORD *ptr;
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ DWORD c;
++ BYTE r, g, b, negColor;
++#else
++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
++#endif
++
++ /* gets clip limits */
++ xMin = clipRec->left;
++ yMin = clipRec->top;
++ xMax = clipRec->right;
++ yMax = clipRec->bottom;
++
++ /* loop for every pixel in bitmap */
++ buf = bmp->buffer;
++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
++ {
++ ptr = (DWORD *)((BYTE *)dib->bits + (dibY * dib->stride) + x * 4);
++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
++ {
++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
++ {
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ c = physDev->textColorTable[*buf];
++ if(*buf < 255)
++ {
++ negColor = 255 - *buf;
++ r = (*ptr >> 16) & 0xff;
++ g = (*ptr >> 8) & 0xff;
++ b = *ptr & 0xff;
++ c += MulDiv(r, 255 - *buf, 255) << 16 |
++ MulDiv(g, 255 - *buf, 255) << 8 |
++ MulDiv(b, 255 - *buf, 255);
++ }
++#endif
++ *ptr = c;
++ }
++ buf++;
++ ptr++;
++ }
++ }
++}
++
++void _DIBDRV_freetype_blit_32_RGB(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
++{
++ /* FIXME : MUST BE OPTIMIZED !!! */
++
++ DIBDRVBITMAP *dib = physDev->physBitmap;
++ int bmpX, bmpY;
++ BYTE *buf;
++ int dibX, dibY;
++ int xMin, xMax, yMin, yMax;
++ DWORD *ptr;
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ DWORD c;
++ BYTE r, g, b, negColor;
++#else
++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
++#endif
++
++ /* gets DIB limits */
++ xMin = clipRec->left;
++ yMin = clipRec->top;
++ xMax = clipRec->right;
++ yMax = clipRec->bottom;
++
++ /* loop for every pixel in bitmap */
++ buf = bmp->buffer;
++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
++ {
++ ptr = (DWORD *)((BYTE *)dib->bits + (dibY * dib->stride) + x * 4);
++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
++ {
++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
++ {
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ c = physDev->textColorTable[*buf];
++ if(*buf < 255)
++ {
++ negColor = 255 - *buf;
++ r = (*ptr >> 16) & 0xff;
++ g = (*ptr >> 8) & 0xff;
++ b = *ptr & 0xff;
++ c += MulDiv(r, 255 - *buf, 255) << 16 |
++ MulDiv(g, 255 - *buf, 255) << 8 |
++ MulDiv(b, 255 - *buf, 255);
++ }
++#endif
++ *ptr = c;
++ }
++ buf++;
++ ptr++;
++ }
++ }
++}
++
++void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
++{
++ /* FIXME : MUST BE OPTIMIZED !!! */
++
++ DIBDRVBITMAP *dib = physDev->physBitmap;
++ int bmpX, bmpY;
++ BYTE *buf;
++ int dibX, dibY;
++ int xMin, xMax, yMin, yMax;
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ DWORD c;
++ COLORREF pix;
++ BYTE r, g, b, negColor;
++#else
++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
++#endif
++
++ /* gets DIB limits */
++ xMin = clipRec->left;
++ yMin = clipRec->top;
++ xMax = clipRec->right;
++ yMax = clipRec->bottom;
++
++ /* loop for every pixel in bitmap */
++ buf = bmp->buffer;
++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
++ {
++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
++ {
++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
++ {
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ c = physDev->textColorTable[*buf];
++ if(*buf < 255)
++ {
++ negColor = 255 - *buf;
++ pix = dib->funcs->GetPixel(dib, dibX, dibY);
++ r = pix & 0xff;
++ g = (pix >> 8) & 0xff;
++ b = (pix >> 16) & 0xff;
++ c += MulDiv(r, 255 - *buf, 255) << 16 |
++ MulDiv(g, 255 - *buf, 255) << 8 |
++ MulDiv(b, 255 - *buf, 255);
++ }
++#endif
++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
++ }
++ buf++;
++ }
++ }
++}
++
++void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
++{
++ /* FIXME : MUST BE OPTIMIZED !!! */
++
++ DIBDRVBITMAP *dib = physDev->physBitmap;
++ int bmpX, bmpY;
++ BYTE *buf;
++ int dibX, dibY;
++ int xMin, xMax, yMin, yMax;
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ DWORD c;
++ COLORREF pix;
++ BYTE r, g, b, negColor;
++#else
++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
++#endif
++
++ /* gets DIB limits */
++ xMin = clipRec->left;
++ yMin = clipRec->top;
++ xMax = clipRec->right;
++ yMax = clipRec->bottom;
++
++ /* loop for every pixel in bitmap */
++ buf = bmp->buffer;
++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
++ {
++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
++ {
++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
++ {
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ c = physDev->textColorTable[*buf];
++ if(*buf < 255)
++ {
++ negColor = 255 - *buf;
++ pix = dib->funcs->GetPixel(dib, dibX, dibY);
++ r = pix & 0xff;
++ g = (pix >> 8) & 0xff;
++ b = (pix >> 16) & 0xff;
++ c += MulDiv(r, 255 - *buf, 255) << 16 |
++ MulDiv(g, 255 - *buf, 255) << 8 |
++ MulDiv(b, 255 - *buf, 255);
++ }
++#endif
++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
++ }
++ buf++;
++ }
++ }
++}
++
++void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
++{
++ /* FIXME : MUST BE OPTIMIZED !!! */
++
++ DIBDRVBITMAP *dib = physDev->physBitmap;
++ int bmpX, bmpY;
++ BYTE *buf;
++ int dibX, dibY;
++ int xMin, xMax, yMin, yMax;
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ DWORD c;
++ COLORREF pix;
++ BYTE r, g, b, negColor;
++#else
++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
++#endif
++
++ /* gets DIB limits */
++ xMin = clipRec->left;
++ yMin = clipRec->top;
++ xMax = clipRec->right;
++ yMax = clipRec->bottom;
++
++ /* loop for every pixel in bitmap */
++ buf = bmp->buffer;
++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
++ {
++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
++ {
++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
++ {
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ c = physDev->textColorTable[*buf];
++ if(*buf < 255)
++ {
++ negColor = 255 - *buf;
++ pix = dib->funcs->GetPixel(dib, dibX, dibY);
++ r = pix & 0xff;
++ g = (pix >> 8) & 0xff;
++ b = (pix >> 16) & 0xff;
++ c += MulDiv(r, 255 - *buf, 255) << 16 |
++ MulDiv(g, 255 - *buf, 255) << 8 |
++ MulDiv(b, 255 - *buf, 255);
++ }
++#endif
++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
++ }
++ buf++;
++ }
++ }
++}
++
++void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
++{
++ /* FIXME : MUST BE OPTIMIZED !!! */
++
++ DIBDRVBITMAP *dib = physDev->physBitmap;
++ int bmpX, bmpY;
++ BYTE *buf;
++ int dibX, dibY;
++ int xMin, xMax, yMin, yMax;
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ DWORD c;
++ COLORREF pix;
++ BYTE r, g, b, negColor;
++#else
++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor);
++#endif
++
++ /* gets DIB limits */
++ xMin = clipRec->left;
++ yMin = clipRec->top;
++ xMax = clipRec->right;
++ yMax = clipRec->bottom;
++
++ /* loop for every pixel in bitmap */
++ buf = bmp->buffer;
++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
++ {
++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
++ {
++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
++ {
++#ifdef DIBDRV_ANTIALIASED_FONTS
++ c = physDev->textColorTable[*buf];
++ if(*buf < 255)
++ {
++ negColor = 255 - *buf;
++ pix = dib->funcs->GetPixel(dib, dibX, dibY);
++ r = pix & 0xff;
++ g = (pix >> 8) & 0xff;
++ b = (pix >> 16) & 0xff;
++ c += MulDiv(r, 255 - *buf, 255) << 16 |
++ MulDiv(g, 255 - *buf, 255) << 8 |
++ MulDiv(b, 255 - *buf, 255);
++ }
++#endif
++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
++ }
++ buf++;
++ }
++ }
++}
++
++void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
++{
++ /* FIXME : MUST BE OPTIMIZED !!! */
++
++ DIBDRVBITMAP *dib = physDev->physBitmap;
++ int bmpX, bmpY;
++ BYTE *buf;
++ int dibX, dibY;
++ int xMin, xMax, yMin, yMax;
++ DWORD c = physDev->textColor;
++
++ /* gets DIB limits */
++ xMin = clipRec->left;
++ yMin = clipRec->top;
++ xMax = clipRec->right;
++ yMax = clipRec->bottom;
++
++ /* loop for every pixel in bitmap */
++ buf = bmp->buffer;
++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
++ {
++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
++ {
++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
++ buf++;
++ }
++ }
++}
++
++void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
++{
++ /* FIXME : MUST BE OPTIMIZED !!! */
++
++ DIBDRVBITMAP *dib = physDev->physBitmap;
++ int bmpX, bmpY;
++ BYTE *buf;
++ int dibX, dibY;
++ int xMin, xMax, yMin, yMax;
++ DWORD c = physDev->textColor;
++
++ /* gets DIB limits */
++ xMin = clipRec->left;
++ yMin = clipRec->top;
++ xMax = clipRec->right;
++ yMax = clipRec->bottom;
++
++ /* loop for every pixel in bitmap */
++ buf = bmp->buffer;
++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
++ {
++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
++ {
++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
++ buf++;
++ }
++ }
++}
++
++void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp)
++{
++ /* FIXME : MUST BE OPTIMIZED !!! */
++
++ DIBDRVBITMAP *dib = physDev->physBitmap;
++ int bmpX, bmpY;
++ BYTE *buf;
++ int dibX, dibY;
++ int xMin, xMax, yMin, yMax;
++ DWORD c = physDev->textColor;
++
++ /* gets DIB limits */
++ xMin = clipRec->left;
++ yMin = clipRec->top;
++ xMax = clipRec->right;
++ yMax = clipRec->bottom;
++
++ /* loop for every pixel in bitmap */
++ buf = bmp->buffer;
++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
++ {
++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
++ {
++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf)
++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
++ buf++;
++ }
++ }
++}
+diff -Nru a/dlls/winedib.drv/primitives_line.c b/dlls/winedib.drv/primitives_line.c
+--- a/dlls/winedib.drv/primitives_line.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/primitives_line.c 2010-08-04 16:08:44.502222017 +0200
+@@ -0,0 +1,434 @@
++/*
++ * DIB Engine line Primitives
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/* ------------------------------------------------------------*/
++/* HORIZONTAL LINES */
++void _DIBDRV_SolidHLine32(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
++{
++ DWORD *ptr;
++ int i;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++
++ for(i = start; i < end; i++)
++ _DIBDRV_rop32(ptr++, and, xor);
++}
++
++void _DIBDRV_SolidHLine24(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
++{
++ BYTE *ptr;
++ int i;
++ BYTE and_bytes[3], xor_bytes[3];
++
++ and_bytes[0] = and & 0xff;
++ and_bytes[1] = (and >> 8) & 0xff;
++ and_bytes[2] = (and >> 16) & 0xff;
++ xor_bytes[0] = xor & 0xff;
++ xor_bytes[1] = (xor >> 8) & 0xff;
++ xor_bytes[2] = (xor >> 16) & 0xff;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++
++ for(i = start; i < end; i++)
++ {
++ _DIBDRV_rop8(ptr++, and_bytes[0], xor_bytes[0]);
++ _DIBDRV_rop8(ptr++, and_bytes[1], xor_bytes[1]);
++ _DIBDRV_rop8(ptr++, and_bytes[2], xor_bytes[2]);
++ }
++}
++
++void _DIBDRV_SolidHLine16(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
++{
++ WORD *ptr;
++ int i;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++
++ for(i = start; i < end; i++)
++ _DIBDRV_rop16(ptr++, and, xor);
++}
++
++void _DIBDRV_SolidHLine8(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
++{
++ BYTE *ptr;
++ int i;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++
++ for(i = start; i < end; i++)
++ _DIBDRV_rop8(ptr++, and, xor);
++}
++
++void _DIBDRV_SolidHLine4(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
++{
++ BYTE *ptr;
++ int i;
++ BYTE byte_and, byte_xor;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++ byte_and = (and & 0xf) | ((and << 4) & 0xf0);
++ byte_xor = (xor & 0xf) | ((xor << 4) & 0xf0);
++
++ if(start & 1) /* upper nibble untouched */
++ _DIBDRV_rop8(ptr++, byte_and | 0xf0, byte_xor & 0x0f);
++
++ for(i = (start + 1) / 2; i < end / 2; i++)
++ _DIBDRV_rop8(ptr++, byte_and, byte_xor);
++
++ if(end & 1) /* lower nibble untouched */
++ _DIBDRV_rop8(ptr, byte_and | 0x0f, byte_xor & 0xf0);
++}
++
++void _DIBDRV_SolidHLine1(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
++{
++ BYTE *ptr;
++ int i;
++ BYTE byte_and = 0, byte_xor = 0, mask;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++
++ if(and & 1) byte_and = 0xff;
++ if(xor & 1) byte_xor = 0xff;
++
++ if((start & ~7) == (end & ~7)) /* special case run inside one byte */
++ {
++ mask = ((1L << ((end & 7) - (start & 7))) - 1) << (8 - (end & 7));
++ _DIBDRV_rop8(ptr, byte_and | ~mask, byte_xor & mask);
++ return;
++ }
++
++ if(start & 7)
++ {
++ mask = (1 << (8 - (start & 7))) - 1;
++ _DIBDRV_rop8(ptr++, byte_and | ~mask, byte_xor & mask);
++ }
++
++ for(i = (start + 7) / 8; i < end / 8; i++)
++ _DIBDRV_rop8(ptr++, byte_and, byte_xor);
++
++ if(end & 7)
++ {
++ mask = ~((1 << (8 - (end & 7))) - 1);
++ _DIBDRV_rop8(ptr++, byte_and | ~mask, byte_xor & mask);
++ }
++}
++
++void _DIBDRV_PatternHLine32(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
++{
++ DWORD *ptr;
++ const DWORD *and_ptr = and, *xor_ptr = xor;
++ int i;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++
++ and_ptr += offset;
++ xor_ptr += offset;
++ for(i = start; i < end; i++)
++ {
++ _DIBDRV_rop32(ptr++, *and_ptr++, *xor_ptr++);
++ if(++offset == count)
++ {
++ offset = 0;
++ and_ptr = and;
++ xor_ptr = xor;
++ }
++ }
++}
++
++void _DIBDRV_PatternHLine24(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
++{
++ BYTE *ptr;
++ const BYTE *and_ptr = and, *xor_ptr = xor;
++ int i;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++
++ and_ptr += offset * 3;
++ xor_ptr += offset * 3;
++
++ for(i = start; i < end; i++)
++ {
++ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
++ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
++ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
++ if(++offset == count)
++ {
++ offset = 0;
++ and_ptr = and;
++ xor_ptr = xor;
++ }
++ }
++}
++
++void _DIBDRV_PatternHLine16(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
++{
++ WORD *ptr;
++ const WORD *and_ptr = and, *xor_ptr = xor;
++ int i;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++
++ and_ptr += offset;
++ xor_ptr += offset;
++
++ for(i = start; i < end; i++)
++ {
++ _DIBDRV_rop16(ptr++, *and_ptr++, *xor_ptr++);
++ if(++offset == count)
++ {
++ offset = 0;
++ and_ptr = and;
++ xor_ptr = xor;
++ }
++ }
++}
++
++void _DIBDRV_PatternHLine8(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
++{
++ BYTE *ptr;
++ const BYTE *and_ptr = and, *xor_ptr = xor;
++ int i;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++
++ and_ptr += offset;
++ xor_ptr += offset;
++
++ for(i = start; i < end; i++)
++ {
++ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
++ if(++offset == count)
++ {
++ offset = 0;
++ and_ptr = and;
++ xor_ptr = xor;
++ }
++ }
++}
++
++void _DIBDRV_PatternHLine4(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
++{
++ BYTE *ptr;
++ const BYTE *and_ptr = and, *xor_ptr = xor;
++ int i;
++ BYTE byte_and, byte_xor;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++
++ and_ptr += offset / 2;
++ xor_ptr += offset / 2;
++
++ for(i = start; i < end; i++)
++ {
++ if(offset & 1)
++ {
++ byte_and = *and_ptr++ & 0x0f;
++ byte_xor = *xor_ptr++ & 0x0f;
++ }
++ else
++ {
++ byte_and = (*and_ptr & 0xf0) >> 4;
++ byte_xor = (*xor_ptr & 0xf0) >> 4;
++ }
++
++ if(i & 1)
++ byte_and |= 0xf0;
++ else
++ {
++ byte_and = (byte_and << 4) | 0x0f;
++ byte_xor <<= 4;
++ }
++
++ _DIBDRV_rop8(ptr, byte_and, byte_xor);
++
++ if(i & 1) ptr++;
++
++ if(++offset == count)
++ {
++ offset = 0;
++ and_ptr = and;
++ xor_ptr = xor;
++ }
++ }
++}
++
++void _DIBDRV_PatternHLine1(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
++{
++ BYTE *ptr;
++ const BYTE *and_ptr = and, *xor_ptr = xor;
++ int i;
++ BYTE byte_and, byte_xor, dst_mask, brush_mask;
++
++ ptr = dib->funcs->GetPixelPointer(dib, start, row);
++
++ and_ptr += offset / 8;
++ xor_ptr += offset / 8;
++
++ for(i = start; i < end; i++)
++ {
++ dst_mask = 1 << (7 - (i & 7));
++ brush_mask = 1 << (7 - (offset & 7));
++
++ byte_and = (*and_ptr & brush_mask) ? 0xff : 0;
++ byte_xor = (*xor_ptr & brush_mask) ? 0xff : 0;
++
++ byte_and |= ~dst_mask;
++ byte_xor &= dst_mask;
++
++ _DIBDRV_rop8(ptr, byte_and, byte_xor);
++
++ if((i & 7) == 7) ptr++;
++ if(++offset == count)
++ {
++ offset = 0;
++ and_ptr = and;
++ xor_ptr = xor;
++ }
++ else if((offset & 7) == 7)
++ {
++ and_ptr++;
++ xor_ptr++;
++ }
++ }
++}
++
++/* ------------------------------------------------------------*/
++/* VERTICAL LINES */
++void _DIBDRV_SolidVLine32(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
++{
++ BYTE *ptr;
++ int i;
++
++ ptr = dib->funcs->GetPixelPointer(dib, col, start);
++
++ for(i = start; i < end; i++)
++ {
++ _DIBDRV_rop32((DWORD*)ptr, and, xor);
++ ptr += dib->stride;
++ }
++}
++
++void _DIBDRV_SolidVLine24(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
++{
++ BYTE *ptr;
++ int i;
++ BYTE and_bytes[3], xor_bytes[3];
++
++ and_bytes[0] = and & 0xff;
++ and_bytes[1] = (and >> 8) & 0xff;
++ and_bytes[2] = (and >> 16) & 0xff;
++ xor_bytes[0] = xor & 0xff;
++ xor_bytes[1] = (xor >> 8) & 0xff;
++ xor_bytes[2] = (xor >> 16) & 0xff;
++
++ ptr = dib->funcs->GetPixelPointer(dib, col, start);
++
++ for(i = start; i < end; i++)
++ {
++ _DIBDRV_rop8(ptr, and_bytes[0], xor_bytes[0]);
++ _DIBDRV_rop8(ptr + 1, and_bytes[1], xor_bytes[1]);
++ _DIBDRV_rop8(ptr + 2, and_bytes[2], xor_bytes[2]);
++ ptr += dib->stride;
++ }
++}
++
++void _DIBDRV_SolidVLine16(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
++{
++ BYTE *ptr;
++ int i;
++
++ ptr = dib->funcs->GetPixelPointer(dib, col, start);
++
++ for(i = start; i < end; i++)
++ {
++ _DIBDRV_rop16((WORD*)ptr, and, xor);
++ ptr += dib->stride;
++ }
++}
++
++void _DIBDRV_SolidVLine8(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
++{
++ BYTE *ptr;
++ int i;
++
++ ptr = dib->funcs->GetPixelPointer(dib, col, start);
++
++ for(i = start; i < end; i++)
++ {
++ _DIBDRV_rop8(ptr, and, xor);
++ ptr += dib->stride;
++ }
++}
++
++void _DIBDRV_SolidVLine4(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
++{
++ BYTE *ptr;
++ int i;
++ BYTE byte_and, byte_xor;
++
++ if(col & 1) /* upper nibble untouched */
++ {
++ byte_and = (and & 0xf) | 0xf0;
++ byte_xor = (xor & 0xf);
++ }
++ else
++ {
++ byte_and = ((and << 4) & 0xf0) | 0x0f;
++ byte_xor = ((xor << 4) & 0xf0);
++ }
++
++ ptr = dib->funcs->GetPixelPointer(dib, col, start);
++
++ for(i = start; i < end; i++)
++ {
++ _DIBDRV_rop8(ptr, byte_and, byte_xor);
++ ptr += dib->stride;
++ }
++}
++
++void _DIBDRV_SolidVLine1(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
++{
++ BYTE *ptr;
++ int i;
++ BYTE byte_and = 0, byte_xor = 0, mask;
++
++ if(and & 1) byte_and = 0xff;
++ if(xor & 1) byte_xor = 0xff;
++
++ mask = 1 << (7 - (col & 7));
++
++ byte_and |= ~mask;
++ byte_xor &= mask;
++
++ ptr = dib->funcs->GetPixelPointer(dib, col, start);
++
++ for(i = start; i < end; i++)
++ {
++ _DIBDRV_rop8(ptr, byte_and, byte_xor);
++ ptr += dib->stride;
++ }
++}
+diff -Nru a/dlls/winedib.drv/primitives_pixel.c b/dlls/winedib.drv/primitives_pixel.c
+--- a/dlls/winedib.drv/primitives_pixel.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/primitives_pixel.c 2010-08-04 16:08:44.643222017 +0200
+@@ -0,0 +1,240 @@
++/*
++ * DIB Engine pixel Primitives
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/* ------------------------------------------------------------*/
++/* BITFIELD HELPERS */
++static inline DWORD GetField32 (DWORD pixel, int shift, int len)
++{
++ pixel = pixel & (((1 << (len)) - 1) << shift);
++ pixel = pixel << (32 - (shift + len)) >> 24;
++ return pixel;
++}
++
++/* ------------------------------------------------------------*/
++/* PIXEL POINTER READING */
++void *_DIBDRV_GetPixelPointer32(const DIBDRVBITMAP *dib, int x, int y)
++{
++ BYTE *ptr = dib->bits;
++
++ ptr += (y * dib->stride);
++
++ ptr += x * 4;
++ return ptr;
++}
++
++void *_DIBDRV_GetPixelPointer24(const DIBDRVBITMAP *dib, int x, int y)
++{
++ BYTE *ptr = dib->bits;
++
++ ptr += (y * dib->stride);
++
++ ptr += x * 3;
++ return ptr;
++}
++
++void *_DIBDRV_GetPixelPointer16(const DIBDRVBITMAP *dib, int x, int y)
++{
++ BYTE *ptr = dib->bits;
++
++ ptr += (y * dib->stride);
++
++ ptr += x * 2;
++ return ptr;
++}
++
++void *_DIBDRV_GetPixelPointer8(const DIBDRVBITMAP *dib, int x, int y)
++{
++ BYTE *ptr = dib->bits;
++
++ ptr += (y * dib->stride);
++
++ ptr += x;
++ return ptr;
++}
++
++void *_DIBDRV_GetPixelPointer4(const DIBDRVBITMAP *dib, int x, int y)
++{
++ BYTE *ptr = dib->bits;
++
++ ptr += (y * dib->stride);
++
++ ptr += x / 2;
++ return ptr;
++}
++
++void *_DIBDRV_GetPixelPointer1(const DIBDRVBITMAP *dib, int x, int y)
++{
++ BYTE *ptr = dib->bits;
++
++ ptr += (y * dib->stride);
++
++ ptr += x / 8;
++ return ptr;
++}
++
++/* ------------------------------------------------------------*/
++/* PIXEL WRITING */
++void _DIBDRV_SetPixel32(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
++{
++ DWORD *ptr = dib->funcs->GetPixelPointer(dib, x, y);
++ _DIBDRV_rop32(ptr, and, xor);
++}
++
++void _DIBDRV_SetPixel24(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
++{
++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y);
++ _DIBDRV_rop8(ptr, and & 0xff, xor & 0xff);
++ _DIBDRV_rop8(ptr + 1, (and >> 8) & 0xff, (xor >> 8) & 0xff);
++ _DIBDRV_rop8(ptr + 2, (and >> 16) & 0xff, (xor >> 16) & 0xff);
++}
++
++void _DIBDRV_SetPixel16(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
++{
++ WORD *ptr = dib->funcs->GetPixelPointer(dib, x, y);
++ _DIBDRV_rop16(ptr, and, xor);
++}
++
++void _DIBDRV_SetPixel8(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
++{
++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y);
++ _DIBDRV_rop8(ptr, and, xor);
++}
++
++void _DIBDRV_SetPixel4(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
++{
++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y);
++ BYTE byte_and, byte_xor;
++
++ if(x & 1) /* upper nibble untouched */
++ {
++ byte_and = (and & 0xf) | 0xf0;
++ byte_xor = (xor & 0xf);
++ }
++ else
++ {
++ byte_and = ((and << 4) & 0xf0) | 0x0f;
++ byte_xor = ((xor << 4) & 0xf0);
++ }
++
++ _DIBDRV_rop8(ptr, byte_and, byte_xor);
++}
++
++void _DIBDRV_SetPixel1(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
++{
++ BYTE *ptr;
++ BYTE byte_and = 0, byte_xor = 0, mask;
++
++ if(and & 1) byte_and = 0xff;
++ if(xor & 1) byte_xor = 0xff;
++
++ mask = 1 << (7 - (x & 7));
++
++ byte_and |= ~mask;
++ byte_xor &= mask;
++
++ ptr = dib->funcs->GetPixelPointer(dib, x, y);
++
++ _DIBDRV_rop8(ptr, byte_and, byte_xor);
++}
++
++/* ------------------------------------------------------------*/
++/* PIXEL READING */
++DWORD _DIBDRV_GetPixel32_RGB(const DIBDRVBITMAP *dib, int x, int y)
++{
++ DWORD c = *(DWORD *)dib->funcs->GetPixelPointer(dib, x, y);
++ return
++ ((c & 0x000000ff) << 16) |
++ ((c & 0x0000ff00) ) |
++ ((c & 0x00ff0000) >> 16) |
++ ( c & 0xff000000 ); /* last one for alpha channel */
++}
++
++DWORD _DIBDRV_GetPixel32_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y)
++{
++ DWORD *ptr = dib->funcs->GetPixelPointer(dib, x, y);
++
++ return GetField32(*ptr, dib->redShift, dib->redLen) |
++ GetField32(*ptr, dib->greenShift, dib->greenLen) << 8 |
++ GetField32(*ptr, dib->blueShift, dib->blueLen) << 16;
++}
++
++DWORD _DIBDRV_GetPixel24(const DIBDRVBITMAP *dib, int x, int y)
++{
++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y);
++ return ((WORD)ptr[0] << 16) | ((WORD)ptr[1] << 8) | (WORD)ptr[2];
++}
++
++DWORD _DIBDRV_GetPixel16_RGB(const DIBDRVBITMAP *dib, int x, int y)
++{
++ WORD c = *(WORD *)dib->funcs->GetPixelPointer(dib, x, y);
++ /* 0RRR|RRGG|GGGB|BBBB */
++ return ((c & 0x7c00) >> 7) | ((c & 0x03e0) << 6) | ((c & 0x001f) << 19);
++}
++
++DWORD _DIBDRV_GetPixel16_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y)
++{
++ WORD c = *(WORD *)dib->funcs->GetPixelPointer(dib, x, y);
++
++ return (((c & dib->blueMask ) >> dib->blueShift ) << (24 - dib->blueLen )) |
++ (((c & dib->greenMask) >> dib->greenShift) << (16 - dib->greenLen)) |
++ (((c & dib->redMask ) >> dib->redShift ) << ( 8 - dib->redLen ));
++}
++
++DWORD _DIBDRV_GetPixel8(const DIBDRVBITMAP *dib, int x, int y)
++{
++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y);
++ RGBQUAD *color = dib->colorTable + *ptr;
++ return (color->rgbRed) | (color->rgbGreen << 8) | (color->rgbBlue << 16);
++}
++
++DWORD _DIBDRV_GetPixel4(const DIBDRVBITMAP *dib, int x, int y)
++{
++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y), pix;
++ RGBQUAD *color;
++
++ if(x & 1)
++ pix = *ptr & 0x0f;
++ else
++ pix = *ptr >> 4;
++
++ color = dib->colorTable + pix;
++ return (color->rgbRed) | (color->rgbGreen << 8) | (color->rgbBlue << 16);
++}
++
++DWORD _DIBDRV_GetPixel1(const DIBDRVBITMAP *dib, int x, int y)
++{
++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y), pix;
++ RGBQUAD *color;
++
++ pix = *ptr;
++
++ pix >>= (7 - (x & 7));
++ pix &= 1;
++
++ color = dib->colorTable + pix;
++ return (color->rgbRed) | (color->rgbGreen << 8) | (color->rgbBlue << 16);
++}
+diff -Nru a/dlls/winedib.drv/primitives_rop2.c b/dlls/winedib.drv/primitives_rop2.c
+--- a/dlls/winedib.drv/primitives_rop2.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/primitives_rop2.c 2010-08-04 16:08:44.508222017 +0200
+@@ -0,0 +1,112 @@
++/*
++ * DIB Engine ROP2 Primitives
++ *
++ * Copyright 2008 Huw Davies
++ * Copyright 2008 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/* ------------------------------------------------------------*/
++/* BASIC ROP HELPER */
++/*
++ *
++ * Decompose the 16 ROP2s into an expression of the form
++ *
++ * D = (D & A) ^ X
++ *
++ * Where A and X depend only on P (and so can be precomputed).
++ *
++ * A X
++ *
++ * R2_BLACK 0 0 0
++ * R2_NOTMERGEPEN ~(D | P) ~P ~P
++ * R2_MASKNOTPEN ~P & D ~P 0
++ * R2_NOTCOPYPEN ~P 0 ~P
++ * R2_MASKPENNOT P & ~D P P
++ * R2_NOT ~D 1 1
++ * R2_XORPEN P ^ D 1 P
++ * R2_NOTMASKPEN ~(P & D) P 1
++ * R2_MASKPEN P & D P 0
++ * R2_NOTXORPEN ~(P ^ D) 1 ~P
++ * R2_NOP D 1 0
++ * R2_MERGENOTPEN ~P | D P ~P
++ * R2_COPYPEN P 0 P
++ * R2_MERGEPENNOT P | ~D ~P 1
++ * R2_MERGEPEN P | D ~P P
++ * R2_WHITE 1 0 1
++ *
++ */
++
++/* A = (P & A1) | (~P & A2) */
++#define ZERO {0, 0}
++#define ONE {0xffffffff, 0xffffffff}
++#define P {0xffffffff, 0}
++#define NOT_P {0, 0xffffffff}
++
++static const DWORD rop2_and_array[16][2] =
++{
++ ZERO, NOT_P, NOT_P, ZERO,
++ P, ONE, ONE, P,
++ P, ONE, ONE, P,
++ ZERO, NOT_P, NOT_P, ZERO
++};
++
++/* X = (P & X1) | (~P & X2) */
++static const DWORD rop2_xor_array[16][2] =
++{
++ ZERO, NOT_P, ZERO, NOT_P,
++ P, ONE, P, ONE,
++ ZERO, NOT_P, ZERO, NOT_P,
++ P, ONE, P, ONE
++};
++
++#undef NOT_P
++#undef P
++#undef ONE
++#undef ZERO
++
++void _DIBDRV_CalcAndXorMasks(INT rop, DWORD color, DWORD *and, DWORD *xor)
++{
++ /* NB The ROP2 codes start at one and the arrays are zero-based */
++ rop = (rop - 1) & 0x0f;
++ *and = (color & rop2_and_array[rop][0]) | ((~color) & rop2_and_array[rop][1]);
++ *xor = (color & rop2_xor_array[rop][0]) | ((~color) & rop2_xor_array[rop][1]);
++}
++
++/* ------------------------------------------------------------*/
++/* ROP PIXEL FUNCTIONS */
++
++inline void _DIBDRV_rop32(DWORD *ptr, DWORD and, DWORD xor)
++{
++ *ptr = (*ptr & and) ^ xor;
++}
++
++inline void _DIBDRV_rop16(WORD *ptr, WORD and, WORD xor)
++{
++ *ptr = (*ptr & and) ^ xor;
++}
++
++inline void _DIBDRV_rop8(BYTE *ptr, BYTE and, BYTE xor)
++{
++ *ptr = (*ptr & and) ^ xor;
++}
+diff -Nru a/dlls/winedib.drv/primitives_rop3.c b/dlls/winedib.drv/primitives_rop3.c
+--- a/dlls/winedib.drv/primitives_rop3.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/primitives_rop3.c 2010-08-04 16:08:44.599222017 +0200
+@@ -0,0 +1,786 @@
++#include "config.h"
++#include "wine/port.h"
++
++#include "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/* the ROP3 operations
++ this is a BIG case block; beware that some
++ commons ROP3 operations will be optimized
++ from inside blt routines */
++DWORD _DIBDRV_ROP3(DWORD p, DWORD s, DWORD d, BYTE rop)
++{
++ switch(rop)
++ {
++ case 0x00: /* 0 BLACKNESS */
++ return 0;
++
++ case 0x01: /* DPSoon */
++ return (~(p | s | d)) & 0x00ffffff;
++
++ case 0x02: /* DPSona */
++ return (d & ~(p | s)) & 0x00ffffff;
++
++ case 0x03: /* PSon */
++ return (~(p | s)) & 0x00ffffff;
++
++ case 0x04: /* SDPona */
++ return (s & ~(d | p)) & 0x00ffffff;
++
++ case 0x05: /* DPon */
++ return (~(d | p)) & 0x00ffffff;
++
++ case 0x06: /* PDSxnon */
++ return (~(p | ~(d ^ s))) & 0x00ffffff;
++
++ case 0x07: /* PDSaon */
++ return (~((d & s) | p) ) & 0x00ffffff;
++
++ case 0x08: /* SDPnaa */
++ return (d & ~p & s) & 0x00ffffff;
++
++ case 0x09: /* PDSxon */
++ return (~((d ^ s) | p)) & 0x00ffffff;
++
++ case 0x0A: /* DPna */
++ return (~p & d) & 0x00ffffff;
++
++ case 0x0B: /* PSDnaon */
++ return (~((~d & s) | p)) & 0x00ffffff;
++
++ case 0x0C: /* SPna */
++ return (~p & s) & 0x00ffffff;
++
++ case 0x0D: /* PDSnaon */
++ return (~((~s & d) | p)) & 0x00ffffff;
++
++ case 0x0E: /* PDSonon */
++ return (~(~(d | s) | p)) & 0x00ffffff;
++
++ case 0x0F: /* Pn */
++ return (~p) & 0x00ffffff;
++
++ case 0x10: /* PDSona */
++ return (~(d | s) & p) & 0x00ffffff;
++
++ case 0x11: /* DSon NOTSRCERASE */
++ return (~(d | s)) & 0x00ffffff;
++
++ case 0x12: /* SDPxnon */
++ return (~(~(d ^ p) | s)) & 0x00ffffff;
++
++ case 0x13: /* SDPaon */
++ return (~((d & p) | s)) & 0x00ffffff;
++
++ case 0x14: /* DPSxnon */
++ return (~(~(p ^ s) | d)) & 0x00ffffff;
++
++ case 0x15: /* DPSaon */
++ return (~((p & s) | d)) & 0x00ffffff;
++
++ case 0x16: /* PSDPSanaxx */
++ return (((~(p & s) & d) ^ s) ^ p) & 0x00ffffff;
++
++ case 0x17: /* SSPxDSxaxn */
++ return (~(((d ^ s) & (s ^ p)) ^ s)) & 0x00ffffff;
++
++ case 0x18: /* SPxPDxa */
++ return ((s ^ p) & (p ^ d)) & 0x00ffffff;
++
++ case 0x19: /* SDPSanaxn */
++ return (~((~(p & s) & d) ^ s)) & 0x00ffffff;
++
++ case 0x1A: /* PDSPaox */
++ return (((s & p) | d) ^ p) & 0x00ffffff;
++
++ case 0x1B: /* SDPSxaxn */
++ return (~(((p ^ s) & d) ^ s)) & 0x00ffffff;
++
++ case 0x1C: /* PSDPaox */
++ return (((d & p) | s) ^ p) & 0x00ffffff;
++
++ case 0x1D: /* DSPDxaxn */
++ return (~(((p ^ d) & s) ^ d)) & 0x00ffffff;
++
++ case 0x1E: /* PDSox */
++ return ((d | s) ^ p) & 0x00ffffff;
++
++ case 0x1F: /* PDSoan */
++ return (~((d | s) & p)) & 0x00ffffff;
++
++ case 0x20: /* DPSnaa */
++ return (p & ~s & d) & 0x00ffffff;
++
++ case 0x21: /* SDPxon */
++ return (~((d ^ p) | s)) & 0x00ffffff;
++
++ case 0x22: /* DSna */
++ return (d & ~s) & 0x00ffffff;
++
++ case 0x23: /* SPDnaon */
++ return (~((p & ~d) | s)) & 0x00ffffff;
++
++ case 0x24: /* SPxDSxa */
++ return ((s ^ p) & (d ^ s)) & 0x00ffffff;
++
++ case 0x25: /* PDSPanaxn */
++ return (~((~(s & p) & d) ^ p)) & 0x00ffffff;
++
++ case 0x26: /* SDPSaox */
++ return (((p & s) | d) ^ s) & 0x00ffffff;
++
++ case 0x27: /* SDPSxnox */
++ return ((~(p ^ s) | d) ^ s) & 0x00ffffff;
++
++ case 0x28: /* DPSxa */
++ return ((p ^ s) & d) & 0x00ffffff;
++
++ case 0x29: /* PSDPSaoxxn */
++ return (~((((p & s) | d) ^ s) ^ p)) & 0x00ffffff;
++
++ case 0x2A: /* DPSana */
++ return (~(p & s) & d) & 0x00ffffff;
++
++ case 0x2B: /* SSPxPDxaxn */
++ return (~(((s ^ p) & (p ^ d)) ^ s)) & 0x00ffffff;
++
++ case 0x2C: /* SPDSoax */
++ return (((d | s) & p) ^ s) & 0x00ffffff;
++
++ case 0x2D: /* PSDnox */
++ return ((s | ~d) ^ p) & 0x00ffffff;
++
++ case 0x2E: /* PSDPxox */
++ return (((d ^ p) | s) ^ p) & 0x00ffffff;
++
++ case 0x2F: /* PSDnoan */
++ return (~((s | ~d) & p)) & 0x00ffffff;
++
++ case 0x30: /* PSna */
++ return (p & ~s) & 0x00ffffff;
++
++ case 0x31: /* SDPnaon */
++ return (~((d & ~p) | s)) & 0x00ffffff;
++
++ case 0x32: /* SDPSoox */
++ return ((p | s | d) ^ s) & 0x00ffffff;
++
++ case 0x33: /* Sn NOTSRCCOPY */
++ return (~s) & 0x00ffffff;
++
++ case 0x34: /* SPDSaox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x35: /* SPDSxnox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x36: /* SDPox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x37: /* SDPoan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x38: /* PSDPoax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x39: /* SPDnox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x3A: /* SPDSxox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x3B: /* SPDnoan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x3C: /* PSx */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x3D: /* SPDSonox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x3E: /* SPDSnaox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x3F: /* PSan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x40: /* PSDnaa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x41: /* DPSxon */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x42: /* SDxPDxa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x43: /* SPDSanaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x44: /* SDna SRCERASE */
++ return (s & ~d) & 0x00ffffff;
++
++ case 0x45: /* DPSnaon */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x46: /* DSPDaox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x47: /* PSDPxaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x48: /* SDPxa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x49: /* PDSPDaoxxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x4A: /* DPSDoax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x4B: /* PDSnox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x4C: /* SDPana */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x4D: /* SSPxDSxoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x4E: /* PDSPxox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x4F: /* PDSnoan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x50: /* PDna */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x51: /* DSPnaon */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x52: /* DPSDaox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x53: /* SPDSxaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x54: /* DPSonon */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x55: /* Dn DSTINVERT */
++ return (~d) & 0x00ffffff;
++
++ case 0x56: /* DPSox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x57: /* DPSoan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x58: /* PDSPoax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x59: /* DPSnox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x5A: /* DPx PATINVERT */
++ return (d ^ p) & 0x00ffffff;
++
++ case 0x5B: /* DPSDonox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x5C: /* DPSDxox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x5D: /* DPSnoan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x5E: /* DPSDnaox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x5F: /* DPan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x60: /* PDSxa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x61: /* DSPDSaoxxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x62: /* DSPDoax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x63: /* SDPnox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x64: /* SDPSoax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x65: /* DSPnox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x66: /* DSx SRCINVERT */
++ return (d ^ s) & 0x00ffffff;
++
++ case 0x67: /* SDPSonox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x68: /* DSPDSonoxxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x69: /* PDSxxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x6A: /* DPSax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x6B: /* PSDPSoaxxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x6C: /* SDPax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x6D: /* PDSPDoaxxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x6E: /* SDPSnoax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x6F: /* PDSxnan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x70: /* PDSana */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x71: /* SSDxPDxaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x72: /* SDPSxox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x73: /* SDPnoan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x74: /* DSPDxox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x75: /* DSPnoan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x76: /* SDPSnaox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x77: /* DSan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x78: /* PDSax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x79: /* DSPDSoaxxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x7A: /* DPSDnoax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x7B: /* SDPxnan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x7C: /* SPDSnoax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x7D: /* DPSxnan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x7E: /* SPxDSxo */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x7F: /* DPSaan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x80: /* DPSaa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x81: /* SPxDSxon */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x82: /* DPSxna */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x83: /* SPDSnoaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x84: /* SDPxna */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x85: /* PDSPnoaxn */
++ return (~(p ^ (d & (s | ~p)))) & 0x00ffffff;
++
++ case 0x86: /* DSPDSoaxx */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x87: /* PDSaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x88: /* DSa SRCAND */
++ return (d & s) & 0x00ffffff;
++
++ case 0x89: /* SDPSnaoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x8A: /* DSPnoa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x8B: /* DSPDxoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x8C: /* SDPnoa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x8D: /* SDPSxoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x8E: /* SSDxPDxax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x8F: /* PDSanan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x90: /* PDSxna */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x91: /* SDPSnoaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x92: /* DPSDPoaxx */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x93: /* SPDaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x94: /* PSDPSoaxx */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x95: /* DPSaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x96: /* DPSxx */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x97: /* PSDPSonoxx */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x98: /* SDPSonoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x99: /* DSxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x9A: /* DPSnax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x9B: /* SDPSoaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x9C: /* SPDnax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x9D: /* DSPDoaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x9E: /* DSPDSaoxx */
++ return (0x123456) & 0x00ffffff;
++
++ case 0x9F: /* PDSxan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xA0: /* DPa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xA1: /* PDSPnaoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xA2: /* DPSnoa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xA3: /* DPSDxoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xA4: /* PDSPonoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xA5: /* PDxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xA6: /* DSPnax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xA7: /* PDSPoaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xA8: /* DPSoa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xA9: /* DPSoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xAA: /* D */
++ return (d) & 0x00ffffff;
++
++ case 0xAB: /* DPSono */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xAC: /* SPDSxax */
++ return (s ^ (p & (d ^ s))) & 0x00ffffff;
++
++ case 0xAD: /* DPSDaoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xAE: /* DSPnao */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xAF: /* DPno */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xB0: /* PDSnoa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xB1: /* PDSPxoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xB2: /* SSPxDSxox */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xB3: /* SDPanan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xB4: /* PSDnax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xB5: /* DPSDoaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xB6: /* DPSDPaoxx */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xB7: /* SDPxan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xB8: /* PSDPxax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xB9: /* DSPDaoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xBA: /* DPSnao */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xBB: /* DSno MERGEPAINT */
++ return (d | ~s) & 0x00ffffff;
++
++ case 0xBC: /* SPDSanax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xBD: /* SDxPDxan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xBE: /* DPSxo */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xBF: /* DPSano */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xC0: /* PSa MERGECOPY */
++ return (p & s) & 0x00ffffff;
++
++ case 0xC1: /* SPDSnaoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xC2: /* SPDSonoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xC3: /* PSxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xC4: /* SPDnoa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xC5: /* SPDSxoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xC6: /* SDPnax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xC7: /* PSDPoaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xC8: /* SDPoa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xC9: /* SPDoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xCA: /* DPSDxax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xCB: /* SPDSaoxn */
++ return (0x123456) & 0x00ffffff;
++
++ default:
++ case 0xCC: /* S SRCCOPY */
++ return (s) & 0x00ffffff;
++
++ case 0xCD: /* SDPono */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xCE: /* SDPnao */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xCF: /* SPno */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xD0: /* PSDnoa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xD1: /* PSDPxoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xD2: /* PDSnax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xD3: /* SPDSoaxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xD4: /* SSPxPDxax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xD5: /* DPSanan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xD6: /* PSDPSaoxx */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xD7: /* DPSxan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xD8: /* PDSPxax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xD9: /* SDPSaoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xDA: /* DPSDanax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xDB: /* SPxDSxan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xDC: /* SPDnao */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xDD: /* SDno */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xDE: /* SDPxo */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xDF: /* SDPano */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xE0: /* PDSoa */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xE1: /* PDSoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xE2: /* DSPDxax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xE3: /* PSDPaoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xE4: /* SDPSxax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xE5: /* PDSPaoxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xE6: /* SDPSanax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xE7: /* SPxPDxan */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xE8: /* SSPxDSxax */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xE9: /* DSPDSanaxxn */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xEA: /* DPSao */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xEB: /* DPSxno */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xEC: /* SDPao */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xED: /* SDPxno */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xEE: /* DSo SRCPAINT */
++ return (d | s) & 0x00ffffff;
++
++ case 0xEF: /* SDPnoo */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xF0: /* P PATCOPY */
++ return (p) & 0x00ffffff;
++
++ case 0xF1: /* PDSono */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xF2: /* PDSnao */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xF3: /* PSno */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xF4: /* PSDnao */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xF5: /* PDno */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xF6: /* PDSxo */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xF7: /* PDSano */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xF8: /* PDSao */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xF9: /* PDSxno */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xFA: /* DPo */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xFB: /* DPSnoo PATPAINT */
++ return (p | ~s | d) & 0x00ffffff;
++
++ case 0xFC: /* PSo */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xFD: /* PSDnoo */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xFE: /* DPSoo */
++ return (0x123456) & 0x00ffffff;
++
++ case 0xFF: /* 1 WHITENESS */
++ return 0x00ffffff;
++
++ } /* switch */
++}
+diff -Nru a/dlls/winedib.drv/text.c b/dlls/winedib.drv/text.c
+--- a/dlls/winedib.drv/text.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/text.c 2010-08-04 16:08:44.718222017 +0200
+@@ -0,0 +1,273 @@
++/*
++ * DIBDRV text functions
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/***********************************************************************
++ * DIBDRV_ExtTextOut
++ */
++BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags,
++ const RECT *lprect, LPCWSTR wstr, UINT count,
++ const INT *lpDx )
++{
++ /* FIXME : TODO many, many stuffs... just trivial text support by now */
++
++ BOOL res;
++ FT_Face face;
++ FT_UInt glyph_index;
++ INT n;
++ INT error;
++ LOGFONTW lf;
++ int w, h;
++ LPCWSTR wstrPnt;
++
++ FT_Glyph glyph;
++ FT_BitmapGlyph bitmapGlyph;
++ FT_Bitmap *bitmap, bitmap8;
++ double cosEsc, sinEsc;
++ FT_Matrix matrix;
++ FT_Vector start;
++ int dx, dy;
++
++ RECT *r;
++ int iRec;
++ RECT clipRec;
++ DWORD backPixel;
++
++ MAYBE(TRACE("physDev:%p, x:%d, y:%d, flags:%x, lprect:%p, wstr:%s, count:%d, lpDx:%p\n",
++ physDev, x, y, flags, lprect, debugstr_w(wstr), count, lpDx));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++
++ face = physDev->face;
++ if(!face)
++ {
++ ERR("FreeType face is null\n");
++ res = FALSE;
++ goto fin;
++ }
++
++ /* outputs the string in case it is given by glyph indexes
++ make locating it in logs much easier */
++ if(TRACE_ON(dibdrv) && flags & ETO_GLYPH_INDEX)
++ {
++ WCHAR a = 'A';
++ WCHAR *str = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR)*(count+1));
++ int delta = a - pFT_Get_Char_Index( face, a);
++ int i;
++ memcpy(str, wstr, sizeof(WCHAR)*count);
++ for(i = 0; str[i] && i < count; i++)
++ str[i] += delta;
++ TRACE("String: '%s'\n", debugstr_w(str));
++ HeapFree(GetProcessHeap(), 0, str);
++ }
++
++ /* gets background pixel value for opaque text */
++ backPixel = physDev->backgroundColor;
++
++ /* gets font data, etc */
++ GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf);
++
++ /* convert sizes to device space */
++ w = abs(lf.lfWidth); h = abs(lf.lfHeight);
++ _DIBDRV_Sizes_ws2ds(physDev, &w, &h);
++
++ /* loop on all clip region rectangles */
++ r = physDev->regionRects;
++ for(iRec = 0; iRec < physDev->regionRectCount; iRec++, r++)
++ {
++ /* if clipped on text rect, intersect with current region */
++ if(flags & ETO_CLIPPED)
++ {
++ if(!_DIBDRV_IntersectRect(&clipRec, r, lprect))
++ continue;
++ }
++ else
++ memcpy(&clipRec, r, sizeof(RECT));
++
++ /* if opaque, paint the font background */
++ if(flags & ETO_OPAQUE)
++ {
++ int iLine;
++ RECT tr;
++
++ /* clips text rectangle */
++ if(_DIBDRV_IntersectRect(&tr, r, lprect))
++ {
++ /* paints the backgound */
++ for(iLine = tr.top; iLine < tr.bottom; iLine++)
++ physDev->physBitmap->funcs->SolidHLine(physDev->physBitmap,
++ tr.left, tr.right-1, iLine, 0, backPixel);
++ }
++ }
++
++ /* sets character pixel size */
++ error = pFT_Set_Pixel_Sizes(face, w, h);
++ if(error)
++ ONCE(ERR("Couldn't set char size to (%d,%d), code %d\n", lf.lfWidth, lf.lfHeight, error));
++
++ /* transformation matrix and vector */
++ start.x = 0;
++ start.y = 0;
++ if(lf.lfEscapement != 0)
++ {
++ cosEsc = cos(lf.lfEscapement * M_PI / 1800);
++ sinEsc = sin(lf.lfEscapement * M_PI / 1800);
++ }
++ else
++ {
++ cosEsc = 1;
++ sinEsc = 0;
++ }
++ matrix.xx = (FT_Fixed)( cosEsc * 0x10000L );
++ matrix.xy = (FT_Fixed)(-sinEsc * 0x10000L );
++ matrix.yx = (FT_Fixed)( sinEsc * 0x10000L );
++ matrix.yy = (FT_Fixed)( cosEsc * 0x10000L );
++
++ /* outputs characters one by one */
++ wstrPnt = wstr;
++ for ( n = 0; n < count; n++ )
++ {
++ /* retrieve glyph index from character code */
++ if(flags & ETO_GLYPH_INDEX)
++ glyph_index = *wstrPnt++;
++ else
++ glyph_index = pFT_Get_Char_Index( face, *wstrPnt++);
++
++ /* load glyph image into the slot (erase previous one) */
++ error = pFT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
++ if(error)
++ {
++ ERR("Couldn't load glyph at index %d\n", glyph_index);
++ /* ignore errors */
++ continue;
++ }
++ error = pFT_Get_Glyph(face->glyph, &glyph);
++ if ( error )
++ {
++ FIXME("Couldn't get glyph\n");
++ continue;
++ }
++
++ /* apply transformation to glyph */
++ if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )
++ pFT_Glyph_Transform(glyph, &matrix, &start );
++
++ /* gets advance BEFORE transforming... */
++ dx = glyph->advance.x;
++ dy = glyph->advance.y;
++
++ /* convert to an anti-aliased bitmap, if needed */
++ if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )
++ {
++ error = pFT_Glyph_To_Bitmap(
++ &glyph,
++ #ifdef DIBDRV_ANTIALIASED_FONTS
++ physDev->physBitmap->bitCount > 8 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO,
++ #else
++ FT_RENDER_MODE_MONO,
++ #endif
++ 0, /* no additional translation */
++ 1 /* destroy copy in "image" */
++ );
++
++ /* ignore errors */
++ if ( error )
++ {
++ FIXME("Couldn't render glyph\n");
++ pFT_Done_Glyph(glyph);
++ continue;
++ }
++ }
++ bitmapGlyph = (FT_BitmapGlyph)glyph;
++
++ /* convert the bitmap in an 8bpp 1 byte aligned one if needed */
++ bitmap = &bitmapGlyph->bitmap;
++ if(bitmap->pixel_mode != FT_PIXEL_MODE_GRAY)
++ {
++ pFT_Bitmap_New(&bitmap8);
++ if(pFT_Bitmap_Convert(glyph->library, bitmap, &bitmap8, 1))
++ {
++ FIXME("Couldn't convert bitmap to 8 bit grayscale\n");
++ pFT_Done_Glyph(glyph);
++ continue;
++ }
++ bitmap = &bitmap8;
++ }
++
++ /* now, draw to our target surface */
++ physDev->physBitmap->funcs->FreetypeBlit(physDev, x+bitmapGlyph->left, y-bitmapGlyph->top, &clipRec, bitmap);
++
++ /* frees converted bitmap, if any */
++ if(bitmap != &bitmapGlyph->bitmap)
++ pFT_Bitmap_Done(glyph->library, bitmap);
++
++ /* increment pen position */
++ x += dx>>16;
++ y -= dy>>16;
++
++ pFT_Done_Glyph(glyph);
++
++ res = TRUE;
++ }
++ } /* end region rects loop */
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pExtTextOut(physDev->X11PhysDev, x, y, flags, lprect,
++ wstr, count, lpDx);
++ }
++fin:
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_GetTextExtentExPoint
++ */
++BOOL DIBDRV_GetTextExtentExPoint( DIBDRVPHYSDEV *physDev, LPCWSTR str, INT count,
++ INT maxExt, LPINT lpnFit, LPINT alpDx, LPSIZE size )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, str:%s, count:%d, maxExt:%d, lpnFit:%p, alpDx:%p, size:%p\n",
++ physDev, debugstr_w(str), count, maxExt, lpnFit, alpDx, size));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetTextExtentExPoint(physDev->X11PhysDev, str, count, maxExt,
++ lpnFit, alpDx, size);
++ }
++ return res;
++}
+diff -Nru a/dlls/winedib.drv/video.c b/dlls/winedib.drv/video.c
+--- a/dlls/winedib.drv/video.c 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/video.c 2010-08-04 16:08:44.517222017 +0200
+@@ -0,0 +1,72 @@
++/*
++ * DIBDRV video functions
++ *
++ * Copyright 2009 Massimo Del Fedele
++ *
++ * 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 "dibdrv.h"
++
++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
++
++/***********************************************************************
++ * DIBDRV_GetDeviceGammaRamp
++ */
++BOOL DIBDRV_GetDeviceGammaRamp( DIBDRVPHYSDEV *physDev, LPVOID ramp )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, ramp:%p\n", physDev, ramp));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
++ res = _DIBDRV_GetDisplayDriver()->pGetDeviceGammaRamp(physDev->X11PhysDev, ramp);
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pGetDeviceGammaRamp(physDev->X11PhysDev, ramp);
++ }
++ return res;
++}
++
++/***********************************************************************
++ * DIBDRV_SetDeviceGammaRamp
++ */
++BOOL DIBDRV_SetDeviceGammaRamp( DIBDRVPHYSDEV *physDev, LPVOID ramp )
++{
++ BOOL res;
++
++ MAYBE(TRACE("physDev:%p, ramp:%p\n", physDev, ramp));
++
++ if(physDev->hasDIB)
++ {
++ /* DIB section selected in, use DIB Engine */
++ ONCE(FIXME("STUB\n"));
++ res = TRUE;
++ }
++ else
++ {
++ /* DDB selected in, use X11 driver */
++ res = _DIBDRV_GetDisplayDriver()->pSetDeviceGammaRamp(physDev->X11PhysDev, ramp);
++ }
++ return res;
++}
+diff -Nru a/dlls/winedib.drv/winedib.drv.spec b/dlls/winedib.drv/winedib.drv.spec
+--- a/dlls/winedib.drv/winedib.drv.spec 1970-01-01 01:00:00.000000000 +0100
++++ b/dlls/winedib.drv/winedib.drv.spec 2010-08-04 16:08:44.395222017 +0200
+@@ -0,0 +1,74 @@
++@ cdecl AlphaBlend(ptr long long long long ptr long long long long long) DIBDRV_AlphaBlend
++@ cdecl Arc(ptr long long long long long long long long) DIBDRV_Arc
++@ cdecl BitBlt(ptr long long long long ptr long long long) DIBDRV_BitBlt
++@ cdecl ChoosePixelFormat(ptr ptr) DIBDRV_ChoosePixelFormat
++@ cdecl Chord(ptr long long long long long long long long) DIBDRV_Chord
++@ cdecl CreateBitmap(ptr long ptr) DIBDRV_CreateBitmap
++@ cdecl CreateDC(long ptr wstr wstr wstr ptr) DIBDRV_CreateDC
++@ cdecl CreateDIBSection(ptr long ptr long) DIBDRV_CreateDIBSection
++@ cdecl DeleteBitmap(long) DIBDRV_DeleteBitmap
++@ cdecl DeleteDC(ptr) DIBDRV_DeleteDC
++@ cdecl DescribePixelFormat(ptr long long ptr) DIBDRV_DescribePixelFormat
++@ cdecl Ellipse(ptr long long long long) DIBDRV_Ellipse
++@ cdecl EnumDeviceFonts(ptr ptr ptr long) DIBDRV_EnumDeviceFonts
++@ cdecl ExtEscape(ptr long long ptr long ptr) DIBDRV_ExtEscape
++@ cdecl ExtFloodFill(ptr long long long long) DIBDRV_ExtFloodFill
++@ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) DIBDRV_ExtTextOut
++@ cdecl GetBitmapBits(long ptr long) DIBDRV_GetBitmapBits
++@ cdecl GetCharWidth(ptr long long ptr) DIBDRV_GetCharWidth
++@ cdecl GetDCOrgEx(ptr ptr) DIBDRV_GetDCOrgEx
++@ cdecl GetDIBits(ptr long long long ptr ptr long) DIBDRV_GetDIBits
++@ cdecl GetDeviceCaps(ptr long) DIBDRV_GetDeviceCaps
++@ cdecl GetDeviceGammaRamp(ptr ptr) DIBDRV_GetDeviceGammaRamp
++@ cdecl GetICMProfile(ptr ptr ptr) DIBDRV_GetICMProfile
++@ cdecl GetNearestColor(ptr long) DIBDRV_GetNearestColor
++@ cdecl GetPixel(ptr long long) DIBDRV_GetPixel
++@ cdecl GetPixelFormat(ptr) DIBDRV_GetPixelFormat
++@ cdecl GetSystemPaletteEntries(ptr long long ptr) DIBDRV_GetSystemPaletteEntries
++@ cdecl GetTextExtentExPoint(ptr ptr long long ptr ptr ptr) DIBDRV_GetTextExtentExPoint
++@ cdecl GetTextMetrics(ptr ptr) DIBDRV_GetTextMetrics
++@ cdecl LineTo(ptr long long) DIBDRV_LineTo
++@ cdecl PaintRgn(ptr long) DIBDRV_PaintRgn
++@ cdecl PatBlt(ptr long long long long long) DIBDRV_PatBlt
++@ cdecl Pie(ptr long long long long long long long long) DIBDRV_Pie
++@ cdecl PolyPolygon(ptr ptr ptr long) DIBDRV_PolyPolygon
++@ cdecl PolyPolyline(ptr ptr ptr long) DIBDRV_PolyPolyline
++@ cdecl Polygon(ptr ptr long) DIBDRV_Polygon
++@ cdecl Polyline(ptr ptr long) DIBDRV_Polyline
++@ cdecl RealizeDefaultPalette(ptr) DIBDRV_RealizeDefaultPalette
++@ cdecl RealizePalette(ptr long long) DIBDRV_RealizePalette
++@ cdecl Rectangle(ptr long long long long) DIBDRV_Rectangle
++@ cdecl RoundRect(ptr long long long long long long) DIBDRV_RoundRect
++@ cdecl SelectBitmap(ptr long) DIBDRV_SelectBitmap
++@ cdecl SelectBrush(ptr long) DIBDRV_SelectBrush
++@ cdecl SelectFont(ptr long long) DIBDRV_SelectFont
++@ cdecl SelectPen(ptr long) DIBDRV_SelectPen
++@ cdecl SetBitmapBits(long ptr long) DIBDRV_SetBitmapBits
++@ cdecl SetBkColor(ptr long) DIBDRV_SetBkColor
++@ cdecl SetDCBrushColor(ptr long) DIBDRV_SetDCBrushColor
++@ cdecl SetDCOrg(ptr long long) DIBDRV_SetDCOrg
++@ cdecl SetDCPenColor(ptr long) DIBDRV_SetDCPenColor
++@ cdecl SetDIBColorTable(ptr long long ptr) DIBDRV_SetDIBColorTable
++@ cdecl SetDIBits(ptr long long long ptr ptr long) DIBDRV_SetDIBits
++@ cdecl SetDIBitsToDevice(ptr long long long long long long long long ptr ptr long) DIBDRV_SetDIBitsToDevice
++@ cdecl SetDeviceClipping(ptr long long) DIBDRV_SetDeviceClipping
++@ cdecl SetDeviceGammaRamp(ptr ptr) DIBDRV_SetDeviceGammaRamp
++@ cdecl SetPixel(ptr long long long) DIBDRV_SetPixel
++@ cdecl SetPixelFormat(ptr long ptr) DIBDRV_SetPixelFormat
++@ cdecl SetTextColor(ptr long) DIBDRV_SetTextColor
++@ cdecl StretchBlt(ptr long long long long ptr long long long long long) DIBDRV_StretchBlt
++@ cdecl SwapBuffers(ptr) DIBDRV_SwapBuffers
++@ cdecl UnrealizePalette(long) DIBDRV_UnrealizePalette
++@ cdecl SetROP2(ptr long) DIBDRV_SetROP2
++# OpenGL
++@ cdecl wglCopyContext(long long long) DIBDRV_wglCopyContext
++@ cdecl wglCreateContext(ptr) DIBDRV_wglCreateContext
++@ cdecl wglDeleteContext(long) DIBDRV_wglDeleteContext
++@ cdecl wglGetProcAddress(str) DIBDRV_wglGetProcAddress
++@ cdecl wglGetPbufferDCARB(ptr ptr) DIBDRV_wglGetPbufferDCARB
++@ cdecl wglMakeContextCurrentARB(ptr ptr long) DIBDRV_wglMakeContextCurrentARB
++@ cdecl wglMakeCurrent(ptr long) DIBDRV_wglMakeCurrent
++@ cdecl wglSetPixelFormatWINE(ptr long ptr) DIBDRV_wglSetPixelFormatWINE
++@ cdecl wglShareLists(long long) DIBDRV_wglShareLists
++@ cdecl wglUseFontBitmapsA(ptr long long long) DIBDRV_wglUseFontBitmapsA
++@ cdecl wglUseFontBitmapsW(ptr long long long) DIBDRV_wglUseFontBitmapsW
+diff -Nru a/dlls/wineps.drv/escape.c b/dlls/wineps.drv/escape.c
+--- a/dlls/wineps.drv/escape.c 2010-07-30 19:43:56.000000000 +0200
++++ b/dlls/wineps.drv/escape.c 2010-08-04 16:08:44.321222017 +0200
+@@ -47,10 +47,11 @@
+ "%%BeginDocument: Wine passthrough\n";
+
+ /* FIXME: should use winspool functions instead */
+-static DWORD create_job(LPCSTR pszOutput)
++static DWORD create_job(LPCSTR pszOutput, LPCSTR pszPageSize)
+ {
+ int fd = -1;
+ char psCmd[1024];
++ char psCmd2[1024];
+ const char *psCmdP = psCmd;
+ HKEY hkey;
+
+@@ -81,6 +82,15 @@
+ }
+ if (!*psCmdP) return 0;
+ }
++
++ /* copy printer command in order to add page size */
++ strcpy(psCmd2, psCmdP);
++ psCmdP = psCmd2;
++
++ /* if page size given, append it to printer line */
++ if(pszPageSize)
++ strcat(psCmd2, pszPageSize);
++
+ TRACE("command: '%s'\n", psCmdP);
+ #ifdef HAVE_FORK
+ if (*psCmdP == '|')
+@@ -505,6 +515,9 @@
+ HANDLE hprn = INVALID_HANDLE_VALUE;
+ PRINTER_INFO_5A *pi5 = (PRINTER_INFO_5A*)buf;
+ DWORD needed;
++
++ LPCSTR pageSize = NULL;
++ BYTE pSizeBuf[300];
+
+ if(physDev->job.id) {
+ FIXME("hJob != 0. Now what?\n");
+@@ -523,8 +536,35 @@
+ if(hprn != INVALID_HANDLE_VALUE)
+ ClosePrinter(hprn);
+ }
++
++ /* check if must send page size too */
++ /* if using LPR: as output device, appends the page size */
++ if(!strncmp(output, "LPR", 3) || !strncmp(output, "LPT", 3)) {
++
++ /* gets page size */
++ int sx = MulDiv(physDev->PageSize.cx, 72, physDev->logPixelsX);
++ int sy = MulDiv(physDev->PageSize.cy, 72, physDev->logPixelsY);
++
++ /* scans all supported page sizes to find page name */
++ PAGESIZE *page;
++ LPCSTR paperName = NULL;
++ LIST_FOR_EACH_ENTRY(page, &physDev->pi->ppd->PageSizes, PAGESIZE, entry) {
++ if(page->PaperDimension->x == sx && page->PaperDimension->y == sy) {
++ paperName = page->Name;
++ break;
++ }
++ }
++ if(paperName) {
++ TRACE("PaperName '%s' found for size '%d x %d'\n", paperName, sx, sy);
++ strcpy(pSizeBuf, " -o PageSize=");
++ strcat(pSizeBuf, paperName);
++ pageSize = pSizeBuf;
++ }
++ else
++ FIXME("PaperName not found for size '%d x %d'\n", sx, sy);
++ }
+
+- physDev->job.id = create_job( output );
++ physDev->job.id = create_job( output, pageSize );
+ if(!physDev->job.id) {
+ WARN("OpenJob failed\n");
+ return 0;
diff --git a/app-emulation/wine/wine-1.3.0.ebuild b/app-emulation/wine/wine-1.3.0.ebuild
new file mode 100644
index 0000000..08c7ea4
--- /dev/null
+++ b/app-emulation/wine/wine-1.3.0.ebuild
@@ -0,0 +1,207 @@
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/app-emulation/wine/wine-1.3.0.ebuild,v 1.2 2010/08/03 18:43:25 vapier Exp $
+
+EAPI=2
+
+inherit eutils flag-o-matic multilib
+
+if [[ ${PV} == "9999" ]] ; then
+ EGIT_REPO_URI="git://source.winehq.org/git/wine.git"
+ inherit git autotools
+ SRC_URI=""
+ #KEYWORDS=""
+else
+ AUTOTOOLS_AUTO_DEPEND="no"
+ inherit autotools
+ MY_P="${PN}-${PV/_/-}"
+ SRC_URI="mirror://sourceforge/${PN}/${MY_P}.tar.bz2"
+ KEYWORDS="-* ~amd64 ~x86 ~x86-fbsd"
+ S=${WORKDIR}/${MY_P}
+fi
+
+pulse_patches() { echo "$1"/winepulse-{0.36,0.35-configure.ac,0.38-winecfg}.patch ; }
+GV="1.0.0-x86"
+DESCRIPTION="free implementation of Windows(tm) on Unix"
+HOMEPAGE="http://www.winehq.org/"
+SRC_URI="${SRC_URI}
+ gecko? ( mirror://sourceforge/wine/wine_gecko-${GV}.cab )
+ pulseaudio? ( `pulse_patches http://art.ified.ca/downloads/winepulse` )"
+
+LICENSE="LGPL-2.1"
+SLOT="0"
+IUSE="alsa capi cups custom-cflags dbus +dib esd fontconfig +gecko gnutls gphoto2 gsm hal jack jpeg lcms ldap mp3 nas ncurses openal +opengl +oss +perl png pulseaudio samba scanner ssl test +threads +truetype +win32 +win64 +X xcomposite xinerama xml"
+RESTRICT="test" #72375
+
+MLIB_DEPS="amd64? (
+ truetype? ( >=app-emulation/emul-linux-x86-xlibs-2.1 )
+ X? (
+ >=app-emulation/emul-linux-x86-xlibs-2.1
+ >=app-emulation/emul-linux-x86-soundlibs-2.1
+ )
+ openal? ( app-emulation/emul-linux-x86-sdl )
+ opengl? ( app-emulation/emul-linux-x86-opengl )
+ app-emulation/emul-linux-x86-baselibs
+ >=sys-kernel/linux-headers-2.6
+ )"
+RDEPEND="truetype? ( >=media-libs/freetype-2.0.0 media-fonts/corefonts )
+ perl? ( dev-lang/perl dev-perl/XML-Simple )
+ capi? ( net-dialup/capi4k-utils )
+ ncurses? ( >=sys-libs/ncurses-5.2 )
+ fontconfig? ( media-libs/fontconfig )
+ gphoto2? ( media-libs/libgphoto2 )
+ jack? ( media-sound/jack-audio-connection-kit )
+ openal? ( media-libs/openal )
+ dbus? ( sys-apps/dbus )
+ gnutls? ( net-libs/gnutls )
+ hal? ( sys-apps/hal )
+ X? (
+ x11-libs/libXcursor
+ x11-libs/libXrandr
+ x11-libs/libXi
+ x11-libs/libXmu
+ x11-libs/libXxf86vm
+ x11-apps/xmessage
+ )
+ xinerama? ( x11-libs/libXinerama )
+ alsa? ( media-libs/alsa-lib )
+ esd? ( media-sound/esound )
+ nas? ( media-libs/nas )
+ cups? ( net-print/cups )
+ opengl? ( virtual/opengl )
+ pulseaudio? ( media-sound/pulseaudio ${AUTOTOOLS_DEPEND} )
+ gsm? ( media-sound/gsm )
+ jpeg? ( media-libs/jpeg )
+ ldap? ( net-nds/openldap )
+ lcms? ( =media-libs/lcms-1* )
+ mp3? ( >=media-sound/mpg123-1.5.0 )
+ samba? ( >=net-fs/samba-3.0.25 )
+ xml? ( dev-libs/libxml2 dev-libs/libxslt )
+ scanner? ( media-gfx/sane-backends )
+ ssl? ( dev-libs/openssl )
+ png? ( media-libs/libpng )
+ !win64? ( ${MLIB_DEPS} )
+ win32? ( ${MLIB_DEPS} )
+ xcomposite? ( x11-libs/libXcomposite ) "
+DEPEND="${RDEPEND}
+ X? (
+ x11-proto/inputproto
+ x11-proto/xextproto
+ x11-proto/xf86vidmodeproto
+ )
+ xinerama? ( x11-proto/xineramaproto )
+ sys-devel/bison
+ sys-devel/flex"
+
+src_unpack() {
+ if [[ $(( $(gcc-major-version) * 100 + $(gcc-minor-version) )) -lt 404 ]] ; then
+ use win64 && die "you need gcc-4.4+ to build 64bit wine"
+ fi
+
+ if [[ ${PV} == "9999" ]] ; then
+ git_src_unpack
+ else
+ unpack ${MY_P}.tar.bz2
+ fi
+}
+
+src_prepare() {
+ if use pulseaudio ; then
+ EPATCH_OPTS=-p1 epatch `pulse_patches "${DISTDIR}"`
+ eautoreconf
+ fi
+ epatch "${FILESDIR}"/${PN}-1.1.15-winegcc.patch #260726
+ epatch_user #282735
+ if use dib ; then
+ epatch "${FILESDIR}"/${P}-dib-engine.patch
+ fi
+ sed -i '/^UPDATE_DESKTOP_DATABASE/s:=.*:=true:' tools/Makefile.in || die
+ sed -i '/^MimeType/d' tools/wine.desktop || die #117785
+}
+
+do_configure() {
+ local builddir="${WORKDIR}/wine$1"
+ mkdir -p "${builddir}"
+ pushd "${builddir}" >/dev/null
+
+ ECONF_SOURCE=${S} \
+ econf \
+ --sysconfdir=/etc/wine \
+ $(use_with alsa) \
+ $(use_with capi) \
+ $(use_with lcms cms) \
+ $(use_with cups) \
+ $(use_with ncurses curses) \
+ $(use_with esd) \
+ $(use_with fontconfig) \
+ $(use_with gnutls) \
+ $(use_with gphoto2 gphoto) \
+ $(use_with gsm) \
+ $(! use dbus && echo --without-hal || use_with hal) \
+ $(use_with jack) \
+ $(use_with jpeg) \
+ $(use_with ldap) \
+ $(use_with mp3 mpg123) \
+ $(use_with nas) \
+ $(use_with openal) \
+ $(use_with opengl) \
+ $(use_with ssl openssl) \
+ $(use_with oss) \
+ $(use_with png) \
+ $(use_with threads pthread) \
+ $(use pulseaudio && use_with pulseaudio pulse) \
+ $(use_with scanner sane) \
+ $(use_enable test tests) \
+ $(use_with truetype freetype) \
+ $(use_with X x) \
+ $(use_with xcomposite) \
+ $(use_with xinerama) \
+ $(use_with xml) \
+ $(use_with xml xslt) \
+ $2
+
+ emake -j1 depend || die "depend"
+
+ popd >/dev/null
+}
+src_configure() {
+ export LDCONFIG=/bin/true
+ use custom-cflags || strip-flags
+
+ if use win64 && use amd64 ; then
+ do_configure 64 --enable-win64
+ use win32 && ABI=x86 do_configure 32 --with-wine64=../wine64
+ else
+ do_configure 32 --disable-win64
+ fi
+}
+
+src_compile() {
+ local b
+ for b in 64 32 ; do
+ local builddir="${WORKDIR}/wine${b}"
+ [[ -d ${builddir} ]] || continue
+ emake -C "${builddir}" all || die
+ done
+}
+
+src_install() {
+ local b
+ for b in 64 32 ; do
+ local builddir="${WORKDIR}/wine${b}"
+ [[ -d ${builddir} ]] || continue
+ emake -C "${builddir}" install DESTDIR="${D}" || die
+ done
+ dodoc ANNOUNCE AUTHORS README
+ if use gecko ; then
+ insinto /usr/share/wine/gecko
+ doins "${DISTDIR}"/wine_gecko-${GV}.cab || die
+ fi
+ if ! use perl ; then
+ rm "${D}"/usr/bin/{wine{dump,maker},function_grep.pl} "${D}"/usr/share/man/man1/wine{dump,maker}.1 || die
+ fi
+}
+
+pkg_postinst() {
+ paxctl -psmr "${ROOT}"/usr/bin/wine{,-preloader} 2>/dev/null #255055
+}