diff options
author | Jens Pranaitis <jens@chaox.net> | 2010-08-04 16:19:27 +0200 |
---|---|---|
committer | Jens Pranaitis <jens@chaox.net> | 2010-08-04 16:19:27 +0200 |
commit | ea1cc5950e90cccf8ecb3883a617ff5ba51826e4 (patch) | |
tree | 69f2926c708df62f9f7a7729a7fb1c78b38cf44e | |
parent | removed pidgin with icq fix, as 2.7.2 was now released including the fix (diff) | |
download | jensp-ea1cc5950e90cccf8ecb3883a617ff5ba51826e4.tar.gz jensp-ea1cc5950e90cccf8ecb3883a617ff5ba51826e4.tar.bz2 jensp-ea1cc5950e90cccf8ecb3883a617ff5ba51826e4.zip |
added wine 1.3.0 with dib engine
-rw-r--r-- | app-emulation/wine/Manifest | 8 | ||||
-rw-r--r-- | app-emulation/wine/files/wine-1.1.15-winegcc.patch | 55 | ||||
-rw-r--r-- | app-emulation/wine/files/wine-1.3.0-dib-engine.patch | 16184 | ||||
-rw-r--r-- | app-emulation/wine/wine-1.3.0.ebuild | 207 |
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 +} |