Restructured DirectDraw. Split into X11 and DGA driver, and multiple
files/dirs for easier maintenance. Cleaned up structs and include
files. Reindented the code. Started the same for Direct3D.  Driver
inclusion now done by using configure/Makefile/ELF constructor tricks.

diff --git a/configure b/configure
index 152cb8f..c66817e 100755
--- a/configure
+++ b/configure
@@ -2889,6 +2889,12 @@
 done
 
 
+
+X_SRCS=""
+
+DGA_SRCS=""
+
+MESA_SRCS=""
 if test "$have_x" = "yes"
 then
     XLIB="-lXext -lX11"
@@ -2899,17 +2905,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2903: checking for $ac_hdr" >&5
+echo "configure:2909: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2908 "configure"
+#line 2914 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2919: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2938,7 +2944,7 @@
     if test "$ac_cv_header_X11_xpm_h" = "yes"
     then 
         echo $ac_n "checking for XpmCreatePixmapFromData in -lXpm""... $ac_c" 1>&6
-echo "configure:2942: checking for XpmCreatePixmapFromData in -lXpm" >&5
+echo "configure:2948: checking for XpmCreatePixmapFromData in -lXpm" >&5
 ac_lib_var=`echo Xpm'_'XpmCreatePixmapFromData | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2946,7 +2952,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lXpm $X_LIBS -lXext -lX11 $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2950 "configure"
+#line 2956 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2957,7 +2963,7 @@
 XpmCreatePixmapFromData()
 ; return 0; }
 EOF
-if { (eval echo configure:2961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2967: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3000,17 +3006,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3004: checking for $ac_hdr" >&5
+echo "configure:3010: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3009 "configure"
+#line 3015 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3014: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3020: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3039,7 +3045,7 @@
     if test "$ac_cv_header_X11_Xlib_h" = "yes" -a "$ac_cv_header_X11_extensions_XShm_h" = "yes"
     then 
         echo $ac_n "checking for XShmQueryExtension in -lXext""... $ac_c" 1>&6
-echo "configure:3043: checking for XShmQueryExtension in -lXext" >&5
+echo "configure:3049: checking for XShmQueryExtension in -lXext" >&5
 ac_lib_var=`echo Xext'_'XShmQueryExtension | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3047,7 +3053,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lXext $X_LIBS -lXext -lX11 $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3051 "configure"
+#line 3057 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3058,7 +3064,7 @@
 XShmQueryExtension()
 ; return 0; }
 EOF
-if { (eval echo configure:3062: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3068: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3086,17 +3092,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3090: checking for $ac_hdr" >&5
+echo "configure:3096: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3095 "configure"
+#line 3101 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3100: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3106: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3125,15 +3131,16 @@
     if test "$ac_cv_header_X11_Xlib_h" = "yes" -a "$ac_cv_header_X11_extensions_xf86dga_h" = "yes"
     then 
          echo $ac_n "checking for XDGAQueryExtension in -lXxf86dga""... $ac_c" 1>&6
-echo "configure:3129: checking for XDGAQueryExtension in -lXxf86dga" >&5
+echo "configure:3135: checking for XDGAQueryExtension in -lXxf86dga" >&5
 ac_lib_var=`echo Xxf86dga'_'XDGAQueryExtension | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lXxf86dga $X_LIBS -lXext -lX11 $X_EXTRA_LIBS $LIBS"
+LIBS="-lXxf86dga $X_LIBS -lXext -lX11 $X_EXTRA_LIBS
+	  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3137 "configure"
+#line 3144 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3144,7 +3151,7 @@
 XDGAQueryExtension()
 ; return 0; }
 EOF
-if { (eval echo configure:3148: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3155: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3162,10 +3169,14 @@
   cat >> confdefs.h <<\EOF
 #define HAVE_LIBXXF86DGA2 1
 EOF
- cat >> confdefs.h <<\EOF
+
+			cat >> confdefs.h <<\EOF
 #define HAVE_LIBXXF86DGA 1
 EOF
- X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga"
+
+			X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga"
+	 		DGA_SRCS='$(DGA_SRCS)'
+			
 else
   echo "$ac_t""no" 1>&6
 fi
@@ -3173,7 +3184,7 @@
 	 if test "$ac_cv_lib_Xxf86dga_XDGAQueryExtension" = "no"
 	 then
            echo $ac_n "checking for XF86DGAQueryExtension in -lXxf86dga""... $ac_c" 1>&6
-echo "configure:3177: checking for XF86DGAQueryExtension in -lXxf86dga" >&5
+echo "configure:3188: checking for XF86DGAQueryExtension in -lXxf86dga" >&5
 ac_lib_var=`echo Xxf86dga'_'XF86DGAQueryExtension | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3181,7 +3192,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lXxf86dga $X_LIBS -lXext -lX11 $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3185 "configure"
+#line 3196 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3192,7 +3203,7 @@
 XF86DGAQueryExtension()
 ; return 0; }
 EOF
-if { (eval echo configure:3196: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3207: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3210,7 +3221,10 @@
   cat >> confdefs.h <<\EOF
 #define HAVE_LIBXXF86DGA 1
 EOF
- X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga"
+
+		X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga"
+		DGA_SRCS='$(DGA_SRCS)'
+		
 else
   echo "$ac_t""no" 1>&6
 fi
@@ -3222,17 +3236,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3226: checking for $ac_hdr" >&5
+echo "configure:3240: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3231 "configure"
+#line 3245 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3236: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3250: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3261,7 +3275,7 @@
     if test "$ac_cv_header_X11_Xlib_h" = "yes" -a "$ac_cv_header_X11_extensions_xf86vmode_h" = "yes"
     then 
         echo $ac_n "checking for XF86VidModeQueryExtension in -lXxf86vm""... $ac_c" 1>&6
-echo "configure:3265: checking for XF86VidModeQueryExtension in -lXxf86vm" >&5
+echo "configure:3279: checking for XF86VidModeQueryExtension in -lXxf86vm" >&5
 ac_lib_var=`echo Xxf86vm'_'XF86VidModeQueryExtension | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3269,7 +3283,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lXxf86vm $X_LIBS -lXext -lX11 $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3273 "configure"
+#line 3287 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3280,7 +3294,7 @@
 XF86VidModeQueryExtension()
 ; return 0; }
 EOF
-if { (eval echo configure:3284: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3298: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3309,17 +3323,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3313: checking for $ac_hdr" >&5
+echo "configure:3327: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3318 "configure"
+#line 3332 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3323: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3337: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3348,19 +3362,19 @@
     if test "$ac_cv_header_GL_gl_h" = "yes" -a "$ac_cv_header_GL_glx_h" = "yes"
     then
                 echo $ac_n "checking "for up-to-date Mesa version"""... $ac_c" 1>&6
-echo "configure:3352: checking "for up-to-date Mesa version"" >&5
+echo "configure:3366: checking "for up-to-date Mesa version"" >&5
 if eval "test \"`echo '$''{'wine_cv_mesa_version_OK'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3357 "configure"
+#line 3371 "configure"
 #include "confdefs.h"
 #include <GL/gl.h>
 int main() {
 GLenum test = GL_UNSIGNED_SHORT_5_6_5;
 ; return 0; }
 EOF
-if { (eval echo configure:3364: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3378: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_mesa_version_OK="yes"
 else
@@ -3377,21 +3391,21 @@
 echo "$ac_t""$wine_cv_mesa_version_OK" 1>&6
 
 	        echo $ac_n "checking "for thread-safe Mesa version"""... $ac_c" 1>&6
-echo "configure:3381: checking "for thread-safe Mesa version"" >&5
+echo "configure:3395: checking "for thread-safe Mesa version"" >&5
 if eval "test \"`echo '$''{'wine_cv_mesa_version_threadsafe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   saved_libs=$LIBS
 		        LIBS="$X_LIBS -lGL"
 			cat > conftest.$ac_ext <<EOF
-#line 3388 "configure"
+#line 3402 "configure"
 #include "confdefs.h"
 
 int main() {
 pthread_getspecific();
 ; return 0; }
 EOF
-if { (eval echo configure:3395: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3409: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   wine_cv_mesa_version_threadsafe="yes"
 else
@@ -3410,7 +3424,7 @@
         if test "$wine_cv_mesa_version_OK" = "yes" -a "$wine_cv_mesa_version_threadsafe" = "no"
         then
 	                echo $ac_n "checking for glXCreateContext in -lGL""... $ac_c" 1>&6
-echo "configure:3414: checking for glXCreateContext in -lGL" >&5
+echo "configure:3428: checking for glXCreateContext in -lGL" >&5
 ac_lib_var=`echo GL'_'glXCreateContext | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3418,7 +3432,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lGL $X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3422 "configure"
+#line 3436 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3429,7 +3443,7 @@
 glXCreateContext()
 ; return 0; }
 EOF
-if { (eval echo configure:3433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3447: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3447,7 +3461,10 @@
   cat >> confdefs.h <<\EOF
 #define HAVE_LIBMESAGL 1
 EOF
- X_PRE_LIBS="$X_PRE_LIBS -lGL"
+
+		X_PRE_LIBS="$X_PRE_LIBS -lGL"
+		MESA_SRCS='$(MESA_SRCS)'
+		
 else
   echo "$ac_t""no" 1>&6
 fi
@@ -3455,7 +3472,7 @@
 	    if test "$ac_cv_lib_GL_glXCreateContext" = "no"
 	    then
 		echo $ac_n "checking for glXCreateContext in -lMesaGL""... $ac_c" 1>&6
-echo "configure:3459: checking for glXCreateContext in -lMesaGL" >&5
+echo "configure:3476: checking for glXCreateContext in -lMesaGL" >&5
 ac_lib_var=`echo MesaGL'_'glXCreateContext | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3463,7 +3480,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lMesaGL $X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3467 "configure"
+#line 3484 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3474,7 +3491,7 @@
 glXCreateContext()
 ; return 0; }
 EOF
-if { (eval echo configure:3478: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3495: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3492,7 +3509,10 @@
   cat >> confdefs.h <<\EOF
 #define HAVE_LIBMESAGL 1
 EOF
- X_PRE_LIBS="$X_PRE_LIBS -lMesaGL"
+
+		    X_PRE_LIBS="$X_PRE_LIBS -lMesaGL"
+		    MESA_SRCS='$(MESA_SRCS)'
+		    
 else
   echo "$ac_t""no" 1>&6
 fi
@@ -3500,19 +3520,19 @@
 	    fi
 
 	    	    echo $ac_n "checking "for the OpenGL Color Index extension"""... $ac_c" 1>&6
-echo "configure:3504: checking "for the OpenGL Color Index extension"" >&5
+echo "configure:3524: checking "for the OpenGL Color Index extension"" >&5
 if eval "test \"`echo '$''{'dummy'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3509 "configure"
+#line 3529 "configure"
 #include "confdefs.h"
 #include <GL/gl.h>
 int main() {
 GLenum test = GL_COLOR_INDEX8_EXT;
 ; return 0; }
 EOF
-if { (eval echo configure:3516: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3536: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   cat >> confdefs.h <<\EOF
 #define HAVE_GL_COLOR_TABLE 1
@@ -3530,7 +3550,7 @@
     	    if test "$ac_cv_lib_GL_glXCreateContext" = "no"
 	    then
 		echo $ac_n "checking for glColorTableEXT in -lMesaGL""... $ac_c" 1>&6
-echo "configure:3534: checking for glColorTableEXT in -lMesaGL" >&5
+echo "configure:3554: checking for glColorTableEXT in -lMesaGL" >&5
 ac_lib_var=`echo MesaGL'_'glColorTableEXT | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3538,7 +3558,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lMesaGL $X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3542 "configure"
+#line 3562 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3549,7 +3569,7 @@
 glColorTableEXT()
 ; return 0; }
 EOF
-if { (eval echo configure:3553: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3574,7 +3594,7 @@
 
 	    else
 		echo $ac_n "checking for glColorTableEXT in -lGL""... $ac_c" 1>&6
-echo "configure:3578: checking for glColorTableEXT in -lGL" >&5
+echo "configure:3598: checking for glColorTableEXT in -lGL" >&5
 ac_lib_var=`echo GL'_'glColorTableEXT | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3582,7 +3602,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lGL $X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3586 "configure"
+#line 3606 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3593,7 +3613,7 @@
 glColorTableEXT()
 ; return 0; }
 EOF
-if { (eval echo configure:3597: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3621,6 +3641,7 @@
     fi
 
     CPPFLAGS="$ac_save_CPPFLAGS"
+    X_SRCS='$(X_SRCS)'
 else
     XLIB=""
     X_CFLAGS=""
@@ -3631,17 +3652,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3635: checking for $ac_hdr" >&5
+echo "configure:3656: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3640 "configure"
+#line 3661 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3645: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3666: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3670,7 +3691,7 @@
 if test "$ac_cv_header_ncurses_h" = "yes"
 then 
     echo $ac_n "checking for waddch in -lncurses""... $ac_c" 1>&6
-echo "configure:3674: checking for waddch in -lncurses" >&5
+echo "configure:3695: checking for waddch in -lncurses" >&5
 ac_lib_var=`echo ncurses'_'waddch | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3678,7 +3699,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lncurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3682 "configure"
+#line 3703 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3689,7 +3710,7 @@
 waddch()
 ; return 0; }
 EOF
-if { (eval echo configure:3693: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3714: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3720,7 +3741,7 @@
 if test "$ac_cv_lib_ncurses_waddch" = "yes"
 then
     echo $ac_n "checking for resizeterm in -lncurses""... $ac_c" 1>&6
-echo "configure:3724: checking for resizeterm in -lncurses" >&5
+echo "configure:3745: checking for resizeterm in -lncurses" >&5
 ac_lib_var=`echo ncurses'_'resizeterm | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3728,7 +3749,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lncurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3732 "configure"
+#line 3753 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3739,7 +3760,7 @@
 resizeterm()
 ; return 0; }
 EOF
-if { (eval echo configure:3743: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3764: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3763,7 +3784,7 @@
 fi
 
     echo $ac_n "checking for getbkgd in -lncurses""... $ac_c" 1>&6
-echo "configure:3767: checking for getbkgd in -lncurses" >&5
+echo "configure:3788: checking for getbkgd in -lncurses" >&5
 ac_lib_var=`echo ncurses'_'getbkgd | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3771,7 +3792,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lncurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3775 "configure"
+#line 3796 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3782,7 +3803,7 @@
 getbkgd()
 ; return 0; }
 EOF
-if { (eval echo configure:3786: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3807: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3810,17 +3831,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3814: checking for $ac_hdr" >&5
+echo "configure:3835: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3819 "configure"
+#line 3840 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3824: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3845: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3849,7 +3870,7 @@
     if test "$ac_cv_header_curses_h" = "yes"
     then    
        echo $ac_n "checking for waddch in -lcurses""... $ac_c" 1>&6
-echo "configure:3853: checking for waddch in -lcurses" >&5
+echo "configure:3874: checking for waddch in -lcurses" >&5
 ac_lib_var=`echo curses'_'waddch | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3857,7 +3878,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lcurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3861 "configure"
+#line 3882 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3868,7 +3889,7 @@
 waddch()
 ; return 0; }
 EOF
-if { (eval echo configure:3872: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3893: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3896,7 +3917,7 @@
 fi
 
        echo $ac_n "checking for resizeterm in -lcurses""... $ac_c" 1>&6
-echo "configure:3900: checking for resizeterm in -lcurses" >&5
+echo "configure:3921: checking for resizeterm in -lcurses" >&5
 ac_lib_var=`echo curses'_'resizeterm | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3904,7 +3925,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lcurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3908 "configure"
+#line 3929 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3915,7 +3936,7 @@
 resizeterm()
 ; return 0; }
 EOF
-if { (eval echo configure:3919: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3939,7 +3960,7 @@
 fi
 
        echo $ac_n "checking for getbkgd in -lcurses""... $ac_c" 1>&6
-echo "configure:3943: checking for getbkgd in -lcurses" >&5
+echo "configure:3964: checking for getbkgd in -lcurses" >&5
 ac_lib_var=`echo curses'_'getbkgd | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3947,7 +3968,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lcurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3951 "configure"
+#line 3972 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3958,7 +3979,7 @@
 getbkgd()
 ; return 0; }
 EOF
-if { (eval echo configure:3962: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3985,12 +4006,12 @@
 fi
 
 echo $ac_n "checking "for GNU style IPX support"""... $ac_c" 1>&6
-echo "configure:3989: checking "for GNU style IPX support"" >&5
+echo "configure:4010: checking "for GNU style IPX support"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_ipx_gnu'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3994 "configure"
+#line 4015 "configure"
 #include "confdefs.h"
 #include <sys/socket.h>
     #include <netipx/ipx.h>
@@ -3998,7 +4019,7 @@
 ((struct sockaddr_ipx *)0)->sipx_family == AF_IPX
 ; return 0; }
 EOF
-if { (eval echo configure:4002: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4023: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_ipx_gnu="yes"
 else
@@ -4023,12 +4044,12 @@
 if test "$ac_cv_c_ipx_gnu" = "no"
 then
  echo $ac_n "checking "for linux style IPX support"""... $ac_c" 1>&6
-echo "configure:4027: checking "for linux style IPX support"" >&5
+echo "configure:4048: checking "for linux style IPX support"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_ipx_linux'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4032 "configure"
+#line 4053 "configure"
 #include "confdefs.h"
 #include <sys/socket.h>
      #include <asm/types.h>
@@ -4037,7 +4058,7 @@
 ((struct sockaddr_ipx *)0)->sipx_family == AF_IPX
 ; return 0; }
 EOF
-if { (eval echo configure:4041: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4062: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_ipx_linux="yes"
 else
@@ -4064,17 +4085,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4068: checking for $ac_hdr" >&5
+echo "configure:4089: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4073 "configure"
+#line 4094 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4078: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4099: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -4102,12 +4123,12 @@
 
 
 echo $ac_n "checking "for Open Sound System"""... $ac_c" 1>&6
-echo "configure:4106: checking "for Open Sound System"" >&5
+echo "configure:4127: checking "for Open Sound System"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_opensoundsystem'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4111 "configure"
+#line 4132 "configure"
 #include "confdefs.h"
 
 	#if defined(HAVE_SYS_SOUNDCARD_H)
@@ -4128,7 +4149,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:4132: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4153: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_opensoundsystem="yes"
 else
@@ -4151,12 +4172,12 @@
 fi
 
 echo $ac_n "checking "for Open Sound System/MIDI interface"""... $ac_c" 1>&6
-echo "configure:4155: checking "for Open Sound System/MIDI interface"" >&5
+echo "configure:4176: checking "for Open Sound System/MIDI interface"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_opensoundsystem_midi'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4160 "configure"
+#line 4181 "configure"
 #include "confdefs.h"
 
 	#if defined(HAVE_SYS_SOUNDCARD_H)
@@ -4177,7 +4198,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:4181: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4202: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_opensoundsystem_midi="yes"
 else
@@ -4206,7 +4227,7 @@
 then
   CFLAGS="$CFLAGS -Wall"
   echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6
-echo "configure:4210: checking "for gcc strength-reduce bug"" >&5
+echo "configure:4231: checking "for gcc strength-reduce bug"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_gcc_strength_bug'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4214,7 +4235,7 @@
   ac_cv_c_gcc_strength_bug="yes"
 else
   cat > conftest.$ac_ext <<EOF
-#line 4218 "configure"
+#line 4239 "configure"
 #include "confdefs.h"
 
 int main(void) {
@@ -4225,7 +4246,7 @@
   exit( Array[1] != -2 );
 }
 EOF
-if { (eval echo configure:4229: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_gcc_strength_bug="no"
 else
@@ -4248,7 +4269,7 @@
 
 
 echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6
-echo "configure:4252: checking "whether external symbols need an underscore prefix"" >&5
+echo "configure:4273: checking "whether external symbols need an underscore prefix"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_extern_prefix'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4260,14 +4281,14 @@
 	.long 0
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 4264 "configure"
+#line 4285 "configure"
 #include "confdefs.h"
 extern int ac_test;
 int main() {
 if (ac_test) return 1
 ; return 0; }
 EOF
-if { (eval echo configure:4271: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4292: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_c_extern_prefix="yes"
 else
@@ -4291,7 +4312,7 @@
 
 
 echo $ac_n "checking "whether assembler accepts .string"""... $ac_c" 1>&6
-echo "configure:4295: checking "whether assembler accepts .string"" >&5
+echo "configure:4316: checking "whether assembler accepts .string"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_asm_string'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4301,14 +4322,14 @@
 	.string "test"
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 4305 "configure"
+#line 4326 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:4312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_c_asm_string="yes"
 else
@@ -4335,21 +4356,21 @@
 if test "$LIBEXT" = "so"
 then
   echo $ac_n "checking "whether we can build a Linux dll"""... $ac_c" 1>&6
-echo "configure:4339: checking "whether we can build a Linux dll"" >&5
+echo "configure:4360: checking "whether we can build a Linux dll"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_dll_linux'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   saved_cflags=$CFLAGS
   CFLAGS="$CFLAGS -fPIC -shared -Wl,-soname,conftest.so.1.0"
   cat > conftest.$ac_ext <<EOF
-#line 4346 "configure"
+#line 4367 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:4353: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_c_dll_linux="yes"
 else
@@ -4369,21 +4390,21 @@
     LDSHARED="\$(CC) -shared -Wl,-soname,\$(SONAME),-rpath,\$(libdir)"
   else
     echo $ac_n "checking whether we can build a UnixWare (Solaris) dll""... $ac_c" 1>&6
-echo "configure:4373: checking whether we can build a UnixWare (Solaris) dll" >&5
+echo "configure:4394: checking whether we can build a UnixWare (Solaris) dll" >&5
 if eval "test \"`echo '$''{'ac_cv_c_dll_unixware'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   saved_cflags=$CFLAGS
     CFLAGS="$CFLAGS -fPIC -Wl,-G,-h,conftest.so.1.0"
     cat > conftest.$ac_ext <<EOF
-#line 4380 "configure"
+#line 4401 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:4387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4408: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_c_dll_unixware="yes"
 else
@@ -4403,21 +4424,21 @@
       LDSHARED="\$(CC) -Wl,-G,-h,\$(libdir)/\$(SONAME)"
     else
       echo $ac_n "checking "whether we can build a NetBSD dll"""... $ac_c" 1>&6
-echo "configure:4407: checking "whether we can build a NetBSD dll"" >&5
+echo "configure:4428: checking "whether we can build a NetBSD dll"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_dll_netbsd'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   saved_cflags=$CFLAGS
       CFLAGS="$CFLAGS -fPIC -Bshareable -Bforcearchive"
       cat > conftest.$ac_ext <<EOF
-#line 4414 "configure"
+#line 4435 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:4421: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_c_dll_netbsd="yes"
 else
@@ -4453,21 +4474,21 @@
     DLLFLAGS="-fPIC"
 else
     echo $ac_n "checking whether the linker supports --[no]-whole-archive (Linux)""... $ac_c" 1>&6
-echo "configure:4457: checking whether the linker supports --[no]-whole-archive (Linux)" >&5
+echo "configure:4478: checking whether the linker supports --[no]-whole-archive (Linux)" >&5
 if eval "test \"`echo '$''{'ac_cv_c_whole_archive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   saved_cflags=$CFLAGS
             CFLAGS="$CFLAGS -Wl,--whole-archive -Wl,--no-whole-archive"
             cat > conftest.$ac_ext <<EOF
-#line 4464 "configure"
+#line 4485 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:4471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4492: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_c_whole_archive="yes"
 else
@@ -4487,21 +4508,21 @@
         DLL_LINK="-Wl,--whole-archive $DLL_LINK -Wl,--no-whole-archive"
     else
         echo $ac_n "checking whether the linker supports -z {all,default}extract (Linux)""... $ac_c" 1>&6
-echo "configure:4491: checking whether the linker supports -z {all,default}extract (Linux)" >&5
+echo "configure:4512: checking whether the linker supports -z {all,default}extract (Linux)" >&5
 if eval "test \"`echo '$''{'ac_cv_c_allextract'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   saved_cflags=$CFLAGS
 		CFLAGS="$CFLAGS -Wl,-z,allextract -Wl,-z,defaultextract"
 		cat > conftest.$ac_ext <<EOF
-#line 4498 "configure"
+#line 4519 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:4505: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_c_allextract="yes"
 else
@@ -4532,7 +4553,7 @@
 
 wine_cv_libc_reentrant=no 
 echo $ac_n "checking "for reentrant libc: __errno_location"""... $ac_c" 1>&6
-echo "configure:4536: checking "for reentrant libc: __errno_location"" >&5
+echo "configure:4557: checking "for reentrant libc: __errno_location"" >&5
 if eval "test \"`echo '$''{'wine_cv_libc_r__errno_location'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4540,14 +4561,14 @@
   wine_cv_libc_r__errno_location=yes 
 else
   cat > conftest.$ac_ext <<EOF
-#line 4544 "configure"
+#line 4565 "configure"
 #include "confdefs.h"
 int myerrno = 0;
 char buf[256];
 int *__errno_location(){return &myerrno;}
 main(){connect(0,buf,255); exit(!myerrno);}
 EOF
-if { (eval echo configure:4551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   wine_cv_libc_r__errno_location=yes
 else
@@ -4572,7 +4593,7 @@
     wine_cv_libc_reentrant=__errno_location 
 fi
 echo $ac_n "checking "for reentrant libc: __error"""... $ac_c" 1>&6
-echo "configure:4576: checking "for reentrant libc: __error"" >&5
+echo "configure:4597: checking "for reentrant libc: __error"" >&5
 if eval "test \"`echo '$''{'wine_cv_libc_r__error'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4580,14 +4601,14 @@
   wine_cv_libc_r__error=yes 
 else
   cat > conftest.$ac_ext <<EOF
-#line 4584 "configure"
+#line 4605 "configure"
 #include "confdefs.h"
 int myerrno = 0;
 char buf[256];
 int *__error(){return &myerrno;}
 main(){connect(0,buf,255); exit(!myerrno);}
 EOF
-if { (eval echo configure:4591: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   wine_cv_libc_r__error=yes
 else
@@ -4612,7 +4633,7 @@
     wine_cv_libc_reentrant=__error 
 fi
 echo $ac_n "checking "for reentrant libc: ___errno"""... $ac_c" 1>&6
-echo "configure:4616: checking "for reentrant libc: ___errno"" >&5
+echo "configure:4637: checking "for reentrant libc: ___errno"" >&5
 if eval "test \"`echo '$''{'wine_cv_libc_r___errno'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4620,14 +4641,14 @@
   wine_cv_libc_r___errno=yes 
 else
   cat > conftest.$ac_ext <<EOF
-#line 4624 "configure"
+#line 4645 "configure"
 #include "confdefs.h"
 int myerrno = 0;
 char buf[256];
 int *___errno(){return &myerrno;}
 main(){connect(0,buf,255); exit(!myerrno);}
 EOF
-if { (eval echo configure:4631: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4652: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   wine_cv_libc_r___errno=yes
 else
@@ -4652,7 +4673,7 @@
     wine_cv_libc_reentrant=___errno 
 fi
 echo $ac_n "checking "for reentrant libc: __thr_errno"""... $ac_c" 1>&6
-echo "configure:4656: checking "for reentrant libc: __thr_errno"" >&5
+echo "configure:4677: checking "for reentrant libc: __thr_errno"" >&5
 if eval "test \"`echo '$''{'wine_cv_libc_r__thr_errno'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4660,14 +4681,14 @@
   wine_cv_libc_r__thr_errno=yes 
 else
   cat > conftest.$ac_ext <<EOF
-#line 4664 "configure"
+#line 4685 "configure"
 #include "confdefs.h"
 int myerrno = 0;
 char buf[256];
 int *__thr_errno(){return &myerrno;}
 main(){connect(0,buf,255); exit(!myerrno);}
 EOF
-if { (eval echo configure:4671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4692: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   wine_cv_libc_r__thr_errno=yes
 else
@@ -4703,7 +4724,7 @@
 if test "$have_x" = "yes" -a "$wine_cv_libc_reentrant" != "no"
 then
 echo $ac_n "checking "for reentrant X libraries"""... $ac_c" 1>&6
-echo "configure:4707: checking "for reentrant X libraries"" >&5
+echo "configure:4728: checking "for reentrant X libraries"" >&5
 if eval "test \"`echo '$''{'wine_cv_x_reentrant'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4749,14 +4770,14 @@
 
 
 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:4753: checking whether byte ordering is bigendian" >&5
+echo "configure:4774: checking whether byte ordering is bigendian" >&5
 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_bigendian=unknown
 # See if sys/param.h defines the BYTE_ORDER macro.
 cat > conftest.$ac_ext <<EOF
-#line 4760 "configure"
+#line 4781 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -4767,11 +4788,11 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:4771: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4792: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat > conftest.$ac_ext <<EOF
-#line 4775 "configure"
+#line 4796 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -4782,7 +4803,7 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:4786: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4807: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -4802,7 +4823,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4806 "configure"
+#line 4827 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -4815,7 +4836,7 @@
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:4819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4840: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_bigendian=no
 else
@@ -4843,19 +4864,19 @@
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:4847: checking for working alloca.h" >&5
+echo "configure:4868: checking for working alloca.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4852 "configure"
+#line 4873 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 void *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:4859: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_header_alloca_h=yes
 else
@@ -4876,12 +4897,12 @@
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:4880: checking for alloca" >&5
+echo "configure:4901: checking for alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4885 "configure"
+#line 4906 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -4909,7 +4930,7 @@
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:4913: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4934: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_func_alloca_works=yes
 else
@@ -4941,12 +4962,12 @@
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:4945: checking whether alloca needs Cray hooks" >&5
+echo "configure:4966: checking whether alloca needs Cray hooks" >&5
 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4950 "configure"
+#line 4971 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -4971,12 +4992,12 @@
 if test $ac_cv_os_cray = yes; then
 for ac_func in _getb67 GETB67 getb67; do
   echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4975: checking for $ac_func" >&5
+echo "configure:4996: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4980 "configure"
+#line 5001 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4999,7 +5020,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:5003: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5024: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5026,7 +5047,7 @@
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:5030: checking stack direction for C alloca" >&5
+echo "configure:5051: checking stack direction for C alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5034,7 +5055,7 @@
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 5038 "configure"
+#line 5059 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -5053,7 +5074,7 @@
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:5057: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5078: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_stack_direction=1
 else
@@ -5104,12 +5125,12 @@
 
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5108: checking for $ac_func" >&5
+echo "configure:5129: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5113 "configure"
+#line 5134 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5132,7 +5153,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:5136: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5157: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5211,17 +5232,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:5215: checking for $ac_hdr" >&5
+echo "configure:5236: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5220 "configure"
+#line 5241 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5225: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5246: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -5248,12 +5269,12 @@
 done
 
 echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:5252: checking whether stat file-mode macros are broken" >&5
+echo "configure:5273: checking whether stat file-mode macros are broken" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5257 "configure"
+#line 5278 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -5306,12 +5327,12 @@
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:5310: checking for working const" >&5
+echo "configure:5331: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5315 "configure"
+#line 5336 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -5360,7 +5381,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:5364: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5385: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -5381,21 +5402,21 @@
 fi
 
 echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:5385: checking for inline" >&5
+echo "configure:5406: checking for inline" >&5
 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat > conftest.$ac_ext <<EOF
-#line 5392 "configure"
+#line 5413 "configure"
 #include "confdefs.h"
 
 int main() {
 } int $ac_kw foo() {
 ; return 0; }
 EOF
-if { (eval echo configure:5399: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5420: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_inline=$ac_kw; break
 else
@@ -5421,12 +5442,12 @@
 esac
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:5425: checking for ANSI C header files" >&5
+echo "configure:5446: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5430 "configure"
+#line 5451 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -5434,7 +5455,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5438: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5459: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -5451,7 +5472,7 @@
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 5455 "configure"
+#line 5476 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -5469,7 +5490,7 @@
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 5473 "configure"
+#line 5494 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -5490,7 +5511,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 5494 "configure"
+#line 5515 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -5501,7 +5522,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:5505: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -5525,12 +5546,12 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:5529: checking for size_t" >&5
+echo "configure:5550: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5534 "configure"
+#line 5555 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -5558,7 +5579,7 @@
 fi
 
 echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:5562: checking size of long long" >&5
+echo "configure:5583: checking size of long long" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5566,7 +5587,7 @@
   ac_cv_sizeof_long_long=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 5570 "configure"
+#line 5591 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -5577,7 +5598,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:5581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long_long=`cat conftestval`
 else
@@ -5600,12 +5621,12 @@
 if test "$ac_cv_header_linux_joystick_h" = "yes"
 then
    echo $ac_n "checking "whether linux/joystick.h uses the Linux 2.2+ API"""... $ac_c" 1>&6
-echo "configure:5604: checking "whether linux/joystick.h uses the Linux 2.2+ API"" >&5
+echo "configure:5625: checking "whether linux/joystick.h uses the Linux 2.2+ API"" >&5
 if eval "test \"`echo '$''{'wine_cv_linux_joystick_22_api'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5609 "configure"
+#line 5630 "configure"
 #include "confdefs.h"
 
 	#include <sys/ioctl.h>
@@ -5620,7 +5641,7 @@
 /*empty*/
 ; return 0; }
 EOF
-if { (eval echo configure:5624: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5645: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_linux_joystick_22_api=yes
 else
@@ -5647,12 +5668,12 @@
 if test "$ac_cv_header_sys_vfs_h" = "yes"
 then
     echo $ac_n "checking "whether sys/vfs.h defines statfs"""... $ac_c" 1>&6
-echo "configure:5651: checking "whether sys/vfs.h defines statfs"" >&5
+echo "configure:5672: checking "whether sys/vfs.h defines statfs"" >&5
 if eval "test \"`echo '$''{'wine_cv_sys_vfs_has_statfs'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5656 "configure"
+#line 5677 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -5669,7 +5690,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:5673: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5694: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_vfs_has_statfs=yes
 else
@@ -5696,12 +5717,12 @@
 if test "$ac_cv_header_sys_statfs_h" = "yes"
 then
     echo $ac_n "checking "whether sys/statfs.h defines statfs"""... $ac_c" 1>&6
-echo "configure:5700: checking "whether sys/statfs.h defines statfs"" >&5
+echo "configure:5721: checking "whether sys/statfs.h defines statfs"" >&5
 if eval "test \"`echo '$''{'wine_cv_sys_statfs_has_statfs'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5705 "configure"
+#line 5726 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -5716,7 +5737,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:5720: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5741: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_statfs_has_statfs=yes
 else
@@ -5743,12 +5764,12 @@
 if test "$ac_cv_header_sys_mount_h" = "yes"
 then
     echo $ac_n "checking "whether sys/mount.h defines statfs"""... $ac_c" 1>&6
-echo "configure:5747: checking "whether sys/mount.h defines statfs"" >&5
+echo "configure:5768: checking "whether sys/mount.h defines statfs"" >&5
 if eval "test \"`echo '$''{'wine_cv_sys_mount_has_statfs'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5752 "configure"
+#line 5773 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -5763,7 +5784,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:5767: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5788: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_mount_has_statfs=yes
 else
@@ -5789,7 +5810,7 @@
 
 
 echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6
-echo "configure:5793: checking "for statfs.f_bfree"" >&5
+echo "configure:5814: checking "for statfs.f_bfree"" >&5
 if eval "test \"`echo '$''{'wine_cv_statfs_bfree'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5798,7 +5819,7 @@
         wine_cv_statfs_bfree=no
     else
     	cat > conftest.$ac_ext <<EOF
-#line 5802 "configure"
+#line 5823 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -5825,7 +5846,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:5829: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5850: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_statfs_bfree=yes
 else
@@ -5849,7 +5870,7 @@
 fi
 
 echo $ac_n "checking "for statfs.f_bavail"""... $ac_c" 1>&6
-echo "configure:5853: checking "for statfs.f_bavail"" >&5
+echo "configure:5874: checking "for statfs.f_bavail"" >&5
 if eval "test \"`echo '$''{'wine_cv_statfs_bavail'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5858,7 +5879,7 @@
         wine_cv_statfs_bavail=no
     else
     	cat > conftest.$ac_ext <<EOF
-#line 5862 "configure"
+#line 5883 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -5885,7 +5906,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:5889: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5910: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_statfs_bavail=yes
 else
@@ -5910,7 +5931,7 @@
 
 
 echo $ac_n "checking "for working sigaltstack"""... $ac_c" 1>&6
-echo "configure:5914: checking "for working sigaltstack"" >&5
+echo "configure:5935: checking "for working sigaltstack"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_working_sigaltstack'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5919,7 +5940,7 @@
 
 else
   cat > conftest.$ac_ext <<EOF
-#line 5923 "configure"
+#line 5944 "configure"
 #include "confdefs.h"
 
 	#include <stdio.h>
@@ -5957,7 +5978,7 @@
 	}
 	
 EOF
-if { (eval echo configure:5961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_working_sigaltstack="yes"
 else
@@ -5984,12 +6005,12 @@
 
 
 echo $ac_n "checking "for msg_accrights in struct msghdr"""... $ac_c" 1>&6
-echo "configure:5988: checking "for msg_accrights in struct msghdr"" >&5
+echo "configure:6009: checking "for msg_accrights in struct msghdr"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_msg_accrights'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5993 "configure"
+#line 6014 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -5997,7 +6018,7 @@
 struct msghdr hdr; hdr.msg_accrights=0
 ; return 0; }
 EOF
-if { (eval echo configure:6001: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6022: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_msg_accrights="yes"
 else
@@ -6020,12 +6041,12 @@
 
 
 echo $ac_n "checking "for sun_len in struct sockaddr_un"""... $ac_c" 1>&6
-echo "configure:6024: checking "for sun_len in struct sockaddr_un"" >&5
+echo "configure:6045: checking "for sun_len in struct sockaddr_un"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_sun_len'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6029 "configure"
+#line 6050 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -6034,7 +6055,7 @@
 static struct sockaddr_un addr; addr.sun_len = 1
 ; return 0; }
 EOF
-if { (eval echo configure:6038: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6059: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_sun_len="yes"
 else
@@ -6057,12 +6078,12 @@
 
 
 echo $ac_n "checking "whether we need to define __i386__"""... $ac_c" 1>&6
-echo "configure:6061: checking "whether we need to define __i386__"" >&5
+echo "configure:6082: checking "whether we need to define __i386__"" >&5
 if eval "test \"`echo '$''{'ac_cv_cpp_def_i386'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6066 "configure"
+#line 6087 "configure"
 #include "confdefs.h"
 #if (defined(i386) || defined(__i386)) && !defined(__i386__)
 yes
@@ -6375,6 +6396,9 @@
 s%@LINT@%$LINT%g
 s%@LINTFLAGS@%$LINTFLAGS%g
 s%@XLIB@%$XLIB%g
+s%@X_SRCS@%$X_SRCS%g
+s%@DGA_SRCS@%$DGA_SRCS%g
+s%@MESA_SRCS@%$MESA_SRCS%g
 s%@DLL_LINK@%$DLL_LINK%g
 s%@BUILDFLAGS@%$BUILDFLAGS%g
 s%@DLLFLAGS@%$DLLFLAGS%g
diff --git a/configure.in b/configure.in
index ead21fa..f369738 100644
--- a/configure.in
+++ b/configure.in
@@ -110,6 +110,12 @@
 	)
 )
 AC_SUBST(XLIB)
+AC_SUBST(X_SRCS)
+X_SRCS=""
+AC_SUBST(DGA_SRCS)
+DGA_SRCS=""
+AC_SUBST(MESA_SRCS)
+MESA_SRCS=""
 if test "$have_x" = "yes"
 then
     XLIB="-lXext -lX11"
@@ -149,10 +155,19 @@
     then 
          AC_CHECK_LIB(Xxf86dga,
 	              XDGAQueryExtension,
-		      AC_DEFINE(HAVE_LIBXXF86DGA2) AC_DEFINE(HAVE_LIBXXF86DGA) X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga",,$X_LIBS -lXext -lX11 $X_EXTRA_LIBS)
+		      	AC_DEFINE(HAVE_LIBXXF86DGA2)
+			AC_DEFINE(HAVE_LIBXXF86DGA)
+			X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga"
+	 		DGA_SRCS='$(DGA_SRCS)'
+			,,$X_LIBS -lXext -lX11 $X_EXTRA_LIBS
+	 )
 	 if test "$ac_cv_lib_Xxf86dga_XDGAQueryExtension" = "no"
 	 then
-           AC_CHECK_LIB(Xxf86dga,XF86DGAQueryExtension,AC_DEFINE(HAVE_LIBXXF86DGA) X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga",,$X_LIBS -lXext -lX11 $X_EXTRA_LIBS)
+           AC_CHECK_LIB(Xxf86dga,XF86DGAQueryExtension,
+		AC_DEFINE(HAVE_LIBXXF86DGA)
+		X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga"
+		DGA_SRCS='$(DGA_SRCS)'
+		,,$X_LIBS -lXext -lX11 $X_EXTRA_LIBS)
 	 fi
     fi
 
@@ -191,10 +206,20 @@
         if test "$wine_cv_mesa_version_OK" = "yes" -a "$wine_cv_mesa_version_threadsafe" = "no"
         then
 	    dnl Check for the presense of the library
-            AC_CHECK_LIB(GL,glXCreateContext,AC_DEFINE(HAVE_LIBMESAGL) X_PRE_LIBS="$X_PRE_LIBS -lGL",,$X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS)
+            AC_CHECK_LIB(GL,glXCreateContext,
+		AC_DEFINE(HAVE_LIBMESAGL)
+		X_PRE_LIBS="$X_PRE_LIBS -lGL"
+		MESA_SRCS='$(MESA_SRCS)'
+		,,
+		$X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS)
 	    if test "$ac_cv_lib_GL_glXCreateContext" = "no"
 	    then
-		AC_CHECK_LIB(MesaGL,glXCreateContext,AC_DEFINE(HAVE_LIBMESAGL) X_PRE_LIBS="$X_PRE_LIBS -lMesaGL",,$X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS)
+		AC_CHECK_LIB(MesaGL,glXCreateContext,
+		    AC_DEFINE(HAVE_LIBMESAGL)
+		    X_PRE_LIBS="$X_PRE_LIBS -lMesaGL"
+		    MESA_SRCS='$(MESA_SRCS)'
+		    ,,
+		    $X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS)
 	    fi
 
 	    dnl Check for the Color Table and Paletted Texture extensions
@@ -215,6 +240,7 @@
     fi
 
     CPPFLAGS="$ac_save_CPPFLAGS"
+    X_SRCS='$(X_SRCS)'
 else
     XLIB=""
     X_CFLAGS=""
diff --git a/dlls/ddraw/.cvsignore b/dlls/ddraw/.cvsignore
index 2586cb4..2eea8de 100644
--- a/dlls/ddraw/.cvsignore
+++ b/dlls/ddraw/.cvsignore
@@ -1,3 +1,4 @@
 Makefile
-ddraw.spec.c
+*.spec.c
+*.spec.s
 libddraw.so.1.0
diff --git a/dlls/ddraw/Makefile.in b/dlls/ddraw/Makefile.in
index 12356c6..66e6922 100644
--- a/dlls/ddraw/Makefile.in
+++ b/dlls/ddraw/Makefile.in
@@ -8,17 +8,55 @@
 
 SPEC_SRCS = ddraw.spec
 
-C_SRCS = \
+
+MESA_SRCS = \
 	d3dcommon.c \
-	d3ddevices.c \
+	d3ddevice/mesa.c \
 	d3dexecutebuffer.c \
 	d3dlight.c \
 	d3dmaterial.c \
 	d3dtexture.c \
 	d3dviewport.c \
-	ddraw_main.c
+	direct3d/mesa.c \
+	mesa.c
+
+DGA_SRCS = \
+	ddraw/dga.c \
+	dpalette/dga.c \
+	dsurface/dga.c \
+	dga.c
+
+X_SRCS = \
+	@DGA_SRCS@ \
+	@MESA_SRCS@ \
+	ddraw/x11.c \
+	dpalette/x11.c \
+	dsurface/x11.c \
+	x11.c 
+
+C_SRCS = \
+	@X_SRCS@ \
+	convert.c \
+	d3ddevice/main.c \
+	dclipper/main.c \
+	ddraw/main.c \
+	direct3d/main.c \
+	dpalette/main.c \
+	dsurface/main.c \
+	helper.c \
+	main.c
+
+SUBDIRS = \
+	d3ddevice \
+	dclipper \
+	ddraw \
+	direct3d \
+	dpalette \
+	dsurface
 
 @MAKE_DLL_RULES@
 
-### Dependencies:
+clean::
+	for i in $(SUBDIRS); do (cd $$i && $(RM) $(CLEAN_FILES)); done
 
+### Dependencies:
diff --git a/dlls/ddraw/convert.c b/dlls/ddraw/convert.c
new file mode 100644
index 0000000..76a6d8d
--- /dev/null
+++ b/dlls/ddraw/convert.c
@@ -0,0 +1,189 @@
+#include "ddraw_private.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+/* *************************************
+      16 / 15 bpp to palettized 8 bpp
+   ************************************* */
+static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
+    unsigned char  *c_src = (unsigned char  *) src;
+    unsigned short *c_dst = (unsigned short *) dst;
+    int y;
+
+    if (palette != NULL) {
+	const unsigned short * pal = (unsigned short *) palette->screen_palents;
+
+	for (y = height; y--; ) {
+#if defined(__i386__) && defined(__GNUC__)
+	    /* gcc generates slightly inefficient code for the the copy/lookup,
+	     * it generates one excess memory access (to pal) per pixel. Since
+	     * we know that pal is not modified by the memory write we can
+	     * put it into a register and reduce the number of memory accesses 
+	     * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline
+	     * stalls. (This is not guaranteed to be the fastest method.)
+	     */
+	    __asm__ __volatile__(
+	    "xor %%eax,%%eax\n"
+	    "1:\n"
+	    "    lodsb\n"
+	    "    movw (%%edx,%%eax,2),%%ax\n"
+	    "    stosw\n"
+	    "	   xor %%eax,%%eax\n"
+	    "    loop 1b\n"
+	    : "=S" (c_src), "=D" (c_dst)
+	    : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
+	    : "eax", "cc", "memory"
+	    );
+	    c_src+=(pitch-width);
+#else
+	    unsigned char * srclineend = c_src+width;
+	    while (c_src < srclineend)
+		*c_dst++ = pal[*c_src++];
+	    c_src+=(pitch-width);
+#endif
+	}
+    } else {
+	WARN("No palette set...\n");
+	memset(dst, 0, width * height * 2);
+    }
+}
+static void palette_convert_16_to_8(
+	LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
+) {
+    int i;
+    unsigned short *pal = (unsigned short *) screen_palette;
+
+    for (i = 0; i < count; i++)
+	pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
+			  ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
+			  ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
+}
+
+static void palette_convert_15_to_8(
+	LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
+) {
+    int i;
+    unsigned short *pal = (unsigned short *) screen_palette;
+
+    for (i = 0; i < count; i++)
+	pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
+			  ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
+			  ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
+}
+
+/* *************************************
+      24 to palettized 8 bpp
+   ************************************* */
+static void pixel_convert_24_to_8(
+	void *src, void *dst, DWORD width, DWORD height, LONG pitch,
+	IDirectDrawPaletteImpl* palette
+) {
+    unsigned char  *c_src = (unsigned char  *) src;
+    unsigned char *c_dst = (unsigned char *) dst;
+    int y;
+
+    if (palette != NULL) {
+	const unsigned int *pal = (unsigned int *) palette->screen_palents;
+
+	for (y = height; y--; ) {
+	    unsigned char * srclineend = c_src+width;
+	    while (c_src < srclineend ) {
+		register long pixel = pal[*c_src++];
+		*c_dst++ = pixel;
+		*c_dst++ = pixel>>8;
+		*c_dst++ = pixel>>16;
+	    }
+	    c_src+=(pitch-width);
+	}
+    } else {
+	WARN("No palette set...\n");
+	memset(dst, 0, width * height * 4);
+    }
+}
+
+/* *************************************
+      32 bpp to palettized 8 bpp
+   ************************************* */
+static void pixel_convert_32_to_8(
+	void *src, void *dst, DWORD width, DWORD height, LONG pitch,
+	IDirectDrawPaletteImpl* palette
+) {
+    unsigned char  *c_src = (unsigned char  *) src;
+    unsigned int *c_dst = (unsigned int *) dst;
+    int y;
+
+    if (palette != NULL) {
+	const unsigned int *pal = (unsigned int *) palette->screen_palents;
+
+	for (y = height; y--; ) {
+#if defined(__i386__) && defined(__GNUC__)
+	    /* See comment in pixel_convert_16_to_8 */
+	    __asm__ __volatile__(
+	    "xor %%eax,%%eax\n"
+	    "1:\n"
+	    "    lodsb\n"
+	    "    movl (%%edx,%%eax,4),%%eax\n"
+	    "    stosl\n"
+	    "	   xor %%eax,%%eax\n"
+	    "    loop 1b\n"
+	    : "=S" (c_src), "=D" (c_dst)
+	    : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
+	    : "eax", "cc", "memory"
+	    );
+	    c_src+=(pitch-width);
+#else
+	    unsigned char * srclineend = c_src+width;
+	    while (c_src < srclineend )
+		*c_dst++ = pal[*c_src++];
+	    c_src+=(pitch-width);
+#endif
+	}
+    } else {
+	WARN("No palette set...\n");
+	memset(dst, 0, width * height * 4);
+    }
+}
+
+static void palette_convert_24_to_8(
+	LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count
+) {
+    int i;
+    unsigned int *pal = (unsigned int *) screen_palette;
+  
+    for (i = 0; i < count; i++)
+	pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
+			  (((unsigned int) palent[i].peGreen) << 8) |
+			   ((unsigned int) palent[i].peBlue));
+}
+
+/* *************************************
+      32 bpp to 16 bpp
+   ************************************* */
+static void pixel_convert_32_to_16(
+	void *src, void *dst, DWORD width, DWORD height, LONG pitch,
+	IDirectDrawPaletteImpl* palette
+) {
+    unsigned short *c_src = (unsigned short *) src;
+    unsigned int *c_dst = (unsigned int *) dst;
+    int y;
+
+    for (y = height; y--; ) {
+	unsigned short * srclineend = c_src+width;
+	while (c_src < srclineend ) {
+	    *c_dst++ = (((*c_src & 0xF800) << 8) |
+			((*c_src & 0x07E0) << 5) |
+			((*c_src & 0x001F) << 3));
+	    c_src++;
+	}
+	c_src+=((pitch/2)-width);
+    }
+}
+
+Convert ModeEmulations[5] = {
+  { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8,  palette_convert_24_to_8 } },
+  { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, {  16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
+  { { 24, 24,   0xFF0000,   0x00FF00,   0x0000FF }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8,  palette_convert_24_to_8 } },
+  { { 16, 16,     0xF800,     0x07E0,     0x001F }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8,  palette_convert_16_to_8 } },
+  { { 16, 15,     0x7C00,     0x03E0,     0x001F }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8,  palette_convert_15_to_8 } },
+};
diff --git a/dlls/ddraw/d3d_private.h b/dlls/ddraw/d3d_private.h
index 8ac67cc..dbadb95 100644
--- a/dlls/ddraw/d3d_private.h
+++ b/dlls/ddraw/d3d_private.h
@@ -7,13 +7,10 @@
 #ifndef __GRAPHICS_WINE_D3D_PRIVATE_H
 #define __GRAPHICS_WINE_D3D_PRIVATE_H
 
-#include "wine_gl.h"
+/* THIS FILE MUST NOT CONTAIN X11 or MESA DEFINES */
+
 #include "d3d.h"
 
-#include "x11drv.h"
-
-#undef USE_OSMESA
-
 /*****************************************************************************
  * Predeclare the interface implementation structures
  */
@@ -29,6 +26,9 @@
 
 #include "ddraw_private.h"
 
+extern ICOM_VTABLE(IDirect3D)	mesa_d3dvt;
+extern ICOM_VTABLE(IDirect3D2)	mesa_d3d2vt;
+
 /*****************************************************************************
  * IDirect3D implementation structure
  */
@@ -38,7 +38,8 @@
     ICOM_VFIELD(IDirect3D);
     DWORD                   ref;
     /* IDirect3D fields */
-    IDirectDrawImpl* ddraw;
+    IDirectDrawImpl*	ddraw;
+    LPVOID		private;
 };
 
 /*****************************************************************************
@@ -50,9 +51,55 @@
     ICOM_VFIELD(IDirect3D2);
     DWORD                    ref;
     /* IDirect3D2 fields */
-    IDirectDrawImpl* ddraw;
+    IDirectDrawImpl*	ddraw;
+    LPVOID		private;
 };
 
+extern HRESULT WINAPI IDirect3DImpl_QueryInterface(
+    LPDIRECT3D iface,REFIID refiid,LPVOID *obj
+);
+extern ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface);
+extern ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
+;
+extern HRESULT WINAPI IDirect3DImpl_Initialize(LPDIRECT3D iface,REFIID refiid);
+extern HRESULT WINAPI IDirect3DImpl_EnumDevices(
+    LPDIRECT3D iface, LPD3DENUMDEVICESCALLBACK cb, LPVOID context
+);
+extern HRESULT WINAPI IDirect3DImpl_CreateLight(
+    LPDIRECT3D iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
+);
+extern HRESULT WINAPI IDirect3DImpl_CreateMaterial(
+    LPDIRECT3D iface, LPDIRECT3DMATERIAL *lpmaterial, IUnknown *lpunk
+);
+extern HRESULT WINAPI IDirect3DImpl_CreateViewport(
+    LPDIRECT3D iface, LPDIRECT3DVIEWPORT *lpviewport, IUnknown *lpunk
+);
+extern HRESULT WINAPI IDirect3DImpl_FindDevice(
+    LPDIRECT3D iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
+    LPD3DFINDDEVICERESULT lpfinddevrst)
+;
+extern HRESULT WINAPI IDirect3D2Impl_QueryInterface(LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj);  
+extern ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface);
+extern ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface);
+extern HRESULT WINAPI IDirect3D2Impl_EnumDevices(
+    LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
+);
+extern HRESULT WINAPI IDirect3D2Impl_CreateLight(
+    LPDIRECT3D2 iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
+);
+extern HRESULT WINAPI IDirect3D2Impl_CreateMaterial(
+    LPDIRECT3D2 iface, LPDIRECT3DMATERIAL2 *lpmaterial, IUnknown *lpunk
+);
+extern HRESULT WINAPI IDirect3D2Impl_CreateViewport(
+    LPDIRECT3D2 iface, LPDIRECT3DVIEWPORT2 *lpviewport, IUnknown *lpunk
+);
+extern HRESULT WINAPI IDirect3D2Impl_FindDevice(
+    LPDIRECT3D2 iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
+    LPD3DFINDDEVICERESULT lpfinddevrst);
+extern HRESULT WINAPI IDirect3D2Impl_CreateDevice(
+    LPDIRECT3D2 iface, REFCLSID rguid, LPDIRECTDRAWSURFACE surface,
+    LPDIRECT3DDEVICE2 *device);
+
 /*****************************************************************************
  * IDirect3DLight implementation structure
  */
@@ -77,10 +124,7 @@
     void (*activate)(IDirect3DLightImpl*);
     int                 is_active;
   
-    /* Awful OpenGL code !!! */
-#ifdef HAVE_MESAGL
-    GLenum              light_num;
-#endif
+    LPVOID		private;
 };
 
 /*****************************************************************************
@@ -105,6 +149,7 @@
     D3DMATERIAL               mat;
 
     void (*activate)(IDirect3DMaterial2Impl* this);
+    LPVOID			private;
 };
 
 /*****************************************************************************
@@ -116,14 +161,37 @@
     ICOM_VFIELD(IDirect3DTexture2);
     DWORD                           ref;
     /* IDirect3DTexture2 fields */
-    void*                    D3Ddevice; /* I put (void *) to use the same pointer for both
-		                           Direct3D and Direct3D2 */
-#ifdef HAVE_MESAGL
-    GLuint                   tex_name;
-#endif  
-    IDirectDrawSurface4Impl* surface;
+    void*			D3Ddevice; /* (void *) to use the same pointer
+					    * for both Direct3D and Direct3D2 */
+    IDirectDrawSurface4Impl*	surface;
+    LPVOID			private;
 };
 
+extern HRESULT WINAPI IDirect3DTexture2Impl_QueryInterface(
+    LPDIRECT3DTEXTURE2 iface, REFIID riid, LPVOID* ppvObj
+);
+extern ULONG WINAPI IDirect3DTexture2Impl_AddRef(LPDIRECT3DTEXTURE2 iface);
+extern ULONG WINAPI IDirect3DTexture2Impl_Release(LPDIRECT3DTEXTURE2 iface);
+extern HRESULT WINAPI IDirect3DTextureImpl_GetHandle(LPDIRECT3DTEXTURE iface,
+						 LPDIRECT3DDEVICE lpD3DDevice,
+						 LPD3DTEXTUREHANDLE lpHandle)
+;
+extern HRESULT WINAPI IDirect3DTextureImpl_Initialize(LPDIRECT3DTEXTURE iface,
+					  LPDIRECT3DDEVICE lpD3DDevice,
+					  LPDIRECTDRAWSURFACE lpSurface)
+;
+extern HRESULT WINAPI IDirect3DTextureImpl_Unload(LPDIRECT3DTEXTURE iface);
+extern HRESULT WINAPI IDirect3DTexture2Impl_GetHandle(
+    LPDIRECT3DTEXTURE2 iface, LPDIRECT3DDEVICE2 lpD3DDevice2,
+    LPD3DTEXTUREHANDLE lpHandle
+);
+extern HRESULT WINAPI IDirect3DTexture2Impl_PaletteChanged(
+    LPDIRECT3DTEXTURE2 iface, DWORD dwStart, DWORD dwCount
+);
+extern HRESULT WINAPI IDirect3DTexture2Impl_Load(
+    LPDIRECT3DTEXTURE2 iface, LPDIRECT3DTEXTURE2 lpD3DTexture2
+);
+
 /*****************************************************************************
  * IDirect3DViewport2 implementation structure
  */
@@ -139,32 +207,84 @@
     } d3d;
     /* If this viewport is active for one device, put the device here */
     union {
-        IDirect3DDeviceImpl*  active_device1;
-        IDirect3DDevice2Impl* active_device2;
+        IDirect3DDeviceImpl*	active_device1;
+        IDirect3DDevice2Impl*	active_device2;
     } device;
-    int                       use_d3d2;
+    int				use_d3d2;
 
     union {
-        D3DVIEWPORT           vp1;
-        D3DVIEWPORT2          vp2;
+        D3DVIEWPORT		vp1;
+        D3DVIEWPORT2		vp2;
     } viewport;
-    int                       use_vp2;
+    int				use_vp2;
 
   /* Activation function */
   void (*activate)(IDirect3DViewport2Impl*);
   
   /* Field used to chain viewports together */
-  IDirect3DViewport2Impl*     next;
+  IDirect3DViewport2Impl*	next;
 
   /* Lights list */
-  IDirect3DLightImpl*         lights;
-
-  /* OpenGL code */
-#ifdef HAVE_MESAGL
-  GLenum                      nextlight;
-#endif
+  IDirect3DLightImpl*		lights;
+  
+  LPVOID			private;
 };
 
+extern HRESULT WINAPI IDirect3DViewport2Impl_QueryInterface(
+    LPDIRECT3DVIEWPORT2 iface, REFIID riid, LPVOID* ppvObj
+);
+extern ULONG WINAPI IDirect3DViewport2Impl_AddRef(LPDIRECT3DVIEWPORT2 iface)
+;
+extern ULONG WINAPI IDirect3DViewport2Impl_Release(LPDIRECT3DVIEWPORT2 iface)
+;
+extern HRESULT WINAPI IDirect3DViewport2Impl_Initialize(
+    LPDIRECT3DVIEWPORT2 iface, LPDIRECT3D d3d
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_GetViewport(
+    LPDIRECT3DVIEWPORT2 iface, LPD3DVIEWPORT lpvp
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_SetViewport(
+    LPDIRECT3DVIEWPORT2 iface,LPD3DVIEWPORT lpvp
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_TransformVertices(
+    LPDIRECT3DVIEWPORT2 iface,DWORD dwVertexCount,LPD3DTRANSFORMDATA lpData,
+    DWORD dwFlags,LPDWORD lpOffScreen
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_LightElements(
+    LPDIRECT3DVIEWPORT2 iface,DWORD dwElementCount,LPD3DLIGHTDATA lpData
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_SetBackground(
+    LPDIRECT3DVIEWPORT2 iface, D3DMATERIALHANDLE hMat
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_GetBackground(
+    LPDIRECT3DVIEWPORT2 iface,LPD3DMATERIALHANDLE lphMat,LPBOOL lpValid
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_SetBackgroundDepth(
+    LPDIRECT3DVIEWPORT2 iface,LPDIRECTDRAWSURFACE lpDDSurface
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_GetBackgroundDepth(
+    LPDIRECT3DVIEWPORT2 iface,LPDIRECTDRAWSURFACE* lplpDDSurface,LPBOOL lpValid
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_Clear(
+    LPDIRECT3DVIEWPORT2 iface, DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_AddLight(
+    LPDIRECT3DVIEWPORT2 iface,LPDIRECT3DLIGHT lpLight
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_DeleteLight(
+    LPDIRECT3DVIEWPORT2 iface,LPDIRECT3DLIGHT lpLight
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_NextLight(
+    LPDIRECT3DVIEWPORT2 iface, LPDIRECT3DLIGHT lpLight,
+    LPDIRECT3DLIGHT* lplpLight, DWORD dwFlags
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_GetViewport2(
+    LPDIRECT3DVIEWPORT2 iface, LPD3DVIEWPORT2 lpViewport2
+);
+extern HRESULT WINAPI IDirect3DViewport2Impl_SetViewport2(
+    LPDIRECT3DVIEWPORT2 iface, LPD3DVIEWPORT2 lpViewport2
+);
+
 /*****************************************************************************
  * IDirect3DExecuteBuffer implementation structure
  */
@@ -190,7 +310,9 @@
     void (*execute)(IDirect3DExecuteBuffer* this,
                     IDirect3DDevice* dev,
                     IDirect3DViewport2* vp);
+    LPVOID private;
 };
+extern LPDIRECT3DEXECUTEBUFFER d3dexecutebuffer_create(IDirect3DDeviceImpl* d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc);
 
 /*****************************************************************************
  * IDirect3DDevice implementation structure
@@ -208,6 +330,7 @@
     IDirect3DViewport2Impl*  current_viewport;
 
     void (*set_context)(IDirect3DDeviceImpl*);
+    LPVOID		private;
 };
 
 /*****************************************************************************
@@ -226,118 +349,175 @@
     IDirect3DViewport2Impl* current_viewport;
 
     void (*set_context)(IDirect3DDevice2Impl*);
+    LPVOID		private;
 };
-
-
-
-#ifdef HAVE_MESAGL
-
-#ifdef USE_OSMESA
-#define LEAVE_GL() ;
-#define ENTER_GL() ;
-#else
-#define LEAVE_GL() LeaveCriticalSection( &X11DRV_CritSection )
-#define ENTER_GL() EnterCriticalSection( &X11DRV_CritSection )
-#endif
-
-/* Matrix copy WITH transposition */
-#define conv_mat2(mat,gl_mat)			\
-{						\
-  TRACE("%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \
-  TRACE("%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \
-  TRACE("%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \
-  TRACE("%f %f %f %f\n", (mat)->_41, (mat)->_42, (mat)->_43, (mat)->_44); \
-  (gl_mat)[ 0] = (mat)->_11;			\
-  (gl_mat)[ 1] = (mat)->_21;			\
-  (gl_mat)[ 2] = (mat)->_31;			\
-  (gl_mat)[ 3] = (mat)->_41;			\
-  (gl_mat)[ 4] = (mat)->_12;			\
-  (gl_mat)[ 5] = (mat)->_22;			\
-  (gl_mat)[ 6] = (mat)->_32;			\
-  (gl_mat)[ 7] = (mat)->_42;			\
-  (gl_mat)[ 8] = (mat)->_13;			\
-  (gl_mat)[ 9] = (mat)->_23;			\
-  (gl_mat)[10] = (mat)->_33;			\
-  (gl_mat)[11] = (mat)->_43;			\
-  (gl_mat)[12] = (mat)->_14;			\
-  (gl_mat)[13] = (mat)->_24;			\
-  (gl_mat)[14] = (mat)->_34;			\
-  (gl_mat)[15] = (mat)->_44;			\
-};
-
-/* Matrix copy WITHOUT transposition */
-#define conv_mat(mat,gl_mat)			\
-{                                               \
-  TRACE("%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \
-  TRACE("%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \
-  TRACE("%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \
-  TRACE("%f %f %f %f\n", (mat)->_41, (mat)->_42, (mat)->_43, (mat)->_44); \
-  memcpy(gl_mat, (mat), 16 * sizeof(float));      \
-};
-
-#define dump_mat(mat) \
-  TRACE("%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \
-  TRACE("%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \
-  TRACE("%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \
-  TRACE("%f %f %f %f\n", (mat)->_41, (mat)->_42, (mat)->_43, (mat)->_44);
-
-typedef struct render_state {
-  /* This is used for the device mode */
-  GLenum src, dst;
-  /* This is used for textures */
-  GLenum mag, min;
-} RenderState;
-
-typedef struct OpenGL_IDirect3DDevice2 {
-  IDirect3DDevice2Impl common;
-  
-  /* These are the OpenGL-specific variables */
-#ifdef USE_OSMESA
-  OSMesaContext ctx;
-  unsigned char *buffer;
-#else
-  GLXContext ctx;
-#endif
-  
-  /* The current render state */
-  RenderState rs;
-
-  /* The last type of vertex drawn */
-  D3DVERTEXTYPE vt;
-  
-  float world_mat[16];
-  float view_mat[16];
-  float proj_mat[16];
-} OpenGL_IDirect3DDevice2;
-
-typedef struct OpenGL_IDirect3DDevice {
-  IDirect3DDeviceImpl common;
-  
-  /* These are the OpenGL-specific variables */
-#ifdef USE_OSMESA
-  OSMesaContext ctx;
-  unsigned char *buffer;
-#else
-  GLXContext ctx;
-#endif
-  
-  /* The current render state */
-  RenderState rs;
-  
-  D3DMATRIX *world_mat;
-  D3DMATRIX *view_mat;
-  D3DMATRIX *proj_mat;
-} OpenGL_IDirect3DDevice;
-
-#define _dump_colorvalue(s,v)               \
-  TRACE(" " s " : %f %f %f %f\n",           \
-	(v).r.r, (v).g.g, (v).b.b, (v).a.a);
-
-/* Common functions defined in d3dcommon.c */
-void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
-		      DWORD dwRenderState, RenderState *rs) ;
-
-#endif /* HAVE_MESAGL */
+extern HRESULT WINAPI IDirect3DDevice2Impl_QueryInterface(
+    LPDIRECT3DDEVICE2 iface, REFIID riid, LPVOID* ppvObj
+);
+extern ULONG WINAPI IDirect3DDevice2Impl_AddRef(LPDIRECT3DDEVICE2 iface);
+extern ULONG WINAPI IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
+;
+extern HRESULT WINAPI IDirect3DDevice2Impl_GetCaps(
+    LPDIRECT3DDEVICE2 iface, LPD3DDEVICEDESC lpdescsoft,
+    LPD3DDEVICEDESC lpdeschard
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_SwapTextureHandles(
+    LPDIRECT3DDEVICE2 iface,LPDIRECT3DTEXTURE2 lptex1,LPDIRECT3DTEXTURE2 lptex2
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_GetStats(
+    LPDIRECT3DDEVICE2 iface, LPD3DSTATS lpstats)
+;
+extern HRESULT WINAPI IDirect3DDevice2Impl_AddViewport(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_DeleteViewport(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp)
+;
+extern HRESULT WINAPI IDirect3DDevice2Impl_NextViewport(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp,
+    LPDIRECT3DVIEWPORT2* lplpvp, DWORD dwFlags
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_EnumTextureFormats(
+    LPDIRECT3DDEVICE2 iface, LPD3DENUMTEXTUREFORMATSCALLBACK cb, LPVOID context
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_BeginScene(LPDIRECT3DDEVICE2 iface);
+extern HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface);
+extern HRESULT WINAPI IDirect3DDevice2Impl_GetDirect3D(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3D2 *lpd3d2
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_SetCurrentViewport(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_GetCurrentViewport(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 *lplpvp
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_SetRenderTarget(
+    LPDIRECT3DDEVICE2 iface, LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_GetRenderTarget(
+    LPDIRECT3DDEVICE2 iface, LPDIRECTDRAWSURFACE *lplpdds
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_Begin(
+    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
+    DWORD dwFlags
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_BeginIndexed(
+    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
+    LPVOID lpvert, DWORD numvert, DWORD dwFlags
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_Vertex(
+    LPDIRECT3DDEVICE2 iface,LPVOID lpvert
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_Index(LPDIRECT3DDEVICE2 iface, WORD index);
+extern HRESULT WINAPI IDirect3DDevice2Impl_End(LPDIRECT3DDEVICE2 iface,DWORD dwFlags);
+extern HRESULT WINAPI IDirect3DDevice2Impl_GetRenderState(
+    LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE d3drs, LPDWORD lprstate
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_SetRenderState(
+    LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE dwRenderStateType,
+    DWORD dwRenderState
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_GetLightState(
+    LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE d3dls, LPDWORD lplstate
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_SetLightState(
+    LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE dwLightStateType,
+    DWORD dwLightState
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_SetTransform(
+    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_GetTransform(
+    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_MultiplyTransform(
+    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_DrawPrimitive(
+    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
+    LPVOID lpvertex, DWORD vertcount, DWORD dwFlags
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_DrawIndexedPrimitive(
+    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
+    LPVOID lpvertex, DWORD vertcount, LPWORD lpindexes, DWORD indexcount,
+    DWORD dwFlags
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_SetClipStatus(
+    LPDIRECT3DDEVICE2 iface, LPD3DCLIPSTATUS lpcs
+);
+extern HRESULT WINAPI IDirect3DDevice2Impl_GetClipStatus(
+    LPDIRECT3DDEVICE2 iface, LPD3DCLIPSTATUS lpcs
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_QueryInterface(
+    LPDIRECT3DDEVICE iface, REFIID riid, LPVOID* ppvObj
+);
+extern ULONG WINAPI IDirect3DDeviceImpl_AddRef(LPDIRECT3DDEVICE iface);
+extern ULONG WINAPI IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface);
+extern HRESULT WINAPI IDirect3DDeviceImpl_Initialize(
+    LPDIRECT3DDEVICE iface, LPDIRECT3D lpd3d, LPGUID lpGUID,
+    LPD3DDEVICEDESC lpd3ddvdesc
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_GetCaps(
+    LPDIRECT3DDEVICE iface, LPD3DDEVICEDESC lpD3DHWDevDesc,
+    LPD3DDEVICEDESC lpD3DSWDevDesc
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_SwapTextureHandles(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DTEXTURE lpD3DTex1,
+    LPDIRECT3DTEXTURE lpD3DTex2
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_CreateExecuteBuffer(
+    LPDIRECT3DDEVICE iface, LPD3DEXECUTEBUFFERDESC lpDesc,
+    LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer, IUnknown *pUnkOuter
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_GetStats(
+    LPDIRECT3DDEVICE iface, LPD3DSTATS lpD3DStats
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_Execute(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
+    LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_AddViewport(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_DeleteViewport(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_NextViewport(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp,
+    LPDIRECT3DVIEWPORT* lplpvp, DWORD dwFlags
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_Pick(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
+    LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags, LPD3DRECT lpRect
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_GetPickRecords(
+    LPDIRECT3DDEVICE iface, LPDWORD lpCount, LPD3DPICKRECORD lpD3DPickRec
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_EnumTextureFormats(
+    LPDIRECT3DDEVICE iface,LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
+    LPVOID lpArg
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_CreateMatrix(
+    LPDIRECT3DDEVICE iface, LPD3DMATRIXHANDLE lpD3DMatHandle
+)
+;
+extern HRESULT WINAPI IDirect3DDeviceImpl_SetMatrix(
+    LPDIRECT3DDEVICE iface, D3DMATRIXHANDLE d3dMatHandle,
+    const LPD3DMATRIX lpD3DMatrix)
+;
+extern HRESULT WINAPI IDirect3DDeviceImpl_GetMatrix(
+    LPDIRECT3DDEVICE iface,D3DMATRIXHANDLE D3DMatHandle,LPD3DMATRIX lpD3DMatrix
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_DeleteMatrix(
+    LPDIRECT3DDEVICE iface, D3DMATRIXHANDLE d3dMatHandle
+);
+extern HRESULT WINAPI IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
+;
+extern HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
+;
+extern HRESULT WINAPI IDirect3DDeviceImpl_GetDirect3D(
+    LPDIRECT3DDEVICE iface, LPDIRECT3D *lpDirect3D
+);
 
 /* All non-static functions 'exported' by various sub-objects */
 extern LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurface4Impl* surf);
@@ -360,4 +540,12 @@
 extern int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d);
 
 
+extern void _dump_renderstate(D3DRENDERSTATETYPE type, DWORD value);
+
+#define dump_mat(mat) \
+    TRACE("%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \
+    TRACE("%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \
+    TRACE("%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \
+    TRACE("%f %f %f %f\n", (mat)->_41, (mat)->_42, (mat)->_43, (mat)->_44);
+
 #endif /* __GRAPHICS_WINE_D3D_PRIVATE_H */
diff --git a/dlls/ddraw/d3dcommon.c b/dlls/ddraw/d3dcommon.c
index f217996..c27582f 100644
--- a/dlls/ddraw/d3dcommon.c
+++ b/dlls/ddraw/d3dcommon.c
@@ -14,10 +14,7 @@
 
 DEFAULT_DEBUG_CHANNEL(ddraw)
 
-#ifdef HAVE_MESAGL
-
-static void _dump_renderstate(D3DRENDERSTATETYPE type,
-			      DWORD value) {
+void _dump_renderstate(D3DRENDERSTATETYPE type, DWORD value) {
   char *states[] = {
     NULL,
     "D3DRENDERSTATE_TEXTUREHANDLE",
@@ -105,245 +102,5 @@
     "D3DRENDERSTATE_STIPPLEPATTERN30",
     "D3DRENDERSTATE_STIPPLEPATTERN31"
   };
-
   DPRINTF(" %s = 0x%08lx\n", states[type], value);
 }
-
-
-void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
-		      DWORD dwRenderState, RenderState *rs)
-{
-
-  if (TRACE_ON(ddraw))
-    _dump_renderstate(dwRenderStateType, dwRenderState);
-
-  /* First, all the stipple patterns */
-  if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) && 
-      (dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) {
-    ERR("Unhandled stipple !\n");
-  } else {
-    ENTER_GL();
-    
-    /* All others state variables */
-    switch (dwRenderStateType) {
-
-    case D3DRENDERSTATE_TEXTUREHANDLE: {    /*  1 */
-      IDirect3DTexture2Impl* tex = (IDirect3DTexture2Impl*) dwRenderState;
-      
-      if (tex == NULL) {
-	glBindTexture(GL_TEXTURE_2D, 0);
-	glDisable(GL_TEXTURE_2D);
-      } else {
-	TRACE("setting OpenGL texture handle : %d\n", tex->tex_name);
-	glEnable(GL_TEXTURE_2D);
-	/* Default parameters */
-	glBindTexture(GL_TEXTURE_2D, tex->tex_name);
-	/* To prevent state change, we could test here what are the parameters
-	   stored in the texture */
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, rs->mag);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, rs->min);
-      }
-    } break;
-
-    case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */
-      if (dwRenderState)
-	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
-      else
-	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
-      break;
-      
-    case D3DRENDERSTATE_ZENABLE:          /*  7 */
-      if (dwRenderState)
-	glEnable(GL_DEPTH_TEST);
-      else
-	glDisable(GL_DEPTH_TEST);
-      break;
-      
-    case D3DRENDERSTATE_FILLMODE:           /*  8 */
-      switch ((D3DFILLMODE) dwRenderState) {
-      case D3DFILL_SOLID:
-	break;
-
-      default:
-	ERR("Unhandled fill mode !\n");
-      }
-      break;
-
-    case D3DRENDERSTATE_SHADEMODE:          /*  9 */
-      switch ((D3DSHADEMODE) dwRenderState) {
-      case D3DSHADE_FLAT:
-	glShadeModel(GL_FLAT);
-	break;
-
-      case D3DSHADE_GOURAUD:
-	glShadeModel(GL_SMOOTH);
-	break;
-
-      default:
-	ERR("Unhandled shade mode !\n");
-      }
-      break;
-      
-    case D3DRENDERSTATE_ZWRITEENABLE:     /* 14 */
-      if (dwRenderState)
-	glDepthMask(GL_TRUE);
-      else
-	glDepthMask(GL_FALSE);
-      break;
-      
-    case D3DRENDERSTATE_TEXTUREMAG:         /* 17 */
-      switch ((D3DTEXTUREFILTER) dwRenderState) {
-      case D3DFILTER_NEAREST:
-	rs->mag = GL_NEAREST;
-	break;
-	
-      case D3DFILTER_LINEAR:
-	rs->mag = GL_LINEAR;
-	break;
-	
-      default:
-	ERR("Unhandled texture mag !\n");
-      }
-      break;
-
-    case D3DRENDERSTATE_TEXTUREMIN:         /* 18 */
-      switch ((D3DTEXTUREFILTER) dwRenderState) {
-      case D3DFILTER_NEAREST:
-	rs->min = GL_NEAREST;
-	break;
-	
-      case D3DFILTER_LINEAR:
-	rs->mag = GL_LINEAR;
-	break;
-	
-      default:
-	ERR("Unhandled texture min !\n");
-      }
-      break;
-      
-    case D3DRENDERSTATE_SRCBLEND:           /* 19 */
-      switch ((D3DBLEND) dwRenderState) {
-      case D3DBLEND_SRCALPHA:
-	rs->src = GL_SRC_ALPHA;
-	break;
-
-      default:
-	ERR("Unhandled blend mode !\n");
-      }
-      
-      glBlendFunc(rs->src, rs->dst);
-      break;
-      
-    case D3DRENDERSTATE_DESTBLEND:          /* 20 */
-      switch ((D3DBLEND) dwRenderState) {
-      case D3DBLEND_INVSRCALPHA:
-	rs->dst = GL_ONE_MINUS_SRC_ALPHA;
-	break;
-	
-      default:
-	ERR("Unhandled blend mode !\n");
-      }
-      
-      glBlendFunc(rs->src, rs->dst);
-      break;
-
-    case D3DRENDERSTATE_TEXTUREMAPBLEND:    /* 21 */
-      switch ((D3DTEXTUREBLEND) dwRenderState) {
-      case D3DTBLEND_MODULATE:
-      case D3DTBLEND_MODULATEALPHA:
-	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-	break;
-
-      default:
-	ERR("Unhandled texture environment !\n");
-      }
-      break;
-      
-    case D3DRENDERSTATE_CULLMODE:           /* 22 */
-      switch ((D3DCULL) dwRenderState) {
-      case D3DCULL_NONE:
-	glDisable(GL_CULL_FACE);
-	break;
-	
-      case D3DCULL_CW:
-	glEnable(GL_CULL_FACE);
-	glFrontFace(GL_CW);
-	break;
-	
-      case D3DCULL_CCW:
-	glEnable(GL_CULL_FACE);
-	glFrontFace(GL_CCW);
-	break;
-	
-      default:
-	ERR("Unhandled cull mode !\n");
-      }
-      break;
-      
-    case D3DRENDERSTATE_ZFUNC:            /* 23 */
-      switch ((D3DCMPFUNC) dwRenderState) {
-      case D3DCMP_NEVER:
-	glDepthFunc(GL_NEVER);
-	break;
-      case D3DCMP_LESS:
-	glDepthFunc(GL_LESS);
-	break;
-      case D3DCMP_EQUAL:
-	glDepthFunc(GL_EQUAL);
-	break;
-      case D3DCMP_LESSEQUAL:
-	glDepthFunc(GL_LEQUAL);
-	break;
-      case D3DCMP_GREATER:
-	glDepthFunc(GL_GREATER);
-	break;
-      case D3DCMP_NOTEQUAL:
-	glDepthFunc(GL_NOTEQUAL);
-	break;
-      case D3DCMP_GREATEREQUAL:
-	glDepthFunc(GL_GEQUAL);
-	break;
-      case D3DCMP_ALWAYS:
-	glDepthFunc(GL_ALWAYS);
-	break;
-
-      default:
-	ERR("Unexpected value\n");
-      }
-      break;
-      
-    case D3DRENDERSTATE_DITHERENABLE:     /* 26 */
-      if (dwRenderState)
-	glEnable(GL_DITHER);
-      else
-	glDisable(GL_DITHER);
-      break;
-      
-    case D3DRENDERSTATE_ALPHABLENDENABLE:   /* 27 */
-      if (dwRenderState)
-	glEnable(GL_BLEND);
-      else
-	glDisable(GL_BLEND);
-      break;
-
-    case D3DRENDERSTATE_COLORKEYENABLE:     /* 41 */
-      if (dwRenderState)
-	glEnable(GL_BLEND);
-      else
-	glDisable(GL_BLEND);
-      break;
-
-    case D3DRENDERSTATE_FLUSHBATCH:         /* 50 */
-      break;
-      
-    default:
-      ERR("Unhandled Render State\n");
-      break;
-    }
-
-    LEAVE_GL();
-  }
-}
-
-
-#endif /* HAVE_MESAGL */
diff --git a/dlls/ddraw/d3ddevice/main.c b/dlls/ddraw/d3ddevice/main.c
new file mode 100644
index 0000000..147ddfb
--- /dev/null
+++ b/dlls/ddraw/d3ddevice/main.c
@@ -0,0 +1,699 @@
+/* Direct3D Device
+   (c) 1998 Lionel ULMER
+   
+   This files contains all the common stuff for D3D devices.
+ */
+
+#include <string.h>
+#include "config.h"
+#include "windef.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "heap.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debugtools.h"
+
+#include "d3d_private.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw)
+
+/*******************************************************************************
+ *				IDirect3DDevice2
+ */
+
+HRESULT WINAPI IDirect3DDevice2Impl_QueryInterface(
+    LPDIRECT3DDEVICE2 iface, REFIID riid, LPVOID* ppvObj
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
+    return S_OK;
+}
+
+ULONG WINAPI IDirect3DDevice2Impl_AddRef(LPDIRECT3DDEVICE2 iface)
+{
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
+
+    return ++(This->ref);
+}
+
+
+
+ULONG WINAPI IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
+{
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
+
+    if (!--(This->ref)) {
+	HeapFree(GetProcessHeap(),0,This);
+	return 0;
+    }
+    return This->ref;
+}
+
+
+/*** IDirect3DDevice2 methods ***/
+HRESULT WINAPI IDirect3DDevice2Impl_GetCaps(
+    LPDIRECT3DDEVICE2 iface, LPD3DDEVICEDESC lpdescsoft,
+    LPD3DDEVICEDESC lpdeschard
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%p,%p), stub!\n", This, lpdescsoft, lpdeschard);
+    return DD_OK;
+}
+
+
+
+HRESULT WINAPI IDirect3DDevice2Impl_SwapTextureHandles(
+    LPDIRECT3DDEVICE2 iface,LPDIRECT3DTEXTURE2 lptex1,LPDIRECT3DTEXTURE2 lptex2
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%p,%p): stub\n", This, lptex1, lptex2);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_GetStats(
+    LPDIRECT3DDEVICE2 iface, LPD3DSTATS lpstats)
+{
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%p): stub\n", This, lpstats);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_AddViewport(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
+    FIXME("(%p)->(%p): stub\n", This, ilpvp);
+
+    /* Adds this viewport to the viewport list */
+    ilpvp->next = This->viewport_list;
+    This->viewport_list = ilpvp;
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_DeleteViewport(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp)
+{
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
+    IDirect3DViewport2Impl *cur, *prev;
+    FIXME("(%p)->(%p): stub\n", This, lpvp);
+
+    /* Finds this viewport in the list */
+    prev = NULL;
+    cur = This->viewport_list;
+    while ((cur != NULL) && (cur != ilpvp)) {
+	prev = cur;
+	cur = cur->next;
+    }
+    if (cur == NULL)
+	return DDERR_INVALIDOBJECT;
+
+    /* And remove it */
+    if (prev == NULL)
+	This->viewport_list = cur->next;
+    else
+	prev->next = cur->next;
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_NextViewport(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp,
+    LPDIRECT3DVIEWPORT2* lplpvp, DWORD dwFlags
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
+    IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
+    FIXME("(%p)->(%p,%p,%08lx): stub\n", This, lpvp, lpvp, dwFlags);
+
+    switch (dwFlags) {
+    case D3DNEXT_NEXT:
+	*ilplpvp = ilpvp->next;
+	break;
+    case D3DNEXT_HEAD:
+	*ilplpvp = This->viewport_list;
+	break;
+    case D3DNEXT_TAIL:
+	ilpvp = This->viewport_list;
+	while (ilpvp->next != NULL)
+	    ilpvp = ilpvp->next;
+	*ilplpvp = ilpvp;
+	break;
+    default:
+	return DDERR_INVALIDPARAMS;
+    }
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_EnumTextureFormats(
+    LPDIRECT3DDEVICE2 iface, LPD3DENUMTEXTUREFORMATSCALLBACK cb, LPVOID context
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%p,%p), stub!\n", This, cb, context);
+
+    return DD_OK; /* no texture formats in stub implementation */
+}
+
+
+
+HRESULT WINAPI IDirect3DDevice2Impl_BeginScene(LPDIRECT3DDEVICE2 iface)
+{
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+
+    FIXME("(%p)->(), stub!\n", This);
+
+    /* Here, we should get the DDraw surface and 'copy it' to the
+     OpenGL surface.... */
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface)
+{
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(): stub\n", This);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_GetDirect3D(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3D2 *lpd3d2
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    TRACE("(%p)->(%p): stub\n", This, lpd3d2);
+    *lpd3d2 = (LPDIRECT3D2)This->d3d;
+    return DD_OK;
+}
+
+/*** DrawPrimitive API ***/
+HRESULT WINAPI IDirect3DDevice2Impl_SetCurrentViewport(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
+    FIXME("(%p)->(%p): stub\n", This, ilpvp);
+
+    /* Should check if the viewport was added or not */
+
+    /* Set this viewport as the current viewport */
+    This->current_viewport = ilpvp;
+
+    /* Activate this viewport */
+    ilpvp->device.active_device2 = This;
+    ilpvp->activate(ilpvp);
+
+    return DD_OK;
+}
+
+
+
+HRESULT WINAPI IDirect3DDevice2Impl_GetCurrentViewport(
+    LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 *lplpvp
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%p): stub\n", This, lplpvp);
+
+    /* Returns the current viewport */
+    *lplpvp = (LPDIRECT3DVIEWPORT2)This->current_viewport;
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_SetRenderTarget(
+    LPDIRECT3DDEVICE2 iface, LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%p,%08lx): stub\n", This, lpdds, dwFlags);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_GetRenderTarget(
+    LPDIRECT3DDEVICE2 iface, LPDIRECTDRAWSURFACE *lplpdds
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%p): stub\n", This, lplpdds);
+
+    /* Returns the current rendering target (the surface on wich we render) */
+    *lplpdds = (LPDIRECTDRAWSURFACE)This->surface;
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_Begin(
+    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
+    DWORD dwFlags
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%d,%d,%08lx): stub\n", This, d3dp, d3dv, dwFlags);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_BeginIndexed(
+    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
+    LPVOID lpvert, DWORD numvert, DWORD dwFlags
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvert, numvert, dwFlags);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_Vertex(
+    LPDIRECT3DDEVICE2 iface,LPVOID lpvert
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%p): stub\n", This, lpvert);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_Index(LPDIRECT3DDEVICE2 iface, WORD index) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%d): stub\n", This, index);
+
+    return DD_OK;
+}
+
+
+
+HRESULT WINAPI IDirect3DDevice2Impl_End(LPDIRECT3DDEVICE2 iface,DWORD dwFlags) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%08lx): stub\n", This, dwFlags);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_GetRenderState(
+    LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE d3drs, LPDWORD lprstate
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%d,%p): stub\n", This, d3drs, lprstate);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_SetRenderState(
+    LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE dwRenderStateType,
+    DWORD dwRenderState
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+
+    FIXME("(%p)->(%d,%ld)\n", This, dwRenderStateType, dwRenderState);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_GetLightState(
+    LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE d3dls, LPDWORD lplstate
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%d,%p): stub\n", This, d3dls, lplstate);
+
+    return DD_OK;
+}
+
+
+
+HRESULT WINAPI IDirect3DDevice2Impl_SetLightState(
+    LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE dwLightStateType,
+    DWORD dwLightState
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%d,%08lx): stub\n", This, dwLightStateType, dwLightState);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_SetTransform(
+    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%d,%p),stub!\n",This,d3dts,lpmatrix);
+    return DD_OK;
+}
+
+
+
+HRESULT WINAPI IDirect3DDevice2Impl_GetTransform(
+    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
+
+    return DD_OK;
+}
+
+
+
+HRESULT WINAPI IDirect3DDevice2Impl_MultiplyTransform(
+    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_DrawPrimitive(
+    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
+    LPVOID lpvertex, DWORD vertcount, DWORD dwFlags
+) {
+  ICOM_THIS(IDirect3DDevice2Impl,iface);
+  
+  TRACE("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags);
+
+  return D3D_OK;
+}
+    
+HRESULT WINAPI IDirect3DDevice2Impl_DrawIndexedPrimitive(
+    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
+    LPVOID lpvertex, DWORD vertcount, LPWORD lpindexes, DWORD indexcount,
+    DWORD dwFlags
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    TRACE("(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
+    return D3D_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_SetClipStatus(
+    LPDIRECT3DDEVICE2 iface, LPD3DCLIPSTATUS lpcs
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%p): stub\n", This, lpcs);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDevice2Impl_GetClipStatus(
+    LPDIRECT3DDEVICE2 iface, LPD3DCLIPSTATUS lpcs
+) {
+    ICOM_THIS(IDirect3DDevice2Impl,iface);
+    FIXME("(%p)->(%p): stub\n", This, lpcs);
+
+    return DD_OK;
+}
+
+/*******************************************************************************
+ *				Direct3DDevice
+ */
+HRESULT WINAPI IDirect3DDeviceImpl_QueryInterface(
+    LPDIRECT3DDEVICE iface, REFIID riid, LPVOID* ppvObj
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
+    return S_OK;
+}
+
+ULONG WINAPI IDirect3DDeviceImpl_AddRef(LPDIRECT3DDEVICE iface)
+{
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
+
+    return ++(This->ref);
+}
+
+ULONG WINAPI IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface)
+{
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
+
+    if (!--(This->ref)) {
+	HeapFree(GetProcessHeap(),0,This);
+	return 0;
+    }
+    return This->ref;
+}
+
+HRESULT WINAPI IDirect3DDeviceImpl_Initialize(
+    LPDIRECT3DDEVICE iface, LPDIRECT3D lpd3d, LPGUID lpGUID,
+    LPD3DDEVICEDESC lpd3ddvdesc
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%p,%p,%p): stub\n", This, lpd3d,lpGUID, lpd3ddvdesc);
+
+    return DDERR_ALREADYINITIALIZED;
+}
+
+
+HRESULT WINAPI IDirect3DDeviceImpl_GetCaps(
+    LPDIRECT3DDEVICE iface, LPD3DDEVICEDESC lpD3DHWDevDesc,
+    LPD3DDEVICEDESC lpD3DSWDevDesc
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%p,%p): stub\n", This, lpD3DHWDevDesc, lpD3DSWDevDesc);
+
+    return DD_OK;
+}
+
+
+HRESULT WINAPI IDirect3DDeviceImpl_SwapTextureHandles(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DTEXTURE lpD3DTex1,
+    LPDIRECT3DTEXTURE lpD3DTex2
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%p,%p): stub\n", This, lpD3DTex1, lpD3DTex2);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDeviceImpl_CreateExecuteBuffer(
+    LPDIRECT3DDEVICE iface, LPD3DEXECUTEBUFFERDESC lpDesc,
+    LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer, IUnknown *pUnkOuter
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%p,%p,%p)\n", This, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
+    *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(This, lpDesc);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDeviceImpl_GetStats(
+    LPDIRECT3DDEVICE iface, LPD3DSTATS lpD3DStats
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%p): stub\n", This, lpD3DStats);
+
+    return DD_OK;
+}
+
+
+HRESULT WINAPI IDirect3DDeviceImpl_Execute(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
+    LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%p,%p,%08ld): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
+
+    /* Put this as the default context */
+
+    /* Execute... */
+    ((IDirect3DExecuteBufferImpl*)lpDirect3DExecuteBuffer)->execute(lpDirect3DExecuteBuffer, iface, lpDirect3DViewport);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDeviceImpl_AddViewport(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
+    FIXME("(%p)->(%p): stub\n", This, ilpvp);
+
+    /* Adds this viewport to the viewport list */
+    ilpvp->next = This->viewport_list;
+    This->viewport_list = ilpvp;
+
+    return DD_OK;
+}
+
+
+
+HRESULT WINAPI IDirect3DDeviceImpl_DeleteViewport(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
+    IDirect3DViewport2Impl *cur, *prev;
+    FIXME("(%p)->(%p): stub\n", This, lpvp);
+
+    /* Finds this viewport in the list */
+    prev = NULL;
+    cur = This->viewport_list;
+    while ((cur != NULL) && (cur != ilpvp)) {
+	prev = cur;
+	cur = cur->next;
+    }
+    if (cur == NULL)
+	return DDERR_INVALIDOBJECT;
+
+    /* And remove it */
+    if (prev == NULL)
+	This->viewport_list = cur->next;
+    else
+	prev->next = cur->next;
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDeviceImpl_NextViewport(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp,
+    LPDIRECT3DVIEWPORT* lplpvp, DWORD dwFlags
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
+    IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
+    FIXME("(%p)->(%p,%p,%08lx): stub\n", This, ilpvp, ilplpvp, dwFlags);
+
+    switch (dwFlags) {
+    case D3DNEXT_NEXT:
+	*ilplpvp = ilpvp->next;
+	break;
+    case D3DNEXT_HEAD:
+	*ilplpvp = This->viewport_list;
+	break;
+    case D3DNEXT_TAIL:
+	ilpvp = This->viewport_list;
+	while (ilpvp->next != NULL)
+	    ilpvp = ilpvp->next;
+	*ilplpvp = ilpvp;
+	break;
+    default:
+	return DDERR_INVALIDPARAMS;
+    }
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDeviceImpl_Pick(
+    LPDIRECT3DDEVICE iface, LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
+    LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags, LPD3DRECT lpRect
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%p,%p,%08lx,%p): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags, lpRect);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DDeviceImpl_GetPickRecords(
+    LPDIRECT3DDEVICE iface, LPDWORD lpCount, LPD3DPICKRECORD lpD3DPickRec
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%p,%p): stub\n", This, lpCount, lpD3DPickRec);
+
+    return DD_OK;
+}
+
+
+HRESULT WINAPI IDirect3DDeviceImpl_EnumTextureFormats(
+    LPDIRECT3DDEVICE iface,LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
+    LPVOID lpArg
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%p,%p): stub\n", This, lpd3dEnumTextureProc, lpArg);
+    return D3D_OK;
+}
+
+
+HRESULT WINAPI IDirect3DDeviceImpl_CreateMatrix(
+    LPDIRECT3DDEVICE iface, LPD3DMATRIXHANDLE lpD3DMatHandle
+)
+{
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%p)\n", This, lpD3DMatHandle);
+
+    *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX));
+
+    return DD_OK;
+}
+
+
+HRESULT WINAPI IDirect3DDeviceImpl_SetMatrix(
+    LPDIRECT3DDEVICE iface, D3DMATRIXHANDLE d3dMatHandle,
+    const LPD3DMATRIX lpD3DMatrix)
+{
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%08lx,%p)\n", This, d3dMatHandle, lpD3DMatrix);
+
+    dump_mat(lpD3DMatrix);
+    *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
+    return DD_OK;
+}
+
+
+HRESULT WINAPI IDirect3DDeviceImpl_GetMatrix(
+    LPDIRECT3DDEVICE iface,D3DMATRIXHANDLE D3DMatHandle,LPD3DMATRIX lpD3DMatrix
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%08lx,%p)\n", This, D3DMatHandle, lpD3DMatrix);
+
+    *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
+
+    return DD_OK;
+}
+
+
+HRESULT WINAPI IDirect3DDeviceImpl_DeleteMatrix(
+    LPDIRECT3DDEVICE iface, D3DMATRIXHANDLE d3dMatHandle
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%08lx)\n", This, d3dMatHandle);
+    HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle);
+    return DD_OK;
+}
+
+
+HRESULT WINAPI IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
+{
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    FIXME("(%p)->(): stub\n", This);
+    return DD_OK;
+}
+
+/* This is for the moment copy-pasted from IDirect3DDevice2...
+   Will make a common function ... */
+HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
+{
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    FIXME("(%p)->(): stub\n", This);
+    return DD_OK;  
+}
+
+HRESULT WINAPI IDirect3DDeviceImpl_GetDirect3D(
+    LPDIRECT3DDEVICE iface, LPDIRECT3D *lpDirect3D
+) {
+    ICOM_THIS(IDirect3DDeviceImpl,iface);
+    TRACE("(%p)->(%p): stub\n", This, lpDirect3D);
+
+    return DD_OK;
+}
+
+/*******************************************************************************
+ *				Direct3DDevice VTable
+ */
+static WINE_UNUSED ICOM_VTABLE(IDirect3DDevice) d3d_d3ddevice_vtbl = 
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  IDirect3DDeviceImpl_QueryInterface,
+  IDirect3DDeviceImpl_AddRef,
+  IDirect3DDeviceImpl_Release,
+  IDirect3DDeviceImpl_Initialize,
+  IDirect3DDeviceImpl_GetCaps,
+  IDirect3DDeviceImpl_SwapTextureHandles,
+  IDirect3DDeviceImpl_CreateExecuteBuffer,
+  IDirect3DDeviceImpl_GetStats,
+  IDirect3DDeviceImpl_Execute,
+  IDirect3DDeviceImpl_AddViewport,
+  IDirect3DDeviceImpl_DeleteViewport,
+  IDirect3DDeviceImpl_NextViewport,
+  IDirect3DDeviceImpl_Pick,
+  IDirect3DDeviceImpl_GetPickRecords,
+  IDirect3DDeviceImpl_EnumTextureFormats,
+  IDirect3DDeviceImpl_CreateMatrix,
+  IDirect3DDeviceImpl_SetMatrix,
+  IDirect3DDeviceImpl_GetMatrix,
+  IDirect3DDeviceImpl_DeleteMatrix,
+  IDirect3DDeviceImpl_BeginScene,
+  IDirect3DDeviceImpl_EndScene,
+  IDirect3DDeviceImpl_GetDirect3D,
+};
diff --git a/dlls/ddraw/d3ddevice/mesa.c b/dlls/ddraw/d3ddevice/mesa.c
new file mode 100644
index 0000000..0608a56
--- /dev/null
+++ b/dlls/ddraw/d3ddevice/mesa.c
@@ -0,0 +1,1036 @@
+/* Direct3D Device
+   (c) 1998 Lionel ULMER
+   
+   This files contains the MESA implementation of all the D3D devices that
+   Wine supports. */
+
+#include <string.h>
+#include "config.h"
+#include "windef.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "heap.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debugtools.h"
+
+#include "mesa_private.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw)
+
+ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable;
+ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3;
+
+/* Define this variable if you have an unpatched Mesa 3.0 (patches are available
+   on Mesa's home page) or version 3.1b.
+
+   Version 3.1b2 should correct this bug */
+#undef HAVE_BUGGY_MESAGL
+
+#define D3DDPRIVATE(x) mesa_d3dd_private *odev=((mesa_d3dd_private*)x->private)
+#define DDPRIVATE(x) x11_dd_private *ddpriv=((x11_dd_private*)(x)->private)
+
+/*******************************************************************************
+ *				OpenGL static functions
+ */
+static void set_context(IDirect3DDevice2Impl* This) {
+    D3DDPRIVATE(This);
+    DDPRIVATE(This->surface->s.ddraw);
+
+#ifdef USE_OSMESA
+    OSMesaMakeCurrent(d3ddpriv->ctx, odev->buffer, GL_UNSIGNED_BYTE,
+		    This->surface->s.surface_desc.dwWidth,
+		    This->surface->s.surface_desc.dwHeight);
+#else
+    if (glXMakeCurrent(display,ddpriv->drawable, odev->ctx) == False) {
+	ERR("Error in setting current context (context %p drawable %ld)!\n",
+	    odev->ctx, ddpriv->drawable);
+}
+#endif
+}
+
+static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
+{
+  pc->dwSize = sizeof(*pc);
+  pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
+    D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
+  pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
+    D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
+  pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
+  pc->dwSrcBlendCaps  = 0xFFFFFFFF; /* FIXME: need REAL values */
+  pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
+  pc->dwAlphaCmpCaps  = 0xFFFFFFFF; /* FIXME: need REAL values */
+  pc->dwShadeCaps = 0xFFFFFFFF;     /* FIXME: need REAL values */
+  pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
+    D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
+  pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
+    D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
+  pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
+  pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
+  pc->dwStippleWidth = 32;
+  pc->dwStippleHeight = 32;
+}
+
+static void fill_opengl_caps(D3DDEVICEDESC *d1, D3DDEVICEDESC *d2)
+{
+  /* GLint maxlight; */
+  
+  d1->dwSize  = sizeof(*d1);
+  d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
+    | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
+  d1->dcmColorModel = D3DCOLOR_RGB;
+  d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
+    D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
+      D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
+  d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
+  d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
+  d1->bClipping = TRUE;
+  d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
+  d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
+  d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
+  d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
+  fill_opengl_primcaps(&(d1->dpcLineCaps));
+  fill_opengl_primcaps(&(d1->dpcTriCaps));  
+  d1->dwDeviceRenderBitDepth  = DDBD_16;
+  d1->dwDeviceZBufferBitDepth = DDBD_16;
+  d1->dwMaxBufferSize = 0;
+  d1->dwMaxVertexCount = 65536;
+  d1->dwMinTextureWidth  = 1;
+  d1->dwMinTextureHeight = 1;
+  d1->dwMaxTextureWidth  = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
+  d1->dwMaxTextureHeight = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
+  d1->dwMinStippleWidth  = 1;
+  d1->dwMinStippleHeight = 1;
+  d1->dwMaxStippleWidth  = 32;
+  d1->dwMaxStippleHeight = 32;
+
+  d2->dwSize  = sizeof(*d2);
+  d2->dwFlags = 0;
+}
+
+int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
+  D3DDEVICEDESC	d1,d2;
+  TRACE(" Enumerating OpenGL D3D device.\n");
+  fill_opengl_caps(&d1, &d2);
+  return cb((void*)&IID_D3DDEVICE2_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
+}
+
+int
+is_OpenGL(
+    REFCLSID rguid, IDirectDrawSurfaceImpl* surface,
+    IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d
+) {
+  mesa_d3dd_private *odev = NULL;
+
+  if (/* Default device */
+      (rguid == NULL) ||
+      /* HAL Device */
+      (!memcmp(&IID_IDirect3DHALDevice,rguid,sizeof(IID_IDirect3DHALDevice))) ||
+      /* OpenGL Device */
+      (!memcmp(&IID_D3DDEVICE2_OpenGL,rguid,sizeof(IID_D3DDEVICE2_OpenGL)))) {
+    
+    const float id_mat[16] = {
+      1.0, 0.0, 0.0, 0.0,
+      0.0, 1.0, 0.0, 0.0,
+      0.0, 0.0, 1.0, 0.0,
+      0.0, 0.0, 0.0, 1.0
+    };
+#ifndef USE_OSMESA
+    int attributeList[]={ GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None };
+    XVisualInfo *xvis;
+#endif
+    
+    *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DDevice2Impl));
+    (*device)->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dd_private));
+    odev = (mesa_d3dd_private*)(*device)->private;
+    (*device)->ref = 1;
+    ICOM_VTBL(*device) = &OpenGL_vtable;
+    (*device)->d3d = d3d;
+    (*device)->surface = surface;
+    (*device)->viewport_list = NULL;
+    (*device)->current_viewport = NULL;
+    (*device)->set_context = set_context;
+    
+    TRACE("Creating OpenGL device for surface %p\n", surface);
+    /* Create the OpenGL context */
+#ifdef USE_OSMESA
+    odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
+    odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
+			     surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
+#else
+    /* First get the correct visual */
+    /* if (surface->s.backbuffer == NULL)
+       attributeList[3] = None; */
+    ENTER_GL();
+    xvis = glXChooseVisual(display,
+			   DefaultScreen(display),
+			   attributeList);
+    if (xvis == NULL)
+      ERR("No visual found !\n");
+    else
+      TRACE("Visual found\n");
+    /* Create the context */
+    odev->ctx = glXCreateContext(display,
+				 xvis,
+				 NULL,
+				 GL_TRUE);
+    if (odev->ctx == NULL)
+      ERR("Error in context creation !\n");
+    else
+      TRACE("Context created (%p)\n", odev->ctx);
+    
+#if 0 /* not functional currently */
+    /* Now override the surface's Flip method (if in double buffering) */
+    surface->s.d3d_device = (void *) odev;
+
+    {
+	int i;
+	struct _surface_chain *chain = surface->s.chain;
+	for (i=0;i<chain->nrofsurfaces;i++)
+	  if (chain->surfaces[i]->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_FLIP)
+	      chain->surfaces[i]->s.d3d_device = (void *) odev;
+    }
+#endif
+
+#endif
+    odev->rs.src = GL_ONE;
+    odev->rs.dst = GL_ZERO;
+    odev->rs.mag = GL_NEAREST;
+    odev->rs.min = GL_NEAREST;
+    odev->vt     = 0;
+    
+    memcpy(odev->world_mat, id_mat, 16 * sizeof(float));
+    memcpy(odev->view_mat , id_mat, 16 * sizeof(float));
+    memcpy(odev->proj_mat , id_mat, 16 * sizeof(float));
+
+    /* Initialisation */
+    TRACE("Setting current context\n");
+    (*device)->set_context(*device);
+    TRACE("Current context set\n");
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glColor3f(1.0, 1.0, 1.0);
+    LEAVE_GL();
+    TRACE("OpenGL device created \n");
+    return 1;
+  }
+  FIXME("bad IID %s\n",debugstr_guid(rguid));
+  /* This is not the OpenGL UID */
+  return 0;
+}
+
+/*******************************************************************************
+ *				MESA IDirect3DDevice2
+ */
+static ULONG WINAPI MESA_IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
+{
+  ICOM_THIS(IDirect3DDevice2Impl,iface);
+  D3DDPRIVATE(This);
+  FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
+  
+  if (!--(This->ref)) {
+#ifdef USE_OSMESA
+    OSMesaDestroyContext(odev->ctx);
+#else
+    ENTER_GL();
+    glXDestroyContext(display, odev->ctx);
+    LEAVE_GL();
+#endif
+    This->private = NULL;
+    HeapFree(GetProcessHeap(),0,This);
+    return 0;
+  }
+  return This->ref;
+}
+
+/*** IDirect3DDevice2 methods ***/
+static HRESULT WINAPI MESA_IDirect3DDevice2Impl_GetCaps(
+    LPDIRECT3DDEVICE2 iface, LPD3DDEVICEDESC lpdescsoft,
+    LPD3DDEVICEDESC lpdeschard
+) {
+  ICOM_THIS(IDirect3DDevice2Impl,iface);
+  FIXME("(%p)->(%p,%p): stub\n", This, lpdescsoft, lpdeschard);
+  fill_opengl_caps(lpdescsoft, lpdeschard);
+  return DD_OK;
+}
+
+static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb,
+					  LPVOID context) {
+  DDSURFACEDESC sdesc;
+  LPDDPIXELFORMAT pformat;
+
+  /* Do the texture enumeration */
+  sdesc.dwSize = sizeof(DDSURFACEDESC);
+  sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
+  sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+  pformat = &(sdesc.ddpfPixelFormat);
+  pformat->dwSize = sizeof(DDPIXELFORMAT);
+  pformat->dwFourCC = 0;
+  
+  TRACE("Enumerating GL_RGBA unpacked (32)\n");
+  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+  pformat->u.dwRGBBitCount = 32;
+  pformat->u1.dwRBitMask =         0xFF000000;
+  pformat->u2.dwGBitMask =         0x00FF0000;
+  pformat->u3.dwBBitMask =        0x0000FF00;
+  pformat->u4.dwRGBAlphaBitMask = 0x000000FF;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+
+  TRACE("Enumerating GL_RGB unpacked (24)\n");
+  pformat->dwFlags = DDPF_RGB;
+  pformat->u.dwRGBBitCount = 24;
+  pformat->u1.dwRBitMask =  0x00FF0000;
+  pformat->u2.dwGBitMask =  0x0000FF00;
+  pformat->u3.dwBBitMask = 0x000000FF;
+  pformat->u4.dwRGBAlphaBitMask = 0x00000000;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+
+#ifndef HAVE_BUGGY_MESAGL
+  /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
+     so that future version will work great. */
+  TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
+  pformat->dwFlags = DDPF_RGB;
+  pformat->u.dwRGBBitCount = 16;
+  pformat->u1.dwRBitMask =  0x0000F800;
+  pformat->u2.dwGBitMask =  0x000007E0;
+  pformat->u3.dwBBitMask = 0x0000001F;
+  pformat->u4.dwRGBAlphaBitMask = 0x00000000;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+
+  TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
+  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+  pformat->u.dwRGBBitCount = 16;
+  pformat->u1.dwRBitMask =         0x0000F800;
+  pformat->u2.dwGBitMask =         0x000007C0;
+  pformat->u3.dwBBitMask =        0x0000003E;
+  pformat->u4.dwRGBAlphaBitMask = 0x00000001;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+
+  TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
+  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+  pformat->u.dwRGBBitCount = 16;
+  pformat->u1.dwRBitMask =         0x0000F000;
+  pformat->u2.dwGBitMask =         0x00000F00;
+  pformat->u3.dwBBitMask =        0x000000F0;
+  pformat->u4.dwRGBAlphaBitMask = 0x0000000F;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+
+  TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
+  pformat->dwFlags = DDPF_RGB;
+  pformat->u.dwRGBBitCount = 8;
+  pformat->u1.dwRBitMask =         0x0000F800;
+  pformat->u2.dwGBitMask =         0x000007C0;
+  pformat->u3.dwBBitMask =        0x0000003E;
+  pformat->u4.dwRGBAlphaBitMask = 0x00000001;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+#endif
+
+#if defined(HAVE_GL_COLOR_TABLE) && defined(HAVE_GL_PALETTED_TEXTURE)
+  TRACE("Enumerating Paletted (8)\n");
+  pformat->dwFlags = DDPF_PALETTEINDEXED8;
+  pformat->u.dwRGBBitCount = 8;
+  pformat->u1.dwRBitMask =  0x00000000;
+  pformat->u2.dwGBitMask =  0x00000000;
+  pformat->u3.dwBBitMask = 0x00000000;
+  pformat->u4.dwRGBAlphaBitMask = 0x00000000;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+#endif
+  
+  TRACE("End of enumeration\n");
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3DDevice2Impl_EnumTextureFormats(
+    LPDIRECT3DDEVICE2 iface, LPD3DENUMTEXTUREFORMATSCALLBACK cb, LPVOID context
+) {
+  ICOM_THIS(IDirect3DDevice2Impl,iface);
+  FIXME("(%p)->(%p,%p): stub\n", This, cb, context);
+  
+  return enum_texture_format_OpenGL(cb, context);
+}
+
+static HRESULT WINAPI MESA_IDirect3DDevice2Impl_BeginScene(
+    LPDIRECT3DDEVICE2 iface
+) {
+  ICOM_THIS(IDirect3DDevice2Impl,iface);
+  
+  FIXME("(%p)->(): stub\n", This);
+  
+  /* Here, we should get the DDraw surface and 'copy it' to the
+     OpenGL surface.... */
+  
+  return DD_OK;
+}
+
+HRESULT WINAPI MESA_IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface) {
+  ICOM_THIS(IDirect3DDevice2Impl,iface);
+#ifdef USE_OSMESA
+  D3DPRIVATE(This);
+
+  LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
+  DDSURFACEDESC sdesc;
+  int x,y;
+  unsigned char *src;
+  unsigned short *dest;
+#endif
+  
+  FIXME("(%p)->(): stub\n", This);
+
+#ifdef USE_OSMESA
+  /* Here we copy back the OpenGL scene to the the DDraw surface */
+  /* First, lock the surface */
+  IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
+
+  /* The copy the OpenGL buffer to this surface */
+  
+  /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
+     I am currently working on a set of patches for Mesa to have OSMesa support
+     16 bpp surfaces => we will able to render directly onto the surface, no
+     need to do a bpp conversion */
+  dest = (unsigned short *) sdesc.y.lpSurface;
+  src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
+  for (y = 0; y < sdesc.dwHeight; y++) {
+    unsigned char *lsrc = src;
+    
+    for (x = 0; x < sdesc.dwWidth ; x++) {
+      unsigned char r =  *lsrc++;
+      unsigned char g =  *lsrc++;
+      unsigned char b =  *lsrc++;
+      lsrc++; /* Alpha */
+      *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
+      
+      dest++;
+    }
+
+    src -= 4 * sdesc.dwWidth;
+  }
+
+  /* Unlock the surface */
+  IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
+#else
+  /* No need to do anything here... */
+#endif
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3DDevice2Impl_SetRenderState(
+    LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE dwRenderStateType,
+    DWORD dwRenderState
+) {
+  ICOM_THIS(IDirect3DDevice2Impl,iface);
+  D3DDPRIVATE(This);
+
+  TRACE("(%p)->(%d,%ld)\n", This, dwRenderStateType, dwRenderState);
+  
+  /* Call the render state functions */
+  set_render_state(dwRenderStateType, dwRenderState, &(odev->rs));
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3DDevice2Impl_SetLightState(
+    LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE dwLightStateType,
+    DWORD dwLightState
+) {
+  ICOM_THIS(IDirect3DDevice2Impl,iface);
+  FIXME("(%p)->(%d,%08lx): stub\n", This, dwLightStateType, dwLightState);
+  
+  switch (dwLightStateType) {
+  case D3DLIGHTSTATE_MATERIAL: {  /* 1 */
+    IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) dwLightState;
+    
+    if (mat != NULL) {
+      ENTER_GL();
+      mat->activate(mat);
+      LEAVE_GL();
+    } else {
+      TRACE("Zoups !!!\n");
+    }
+  } break;
+    
+  case D3DLIGHTSTATE_AMBIENT: {   /* 2 */
+    float light[4];
+    
+    light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
+    light[1] = ((dwLightState >>  8) & 0xFF) / 255.0;
+    light[2] = ((dwLightState >>  0) & 0xFF) / 255.0;
+    light[3] = 1.0;
+    ENTER_GL();
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
+    LEAVE_GL();
+  } break;
+
+#define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
+  UNSUP(COLORMODEL);
+  UNSUP(FOGMODE);
+  UNSUP(FOGSTART);
+  UNSUP(FOGEND);
+  UNSUP(FOGDENSITY);
+#undef UNSUP
+  default:
+    TRACE("Unexpected Light State Type\n");
+    return DDERR_INVALIDPARAMS;
+  }
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3DDevice2Impl_SetTransform(
+    LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts,
+    LPD3DMATRIX lpmatrix
+) {
+  ICOM_THIS(IDirect3DDevice2Impl,iface);
+  D3DDPRIVATE(This);
+  
+  FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
+  
+  ENTER_GL();
+  
+  /* Using a trial and failure approach, I found that the order of 
+     Direct3D transformations that works best is :
+
+     ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
+
+     As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
+     OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
+
+     If anyone has a good explanation of the three different matrices in
+     the SDK online documentation, feel free to point it to me. For example,
+     which matrices transform lights ? In OpenGL only the PROJECTION matrix
+     transform the lights, not the MODELVIEW. Using the matrix names, I 
+     supposed that PROJECTION and VIEW (all 'camera' related names) do
+     transform lights, but WORLD do not. It may be wrong though... */
+
+  /* After reading through both OpenGL and Direct3D documentations, I
+     thought that D3D matrices were written in 'line major mode' transposed
+     from OpenGL's 'column major mode'. But I found out that a simple memcpy
+     works fine to transfer one matrix format to the other (it did not work
+     when transposing)....
+
+     So :
+      1) are the documentations wrong
+      2) does the matrix work even if they are not read correctly
+      3) is Mesa's implementation of OpenGL not compliant regarding Matrix
+         loading using glLoadMatrix ?
+
+     Anyway, I always use 'conv_mat' to transfer the matrices from one format
+     to the other so that if I ever find out that I need to transpose them, I
+     will able to do it quickly, only by changing the macro conv_mat. */
+
+  switch (d3dts) {
+  case D3DTRANSFORMSTATE_WORLD: {
+    conv_mat(lpmatrix, odev->world_mat);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadMatrixf((float *) &(odev->world_mat));
+  } break;
+    
+  case D3DTRANSFORMSTATE_VIEW: {
+    conv_mat(lpmatrix, odev->view_mat);
+    glMatrixMode(GL_PROJECTION);
+    glLoadMatrixf((float *) &(odev->proj_mat));
+    glMultMatrixf((float *) &(odev->view_mat));
+  } break;
+    
+  case D3DTRANSFORMSTATE_PROJECTION: {
+    conv_mat(lpmatrix, odev->proj_mat);
+    glMatrixMode(GL_PROJECTION);
+    glLoadMatrixf((float *) &(odev->proj_mat));
+    glMultMatrixf((float *) &(odev->view_mat));
+  } break;
+    
+  default:
+    break;
+  }
+  LEAVE_GL();
+  return DD_OK;
+}
+
+#define DRAW_PRIMITIVE(MAXVERT,INDEX)					\
+  /* Puts GL in the correct lighting mode */				\
+  if (odev->vt != d3dv) {						\
+    if (odev->vt == D3DVT_TLVERTEX) {					\
+      /* Need to put the correct transformation again */		\
+      glMatrixMode(GL_MODELVIEW);					\
+      glLoadMatrixf((float *) &(odev->world_mat));			\
+      glMatrixMode(GL_PROJECTION);					\
+      glLoadMatrixf((float *) &(odev->proj_mat));			\
+      glMultMatrixf((float *) &(odev->view_mat));			\
+    }									\
+									\
+    switch (d3dv) {							\
+    case D3DVT_VERTEX:							\
+      TRACE("Standard Vertex\n");					\
+      glEnable(GL_LIGHTING);						\
+      break;								\
+									\
+    case D3DVT_LVERTEX:							\
+      TRACE("Lighted Vertex\n");					\
+      glDisable(GL_LIGHTING);						\
+      break;								\
+									\
+    case D3DVT_TLVERTEX: {						\
+      GLdouble height, width, minZ, maxZ;				\
+									\
+      TRACE("Transformed - Lighted Vertex\n");				\
+      /* First, disable lighting */					\
+      glDisable(GL_LIGHTING);						\
+									\
+      /* Then do not put any transformation matrixes */			\
+      glMatrixMode(GL_MODELVIEW);					\
+      glLoadIdentity();							\
+      glMatrixMode(GL_PROJECTION);					\
+      glLoadIdentity();							\
+									\
+      if (This->current_viewport == NULL) {				\
+	ERR("No current viewport !\n");					\
+	/* Using standard values */					\
+	height = 640.0;							\
+	width = 480.0;							\
+	minZ = -10.0;							\
+	maxZ = 10.0;							\
+      } else {								\
+	if (This->current_viewport->use_vp2) {				\
+	  height = (GLdouble) This->current_viewport->viewport.vp2.dwHeight;\
+	  width  = (GLdouble) This->current_viewport->viewport.vp2.dwWidth;\
+	  minZ   = (GLdouble) This->current_viewport->viewport.vp2.dvMinZ;\
+	  maxZ   = (GLdouble) This->current_viewport->viewport.vp2.dvMaxZ;\
+	} else {							\
+	  height = (GLdouble) This->current_viewport->viewport.vp1.dwHeight;\
+	  width  = (GLdouble) This->current_viewport->viewport.vp1.dwWidth;\
+	  minZ   = (GLdouble) This->current_viewport->viewport.vp1.dvMinZ;\
+	  maxZ   = (GLdouble) This->current_viewport->viewport.vp1.dvMaxZ;\
+	}								\
+      }									\
+									\
+      glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);			\
+    } break;								\
+									\
+    default:								\
+      ERR("Unhandled vertex type\n");					\
+      break;								\
+    }									\
+									\
+    odev->vt = d3dv;							\
+  }									\
+									\
+  switch (d3dp) {							\
+  case D3DPT_POINTLIST:							\
+    TRACE("Start POINTS\n");						\
+    glBegin(GL_POINTS);							\
+    break;								\
+									\
+  case D3DPT_LINELIST:							\
+    TRACE("Start LINES\n");						\
+    glBegin(GL_LINES);							\
+    break;								\
+									\
+  case D3DPT_LINESTRIP:							\
+    TRACE("Start LINE_STRIP\n");					\
+    glBegin(GL_LINE_STRIP);						\
+    break;								\
+									\
+  case D3DPT_TRIANGLELIST:						\
+    TRACE("Start TRIANGLES\n");						\
+    glBegin(GL_TRIANGLES);						\
+    break;								\
+									\
+  case D3DPT_TRIANGLESTRIP:						\
+    TRACE("Start TRIANGLE_STRIP\n");					\
+    glBegin(GL_TRIANGLE_STRIP);						\
+    break;								\
+									\
+  case D3DPT_TRIANGLEFAN:						\
+    TRACE("Start TRIANGLE_FAN\n");					\
+    glBegin(GL_TRIANGLE_FAN);						\
+    break;								\
+									\
+  default:								\
+    TRACE("Unhandled primitive\n");					\
+    break;								\
+  }									\
+									\
+  /* Draw the primitives */						\
+  for (vx_index = 0; vx_index < MAXVERT; vx_index++) {			\
+    switch (d3dv) {							\
+    case D3DVT_VERTEX: {						\
+      D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + INDEX;			\
+									\
+      glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz);			\
+      glVertex3f(vx->x.x, vx->y.y, vx->z.z);				\
+      TRACE("   V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z);		\
+    } break;								\
+									\
+    case D3DVT_LVERTEX: {						\
+      D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + INDEX;		\
+      DWORD col = vx->c.color;						\
+									\
+      glColor3f(((col >> 16) & 0xFF) / 255.0,				\
+		((col >>  8) & 0xFF) / 255.0,				\
+		((col >>  0) & 0xFF) / 255.0);				\
+      glVertex3f(vx->x.x, vx->y.y, vx->z.z);				\
+      TRACE("  LV: %f %f %f (%02lx %02lx %02lx)\n",			\
+	    vx->x.x, vx->y.y, vx->z.z,					\
+	    ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF));\
+    } break;								\
+									\
+    case D3DVT_TLVERTEX: {						\
+      D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + INDEX;		\
+      DWORD col = vx->c.color;						\
+									\
+      glColor3f(((col >> 16) & 0xFF) / 255.0,				\
+		((col >>  8) & 0xFF) / 255.0,				\
+		((col >>  0) & 0xFF) / 255.0);				\
+      glTexCoord2f(vx->u.tu, vx->v.tv);					\
+      if (vx->r.rhw < 0.01)						\
+	glVertex3f(vx->x.sx,						\
+		   vx->y.sy,						\
+		   vx->z.sz);						\
+      else								\
+	glVertex4f(vx->x.sx / vx->r.rhw,				\
+		   vx->y.sy / vx->r.rhw,				\
+		   vx->z.sz / vx->r.rhw,				\
+		   1.0 / vx->r.rhw);					\
+      TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n",	\
+	    vx->x.sx, vx->y.sy, vx->z.sz,				\
+	    ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF),\
+	    vx->u.tu, vx->v.tv, vx->r.rhw);				\
+    } break;								\
+									\
+    default:								\
+      FIXME("Unhandled vertex type\n");					\
+      break;								\
+    }									\
+  }									\
+									\
+  glEnd();								\
+  TRACE("End\n");
+
+
+static HRESULT WINAPI MESA_IDirect3DDevice2Impl_DrawPrimitive(
+    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
+    LPVOID lpvertex, DWORD vertcount, DWORD dwFlags
+) {
+  ICOM_THIS(IDirect3DDevice2Impl,iface);
+  D3DDPRIVATE(This);
+  int vx_index;
+  
+  TRACE("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags);
+
+  ENTER_GL();
+  DRAW_PRIMITIVE(vertcount, vx_index);
+  LEAVE_GL();
+    
+  return D3D_OK;
+}
+      
+static HRESULT WINAPI MESA_IDirect3DDevice2Impl_DrawIndexedPrimitive(
+    LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
+    LPVOID lpvertex, DWORD vertcount, LPWORD lpindexes, DWORD indexcount,
+    DWORD dwFlags
+) {
+  ICOM_THIS(IDirect3DDevice2Impl,iface);
+  D3DDPRIVATE(This);
+  int vx_index;
+  
+  TRACE("(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
+  
+  ENTER_GL();
+  DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]);
+  LEAVE_GL();
+  
+  return D3D_OK;
+}
+
+/*******************************************************************************
+ *				OpenGL-specific IDirect3DDevice2
+ */
+
+/*******************************************************************************
+ *				OpenGL-specific VTable
+ */
+
+ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable = 
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  IDirect3DDevice2Impl_QueryInterface,
+  IDirect3DDevice2Impl_AddRef,
+  MESA_IDirect3DDevice2Impl_Release,
+  /*** IDirect3DDevice2 methods ***/
+  MESA_IDirect3DDevice2Impl_GetCaps,
+  IDirect3DDevice2Impl_SwapTextureHandles,
+  IDirect3DDevice2Impl_GetStats,
+  IDirect3DDevice2Impl_AddViewport,
+  IDirect3DDevice2Impl_DeleteViewport,
+  IDirect3DDevice2Impl_NextViewport,
+  MESA_IDirect3DDevice2Impl_EnumTextureFormats,
+  MESA_IDirect3DDevice2Impl_BeginScene,
+  MESA_IDirect3DDevice2Impl_EndScene,
+  IDirect3DDevice2Impl_GetDirect3D,
+  
+  /*** DrawPrimitive API ***/
+  IDirect3DDevice2Impl_SetCurrentViewport,
+  IDirect3DDevice2Impl_GetCurrentViewport,
+  
+  IDirect3DDevice2Impl_SetRenderTarget,
+  IDirect3DDevice2Impl_GetRenderTarget,
+  
+  IDirect3DDevice2Impl_Begin,
+  IDirect3DDevice2Impl_BeginIndexed,
+  IDirect3DDevice2Impl_Vertex,
+  IDirect3DDevice2Impl_Index,
+  IDirect3DDevice2Impl_End,
+  
+  IDirect3DDevice2Impl_GetRenderState,
+  MESA_IDirect3DDevice2Impl_SetRenderState,
+  IDirect3DDevice2Impl_GetLightState,
+  MESA_IDirect3DDevice2Impl_SetLightState,
+  MESA_IDirect3DDevice2Impl_SetTransform,
+  IDirect3DDevice2Impl_GetTransform,
+  IDirect3DDevice2Impl_MultiplyTransform,
+  
+  MESA_IDirect3DDevice2Impl_DrawPrimitive,
+  MESA_IDirect3DDevice2Impl_DrawIndexedPrimitive,
+  
+  IDirect3DDevice2Impl_SetClipStatus,
+  IDirect3DDevice2Impl_GetClipStatus,
+};
+
+/*******************************************************************************
+ *				Direct3DDevice
+ */
+int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
+  D3DDEVICEDESC	d1,d2;
+  
+  TRACE(" Enumerating OpenGL D3D device.\n");
+  
+  fill_opengl_caps(&d1, &d2);
+  
+  return cb((void*)&IID_D3DDEVICE_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
+}
+
+float id_mat[16] = {
+  1.0, 0.0, 0.0, 0.0,
+  0.0, 1.0, 0.0, 0.0,
+  0.0, 0.0, 1.0, 0.0,
+  0.0, 0.0, 0.0, 1.0
+};
+
+int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device)
+{
+  if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
+    mesa_d3dd_private *odev;
+#ifndef USE_OSMESA
+    int attributeList[]={ GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None };
+    XVisualInfo *xvis;
+#endif
+       
+    *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DDeviceImpl));
+    (*device)->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dd_private));
+    odev = (mesa_d3dd_private*)(*device)->private;
+    (*device)->ref = 1;
+    ICOM_VTBL(*device) = &OpenGL_vtable_dx3;
+    (*device)->d3d = NULL;
+    (*device)->surface = surface;
+    
+    (*device)->viewport_list = NULL;
+    (*device)->current_viewport = NULL;
+    
+    (*device)->set_context = (void*)set_context;
+    
+    TRACE("OpenGL device created \n");
+    
+    /* Create the OpenGL context */
+#ifdef USE_OSMESA
+    odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
+    odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
+			     surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
+#else
+    /* First get the correct visual */
+    /* if (surface->s.backbuffer == NULL)
+       attributeList[3] = None; */
+    ENTER_GL();
+    xvis = glXChooseVisual(display,
+			   DefaultScreen(display),
+			   attributeList);
+    if (xvis == NULL)
+      ERR("No visual found !\n");
+    else
+      TRACE("Visual found\n");
+    /* Create the context */
+    odev->ctx = glXCreateContext(display,
+				 xvis,
+				 NULL,
+				 GL_TRUE);
+    TRACE("Context created\n");
+    
+#if 0 /* non working currently */
+    /* Now override the surface's Flip method (if in double buffering) */
+    surface->s.d3d_device = (void *) odev;
+    {
+	int i;
+	struct _surface_chain *chain = surface->s.chain;
+	for (i=0;i<chain->nrofsurfaces;i++)
+	  if (chain->surfaces[i]->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_FLIP)
+	      chain->surfaces[i]->s.d3d_device = (void *) odev;
+    }
+#endif
+#endif
+    odev->rs.src = GL_ONE;
+    odev->rs.dst = GL_ZERO;
+    odev->rs.mag = GL_NEAREST;
+    odev->rs.min = GL_NEAREST;
+
+    odev->world_mat = (LPD3DMATRIX) &id_mat;
+    odev->view_mat  = (LPD3DMATRIX) &id_mat;
+    odev->proj_mat  = (LPD3DMATRIX) &id_mat;
+
+    /* Initialisation */
+    (*device)->set_context(*device);
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glColor3f(1.0, 1.0, 1.0);
+    
+    return 1;
+  }
+  
+  /* This is not the OpenGL UID */
+  return DD_OK;
+}
+
+static ULONG WINAPI MESA_IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface)
+{
+  ICOM_THIS(IDirect3DDeviceImpl,iface);
+  FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
+  
+  if (!--(This->ref)) {
+    D3DDPRIVATE(This);
+#ifdef USE_OSMESA
+    OSMesaDestroyContext(odev->ctx);
+#else
+    ENTER_GL();
+    glXDestroyContext(display, odev->ctx);
+    LEAVE_GL();
+#endif    
+    This->private = NULL;
+    HeapFree(GetProcessHeap(),0,This);
+    return 0;
+  }
+  return This->ref;
+}
+
+static HRESULT WINAPI MESA_IDirect3DDeviceImpl_EnumTextureFormats(
+    LPDIRECT3DDEVICE iface,LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
+    LPVOID lpArg)
+{
+  ICOM_THIS(IDirect3DDeviceImpl,iface);
+  TRACE("(%p)->(%p,%p): stub\n", This, lpd3dEnumTextureProc, lpArg);
+  
+  return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg);
+}
+
+
+static HRESULT WINAPI MESA_IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
+{
+  ICOM_THIS(IDirect3DDeviceImpl,iface);
+  /* OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This; */
+  
+  FIXME("(%p)->(): stub\n", This);
+  
+  /* We get the pointer to the surface (should be done on flip) */
+  /* odev->zb->pbuf = This->surface->s.surface_desc.y.lpSurface; */
+  
+  return DD_OK;
+}
+
+
+/* This is for the moment copy-pasted from IDirect3DDevice2...
+   Will make a common function ... */
+static HRESULT WINAPI MESA_IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
+{
+  ICOM_THIS(IDirect3DDeviceImpl,iface);
+#ifdef USE_OSMESA
+  D3DDPRIVATE(This);
+  LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
+  DDSURFACEDESC sdesc;
+  int x,y;
+  unsigned char *src;
+  unsigned short *dest;
+#endif
+  
+  FIXME("(%p)->(): stub\n", This);
+
+#ifdef USE_OSMESA
+  /* Here we copy back the OpenGL scene to the the DDraw surface */
+  /* First, lock the surface */
+  IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
+
+  /* The copy the OpenGL buffer to this surface */
+  
+  /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
+     I am currently working on a set of patches for Mesa to have OSMesa support
+     16 bpp surfaces => we will able to render directly onto the surface, no
+     need to do a bpp conversion */
+  dest = (unsigned short *) sdesc.y.lpSurface;
+  src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
+  for (y = 0; y < sdesc.dwHeight; y++) {
+    unsigned char *lsrc = src;
+    
+    for (x = 0; x < sdesc.dwWidth ; x++) {
+      unsigned char r =  *lsrc++;
+      unsigned char g =  *lsrc++;
+      unsigned char b =  *lsrc++;
+      lsrc++; /* Alpha */
+
+      *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
+      
+      dest++;
+    }
+
+    src -= 4 * sdesc.dwWidth;
+  }
+
+  /* Unlock the surface */
+  IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
+#else
+  /* No need to do anything here... */
+#endif
+  
+  return DD_OK;  
+}
+
+/*******************************************************************************
+ *				Direct3DDevice VTable
+ */
+ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3 = 
+{
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  IDirect3DDeviceImpl_QueryInterface,
+  IDirect3DDeviceImpl_AddRef,
+  MESA_IDirect3DDeviceImpl_Release,
+  IDirect3DDeviceImpl_Initialize,
+  IDirect3DDeviceImpl_GetCaps,
+  IDirect3DDeviceImpl_SwapTextureHandles,
+  IDirect3DDeviceImpl_CreateExecuteBuffer,
+  IDirect3DDeviceImpl_GetStats,
+  IDirect3DDeviceImpl_Execute,
+  IDirect3DDeviceImpl_AddViewport,
+  IDirect3DDeviceImpl_DeleteViewport,
+  IDirect3DDeviceImpl_NextViewport,
+  IDirect3DDeviceImpl_Pick,
+  IDirect3DDeviceImpl_GetPickRecords,
+  MESA_IDirect3DDeviceImpl_EnumTextureFormats,
+  IDirect3DDeviceImpl_CreateMatrix,
+  IDirect3DDeviceImpl_SetMatrix,
+  IDirect3DDeviceImpl_GetMatrix,
+  IDirect3DDeviceImpl_DeleteMatrix,
+  MESA_IDirect3DDeviceImpl_BeginScene,
+  MESA_IDirect3DDeviceImpl_EndScene,
+  IDirect3DDeviceImpl_GetDirect3D,
+};
diff --git a/dlls/ddraw/d3ddevices.c b/dlls/ddraw/d3ddevices.c
deleted file mode 100644
index efe730e..0000000
--- a/dlls/ddraw/d3ddevices.c
+++ /dev/null
@@ -1,1732 +0,0 @@
-/* Direct3D Device
-   (c) 1998 Lionel ULMER
-   
-   This files contains all the D3D devices that Wine supports. For the moment
-   only the 'OpenGL' target is supported. */
-
-#include <string.h>
-#include "config.h"
-#include "windef.h"
-#include "winerror.h"
-#include "wine/obj_base.h"
-#include "heap.h"
-#include "ddraw.h"
-#include "d3d.h"
-#include "debugtools.h"
-
-#include "d3d_private.h"
-
-DEFAULT_DEBUG_CHANNEL(ddraw)
-
-/* Define this variable if you have an unpatched Mesa 3.0 (patches are available
-   on Mesa's home page) or version 3.1b.
-
-   Version 3.1b2 should correct this bug */
-#undef HAVE_BUGGY_MESAGL
-
-#ifdef HAVE_MESAGL
-
-static GUID IID_D3DDEVICE2_OpenGL = {
-  0x39a0da38,
-  0x7e57,
-  0x11d2,
-  { 0x8b,0x7c,0x0e,0x4e,0xd8,0x3c,0x2b,0x3c }
-};
-
-static GUID IID_D3DDEVICE_OpenGL = {
-  0x31416d44,
-  0x86ae,
-  0x11d2,
-  { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
-};
-
-
-static ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable;
-static ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3;
-
-/*******************************************************************************
- *				OpenGL static functions
- */
-static void set_context(IDirect3DDevice2Impl* This) {
-  OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
-
-#ifdef USE_OSMESA
-  OSMesaMakeCurrent(odev->ctx, odev->buffer,
-		    GL_UNSIGNED_BYTE,
-		    This->surface->s.surface_desc.dwWidth,
-		    This->surface->s.surface_desc.dwHeight);
-#else
-  if (glXMakeCurrent(display,
-		     odev->common.surface->s.ddraw->d.drawable,
-		     odev->ctx) == False) {
-    ERR("Error in setting current context (context %p drawable %ld)!\n",
-	odev->ctx, odev->common.surface->s.ddraw->d.drawable);
-}
-#endif
-}
-
-static void set_context_dx3(IDirect3DDeviceImpl* This) {
-  OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
-
-#ifdef USE_OSMESA
-  OSMesaMakeCurrent(odev->ctx, odev->buffer,
-		    GL_UNSIGNED_BYTE,
-		    This->surface->s.surface_desc.dwWidth,
-		    This->surface->s.surface_desc.dwHeight);
-#else
-  if (glXMakeCurrent(display,
-		     odev->common.surface->s.ddraw->d.drawable,
-		     odev->ctx) == False) {
-    ERR("Error in setting current context !\n");
-  }
-#endif
-}
-
-static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
-{
-  pc->dwSize = sizeof(*pc);
-  pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
-    D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
-  pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
-    D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
-  pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
-  pc->dwSrcBlendCaps  = 0xFFFFFFFF; /* FIXME: need REAL values */
-  pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
-  pc->dwAlphaCmpCaps  = 0xFFFFFFFF; /* FIXME: need REAL values */
-  pc->dwShadeCaps = 0xFFFFFFFF;     /* FIXME: need REAL values */
-  pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
-    D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
-  pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
-    D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
-  pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
-  pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
-  pc->dwStippleWidth = 32;
-  pc->dwStippleHeight = 32;
-}
-
-static void fill_opengl_caps(D3DDEVICEDESC *d1, D3DDEVICEDESC *d2)
-{
-  /* GLint maxlight; */
-  
-  d1->dwSize  = sizeof(*d1);
-  d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
-    | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
-  d1->dcmColorModel = D3DCOLOR_RGB;
-  d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
-    D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
-      D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
-  d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
-  d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
-  d1->bClipping = TRUE;
-  d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
-  d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
-  d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
-  d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
-  fill_opengl_primcaps(&(d1->dpcLineCaps));
-  fill_opengl_primcaps(&(d1->dpcTriCaps));  
-  d1->dwDeviceRenderBitDepth  = DDBD_16;
-  d1->dwDeviceZBufferBitDepth = DDBD_16;
-  d1->dwMaxBufferSize = 0;
-  d1->dwMaxVertexCount = 65536;
-  d1->dwMinTextureWidth  = 1;
-  d1->dwMinTextureHeight = 1;
-  d1->dwMaxTextureWidth  = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
-  d1->dwMaxTextureHeight = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
-  d1->dwMinStippleWidth  = 1;
-  d1->dwMinStippleHeight = 1;
-  d1->dwMaxStippleWidth  = 32;
-  d1->dwMaxStippleHeight = 32;
-
-  d2->dwSize  = sizeof(*d2);
-  d2->dwFlags = 0;
-}
-
-int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
-  D3DDEVICEDESC	d1,d2;
-  
-  TRACE(" Enumerating OpenGL D3D device.\n");
-  
-  fill_opengl_caps(&d1, &d2);
-  
-  return cb((void*)&IID_D3DDEVICE2_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
-}
-
-int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d)
-{
-  if (/* Default device */
-      (rguid == NULL) ||
-      /* HAL Device */
-      (!memcmp(&IID_IDirect3DHALDevice,rguid,sizeof(IID_IDirect3DHALDevice))) ||
-      /* OpenGL Device */
-      (!memcmp(&IID_D3DDEVICE2_OpenGL,rguid,sizeof(IID_D3DDEVICE2_OpenGL)))) {
-    OpenGL_IDirect3DDevice2 *odev;
-    
-    const float id_mat[16] = {
-      1.0, 0.0, 0.0, 0.0,
-      0.0, 1.0, 0.0, 0.0,
-      0.0, 0.0, 1.0, 0.0,
-      0.0, 0.0, 0.0, 1.0
-    };
-#ifndef USE_OSMESA
-    int attributeList[]={ GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None };
-    XVisualInfo *xvis;
-#endif
-    
-    *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice2));
-    odev = (OpenGL_IDirect3DDevice2 *) (*device);
-    (*device)->ref = 1;
-    ICOM_VTBL(*device) = &OpenGL_vtable;
-    (*device)->d3d = d3d;
-    (*device)->surface = surface;
-    
-    (*device)->viewport_list = NULL;
-    (*device)->current_viewport = NULL;
-    
-    (*device)->set_context = set_context;
-    
-    TRACE("Creating OpenGL device for surface %p\n", surface);
-    
-    /* Create the OpenGL context */
-#ifdef USE_OSMESA
-    odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
-    odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
-			     surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
-#else
-    /* First get the correct visual */
-    /* if (surface->s.backbuffer == NULL)
-       attributeList[3] = None; */
-    ENTER_GL();
-    xvis = glXChooseVisual(display,
-			   DefaultScreen(display),
-			   attributeList);
-    if (xvis == NULL)
-      ERR("No visual found !\n");
-    else
-      TRACE("Visual found\n");
-    /* Create the context */
-    odev->ctx = glXCreateContext(display,
-				 xvis,
-				 NULL,
-				 GL_TRUE);
-    if (odev->ctx == NULL)
-      ERR("Error in context creation !\n");
-    else
-      TRACE("Context created (%p)\n", odev->ctx);
-    
-    /* Now override the surface's Flip method (if in double buffering) */
-    surface->s.d3d_device = (void *) odev;
-    {
-	int i;
-	struct _surface_chain *chain = surface->s.chain;
-	for (i=0;i<chain->nrofsurfaces;i++)
-	  if (chain->surfaces[i]->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_FLIP)
-	      chain->surfaces[i]->s.d3d_device = (void *) odev;
-    }
-#endif
-    odev->rs.src = GL_ONE;
-    odev->rs.dst = GL_ZERO;
-    odev->rs.mag = GL_NEAREST;
-    odev->rs.min = GL_NEAREST;
-    odev->vt     = 0;
-    
-    memcpy(odev->world_mat, id_mat, 16 * sizeof(float));
-    memcpy(odev->view_mat , id_mat, 16 * sizeof(float));
-    memcpy(odev->proj_mat , id_mat, 16 * sizeof(float));
-
-    /* Initialisation */
-    TRACE("Setting current context\n");
-    (*device)->set_context(*device);
-    TRACE("Current context set\n");
-    glClearColor(0.0, 0.0, 0.0, 0.0);
-    glColor3f(1.0, 1.0, 1.0);
-    LEAVE_GL();
-    
-    TRACE("OpenGL device created \n");
-    
-    return 1;
-  }
-  
-  /* This is not the OpenGL UID */
-  return 0;
-}
-
-/*******************************************************************************
- *				Common IDirect3DDevice2
- */
-
-static HRESULT WINAPI IDirect3DDevice2Impl_QueryInterface(LPDIRECT3DDEVICE2 iface,
-						      REFIID riid,
-						      LPVOID* ppvObj)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  
-  FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
-  
-  return S_OK;
-}
-
-
-
-static ULONG WINAPI IDirect3DDevice2Impl_AddRef(LPDIRECT3DDEVICE2 iface)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
-  
-  return ++(This->ref);
-}
-
-
-
-static ULONG WINAPI IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
-  
-  if (!--(This->ref)) {
-    OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
-
-#ifdef USE_OSMESA
-    OSMesaDestroyContext(odev->ctx);
-#else
-    ENTER_GL();
-    glXDestroyContext(display,
-		      odev->ctx);
-    LEAVE_GL();
-#endif
-    
-    HeapFree(GetProcessHeap(),0,This);
-    return 0;
-  }
-  
-  return This->ref;
-}
-
-
-/*** IDirect3DDevice2 methods ***/
-static HRESULT WINAPI IDirect3DDevice2Impl_GetCaps(LPDIRECT3DDEVICE2 iface,
-					       LPD3DDEVICEDESC lpdescsoft,
-					       LPD3DDEVICEDESC lpdeschard)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p,%p): stub\n", This, lpdescsoft, lpdeschard);
-  
-  fill_opengl_caps(lpdescsoft, lpdeschard);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_SwapTextureHandles(LPDIRECT3DDEVICE2 iface,
-							  LPDIRECT3DTEXTURE2 lptex1,
-							  LPDIRECT3DTEXTURE2 lptex2)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p,%p): stub\n", This, lptex1, lptex2);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_GetStats(LPDIRECT3DDEVICE2 iface,
-						LPD3DSTATS lpstats)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p): stub\n", This, lpstats);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_AddViewport(LPDIRECT3DDEVICE2 iface,
-						   LPDIRECT3DVIEWPORT2 lpvp)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-  FIXME("(%p)->(%p): stub\n", This, ilpvp);
-  
-  /* Adds this viewport to the viewport list */
-  ilpvp->next = This->viewport_list;
-  This->viewport_list = ilpvp;
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_DeleteViewport(LPDIRECT3DDEVICE2 iface,
-						      LPDIRECT3DVIEWPORT2 lpvp)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-  IDirect3DViewport2Impl *cur, *prev;
-  FIXME("(%p)->(%p): stub\n", This, lpvp);
-  
-  /* Finds this viewport in the list */
-  prev = NULL;
-  cur = This->viewport_list;
-  while ((cur != NULL) && (cur != ilpvp)) {
-    prev = cur;
-    cur = cur->next;
-  }
-  if (cur == NULL)
-    return DDERR_INVALIDOBJECT;
-  
-  /* And remove it */
-  if (prev == NULL)
-    This->viewport_list = cur->next;
-  else
-    prev->next = cur->next;
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_NextViewport(LPDIRECT3DDEVICE2 iface,
-						    LPDIRECT3DVIEWPORT2 lpvp,
-						    LPDIRECT3DVIEWPORT2* lplpvp,
-						    DWORD dwFlags)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-  IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
-  FIXME("(%p)->(%p,%p,%08lx): stub\n", This, lpvp, lpvp, dwFlags);
-  
-  switch (dwFlags) {
-  case D3DNEXT_NEXT:
-    *ilplpvp = ilpvp->next;
-    break;
-    
-  case D3DNEXT_HEAD:
-    *ilplpvp = This->viewport_list;
-    break;
-    
-  case D3DNEXT_TAIL:
-    ilpvp = This->viewport_list;
-    while (ilpvp->next != NULL)
-      ilpvp = ilpvp->next;
-    
-    *ilplpvp = ilpvp;
-    break;
-    
-  default:
-    return DDERR_INVALIDPARAMS;
-  }
-  
-  return DD_OK;
-}
-
-static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb,
-					  LPVOID context) {
-  DDSURFACEDESC sdesc;
-  LPDDPIXELFORMAT pformat;
-
-  /* Do the texture enumeration */
-  sdesc.dwSize = sizeof(DDSURFACEDESC);
-  sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
-  sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
-  pformat = &(sdesc.ddpfPixelFormat);
-  pformat->dwSize = sizeof(DDPIXELFORMAT);
-  pformat->dwFourCC = 0;
-  
-  TRACE("Enumerating GL_RGBA unpacked (32)\n");
-  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-  pformat->u.dwRGBBitCount = 32;
-  pformat->u1.dwRBitMask =         0xFF000000;
-  pformat->u2.dwGBitMask =         0x00FF0000;
-  pformat->u3.dwBBitMask =        0x0000FF00;
-  pformat->u4.dwRGBAlphaBitMask = 0x000000FF;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
-
-  TRACE("Enumerating GL_RGB unpacked (24)\n");
-  pformat->dwFlags = DDPF_RGB;
-  pformat->u.dwRGBBitCount = 24;
-  pformat->u1.dwRBitMask =  0x00FF0000;
-  pformat->u2.dwGBitMask =  0x0000FF00;
-  pformat->u3.dwBBitMask = 0x000000FF;
-  pformat->u4.dwRGBAlphaBitMask = 0x00000000;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
-
-#ifndef HAVE_BUGGY_MESAGL
-  /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
-     so that future version will work great. */
-  TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
-  pformat->dwFlags = DDPF_RGB;
-  pformat->u.dwRGBBitCount = 16;
-  pformat->u1.dwRBitMask =  0x0000F800;
-  pformat->u2.dwGBitMask =  0x000007E0;
-  pformat->u3.dwBBitMask = 0x0000001F;
-  pformat->u4.dwRGBAlphaBitMask = 0x00000000;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
-
-  TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
-  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-  pformat->u.dwRGBBitCount = 16;
-  pformat->u1.dwRBitMask =         0x0000F800;
-  pformat->u2.dwGBitMask =         0x000007C0;
-  pformat->u3.dwBBitMask =        0x0000003E;
-  pformat->u4.dwRGBAlphaBitMask = 0x00000001;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
-
-  TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
-  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
-  pformat->u.dwRGBBitCount = 16;
-  pformat->u1.dwRBitMask =         0x0000F000;
-  pformat->u2.dwGBitMask =         0x00000F00;
-  pformat->u3.dwBBitMask =        0x000000F0;
-  pformat->u4.dwRGBAlphaBitMask = 0x0000000F;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
-
-  TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
-  pformat->dwFlags = DDPF_RGB;
-  pformat->u.dwRGBBitCount = 8;
-  pformat->u1.dwRBitMask =         0x0000F800;
-  pformat->u2.dwGBitMask =         0x000007C0;
-  pformat->u3.dwBBitMask =        0x0000003E;
-  pformat->u4.dwRGBAlphaBitMask = 0x00000001;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
-#endif
-
-#if defined(HAVE_GL_COLOR_TABLE) && defined(HAVE_GL_PALETTED_TEXTURE)
-  TRACE("Enumerating Paletted (8)\n");
-  pformat->dwFlags = DDPF_PALETTEINDEXED8;
-  pformat->u.dwRGBBitCount = 8;
-  pformat->u1.dwRBitMask =  0x00000000;
-  pformat->u2.dwGBitMask =  0x00000000;
-  pformat->u3.dwBBitMask = 0x00000000;
-  pformat->u4.dwRGBAlphaBitMask = 0x00000000;
-  if (cb(&sdesc, context) == 0)
-    return DD_OK;
-#endif
-  
-  TRACE("End of enumeration\n");
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DDevice2Impl_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
-							  LPD3DENUMTEXTUREFORMATSCALLBACK cb,
-							  LPVOID context)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p,%p): stub\n", This, cb, context);
-  
-  return enum_texture_format_OpenGL(cb, context);
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_BeginScene(LPDIRECT3DDEVICE2 iface)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  /* OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This; */
-  
-  FIXME("(%p)->(): stub\n", This);
-  
-  /* Here, we should get the DDraw surface and 'copy it' to the
-     OpenGL surface.... */
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-#ifdef USE_OSMESA
-  OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
-  LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
-  DDSURFACEDESC sdesc;
-  int x,y;
-  unsigned char *src;
-  unsigned short *dest;
-#endif
-  
-  FIXME("(%p)->(): stub\n", This);
-
-#ifdef USE_OSMESA
-  /* Here we copy back the OpenGL scene to the the DDraw surface */
-  /* First, lock the surface */
-  IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
-
-  /* The copy the OpenGL buffer to this surface */
-  
-  /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
-     I am currently working on a set of patches for Mesa to have OSMesa support
-     16 bpp surfaces => we will able to render directly onto the surface, no
-     need to do a bpp conversion */
-  dest = (unsigned short *) sdesc.y.lpSurface;
-  src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
-  for (y = 0; y < sdesc.dwHeight; y++) {
-    unsigned char *lsrc = src;
-    
-    for (x = 0; x < sdesc.dwWidth ; x++) {
-      unsigned char r =  *lsrc++;
-      unsigned char g =  *lsrc++;
-      unsigned char b =  *lsrc++;
-      lsrc++; /* Alpha */
-      *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
-      
-      dest++;
-    }
-
-    src -= 4 * sdesc.dwWidth;
-  }
-
-  /* Unlock the surface */
-  IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
-#else
-  /* No need to do anything here... */
-#endif
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_GetDirect3D(LPDIRECT3DDEVICE2 iface, LPDIRECT3D2 *lpd3d2)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  TRACE("(%p)->(%p): stub\n", This, lpd3d2);
-  
-  *lpd3d2 = (LPDIRECT3D2)This->d3d;
-  
-  return DD_OK;
-}
-
-
-
-/*** DrawPrimitive API ***/
-static HRESULT WINAPI IDirect3DDevice2Impl_SetCurrentViewport(LPDIRECT3DDEVICE2 iface,
-							  LPDIRECT3DVIEWPORT2 lpvp)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-  FIXME("(%p)->(%p): stub\n", This, ilpvp);
-  
-  /* Should check if the viewport was added or not */
-  
-  /* Set this viewport as the current viewport */
-  This->current_viewport = ilpvp;
-  
-  /* Activate this viewport */
-  ilpvp->device.active_device2 = This;
-  ilpvp->activate(ilpvp);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_GetCurrentViewport(LPDIRECT3DDEVICE2 iface,
-							  LPDIRECT3DVIEWPORT2 *lplpvp)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p): stub\n", This, lplpvp);
-  
-  /* Returns the current viewport */
-  *lplpvp = (LPDIRECT3DVIEWPORT2)This->current_viewport;
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_SetRenderTarget(LPDIRECT3DDEVICE2 iface,
-						       LPDIRECTDRAWSURFACE lpdds,
-						       DWORD dwFlags)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p,%08lx): stub\n", This, lpdds, dwFlags);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_GetRenderTarget(LPDIRECT3DDEVICE2 iface,
-						       LPDIRECTDRAWSURFACE *lplpdds)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p): stub\n", This, lplpdds);
-  
-  /* Returns the current rendering target (the surface on wich we render) */
-  *lplpdds = (LPDIRECTDRAWSURFACE)This->surface;
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_Begin(LPDIRECT3DDEVICE2 iface,
-					     D3DPRIMITIVETYPE d3dp,
-					     D3DVERTEXTYPE d3dv,
-					     DWORD dwFlags)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%d,%d,%08lx): stub\n", This, d3dp, d3dv, dwFlags);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_BeginIndexed(LPDIRECT3DDEVICE2 iface,
-						    D3DPRIMITIVETYPE d3dp,
-						    D3DVERTEXTYPE d3dv,
-						    LPVOID lpvert,
-						    DWORD numvert,
-						    DWORD dwFlags)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvert, numvert, dwFlags);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_Vertex(LPDIRECT3DDEVICE2 iface,
-					      LPVOID lpvert)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p): stub\n", This, lpvert);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_Index(LPDIRECT3DDEVICE2 iface,
-					     WORD index)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%d): stub\n", This, index);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_End(LPDIRECT3DDEVICE2 iface,
-					   DWORD dwFlags)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%08lx): stub\n", This, dwFlags);
-  
-  return DD_OK;
-}
-
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_GetRenderState(LPDIRECT3DDEVICE2 iface,
-						      D3DRENDERSTATETYPE d3drs,
-						      LPDWORD lprstate)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%d,%p): stub\n", This, d3drs, lprstate);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_SetRenderState(LPDIRECT3DDEVICE2 iface,
-						      D3DRENDERSTATETYPE dwRenderStateType,
-						      DWORD dwRenderState)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
-
-  TRACE("(%p)->(%d,%ld)\n", This, dwRenderStateType, dwRenderState);
-  
-  /* Call the render state functions */
-  set_render_state(dwRenderStateType, dwRenderState, &(odev->rs));
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_GetLightState(LPDIRECT3DDEVICE2 iface,
-						     D3DLIGHTSTATETYPE d3dls,
-						     LPDWORD lplstate)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%d,%p): stub\n", This, d3dls, lplstate);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_SetLightState(LPDIRECT3DDEVICE2 iface,
-						     D3DLIGHTSTATETYPE dwLightStateType,
-						     DWORD dwLightState)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%d,%08lx): stub\n", This, dwLightStateType, dwLightState);
-  
-  switch (dwLightStateType) {
-  case D3DLIGHTSTATE_MATERIAL: {  /* 1 */
-    IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) dwLightState;
-    
-    if (mat != NULL) {
-      ENTER_GL();
-      mat->activate(mat);
-      LEAVE_GL();
-    } else {
-      TRACE("Zoups !!!\n");
-    }
-  } break;
-    
-  case D3DLIGHTSTATE_AMBIENT: {   /* 2 */
-    float light[4];
-    
-    light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
-    light[1] = ((dwLightState >>  8) & 0xFF) / 255.0;
-    light[2] = ((dwLightState >>  0) & 0xFF) / 255.0;
-    light[3] = 1.0;
-    ENTER_GL();
-    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
-    LEAVE_GL();
-  } break;
-    
-  case D3DLIGHTSTATE_COLORMODEL:  /* 3 */
-    break;
-    
-  case D3DLIGHTSTATE_FOGMODE:     /* 4 */
-    break;
-    
-  case D3DLIGHTSTATE_FOGSTART:    /* 5 */
-    break;
-    
-  case D3DLIGHTSTATE_FOGEND:      /* 6 */
-    break;
-    
-  case D3DLIGHTSTATE_FOGDENSITY:  /* 7 */
-    break;
-    
-  default:
-    TRACE("Unexpected Light State Type\n");
-    return DDERR_INVALIDPARAMS;
-  }
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_SetTransform(LPDIRECT3DDEVICE2 iface,
-						    D3DTRANSFORMSTATETYPE d3dts,
-						    LPD3DMATRIX lpmatrix)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
-  
-  FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
-  
-  ENTER_GL();
-  
-  /* Using a trial and failure approach, I found that the order of 
-     Direct3D transformations that works best is :
-
-     ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
-
-     As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
-     OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
-
-     If anyone has a good explanation of the three different matrices in
-     the SDK online documentation, feel free to point it to me. For example,
-     which matrices transform lights ? In OpenGL only the PROJECTION matrix
-     transform the lights, not the MODELVIEW. Using the matrix names, I 
-     supposed that PROJECTION and VIEW (all 'camera' related names) do
-     transform lights, but WORLD do not. It may be wrong though... */
-
-  /* After reading through both OpenGL and Direct3D documentations, I
-     thought that D3D matrices were written in 'line major mode' transposed
-     from OpenGL's 'column major mode'. But I found out that a simple memcpy
-     works fine to transfer one matrix format to the other (it did not work
-     when transposing)....
-
-     So :
-      1) are the documentations wrong
-      2) does the matrix work even if they are not read correctly
-      3) is Mesa's implementation of OpenGL not compliant regarding Matrix
-         loading using glLoadMatrix ?
-
-     Anyway, I always use 'conv_mat' to transfer the matrices from one format
-     to the other so that if I ever find out that I need to transpose them, I
-     will able to do it quickly, only by changing the macro conv_mat. */
-
-  switch (d3dts) {
-  case D3DTRANSFORMSTATE_WORLD: {
-    conv_mat(lpmatrix, odev->world_mat);
-    glMatrixMode(GL_MODELVIEW);
-    glLoadMatrixf((float *) &(odev->world_mat));
-  } break;
-    
-  case D3DTRANSFORMSTATE_VIEW: {
-    conv_mat(lpmatrix, odev->view_mat);
-    glMatrixMode(GL_PROJECTION);
-    glLoadMatrixf((float *) &(odev->proj_mat));
-    glMultMatrixf((float *) &(odev->view_mat));
-  } break;
-    
-  case D3DTRANSFORMSTATE_PROJECTION: {
-    conv_mat(lpmatrix, odev->proj_mat);
-    glMatrixMode(GL_PROJECTION);
-    glLoadMatrixf((float *) &(odev->proj_mat));
-    glMultMatrixf((float *) &(odev->view_mat));
-  } break;
-    
-  default:
-    break;
-  }
-  
-  LEAVE_GL();
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_GetTransform(LPDIRECT3DDEVICE2 iface,
-						    D3DTRANSFORMSTATETYPE d3dts,
-						    LPD3DMATRIX lpmatrix)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_MultiplyTransform(LPDIRECT3DDEVICE2 iface,
-							 D3DTRANSFORMSTATETYPE d3dts,
-							 LPD3DMATRIX lpmatrix)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
-  
-  return DD_OK;
-}
-
-#define DRAW_PRIMITIVE(MAXVERT,INDEX)						\
-  /* Puts GL in the correct lighting mode */					\
-  if (odev->vt != d3dv) {							\
-    if (odev->vt == D3DVT_TLVERTEX) {						\
-      /* Need to put the correct transformation again */			\
-      glMatrixMode(GL_MODELVIEW);						\
-      glLoadMatrixf((float *) &(odev->world_mat));				\
-      glMatrixMode(GL_PROJECTION);						\
-      glLoadMatrixf((float *) &(odev->proj_mat));				\
-      glMultMatrixf((float *) &(odev->view_mat));				\
-    }										\
-										\
-    switch (d3dv) {								\
-    case D3DVT_VERTEX:								\
-      TRACE("Standard Vertex\n");					\
-      glEnable(GL_LIGHTING);							\
-      break;									\
-										\
-    case D3DVT_LVERTEX:								\
-      TRACE("Lighted Vertex\n");						\
-      glDisable(GL_LIGHTING);							\
-      break;									\
-										\
-    case D3DVT_TLVERTEX: {							\
-      GLdouble height, width, minZ, maxZ;					\
-										\
-      TRACE("Transformed - Lighted Vertex\n");				\
-      /* First, disable lighting */						\
-      glDisable(GL_LIGHTING);							\
-										\
-      /* Then do not put any transformation matrixes */				\
-      glMatrixMode(GL_MODELVIEW);						\
-      glLoadIdentity();								\
-      glMatrixMode(GL_PROJECTION);						\
-      glLoadIdentity();								\
-										\
-      if (This->current_viewport == NULL) {					\
-	ERR("No current viewport !\n");					\
-	/* Using standard values */						\
-	height = 640.0;								\
-	width = 480.0;								\
-	minZ = -10.0;								\
-	maxZ = 10.0;								\
-      } else {									\
-	if (This->current_viewport->use_vp2) {					\
-	  height = (GLdouble) This->current_viewport->viewport.vp2.dwHeight;	\
-	  width  = (GLdouble) This->current_viewport->viewport.vp2.dwWidth;	\
-	  minZ   = (GLdouble) This->current_viewport->viewport.vp2.dvMinZ;	\
-	  maxZ   = (GLdouble) This->current_viewport->viewport.vp2.dvMaxZ;	\
-	} else {								\
-	  height = (GLdouble) This->current_viewport->viewport.vp1.dwHeight;	\
-	  width  = (GLdouble) This->current_viewport->viewport.vp1.dwWidth;	\
-	  minZ   = (GLdouble) This->current_viewport->viewport.vp1.dvMinZ;	\
-	  maxZ   = (GLdouble) This->current_viewport->viewport.vp1.dvMaxZ;	\
-	}									\
-      }										\
-										\
-      glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);				\
-    } break;									\
-										\
-    default:									\
-      ERR("Unhandled vertex type\n");					\
-      break;									\
-    }										\
-										\
-    odev->vt = d3dv;								\
-  }										\
-										\
-  switch (d3dp) {								\
-  case D3DPT_POINTLIST:								\
-    TRACE("Start POINTS\n");						\
-    glBegin(GL_POINTS);								\
-    break;									\
-										\
-  case D3DPT_LINELIST:								\
-    TRACE("Start LINES\n");						\
-    glBegin(GL_LINES);								\
-    break;									\
-										\
-  case D3DPT_LINESTRIP:								\
-    TRACE("Start LINE_STRIP\n");						\
-    glBegin(GL_LINE_STRIP);							\
-    break;									\
-										\
-  case D3DPT_TRIANGLELIST:							\
-    TRACE("Start TRIANGLES\n");						\
-    glBegin(GL_TRIANGLES);							\
-    break;									\
-										\
-  case D3DPT_TRIANGLESTRIP:							\
-    TRACE("Start TRIANGLE_STRIP\n");					\
-    glBegin(GL_TRIANGLE_STRIP);							\
-    break;									\
-										\
-  case D3DPT_TRIANGLEFAN:							\
-    TRACE("Start TRIANGLE_FAN\n");					\
-    glBegin(GL_TRIANGLE_FAN);							\
-    break;									\
-										\
-  default:									\
-    TRACE("Unhandled primitive\n");					\
-    break;									\
-  }										\
-										\
-  /* Draw the primitives */							\
-  for (vx_index = 0; vx_index < MAXVERT; vx_index++) {				\
-    switch (d3dv) {								\
-    case D3DVT_VERTEX: {							\
-      D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + INDEX;				\
-										\
-      glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz);				\
-      glVertex3f(vx->x.x, vx->y.y, vx->z.z);					\
-      TRACE("   V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z);		\
-    } break;									\
-										\
-    case D3DVT_LVERTEX: {							\
-      D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + INDEX;			\
-      DWORD col = vx->c.color;							\
-										\
-      glColor3f(((col >> 16) & 0xFF) / 255.0,					\
-		((col >>  8) & 0xFF) / 255.0,					\
-		((col >>  0) & 0xFF) / 255.0);					\
-      glVertex3f(vx->x.x, vx->y.y, vx->z.z);					\
-      TRACE("  LV: %f %f %f (%02lx %02lx %02lx)\n",			\
-	    vx->x.x, vx->y.y, vx->z.z,						\
-	    ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF));	\
-    } break;									\
-										\
-    case D3DVT_TLVERTEX: {							\
-      D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + INDEX;			\
-      DWORD col = vx->c.color;							\
-										\
-      glColor3f(((col >> 16) & 0xFF) / 255.0,					\
-		((col >>  8) & 0xFF) / 255.0,					\
-		((col >>  0) & 0xFF) / 255.0);					\
-      glTexCoord2f(vx->u.tu, vx->v.tv);						\
-      if (vx->r.rhw < 0.01)							\
-	glVertex3f(vx->x.sx,							\
-		   vx->y.sy,							\
-		   vx->z.sz);							\
-      else									\
-	glVertex4f(vx->x.sx / vx->r.rhw,					\
-		   vx->y.sy / vx->r.rhw,					\
-		   vx->z.sz / vx->r.rhw,					\
-		   1.0 / vx->r.rhw);						\
-      TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n",		\
-	    vx->x.sx, vx->y.sy, vx->z.sz,					\
-	    ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF),	\
-	    vx->u.tu, vx->v.tv, vx->r.rhw);					\
-    } break;									\
-										\
-    default:									\
-      TRACE("Unhandled vertex type\n");					\
-      break;									\
-    }										\
-  }										\
-										\
-  glEnd();									\
-  TRACE("End\n");
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
-						     D3DPRIMITIVETYPE d3dp,
-						     D3DVERTEXTYPE d3dv,
-						     LPVOID lpvertex,
-						     DWORD vertcount,
-						     DWORD dwFlags)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
-  int vx_index;
-  
-  TRACE("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags);
-
-  ENTER_GL();
-  DRAW_PRIMITIVE(vertcount, vx_index);
-  LEAVE_GL();
-    
-  return D3D_OK;
-      }
-    
-
-      
-static HRESULT WINAPI IDirect3DDevice2Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
-							    D3DPRIMITIVETYPE d3dp,
-							    D3DVERTEXTYPE d3dv,
-							    LPVOID lpvertex,
-							    DWORD vertcount,
-							    LPWORD lpindexes,
-							    DWORD indexcount,
-							    DWORD dwFlags)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
-  int vx_index;
-  
-  TRACE("(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
-  
-  ENTER_GL();
-  DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]);
-  LEAVE_GL();
-  
-  return D3D_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_SetClipStatus(LPDIRECT3DDEVICE2 iface,
-						     LPD3DCLIPSTATUS lpcs)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p): stub\n", This, lpcs);
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDevice2Impl_GetClipStatus(LPDIRECT3DDEVICE2 iface,
-						     LPD3DCLIPSTATUS lpcs)
-{
-  ICOM_THIS(IDirect3DDevice2Impl,iface);
-  FIXME("(%p)->(%p): stub\n", This, lpcs);
-  
-  return DD_OK;
-}
-
-
-
-/*******************************************************************************
- *				OpenGL-specific IDirect3DDevice2
- */
-
-/*******************************************************************************
- *				OpenGL-specific VTable
- */
-
-static ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable = 
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  IDirect3DDevice2Impl_QueryInterface,
-  IDirect3DDevice2Impl_AddRef,
-  IDirect3DDevice2Impl_Release,
-  /*** IDirect3DDevice2 methods ***/
-  IDirect3DDevice2Impl_GetCaps,
-  IDirect3DDevice2Impl_SwapTextureHandles,
-  IDirect3DDevice2Impl_GetStats,
-  IDirect3DDevice2Impl_AddViewport,
-  IDirect3DDevice2Impl_DeleteViewport,
-  IDirect3DDevice2Impl_NextViewport,
-  IDirect3DDevice2Impl_EnumTextureFormats,
-  IDirect3DDevice2Impl_BeginScene,
-  IDirect3DDevice2Impl_EndScene,
-  IDirect3DDevice2Impl_GetDirect3D,
-  
-  /*** DrawPrimitive API ***/
-  IDirect3DDevice2Impl_SetCurrentViewport,
-  IDirect3DDevice2Impl_GetCurrentViewport,
-  
-  IDirect3DDevice2Impl_SetRenderTarget,
-  IDirect3DDevice2Impl_GetRenderTarget,
-  
-  IDirect3DDevice2Impl_Begin,
-  IDirect3DDevice2Impl_BeginIndexed,
-  IDirect3DDevice2Impl_Vertex,
-  IDirect3DDevice2Impl_Index,
-  IDirect3DDevice2Impl_End,
-  
-  IDirect3DDevice2Impl_GetRenderState,
-  IDirect3DDevice2Impl_SetRenderState,
-  IDirect3DDevice2Impl_GetLightState,
-  IDirect3DDevice2Impl_SetLightState,
-  IDirect3DDevice2Impl_SetTransform,
-  IDirect3DDevice2Impl_GetTransform,
-  IDirect3DDevice2Impl_MultiplyTransform,
-  
-  IDirect3DDevice2Impl_DrawPrimitive,
-  IDirect3DDevice2Impl_DrawIndexedPrimitive,
-  
-  IDirect3DDevice2Impl_SetClipStatus,
-  IDirect3DDevice2Impl_GetClipStatus,
-};
-
-/*******************************************************************************
- *				Direct3DDevice
- */
-int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
-  D3DDEVICEDESC	d1,d2;
-  
-  TRACE(" Enumerating OpenGL D3D device.\n");
-  
-  fill_opengl_caps(&d1, &d2);
-  
-  return cb((void*)&IID_D3DDEVICE_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
-}
-
-float id_mat[16] = {
-  1.0, 0.0, 0.0, 0.0,
-  0.0, 1.0, 0.0, 0.0,
-  0.0, 0.0, 1.0, 0.0,
-  0.0, 0.0, 0.0, 1.0
-};
-
-int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device)
-{
-  if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
-    OpenGL_IDirect3DDevice *odev;
-#ifndef USE_OSMESA
-    int attributeList[]={ GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None };
-    XVisualInfo *xvis;
-#endif
-       
-    *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice));
-    odev = (OpenGL_IDirect3DDevice *) (*device);
-    (*device)->ref = 1;
-    ICOM_VTBL(*device) = &OpenGL_vtable_dx3;
-    (*device)->d3d = NULL;
-    (*device)->surface = surface;
-    
-    (*device)->viewport_list = NULL;
-    (*device)->current_viewport = NULL;
-    
-    (*device)->set_context = set_context_dx3;
-    
-    TRACE("OpenGL device created \n");
-    
-    /* Create the OpenGL context */
-#ifdef USE_OSMESA
-    odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
-    odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
-			     surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
-#else
-    /* First get the correct visual */
-    /* if (surface->s.backbuffer == NULL)
-       attributeList[3] = None; */
-    ENTER_GL();
-    xvis = glXChooseVisual(display,
-			   DefaultScreen(display),
-			   attributeList);
-    if (xvis == NULL)
-      ERR("No visual found !\n");
-    else
-      TRACE("Visual found\n");
-    /* Create the context */
-    odev->ctx = glXCreateContext(display,
-				 xvis,
-				 NULL,
-				 GL_TRUE);
-    TRACE("Context created\n");
-    
-    /* Now override the surface's Flip method (if in double buffering) */
-    surface->s.d3d_device = (void *) odev;
-    {
-	int i;
-	struct _surface_chain *chain = surface->s.chain;
-	for (i=0;i<chain->nrofsurfaces;i++)
-	  if (chain->surfaces[i]->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_FLIP)
-	      chain->surfaces[i]->s.d3d_device = (void *) odev;
-    }
-#endif
-    odev->rs.src = GL_ONE;
-    odev->rs.dst = GL_ZERO;
-    odev->rs.mag = GL_NEAREST;
-    odev->rs.min = GL_NEAREST;
-
-    odev->world_mat = (LPD3DMATRIX) &id_mat;
-    odev->view_mat  = (LPD3DMATRIX) &id_mat;
-    odev->proj_mat  = (LPD3DMATRIX) &id_mat;
-
-    /* Initialisation */
-    (*device)->set_context(*device);
-    glClearColor(0.0, 0.0, 0.0, 0.0);
-    glColor3f(1.0, 1.0, 1.0);
-    
-    return 1;
-  }
-  
-  /* This is not the OpenGL UID */
-  return DD_OK;
-}
-
-
-/*******************************************************************************
- *				Direct3DDevice
- */
-static HRESULT WINAPI IDirect3DDeviceImpl_QueryInterface(LPDIRECT3DDEVICE iface,
-						     REFIID riid,
-						     LPVOID* ppvObj)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  
-  FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
-  
-  return S_OK;
-}
-
-
-
-static ULONG WINAPI IDirect3DDeviceImpl_AddRef(LPDIRECT3DDEVICE iface)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
-  
-  return ++(This->ref);
-}
-
-
-
-static ULONG WINAPI IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
-  
-  if (!--(This->ref)) {
-    OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
-
-#ifdef USE_OSMESA
-    OSMesaDestroyContext(odev->ctx);
-#else
-    ENTER_GL();
-    glXDestroyContext(display,
-		      odev->ctx);
-    LEAVE_GL();
-#endif    
-    
-    HeapFree(GetProcessHeap(),0,This);
-    return 0;
-  }
-  
-  return This->ref;
-}
-
-static HRESULT WINAPI IDirect3DDeviceImpl_Initialize(LPDIRECT3DDEVICE iface,
-						 LPDIRECT3D lpd3d,
-						 LPGUID lpGUID,
-						 LPD3DDEVICEDESC lpd3ddvdesc)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p,%p,%p): stub\n", This, lpd3d,lpGUID, lpd3ddvdesc);
-  
-  return DDERR_ALREADYINITIALIZED;
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_GetCaps(LPDIRECT3DDEVICE iface,
-					      LPD3DDEVICEDESC lpD3DHWDevDesc,
-					      LPD3DDEVICEDESC lpD3DSWDevDesc)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lpD3DHWDevDesc, lpD3DSWDevDesc);
-
-  fill_opengl_caps(lpD3DHWDevDesc, lpD3DSWDevDesc);  
-  
-  return DD_OK;
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_SwapTextureHandles(LPDIRECT3DDEVICE iface,
-							 LPDIRECT3DTEXTURE lpD3DTex1,
-							 LPDIRECT3DTEXTURE lpD3DTex2)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lpD3DTex1, lpD3DTex2);
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DDeviceImpl_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
-							  LPD3DEXECUTEBUFFERDESC lpDesc,
-							  LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer,
-							  IUnknown *pUnkOuter)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p,%p,%p)\n", This, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
-
-  *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(This, lpDesc);
-  
-  return DD_OK;
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_GetStats(LPDIRECT3DDEVICE iface,
-					       LPD3DSTATS lpD3DStats)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p): stub\n", This, lpD3DStats);
-  
-  return DD_OK;
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_Execute(LPDIRECT3DDEVICE iface,
-					      LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
-					      LPDIRECT3DVIEWPORT lpDirect3DViewport,
-					      DWORD dwFlags)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p,%p,%08ld): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
-
-  /* Put this as the default context */
-
-  /* Execute... */
-  ((IDirect3DExecuteBufferImpl*)lpDirect3DExecuteBuffer)->execute(lpDirect3DExecuteBuffer, iface, lpDirect3DViewport);
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DDeviceImpl_AddViewport(LPDIRECT3DDEVICE iface,
-						  LPDIRECT3DVIEWPORT lpvp)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-  FIXME("(%p)->(%p): stub\n", This, ilpvp);
-  
-  /* Adds this viewport to the viewport list */
-  ilpvp->next = This->viewport_list;
-  This->viewport_list = ilpvp;
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_DeleteViewport(LPDIRECT3DDEVICE iface,
-						     LPDIRECT3DVIEWPORT lpvp)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-  IDirect3DViewport2Impl *cur, *prev;
-  FIXME("(%p)->(%p): stub\n", This, lpvp);
-  
-  /* Finds this viewport in the list */
-  prev = NULL;
-  cur = This->viewport_list;
-  while ((cur != NULL) && (cur != ilpvp)) {
-    prev = cur;
-    cur = cur->next;
-  }
-  if (cur == NULL)
-    return DDERR_INVALIDOBJECT;
-  
-  /* And remove it */
-  if (prev == NULL)
-    This->viewport_list = cur->next;
-  else
-    prev->next = cur->next;
-  
-  return DD_OK;
-}
-
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_NextViewport(LPDIRECT3DDEVICE iface,
-						   LPDIRECT3DVIEWPORT lpvp,
-						   LPDIRECT3DVIEWPORT* lplpvp,
-						   DWORD dwFlags)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
-  IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
-  FIXME("(%p)->(%p,%p,%08lx): stub\n", This, ilpvp, ilplpvp, dwFlags);
-  
-  switch (dwFlags) {
-  case D3DNEXT_NEXT:
-    *ilplpvp = ilpvp->next;
-    break;
-    
-  case D3DNEXT_HEAD:
-    *ilplpvp = This->viewport_list;
-    break;
-    
-  case D3DNEXT_TAIL:
-    ilpvp = This->viewport_list;
-    while (ilpvp->next != NULL)
-      ilpvp = ilpvp->next;
-    
-    *ilplpvp = ilpvp;
-    break;
-    
-  default:
-    return DDERR_INVALIDPARAMS;
-  }
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DDeviceImpl_Pick(LPDIRECT3DDEVICE iface,
-					   LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
-					   LPDIRECT3DVIEWPORT lpDirect3DViewport,
-					   DWORD dwFlags,
-					   LPD3DRECT lpRect)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p,%p,%08lx,%p): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport,
-	dwFlags, lpRect);
-  
-  return DD_OK;
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_GetPickRecords(LPDIRECT3DDEVICE iface,
-						     LPDWORD lpCount,
-						     LPD3DPICKRECORD lpD3DPickRec)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lpCount, lpD3DPickRec);
-  
-  return DD_OK;
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_EnumTextureFormats(LPDIRECT3DDEVICE iface,
-							 LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
-							 LPVOID lpArg)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lpd3dEnumTextureProc, lpArg);
-  
-  return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg);
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_CreateMatrix(LPDIRECT3DDEVICE iface,
-						   LPD3DMATRIXHANDLE lpD3DMatHandle)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p)\n", This, lpD3DMatHandle);
-
-  *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX));
-  
-  return DD_OK;
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_SetMatrix(LPDIRECT3DDEVICE iface,
-						D3DMATRIXHANDLE d3dMatHandle,
-						const LPD3DMATRIX lpD3DMatrix)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%08lx,%p)\n", This, d3dMatHandle, lpD3DMatrix);
-
-  dump_mat(lpD3DMatrix);
-  
-  *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
-  
-  return DD_OK;
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_GetMatrix(LPDIRECT3DDEVICE iface,
-						D3DMATRIXHANDLE D3DMatHandle,
-						LPD3DMATRIX lpD3DMatrix)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%08lx,%p)\n", This, D3DMatHandle, lpD3DMatrix);
-
-  *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
-  
-  return DD_OK;
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_DeleteMatrix(LPDIRECT3DDEVICE iface,
-						   D3DMATRIXHANDLE d3dMatHandle)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%08lx)\n", This, d3dMatHandle);
-
-  HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle);
-  
-  return DD_OK;
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  /* OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This; */
-  
-  FIXME("(%p)->(): stub\n", This);
-  
-  /* We get the pointer to the surface (should be done on flip) */
-  /* odev->zb->pbuf = This->surface->s.surface_desc.y.lpSurface; */
-  
-  return DD_OK;
-}
-
-
-/* This is for the moment copy-pasted from IDirect3DDevice2...
-   Will make a common function ... */
-static HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-#ifdef USE_OSMESA
-  OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
-  LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
-  DDSURFACEDESC sdesc;
-  int x,y;
-  unsigned char *src;
-  unsigned short *dest;
-#endif
-  
-  FIXME("(%p)->(): stub\n", This);
-
-#ifdef USE_OSMESA
-  /* Here we copy back the OpenGL scene to the the DDraw surface */
-  /* First, lock the surface */
-  IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
-
-  /* The copy the OpenGL buffer to this surface */
-  
-  /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
-     I am currently working on a set of patches for Mesa to have OSMesa support
-     16 bpp surfaces => we will able to render directly onto the surface, no
-     need to do a bpp conversion */
-  dest = (unsigned short *) sdesc.y.lpSurface;
-  src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
-  for (y = 0; y < sdesc.dwHeight; y++) {
-    unsigned char *lsrc = src;
-    
-    for (x = 0; x < sdesc.dwWidth ; x++) {
-      unsigned char r =  *lsrc++;
-      unsigned char g =  *lsrc++;
-      unsigned char b =  *lsrc++;
-      lsrc++; /* Alpha */
-
-      *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
-      
-      dest++;
-    }
-
-    src -= 4 * sdesc.dwWidth;
-  }
-
-  /* Unlock the surface */
-  IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
-#else
-  /* No need to do anything here... */
-#endif
-  
-  return DD_OK;  
-}
-
-
-static HRESULT WINAPI IDirect3DDeviceImpl_GetDirect3D(LPDIRECT3DDEVICE iface,
-						  LPDIRECT3D *lpDirect3D)
-{
-  ICOM_THIS(IDirect3DDeviceImpl,iface);
-  TRACE("(%p)->(%p): stub\n", This, lpDirect3D);
-
-  return DD_OK;
-}
-
-
-
-/*******************************************************************************
- *				Direct3DDevice VTable
- */
-static ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3 = 
-{
-  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-  IDirect3DDeviceImpl_QueryInterface,
-  IDirect3DDeviceImpl_AddRef,
-  IDirect3DDeviceImpl_Release,
-  IDirect3DDeviceImpl_Initialize,
-  IDirect3DDeviceImpl_GetCaps,
-  IDirect3DDeviceImpl_SwapTextureHandles,
-  IDirect3DDeviceImpl_CreateExecuteBuffer,
-  IDirect3DDeviceImpl_GetStats,
-  IDirect3DDeviceImpl_Execute,
-  IDirect3DDeviceImpl_AddViewport,
-  IDirect3DDeviceImpl_DeleteViewport,
-  IDirect3DDeviceImpl_NextViewport,
-  IDirect3DDeviceImpl_Pick,
-  IDirect3DDeviceImpl_GetPickRecords,
-  IDirect3DDeviceImpl_EnumTextureFormats,
-  IDirect3DDeviceImpl_CreateMatrix,
-  IDirect3DDeviceImpl_SetMatrix,
-  IDirect3DDeviceImpl_GetMatrix,
-  IDirect3DDeviceImpl_DeleteMatrix,
-  IDirect3DDeviceImpl_BeginScene,
-  IDirect3DDeviceImpl_EndScene,
-  IDirect3DDeviceImpl_GetDirect3D,
-};
-
-#else /* HAVE_MESAGL */
-
-int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
-  return 0;
-}
-
-int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d)
-{
-  return 0;
-}
-
-int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
-  return 0;
-}
-
-int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device)
-{
-  return 0;
-}
-
-#endif /* HAVE_MESAGL */
diff --git a/dlls/ddraw/d3dexecutebuffer.c b/dlls/ddraw/d3dexecutebuffer.c
index 1a7eb5a..bca7dbe 100644
--- a/dlls/ddraw/d3dexecutebuffer.c
+++ b/dlls/ddraw/d3dexecutebuffer.c
@@ -14,12 +14,12 @@
 #include "d3d.h"
 #include "debugtools.h"
 
-#include "d3d_private.h"
+#include "mesa_private.h"
+
+#define D3DDPRIVATE(x) mesa_d3dd_private *odev=((mesa_d3dd_private*)(x)->private)
 
 DEFAULT_DEBUG_CHANNEL(ddraw)
 
-#ifdef HAVE_MESAGL
-
 /* Structure to store the 'semi transformed' vertices */
 typedef struct {
   D3DVALUE x;
@@ -180,7 +180,7 @@
   /* DWORD il = ilpBuff->data.dwInstructionLength; */
   
   void *instr = ilpBuff->desc.lpData + is;
-  OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) dev;
+  D3DDPRIVATE((IDirect3DDeviceImpl*)dev);
   
   TRACE("ExecuteData : \n");
   if (TRACE_ON(ddraw))
@@ -857,5 +857,3 @@
   IDirect3DExecuteBufferImpl_Validate,
   IDirect3DExecuteBufferImpl_Optimize
 };
-
-#endif /* HAVE_MESAGL */
diff --git a/dlls/ddraw/d3dlight.c b/dlls/ddraw/d3dlight.c
index 0b378b9..71d597b 100644
--- a/dlls/ddraw/d3dlight.c
+++ b/dlls/ddraw/d3dlight.c
@@ -13,11 +13,11 @@
 #include "d3d.h"
 #include "debugtools.h"
 
-#include "d3d_private.h"
+#include "mesa_private.h"
 
 DEFAULT_DEBUG_CHANNEL(ddraw)
-
-#ifdef HAVE_MESAGL
+    
+#define D3DLPRIVATE(x) mesa_d3dl_private*dlpriv=((mesa_d3dl_private*)x->private)
 
 static ICOM_VTABLE(IDirect3DLight) light_vtable;
 
@@ -34,6 +34,7 @@
 };
 
 static void update(IDirect3DLightImpl* This) {
+  D3DLPRIVATE(This);
   switch (This->light.dltType) {
   case D3DLIGHT_POINT:         /* 1 */
     TRACE("Activating POINT\n");
@@ -53,21 +54,15 @@
 	  This->light.dvDirection.z.z);
     _dump_colorvalue(" color    ", This->light.dcvColor);
 
-    glLightfv(This->light_num,
-	      GL_AMBIENT,
-	      (float *) zero_value);
-
-    glLightfv(This->light_num,
-	      GL_DIFFUSE,
-	      (float *) &(This->light.dcvColor));
+    glLightfv(dlpriv->light_num, GL_AMBIENT, (float *) zero_value);
+    glLightfv(dlpriv->light_num, GL_DIFFUSE, (float *) &(This->light.dcvColor));
 
     direction[0] = -This->light.dvDirection.x.x;
     direction[1] = -This->light.dvDirection.y.y;
     direction[2] = -This->light.dvDirection.z.z;
     direction[3] = 0.0; /* This is a directional light */
-    glLightfv(This->light_num,
-	      GL_POSITION,
-	      (float *) direction);
+
+    glLightfv(dlpriv->light_num, GL_POSITION, (float *) direction);
   } break;
     
   case D3DLIGHT_PARALLELPOINT:  /* 4 */
@@ -75,19 +70,19 @@
     break;
 
   default:
-    TRACE("Not a know Light Type\n");
+    TRACE("Not a known Light Type: %d\n",This->light.dltType);
     break;
   }
 }
 
 static void activate(IDirect3DLightImpl* This) {
+  D3DLPRIVATE(This);
+
   ENTER_GL();
   update(This);
-
   /* If was not active, activate it */
   if (This->is_active == 0) {
-    glEnable(This->light_num);
-
+    glEnable(dlpriv->light_num);
     This->is_active = 1;
   }
   LEAVE_GL();
@@ -254,18 +249,3 @@
   IDirect3DLightImpl_SetLight,
   IDirect3DLightImpl_GetLight
 };
-
-#else /* HAVE_MESAGL */
-
-/* These function should never be called if MesaGL is not present */
-LPDIRECT3DLIGHT d3dlight_create_dx3(IDirect3DImpl* d3d1) {
-  ERR("Should not be called...\n");
-  return NULL;
-}
-
-LPDIRECT3DLIGHT d3dlight_create(IDirect3D2Impl* d3d2) {
-  ERR("Should not be called...\n");
-  return NULL;
-}
-
-#endif /* HAVE_MESAGL */
diff --git a/dlls/ddraw/d3dmaterial.c b/dlls/ddraw/d3dmaterial.c
index 911619c..d025efd 100644
--- a/dlls/ddraw/d3dmaterial.c
+++ b/dlls/ddraw/d3dmaterial.c
@@ -12,12 +12,10 @@
 #include "d3d.h"
 #include "debugtools.h"
 
-#include "d3d_private.h"
+#include "mesa_private.h"
 
 DEFAULT_DEBUG_CHANNEL(ddraw)
 
-#ifdef HAVE_MESAGL
-
 static ICOM_VTABLE(IDirect3DMaterial2) material2_vtable;
 static ICOM_VTABLE(IDirect3DMaterial) material_vtable;
 
@@ -250,18 +248,3 @@
   IDirect3DMaterial2Impl_GetMaterial,
   IDirect3DMaterial2Impl_GetHandle
 };
-
-#else /* HAVE_MESAGL */
-
-LPDIRECT3DMATERIAL d3dmaterial_create(IDirect3DImpl* d3d1) {
-  ERR("Should not be called...\n");
-  return NULL;
-}
-
-LPDIRECT3DMATERIAL2 d3dmaterial2_create(IDirect3D2Impl* d3d2) {
-  ERR("Should not be called...\n");
-  return NULL;
-}
-
-
-#endif /* HAVE_MESAGL */
diff --git a/dlls/ddraw/d3dtexture.c b/dlls/ddraw/d3dtexture.c
index 34ff0ae..b05570c 100644
--- a/dlls/ddraw/d3dtexture.c
+++ b/dlls/ddraw/d3dtexture.c
@@ -14,12 +14,13 @@
 #include "d3d.h"
 #include "debugtools.h"
 
-#include "d3d_private.h"
+#include "mesa_private.h"
+
+#define D3DDPRIVATE(x) mesa_d3dd_private*odev=(mesa_d3dd_private*)(x)->private
+#define D3DTPRIVATE(x) mesa_d3dt_private*dtpriv=(mesa_d3dt_private*)(x)->private
 
 DEFAULT_DEBUG_CHANNEL(ddraw)
 
-#ifdef HAVE_MESAGL
-
 /* Define this if you want to save to a file all the textures used by a game
    (can be funny to see how they managed to cram all the pictures in
    texture memory) */
@@ -34,7 +35,7 @@
 	char buf[32];										\
 	int x, y;										\
 												\
-	sprintf(buf, "%ld.pnm", This->tex_name);							\
+	sprintf(buf, "%ld.pnm", dtpriv->tex_name);							\
 	f = fopen(buf, "wb");									\
 	fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);			\
 	for (y = 0; y < src_d->dwHeight; y++) {							\
@@ -54,7 +55,7 @@
 	    char buf[32];										\
 	    int x, y;											\
 	    												\
-	    sprintf(buf, "%ld.pnm", This->tex_name);							\
+	    sprintf(buf, "%ld.pnm", dtpriv->tex_name);							\
 	    f = fopen(buf, "wb");									\
 	    fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);				\
 	    for (y = 0; y < src_d->dwHeight; y++) {							\
@@ -74,7 +75,7 @@
 	    char buf[32];										\
 	    int x, y;											\
 	    												\
-	    sprintf(buf, "%ld.pnm", This->tex_name);							\
+	    sprintf(buf, "%ld.pnm", dtpriv->tex_name);							\
 	    f = fopen(buf, "wb");									\
 	    fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight);				\
 	    for (y = 0; y < src_d->dwHeight; y++) {							\
@@ -132,6 +133,7 @@
 HRESULT WINAPI  SetColorKey_cb(IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
 {
   DDSURFACEDESC	*tex_d;
+  D3DTPRIVATE(texture);
   int bpp;
   GLuint current_texture;
   
@@ -148,12 +150,12 @@
   glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
 
   /* If the GetHandle was not done yet, it's an error */
-  if (texture->tex_name == 0) {
+  if (dtpriv->tex_name == 0) {
     ERR("Unloaded texture !\n");
     LEAVE_GL();
     return DD_OK;
   }
-  glBindTexture(GL_TEXTURE_2D, texture->tex_name);
+  glBindTexture(GL_TEXTURE_2D, dtpriv->tex_name);
 
   if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
     FIXME("Todo Paletted\n");
@@ -219,7 +221,7 @@
  *				IDirect3DTexture2 methods
  */
 
-static HRESULT WINAPI IDirect3DTexture2Impl_QueryInterface(LPDIRECT3DTEXTURE2 iface,
+HRESULT WINAPI IDirect3DTexture2Impl_QueryInterface(LPDIRECT3DTEXTURE2 iface,
 							REFIID riid,
 							LPVOID* ppvObj)
 {
@@ -232,7 +234,7 @@
 
 
 
-static ULONG WINAPI IDirect3DTexture2Impl_AddRef(LPDIRECT3DTEXTURE2 iface)
+ULONG WINAPI IDirect3DTexture2Impl_AddRef(LPDIRECT3DTEXTURE2 iface)
 {
   ICOM_THIS(IDirect3DTexture2Impl,iface);
   TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
@@ -242,15 +244,16 @@
 
 
 
-static ULONG WINAPI IDirect3DTexture2Impl_Release(LPDIRECT3DTEXTURE2 iface)
+ULONG WINAPI IDirect3DTexture2Impl_Release(LPDIRECT3DTEXTURE2 iface)
 {
   ICOM_THIS(IDirect3DTexture2Impl,iface);
+  D3DTPRIVATE(This);
   FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
   
   if (!--(This->ref)) {
     /* Delete texture from OpenGL */
     ENTER_GL();
-    glDeleteTextures(1, &(This->tex_name));
+    glDeleteTextures(1, &(dtpriv->tex_name));
     LEAVE_GL();
     
     /* Release surface */
@@ -264,30 +267,31 @@
 }
 
 /*** IDirect3DTexture methods ***/
-static HRESULT WINAPI IDirect3DTextureImpl_GetHandle(LPDIRECT3DTEXTURE iface,
+HRESULT WINAPI IDirect3DTextureImpl_GetHandle(LPDIRECT3DTEXTURE iface,
 						 LPDIRECT3DDEVICE lpD3DDevice,
 						 LPD3DTEXTUREHANDLE lpHandle)
 {
-  ICOM_THIS(IDirect3DTexture2Impl,iface);
-  IDirect3DDeviceImpl* ilpD3DDevice=(IDirect3DDeviceImpl*)lpD3DDevice;
-  FIXME("(%p)->(%p,%p): stub\n", This, ilpD3DDevice, lpHandle);
+    ICOM_THIS(IDirect3DTexture2Impl,iface);
+    D3DTPRIVATE(This);
+    IDirect3DDeviceImpl* ilpD3DDevice=(IDirect3DDeviceImpl*)lpD3DDevice;
+    FIXME("(%p)->(%p,%p): stub\n", This, ilpD3DDevice, lpHandle);
 
-  *lpHandle = (D3DTEXTUREHANDLE) This;
-  
-  /* Now, bind a new texture */
-  ENTER_GL();
-  ilpD3DDevice->set_context(ilpD3DDevice);
-  This->D3Ddevice = (void *) ilpD3DDevice;
-  if (This->tex_name == 0)
-    glGenTextures(1, &(This->tex_name));
-  LEAVE_GL();
+    *lpHandle = (D3DTEXTUREHANDLE) This;
 
-  TRACE("OpenGL texture handle is : %ld\n", This->tex_name);
-  
-  return D3D_OK;
+    /* Now, bind a new texture */
+    ENTER_GL();
+    ilpD3DDevice->set_context(ilpD3DDevice);
+    This->D3Ddevice = (void *) ilpD3DDevice;
+    if (dtpriv->tex_name == 0)
+	glGenTextures(1, &(dtpriv->tex_name));
+    LEAVE_GL();
+
+    TRACE("OpenGL texture handle is : %d\n", dtpriv->tex_name);
+
+    return D3D_OK;
 }
 
-static HRESULT WINAPI IDirect3DTextureImpl_Initialize(LPDIRECT3DTEXTURE iface,
+HRESULT WINAPI IDirect3DTextureImpl_Initialize(LPDIRECT3DTEXTURE iface,
 						  LPDIRECT3DDEVICE lpD3DDevice,
 						  LPDIRECTDRAWSURFACE lpSurface)
 {
@@ -297,7 +301,7 @@
   return DDERR_ALREADYINITIALIZED;
 }
 
-static HRESULT WINAPI IDirect3DTextureImpl_Unload(LPDIRECT3DTEXTURE iface)
+HRESULT WINAPI IDirect3DTextureImpl_Unload(LPDIRECT3DTEXTURE iface)
 {
   ICOM_THIS(IDirect3DTexture2Impl,iface);
   FIXME("(%p)->(): stub\n", This);
@@ -306,35 +310,35 @@
 }
 
 /*** IDirect3DTexture2 methods ***/
-static HRESULT WINAPI IDirect3DTexture2Impl_GetHandle(LPDIRECT3DTEXTURE2 iface,
+HRESULT WINAPI IDirect3DTexture2Impl_GetHandle(LPDIRECT3DTEXTURE2 iface,
 						  LPDIRECT3DDEVICE2 lpD3DDevice2,
 						  LPD3DTEXTUREHANDLE lpHandle)
 {
-  ICOM_THIS(IDirect3DTexture2Impl,iface);
-  IDirect3DDevice2Impl* ilpD3DDevice2=(IDirect3DDevice2Impl*)lpD3DDevice2;
-  TRACE("(%p)->(%p,%p)\n", This, ilpD3DDevice2, lpHandle);
+    ICOM_THIS(IDirect3DTexture2Impl,iface);
+    D3DTPRIVATE(This);
+    IDirect3DDevice2Impl* ilpD3DDevice2=(IDirect3DDevice2Impl*)lpD3DDevice2;
+    TRACE("(%p)->(%p,%p)\n", This, ilpD3DDevice2, lpHandle);
 
-  /* For 32 bits OSes, handles = pointers */
-  *lpHandle = (D3DTEXTUREHANDLE) This;
-  
-  /* Now, bind a new texture */
-  ENTER_GL();
-  ilpD3DDevice2->set_context(ilpD3DDevice2);
-  This->D3Ddevice = (void *) ilpD3DDevice2;
-  if (This->tex_name == 0)
-  glGenTextures(1, &(This->tex_name));
-  LEAVE_GL();
+    /* For 32 bits OSes, handles = pointers */
+    *lpHandle = (D3DTEXTUREHANDLE) This;
 
-  TRACE("OpenGL texture handle is : %ld\n", This->tex_name);
-  
-  return D3D_OK;
+    /* Now, bind a new texture */
+    ENTER_GL();
+    ilpD3DDevice2->set_context(ilpD3DDevice2);
+    This->D3Ddevice = (void *) ilpD3DDevice2;
+    if (dtpriv->tex_name == 0)
+	glGenTextures(1, &(dtpriv->tex_name));
+    LEAVE_GL();
+
+    TRACE("OpenGL texture handle is : %d\n", dtpriv->tex_name);
+
+    return D3D_OK;
 }
 
 /* Common methods */
-static HRESULT WINAPI IDirect3DTexture2Impl_PaletteChanged(LPDIRECT3DTEXTURE2 iface,
-						       DWORD dwStart,
-						       DWORD dwCount)
-{
+HRESULT WINAPI IDirect3DTexture2Impl_PaletteChanged(
+    LPDIRECT3DTEXTURE2 iface, DWORD dwStart, DWORD dwCount
+) {
   ICOM_THIS(IDirect3DTexture2Impl,iface);
   FIXME("(%p)->(%8ld,%8ld): stub\n", This, dwStart, dwCount);
 
@@ -343,10 +347,11 @@
 
 /* NOTE : if you experience crashes in this function, you must have a buggy
           version of Mesa. See the file d3dtexture.c for a cure */
-static HRESULT WINAPI IDirect3DTexture2Impl_Load(LPDIRECT3DTEXTURE2 iface,
-					     LPDIRECT3DTEXTURE2 lpD3DTexture2)
-{
+HRESULT WINAPI IDirect3DTexture2Impl_Load(
+    LPDIRECT3DTEXTURE2 iface, LPDIRECT3DTEXTURE2 lpD3DTexture2
+) {
   ICOM_THIS(IDirect3DTexture2Impl,iface);
+  D3DTPRIVATE(This);
   IDirect3DTexture2Impl* ilpD3DTexture2=(IDirect3DTexture2Impl*)lpD3DTexture2;
   DDSURFACEDESC	*src_d, *dst_d;
   TRACE("(%p)->(%p)\n", This, ilpD3DTexture2);
@@ -387,9 +392,9 @@
     glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
 
     /* If the GetHandle was not done, get the texture name here */
-    if (This->tex_name == 0)
-      glGenTextures(1, &(This->tex_name));
-    glBindTexture(GL_TEXTURE_2D, This->tex_name);
+    if (dtpriv->tex_name == 0)
+      glGenTextures(1, &(dtpriv->tex_name));
+    glBindTexture(GL_TEXTURE_2D, dtpriv->tex_name);
 
     if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
       /* ****************
@@ -530,7 +535,7 @@
 /*******************************************************************************
  *				IDirect3DTexture2 VTable
  */
-static ICOM_VTABLE(IDirect3DTexture2) texture2_vtable = 
+ICOM_VTABLE(IDirect3DTexture2) mesa_texture2_vtable = 
 {
   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
   /*** IUnknown methods ***/
@@ -546,7 +551,7 @@
 /*******************************************************************************
  *				IDirect3DTexture VTable
  */
-static ICOM_VTABLE(IDirect3DTexture) texture_vtable = 
+ICOM_VTABLE(IDirect3DTexture) mesa_texture_vtable = 
 {
   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
   /*** IUnknown methods ***/
@@ -560,18 +565,3 @@
   IDirect3DTexture2Impl_Load,
   IDirect3DTextureImpl_Unload
 };
-
-#else /* HAVE_MESAGL */
-
-/* These function should never be called if MesaGL is not present */
-LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurface4Impl* surf) {
-  ERR("Should not be called...\n");
-  return NULL;
-}
-
-LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurface4Impl* surf) {
-  ERR("Should not be called...\n");
-  return NULL;
-}
-
-#endif /* HAVE_MESAGL */
diff --git a/dlls/ddraw/dclipper/main.c b/dlls/ddraw/dclipper/main.c
new file mode 100644
index 0000000..5bb6f37
--- /dev/null
+++ b/dlls/ddraw/dclipper/main.c
@@ -0,0 +1,137 @@
+/*		DirectDrawClipper implementation
+ *
+ * Copyright 2000 Marcus Meissner
+ */
+
+#include "config.h"
+#include "winerror.h"
+
+#include <unistd.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "debugtools.h"
+#include "ddraw_private.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+/******************************************************************************
+ *			DirectDrawCreateClipper (DDRAW.7)
+ */
+HRESULT WINAPI DirectDrawCreateClipper(
+    DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter
+) {
+    IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
+    TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
+
+    *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
+    ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
+    (*ilplpDDClipper)->ref = 1;
+    (*ilplpDDClipper)->hWnd = 0; 
+    return DD_OK;
+}
+
+/******************************************************************************
+ *			IDirectDrawClipper
+ */
+static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
+    LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
+) {
+    ICOM_THIS(IDirectDrawClipperImpl,iface);
+
+    TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
+    if( dwFlags ) {
+	FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
+	return DDERR_INVALIDPARAMS; 
+    }
+
+    This->hWnd = hWnd;
+    return DD_OK;
+}
+
+static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
+    ICOM_THIS(IDirectDrawClipperImpl,iface);
+    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+
+    This->ref--;
+    if (This->ref)
+	return This->ref;
+    HeapFree(GetProcessHeap(),0,This);
+    return S_OK;
+}
+
+static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
+    LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
+) {
+    ICOM_THIS(IDirectDrawClipperImpl,iface);
+    FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
+    if (hmm) *hmm=0;
+    return DD_OK;
+}
+
+static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
+    LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
+) {
+    ICOM_THIS(IDirectDrawClipperImpl,iface);
+    FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
+    return DD_OK;
+}
+
+static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
+    LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
+) {
+    ICOM_THIS(IDirectDrawClipperImpl,iface);
+    FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
+    return OLE_E_ENUM_NOMORE;
+}
+
+static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
+{
+    ICOM_THIS(IDirectDrawClipperImpl,iface);
+    TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
+    return ++(This->ref);
+}
+
+static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
+    LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
+) {
+    ICOM_THIS(IDirectDrawClipperImpl,iface);
+    FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
+
+    *hWndPtr = This->hWnd; 
+
+    return DD_OK;
+}
+
+static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
+     LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
+) {
+    ICOM_THIS(IDirectDrawClipperImpl,iface);
+    FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
+    return DD_OK;
+}
+
+static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
+    LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
+) {
+    ICOM_THIS(IDirectDrawClipperImpl,iface);
+    FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
+    return DD_OK;
+}
+
+ICOM_VTABLE(IDirectDrawClipper) ddclipvt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IDirectDrawClipperImpl_QueryInterface,
+    IDirectDrawClipperImpl_AddRef,
+    IDirectDrawClipperImpl_Release,
+    IDirectDrawClipperImpl_GetClipList,
+    IDirectDrawClipperImpl_GetHWnd,
+    IDirectDrawClipperImpl_Initialize,
+    IDirectDrawClipperImpl_IsClipListChanged,
+    IDirectDrawClipperImpl_SetClipList,
+    IDirectDrawClipperImpl_SetHwnd
+};
diff --git a/dlls/ddraw/ddraw.spec b/dlls/ddraw/ddraw.spec
index ec39e94..d5052b7 100644
--- a/dlls/ddraw/ddraw.spec
+++ b/dlls/ddraw/ddraw.spec
@@ -1,11 +1,15 @@
 name ddraw
 type win32
 
+import kernel32.dll
+import user32.dll
+import ole32.dll
+
 @ stub DDHAL32_VidMemAlloc
 @ stub DDHAL32_VidMemFree
 @ stub DDInternalLock
 @ stub DDInternalUnlock
-@ stdcall DSoundHelp(long long long) DSoundHelp
+@ stub DSoundHelp
 @ stdcall DirectDrawCreate(ptr ptr ptr) DirectDrawCreate
 @ stdcall DirectDrawCreateClipper(long ptr ptr) DirectDrawCreateClipper
 @ stdcall DirectDrawEnumerateA(ptr ptr) DirectDrawEnumerateA
diff --git a/dlls/ddraw/ddraw/dga.c b/dlls/ddraw/ddraw/dga.c
new file mode 100644
index 0000000..fcee086
--- /dev/null
+++ b/dlls/ddraw/ddraw/dga.c
@@ -0,0 +1,894 @@
+/*		DirectDraw IDirectDraw XF86DGA interface
+ *
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
+ */
+/* XF86DGA:
+ * When DirectVideo mode is enabled you can no longer use 'normal' X 
+ * applications nor can you switch to a virtual console. Also, enabling
+ * only works, if you have switched to the screen where the application
+ * is running.
+ * Some ways to debug this stuff are:
+ * - A terminal connected to the serial port. Can be bought used for cheap.
+ *   (This is the method I am using.)
+ * - Another machine connected over some kind of network.
+ */
+
+/*
+ * This file contains the XF86 DGA specific interface functions.
+ * We are 'allowed' to call X11 specific IDirectDraw functions.
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "winerror.h"
+#include "wine/exception.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debugtools.h"
+#include "message.h"
+#include "options.h"
+#include "monitor.h"
+
+#define RESTORE_SIGNALS
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+#include "dga_private.h"
+
+struct ICOM_VTABLE(IDirectDraw)		dga_ddvt;
+struct ICOM_VTABLE(IDirectDraw2)	dga_dd2vt;
+struct ICOM_VTABLE(IDirectDraw4)	dga_dd4vt;
+
+#ifdef HAVE_LIBXXF86VM
+static XF86VidModeModeInfo *orig_mode = NULL;
+#endif
+
+#define DDPRIVATE(x) dga_dd_private *ddpriv = ((dga_dd_private*)(x)->private)
+#define DPPRIVATE(x) dga_dp_private *dppriv = ((dga_dp_private*)(x)->private)
+
+/*******************************************************************************
+ *				IDirectDraw
+ */
+static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
+    LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,
+    IUnknown *lpunk
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    IDirectDrawSurfaceImpl* dsurf;
+    DDPRIVATE(This);
+    dga_ds_private *dspriv;
+    int	i, fbheight = ddpriv->fb_height;
+
+    TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,lpdsf,lpunk);
+    if (TRACE_ON(ddraw)) _dump_surface_desc(lpddsd);
+
+    *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(
+    	GetProcessHeap(),
+	HEAP_ZERO_MEMORY,
+	sizeof(IDirectDrawSurfaceImpl)
+    );
+    dsurf = *(IDirectDrawSurfaceImpl**)lpdsf;
+    dsurf->private = (dga_ds_private*)HeapAlloc(
+	GetProcessHeap(),
+	HEAP_ZERO_MEMORY,
+	sizeof(dga_ds_private)
+    );
+    dspriv = (dga_ds_private*)dsurf->private;
+    IDirectDraw2_AddRef(iface);
+
+    dsurf->ref = 1;
+#ifdef HAVE_LIBXXF86DGA2
+    if (ddpriv->version == 2)
+      ICOM_VTBL(dsurf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt;
+    else
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+      ICOM_VTBL(dsurf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
+    dsurf->s.ddraw = This;
+    dsurf->s.palette = NULL;
+    dspriv->fb_height = -1; /* This is to have non-on screen surfaces freed */
+    dsurf->s.lpClipper = NULL;
+
+    /* Copy the surface description */
+    dsurf->s.surface_desc = *lpddsd;
+
+    if (!(lpddsd->dwFlags & DDSD_WIDTH))
+	dsurf->s.surface_desc.dwWidth  = This->d.width;
+    if (!(lpddsd->dwFlags & DDSD_HEIGHT))
+	dsurf->s.surface_desc.dwHeight = This->d.height;
+
+    dsurf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
+
+    /* Check if this a 'primary surface' or not */
+    if ((lpddsd->dwFlags & DDSD_CAPS) &&
+	(lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
+	/* This is THE primary surface => there is DGA-specific code */
+
+	/* Find a viewport */
+	for (i=0;i<32;i++)
+	    if (!(ddpriv->vpmask & (1<<i)))
+		break;
+	TRACE("using viewport %d for a primary surface\n",i);
+	/* if i == 32 or maximum ... return error */
+	ddpriv->vpmask|=(1<<i);
+	lpddsd->lPitch = dsurf->s.surface_desc.lPitch = 
+		ddpriv->fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
+
+	dsurf->s.surface_desc.u1.lpSurface =
+	    ddpriv->fb_addr + i*fbheight*lpddsd->lPitch;
+
+	dspriv->fb_height = i*fbheight;
+
+	/* Add flags if there were not present */
+	dsurf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
+	dsurf->s.surface_desc.dwWidth = This->d.width;
+	dsurf->s.surface_desc.dwHeight = This->d.height;
+	TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
+	/* We put our surface always in video memory */
+	SDDSCAPS(dsurf) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
+	dsurf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
+	dsurf->s.chain = NULL;
+
+	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
+	    IDirectDrawSurface4Impl*	back;
+	    dga_ds_private		*bspriv;
+	    int	bbc;
+
+	    for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
+	        int i;
+	      
+		back = (IDirectDrawSurface4Impl*)HeapAlloc(
+		    GetProcessHeap(),
+		    HEAP_ZERO_MEMORY,
+		    sizeof(IDirectDrawSurface4Impl)
+		);
+		IDirectDraw2_AddRef(iface);
+		back->ref = 1;
+		ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
+		back->private = HeapAlloc(
+			GetProcessHeap(),
+			HEAP_ZERO_MEMORY,
+			sizeof(dga_ds_private)
+		);
+		bspriv = (dga_ds_private*)back->private;
+
+		for (i=0;i<32;i++)
+		    if (!(ddpriv->vpmask & (1<<i)))
+			break;
+		TRACE("using viewport %d for backbuffer %d\n",i, bbc);
+		/* if i == 32 or maximum ... return error */
+		ddpriv->vpmask|=(1<<i);
+
+		bspriv->fb_height = i*fbheight;
+		/* Copy the surface description from the front buffer */
+		back->s.surface_desc = dsurf->s.surface_desc;
+		/* Change the parameters that are not the same */
+		back->s.surface_desc.u1.lpSurface =
+		    ddpriv->fb_addr + i*fbheight*lpddsd->lPitch;
+
+		back->s.ddraw = This;
+		/* Add relevant info to front and back buffers */
+		/* FIXME: backbuffer/frontbuffer handling broken here, but
+		 * will be fixed up in _Flip().
+		 */
+		SDDSCAPS(dsurf) |= DDSCAPS_FRONTBUFFER;
+		SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
+		back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
+		SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
+		IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*lpdsf),(LPDIRECTDRAWSURFACE4)back);
+	    }
+	}
+    } else {
+	/* There is no DGA-specific code here...
+	 * Go to the common surface creation function
+	 */
+	return common_off_screen_CreateSurface(This, dsurf);
+    }
+    return DD_OK;
+}
+
+#ifdef HAVE_LIBXXF86DGA2
+static HRESULT WINAPI DGA_IDirectDraw2Impl_SetCooperativeLevel(
+    LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    HRESULT ret;
+    int evbase, erbase;
+
+    ret = IDirectDraw2Impl_SetCooperativeLevel(iface, hwnd, cooplevel);
+
+    if (ddpriv->version != 2) {
+	return ret;
+    } else {
+	if (ret != DD_OK)
+	  return ret;
+
+	TSXDGAQueryExtension(display, &evbase, &erbase);
+
+	/* Now, start handling of DGA events giving the handle to the DDraw window
+	   as the window for which the event will be reported */
+	TSXDGASelectInput(display, DefaultScreen(display),
+			  KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
+	X11DRV_EVENT_SetDGAStatus(hwnd, evbase);
+	return DD_OK;
+    }
+}
+#endif
+
+#ifdef HAVE_LIBXXF86DGA2
+static void _DGA_Initialize_FrameBuffer(IDirectDrawImpl *This, int mode) {
+    DDPIXELFORMAT *pf = &(This->d.directdraw_pixelformat);
+
+    /* Now, get the device / mode description */
+    ddpriv->dev = TSXDGASetMode(display, DefaultScreen(display), mode);
+
+    ddpriv->fb_width = ddpriv->dev->mode.imageWidth;
+    TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
+    ddpriv->fb_height = ddpriv->dev->mode.viewportHeight;
+    TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
+	ddpriv->dev->data,
+	ddpriv->dev->mode.imageWidth,
+	(ddpriv->dev->mode.imageWidth *
+	 ddpriv->dev->mode.imageHeight *
+	 (ddpriv->dev->mode.bitsPerPixel / 8))
+    );
+    TRACE("viewport height: %d\n", ddpriv->dev->mode.viewportHeight);
+    /* Get the screen dimensions as seen by Wine.
+     * In that case, it may be better to ignore the -desktop mode and return the
+     * real screen size => print a warning */
+    This->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
+    This->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
+    ddpriv->fb_addr = ddpriv->dev->data;
+    ddpriv->fb_memsize = (ddpriv->dev->mode.imageWidth *
+			      ddpriv->dev->mode.imageHeight *
+			      (ddpriv->dev->mode.bitsPerPixel / 8));
+    ddpriv->vpmask = 0;
+
+    /* Fill the screen pixelformat */
+    pf->dwSize = sizeof(DDPIXELFORMAT);
+    pf->dwFourCC = 0;
+    pf->u.dwRGBBitCount = ddpriv->dev->mode.bitsPerPixel;
+    if (ddpriv->dev->mode.depth == 8) {
+	pf->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
+	pf->u1.dwRBitMask = 0;
+	pf->u2.dwGBitMask = 0;
+	pf->u3.dwBBitMask = 0;
+    } else {
+	pf->dwFlags = DDPF_RGB;
+	pf->u1.dwRBitMask = ddpriv->dev->mode.redMask;
+	pf->u2.dwGBitMask = ddpriv->dev->mode.greenMask;
+	pf->u3.dwBBitMask = ddpriv->dev->mode.blueMask;
+    }
+    pf->u4.dwRGBAlphaBitMask= 0;
+    This->d.screen_pixelformat = *pf; 
+}
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+
+static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
+    LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
+) {
+    ICOM_THIS(IDirectDrawImpl,iface);
+    DDPRIVATE(This);
+    int	i,mode_count;
+
+    TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
+
+#ifdef HAVE_LIBXXF86DGA2
+    if (ddpriv->version == 2) {
+	XDGAMode *modes = ddpriv->modes;
+	int mode_to_use = -1;
+
+	/* Search in the list a display mode that corresponds to what is requested */
+	for (i = 0; i < ddpriv->num_modes; i++) {
+	    if ((height == modes[i].viewportHeight) &&
+		(width == modes[i].viewportWidth) &&
+		(depth == modes[i].depth)
+	    )
+		mode_to_use = modes[i].num;
+	}
+
+	if (mode_to_use < 0) {
+	    ERR("Could not find matching mode !!!\n");
+	    return DDERR_UNSUPPORTEDMODE;
+	} else {
+	    TRACE("Using mode number %d\n", mode_to_use);
+
+	    TSXDGACloseFramebuffer(display, DefaultScreen(display));
+
+	    if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
+		ERR("Error opening the frame buffer !!!\n");
+		return DDERR_GENERIC;
+	    }
+
+	    /* Initialize the frame buffer */
+	    _DGA_Initialize_FrameBuffer(This, mode_to_use);
+
+	    /* Re-get (if necessary) the DGA events */
+	    TSXDGASelectInput(display, DefaultScreen(display),
+		KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
+	}
+
+	return DD_OK;
+    }
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+
+    /* We hope getting the asked for depth */
+    if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
+	/* I.e. no visual found or emulated */
+	ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
+	return DDERR_UNSUPPORTEDMODE;
+    }
+
+    if (This->d.width < width) {
+	ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
+	return DDERR_UNSUPPORTEDMODE;
+    }
+    This->d.width	= width;
+    This->d.height	= height;
+
+    /* adjust fb_height, so we don't overlap */
+    if (ddpriv->fb_height < height)
+	ddpriv->fb_height = height;
+    _common_IDirectDrawImpl_SetDisplayMode(This);
+
+#ifdef HAVE_LIBXXF86VM
+#ifdef HAVE_LIBXXF86DGA2
+    if (ddpriv->version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+    {
+	XF86VidModeModeInfo **all_modes, *vidmode = NULL;
+	XF86VidModeModeLine mod_tmp;
+	/* int dotclock_tmp; */
+
+	/* save original video mode and set fullscreen if available*/
+	orig_mode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));  
+	TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
+	orig_mode->hdisplay = mod_tmp.hdisplay; 
+	orig_mode->hsyncstart = mod_tmp.hsyncstart;
+	orig_mode->hsyncend = mod_tmp.hsyncend; 
+	orig_mode->htotal = mod_tmp.htotal;
+	orig_mode->vdisplay = mod_tmp.vdisplay; 
+	orig_mode->vsyncstart = mod_tmp.vsyncstart;
+	orig_mode->vsyncend = mod_tmp.vsyncend; 
+	orig_mode->vtotal = mod_tmp.vtotal;
+	orig_mode->flags = mod_tmp.flags; 
+	orig_mode->private = mod_tmp.private;
+
+	TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
+	for (i=0;i<mode_count;i++) {
+	    if (all_modes[i]->hdisplay == width &&
+		all_modes[i]->vdisplay == height
+	    ) {
+		vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
+		*vidmode = *(all_modes[i]);
+		break;
+	    } else
+		TSXFree(all_modes[i]->private);
+	}
+	for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
+	    TSXFree(all_modes);
+
+	if (!vidmode)
+	    WARN("Fullscreen mode not available!\n");
+
+	if (vidmode) {
+	    TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
+	    TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
+#if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
+	    TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
+#endif
+	}
+    }
+#endif
+
+    /* FIXME: this function OVERWRITES several signal handlers. 
+     * can we save them? and restore them later? In a way that
+     * it works for the library too?
+     */
+    TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
+    TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
+
+#ifdef RESTORE_SIGNALS
+    SIGNAL_Init();
+#endif
+    return DD_OK;
+}
+
+static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
+    LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    DDPRIVATE(This);
+
+    TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
+    if (!caps1 && !caps2)
+       return DDERR_INVALIDPARAMS;
+    if (caps1) {
+	caps1->dwVidMemTotal = ddpriv->fb_memsize;
+	caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);		/* we can do anything */
+	caps1->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
+    }
+    if (caps2) {
+	caps2->dwVidMemTotal = ddpriv->fb_memsize;
+	caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);		/* we can do anything */
+	caps2->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
+    }
+    return DD_OK;
+}
+
+static void fill_caps(LPDDCAPS caps) {
+    /* This function tries to fill the capabilities of Wine's DDraw
+     * implementation. Needs to be fixed, though.. */
+    if (caps == NULL)
+	return;
+
+    caps->dwSize = sizeof(*caps);
+    caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM |  DDCAPS_COLORKEY | DDCAPS_PALETTE /*| DDCAPS_NOHARDWARE*/;
+    caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
+    caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
+    caps->dwFXCaps = 0;
+    caps->dwFXAlphaCaps = 0;
+    caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
+    caps->dwSVCaps = 0;
+    caps->dwZBufferBitDepths = DDBD_16;
+    /* I put here 8 Mo so that D3D applications will believe they have enough
+     * memory to put textures in video memory.
+     * BTW, is this only frame buffer memory or also texture memory (for Voodoo
+     * boards for example) ?
+     */
+    caps->dwVidMemTotal = 8192 * 1024;
+    caps->dwVidMemFree = 8192 * 1024;
+    /* These are all the supported capabilities of the surfaces */
+    caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
+    DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
+      /*DDSCAPS_OVERLAY |*/ DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
+	DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
+#ifdef HAVE_MESAGL
+    caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
+    caps->dwCaps2 |=  DDCAPS2_NO2DDURING3DSCENE;
+    caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
+#endif
+}
+
+static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
+    LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    IDirectDrawPaletteImpl*	ddpal;
+    dga_dp_private		*dppriv;
+    HRESULT			res;
+    int 			xsize = 0,i;
+
+    TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,lpddpal,lpunk);
+    res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,(IDirectDrawPaletteImpl**)lpddpal,lpunk,&xsize);
+    if (res != 0)
+	return res;
+    ddpal = *(IDirectDrawPaletteImpl**)lpddpal;
+    ddpal->private = HeapAlloc(
+	GetProcessHeap(),
+	HEAP_ZERO_MEMORY,
+	sizeof(dga_dp_private)
+    );
+    dppriv = (dga_dp_private*)ddpal->private;
+
+    ICOM_VTBL(ddpal)= &dga_ddpalvt;
+    if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
+	dppriv->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
+    } else {
+	ERR("why are we doing CreatePalette in hi/truecolor?\n");
+	dppriv->cm = 0;
+    }
+    if (dppriv->cm && xsize) {
+	for (i=0;i<xsize;i++) {
+	    XColor xc;
+
+	    xc.red = ddpal->palents[i].peRed<<8;
+	    xc.blue = ddpal->palents[i].peBlue<<8;
+	    xc.green = ddpal->palents[i].peGreen<<8;
+	    xc.flags = DoRed|DoBlue|DoGreen;
+	    xc.pixel = i;
+	    TSXStoreColor(display,dppriv->cm,&xc);
+	}
+    }
+    return DD_OK;
+}
+
+static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->()\n",This);
+    Sleep(1000);
+    TSXF86DGADirectVideo(display,DefaultScreen(display),0);
+#ifdef RESTORE_SIGNALS
+    SIGNAL_Init();
+#endif
+    return DD_OK;
+}
+
+static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+
+    if (!--(This->ref)) {
+#ifdef HAVE_LIBXXF86DGA2
+       if (ddpriv->version == 2) {
+	    TRACE("Closing access to the FrameBuffer\n");
+	    TSXDGACloseFramebuffer(display, DefaultScreen(display));
+	    TRACE("Going back to normal X mode of operation\n");
+	    TSXDGASetMode(display, DefaultScreen(display), 0);
+
+	    /* Set the input handling back to absolute */
+	    X11DRV_EVENT_SetInputMethod(X11DRV_INPUT_ABSOLUTE);
+
+	    /* Remove the handling of DGA2 events */
+	    X11DRV_EVENT_SetDGAStatus(0, -1);
+
+	    /* Free the modes list */
+	    TSXFree(ddpriv->modes);
+       } else
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+	 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
+	 if (This->d.window && GetPropA(This->d.window,ddProp))
+	    DestroyWindow(This->d.window);
+#ifdef HAVE_LIBXXF86VM
+	if (orig_mode) {
+	    TSXF86VidModeSwitchToMode(
+		display,
+		DefaultScreen(display),
+		orig_mode
+	    );
+	    if (orig_mode->privsize)
+		TSXFree(orig_mode->private);		
+	    free(orig_mode);
+	    orig_mode = NULL;
+	}
+#endif
+	
+#ifdef RESTORE_SIGNALS
+	SIGNAL_Init();
+#endif
+	HeapFree(GetProcessHeap(),0,This);
+	return S_OK;
+    }
+    return This->ref;
+}
+
+static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
+    LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+
+    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
+    if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
+	*obj = This;
+	IDirectDraw2_AddRef(iface);
+
+	TRACE("  Creating IUnknown interface (%p)\n", *obj);
+	
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
+	ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
+	IDirectDraw2_AddRef(iface);
+	*obj = This;
+
+	TRACE("  Creating IDirectDraw interface (%p)\n", *obj);
+	
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
+	ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
+	IDirectDraw2_AddRef(iface);
+	*obj = This;
+
+	TRACE("  Creating IDirectDraw2 interface (%p)\n", *obj);
+
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
+	ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
+	IDirectDraw2_AddRef(iface);
+	*obj = This;
+
+	TRACE("  Creating IDirectDraw4 interface (%p)\n", *obj);
+
+	return S_OK;
+    }
+    FIXME("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
+    return OLE_E_ENUM_NOMORE;
+}
+
+static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
+    LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    DDSURFACEDESC	ddsfd;
+    static struct {
+	    int w,h;
+    } modes[5] = { /* some usual modes */
+	{512,384},
+	{640,400},
+	{640,480},
+	{800,600},
+	{1024,768},
+    };
+    static int depths[4] = {8,16,24,32};
+    int	i,j;
+
+    TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
+    ddsfd.dwSize = sizeof(ddsfd);
+    ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
+    if (dwFlags & DDEDM_REFRESHRATES) {
+	    ddsfd.dwFlags |= DDSD_REFRESHRATE;
+	    ddsfd.u.dwRefreshRate = 60;
+    }
+    ddsfd.ddsCaps.dwCaps = 0;
+    ddsfd.dwBackBufferCount = 1;
+
+#ifdef HAVE_LIBXXF86DGA2
+    if (ddpriv->version == 2) {
+      XDGAMode *modes = ddpriv->modes;
+
+      ddsfd.dwFlags |= DDSD_PITCH;
+      for (i = 0; i < ddpriv->num_modes; i++) {
+	    if (TRACE_ON(ddraw)) {
+	      DPRINTF("  Enumerating mode %d : %s (FB: %dx%d / VP: %dx%d) - depth %d -",
+		      modes[i].num,
+		      modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
+		      modes[i].viewportWidth, modes[i].viewportHeight,
+		      modes[i].depth);
+	      if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
+	      if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
+	      if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
+	      if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
+	      if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
+	      DPRINTF("\n");
+	    }
+	    /* Fill the pixel format */
+	    ddsfd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+	    ddsfd.ddpfPixelFormat.dwFourCC = 0;
+	    ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
+	    ddsfd.ddpfPixelFormat.u.dwRGBBitCount = modes[i].bitsPerPixel;
+	    if (modes[i].depth == 8) {
+	      ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
+	      ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
+	      ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
+	      ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
+	      ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
+	    } else {
+	      ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
+	      ddsfd.ddpfPixelFormat.u1.dwRBitMask = modes[i].redMask;
+	      ddsfd.ddpfPixelFormat.u2.dwGBitMask = modes[i].greenMask;
+	      ddsfd.ddpfPixelFormat.u3.dwBBitMask = modes[i].blueMask;
+	    }
+	    
+	    ddsfd.dwWidth = modes[i].viewportWidth;
+	    ddsfd.dwHeight = modes[i].viewportHeight;
+	    ddsfd.lPitch = modes[i].imageWidth;
+	      
+	    /* Send mode to the application */
+	    if (!modescb(&ddsfd,context)) return DD_OK;
+	  }
+	} else {
+#endif
+	for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
+		ddsfd.dwBackBufferCount = 1;
+		ddsfd.ddpfPixelFormat.dwFourCC	= 0;
+		ddsfd.ddpfPixelFormat.dwFlags 	= DDPF_RGB;
+		ddsfd.ddpfPixelFormat.u.dwRGBBitCount	= depths[i];
+		/* FIXME: those masks would have to be set in depth > 8 */
+		if (depths[i]==8) {
+		  ddsfd.ddpfPixelFormat.u1.dwRBitMask  	= 0;
+		  ddsfd.ddpfPixelFormat.u2.dwGBitMask  	= 0;
+		  ddsfd.ddpfPixelFormat.u3.dwBBitMask 	= 0;
+		  ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
+		  ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
+		  ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
+		} else {
+		  ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
+		  
+		  /* FIXME: We should query those from X itself */
+		  switch (depths[i]) {
+		  case 16:
+		    ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
+		    ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
+		    ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
+		    break;
+		  case 24:
+		    ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
+		    ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
+		    ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
+		    break;
+		  case 32:
+		    ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
+		    ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
+		    ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
+		    break;
+		  }
+		}
+
+		ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
+		ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
+		TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
+		if (!modescb(&ddsfd,context)) return DD_OK;
+
+		for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
+			ddsfd.dwWidth	= modes[j].w;
+			ddsfd.dwHeight	= modes[j].h;
+			TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
+			if (!modescb(&ddsfd,context)) return DD_OK;
+		}
+
+		if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
+			/* modeX is not standard VGA */
+
+			ddsfd.dwHeight = 200;
+			ddsfd.dwWidth = 320;
+			TRACE(" enumerating (320x200x%d)\n",depths[i]);
+			if (!modescb(&ddsfd,context)) return DD_OK;
+		}
+	}
+#ifdef HAVE_LIBXXF86DGA2
+      }
+#endif
+	return DD_OK;
+}
+
+static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
+	LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    DDPRIVATE(This);
+
+    TRACE("(%p)->(%p)\n",This,lpddsfd);
+    lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
+    lpddsfd->dwHeight = This->d.height;
+    lpddsfd->dwWidth = This->d.width;
+    lpddsfd->lPitch = ddpriv->fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
+    lpddsfd->dwBackBufferCount = 2;
+    lpddsfd->u.dwRefreshRate = 60;
+    lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
+    lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
+    if (TRACE_ON(ddraw))
+	_dump_surface_desc(lpddsfd);
+    return DD_OK;
+}
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)	(typeof(dga_ddvt.fn##fun))
+#else
+# define XCAST(fun)	(void *)
+#endif
+
+struct ICOM_VTABLE(IDirectDraw) dga_ddvt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
+    XCAST(AddRef)IDirectDraw2Impl_AddRef,
+    XCAST(Release)DGA_IDirectDraw2Impl_Release,
+    XCAST(Compact)IDirectDraw2Impl_Compact,
+    XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
+    XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
+    XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
+    XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
+    XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
+    XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
+    XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
+    XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
+    XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
+    XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
+    XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
+    XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
+    XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
+    XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
+    XCAST(Initialize)IDirectDraw2Impl_Initialize,
+    XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
+#ifdef HAVE_LIBXXF86DGA2
+    XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel,
+#else
+    XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
+#endif
+    DGA_IDirectDrawImpl_SetDisplayMode,
+    XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
+};
+#undef XCAST
+
+/*****************************************************************************
+ * 	IDirectDraw2
+ *
+ */
+
+static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
+    LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
+) {
+    FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags ); 
+    return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
+}
+
+static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
+    LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    DDPRIVATE(This);
+
+    TRACE("(%p)->(%p,%p,%p)\n",This,ddscaps,total,free);
+    if (total) *total = ddpriv->fb_memsize * 1024;
+    if (free) *free = ddpriv->fb_memsize * 1024;
+    return DD_OK;
+}
+
+ICOM_VTABLE(IDirectDraw2) dga_dd2vt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    DGA_IDirectDraw2Impl_QueryInterface,
+    IDirectDraw2Impl_AddRef,
+    DGA_IDirectDraw2Impl_Release,
+    IDirectDraw2Impl_Compact,
+    IDirectDraw2Impl_CreateClipper,
+    DGA_IDirectDraw2Impl_CreatePalette,
+    DGA_IDirectDraw2Impl_CreateSurface,
+    IDirectDraw2Impl_DuplicateSurface,
+    DGA_IDirectDraw2Impl_EnumDisplayModes,
+    IDirectDraw2Impl_EnumSurfaces,
+    IDirectDraw2Impl_FlipToGDISurface,
+    DGA_IDirectDraw2Impl_GetCaps,
+    DGA_IDirectDraw2Impl_GetDisplayMode,
+    IDirectDraw2Impl_GetFourCCCodes,
+    IDirectDraw2Impl_GetGDISurface,
+    IDirectDraw2Impl_GetMonitorFrequency,
+    IDirectDraw2Impl_GetScanLine,
+    IDirectDraw2Impl_GetVerticalBlankStatus,
+    IDirectDraw2Impl_Initialize,
+    DGA_IDirectDraw2Impl_RestoreDisplayMode,
+    IDirectDraw2Impl_SetCooperativeLevel,
+    DGA_IDirectDraw2Impl_SetDisplayMode,
+    IDirectDraw2Impl_WaitForVerticalBlank,
+    DGA_IDirectDraw2Impl_GetAvailableVidMem
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)	(typeof(dga_dd4vt.fn##fun))
+#else
+# define XCAST(fun)	(void*)
+#endif
+
+ICOM_VTABLE(IDirectDraw4) dga_dd4vt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
+    XCAST(AddRef)IDirectDraw2Impl_AddRef,
+    XCAST(Release)DGA_IDirectDraw2Impl_Release,
+    XCAST(Compact)IDirectDraw2Impl_Compact,
+    XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
+    XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
+    XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
+    XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
+    XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
+    XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
+    XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
+    XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
+    XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
+    XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
+    XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
+    XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
+    XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
+    XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
+    XCAST(Initialize)IDirectDraw2Impl_Initialize,
+    XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
+    XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
+    XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
+    XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
+    XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
+    IDirectDraw4Impl_GetSurfaceFromDC,
+    IDirectDraw4Impl_RestoreAllSurfaces,
+    IDirectDraw4Impl_TestCooperativeLevel,
+    IDirectDraw4Impl_GetDeviceIdentifier
+};
+#undef XCAST
diff --git a/dlls/ddraw/ddraw/main.c b/dlls/ddraw/ddraw/main.c
new file mode 100644
index 0000000..e6a741c
--- /dev/null
+++ b/dlls/ddraw/ddraw/main.c
@@ -0,0 +1,557 @@
+/*		DirectDraw IDirectDraw interface (generic)
+ *
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
+ */
+
+/*
+ * This file contains all the interface functions that are shared between
+ * all interfaces. Or better, it is a "common stub" library for the IDirectDraw*
+ * objects
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "winerror.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debugtools.h"
+#include "message.h"
+#include "options.h"
+#include "monitor.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+#include "ddraw_private.h"
+
+HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
+    LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
+    *dst = src; /* FIXME */
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
+    LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+
+    FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
+    _dump_cooperativelevel(cooplevel);
+    This->d.mainWindow = hwnd;
+    return DD_OK;
+}
+
+/*
+ * Small helper to either use the cooperative window or create a new 
+ * one (for mouse and keyboard input) and drawing in the Xlib implementation.
+ * 
+ * Note this just uses USER calls, so it is safe in here.
+ */
+void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
+    RECT	rect;
+
+    /* Do destroy only our window */
+    if (This->d.window && GetPropA(This->d.window,ddProp)) {
+	DestroyWindow(This->d.window);
+	This->d.window = 0;
+    }
+    /* Sanity check cooperative window before assigning it to drawing. */
+    if (IsWindow(This->d.mainWindow) &&
+	IsWindowVisible(This->d.mainWindow)
+    ) {
+	GetWindowRect(This->d.mainWindow,&rect);
+	if ((((rect.right-rect.left) >= This->d.width)	&&
+	     ((rect.bottom-rect.top) >= This->d.height))
+	) {
+	    This->d.window = This->d.mainWindow;
+	    /* FIXME: resizing is not windows compatible behaviour, need test */
+	    /* SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOOWNERZORDER); */
+	    This->d.paintable = 1; /* don't wait for WM_PAINT */
+	}
+    }
+    /* ... failed, create new one. */
+    if (!This->d.window) {
+	This->d.window = CreateWindowExA(
+	    0,
+	    "WINE_DirectDraw",
+	    "WINE_DirectDraw",
+	    WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME|WS_BORDER,
+	    0,0,
+	    This->d.width,
+	    This->d.height,
+	    0,
+	    0,
+	    0,
+	    NULL
+	);
+	/*Store THIS with the window. We'll use it in the window procedure*/
+	SetPropA(This->d.window,ddProp,(LONG)This);
+	ShowWindow(This->d.window,TRUE);
+	UpdateWindow(This->d.window);
+    }
+    SetFocus(This->d.window);
+}
+
+HRESULT WINAPI IDirectDrawImpl_SetDisplayMode(
+	LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
+) {
+        ICOM_THIS(IDirectDrawImpl,iface);
+
+	FIXME("(%p)->SetDisplayMode(%ld,%ld,%ld), needs to be implemented for your display adapter!\n",This,width,height,depth);
+	This->d.width	= width;
+	This->d.height	= height;
+	_common_IDirectDrawImpl_SetDisplayMode(This);
+	return DD_OK;
+}
+
+static void fill_caps(LPDDCAPS caps) {
+    /* This function tries to fill the capabilities of Wines DDraw
+     * implementation. Needs to be fixed, though.. */
+    if (caps == NULL)
+	return;
+
+    caps->dwSize = sizeof(*caps);
+    caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM |  DDCAPS_COLORKEY | DDCAPS_PALETTE /*| DDCAPS_NOHARDWARE*/;
+    caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
+    caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
+    caps->dwFXCaps = 0;
+    caps->dwFXAlphaCaps = 0;
+    caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
+    caps->dwSVCaps = 0;
+    caps->dwZBufferBitDepths = DDBD_16;
+    /* I put here 8 Mo so that D3D applications will believe they have enough
+     * memory to put textures in video memory. BTW, is this only frame buffer
+     * memory or also texture memory (for Voodoo boards for example) ?
+     */
+    caps->dwVidMemTotal = 8192 * 1024;
+    caps->dwVidMemFree = 8192 * 1024;
+    /* These are all the supported capabilities of the surfaces */
+    caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
+    DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
+      /*DDSCAPS_OVERLAY |*/ DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
+	DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_GetCaps(
+    LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
+)  {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
+
+    /* Put the same caps for the two capabilities */
+    fill_caps(caps1);
+    fill_caps(caps2);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
+    LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
+    FIXME("(%p)->(%08lx,%p,%p),stub!\n", This,x,ilpddclip,lpunk);
+    *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
+    (*ilpddclip)->ref = 1;
+    ICOM_VTBL(*ilpddclip) = &ddclipvt;
+    return DD_OK;
+}
+
+HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
+    IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,
+    IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
+) {
+    int size = 0;
+	  
+    if (TRACE_ON(ddraw))
+	_dump_paletteformat(dwFlags);
+	
+    *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
+    if (*lpddpal == NULL) return E_OUTOFMEMORY;
+    (*lpddpal)->ref = 1;
+    (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
+
+    if (dwFlags & DDPCAPS_1BIT)
+	size = 2;
+    else if (dwFlags & DDPCAPS_2BIT)
+	size = 4;
+    else if (dwFlags & DDPCAPS_4BIT)
+	size = 16;
+    else if (dwFlags & DDPCAPS_8BIT)
+	size = 256;
+    else
+	ERR("unhandled palette format\n");
+
+    *psize = size;
+    if (palent) {
+	/* Now, if we are in depth conversion mode, create the screen palette */
+	if (This->d.palette_convert != NULL)	    
+	    This->d.palette_convert(palent,(*lpddpal)->screen_palents,0,size);
+
+	memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
+    } else if (This->d.palette_convert != NULL) {
+	/* In that case, put all 0xFF */
+	memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
+    }
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_CreatePalette(
+    LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
+    int xsize;
+    HRESULT res;
+
+    TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
+    res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
+    if (res != 0) return res;
+    ICOM_VTBL(*ilpddpal) = &ddraw_ddpalvt;
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->RestoreDisplayMode()\n", This);
+    Sleep(1000);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
+    LPDIRECTDRAW2 iface,DWORD x,HANDLE h
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    FIXME("(%p)->(flags=0x%08lx,handle=0x%08x)\n",This,x,h);
+    return DD_OK;
+}
+
+ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
+
+    return ++(This->ref);
+}
+
+ULONG WINAPI IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+
+    if (!--(This->ref)) {
+	if (This->d.window && GetPropA(This->d.window,ddProp))
+	    DestroyWindow(This->d.window);
+	HeapFree(GetProcessHeap(),0,This);
+	return S_OK;
+    }
+    return This->ref;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_QueryInterface(
+    LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+
+    if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
+	*obj = This;
+	IDirectDraw2_AddRef(iface);
+	TRACE("  Creating IUnknown interface (%p)\n", *obj);
+	return S_OK;
+    }
+    ERR("(%p)->(%s,%p), must be implemented by display interface!\n",This,debugstr_guid(refiid),obj);
+    return OLE_E_ENUM_NOMORE;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
+    LPDIRECTDRAW2 iface,BOOL *status
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->(%p)\n",This,status);
+    *status = TRUE;
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_EnumDisplayModes(
+    LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,
+    LPDDENUMMODESCALLBACK modescb
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    DDSURFACEDESC	ddsfd;
+    static struct {
+	int w,h;
+    } modes[5] = { /* some of the usual modes */
+	{512,384},
+	{640,400},
+	{640,480},
+	{800,600},
+	{1024,768},
+    };
+    static int depths[4] = {8,16,24,32};
+    int	i,j;
+
+    TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
+    ddsfd.dwSize = sizeof(ddsfd);
+    ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
+    if (dwFlags & DDEDM_REFRESHRATES) {
+	ddsfd.dwFlags |= DDSD_REFRESHRATE;
+	ddsfd.u.dwRefreshRate = 60;
+    }
+    ddsfd.ddsCaps.dwCaps = 0;
+    ddsfd.dwBackBufferCount = 1;
+
+    for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
+	ddsfd.dwBackBufferCount = 1;
+	ddsfd.ddpfPixelFormat.dwFourCC	= 0;
+	ddsfd.ddpfPixelFormat.dwFlags 	= DDPF_RGB;
+	ddsfd.ddpfPixelFormat.u.dwRGBBitCount	= depths[i];
+	/* FIXME: those masks would have to be set in depth > 8 */
+	if (depths[i]==8) {
+	  ddsfd.ddpfPixelFormat.u1.dwRBitMask  	= 0;
+	  ddsfd.ddpfPixelFormat.u2.dwGBitMask  	= 0;
+	  ddsfd.ddpfPixelFormat.u3.dwBBitMask 	= 0;
+	  ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
+	  ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
+	  ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
+	} else {
+	  ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
+	  
+	  /* FIXME: We should query those from X itself */
+	  switch (depths[i]) {
+	  case 16:
+	    ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
+	    ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
+	    ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
+	    break;
+	  case 24:
+	    ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
+	    ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
+	    ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
+	    break;
+	  case 32:
+	    ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
+	    ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
+	    ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
+	    break;
+	  }
+	}
+
+	ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
+	ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
+	TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
+	if (!modescb(&ddsfd,context)) return DD_OK;
+
+	for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
+	    ddsfd.dwWidth	= modes[j].w;
+	    ddsfd.dwHeight	= modes[j].h;
+	    TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
+	    if (!modescb(&ddsfd,context)) return DD_OK;
+	}
+
+	if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
+	    /* modeX is not standard VGA */
+
+	    ddsfd.dwHeight = 200;
+	    ddsfd.dwWidth = 320;
+	    TRACE(" enumerating (320x200x%d)\n",depths[i]);
+	    if (!modescb(&ddsfd,context)) return DD_OK;
+	}
+    }
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_GetDisplayMode(
+    LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
+    lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
+    lpddsfd->dwHeight = This->d.height;
+    lpddsfd->dwWidth = This->d.width;
+    lpddsfd->lPitch =lpddsfd->dwWidth*PFGET_BPP(This->d.directdraw_pixelformat);
+    lpddsfd->dwBackBufferCount = 2;
+    lpddsfd->u.dwRefreshRate = 60;
+    lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
+    lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
+    if (TRACE_ON(ddraw))
+	_dump_surface_desc(lpddsfd);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    FIXME("(%p)->()\n",This);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
+    LPDIRECTDRAW2 iface,LPDWORD freq
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
+    *freq = 60*100; /* 60 Hz */
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
+    LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    FIXME("(%p,%p,%p), stub\n",This,x,y);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
+    LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,
+    LPDDENUMSURFACESCALLBACK ddsfcb
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_Compact( LPDIRECTDRAW2 iface ) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    FIXME("(%p)->()\n", This );
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(
+    LPDIRECTDRAW2 iface, LPDIRECTDRAWSURFACE *lplpGDIDDSSurface
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_GetScanLine(
+    LPDIRECTDRAW2 iface, LPDWORD lpdwScanLine
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    FIXME("(%p)->(%p)\n", This, lpdwScanLine);
+
+    if (lpdwScanLine)
+	*lpdwScanLine = 0;
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface, GUID *lpGUID) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    FIXME("(%p)->(%p)\n", This, lpGUID);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * 	IDirectDraw2
+ *
+ * We only need to list the changed/new functions.
+ */
+HRESULT WINAPI IDirectDraw2Impl_SetDisplayMode(
+    LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,
+    DWORD dwRefreshRate, DWORD dwFlags
+) {
+    FIXME("Ignoring parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags ); 
+    return IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
+}
+
+HRESULT WINAPI IDirectDraw2Impl_GetAvailableVidMem(
+    LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->(%p,%p,%p)\n", This,ddscaps,total,free);
+
+    /* We have 16 MB videomemory */
+    if (total)	*total= 16*1024*1024;
+    if (free)	*free = 16*1024*1024;
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * 	IDirectDraw4
+ *
+ */
+
+HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(
+    LPDIRECTDRAW4 iface, HDC hdc, LPDIRECTDRAWSURFACE *lpDDS
+) {
+    ICOM_THIS(IDirectDraw4Impl,iface);
+    FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
+    ICOM_THIS(IDirectDraw4Impl,iface);
+    FIXME("(%p)->()\n", This);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
+    ICOM_THIS(IDirectDraw4Impl,iface);
+    FIXME("(%p)->()\n", This);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(
+    LPDIRECTDRAW4 iface,LPDDDEVICEIDENTIFIER lpdddi,DWORD dwFlags
+) {
+    ICOM_THIS(IDirectDraw4Impl,iface);
+    FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
+
+    /* just guessing values */
+    strcpy(lpdddi->szDriver,"directdraw");
+    strcpy(lpdddi->szDescription,"WINE DirectDraw");
+    lpdddi->liDriverVersion.s.HighPart = 7;
+    lpdddi->liDriverVersion.s.LowPart = 0;
+    /* Do I smell PCI ids here ? -MM */
+    lpdddi->dwVendorId			= 0;
+    lpdddi->dwDeviceId			= 0;
+    lpdddi->dwSubSysId			= 0;
+    lpdddi->dwRevision			= 1;
+    memset(&(lpdddi->guidDeviceIdentifier),0,sizeof(lpdddi->guidDeviceIdentifier));
+    return DD_OK;
+}
+
+HRESULT common_off_screen_CreateSurface(
+    IDirectDraw2Impl* This,IDirectDrawSurfaceImpl* lpdsf
+) {
+    int bpp;
+
+    /* The surface was already allocated when entering in this function */
+    TRACE("using system memory for a surface (%p) \n", lpdsf);
+
+    if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
+	/* This is a Z Buffer */
+	TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
+	bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
+    } else {
+	/* This is a standard image */
+	if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
+	    /* No pixel format => use DirectDraw's format */
+	    lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
+	    lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
+	}
+	bpp = GET_BPP(lpdsf->s.surface_desc);
+    }
+
+    if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE)
+	ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
+
+    lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
+    lpdsf->s.surface_desc.u1.lpSurface =(LPBYTE)HeapAlloc(
+	GetProcessHeap(),
+	0,
+	lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp
+    );
+    lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
+    return DD_OK;
+}
diff --git a/dlls/ddraw/ddraw/x11.c b/dlls/ddraw/ddraw/x11.c
new file mode 100644
index 0000000..92a3e84
--- /dev/null
+++ b/dlls/ddraw/ddraw/x11.c
@@ -0,0 +1,995 @@
+/*		DirectDraw IDirectDraw Xlib interface
+ *
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
+ */
+/*
+ * This file contains the Xlib specific interface functions.
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "winerror.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "win.h"
+#include "debugtools.h"
+#include "message.h"
+#include "options.h"
+#include "monitor.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+#include "x11_private.h"
+
+#define DDPRIVATE(x) x11_dd_private *ddpriv = ((x11_dd_private*)(x)->private)
+#define DPPRIVATE(x) x11_dp_private *dppriv = ((x11_dp_private*)(x)->private)
+#define DSPRIVATE(x) x11_ds_private *dspriv = ((x11_ds_private*)(x)->private)
+
+static inline BOOL get_option( const char *name, BOOL def ) {
+    return PROFILE_GetWineIniBool( "x11drv", name, def );
+}
+
+int _common_depth_to_pixelformat(
+    DWORD depth, DDPIXELFORMAT *pixelformat,DDPIXELFORMAT *screen_pixelformat,
+    int *pix_depth
+) {
+  XVisualInfo *vi;
+  XPixmapFormatValues *pf;
+  XVisualInfo vt;
+  int nvisuals, npixmap, i;
+  int match = 0;
+  int index = -2;
+
+  vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
+  pf = XListPixmapFormats(display, &npixmap);
+
+  for (i = 0; i < npixmap; i++) {
+    if (pf[i].depth == depth) {
+      int j;
+
+      for (j = 0; j < nvisuals; j++) {
+	if (vi[j].depth == pf[i].depth) {
+	  pixelformat->dwSize = sizeof(*pixelformat);
+	  if (depth == 8) {
+	    pixelformat->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
+	    pixelformat->u1.dwRBitMask = 0;
+	    pixelformat->u2.dwGBitMask = 0;
+	    pixelformat->u3.dwBBitMask = 0;
+	  } else {
+	    pixelformat->dwFlags = DDPF_RGB;
+	    pixelformat->u1.dwRBitMask = vi[j].red_mask;
+	    pixelformat->u2.dwGBitMask = vi[j].green_mask;
+	    pixelformat->u3.dwBBitMask = vi[j].blue_mask;
+	  }
+	  pixelformat->dwFourCC = 0;
+	  pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
+	  pixelformat->u4.dwRGBAlphaBitMask= 0;
+
+	  *screen_pixelformat = *pixelformat;
+
+	  if (pix_depth)
+	    *pix_depth = vi[j].depth;
+
+	  match = 1;
+	  index = -1;
+	  goto clean_up_and_exit;
+	}
+      }
+      ERR("No visual corresponding to pixmap format !\n");
+    }
+  }
+
+  if (match == 0) {
+    /* We try now to find an emulated mode */
+    int c;
+
+    for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
+      if (ModeEmulations[c].dest.depth == depth) {
+	/* Found an emulation function, now tries to find a matching visual / pixel format pair */
+	for (i = 0; i < npixmap; i++) {
+	  if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
+	      (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
+	    int j;
+
+	    for (j = 0; j < nvisuals; j++) {
+	      if (vi[j].depth == pf[i].depth) {
+		screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
+		screen_pixelformat->dwFlags = DDPF_RGB;
+		screen_pixelformat->dwFourCC = 0;
+		screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
+		screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
+		screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
+		screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
+		screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
+
+		pixelformat->dwSize = sizeof(*pixelformat);
+		pixelformat->dwFourCC = 0;
+		if (depth == 8) {
+		  pixelformat->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
+		  pixelformat->u.dwRGBBitCount = 8;
+		  pixelformat->u1.dwRBitMask = 0;
+		  pixelformat->u2.dwGBitMask = 0;
+		  pixelformat->u3.dwBBitMask = 0;
+		} else {
+		  pixelformat->dwFlags = DDPF_RGB;
+		  pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
+		  pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
+		  pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
+		  pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
+		}
+		pixelformat->u4.dwRGBAlphaBitMask= 0;    
+
+		if (pix_depth)
+		  *pix_depth = vi[j].depth;
+
+		match = 2;
+		index = c;
+		goto clean_up_and_exit;
+	      }
+	      ERR("No visual corresponding to pixmap format !\n");
+	    }
+	  }
+	}
+      }
+    }
+  }
+
+clean_up_and_exit:
+  TSXFree(vi);
+  TSXFree(pf);
+
+  return index;
+}
+
+/*******************************************************************************
+ *				IDirectDraw
+ */
+#ifdef HAVE_LIBXXSHM
+/* Error handlers for Image creation */
+static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
+    XShmErrorFlag = 1;
+    return 0;
+}
+
+static XImage *create_xshmimage(
+    IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf
+) {
+    DSPRIVATE(lpdsf);
+    DDPRIVATE(This);
+    XImage *img;
+    int (*WineXHandler)(Display *, XErrorEvent *);
+
+    img = TSXShmCreateImage(display,
+	DefaultVisualOfScreen(X11DRV_GetXScreen()),
+	This->d.pixmap_depth,
+	ZPixmap,
+	NULL,
+	&(dspriv->shminfo),
+	lpdsf->s.surface_desc.dwWidth,
+	lpdsf->s.surface_desc.dwHeight
+    );
+
+    if (img == NULL) {
+	FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
+	ddpriv->xshm_active = 0;
+	return NULL;
+    }
+
+    dspriv->shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
+    if (dspriv->shminfo.shmid < 0) {
+	FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
+	ddpriv->xshm_active = 0;
+	TSXDestroyImage(img);
+	return NULL;
+    }
+
+    dspriv->shminfo.shmaddr=img->data=(char*)shmat(dspriv->shminfo.shmid,0,0);
+
+    if (img->data == (char *) -1) {
+	FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
+	ddpriv->xshm_active = 0;
+	TSXDestroyImage(img);
+	shmctl(dspriv->shminfo.shmid, IPC_RMID, 0);
+	return NULL;
+    }
+    dspriv->shminfo.readOnly = False;
+
+    /* This is where things start to get trickier....
+     * First, we flush the current X connections to be sure to catch all
+     * non-XShm related errors
+     */
+    TSXSync(display, False);
+    /* Then we enter in the non-thread safe part of the tests */
+    EnterCriticalSection( &X11DRV_CritSection );
+
+    /* Reset the error flag, sets our new error handler and try to attach
+     * the surface
+     */
+    XShmErrorFlag = 0;
+    WineXHandler = XSetErrorHandler(XShmErrorHandler);
+    XShmAttach(display, &(dspriv->shminfo));
+    XSync(display, False);
+
+    /* Check the error flag */
+    if (XShmErrorFlag) {
+	/* An error occured */
+	XFlush(display);
+	XShmErrorFlag = 0;
+	XDestroyImage(img);
+	shmdt(dspriv->shminfo.shmaddr);
+	shmctl(dspriv->shminfo.shmid, IPC_RMID, 0);
+	XSetErrorHandler(WineXHandler);
+
+	FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
+	ddpriv->xshm_active = 0;
+
+	/* Leave the critical section */
+	LeaveCriticalSection( &X11DRV_CritSection );
+	return NULL;
+    }
+    /* Here, to be REALLY sure, I should do a XShmPutImage to check if
+     * this works, but it may be a bit overkill....
+     */
+    XSetErrorHandler(WineXHandler);
+    LeaveCriticalSection( &X11DRV_CritSection );
+
+    shmctl(dspriv->shminfo.shmid, IPC_RMID, 0);
+
+    if (This->d.pixel_convert != NULL) {
+	int bpp = PFGET_BPP(This->d.directdraw_pixelformat);
+	lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
+	    GetProcessHeap(),
+	    HEAP_ZERO_MEMORY,
+	    lpdsf->s.surface_desc.dwWidth *
+	    lpdsf->s.surface_desc.dwHeight *
+	    bpp
+	);
+    } else
+	lpdsf->s.surface_desc.u1.lpSurface = img->data;
+    return img;
+}
+#endif /* HAVE_LIBXXSHM */
+
+static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
+    XImage *img = NULL;
+    DDPRIVATE(This);
+    void *img_data;
+    int bpp = PFGET_BPP(This->d.directdraw_pixelformat);
+    
+#ifdef HAVE_LIBXXSHM
+    if (ddpriv->xshm_active)
+	img = create_xshmimage(This, lpdsf);
+
+    if (img == NULL) {
+#endif
+    /* Allocate surface memory */
+	lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
+	    GetProcessHeap(),
+	    HEAP_ZERO_MEMORY,
+	    lpdsf->s.surface_desc.dwWidth *
+	    lpdsf->s.surface_desc.dwHeight *
+	    bpp
+	);
+
+	if (This->d.pixel_convert != NULL)
+	    img_data = HeapAlloc(
+		GetProcessHeap(),
+		HEAP_ZERO_MEMORY,
+		lpdsf->s.surface_desc.dwWidth *
+		lpdsf->s.surface_desc.dwHeight *
+		bpp
+	    );
+	else
+	    img_data = lpdsf->s.surface_desc.u1.lpSurface;
+
+	/* In this case, create an XImage */
+	img = TSXCreateImage(display,
+	    DefaultVisualOfScreen(X11DRV_GetXScreen()),
+	    This->d.pixmap_depth,
+	    ZPixmap,
+	    0,
+	    img_data,
+	    lpdsf->s.surface_desc.dwWidth,
+	    lpdsf->s.surface_desc.dwHeight,
+	    32,
+	    lpdsf->s.surface_desc.dwWidth*bpp
+	);
+#ifdef HAVE_LIBXXSHM
+    }
+#endif
+    /* assert(bpp*lpdsf->s.surface_desc.dwWidth == img->bytes_per_line); */
+
+    if (This->d.pixel_convert != NULL)
+	lpdsf->s.surface_desc.lPitch = bpp*lpdsf->s.surface_desc.dwWidth;
+    else
+	lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
+    return img;
+}
+
+static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
+    LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,
+    IUnknown *lpunk
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    IDirectDrawSurfaceImpl* dsurf;
+    x11_ds_private	*dspriv;
+
+    TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,lpdsf,lpunk);
+
+    if (TRACE_ON(ddraw)) _dump_surface_desc(lpddsd);
+
+    *lpdsf = HeapAlloc(
+    	GetProcessHeap(),
+	HEAP_ZERO_MEMORY,
+	sizeof(IDirectDrawSurfaceImpl)
+    );
+    dsurf = (IDirectDrawSurfaceImpl*)*lpdsf;
+    dsurf->ref                 = 2;
+    dsurf->private = HeapAlloc(
+	    GetProcessHeap(),
+	    HEAP_ZERO_MEMORY,
+	    sizeof(x11_ds_private)
+    );
+    ICOM_VTBL(dsurf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
+    dspriv = (x11_ds_private*)dsurf->private;
+
+    dsurf->s.ddraw	= This;
+    IDirectDraw2_AddRef(iface);
+
+    dsurf->s.palette	= NULL;
+    dsurf->s.lpClipper	= NULL;
+    dspriv->image	= NULL; /* This is for off-screen buffers */
+
+    /* Copy the surface description */
+    dsurf->s.surface_desc = *lpddsd;
+
+    if (!(lpddsd->dwFlags & DDSD_WIDTH))
+	dsurf->s.surface_desc.dwWidth  = This->d.width;
+    if (!(lpddsd->dwFlags & DDSD_HEIGHT))
+	dsurf->s.surface_desc.dwHeight = This->d.height;
+    dsurf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
+
+    /* Check if this a 'primary surface' or not */
+    if ((lpddsd->dwFlags & DDSD_CAPS) && 
+	(lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+    ) {
+	XImage *img;
+
+	TRACE("using standard XImage for a primary surface (%p)\n", dsurf);
+	/* Create the XImage */
+	img = create_ximage(This,(IDirectDrawSurface4Impl*)dsurf);
+	if (img == NULL)
+	    return DDERR_OUTOFMEMORY;
+	dspriv->image = img;
+
+	/* Add flags if there were not present */
+	dsurf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
+	dsurf->s.surface_desc.dwWidth = This->d.width;
+	dsurf->s.surface_desc.dwHeight = This->d.height;
+	dsurf->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
+	dsurf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
+
+	/* Check for backbuffers */
+	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
+	    IDirectDrawSurface4Impl*	back;
+	    XImage *img;
+	    int	i;
+
+	    for (i=lpddsd->dwBackBufferCount;i--;) {
+		x11_ds_private *bspriv;
+		back = (IDirectDrawSurface4Impl*)HeapAlloc(
+		    GetProcessHeap(),
+		    HEAP_ZERO_MEMORY,
+		    sizeof(IDirectDrawSurface4Impl)
+		);
+		TRACE("allocated back-buffer (%p)\n", back);
+
+		IDirectDraw2_AddRef(iface);
+		back->s.ddraw = This;
+		
+		back->ref = 2;
+		ICOM_VTBL(back)=(ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
+		/* Copy the surface description from the front buffer */
+		back->s.surface_desc = dsurf->s.surface_desc;
+		back->s.surface_desc.u1.lpSurface = NULL;
+		
+		back->private = HeapAlloc(
+		    GetProcessHeap(),
+		    HEAP_ZERO_MEMORY,
+		    sizeof(x11_ds_private)
+		);
+		bspriv = (x11_ds_private*)back->private;
+
+		/* Create the XImage. */
+		img = create_ximage(This, back);
+		if (img == NULL)
+		    return DDERR_OUTOFMEMORY;
+		TRACE("bspriv = %p\n",bspriv);
+		bspriv->image = img;
+
+		/* Add relevant info to front and back buffers */
+		/* FIXME: backbuffer/frontbuffer handling broken here, but
+		 * will be fixed up in _Flip().
+		 */
+		SDDSCAPS(dsurf) |= DDSCAPS_FRONTBUFFER;
+		SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
+		back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
+		SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
+		TRACE("attaching surface %p to %p\n",back,*lpdsf);
+		IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*lpdsf),(LPDIRECTDRAWSURFACE4)back);
+	    }
+	}
+    } else {
+	/* There is no Xlib-specific code here...
+	 * Go to the common surface creation function
+	 */
+	return common_off_screen_CreateSurface(This,dsurf);
+    }
+    return DD_OK;
+}
+
+/* 
+ * The Xlib Implementation tries to use the passed hwnd as drawing window,
+ * even when the approbiate bitmasks are not specified.
+ */
+static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetCooperativeLevel(
+    LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    DDPRIVATE(This);
+
+    FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
+    if (TRACE_ON(ddraw))
+	_dump_cooperativelevel(cooplevel);
+    This->d.mainWindow = hwnd;
+
+    /* This will be overwritten in the case of Full Screen mode.
+       Windowed games could work with that :-) */
+    if (hwnd) {
+	WND *tmpWnd = WIN_FindWndPtr(hwnd);
+	ddpriv->drawable  = X11DRV_WND_GetXWindow(tmpWnd);
+	WIN_ReleaseWndPtr(tmpWnd);
+
+	if( !ddpriv->drawable ) {
+	    ddpriv->drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
+	    WIN_ReleaseDesktop();
+	}
+	TRACE("Setting drawable to %ld\n", ddpriv->drawable);
+    }
+    return DD_OK;
+}
+
+static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
+    LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
+) {
+    ICOM_THIS(IDirectDrawImpl,iface);
+    DDPRIVATE(This);
+    char	buf[200];
+    WND *tmpWnd;
+    int c;
+
+    TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
+		  This, width, height, depth);
+
+    switch ((c = _common_depth_to_pixelformat(depth,
+					 &(This->d.directdraw_pixelformat),
+					 &(This->d.screen_pixelformat),
+					      &(This->d.pixmap_depth)))) {
+    case -2:
+      sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
+      MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
+      return DDERR_UNSUPPORTEDMODE;
+
+    case -1:
+      /* No convertion */
+      This->d.pixel_convert = NULL;
+      This->d.palette_convert = NULL;
+      break;
+
+    default:
+      DPRINTF("DirectDraw warning: running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
+      /* Set the depth convertion routines */
+      This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
+      This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
+    }
+	
+    This->d.width	= width;
+    This->d.height	= height;
+
+    _common_IDirectDrawImpl_SetDisplayMode(This);
+
+    tmpWnd = WIN_FindWndPtr(This->d.window);
+    This->d.paintable = 1;
+    ddpriv->drawable  = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
+    WIN_ReleaseWndPtr(tmpWnd);
+
+    /* We don't have a context for this window. Host off the desktop */
+    if( !ddpriv->drawable )
+    {
+       ddpriv->drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
+	WIN_ReleaseDesktop();
+    }
+    TRACE("Setting drawable to %ld\n", ddpriv->drawable);
+
+    if (get_option( "DXGrab", 0 )) {
+	/* Confine cursor movement (risky, but the user asked for it) */
+	TSXGrabPointer(display, ddpriv->drawable, True, 0, GrabModeAsync, GrabModeAsync, ddpriv->drawable, None, CurrentTime);
+    }
+
+    return DD_OK;
+}
+
+static void fill_caps(LPDDCAPS caps) {
+  /* This function tries to fill the capabilities of Wine's DDraw implementation.
+     Need to be fixed, though.. */
+  if (caps == NULL)
+    return;
+
+  caps->dwSize = sizeof(*caps);
+  caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM |  DDCAPS_COLORKEY | DDCAPS_PALETTE /*| DDCAPS_NOHARDWARE*/;
+  caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
+  caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
+  caps->dwFXCaps = 0;
+  caps->dwFXAlphaCaps = 0;
+  caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
+  caps->dwSVCaps = 0;
+  caps->dwZBufferBitDepths = DDBD_16;
+  /* I put here 8 Mo so that D3D applications will believe they have enough memory
+     to put textures in video memory.
+     BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
+     for example) ? */
+  caps->dwVidMemTotal = 8192 * 1024;
+  caps->dwVidMemFree = 8192 * 1024;
+  /* These are all the supported capabilities of the surfaces */
+  caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
+    DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
+      /*DDSCAPS_OVERLAY |*/ DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
+	DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
+#ifdef HAVE_MESAGL
+  caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
+  caps->dwCaps2 |=  DDCAPS2_NO2DDURING3DSCENE;
+  caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
+#endif
+}
+
+static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
+    LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
+)  {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
+
+    /* Put the same caps for the two capabilities */
+    fill_caps(caps1);
+    fill_caps(caps2);
+
+    return DD_OK;
+}
+
+static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
+    LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,
+    LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
+    int xsize;
+    HRESULT res;
+
+    TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
+    res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
+    if (res != 0)
+	return res;
+    (*ilpddpal)->private = HeapAlloc(
+	GetProcessHeap(),
+	HEAP_ZERO_MEMORY,
+	sizeof(x11_dp_private)
+    );
+    ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
+    return DD_OK;
+}
+
+static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+
+    if (!--(This->ref)) {
+	if (This->d.window && GetPropA(This->d.window,ddProp))
+	    DestroyWindow(This->d.window);
+	HeapFree(GetProcessHeap(),0,This);
+	return S_OK;
+    }
+    /* FIXME: destroy window ... */
+    return This->ref;
+}
+
+static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
+    LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+
+    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
+    if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
+	*obj = This;
+	IDirectDraw2_AddRef(iface);
+
+	TRACE("  Creating IUnknown interface (%p)\n", *obj);
+	
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
+	ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
+	IDirectDraw2_AddRef(iface);
+	*obj = This;
+
+	TRACE("  Creating IDirectDraw interface (%p)\n", *obj);
+	
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
+	ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
+	IDirectDraw2_AddRef(iface);
+	*obj = This;
+
+	TRACE("  Creating IDirectDraw2 interface (%p)\n", *obj);
+	
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
+	ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
+	IDirectDraw2_AddRef(iface);
+	*obj = This;
+
+	TRACE("  Creating IDirectDraw4 interface (%p)\n", *obj);
+
+	return S_OK;
+    }
+#ifdef HAVE_MESAGL
+    if ( IsEqualGUID( &IID_IDirect3D, refiid ) )
+	return create_direct3d(obj,This);
+    if ( IsEqualGUID( &IID_IDirect3D2, refiid ) )
+	return create_direct3d2(obj,This);
+#endif
+    FIXME("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
+    return OLE_E_ENUM_NOMORE;
+}
+
+static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
+    LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
+) {
+  ICOM_THIS(IDirectDraw2Impl,iface);
+  XVisualInfo *vi;
+  XPixmapFormatValues *pf;
+  XVisualInfo vt;
+  int xbpp = 1, nvisuals, npixmap, i, emu;
+  int has_mode[]  = { 0,  0,  0,  0 };
+  int has_depth[] = { 8, 15, 16, 24 };
+  DDSURFACEDESC	ddsfd;
+  static struct {
+	int w,h;
+  } modes[] = { /* some of the usual modes */
+	{512,384},
+	{640,400},
+	{640,480},
+	{800,600},
+	{1024,768},
+	{1280,1024}
+  };
+  DWORD maxWidth, maxHeight;
+
+  TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
+  ddsfd.dwSize = sizeof(ddsfd);
+  ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_PITCH;
+  if (dwFlags & DDEDM_REFRESHRATES) {
+    ddsfd.dwFlags |= DDSD_REFRESHRATE;
+    ddsfd.u.dwRefreshRate = 60;
+  }
+  maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
+  maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
+  
+  vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
+  pf = XListPixmapFormats(display, &npixmap);
+
+  i = 0;
+  emu = 0;
+  while ((i < npixmap) || (emu != 4)) {
+    int mode_index = 0;
+    int send_mode = 0;
+    int j;
+
+    if (i < npixmap) {
+      for (j = 0; j < 4; j++) {
+	if (has_depth[j] == pf[i].depth) {
+	  mode_index = j;
+	  break;
+	}
+      }
+      if (j == 4) {
+	i++;
+	continue;
+      }
+      
+
+      if (has_mode[mode_index] == 0) {
+	if (mode_index == 0) {
+	  send_mode = 1;
+
+	  ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
+	  ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
+	  ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
+	  ddsfd.ddpfPixelFormat.dwFourCC = 0;
+	  ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
+	  ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
+	  ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
+	  ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
+	  ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
+
+	  xbpp = 1;
+	  
+	  has_mode[mode_index] = 1;
+	} else {
+      /* All the 'true color' depths (15, 16 and 24)
+	 First, find the corresponding visual to extract the bit masks */
+	  for (j = 0; j < nvisuals; j++) {
+	    if (vi[j].depth == pf[i].depth) {
+	      ddsfd.ddsCaps.dwCaps = 0;
+	      ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
+	      ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
+	      ddsfd.ddpfPixelFormat.dwFourCC = 0;
+	      ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
+	      ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
+	      ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
+	      ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
+	      ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
+
+	      xbpp = pf[i].bits_per_pixel/8;
+
+	      send_mode = 1;
+		  has_mode[mode_index] = 1;
+	      break;
+	    }
+	  }
+	  if (j == nvisuals)
+	    ERR("Did not find visual corresponding the the pixmap format !\n");
+	}
+      }
+      i++;
+    } else {
+      /* Now to emulated modes */
+      if (has_mode[emu] == 0) {
+	int c;
+	int l;
+	int depth = has_depth[emu];
+      
+	for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
+	  if (ModeEmulations[c].dest.depth == depth) {
+	    /* Found an emulation function, now tries to find a matching visual / pixel format pair */
+	    for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
+	      if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
+		  (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
+		int j;
+		for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
+		  if ((vi[j].depth == pf[l].depth) &&
+		      (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
+		      (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
+		      (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
+		    ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
+		    ddsfd.ddpfPixelFormat.dwFourCC = 0;
+		    if (depth == 8) {
+		      ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
+		      ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
+		      ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
+		      ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
+		      ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
+    } else {
+		      ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
+		      ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
+		      ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
+		      ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
+		      ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
+		    }
+		    ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
+		    send_mode = 1;
+		  }
+		  
+		  if (send_mode == 0)
+		    ERR("No visual corresponding to pixmap format !\n");
+		}
+	      }
+	    }
+          }
+	}
+      }
+
+      emu++;
+    }
+
+    if (send_mode) {
+      int mode;
+
+      if (TRACE_ON(ddraw)) {
+	TRACE("Enumerating with pixel format : \n");
+	_dump_pixelformat(&(ddsfd.ddpfPixelFormat));
+	DPRINTF("\n");
+      }
+      
+      for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
+	/* Do not enumerate modes we cannot handle anyway */
+	if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
+	  break;
+
+	ddsfd.dwWidth = modes[mode].w;
+	ddsfd.dwHeight= modes[mode].h;
+	ddsfd.lPitch  = ddsfd.dwWidth * xbpp;
+	
+	/* Now, send the mode description to the application */
+	TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
+	if (!modescb(&ddsfd, context))
+	  goto exit_enum;
+      }
+
+      if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
+	/* modeX is not standard VGA */
+	ddsfd.dwWidth = 320;
+	ddsfd.dwHeight = 200;
+	ddsfd.lPitch  = 320 * xbpp;
+	if (!modescb(&ddsfd, context))
+	  goto exit_enum;
+      }
+    }
+  }
+ exit_enum:
+  TSXFree(vi);
+  TSXFree(pf);
+
+  return DD_OK;
+}
+
+static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
+    LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
+    lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
+    lpddsfd->dwHeight = This->d.height;
+    lpddsfd->dwWidth = This->d.width;
+    lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
+    lpddsfd->dwBackBufferCount = 2;
+    lpddsfd->u.dwRefreshRate = 60;
+    lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
+    lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
+    if (TRACE_ON(ddraw))
+	_dump_surface_desc(lpddsfd);
+    return DD_OK;
+}
+
+/* Note: Hack so we can reuse the old functions without compiler warnings */
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)	(typeof(xlib_ddvt.fn##fun))
+#else
+# define XCAST(fun)	(void *)
+#endif
+
+ICOM_VTABLE(IDirectDraw) xlib_ddvt = {
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
+    XCAST(AddRef)IDirectDraw2Impl_AddRef,
+    XCAST(Release)Xlib_IDirectDraw2Impl_Release,
+    XCAST(Compact)IDirectDraw2Impl_Compact,
+    XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
+    XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
+    XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
+    XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
+    XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
+    XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
+    XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
+    XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
+    XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
+    XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
+    XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
+    XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
+    XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
+    XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
+    XCAST(Initialize)IDirectDraw2Impl_Initialize,
+    XCAST(RestoreDisplayMode)IDirectDraw2Impl_RestoreDisplayMode,
+    XCAST(SetCooperativeLevel)Xlib_IDirectDraw2Impl_SetCooperativeLevel,
+    Xlib_IDirectDrawImpl_SetDisplayMode,
+    XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
+};
+
+#undef XCAST
+
+/*****************************************************************************
+ * 	IDirectDraw2
+ *
+ */
+
+static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
+    LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
+) {
+    FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags ); 
+    return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
+}
+
+static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
+    LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
+) {
+    ICOM_THIS(IDirectDraw2Impl,iface);
+    TRACE("(%p)->(%p,%p,%p)\n",This,ddscaps,total,free);
+    if (total) *total = 16* 1024 * 1024;
+    if (free) *free = 16* 1024 * 1024;
+    return DD_OK;
+}
+
+ICOM_VTABLE(IDirectDraw2) xlib_dd2vt = {
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    Xlib_IDirectDraw2Impl_QueryInterface,
+    IDirectDraw2Impl_AddRef,
+    Xlib_IDirectDraw2Impl_Release,
+    IDirectDraw2Impl_Compact,
+    IDirectDraw2Impl_CreateClipper,
+    Xlib_IDirectDraw2Impl_CreatePalette,
+    Xlib_IDirectDraw2Impl_CreateSurface,
+    IDirectDraw2Impl_DuplicateSurface,
+    Xlib_IDirectDraw2Impl_EnumDisplayModes,
+    IDirectDraw2Impl_EnumSurfaces,
+    IDirectDraw2Impl_FlipToGDISurface,
+    Xlib_IDirectDraw2Impl_GetCaps,
+    Xlib_IDirectDraw2Impl_GetDisplayMode,
+    IDirectDraw2Impl_GetFourCCCodes,
+    IDirectDraw2Impl_GetGDISurface,
+    IDirectDraw2Impl_GetMonitorFrequency,
+    IDirectDraw2Impl_GetScanLine,
+    IDirectDraw2Impl_GetVerticalBlankStatus,
+    IDirectDraw2Impl_Initialize,
+    IDirectDraw2Impl_RestoreDisplayMode,
+    Xlib_IDirectDraw2Impl_SetCooperativeLevel,
+    Xlib_IDirectDraw2Impl_SetDisplayMode,
+    IDirectDraw2Impl_WaitForVerticalBlank,
+    Xlib_IDirectDraw2Impl_GetAvailableVidMem	
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun)	(typeof(xlib_dd4vt.fn##fun))
+#else
+# define XCAST(fun)	(void*)
+#endif
+
+ICOM_VTABLE(IDirectDraw4) xlib_dd4vt = {
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
+    XCAST(AddRef)IDirectDraw2Impl_AddRef,
+    XCAST(Release)Xlib_IDirectDraw2Impl_Release,
+    XCAST(Compact)IDirectDraw2Impl_Compact,
+    XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
+    XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
+    XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
+    XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
+    XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
+    XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
+    XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
+    XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
+    XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
+    XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
+    XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
+    XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
+    XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
+    XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
+    XCAST(Initialize)IDirectDraw2Impl_Initialize,
+    XCAST(RestoreDisplayMode)IDirectDraw2Impl_RestoreDisplayMode,
+    XCAST(SetCooperativeLevel)Xlib_IDirectDraw2Impl_SetCooperativeLevel,
+    XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
+    XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
+    XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
+    IDirectDraw4Impl_GetSurfaceFromDC,
+    IDirectDraw4Impl_RestoreAllSurfaces,
+    IDirectDraw4Impl_TestCooperativeLevel,
+    IDirectDraw4Impl_GetDeviceIdentifier
+};
+#undef XCAST
diff --git a/dlls/ddraw/ddraw_main.c b/dlls/ddraw/ddraw_main.c
deleted file mode 100644
index 89f9caa..0000000
--- a/dlls/ddraw/ddraw_main.c
+++ /dev/null
@@ -1,5803 +0,0 @@
-/*		DirectDraw using DGA or Xlib(XSHM)
- *
- * Copyright 1997-1999 Marcus Meissner
- * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
- */
-/* XF86DGA:
- * When DirectVideo mode is enabled you can no longer use 'normal' X 
- * applications nor can you switch to a virtual console. Also, enabling
- * only works, if you have switched to the screen where the application
- * is running.
- * Some ways to debug this stuff are:
- * - A terminal connected to the serial port. Can be bought used for cheap.
- *   (This is the method I am using.)
- * - Another machine connected over some kind of network.
- */
-
-#include "config.h"
-#include "winerror.h"
-
-#ifndef X_DISPLAY_MISSING 
-
-#include "ts_xlib.h"
-#include "ts_xutil.h"
-
-#ifdef HAVE_LIBXXSHM
-# include <sys/types.h>
-# ifdef HAVE_SYS_IPC_H
-#  include <sys/ipc.h>
-# endif
-# ifdef HAVE_SYS_SHM_H
-#  include <sys/shm.h>
-# endif
-# include "ts_xshm.h"
-#endif /* defined(HAVE_LIBXXSHM) */
-
-#ifdef HAVE_LIBXXF86DGA
-#include "ts_xf86dga.h"
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-#ifdef HAVE_LIBXXF86DGA2
-#include "ts_xf86dga2.h"
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-
-#ifdef HAVE_LIBXXF86VM
-#include "ts_xf86vmode.h"
-#endif /* defined(HAVE_LIBXXF86VM) */
-
-#include "x11drv.h"
-
-#include <unistd.h>
-#include <assert.h>
-#ifdef HAVE_SYS_SIGNAL_H
-# include <sys/signal.h>
-#endif
-#include <fcntl.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "gdi.h"
-#include "heap.h"
-#include "dc.h"
-#include "win.h"
-#include "wine/exception.h"
-#include "ddraw.h"
-#include "d3d.h"
-#include "debugtools.h"
-#include "spy.h"
-#include "message.h"
-#include "options.h"
-#include "monitor.h"
-
-static char *ddProp = "WINE_DDRAW_Property";
-
-/* This for all the enumeration and creation of D3D-related objects */
-#include "ddraw_private.h"
-#include "d3d_private.h"
-
-DEFAULT_DEBUG_CHANNEL(ddraw);
-
-/* Restore signal handlers overwritten by XF86DGA 
- */
-#define RESTORE_SIGNALS
-
-/* Get DDSCAPS of surface (shortcutmacro) */
-#define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
-
-/* Get the number of bytes per pixel for a given surface */
-#define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8))
-
-#define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
-
-/* Where do these GUIDs come from?  mkuuid.
- * They exist solely to distinguish between the targets Wine support,
- * and should be different than any other GUIDs in existence.
- */
-static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
-	0xe2dcb020,
-	0xdc60,
-	0x11d1,
-	{0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
-};
-
-static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
-    0x1574a740,
-    0xdc61,
-    0x11d1,
-    {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
-};
-
-#ifdef HAVE_LIBXXF86DGA
-static struct ICOM_VTABLE(IDirectDrawSurface4)	dga_dds4vt;
-static struct ICOM_VTABLE(IDirectDraw)		dga_ddvt;
-static struct ICOM_VTABLE(IDirectDraw2)		dga_dd2vt;
-static struct ICOM_VTABLE(IDirectDraw4)		dga_dd4vt;
-static struct ICOM_VTABLE(IDirectDrawPalette)	dga_ddpalvt;
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-#ifdef HAVE_LIBXXF86DGA2
-static struct ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt;
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-
-static struct ICOM_VTABLE(IDirectDrawSurface4)	xlib_dds4vt;
-static struct ICOM_VTABLE(IDirectDraw)		xlib_ddvt;
-static struct ICOM_VTABLE(IDirectDraw2)		xlib_dd2vt;
-static struct ICOM_VTABLE(IDirectDraw4)		xlib_dd4vt;
-static struct ICOM_VTABLE(IDirectDrawPalette)	xlib_ddpalvt;
-
-static struct ICOM_VTABLE(IDirectDrawClipper)	ddclipvt;
-static struct ICOM_VTABLE(IDirect3D)		d3dvt;
-static struct ICOM_VTABLE(IDirect3D2)		d3d2vt;
-
-/* This is for mode-emulation */
-
-static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
-static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
-static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
-static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
-static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
-static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
-static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
-
-typedef struct {
-  unsigned short bpp;
-  unsigned short depth;
-  unsigned int rmask;
-  unsigned int gmask;
-  unsigned int bmask;
-} ConvertMode;
-
-typedef struct {
-  void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
-  void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
-} ConvertFuncs;
-
-typedef struct {
-  ConvertMode screen, dest;
-  ConvertFuncs funcs;
-} Convert;
-
-static Convert ModeEmulations[] = {
-  { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8,  palette_convert_24_to_8 } },
-  { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, {  16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
-  { { 24, 24,   0xFF0000,   0x00FF00,   0x0000FF }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8,  palette_convert_24_to_8 } },
-  { { 16, 16,     0xF800,     0x07E0,     0x001F }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8,  palette_convert_16_to_8 } },
-  { { 16, 15,     0x7C00,     0x03E0,     0x001F }, {  8,  8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8,  palette_convert_15_to_8 } },
-};
-
-#ifdef HAVE_LIBXXF86VM
-static XF86VidModeModeInfo *orig_mode = NULL;
-#endif
-
-#ifdef HAVE_LIBXXSHM
-static int XShmErrorFlag = 0;
-#endif
-
-static inline BOOL get_option( const char *name, BOOL def )
-{
-    return PROFILE_GetWineIniBool( "x11drv", name, def );
-}
-
-static BYTE
-DDRAW_DGA_Available(void)
-{
-#ifdef HAVE_LIBXXF86DGA
-	int fd, evbase, evret, majver, minver;
-	static BYTE return_value = 0xFF;
-
-	/* This prevents from probing X times for DGA */
-	if (return_value != 0xFF)
-	  return return_value;
-	
-   	if (!get_option( "UseDGA", 1 )) {
-	  return_value = 0;
-     	  return 0;
-	}
-
-	/* First, query the extenstion and its version */
-	if (!TSXF86DGAQueryExtension(display,&evbase,&evret)) {
-	  return_value = 0;
-	  return 0;
-	}
-
-	if (!TSXF86DGAQueryVersion(display,&majver,&minver)) {
-	  return_value = 0;
-	  return 0;
-	}
-
-#ifdef HAVE_LIBXXF86DGA2
-	if (majver >= 2) {
-	  /* We have DGA 2.0 available ! */
-	  if (TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
-	    TSXDGACloseFramebuffer(display, DefaultScreen(display));
-	    return_value = 2;
-	  } else {
-	    return_value = 0;
-	  }
-
-	  return return_value;
-	} else {
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-	
-	  /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
-	  /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
-	  /* others. --stephenc */
-	  if ((fd = open("/dev/mem", O_RDWR)) != -1)
-	    close(fd);
-
-	  if (fd != -1)
-	    return_value = 1;
-	  else
-	    return_value = 0;
-
-	  return return_value;
-#ifdef HAVE_LIBXXF86DGA2  
-	}
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-#else /* defined(HAVE_LIBXXF86DGA) */
-	return 0;
-#endif /* defined(HAVE_LIBXXF86DGA) */
-}
-
-/**********************************************************************/
-
-typedef struct {
-  LPVOID lpCallback;
-  LPVOID lpContext; 
-} DirectDrawEnumerateProcData;
-
-/***********************************************************************
- *		DirectDrawEnumerateExA (DDRAW.*)
- */
-HRESULT WINAPI DirectDrawEnumerateExA(
-  LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
-{
-  TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
-  
-  if (TRACE_ON(ddraw)) {
-    DPRINTF("  Flags : ");
-    if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
-      DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
-    if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
-      DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
-    if (dwFlags & DDENUM_NONDISPLAYDEVICES)
-      DPRINTF("DDENUM_NONDISPLAYDEVICES ");
-    DPRINTF("\n");
-  }
-
-  if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
-    /* For the moment, Wine does not support any 3D only accelerators */
-    return DD_OK;
-  }
-  if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
-    /* For the moment, Wine does not support any attached secondary devices */
-    return DD_OK;
-  }
-  
-  if (DDRAW_DGA_Available()) {
-    TRACE("Enumerating DGA interface\n");
-    if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
-      return DD_OK;
-  }
-
-  TRACE("Enumerating Xlib interface\n");
-  if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
-    return DD_OK;
-  
-  TRACE("Enumerating Default interface\n");
-  if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
-    return DD_OK;
-  
-  return DD_OK;
-}
-
-/***********************************************************************
- *		DirectDrawEnumerateExW (DDRAW.*)
- */
-
-static BOOL CALLBACK DirectDrawEnumerateExProcW(
-	GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, 
-	LPVOID lpContext, HMONITOR hm)
-{
-  DirectDrawEnumerateProcData *pEPD =
-    (DirectDrawEnumerateProcData *) lpContext;
-  LPWSTR lpDriverDescriptionW =
-    HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
-  LPWSTR lpDriverNameW =
-    HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
-
-  BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
-    lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
-
-  HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
-  HeapFree(GetProcessHeap(), 0, lpDriverNameW);
-
-  return bResult;
-}
-
-/**********************************************************************/
-
-HRESULT WINAPI DirectDrawEnumerateExW(
-  LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
-{
-  DirectDrawEnumerateProcData epd;
-  epd.lpCallback = (LPVOID) lpCallback;
-  epd.lpContext = lpContext;
-
-  return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW, 
-				  (LPVOID) &epd, 0);
-}
-
-/***********************************************************************
- *		DirectDrawEnumerateA (DDRAW.*)
- */
-
-static BOOL CALLBACK DirectDrawEnumerateProcA(
-	GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, 
-	LPVOID lpContext, HMONITOR hm)
-{
-  DirectDrawEnumerateProcData *pEPD = 
-    (DirectDrawEnumerateProcData *) lpContext;
-  
-  return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
-    lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
-}
-
-/**********************************************************************/
-
-HRESULT WINAPI DirectDrawEnumerateA(
-  LPDDENUMCALLBACKA lpCallback, LPVOID lpContext) 
-{
-  DirectDrawEnumerateProcData epd;  
-  epd.lpCallback = (LPVOID) lpCallback;
-  epd.lpContext = lpContext;
-
-  return DirectDrawEnumerateExA(DirectDrawEnumerateProcA, 
-				(LPVOID) &epd, 0);
-}
-
-/***********************************************************************
- *		DirectDrawEnumerateW (DDRAW.*)
- */
-
-static BOOL WINAPI DirectDrawEnumerateProcW(
-  GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName, 
-  LPVOID lpContext, HMONITOR hm)
-{
-  DirectDrawEnumerateProcData *pEPD = 
-    (DirectDrawEnumerateProcData *) lpContext;
-  
-  return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
-    lpGUID, lpDriverDescription, lpDriverName, 
-    pEPD->lpContext);
-}
-
-/**********************************************************************/
-
-HRESULT WINAPI DirectDrawEnumerateW(
-  LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) 
-{
-  DirectDrawEnumerateProcData epd;  
-  epd.lpCallback = (LPVOID) lpCallback;
-  epd.lpContext = lpContext;
-
-  return DirectDrawEnumerateExW(DirectDrawEnumerateProcW, 
-				(LPVOID) &epd, 0);
-}
-
-/***********************************************************************
- *		DSoundHelp (DDRAW.?)
- */
-
-/* What is this doing here? */
-HRESULT WINAPI 
-DSoundHelp(DWORD x,DWORD y,DWORD z) {
-	FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
-	return 0;
-}
-
-/******************************************************************************
- *		internal helper functions
- */
-static void _dump_DDBLTFX(DWORD flagmask) {
-	int	i;
-	const struct {
-		DWORD	mask;
-		char	*name;
-	} flags[] = {
-#define FE(x) { x, #x},
-		FE(DDBLTFX_ARITHSTRETCHY)
-		FE(DDBLTFX_MIRRORLEFTRIGHT)
-		FE(DDBLTFX_MIRRORUPDOWN)
-		FE(DDBLTFX_NOTEARING)
-		FE(DDBLTFX_ROTATE180)
-		FE(DDBLTFX_ROTATE270)
-		FE(DDBLTFX_ROTATE90)
-		FE(DDBLTFX_ZBUFFERRANGE)
-		FE(DDBLTFX_ZBUFFERBASEDEST)
-#undef FE
-	};
-	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
-	   if (flags[i].mask & flagmask) {
-	      DPRINTF("%s ",flags[i].name);
-	      
-	   };
-	DPRINTF("\n");
-	
-}
-
-static void _dump_DDBLTFAST(DWORD flagmask) {
-	int	i;
-	const struct {
-		DWORD	mask;
-		char	*name;
-	} flags[] = {
-#define FE(x) { x, #x},
-		FE(DDBLTFAST_NOCOLORKEY)
-		FE(DDBLTFAST_SRCCOLORKEY)
-		FE(DDBLTFAST_DESTCOLORKEY)
-		FE(DDBLTFAST_WAIT)
-#undef FE
-	};
-	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
-		if (flags[i].mask & flagmask)
-			DPRINTF("%s ",flags[i].name);
-	DPRINTF("\n");
-}
-
-static void _dump_DDBLT(DWORD flagmask) {
-	int	i;
-	const struct {
-		DWORD	mask;
-		char	*name;
-	} flags[] = {
-#define FE(x) { x, #x},
-		FE(DDBLT_ALPHADEST)
-		FE(DDBLT_ALPHADESTCONSTOVERRIDE)
-		FE(DDBLT_ALPHADESTNEG)
-		FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
-		FE(DDBLT_ALPHAEDGEBLEND)
-		FE(DDBLT_ALPHASRC)
-		FE(DDBLT_ALPHASRCCONSTOVERRIDE)
-		FE(DDBLT_ALPHASRCNEG)
-		FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
-		FE(DDBLT_ASYNC)
-		FE(DDBLT_COLORFILL)
-		FE(DDBLT_DDFX)
-		FE(DDBLT_DDROPS)
-		FE(DDBLT_KEYDEST)
-		FE(DDBLT_KEYDESTOVERRIDE)
-		FE(DDBLT_KEYSRC)
-		FE(DDBLT_KEYSRCOVERRIDE)
-		FE(DDBLT_ROP)
-		FE(DDBLT_ROTATIONANGLE)
-		FE(DDBLT_ZBUFFER)
-		FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
-		FE(DDBLT_ZBUFFERDESTOVERRIDE)
-		FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
-		FE(DDBLT_ZBUFFERSRCOVERRIDE)
-		FE(DDBLT_WAIT)
-		FE(DDBLT_DEPTHFILL)
-#undef FE
-	};
-	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
-		if (flags[i].mask & flagmask)
-			DPRINTF("%s ",flags[i].name);
-	DPRINTF("\n");
-}
-
-static void _dump_DDSCAPS(void *in) {
-	int	i;
-	const struct {
-		DWORD	mask;
-		char	*name;
-	} flags[] = {
-#define FE(x) { x, #x},
-		FE(DDSCAPS_RESERVED1)
-		FE(DDSCAPS_ALPHA)
-		FE(DDSCAPS_BACKBUFFER)
-		FE(DDSCAPS_COMPLEX)
-		FE(DDSCAPS_FLIP)
-		FE(DDSCAPS_FRONTBUFFER)
-		FE(DDSCAPS_OFFSCREENPLAIN)
-		FE(DDSCAPS_OVERLAY)
-		FE(DDSCAPS_PALETTE)
-		FE(DDSCAPS_PRIMARYSURFACE)
-		FE(DDSCAPS_PRIMARYSURFACELEFT)
-		FE(DDSCAPS_SYSTEMMEMORY)
-		FE(DDSCAPS_TEXTURE)
-		FE(DDSCAPS_3DDEVICE)
-		FE(DDSCAPS_VIDEOMEMORY)
-		FE(DDSCAPS_VISIBLE)
-		FE(DDSCAPS_WRITEONLY)
-		FE(DDSCAPS_ZBUFFER)
-		FE(DDSCAPS_OWNDC)
-		FE(DDSCAPS_LIVEVIDEO)
-		FE(DDSCAPS_HWCODEC)
-		FE(DDSCAPS_MODEX)
-		FE(DDSCAPS_MIPMAP)
-		FE(DDSCAPS_RESERVED2)
-		FE(DDSCAPS_ALLOCONLOAD)
-		FE(DDSCAPS_VIDEOPORT)
-		FE(DDSCAPS_LOCALVIDMEM)
-		FE(DDSCAPS_NONLOCALVIDMEM)
-		FE(DDSCAPS_STANDARDVGAMODE)
-		FE(DDSCAPS_OPTIMIZED)
-#undef FE
-	};
-	DWORD flagmask = *((DWORD *) in);
-	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
-		if (flags[i].mask & flagmask)
-			DPRINTF("%s ",flags[i].name);
-}
-
-static void _dump_pixelformat_flag(DWORD flagmask) {
-	int	i;
-	const struct {
-		DWORD	mask;
-		char	*name;
-	} flags[] = {
-#define FE(x) { x, #x},
-	        FE(DDPF_ALPHAPIXELS)
-		FE(DDPF_ALPHA)
-		FE(DDPF_FOURCC)
-		FE(DDPF_PALETTEINDEXED4)
-		FE(DDPF_PALETTEINDEXEDTO8)
-		FE(DDPF_PALETTEINDEXED8)
-		FE(DDPF_RGB)
-		FE(DDPF_COMPRESSED)
-		FE(DDPF_RGBTOYUV)
-		FE(DDPF_YUV)
-		FE(DDPF_ZBUFFER)
-		FE(DDPF_PALETTEINDEXED1)
-		FE(DDPF_PALETTEINDEXED2)
-		FE(DDPF_ZPIXELS)
-#undef FE
-	};
-	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
-		if (flags[i].mask & flagmask)
-			DPRINTF("%s ",flags[i].name);
-}
-
-static void _dump_paletteformat(DWORD dwFlags) {
-  int	i;
-  const struct {
-    DWORD	mask;
-    char	*name;
-  } flags[] = {
-#define FE(x) { x, #x},
-    FE(DDPCAPS_4BIT)
-    FE(DDPCAPS_8BITENTRIES)
-    FE(DDPCAPS_8BIT)
-    FE(DDPCAPS_INITIALIZE)
-    FE(DDPCAPS_PRIMARYSURFACE)
-    FE(DDPCAPS_PRIMARYSURFACELEFT)
-    FE(DDPCAPS_ALLOW256)
-    FE(DDPCAPS_VSYNC)
-    FE(DDPCAPS_1BIT)
-    FE(DDPCAPS_2BIT)
-    FE(DDPCAPS_ALPHA)
-#undef FE
-  };
-  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
-    if (flags[i].mask & dwFlags)
-      DPRINTF("%s ",flags[i].name);
-  DPRINTF("\n");
-}
-
-static void _dump_pixelformat(void *in) {
-  LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
-  char *cmd;
-  
-  DPRINTF("( ");
-  _dump_pixelformat_flag(pf->dwFlags);
-  if (pf->dwFlags & DDPF_FOURCC) {
-    DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
-  }
-  if (pf->dwFlags & DDPF_RGB) {
-    DPRINTF(", RGB bits: %ld, ", pf->u.dwRGBBitCount);
-    switch (pf->u.dwRGBBitCount) {
-    case 4:
-      cmd = "%1lx";
-      break;
-    case 8:
-      cmd = "%02lx";
-      break;
-    case 16:
-      cmd = "%04lx";
-      break;
-    case 24:
-      cmd = "%06lx";
-      break;
-    case 32:
-      cmd = "%08lx";
-      break;
-    default:
-      ERR("Unexpected bit depth !\n");
-      cmd = "%d";
-    }
-    DPRINTF(" R "); DPRINTF(cmd, pf->u1.dwRBitMask);
-    DPRINTF(" G "); DPRINTF(cmd, pf->u2.dwGBitMask);
-    DPRINTF(" B "); DPRINTF(cmd, pf->u3.dwBBitMask);
-    if (pf->dwFlags & DDPF_ALPHAPIXELS) {
-      DPRINTF(" A "); DPRINTF(cmd, pf->u4.dwRGBAlphaBitMask);
-    }
-    if (pf->dwFlags & DDPF_ZPIXELS) {
-      DPRINTF(" Z "); DPRINTF(cmd, pf->u4.dwRGBZBitMask);
-}
-  }
-  if (pf->dwFlags & DDPF_ZBUFFER) {
-    DPRINTF(", Z bits : %ld", pf->u.dwZBufferBitDepth);
-  }
-  if (pf->dwFlags & DDPF_ALPHA) {
-    DPRINTF(", Alpha bits : %ld", pf->u.dwAlphaBitDepth);
-  }
-  DPRINTF(")");
-}
-
-static void _dump_colorkeyflag(DWORD ck) {
-	int	i;
-	const struct {
-		DWORD	mask;
-		char	*name;
-	} flags[] = {
-#define FE(x) { x, #x},
-	  FE(DDCKEY_COLORSPACE)
-	  FE(DDCKEY_DESTBLT)
-	  FE(DDCKEY_DESTOVERLAY)
-	  FE(DDCKEY_SRCBLT)
-	  FE(DDCKEY_SRCOVERLAY)
-#undef FE
-	};
-	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
-		if (flags[i].mask & ck)
-			DPRINTF("%s ",flags[i].name);
-}
-
-static void _dump_DWORD(void *in) {
-  DPRINTF("%ld", *((DWORD *) in));
-}
-static void _dump_PTR(void *in) {
-  DPRINTF("%p", *((void **) in));
-}
-static void _dump_DDCOLORKEY(void *in) {
-  DDCOLORKEY *ddck = (DDCOLORKEY *) in;
-
-  DPRINTF(" Low : %ld  - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
-}
-
-static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
-  int	i;
-  struct {
-    DWORD	mask;
-    char	*name;
-    void (*func)(void *);
-    void        *elt;
-  } flags[16], *fe = flags;
-#define FE(x,f,e) do { fe->mask = x;  fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
-    FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps);
-    FE(DDSD_HEIGHT, _dump_DWORD, dwHeight);
-    FE(DDSD_WIDTH, _dump_DWORD, dwWidth);
-    FE(DDSD_PITCH, _dump_DWORD, lPitch);
-    FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount);
-    FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, u.dwZBufferBitDepth);
-    FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth);
-    FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat);
-    FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay);
-    FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt);
-    FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay);
-    FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt);
-    FE(DDSD_MIPMAPCOUNT, _dump_DWORD, u.dwMipMapCount);
-    FE(DDSD_REFRESHRATE, _dump_DWORD, u.dwRefreshRate);
-    FE(DDSD_LINEARSIZE, _dump_DWORD, u1.dwLinearSize);
-    FE(DDSD_LPSURFACE, _dump_PTR, u1.lpSurface);
-#undef FE
-
-  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
-    if (flags[i].mask & lpddsd->dwFlags) {
-      DPRINTF(" - %s : ",flags[i].name);
-      flags[i].func(flags[i].elt);
-	DPRINTF("\n");  
-}
-}
-
-
-/******************************************************************************
- *		IDirectDrawSurface methods
- *
- * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
- * DDS and DDS2 use those functions. (Function calls did not change (except
- * using different DirectDrawSurfaceX version), just added flags and functions)
- */
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
-    LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
-) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-        TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
-		This,lprect,lpddsd,flags,(DWORD)hnd);
-	if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
-	    WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
-			 This,lprect,lpddsd,flags,(DWORD)hnd);
-
-	/* First, copy the Surface description */
-	*lpddsd = This->s.surface_desc;
-	TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
-	      lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
-
-	/* If asked only for a part, change the surface pointer */
-	if (lprect) {
-		TRACE("	lprect: %dx%d-%dx%d\n",
-			lprect->top,lprect->left,lprect->bottom,lprect->right
-		);
-		if ((lprect->top < 0) ||
-		    (lprect->left < 0) ||
-		    (lprect->bottom < 0) ||
-		    (lprect->right < 0)) {
-		  ERR(" Negative values in LPRECT !!!\n");
-		  return DDERR_INVALIDPARAMS;
-               }
-               
-		lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
-			(lprect->top*This->s.surface_desc.lPitch) +
-			lprect->left*GET_BPP(This->s.surface_desc));
-	} else {
-		assert(This->s.surface_desc.u1.lpSurface);
-	}
-
-	/* wait for any previous operations to complete */
-#ifdef HAVE_LIBXXSHM
-        if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE) &&
-	    This->s.ddraw->e.xlib.xshm_active) {
-/*
-	  int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
-          if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
-*/
-          X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
-	}
-#endif
-	return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
-	LPDIRECTDRAWSURFACE4 iface,LPVOID surface
-) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-	TRACE("(%p)->Unlock(%p)\n",This,surface);
-	return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
-  if (This->s.ddraw->d.pixel_convert != NULL)
-    This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
-				   This->t.xlib.image->data,
-				   This->s.surface_desc.dwWidth,
-				   This->s.surface_desc.dwHeight,
-				   This->s.surface_desc.lPitch,
-				   This->s.palette);
-
-#ifdef HAVE_LIBXXSHM
-    if (This->s.ddraw->e.xlib.xshm_active) {
-/*
-      X11DRV_EVENT_WaitReplaceShmCompletion( &This->s.ddraw->e.xlib.xshm_compl, This->s.ddraw->d.drawable );
-*/
-      /* let WaitShmCompletions track 'em for now */
-      /* (you may want to track it again whenever you implement DX7's partial surface locking,
-          where threads have concurrent access) */
-      X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable );
-      TSXShmPutImage(display,
-		     This->s.ddraw->d.drawable,
-		     DefaultGCOfScreen(X11DRV_GetXScreen()),
-		     This->t.xlib.image,
-		     0, 0, 0, 0,
-		     This->t.xlib.image->width,
-		     This->t.xlib.image->height,
-		     True);
-      /* make sure the image is transferred ASAP */
-      TSXFlush(display);
-    }
-    else
-#endif
-	TSXPutImage(		display,
-				This->s.ddraw->d.drawable,
-				DefaultGCOfScreen(X11DRV_GetXScreen()),
-				This->t.xlib.image,
-				0, 0, 0, 0,
-				This->t.xlib.image->width,
-		  This->t.xlib.image->height);
-}
-
-static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
-	LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
-{
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-    TRACE("(%p)->Unlock(%p)\n",This,surface);
-
-    if (!This->s.ddraw->d.paintable)
-	return DD_OK;
-
-    /* Only redraw the screen when unlocking the buffer that is on screen */
-    if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
-	Xlib_copy_surface_on_screen(This);
-
-	if (This->s.palette && This->s.palette->cm)
-	    TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
-    }
-    return DD_OK;
-}
-
-static IDirectDrawSurface4Impl* _common_find_flipto(
-	IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
-) {
-    int	i,j,flipable=0;
-    struct _surface_chain	*chain = This->s.chain;
-
-    /* if there was no override flipto, look for current backbuffer */
-    if (!flipto) {
-	/* walk the flip chain looking for backbuffer */
-	for (i=0;i<chain->nrofsurfaces;i++) {
-	    if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
-	    	flipable++;
-	    if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
-		flipto = chain->surfaces[i];
-	}
-	/* sanity checks ... */
-	if (!flipto) {
-	    if (flipable>1) {
-		for (i=0;i<chain->nrofsurfaces;i++)
-		    if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
-		    	break;
-		if (i==chain->nrofsurfaces) {
-		    /* we do not have a frontbuffer either */
-		    for (i=0;i<chain->nrofsurfaces;i++)
-			if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
-			    SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
-			    break;
-			}
-		    for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
-		    	int k = j % chain->nrofsurfaces;
-			if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
-			    SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
-			    flipto = chain->surfaces[k];
-			    break;
-			}
-		    }
-		}
-	    }
-	    if (!flipto)
-		flipto = This;
-	}
-	TRACE("flipping to %p\n",flipto);
-    }
-    return flipto;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
-	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
-) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-    IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
-    DWORD	xheight;
-    LPBYTE	surf;
-
-    TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
-    iflipto = _common_find_flipto(This,iflipto);
-
-    /* and flip! */
-    TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
-    if (iflipto->s.palette && iflipto->s.palette->cm)
-	    TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
-    while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
-
-    }
-    /* We need to switch the lowlevel surfaces, for DGA this is: */
-
-    /* The height within the framebuffer */
-    xheight			= This->t.dga.fb_height;
-    This->t.dga.fb_height	= iflipto->t.dga.fb_height;
-    iflipto->t.dga.fb_height	= xheight;
-
-    /* And the assciated surface pointer */
-    surf				= This->s.surface_desc.u1.lpSurface;
-    This->s.surface_desc.u1.lpSurface	= iflipto->s.surface_desc.u1.lpSurface;
-    iflipto->s.surface_desc.u1.lpSurface	= surf;
-
-    return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-#ifdef HAVE_LIBXXF86DGA2
-static HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
-	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
-) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-    IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
-    DWORD	xheight;
-    LPBYTE	surf;
-
-    TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
-    iflipto = _common_find_flipto(This,iflipto);
-
-    /* and flip! */
-    TSXDGASetViewport(display,DefaultScreen(display),0,iflipto->t.dga.fb_height, XDGAFlipRetrace);
-    TSXDGASync(display,DefaultScreen(display));
-    TSXFlush(display);
-    if (iflipto->s.palette && iflipto->s.palette->cm)
-	    TSXDGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
-    /* We need to switch the lowlevel surfaces, for DGA this is: */
-
-    /* The height within the framebuffer */
-    xheight			= This->t.dga.fb_height;
-    This->t.dga.fb_height	= iflipto->t.dga.fb_height;
-    iflipto->t.dga.fb_height	= xheight;
-
-    /* And the assciated surface pointer */
-    surf	                         = This->s.surface_desc.u1.lpSurface;
-    This->s.surface_desc.u1.lpSurface    = iflipto->s.surface_desc.u1.lpSurface;
-    iflipto->s.surface_desc.u1.lpSurface = surf;
-
-    return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-
-static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
-	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
-) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-    XImage	*image;
-    LPBYTE	surf;
-    IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
-
-    TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
-    iflipto = _common_find_flipto(This,iflipto);
-
-#if defined(HAVE_MESAGL) && 0 /* does not work */
-	if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
-	  TRACE(" - OpenGL flip\n");
-	  ENTER_GL();
-	  glXSwapBuffers(display, This->s.ddraw->d.drawable);
-	  LEAVE_GL();
-
-	  return DD_OK;
-	}
-#endif /* defined(HAVE_MESAGL) */
-	
-    if (!This->s.ddraw->d.paintable)
-	    return DD_OK;
-
-    /* We need to switch the lowlevel surfaces, for xlib this is: */
-    /* The surface pointer */
-    surf				= This->s.surface_desc.u1.lpSurface;
-    This->s.surface_desc.u1.lpSurface	= iflipto->s.surface_desc.u1.lpSurface;
-    iflipto->s.surface_desc.u1.lpSurface	= surf;
-    /* the associated ximage */
-    image				= This->t.xlib.image;
-    This->t.xlib.image			= iflipto->t.xlib.image;
-    iflipto->t.xlib.image		= image;
-
-#ifdef HAVE_LIBXXSHM
-    if (This->s.ddraw->e.xlib.xshm_active) {
-/*
-      int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
-      if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
-*/
-      X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
-    }
-#endif
-    Xlib_copy_surface_on_screen(This);
-
-    if (iflipto->s.palette && iflipto->s.palette->cm)
-	TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
-    return DD_OK;
-}
-
-/* The IDirectDrawSurface4::SetPalette method attaches the specified
- * DirectDrawPalette object to a surface. The surface uses this palette for all
- * subsequent operations. The palette change takes place immediately.
- */
-static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
-	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
-) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-        IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
-	int i;
-	TRACE("(%p)->(%p)\n",This,ipal);
-
-	if (ipal == NULL) {
-          if( This->s.palette != NULL )
-            IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
-	  This->s.palette = ipal;
-
-	  return DD_OK;
-	}
-	
-	if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8)) 
-	{
-            ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
-                                         X11DRV_GetVisual(),AllocAll);
-
-    	    	if (!Options.managed)
-			TSXInstallColormap(display,ipal->cm);
-
-		for (i=0;i<256;i++) {
-			XColor xc;
-
-			xc.red = ipal->palents[i].peRed<<8;
-			xc.blue = ipal->palents[i].peBlue<<8;
-			xc.green = ipal->palents[i].peGreen<<8;
-			xc.flags = DoRed|DoBlue|DoGreen;
-			xc.pixel = i;
-			TSXStoreColor(display,ipal->cm,&xc);
-		}
-		TSXInstallColormap(display,ipal->cm);
-        }
-
-        /* According to spec, we are only supposed to 
-         * AddRef if this is not the same palette.
-         */
-        if( This->s.palette != ipal )
-        {
-          if( ipal != NULL )
-            IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
-          if( This->s.palette != NULL )
-            IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
-	  This->s.palette = ipal; 
-          /* Perform the refresh */
-          TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
-        }
-	return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
-	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
-) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-        IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
-	TRACE("(%p)->(%p)\n",This,ipal);
-
-        /* According to spec, we are only supposed to 
-         * AddRef if this is not the same palette.
-         */
-        if( This->s.palette != ipal )
-        {
-          if( ipal != NULL ) 
-	  	IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
-          if( This->s.palette != NULL )
-            IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
-	  This->s.palette = ipal;
-#ifdef HAVE_LIBXXF86DGA2
-	  if (This->s.ddraw->e.dga.version == 2)
-	    TSXDGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
-	  else
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-	    TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
-        }
-	return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
-{
-	int x, y;
-	LPBYTE first;
-
-	/* Do first row */
-
-#define COLORFILL_ROW(type) { \
-	type *d = (type *) buf; \
-	for (x = 0; x < width; x++) \
-		d[x] = (type) color; \
-	break; \
-}
-
-	switch(bpp) {
-	case 1: COLORFILL_ROW(BYTE)
-	case 2: COLORFILL_ROW(WORD)
-	case 4: COLORFILL_ROW(DWORD)
-	default:
-	FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
-	return DDERR_UNSUPPORTED;
-	}
-
-#undef COLORFILL_ROW
-
-	/* Now copy first row */
-	first = buf;
-	for (y = 1; y < height; y++) {
-		buf += lPitch;
-		memcpy(buf, first, width * bpp);
-	}
-
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
-	LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
-) {
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  RECT	xdst,xsrc;
-  DDSURFACEDESC	ddesc,sdesc;
-  HRESULT			ret = DD_OK;
-  int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
-  int x, y;
-  LPBYTE dbuf, sbuf;
-  
-  TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
-  
-  if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
-  IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
-  
-  if (TRACE_ON(ddraw)) {
-    if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
-    if (rsrc) TRACE("\tsrcrect  :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
-    TRACE("\tflags: ");
-    _dump_DDBLT(dwFlags);
-    if (dwFlags & DDBLT_DDFX) {
-      TRACE("\tblitfx: ");
-      _dump_DDBLTFX(lpbltfx->dwDDFX);
-    }
-  }
-  
-  if (rdst) {
-    if ((rdst->top < 0) ||
-        (rdst->left < 0) ||
-        (rdst->bottom < 0) ||
-        (rdst->right < 0)) {
-      ERR(" Negative values in LPRECT !!!\n");
-      goto release;
-    }
-    memcpy(&xdst,rdst,sizeof(xdst));
-  } else {
-    xdst.top	= 0;
-    xdst.bottom	= ddesc.dwHeight;
-    xdst.left	= 0;
-    xdst.right	= ddesc.dwWidth;
-  }
-  
-  if (rsrc) {
-    if ((rsrc->top < 0) ||
-        (rsrc->left < 0) ||
-        (rsrc->bottom < 0) ||
-        (rsrc->right < 0)) {
-      ERR(" Negative values in LPRECT !!!\n");
-      goto release;
-    }
-    memcpy(&xsrc,rsrc,sizeof(xsrc));
-  } else {
-    if (src) {
-      xsrc.top	= 0;
-      xsrc.bottom	= sdesc.dwHeight;
-      xsrc.left	= 0;
-      xsrc.right	= sdesc.dwWidth;
-    } else {
-      memset(&xsrc,0,sizeof(xsrc));
-    }
-  }
-  
-  bpp = GET_BPP(ddesc);
-  srcheight = xsrc.bottom - xsrc.top;
-  srcwidth = xsrc.right - xsrc.left;
-  dstheight = xdst.bottom - xdst.top;
-  dstwidth = xdst.right - xdst.left;
-  width = (xdst.right - xdst.left) * bpp;
-  dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
-  
-  dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
-  
-  /* First, all the 'source-less' blits */
-  if (dwFlags & DDBLT_COLORFILL) {
-    ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
-			 ddesc.lPitch, lpbltfx->u4.dwFillColor);
-    dwFlags &= ~DDBLT_COLORFILL;
-  }
-  
-  if (dwFlags & DDBLT_DEPTHFILL) {
-#ifdef HAVE_MESAGL
-    GLboolean ztest;
-    
-    /* Clears the screen */
-    TRACE("	Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth);
-    glClearDepth(lpbltfx->u4.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
-    glGetBooleanv(GL_DEPTH_TEST, &ztest);
-    glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
-    glClear(GL_DEPTH_BUFFER_BIT);
-    glDepthMask(ztest);
-    
-    dwFlags &= ~(DDBLT_DEPTHFILL);
-#endif /* defined(HAVE_MESAGL) */
-  }
-	
-  if (dwFlags & DDBLT_ROP) {
-    /* Catch some degenerate cases here */
-    switch(lpbltfx->dwROP) {
-    case BLACKNESS:
-      ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
-      break;
-    case 0xAA0029: /* No-op */
-      break;
-    case WHITENESS:
-      ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
-      break;
-    default: 
-      FIXME("Unsupported raster op: %08lx  Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
-      goto error;
-    }
-    dwFlags &= ~DDBLT_ROP;
-  }
-
-  if (dwFlags & DDBLT_DDROPS) {
-    FIXME("\tDdraw Raster Ops: %08lx  Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
-  }
-  
-  /* Now the 'with source' blits */
-  if (src) {
-    LPBYTE sbase;
-    int sx, xinc, sy, yinc;
-    
-    sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
-    xinc = (srcwidth << 16) / dstwidth;
-    yinc = (srcheight << 16) / dstheight;
-    
-    if (!dwFlags) {
-      
-      /* No effects, we can cheat here */
-      if (dstwidth == srcwidth) {
-	if (dstheight == srcheight) {
-	  /* No stretching in either direction.  This needs to be as fast as possible */
-	  sbuf = sbase;
-	  for (y = 0; y < dstheight; y++) {
-	    memcpy(dbuf, sbuf, width);
-	    sbuf += sdesc.lPitch;
-	    dbuf += ddesc.lPitch;
-	  }
-	} else {
-	  /* Stretching in Y direction only */
-	  for (y = sy = 0; y < dstheight; y++, sy += yinc) {
-	    sbuf = sbase + (sy >> 16) * sdesc.lPitch;
-	    memcpy(dbuf, sbuf, width);
-	    dbuf += ddesc.lPitch;
-	  }
-	}
-      } else {
-	/* Stretching in X direction */
-	int last_sy = -1;
-	for (y = sy = 0; y < dstheight; y++, sy += yinc) {
-	  sbuf = sbase + (sy >> 16) * sdesc.lPitch;
-	  
-	  if ((sy >> 16) == (last_sy >> 16)) {
-	    /* Same as last row - copy already stretched row */
-	    memcpy(dbuf, dbuf - ddesc.lPitch, width);
-	  } else {
-
-#define STRETCH_ROW(type) { \
-	type *s = (type *) sbuf, *d = (type *) dbuf; \
-	for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
-		d[x] = s[sx >> 16]; \
-	break; }
-	      
-	    switch(bpp) {
-	    case 1: STRETCH_ROW(BYTE)
-	    case 2: STRETCH_ROW(WORD)
-	    case 4: STRETCH_ROW(DWORD)
-	    case 3: {
-		LPBYTE s,d;
-		for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {
-			DWORD pixel;
-
-			s = sbuf+3*(sx>>16);
-			d = dbuf+3*x;
-			pixel = (s[0]<<16)|(s[1]<<8)|s[2];
-			d[0] = (pixel>>16)&0xff;
-			d[1] = (pixel>> 8)&0xff;
-			d[2] = (pixel    )&0xff;
-		}
-		break;
-	    }
-	    default:
-	      FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
-	      ret = DDERR_UNSUPPORTED;
-	      goto error;
-	    }
-	    
-#undef STRETCH_ROW
-	    
-	  }
-	  last_sy = sy;
-	  dbuf += ddesc.lPitch;
-	}
-      }
-    } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
-      DWORD keylow, keyhigh;
-      
-      if (dwFlags & DDBLT_KEYSRC) {
-	keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
-	keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
-      } else {
-	/* I'm not sure if this is correct */
-	FIXME("DDBLT_KEYDEST not fully supported yet.\n");
-	keylow  = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
-	keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
-      }
-      
-		
-      for (y = sy = 0; y < dstheight; y++, sy += yinc) {
-	sbuf = sbase + (sy >> 16) * sdesc.lPitch;
-	
-#define COPYROW_COLORKEY(type) { \
-	type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
-	for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
-		tmp = s[sx >> 16]; \
-		if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
-	} \
-	break; }
-	  
-	switch (bpp) {
-	case 1: COPYROW_COLORKEY(BYTE)
-	case 2: COPYROW_COLORKEY(WORD)
-	case 4: COPYROW_COLORKEY(DWORD)
-	default:
-	  FIXME("%s color-keyed blit not implemented for bpp %d!\n",
-		(dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
-	  ret = DDERR_UNSUPPORTED;
-	  goto error;
-	}
-	dbuf += ddesc.lPitch;
-      }
-
-#undef COPYROW_COLORKEY
-			
-      dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
-      
-    }
-  }
-  
- error:
-  
-  if (dwFlags && FIXME_ON(ddraw)) {
-    FIXME("\tUnsupported flags: ");
-    _dump_DDBLT(dwFlags);
-  }
-  release:
-  
-  IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
-  if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
-	LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
-) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-	int				bpp, w, h, x, y;
-	DDSURFACEDESC	ddesc,sdesc;
-	HRESULT			ret = DD_OK;
-	LPBYTE			sbuf, dbuf;
-	RECT                            rsrc2;
-
-
-	if (TRACE_ON(ddraw)) {
-	    FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
-		    This,dstx,dsty,src,rsrc,trans
-	    );
-	    FIXME("	trans:");
-	    if (FIXME_ON(ddraw))
-	      _dump_DDBLTFAST(trans);
-	    if (rsrc)
-	      FIXME("        srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
-	    else
-	      FIXME(" srcrect: NULL\n");
-	}
-	
-	/* We need to lock the surfaces, or we won't get refreshes when done. */
-	IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
-	IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
-
-       if (!rsrc) {
-               WARN("rsrc is NULL!\n");
-               rsrc = &rsrc2;
-               rsrc->left = rsrc->top = 0;
-               rsrc->right = sdesc.dwWidth;
-               rsrc->bottom = sdesc.dwHeight;
-       }
-
-	bpp = GET_BPP(This->s.surface_desc);
-	sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
-	dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty      * ddesc.lPitch) + dstx       * bpp;
-
-
-	h=rsrc->bottom-rsrc->top;
-	if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
-	if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
-	if (h<0) h=0;
-
-	w=rsrc->right-rsrc->left;
-	if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
-	if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
-	if (w<0) w=0;
-
-	if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
-		DWORD keylow, keyhigh;
-		if (trans & DDBLTFAST_SRCCOLORKEY) {
-			keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
-			keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
-		} else {
-			/* I'm not sure if this is correct */
-			FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
-			keylow  = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
-			keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
-		}
-
-#define COPYBOX_COLORKEY(type) { \
-	type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
-	s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
-	d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
-	for (y = 0; y < h; y++) { \
-		for (x = 0; x < w; x++) { \
-			tmp = s[x]; \
-			if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
-		} \
-		(LPBYTE)s += sdesc.lPitch; \
-		(LPBYTE)d += ddesc.lPitch; \
-	} \
-	break; \
-}
-
-		switch (bpp) {
-			case 1: COPYBOX_COLORKEY(BYTE)
-			case 2: COPYBOX_COLORKEY(WORD)
-			case 4: COPYBOX_COLORKEY(DWORD)
-			default:
-				FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
-				ret = DDERR_UNSUPPORTED;
-				goto error;
-	}
-
-#undef COPYBOX_COLORKEY
-
-	} else {
-		int width = w * bpp;
-
-		for (y = 0; y < h; y++) {
-			memcpy(dbuf, sbuf, width);
-			sbuf += sdesc.lPitch;
-			dbuf += ddesc.lPitch;
-		}
-	}
-
-error:
-
-	IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
-	IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
-	return ret;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
-	LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
-) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-	FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
-		This,ddbltbatch,x,y
-	);
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
-	LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
-) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-	TRACE("(%p)->GetCaps(%p)\n",This,caps);
-	caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
-	LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
-) { 
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-    TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
-  
-    /* Simply copy the surface description stored in the object */
-    *ddsd = This->s.surface_desc;
-  
-    if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
-
-    return DD_OK;
-}
-
-static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-    TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
-    return ++(This->ref);
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-
-    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-    if (--(This->ref))
-    	return This->ref;
-
-    IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
-    /* clear out of surface list */
-    if (This->t.dga.fb_height == -1)
-	HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
-    else
-	This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
-
-    /* Free the DIBSection (if any) */
-    if (This->s.hdc != 0) {
-      SelectObject(This->s.hdc, This->s.holdbitmap);
-      DeleteDC(This->s.hdc);
-      DeleteObject(This->s.DIBsection);
-    }
-
-    /* Free the clipper if attached to this surface */
-    if( This->s.lpClipper )
-      IDirectDrawClipper_Release(This->s.lpClipper);
-    
-    HeapFree(GetProcessHeap(),0,This);
-    return S_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-
-    TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
-
-    if (--(This->ref))
-    	return This->ref;
-
-    IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
-
-    if (This->t.xlib.image != NULL) {
-	if (This->s.ddraw->d.pixel_convert != NULL) {
-	    /* In pixel conversion mode, there are 2 buffers to release. */
-	    HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
-
-#ifdef HAVE_LIBXXSHM
-	    if (This->s.ddraw->e.xlib.xshm_active) {
-		TSXShmDetach(display, &(This->t.xlib.shminfo));
-		TSXDestroyImage(This->t.xlib.image);
-		shmdt(This->t.xlib.shminfo.shmaddr);
-	    } else {
-#endif
-		HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
-		This->t.xlib.image->data = NULL;
-		TSXDestroyImage(This->t.xlib.image);
-#ifdef HAVE_LIBXXSHM
-	    }
-#endif
-	} else {
-	    This->t.xlib.image->data = NULL;
-
-#ifdef HAVE_LIBXXSHM
-	    if (This->s.ddraw->e.xlib.xshm_active) {
-		TSXShmDetach(display, &(This->t.xlib.shminfo));
-		TSXDestroyImage(This->t.xlib.image);
-		shmdt(This->t.xlib.shminfo.shmaddr);
-	    } else {
-#endif
-		HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
-		TSXDestroyImage(This->t.xlib.image);
-#ifdef HAVE_LIBXXSHM	
-	    }
-#endif
-	}
-	This->t.xlib.image = 0;
-    } else {
-	HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
-    }
-
-    if (This->s.palette)
-	IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
-
-    /* Free the DIBSection (if any) */
-    if (This->s.hdc != 0) {
-	SelectObject(This->s.hdc, This->s.holdbitmap);
-	DeleteDC(This->s.hdc);
-	DeleteObject(This->s.DIBsection);
-    }
-
-    /* Free the clipper if present */
-    if( This->s.lpClipper )
-      IDirectDrawClipper_Release(This->s.lpClipper);
-
-    HeapFree(GetProcessHeap(),0,This);
-    return S_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
-	LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
-) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-    int	i,found = 0,xstart;
-    struct _surface_chain	*chain;
-
-    TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
-    if (TRACE_ON(ddraw)) {
-	TRACE("	caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
-	DPRINTF("\n");
-    }
-    chain = This->s.chain;
-    if (!chain)
-    	return DDERR_NOTFOUND;
-
-    for (i=0;i<chain->nrofsurfaces;i++)
-    	if (chain->surfaces[i] == This)
-	    break;
-
-    xstart = i;
-    for (i=0;i<chain->nrofsurfaces;i++) {
-	if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
-#if 0
-	    if (found) /* may not find the same caps twice, (doc) */
-		return DDERR_INVALIDPARAMS;/*FIXME: correct? */
-#endif
-	    found = (i+1)+xstart;
-	}
-    }
-    if (!found)
-	return DDERR_NOTFOUND;
-    *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
-    /* FIXME: AddRef? */
-    TRACE("found %p\n",*lpdsf);
-    return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
-	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
-) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-	TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
-
-	return DDERR_ALREADYINITIALIZED;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
-	LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
-) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-	TRACE("(%p)->(%p)\n",This,pf);
-
-	*pf = This->s.surface_desc.ddpfPixelFormat;
-	if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-	FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
-	LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
-) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-	FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
-	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
-) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-	TRACE("(%p)->(%p)!\n",This,lpClipper);
-
-	if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
-	This->s.lpClipper = lpClipper;
-	if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
-	LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
-) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-    IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
-    int i;
-    struct _surface_chain *chain;
-
-    FIXME("(%p)->(%p)\n",This,surf);
-    chain = This->s.chain;
-
-    /* IDirectDrawSurface4_AddRef(surf); */
-    
-    if (chain) {
-	for (i=0;i<chain->nrofsurfaces;i++)
-	    if (chain->surfaces[i] == isurf)
-		FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
-    } else {
-    	chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
-	chain->nrofsurfaces = 1;
-	chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
-	chain->surfaces[0] = This;
-	This->s.chain = chain;
-    }
-
-    if (chain->surfaces)
-	chain->surfaces = HeapReAlloc(
-	    GetProcessHeap(),
-	    0,
-	    chain->surfaces,
-	    sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
-	);
-    else
-	chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
-    isurf->s.chain = chain;
-    chain->surfaces[chain->nrofsurfaces++] = isurf;
-    return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-    DDSURFACEDESC desc;
-    BITMAPINFO *b_info;
-    UINT usage;
-
-    FIXME("(%p)->GetDC(%p)\n",This,lphdc);
-
-    /* Creates a DIB Section of the same size / format as the surface */
-    IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
-
-    if (This->s.hdc == 0) {
-	switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
-	case 16:
-	case 32:
-#if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
-	    b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
-	    break;
-#endif
-
-	case 24:
-	    b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
-	    break;
-
-	default:
-	    b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-		    sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
-	    break;
-	}
-
-	b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-	b_info->bmiHeader.biWidth = desc.dwWidth;
-	b_info->bmiHeader.biHeight = desc.dwHeight;
-	b_info->bmiHeader.biPlanes = 1;
-	b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
-#if 0
-	if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
-	    (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
-#endif
-	b_info->bmiHeader.biCompression = BI_RGB;
-#if 0
-	else
-	b_info->bmiHeader.biCompression = BI_BITFIELDS;
-#endif
-	b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
-	b_info->bmiHeader.biXPelsPerMeter = 0;
-	b_info->bmiHeader.biYPelsPerMeter = 0;
-	b_info->bmiHeader.biClrUsed = 0;
-	b_info->bmiHeader.biClrImportant = 0;
-
-	switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
-	case 16:
-	case 32:
-#if 0
-	    {
-		DWORD *masks = (DWORD *) &(b_info->bmiColors);
-
-		usage = 0;
-		masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
-		masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
-		masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
-	    }
-	    break;
-#endif
-	case 24:
-	    /* Nothing to do */
-	    usage = DIB_RGB_COLORS;
-	    break;
-
-	default: {
-		int i;
-
-		/* Fill the palette */
-		usage = DIB_RGB_COLORS;
-
-		if (This->s.palette == NULL) {
-		    ERR("Bad palette !!!\n");
-		} else {
-		    RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
-		    PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
-
-		    for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
-			rgb[i].rgbBlue = pent[i].peBlue;
-			rgb[i].rgbRed = pent[i].peRed;
-			rgb[i].rgbGreen = pent[i].peGreen; 
-		    }
-		}
-	    }
-	    break;
-	}
-	This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
-	    b_info,
-	    usage,
-	    &(This->s.bitmap_data),
-	    0,
-	    0
-	);
-	EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
-	TRACE("DIBSection at : %p\n", This->s.bitmap_data);
-
-	/* b_info is not useful anymore */
-	HeapFree(GetProcessHeap(), 0, b_info);
-
-	/* Create the DC */
-	This->s.hdc = CreateCompatibleDC(0);
-	This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
-    }
-
-    /* Copy our surface in the DIB section */
-    if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
-	memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
-    else
-	/* TODO */
-	FIXME("This case has to be done :/\n");
-
-    TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
-    *lphdc = This->s.hdc;
-
-    return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-
-    FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
-    TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
-    /* Copy the DIB section to our surface */
-    if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
-	memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
-    } else {
-	/* TODO */
-	FIXME("This case has to be done :/\n");
-    }
-    /* Unlock the surface */
-    IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
-    return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-
-    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
-    
-    /* All DirectDrawSurface versions (1, 2, 3 and 4) use
-     * the same interface. And IUnknown does that too of course.
-     */
-    if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid )	||
-	 IsEqualGUID( &IID_IDirectDrawSurface3, refiid )	||
-	 IsEqualGUID( &IID_IDirectDrawSurface2, refiid )	||
-	 IsEqualGUID( &IID_IDirectDrawSurface,  refiid )	||
-	 IsEqualGUID( &IID_IUnknown,            refiid )
-    ) {
-	    *obj = This;
-	    IDirectDrawSurface4_AddRef(iface);
-
-	    TRACE("  Creating IDirectDrawSurface interface (%p)\n", *obj);
-	    return S_OK;
-    }
-    else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
-      {
-	/* Texture interface */
-	*obj = d3dtexture2_create(This);
-	IDirectDrawSurface4_AddRef(iface);
-	TRACE("  Creating IDirect3DTexture2 interface (%p)\n", *obj);
-	return S_OK;
-      }
-    else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
-      {
-	/* Texture interface */
-	*obj = d3dtexture_create(This);
-	IDirectDrawSurface4_AddRef(iface);
-	
-	TRACE("  Creating IDirect3DTexture interface (%p)\n", *obj);
-	
-	return S_OK;
-      }
-    else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
-	/* It is the OpenGL Direct3D Device */
-	IDirectDrawSurface4_AddRef(iface);
-	TRACE("  Creating IDirect3DDevice interface (%p)\n", *obj);
-	return S_OK;
-    }
-    
-    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
-    return OLE_E_ENUM_NOMORE;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-	TRACE("(%p)->(), stub!\n",This);
-	return DD_OK; /* hmm */
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-    int i;
-    struct _surface_chain *chain = This->s.chain;
-
-    TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
-    for (i=0;i<chain->nrofsurfaces;i++) {
-      TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
-      if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
-	return DD_OK; /* FIXME: return value correct? */
-    }
-    return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-	FIXME("(%p)->(),stub!\n",This);
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
-	LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey ) 
-{
-        ICOM_THIS(IDirectDrawSurface4Impl,iface);
-        TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
-	if (TRACE_ON(ddraw)) {
-	  _dump_colorkeyflag(dwFlags);
-	  DPRINTF(" : ");
-	  _dump_DDCOLORKEY((void *) ckey);
-	  DPRINTF("\n");
-	}
-
-	/* If this surface was loaded as a texture, call also the texture
-	   SetColorKey callback */
-	if (This->s.texture) {
-	  This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
-	}
-
-        if( dwFlags & DDCKEY_SRCBLT )
-        {
-           dwFlags &= ~DDCKEY_SRCBLT;
-	   This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
-           memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
-        }
-
-        if( dwFlags & DDCKEY_DESTBLT )
-        {
-           dwFlags &= ~DDCKEY_DESTBLT;
-	   This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
-           memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
-        }
-
-        if( dwFlags & DDCKEY_SRCOVERLAY )
-        {
-           dwFlags &= ~DDCKEY_SRCOVERLAY;
-	   This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
-           memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );	   
-        }
-	
-        if( dwFlags & DDCKEY_DESTOVERLAY )
-        {
-           dwFlags &= ~DDCKEY_DESTOVERLAY;
-	   This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
-           memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );	   
-        }
-
-        if( dwFlags )
-        {
-          FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
-        }
-
-        return DD_OK;
-
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
-        LPDIRECTDRAWSURFACE4 iface, 
-        LPRECT lpRect )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(%p),stub!\n",This,lpRect); 
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
-        LPDIRECTDRAWSURFACE4 iface, 
-        DWORD dwFlags,
-        LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
-{
-    ICOM_THIS(IDirectDrawSurface4Impl,iface);
-    int i;
-    struct _surface_chain *chain;
-
-    TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
-    chain = This->s.chain;
-    for (i=0;i<chain->nrofsurfaces;i++) {
-	if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
-	    IDirectDrawSurface4_Release(lpDDSAttachedSurface);
-
-	    chain->surfaces[i]->s.chain = NULL;
-	    memcpy( chain->surfaces+i,
-		    chain->surfaces+(i+1),
-		    (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
-	    );
-	    chain->surfaces = HeapReAlloc(
-		GetProcessHeap(),
-		0,
-		chain->surfaces,
-		sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
-	    );
-	    chain->nrofsurfaces--;
-	    return DD_OK;
-	}
-    }
-    return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
-        LPDIRECTDRAWSURFACE4 iface,
-        DWORD dwFlags,
-        LPVOID lpContext,
-        LPDDENUMSURFACESCALLBACK lpfnCallback )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
-          lpContext, lpfnCallback );
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
-        LPDIRECTDRAWSURFACE4 iface,
-        LPDIRECTDRAWCLIPPER* lplpDDClipper )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
-        LPDIRECTDRAWSURFACE4 iface,
-        DWORD dwFlags,
-        LPDDCOLORKEY lpDDColorKey )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
-
-  if( dwFlags & DDCKEY_SRCBLT )  {
-     dwFlags &= ~DDCKEY_SRCBLT;
-     memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
-  }
-
-  if( dwFlags & DDCKEY_DESTBLT )
-  {
-    dwFlags &= ~DDCKEY_DESTBLT;
-    memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
-  }
-
-  if( dwFlags & DDCKEY_SRCOVERLAY )
-  {
-    dwFlags &= ~DDCKEY_SRCOVERLAY;
-    memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
-  }
-
-  if( dwFlags & DDCKEY_DESTOVERLAY )
-  {
-    dwFlags &= ~DDCKEY_DESTOVERLAY;
-    memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
-  }
-
-  if( dwFlags )
-  {
-    FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
-  }
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
-        LPDIRECTDRAWSURFACE4 iface,
-        DWORD dwFlags ) 
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
-        LPDIRECTDRAWSURFACE4 iface,
-        LPDIRECTDRAWPALETTE* lplpDDPalette )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
-
-  if (This->s.palette != NULL) {
-    IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
-
-    *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
-    return DD_OK;
-  } else {
-    return DDERR_NOPALETTEATTACHED;
-  }
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
-        LPDIRECTDRAWSURFACE4 iface,
-        LONG lX,
-        LONG lY)
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
-        LPDIRECTDRAWSURFACE4 iface,
-        LPRECT lpSrcRect,
-        LPDIRECTDRAWSURFACE4 lpDDDestSurface,
-        LPRECT lpDestRect,
-        DWORD dwFlags,
-        LPDDOVERLAYFX lpDDOverlayFx )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
-         lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );  
-
-  return DD_OK;
-}
- 
-static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
-        LPDIRECTDRAWSURFACE4 iface,
-        DWORD dwFlags )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags); 
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
-        LPDIRECTDRAWSURFACE4 iface,
-        DWORD dwFlags,
-        LPDIRECTDRAWSURFACE4 lpDDSReference )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
-        LPDIRECTDRAWSURFACE4 iface,
-        LPVOID* lplpDD )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(%p),stub!\n", This, lplpDD);
-
-  /* Not sure about that... */
-  *lplpDD = (void *) This->s.ddraw;
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
-        LPDIRECTDRAWSURFACE4 iface,
-        DWORD dwFlags )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
-        LPDIRECTDRAWSURFACE4 iface,
-        DWORD dwFlags )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
-        LPDIRECTDRAWSURFACE4 iface,
-        LPDDSURFACEDESC lpDDSD,
-        DWORD dwFlags )
-{
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
-							 REFGUID guidTag,
-							 LPVOID lpData,
-							 DWORD cbSize,
-							 DWORD dwFlags) {
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
-							 REFGUID guidTag,
-							 LPVOID lpBuffer,
-							 LPDWORD lpcbBufferSize) {
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
-							  REFGUID guidTag)  {
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(%p)\n", This, guidTag);
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
-							     LPDWORD lpValue)  {
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)->(%p)\n", This, lpValue);
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
-  ICOM_THIS(IDirectDrawSurface4Impl,iface);
-  FIXME("(%p)\n", This);
-  
-  return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	IDirectDrawSurface4Impl_QueryInterface,
-	IDirectDrawSurface4Impl_AddRef,
-	DGA_IDirectDrawSurface4Impl_Release,
-	IDirectDrawSurface4Impl_AddAttachedSurface,
-	IDirectDrawSurface4Impl_AddOverlayDirtyRect,
-	IDirectDrawSurface4Impl_Blt,
-	IDirectDrawSurface4Impl_BltBatch,
-	IDirectDrawSurface4Impl_BltFast,
-	IDirectDrawSurface4Impl_DeleteAttachedSurface,
-	IDirectDrawSurface4Impl_EnumAttachedSurfaces,
-	IDirectDrawSurface4Impl_EnumOverlayZOrders,
-	DGA_IDirectDrawSurface4Impl_Flip,
-	IDirectDrawSurface4Impl_GetAttachedSurface,
-	IDirectDrawSurface4Impl_GetBltStatus,
-	IDirectDrawSurface4Impl_GetCaps,
-	IDirectDrawSurface4Impl_GetClipper,
-	IDirectDrawSurface4Impl_GetColorKey,
-	IDirectDrawSurface4Impl_GetDC,
-	IDirectDrawSurface4Impl_GetFlipStatus,
-	IDirectDrawSurface4Impl_GetOverlayPosition,
-	IDirectDrawSurface4Impl_GetPalette,
-	IDirectDrawSurface4Impl_GetPixelFormat,
-	IDirectDrawSurface4Impl_GetSurfaceDesc,
-	IDirectDrawSurface4Impl_Initialize,
-	IDirectDrawSurface4Impl_IsLost,
-	IDirectDrawSurface4Impl_Lock,
-	IDirectDrawSurface4Impl_ReleaseDC,
-	IDirectDrawSurface4Impl_Restore,
-	IDirectDrawSurface4Impl_SetClipper,
-	IDirectDrawSurface4Impl_SetColorKey,
-	IDirectDrawSurface4Impl_SetOverlayPosition,
-	DGA_IDirectDrawSurface4Impl_SetPalette,
-	DGA_IDirectDrawSurface4Impl_Unlock,
-	IDirectDrawSurface4Impl_UpdateOverlay,
-	IDirectDrawSurface4Impl_UpdateOverlayDisplay,
-	IDirectDrawSurface4Impl_UpdateOverlayZOrder,
-	IDirectDrawSurface4Impl_GetDDInterface,
-	IDirectDrawSurface4Impl_PageLock,
-	IDirectDrawSurface4Impl_PageUnlock,
-	IDirectDrawSurface4Impl_SetSurfaceDesc,
-	IDirectDrawSurface4Impl_SetPrivateData,
-	IDirectDrawSurface4Impl_GetPrivateData,
-	IDirectDrawSurface4Impl_FreePrivateData,
-	IDirectDrawSurface4Impl_GetUniquenessValue,
-	IDirectDrawSurface4Impl_ChangeUniquenessValue
-};
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-#ifdef HAVE_LIBXXF86DGA2
-static ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	IDirectDrawSurface4Impl_QueryInterface,
-	IDirectDrawSurface4Impl_AddRef,
-	DGA_IDirectDrawSurface4Impl_Release,
-	IDirectDrawSurface4Impl_AddAttachedSurface,
-	IDirectDrawSurface4Impl_AddOverlayDirtyRect,
-	IDirectDrawSurface4Impl_Blt,
-	IDirectDrawSurface4Impl_BltBatch,
-	IDirectDrawSurface4Impl_BltFast,
-	IDirectDrawSurface4Impl_DeleteAttachedSurface,
-	IDirectDrawSurface4Impl_EnumAttachedSurfaces,
-	IDirectDrawSurface4Impl_EnumOverlayZOrders,
-	DGA2_IDirectDrawSurface4Impl_Flip,
-	IDirectDrawSurface4Impl_GetAttachedSurface,
-	IDirectDrawSurface4Impl_GetBltStatus,
-	IDirectDrawSurface4Impl_GetCaps,
-	IDirectDrawSurface4Impl_GetClipper,
-	IDirectDrawSurface4Impl_GetColorKey,
-	IDirectDrawSurface4Impl_GetDC,
-	IDirectDrawSurface4Impl_GetFlipStatus,
-	IDirectDrawSurface4Impl_GetOverlayPosition,
-	IDirectDrawSurface4Impl_GetPalette,
-	IDirectDrawSurface4Impl_GetPixelFormat,
-	IDirectDrawSurface4Impl_GetSurfaceDesc,
-	IDirectDrawSurface4Impl_Initialize,
-	IDirectDrawSurface4Impl_IsLost,
-	IDirectDrawSurface4Impl_Lock,
-	IDirectDrawSurface4Impl_ReleaseDC,
-	IDirectDrawSurface4Impl_Restore,
-	IDirectDrawSurface4Impl_SetClipper,
-	IDirectDrawSurface4Impl_SetColorKey,
-	IDirectDrawSurface4Impl_SetOverlayPosition,
-	DGA_IDirectDrawSurface4Impl_SetPalette,
-	DGA_IDirectDrawSurface4Impl_Unlock,
-	IDirectDrawSurface4Impl_UpdateOverlay,
-	IDirectDrawSurface4Impl_UpdateOverlayDisplay,
-	IDirectDrawSurface4Impl_UpdateOverlayZOrder,
-	IDirectDrawSurface4Impl_GetDDInterface,
-	IDirectDrawSurface4Impl_PageLock,
-	IDirectDrawSurface4Impl_PageUnlock,
-	IDirectDrawSurface4Impl_SetSurfaceDesc,
-	IDirectDrawSurface4Impl_SetPrivateData,
-	IDirectDrawSurface4Impl_GetPrivateData,
-	IDirectDrawSurface4Impl_FreePrivateData,
-	IDirectDrawSurface4Impl_GetUniquenessValue,
-	IDirectDrawSurface4Impl_ChangeUniquenessValue
-};
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-
-static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	IDirectDrawSurface4Impl_QueryInterface,
-	IDirectDrawSurface4Impl_AddRef,
-	Xlib_IDirectDrawSurface4Impl_Release,
-	IDirectDrawSurface4Impl_AddAttachedSurface,
-	IDirectDrawSurface4Impl_AddOverlayDirtyRect,
-	IDirectDrawSurface4Impl_Blt,
-	IDirectDrawSurface4Impl_BltBatch,
-	IDirectDrawSurface4Impl_BltFast,
-	IDirectDrawSurface4Impl_DeleteAttachedSurface,
-	IDirectDrawSurface4Impl_EnumAttachedSurfaces,
-	IDirectDrawSurface4Impl_EnumOverlayZOrders,
-	Xlib_IDirectDrawSurface4Impl_Flip,
-	IDirectDrawSurface4Impl_GetAttachedSurface,
-	IDirectDrawSurface4Impl_GetBltStatus,
-	IDirectDrawSurface4Impl_GetCaps,
-	IDirectDrawSurface4Impl_GetClipper,
-	IDirectDrawSurface4Impl_GetColorKey,
-	IDirectDrawSurface4Impl_GetDC,
-	IDirectDrawSurface4Impl_GetFlipStatus,
-	IDirectDrawSurface4Impl_GetOverlayPosition,
-	IDirectDrawSurface4Impl_GetPalette,
-	IDirectDrawSurface4Impl_GetPixelFormat,
-	IDirectDrawSurface4Impl_GetSurfaceDesc,
-	IDirectDrawSurface4Impl_Initialize,
-	IDirectDrawSurface4Impl_IsLost,
-	IDirectDrawSurface4Impl_Lock,
-	IDirectDrawSurface4Impl_ReleaseDC,
-	IDirectDrawSurface4Impl_Restore,
-	IDirectDrawSurface4Impl_SetClipper,
-	IDirectDrawSurface4Impl_SetColorKey,
-	IDirectDrawSurface4Impl_SetOverlayPosition,
-	Xlib_IDirectDrawSurface4Impl_SetPalette,
-	Xlib_IDirectDrawSurface4Impl_Unlock,
-	IDirectDrawSurface4Impl_UpdateOverlay,
-	IDirectDrawSurface4Impl_UpdateOverlayDisplay,
-	IDirectDrawSurface4Impl_UpdateOverlayZOrder,
-	IDirectDrawSurface4Impl_GetDDInterface,
-	IDirectDrawSurface4Impl_PageLock,
-	IDirectDrawSurface4Impl_PageUnlock,
-	IDirectDrawSurface4Impl_SetSurfaceDesc,
-	IDirectDrawSurface4Impl_SetPrivateData,
-	IDirectDrawSurface4Impl_GetPrivateData,
-	IDirectDrawSurface4Impl_FreePrivateData,
-	IDirectDrawSurface4Impl_GetUniquenessValue,
-	IDirectDrawSurface4Impl_ChangeUniquenessValue
-};
-
-/******************************************************************************
- *			DirectDrawCreateClipper (DDRAW.7)
- */
-HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
-				        LPDIRECTDRAWCLIPPER *lplpDDClipper,
-				        LPUNKNOWN pUnkOuter)
-{
-  IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
-  TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
-
-  *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
-  ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
-  (*ilplpDDClipper)->ref = 1;
-
-  (*ilplpDDClipper)->hWnd = 0; 
-
-  return DD_OK;
-}
-
-/******************************************************************************
- *			IDirectDrawClipper
- */
-static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
-	LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
-) {
-        ICOM_THIS(IDirectDrawClipperImpl,iface);
-
-	TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
-        if( dwFlags ) {
-	  FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
-          return DDERR_INVALIDPARAMS; 
-        }
-
-        This->hWnd = hWnd;
-	return DD_OK;
-}
-
-static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
-        ICOM_THIS(IDirectDrawClipperImpl,iface);
-        TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-	This->ref--;
-	if (This->ref)
-		return This->ref;
-	HeapFree(GetProcessHeap(),0,This);
-	return S_OK;
-}
-
-static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
-	LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
-) {
-        ICOM_THIS(IDirectDrawClipperImpl,iface);
-	FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
-	if (hmm) *hmm=0;
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
-	LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
-) {
-        ICOM_THIS(IDirectDrawClipperImpl,iface);
-	FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
-         LPDIRECTDRAWCLIPPER iface,
-         REFIID riid,
-         LPVOID* ppvObj )
-{
-   ICOM_THIS(IDirectDrawClipperImpl,iface);
-   FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
-   return OLE_E_ENUM_NOMORE;
-}
-
-static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
-{
-  ICOM_THIS(IDirectDrawClipperImpl,iface);
-  TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
-  return ++(This->ref);
-}
-
-static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
-         LPDIRECTDRAWCLIPPER iface,
-         HWND* hWndPtr )
-{
-   ICOM_THIS(IDirectDrawClipperImpl,iface);
-   FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
-
-   *hWndPtr = This->hWnd; 
-
-   return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
-         LPDIRECTDRAWCLIPPER iface,
-         LPDIRECTDRAW lpDD,
-         DWORD dwFlags )
-{
-   ICOM_THIS(IDirectDrawClipperImpl,iface);
-   FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
-   return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
-         LPDIRECTDRAWCLIPPER iface,
-         BOOL* lpbChanged )
-{
-   ICOM_THIS(IDirectDrawClipperImpl,iface);
-   FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
-   return DD_OK;
-}
-
-static ICOM_VTABLE(IDirectDrawClipper) ddclipvt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-        IDirectDrawClipperImpl_QueryInterface,
-        IDirectDrawClipperImpl_AddRef,
-        IDirectDrawClipperImpl_Release,
-        IDirectDrawClipperImpl_GetClipList,
-        IDirectDrawClipperImpl_GetHWnd,
-        IDirectDrawClipperImpl_Initialize,
-        IDirectDrawClipperImpl_IsClipListChanged,
-        IDirectDrawClipperImpl_SetClipList,
-        IDirectDrawClipperImpl_SetHwnd
-};
-
-
-/******************************************************************************
- *			IDirectDrawPalette
- */
-static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
-	LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
-) {
-        ICOM_THIS(IDirectDrawPaletteImpl,iface);
-	int	i;
-
-	TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
-	      This,x,start,count,palent);
-
-	/* No palette created and not in depth-convertion mode -> BUG ! */
-	if ((This->cm == None) &&
-	    (This->ddraw->d.palette_convert == NULL))
-	{
-		FIXME("app tried to read colormap for non-palettized mode\n");
-		return DDERR_GENERIC;
-	}
-	for (i=0;i<count;i++) {
-                palent[i].peRed   = This->palents[start+i].peRed;
-                palent[i].peBlue  = This->palents[start+i].peBlue;
-                palent[i].peGreen = This->palents[start+i].peGreen;
-                palent[i].peFlags = This->palents[start+i].peFlags;
-
-	}
-	return DD_OK;
-}
-
-static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
-	LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
-) {
-        ICOM_THIS(IDirectDrawPaletteImpl,iface);
-	XColor		xc;
-	int		i;
-
-	TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
-		This,x,start,count,palent
-	);
-	for (i=0;i<count;i++) {
-		xc.red = palent[i].peRed<<8;
-		xc.blue = palent[i].peBlue<<8;
-		xc.green = palent[i].peGreen<<8;
-		xc.flags = DoRed|DoBlue|DoGreen;
-		xc.pixel = start+i;
-
-		if (This->cm)
-		    TSXStoreColor(display,This->cm,&xc);
-
-		This->palents[start+i].peRed = palent[i].peRed;
-		This->palents[start+i].peBlue = palent[i].peBlue;
-		This->palents[start+i].peGreen = palent[i].peGreen;
-                This->palents[start+i].peFlags = palent[i].peFlags;
-	}
-
-	/* Now, if we are in 'depth conversion mode', update the screen palette */
-	/* FIXME: we need to update the image or we won't get palette fading. */
-	if (This->ddraw->d.palette_convert != NULL)
-	  This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
-	  
-	return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
-	LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
-) {
-        ICOM_THIS(IDirectDrawPaletteImpl,iface);
-	XColor		xc;
-	Colormap	cm;
-	int		i;
-
-	TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
-		This,x,start,count,palent
-	);
-	if (!This->cm) /* should not happen */ {
-		FIXME("app tried to set colormap in non-palettized mode\n");
-		return DDERR_GENERIC;
-	}
-	/* FIXME: free colorcells instead of freeing whole map */
-	cm = This->cm;
-	This->cm = TSXCopyColormapAndFree(display,This->cm);
-	TSXFreeColormap(display,cm);
-
-	for (i=0;i<count;i++) {
-		xc.red = palent[i].peRed<<8;
-		xc.blue = palent[i].peBlue<<8;
-		xc.green = palent[i].peGreen<<8;
-		xc.flags = DoRed|DoBlue|DoGreen;
-		xc.pixel = i+start;
-
-		TSXStoreColor(display,This->cm,&xc);
-
-		This->palents[start+i].peRed = palent[i].peRed;
-		This->palents[start+i].peBlue = palent[i].peBlue;
-		This->palents[start+i].peGreen = palent[i].peGreen;
-                This->palents[start+i].peFlags = palent[i].peFlags;
-	}
-#ifdef HAVE_LIBXXF86DGA2
-	if (This->ddraw->e.dga.version == 2)
-	  TSXDGAInstallColormap(display,DefaultScreen(display),This->cm);
-	else
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-	  TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
-	return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
-        ICOM_THIS(IDirectDrawPaletteImpl,iface);
-        TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-	if (!--(This->ref)) {
-		if (This->cm) {
-			TSXFreeColormap(display,This->cm);
-			This->cm = 0;
-		}
-		HeapFree(GetProcessHeap(),0,This);
-		return S_OK;
-	}
-	return This->ref;
-}
-
-static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
-        ICOM_THIS(IDirectDrawPaletteImpl,iface);
-
-        TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
-	return ++(This->ref);
-}
-
-static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
-	LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
-) {
-        ICOM_THIS(IDirectDrawPaletteImpl,iface);
-        TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
-
-	return DDERR_ALREADYINITIALIZED;
-}
-
-static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
-         LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
-{
-   ICOM_THIS(IDirectDrawPaletteImpl,iface);
-   FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
-   return DD_OK;
-} 
-
-static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
-        LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj ) 
-{
-  ICOM_THIS(IDirectDrawPaletteImpl,iface);
-
-  FIXME("(%p)->(%s,%p) stub.\n",This,debugstr_guid(refiid),obj);
-
-  return S_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	IDirectDrawPaletteImpl_QueryInterface,
-	IDirectDrawPaletteImpl_AddRef,
-	IDirectDrawPaletteImpl_Release,
-	IDirectDrawPaletteImpl_GetCaps,
-	IDirectDrawPaletteImpl_GetEntries,
-	IDirectDrawPaletteImpl_Initialize,
-	DGA_IDirectDrawPaletteImpl_SetEntries
-};
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	IDirectDrawPaletteImpl_QueryInterface,
-	IDirectDrawPaletteImpl_AddRef,
-	IDirectDrawPaletteImpl_Release,
-	IDirectDrawPaletteImpl_GetCaps,
-	IDirectDrawPaletteImpl_GetEntries,
-	IDirectDrawPaletteImpl_Initialize,
-	Xlib_IDirectDrawPaletteImpl_SetEntries
-};
-
-/*******************************************************************************
- *				IDirect3D
- */
-static HRESULT WINAPI IDirect3DImpl_QueryInterface(
-        LPDIRECT3D iface,REFIID refiid,LPVOID *obj
-) {
-        ICOM_THIS(IDirect3DImpl,iface);
-	/* FIXME: Not sure if this is correct */
-
-        TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
-        if ( ( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
-	     ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
-	     ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
-                *obj = This->ddraw;
-                IDirect3D_AddRef(iface);
-
-		TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);
-		
-                return S_OK;
-        }
-        if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
-	     ( IsEqualGUID( &IID_IUnknown,  refiid ) ) ) {
-                *obj = This;
-                IDirect3D_AddRef(iface);
-
-		TRACE("  Creating IDirect3D interface (%p)\n", *obj);
-
-                return S_OK;
-        }
-        if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
-                IDirect3D2Impl*  d3d;
-
-                d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-                d3d->ref = 1;
-                d3d->ddraw = This->ddraw;
-                IDirect3D_AddRef(iface);
-                ICOM_VTBL(d3d) = &d3d2vt;
-                *obj = d3d;
-
-		TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
-
-                return S_OK;
-        }
-        FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
-        return OLE_E_ENUM_NOMORE;
-}
-
-static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
-        ICOM_THIS(IDirect3DImpl,iface);
-        TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
-
-        return ++(This->ref);
-}
-
-static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
-{
-        ICOM_THIS(IDirect3DImpl,iface);
-        TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-        if (!--(This->ref)) {
-                IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
-                HeapFree(GetProcessHeap(),0,This);
-                return S_OK;
-        }
-        return This->ref;
-}
-
-static HRESULT WINAPI IDirect3DImpl_Initialize(
-         LPDIRECT3D iface, REFIID refiid )
-{
-  ICOM_THIS(IDirect3DImpl,iface);
-  /* FIXME: Not sure if this is correct */
-
-  FIXME("(%p)->(%s):stub.\n",This,debugstr_guid(refiid));
-  
-  return DDERR_ALREADYINITIALIZED;
-}
-
-static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
-					    LPD3DENUMDEVICESCALLBACK cb,
-					    LPVOID context) {
-  ICOM_THIS(IDirect3DImpl,iface);
-  FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
-
-  /* Call functions defined in d3ddevices.c */
-  if (!d3d_OpenGL_dx3(cb, context))
-    return DD_OK;
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
-					    LPDIRECT3DLIGHT *lplight,
-					    IUnknown *lpunk)
-{
-  ICOM_THIS(IDirect3DImpl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
-  
-  /* Call the creation function that is located in d3dlight.c */
-  *lplight = d3dlight_create_dx3(This);
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
-					       LPDIRECT3DMATERIAL *lpmaterial,
-					       IUnknown *lpunk)
-{
-  ICOM_THIS(IDirect3DImpl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
-
-  /* Call the creation function that is located in d3dviewport.c */
-  *lpmaterial = d3dmaterial_create(This);
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
-					       LPDIRECT3DVIEWPORT *lpviewport,
-					       IUnknown *lpunk)
-{
-  ICOM_THIS(IDirect3DImpl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
-  
-  /* Call the creation function that is located in d3dviewport.c */
-  *lpviewport = d3dviewport_create(This);
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
-					   LPD3DFINDDEVICESEARCH lpfinddevsrc,
-					   LPD3DFINDDEVICERESULT lpfinddevrst)
-{
-  ICOM_THIS(IDirect3DImpl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
-  
-  return DD_OK;
-}
-
-static ICOM_VTABLE(IDirect3D) d3dvt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-        IDirect3DImpl_QueryInterface,
-        IDirect3DImpl_AddRef,
-        IDirect3DImpl_Release,
-        IDirect3DImpl_Initialize,
-        IDirect3DImpl_EnumDevices,
-        IDirect3DImpl_CreateLight,
-        IDirect3DImpl_CreateMaterial,
-        IDirect3DImpl_CreateViewport,
-	IDirect3DImpl_FindDevice
-};
-
-/*******************************************************************************
- *				IDirect3D2
- */
-static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
-        LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {  
-	ICOM_THIS(IDirect3D2Impl,iface);
-
-	/* FIXME: Not sure if this is correct */
-
-        TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
-        if ( ( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
-	     ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
-	     ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
-                *obj = This->ddraw;
-                IDirect3D2_AddRef(iface);
-
-		TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);
-		
-                return S_OK;
-        }
-        if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
-	     ( IsEqualGUID( &IID_IUnknown,   refiid ) ) ) {
-                *obj = This;
-                IDirect3D2_AddRef(iface);
-
-		TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
-
-                return S_OK;
-        }
-        if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
-                IDirect3DImpl*  d3d;
-
-                d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-                d3d->ref = 1;
-                d3d->ddraw = This->ddraw;
-                IDirect3D2_AddRef(iface);
-                ICOM_VTBL(d3d) = &d3dvt;
-                *obj = d3d;
-
-		TRACE("  Creating IDirect3D interface (%p)\n", *obj);
-
-                return S_OK;
-        }
-        FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
-        return OLE_E_ENUM_NOMORE;
-}
-
-static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
-        ICOM_THIS(IDirect3D2Impl,iface);
-        TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
-
-        return ++(This->ref);
-}
-
-static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
-        ICOM_THIS(IDirect3D2Impl,iface);
-        TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-	if (!--(This->ref)) {
-		IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
-		HeapFree(GetProcessHeap(),0,This);
-		return S_OK;
-	}
-	return This->ref;
-}
-
-static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
-	LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
-) {
-        ICOM_THIS(IDirect3D2Impl,iface);
-	FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
-
-	/* Call functions defined in d3ddevices.c */
-	if (!d3d_OpenGL(cb, context))
-	  return DD_OK;
-
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
-					     LPDIRECT3DLIGHT *lplight,
-					     IUnknown *lpunk)
-{
-  ICOM_THIS(IDirect3D2Impl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
-
-  /* Call the creation function that is located in d3dlight.c */
-  *lplight = d3dlight_create(This);
-  
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
-						LPDIRECT3DMATERIAL2 *lpmaterial,
-						IUnknown *lpunk)
-{
-  ICOM_THIS(IDirect3D2Impl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
-
-  /* Call the creation function that is located in d3dviewport.c */
-  *lpmaterial = d3dmaterial2_create(This);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
-						LPDIRECT3DVIEWPORT2 *lpviewport,
-						IUnknown *lpunk)
-{
-  ICOM_THIS(IDirect3D2Impl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
-  
-  /* Call the creation function that is located in d3dviewport.c */
-  *lpviewport = d3dviewport2_create(This);
-  
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
-					    LPD3DFINDDEVICESEARCH lpfinddevsrc,
-					    LPD3DFINDDEVICERESULT lpfinddevrst)
-{
-  ICOM_THIS(IDirect3D2Impl,iface);
-  TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
-					      REFCLSID rguid,
-					      LPDIRECTDRAWSURFACE surface,
-					      LPDIRECT3DDEVICE2 *device)
-{
-  ICOM_THIS(IDirect3D2Impl,iface);
-  
-  FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
-
-  if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
-    IDirect3D2_AddRef(iface);
-    return DD_OK;
-}
-
-  return DDERR_INVALIDPARAMS;
-}
-
-static ICOM_VTABLE(IDirect3D2) d3d2vt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	IDirect3D2Impl_QueryInterface,
-	IDirect3D2Impl_AddRef,
-        IDirect3D2Impl_Release,
-        IDirect3D2Impl_EnumDevices,
-	IDirect3D2Impl_CreateLight,
-	IDirect3D2Impl_CreateMaterial,
-	IDirect3D2Impl_CreateViewport,
-	IDirect3D2Impl_FindDevice,
-	IDirect3D2Impl_CreateDevice
-};
-
-/*******************************************************************************
- *				IDirectDraw
- */
-
-/* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
- * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
- */
-static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
-					       IDirectDrawSurfaceImpl* lpdsf)
-{
-  int bpp;
-  
-  /* The surface was already allocated when entering in this function */
-  TRACE("using system memory for a surface (%p) \n", lpdsf);
-
-  if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
-    /* This is a Z Buffer */
-    TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
-    bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
-  } else {
-    /* This is a standard image */
-    if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
-    /* No pixel format => use DirectDraw's format */
-      lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
-      lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
-    }
-    bpp = GET_BPP(lpdsf->s.surface_desc);
-  }
-
-  if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
-    /* The surface was preallocated : seems that we have nothing to do :-) */
-    ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
-  }
-
-  assert(bpp);
-  FIXME("using w=%ld, h=%ld, bpp=%d\n",lpdsf->s.surface_desc.dwWidth,lpdsf->s.surface_desc.dwHeight,bpp);
-  
-  lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
-  lpdsf->s.surface_desc.u1.lpSurface =
-    (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
-  lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
-  
-  return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
-	LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
-) {
-    ICOM_THIS(IDirectDraw2Impl,iface);
-    IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
-    int	i, fbheight = This->e.dga.fb_height;
-
-    TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
-    if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
-
-    *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
-    	GetProcessHeap(),
-	HEAP_ZERO_MEMORY,
-	sizeof(IDirectDrawSurfaceImpl)
-    );
-    IDirectDraw2_AddRef(iface);
-
-    (*ilpdsf)->ref = 1;
-#ifdef HAVE_LIBXXF86DGA2
-    if (This->e.dga.version == 2)
-      ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt;
-    else
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-      ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
-    (*ilpdsf)->s.ddraw = This;
-    (*ilpdsf)->s.palette = NULL;
-    (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
-    (*ilpdsf)->s.lpClipper = NULL;
-
-    /* Copy the surface description */
-    (*ilpdsf)->s.surface_desc = *lpddsd;
-
-    if (!(lpddsd->dwFlags & DDSD_WIDTH))
-	(*ilpdsf)->s.surface_desc.dwWidth  = This->d.width;
-    if (!(lpddsd->dwFlags & DDSD_HEIGHT))
-	(*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
-
-    (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
-
-    /* Check if this a 'primary surface' or not */
-    if ((lpddsd->dwFlags & DDSD_CAPS) &&
-	(lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
-	/* This is THE primary surface => there is DGA-specific code */
-
-	/* First, store the surface description */
-	(*ilpdsf)->s.surface_desc = *lpddsd;
-
-	/* Find a viewport */
-	for (i=0;i<32;i++)
-	    if (!(This->e.dga.vpmask & (1<<i)))
-		break;
-	TRACE("using viewport %d for a primary surface\n",i);
-	/* if i == 32 or maximum ... return error */
-	This->e.dga.vpmask|=(1<<i);
-	lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch = 
-		This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
-
-	(*ilpdsf)->s.surface_desc.u1.lpSurface =
-	    This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
-
-	(*ilpdsf)->t.dga.fb_height = i*fbheight;
-
-	/* Add flags if there were not present */
-	(*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
-	(*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
-	(*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
-	TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
-	/* We put our surface always in video memory */
-	SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
-	(*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
-	(*ilpdsf)->s.chain = NULL;
-
-	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
-	    IDirectDrawSurface4Impl*	back;
-	    int	bbc;
-
-	    for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
-	        int i;
-	      
-		back = (IDirectDrawSurface4Impl*)HeapAlloc(
-		    GetProcessHeap(),
-		    HEAP_ZERO_MEMORY,
-		    sizeof(IDirectDrawSurface4Impl)
-		);
-		IDirectDraw2_AddRef(iface);
-		back->ref = 1;
-		ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
-		for (i=0;i<32;i++)
-		    if (!(This->e.dga.vpmask & (1<<i)))
-			break;
-		TRACE("using viewport %d for backbuffer %d\n",i, bbc);
-		/* if i == 32 or maximum ... return error */
-		This->e.dga.vpmask|=(1<<i);
-		back->t.dga.fb_height = i*fbheight;
-		/* Copy the surface description from the front buffer */
-		back->s.surface_desc = (*ilpdsf)->s.surface_desc;
-		/* Change the parameters that are not the same */
-		back->s.surface_desc.u1.lpSurface =
-		    This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
-
-		back->s.ddraw = This;
-		/* Add relevant info to front and back buffers */
-		/* FIXME: backbuffer/frontbuffer handling broken here, but
-		 * will be fixed up in _Flip().
-		 */
-		SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
-		SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
-		back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
-		SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
-		IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
-	    }
-	}
-    } else {
-	/* There is no DGA-specific code here...
-	Go to the common surface creation function */
-	return common_off_screen_CreateSurface(This, *ilpdsf);
-    }
-    return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-#ifdef HAVE_LIBXXSHM
-/* Error handlers for Image creation */
-static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
-  XShmErrorFlag = 1;
-  return 0;
-}
-
-static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
-    XImage *img;
-    int (*WineXHandler)(Display *, XErrorEvent *);
-
-    img = TSXShmCreateImage(display, X11DRV_GetVisual(),
-	This->d.pixmap_depth,
-	ZPixmap,
-	NULL,
-	&(lpdsf->t.xlib.shminfo),
-	lpdsf->s.surface_desc.dwWidth,
-	lpdsf->s.surface_desc.dwHeight
-    );
-
-    if (img == NULL) {
-	FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
-	This->e.xlib.xshm_active = 0;
-	return NULL;
-    }
-
-    lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
-    if (lpdsf->t.xlib.shminfo.shmid < 0) {
-	FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
-	This->e.xlib.xshm_active = 0;
-	TSXDestroyImage(img);
-	return NULL;
-    }
-
-    lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
-
-    if (img->data == (char *) -1) {
-	FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
-	This->e.xlib.xshm_active = 0;
-	TSXDestroyImage(img);
-	shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
-	return NULL;
-    }
-    lpdsf->t.xlib.shminfo.readOnly = False;
-
-    /* This is where things start to get trickier....
-     * First, we flush the current X connections to be sure to catch all
-     * non-XShm related errors
-     */
-    TSXSync(display, False);
-    /* Then we enter in the non-thread safe part of the tests */
-    EnterCriticalSection( &X11DRV_CritSection );
-
-    /* Reset the error flag, sets our new error handler and try to attach
-     * the surface
-     */
-    XShmErrorFlag = 0;
-    WineXHandler = XSetErrorHandler(XShmErrorHandler);
-    XShmAttach(display, &(lpdsf->t.xlib.shminfo));
-    XSync(display, False);
-
-    /* Check the error flag */
-    if (XShmErrorFlag) {
-	/* An error occured */
-	XFlush(display);
-	XShmErrorFlag = 0;
-	XDestroyImage(img);
-	shmdt(lpdsf->t.xlib.shminfo.shmaddr);
-	shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
-	XSetErrorHandler(WineXHandler);
-
-	FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
-	This->e.xlib.xshm_active = 0;
-
-	/* Leave the critical section */
-	LeaveCriticalSection( &X11DRV_CritSection );
-	return NULL;
-    }
-    /* Here, to be REALLY sure, I should do a XShmPutImage to check if
-     * this works, but it may be a bit overkill....
-     */
-    XSetErrorHandler(WineXHandler);
-    LeaveCriticalSection( &X11DRV_CritSection );
-
-    shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
-
-    if (This->d.pixel_convert != NULL) {
-	lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
-	    GetProcessHeap(),
-	    HEAP_ZERO_MEMORY,
-	    lpdsf->s.surface_desc.dwWidth *
-	    lpdsf->s.surface_desc.dwHeight *
-	    PFGET_BPP(This->d.directdraw_pixelformat)
-	);
-    } else {
-	lpdsf->s.surface_desc.u1.lpSurface = img->data;
-    }
-    return img;
-}
-#endif /* HAVE_LIBXXSHM */
-
-static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
-    XImage *img = NULL;
-    void *img_data;
-
-#ifdef HAVE_LIBXXSHM
-    if (This->e.xlib.xshm_active)
-	img = create_xshmimage(This, lpdsf);
-
-    if (img == NULL) {
-#endif
-    /* Allocate surface memory */
-	lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
-	    GetProcessHeap(),HEAP_ZERO_MEMORY,
-	    lpdsf->s.surface_desc.dwWidth *
-	    lpdsf->s.surface_desc.dwHeight *
-	    PFGET_BPP(This->d.directdraw_pixelformat)
-	);
-
-	if (This->d.pixel_convert != NULL) {
-	    img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
-		lpdsf->s.surface_desc.dwWidth *
-		lpdsf->s.surface_desc.dwHeight *
-		PFGET_BPP(This->d.screen_pixelformat)
-	    );
-	} else {
-	    img_data = lpdsf->s.surface_desc.u1.lpSurface;
-	}
-
-	/* In this case, create an XImage */
-	img = TSXCreateImage(display, X11DRV_GetVisual(),
-	    This->d.pixmap_depth,
-	    ZPixmap,
-	    0,
-	    img_data,
-	    lpdsf->s.surface_desc.dwWidth,
-	    lpdsf->s.surface_desc.dwHeight,
-	    32,
-	    lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
-	);
-#ifdef HAVE_LIBXXSHM
-    }
-#endif
-    if (This->d.pixel_convert != NULL)
-	lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
-    else
-	lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
-    return img;
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
-	LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
-) {
-    ICOM_THIS(IDirectDraw2Impl,iface);
-    IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
-
-    TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
-
-    if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
-
-    *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
-    	GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
-    );
-
-    IDirectDraw2_AddRef(iface);
-
-    (*ilpdsf)->s.ddraw             = This;
-    (*ilpdsf)->ref                 = 1;
-    ICOM_VTBL(*ilpdsf)             = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
-    (*ilpdsf)->s.palette = NULL;
-    (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
-    (*ilpdsf)->s.lpClipper = NULL;
-
-    /* Copy the surface description */
-    (*ilpdsf)->s.surface_desc = *lpddsd;
-
-    if (!(lpddsd->dwFlags & DDSD_WIDTH))
-	(*ilpdsf)->s.surface_desc.dwWidth  = This->d.width;
-    if (!(lpddsd->dwFlags & DDSD_HEIGHT))
-	(*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
-    (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
-
-    /* Check if this a 'primary surface' or not */
-    if ((lpddsd->dwFlags & DDSD_CAPS) && 
-	(lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
-	XImage *img;
-
-	TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
-	/* Create the XImage */
-	img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
-	if (img == NULL)
-	    return DDERR_OUTOFMEMORY;
-	(*ilpdsf)->t.xlib.image = img;
-
-	/* Add flags if there were not present */
-	(*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
-	(*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
-	(*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
-	(*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
-	(*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
-
-	/* Check for backbuffers */
-	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
-	    IDirectDrawSurface4Impl*	back;
-	    XImage *img;
-	    int	i;
-
-	    for (i=lpddsd->dwBackBufferCount;i--;) {
-		back = (IDirectDrawSurface4Impl*)HeapAlloc(
-		    GetProcessHeap(),HEAP_ZERO_MEMORY,
-		    sizeof(IDirectDrawSurface4Impl)
-		);
-
-		TRACE("allocated back-buffer (%p)\n", back);
-
-		IDirectDraw2_AddRef(iface);
-		back->s.ddraw = This;
-
-		back->ref = 1;
-		ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
-		/* Copy the surface description from the front buffer */
-		back->s.surface_desc = (*ilpdsf)->s.surface_desc;
-
-		/* Create the XImage */
-		img = create_ximage(This, back);
-		if (img == NULL)
-		    return DDERR_OUTOFMEMORY;
-		back->t.xlib.image = img;
-
-		/* Add relevant info to front and back buffers */
-		/* FIXME: backbuffer/frontbuffer handling broken here, but
-		 * will be fixed up in _Flip().
-		 */
-		SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
-		SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
-		back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
-		SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
-		IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
-	    }
-	}
-    } else {
-	/* There is no Xlib-specific code here...
-	Go to the common surface creation function */
-	return common_off_screen_CreateSurface(This, *ilpdsf);
-    }
-    return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
-	LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
-	*dst = src; /* FIXME */
-	return DD_OK;
-}
-
-/* 
- * The Xlib Implementation tries to use the passed hwnd as drawing window,
- * even when the approbiate bitmasks are not specified.
- */
-static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
-	LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	int	i;
-	const struct {
-		int	mask;
-		char	*name;
-	} flags[] = {
-#define FE(x) { x, #x},
-		FE(DDSCL_FULLSCREEN)
-		FE(DDSCL_ALLOWREBOOT)
-		FE(DDSCL_NOWINDOWCHANGES)
-		FE(DDSCL_NORMAL)
-		FE(DDSCL_ALLOWMODEX)
-		FE(DDSCL_EXCLUSIVE)
-		FE(DDSCL_SETFOCUSWINDOW)
-		FE(DDSCL_SETDEVICEWINDOW)
-		FE(DDSCL_CREATEDEVICEWINDOW)
-#undef FE
-	};
-
-	FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
-	if (TRACE_ON(ddraw)) {
-	  DPRINTF(" - ");
-	  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
-	    if (flags[i].mask & cooplevel) {
-	      DPRINTF("%s ",flags[i].name);
-	    }
-	  }
-	  DPRINTF("\n");
-	}
-        This->d.mainWindow = hwnd;
-
-	/* This will be overwritten in the case of Full Screen mode.
-	   Windowed games could work with that :-) */
-	if (hwnd)
-        {
-            WND *tmpWnd = WIN_FindWndPtr(hwnd);
-            This->d.drawable  = X11DRV_WND_GetXWindow(tmpWnd);
-            WIN_ReleaseWndPtr(tmpWnd);
-
-	    if( !This->d.drawable ) {
-	      This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
-	      WIN_ReleaseDesktop();
-            }
-	    TRACE("Setting drawable to %ld\n", This->d.drawable);
-        }
-
-	return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA2
-static HRESULT WINAPI DGA_IDirectDraw2Impl_SetCooperativeLevel(
-	LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
-) {
-  ICOM_THIS(IDirectDraw2Impl,iface);
-  HRESULT ret;
-  int evbase, erbase;
-  
-  ret = IDirectDraw2Impl_SetCooperativeLevel(iface, hwnd, cooplevel);
-
-  if (This->e.dga.version != 2) {
-    return ret;
-  } else {
-    if (ret != DD_OK)
-      return ret;
-    
-    TSXDGAQueryExtension(display, &evbase, &erbase);
-    
-    /* Now, start handling of DGA events giving the handle to the DDraw window
-       as the window for which the event will be reported */
-    TSXDGASelectInput(display, DefaultScreen(display),
-		      KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
-    X11DRV_EVENT_SetDGAStatus(hwnd, evbase);
-    
-    return DD_OK;
-  }
-}
-#endif
-
-/* Small helper to either use the cooperative window or create a new 
- * one (for mouse and keyboard input) and drawing in the Xlib implementation.
- */
-static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
-	RECT	rect;
-
-	/* Do destroy only our window */
-	if (This->d.window && GetPropA(This->d.window,ddProp)) {
-		DestroyWindow(This->d.window);
-		This->d.window = 0;
-	}
-	/* Sanity check cooperative window before assigning it to drawing. */
-	if (	IsWindow(This->d.mainWindow) &&
-		IsWindowVisible(This->d.mainWindow)
-	) {
-		/* if it does not fit, resize the cooperative window.
-		 * and hope the app likes it 
-		 */
-		GetWindowRect(This->d.mainWindow,&rect);
-		if ((((rect.right-rect.left) >= This->d.width)	&&
-		     ((rect.bottom-rect.top) >= This->d.height))
-		) {
-		    This->d.window = This->d.mainWindow;
-		    /* SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOOWNERZORDER); */
-		    This->d.paintable = 1;
-		}
-	}
-	/* ... failed, create new one. */
-	if (!This->d.window) {
-	    This->d.window = CreateWindowExA(
-		    0,
-		    "WINE_DirectDraw",
-		    "WINE_DirectDraw",
-		    WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
-		    0,0,
-		    This->d.width,
-		    This->d.height,
-		    0,
-		    0,
-		    0,
-		    NULL
-	    );
-	    /*Store THIS with the window. We'll use it in the window procedure*/
-	    SetPropA(This->d.window,ddProp,(LONG)This);
-	    ShowWindow(This->d.window,TRUE);
-	    UpdateWindow(This->d.window);
-	}
-	SetFocus(This->d.window);
-}
-
-static int _common_depth_to_pixelformat(DWORD depth, 
-					DDPIXELFORMAT *pixelformat, 
-					DDPIXELFORMAT *screen_pixelformat, 
-					int *pix_depth) {
-  XVisualInfo *vi;
-  XPixmapFormatValues *pf;
-  XVisualInfo vt;
-  int nvisuals, npixmap, i;
-  int match = 0;
-  int index = -2;
-
-  vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
-  pf = XListPixmapFormats(display, &npixmap);
-  
-  for (i = 0; i < npixmap; i++) {
-    if (pf[i].depth == depth) {
-      int j;
-      
-      for (j = 0; j < nvisuals; j++) {
-	if (vi[j].depth == pf[i].depth) {
-	  pixelformat->dwSize = sizeof(*pixelformat);
-	  if (depth == 8) {
-	    pixelformat->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
-	    pixelformat->u1.dwRBitMask = 0;
-	    pixelformat->u2.dwGBitMask = 0;
-	    pixelformat->u3.dwBBitMask = 0;
-	  } else {
-	    pixelformat->dwFlags = DDPF_RGB;
-	    pixelformat->u1.dwRBitMask = vi[j].red_mask;
-	    pixelformat->u2.dwGBitMask = vi[j].green_mask;
-	    pixelformat->u3.dwBBitMask = vi[j].blue_mask;
-	  }
-	  pixelformat->dwFourCC = 0;
-	  pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
-	  pixelformat->u4.dwRGBAlphaBitMask= 0;
-
-	  *screen_pixelformat = *pixelformat;
-	  
-	  if (pix_depth != NULL)
-	    *pix_depth = vi[j].depth;
-	  
-	  match = 1;
-	  index = -1;
-	  
-	  goto clean_up_and_exit;
-	}
-      }
-
-	ERR("No visual corresponding to pixmap format !\n");
-    }
-  }
-
-  if (match == 0) {
-    /* We try now to find an emulated mode */
-    int c;
-
-    for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
-      if (ModeEmulations[c].dest.depth == depth) {
-	/* Found an emulation function, now tries to find a matching visual / pixel format pair */
-    for (i = 0; i < npixmap; i++) {
-	  if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
-	      (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
-	int j;
-	
-	for (j = 0; j < nvisuals; j++) {
-	  if (vi[j].depth == pf[i].depth) {
-	    screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
-	    screen_pixelformat->dwFlags = DDPF_RGB;
-	    screen_pixelformat->dwFourCC = 0;
-	    screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
-	    screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
-	    screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
-	    screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
-	    screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
-
-		pixelformat->dwSize = sizeof(*pixelformat);
-		pixelformat->dwFourCC = 0;
-		if (depth == 8) {
-		  pixelformat->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
-		  pixelformat->u.dwRGBBitCount = 8;
-		  pixelformat->u1.dwRBitMask = 0;
-		  pixelformat->u2.dwGBitMask = 0;
-		  pixelformat->u3.dwBBitMask = 0;
-		} else {
-		  pixelformat->dwFlags = DDPF_RGB;
-		  pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
-		  pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
-		  pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
-		  pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
-		}
-		pixelformat->u4.dwRGBAlphaBitMask= 0;    
-
-	    if (pix_depth != NULL)
-	      *pix_depth = vi[j].depth;
-	    
-	    match = 2;
-		index = c;
-	    
-		goto clean_up_and_exit;
-	}
-	
-	  ERR("No visual corresponding to pixmap format !\n");
-      }
-    }
-  }
-      }
-    }
-  }
-  
- clean_up_and_exit:
-  TSXFree(vi);
-  TSXFree(pf);
-
-  return index;
-}
-
-#ifdef HAVE_LIBXXF86DGA2
-static void _DGA_Initialize_FrameBuffer(IDirectDrawImpl *This, int mode) {
-  DDPIXELFORMAT *pf = &(This->d.directdraw_pixelformat);
-
-  /* Now, get the device / mode description */
-  This->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode);
-  
-  This->e.dga.fb_width = This->e.dga.dev->mode.imageWidth;
-  TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
-  This->e.dga.fb_height = This->e.dga.dev->mode.viewportHeight;
-  TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
-	This->e.dga.dev->data,
-	This->e.dga.dev->mode.imageWidth,
-	(This->e.dga.dev->mode.imageWidth *
-	 This->e.dga.dev->mode.imageHeight *
-	 (This->e.dga.dev->mode.bitsPerPixel / 8))
-	);
-  TRACE("viewport height: %d\n", This->e.dga.dev->mode.viewportHeight);
-  /* Get the screen dimensions as seen by Wine.
-     In that case, it may be better to ignore the -desktop mode and return the
-     real screen size => print a warning */
-  This->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
-  This->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
-  This->e.dga.fb_addr = This->e.dga.dev->data;
-  This->e.dga.fb_memsize = (This->e.dga.dev->mode.imageWidth *
-				  This->e.dga.dev->mode.imageHeight *
-				  (This->e.dga.dev->mode.bitsPerPixel / 8));
-  This->e.dga.vpmask = 0;
-  
-  /* Fill the screen pixelformat */
-  pf->dwSize = sizeof(DDPIXELFORMAT);
-  pf->dwFourCC = 0;
-  pf->u.dwRGBBitCount = This->e.dga.dev->mode.bitsPerPixel;
-  if (This->e.dga.dev->mode.depth == 8) {
-    pf->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
-    pf->u1.dwRBitMask = 0;
-    pf->u2.dwGBitMask = 0;
-    pf->u3.dwBBitMask = 0;
-  } else {
-    pf->dwFlags = DDPF_RGB;
-    pf->u1.dwRBitMask = This->e.dga.dev->mode.redMask;
-    pf->u2.dwGBitMask = This->e.dga.dev->mode.greenMask;
-    pf->u3.dwBBitMask = This->e.dga.dev->mode.blueMask;
-  }
-  pf->u4.dwRGBAlphaBitMask= 0;
-  
-  This->d.screen_pixelformat = *pf; 
-}
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
-	LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
-) {
-        ICOM_THIS(IDirectDrawImpl,iface);
-        int	i,mode_count;
-
-	TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
-
-#ifdef HAVE_LIBXXF86DGA2
-	if (This->e.dga.version == 2) {
-	  XDGAMode *modes = This->e.dga.modes;
-	  int mode_to_use = -1;
-	  
-	  /* Search in the list a display mode that corresponds to what is requested */
-	  for (i = 0; i < This->e.dga.num_modes; i++) {
-	    if ((height == modes[i].viewportHeight) &&
-		(width == modes[i].viewportWidth) &&
-		(depth == modes[i].depth)) {
-	      mode_to_use = modes[i].num;
-	    }
-	  }
-
-	  if (mode_to_use < 0) {
-	    ERR("Could not find matching mode !!!\n");
-	    return DDERR_UNSUPPORTEDMODE;
-	  } else {
-	    TRACE("Using mode number %d\n", mode_to_use);
-	    
-	    TSXDGACloseFramebuffer(display, DefaultScreen(display));
-	    
-	    if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
-	      ERR("Error opening the frame buffer !!!\n");
-
-	      return DDERR_GENERIC;
-	    }
-	    
-	    /* Initialize the frame buffer */
-	    _DGA_Initialize_FrameBuffer(This, mode_to_use);
-
-	    /* Re-get (if necessary) the DGA events */
-	    TSXDGASelectInput(display, DefaultScreen(display),
-			      KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
-	  }
-	  
-	  return DD_OK;
-	}
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-
-	/* We hope getting the asked for depth */
-	if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
-	  /* I.e. no visual found or emulated */
-		ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
-		return DDERR_UNSUPPORTEDMODE;
-	}
-	
-	if (This->d.width < width) {
-		ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
-		return DDERR_UNSUPPORTEDMODE;
-	}
-	This->d.width	= width;
-	This->d.height	= height;
-
-	/* adjust fb_height, so we don't overlap */
-	if (This->e.dga.fb_height < height)
-		This->e.dga.fb_height = height;
-	_common_IDirectDrawImpl_SetDisplayMode(This);
-
-#ifdef HAVE_LIBXXF86VM
-#ifdef HAVE_LIBXXF86DGA2
-	if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-        {
-            XF86VidModeModeInfo **all_modes, *vidmode = NULL;
-	    XF86VidModeModeLine mod_tmp;
-	    /* int dotclock_tmp; */
-
-            /* save original video mode and set fullscreen if available*/
-	    orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));  
-	    TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
-	    orig_mode->hdisplay = mod_tmp.hdisplay; 
-	    orig_mode->hsyncstart = mod_tmp.hsyncstart;
-	    orig_mode->hsyncend = mod_tmp.hsyncend; 
-	    orig_mode->htotal = mod_tmp.htotal;
-	    orig_mode->vdisplay = mod_tmp.vdisplay; 
-	    orig_mode->vsyncstart = mod_tmp.vsyncstart;
-	    orig_mode->vsyncend = mod_tmp.vsyncend; 
-	    orig_mode->vtotal = mod_tmp.vtotal;
-	    orig_mode->flags = mod_tmp.flags; 
-	    orig_mode->private = mod_tmp.private;
-	    
-            TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
-            for (i=0;i<mode_count;i++)
-            {
-                if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
-                {
-                    vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
-                    *vidmode = *(all_modes[i]);
-                    break;
-                } else
-                    TSXFree(all_modes[i]->private);
-            }
-	    for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
-            TSXFree(all_modes);
-
-            if (!vidmode)
-                WARN("Fullscreen mode not available!\n");
-
-            if (vidmode)
-	      {
-	        TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
-                TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
-#if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
-		TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
-#endif
-	      }
-        }
-#endif
-
-	/* FIXME: this function OVERWRITES several signal handlers. 
-	 * can we save them? and restore them later? In a way that
-	 * it works for the library too?
-	 */
-	TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
-	TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
-
-#ifdef RESTORE_SIGNALS
-	SIGNAL_Init();
-#endif
-	return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-/* *************************************
-      16 / 15 bpp to palettized 8 bpp
-   ************************************* */
-static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
-  unsigned char  *c_src = (unsigned char  *) src;
-  unsigned short *c_dst = (unsigned short *) dst;
-  int y;
-
-  if (palette != NULL) {
-    const unsigned short * pal = (unsigned short *) palette->screen_palents;
-
-    for (y = height; y--; ) {
-#if defined(__i386__) && defined(__GNUC__)
-      /* gcc generates slightly inefficient code for the the copy / lookup,
-       * it generates one excess memory access (to pal) per pixel. Since
-       * we know that pal is not modified by the memory write we can
-       * put it into a register and reduce the number of memory accesses 
-       * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
-       * (This is not guaranteed to be the fastest method.)
-       */
-      __asm__ __volatile__(
-      "xor %%eax,%%eax\n"
-      "1:\n"
-      "    lodsb\n"
-      "    movw (%%edx,%%eax,2),%%ax\n"
-      "    stosw\n"
-      "	   xor %%eax,%%eax\n"
-      "    loop 1b\n"
-      : "=S" (c_src), "=D" (c_dst)
-      : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
-      : "eax", "cc", "memory"
-      );
-      c_src+=(pitch-width);
-#else
-      unsigned char * srclineend = c_src+width;
-      while (c_src < srclineend)
-        *c_dst++ = pal[*c_src++];
-      c_src+=(pitch-width);
-#endif
-    }
-  } else {
-    WARN("No palette set...\n");
-    memset(dst, 0, width * height * 2);
-  }
-}
-static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
-  int i;
-  unsigned short *pal = (unsigned short *) screen_palette;
-  
-  for (i = 0; i < count; i++)
-    pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
-		      ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
-		      ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
-}
-static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
-  int i;
-  unsigned short *pal = (unsigned short *) screen_palette;
-  
-  for (i = 0; i < count; i++)
-    pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
-		      ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
-		      ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
-}
-
-/* *************************************
-      24 to palettized 8 bpp
-   ************************************* */
-static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
-  unsigned char  *c_src = (unsigned char  *) src;
-  unsigned char *c_dst = (unsigned char *) dst;
-  int y;
-
-  if (palette != NULL) {
-    const unsigned int *pal = (unsigned int *) palette->screen_palents;
-    
-    for (y = height; y--; ) {
-      unsigned char * srclineend = c_src+width;
-      while (c_src < srclineend ) {
-	register long pixel = pal[*c_src++];
-	*c_dst++ = pixel;
-	*c_dst++ = pixel>>8;
-	*c_dst++ = pixel>>16;
-      }
-      c_src+=(pitch-width);
-    }
-  } else {
-    WARN("No palette set...\n");
-    memset(dst, 0, width * height * 4);
-  }
-}
-/* *************************************
-      32 bpp to palettized 8 bpp
-   ************************************* */
-static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
-  unsigned char  *c_src = (unsigned char  *) src;
-  unsigned int *c_dst = (unsigned int *) dst;
-  int y;
-
-  if (palette != NULL) {
-    const unsigned int *pal = (unsigned int *) palette->screen_palents;
-    
-    for (y = height; y--; ) {
-#if defined(__i386__) && defined(__GNUC__)
-      /* See comment in pixel_convert_16_to_8 */
-      __asm__ __volatile__(
-      "xor %%eax,%%eax\n"
-      "1:\n"
-      "    lodsb\n"
-      "    movl (%%edx,%%eax,4),%%eax\n"
-      "    stosl\n"
-      "	   xor %%eax,%%eax\n"
-      "    loop 1b\n"
-      : "=S" (c_src), "=D" (c_dst)
-      : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
-      : "eax", "cc", "memory"
-      );
-      c_src+=(pitch-width);
-#else
-      unsigned char * srclineend = c_src+width;
-      while (c_src < srclineend )
-	*c_dst++ = pal[*c_src++];
-      c_src+=(pitch-width);
-#endif
-    }
-  } else {
-    WARN("No palette set...\n");
-    memset(dst, 0, width * height * 4);
-  }
-}
-
-static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
-  int i;
-  unsigned int *pal = (unsigned int *) screen_palette;
-  
-  for (i = 0; i < count; i++)
-    pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
-		      (((unsigned int) palent[i].peGreen) << 8) |
-		      ((unsigned int) palent[i].peBlue));
-}
-
-/* *************************************
-      32 bpp to 16 bpp
-   ************************************* */
-static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
-  unsigned short *c_src = (unsigned short *) src;
-  unsigned int *c_dst = (unsigned int *) dst;
-  int y;
-
-  for (y = height; y--; ) {
-    unsigned short * srclineend = c_src+width;
-    while (c_src < srclineend ) {
-      *c_dst++ = (((*c_src & 0xF800) << 8) |
-		  ((*c_src & 0x07E0) << 5) |
-		  ((*c_src & 0x001F) << 3));
-      c_src++;
-    }
-    c_src+=((pitch/2)-width);
-  }
-}
-
-
-static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
-	LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
-) {
-        ICOM_THIS(IDirectDrawImpl,iface);
-	char	buf[200];
-        WND *tmpWnd;
-	int c;
-
-	TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
-		      This, width, height, depth);
-
-	switch ((c = _common_depth_to_pixelformat(depth,
-					     &(This->d.directdraw_pixelformat),
-					     &(This->d.screen_pixelformat),
-						  &(This->d.pixmap_depth)))) {
-	case -2:
-	  sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
-	  MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
-	  return DDERR_UNSUPPORTEDMODE;
-
-	case -1:
-	  /* No convertion */
-	  This->d.pixel_convert = NULL;
-	  This->d.palette_convert = NULL;
-	  break;
-
-	default:
-	  WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
-	  
-	  /* Set the depth convertion routines */
-	  This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
-	  This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
-	    }
-	    
-	This->d.width	= width;
-	This->d.height	= height;
-
-	_common_IDirectDrawImpl_SetDisplayMode(This);
-
-        tmpWnd = WIN_FindWndPtr(This->d.window);
-	This->d.paintable = 1;
-        This->d.drawable  = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
-        WIN_ReleaseWndPtr(tmpWnd);
-
-        /* We don't have a context for this window. Host off the desktop */
-        if( !This->d.drawable )
-        {
-           This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
-            WIN_ReleaseDesktop();
-        }
-	TRACE("Setting drawable to %ld\n", This->d.drawable);
-
-	if (get_option( "DXGrab", 0 )) {
-	    /* Confine cursor movement (risky, but the user asked for it) */
-	    TSXGrabPointer(display, This->d.drawable, True, 0, GrabModeAsync, GrabModeAsync, This->d.drawable, None, CurrentTime);
-	}
-
-	return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
-	LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
-	if (!caps1 && !caps2)
-	   return DDERR_INVALIDPARAMS;
-	if (caps1) {
-		caps1->dwVidMemTotal = This->e.dga.fb_memsize;
-		caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);		/* we can do anything */
-		caps1->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
-	}
-	if (caps2) {
-		caps2->dwVidMemTotal = This->e.dga.fb_memsize;
-		caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);		/* we can do anything */
-		caps2->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
-	}
-	return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static void fill_caps(LPDDCAPS caps) {
-  /* This function tries to fill the capabilities of Wine's DDraw implementation.
-     Need to be fixed, though.. */
-  if (caps == NULL)
-    return;
-
-  caps->dwSize = sizeof(*caps);
-  caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM |  DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
-  caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
-  caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
-  caps->dwFXCaps = 0;
-  caps->dwFXAlphaCaps = 0;
-  caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
-  caps->dwSVCaps = 0;
-  caps->dwZBufferBitDepths = DDBD_16;
-  /* I put here 8 Mo so that D3D applications will believe they have enough memory
-     to put textures in video memory.
-     BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
-     for example) ? */
-  caps->dwVidMemTotal = 8192 * 1024;
-  caps->dwVidMemFree = 8192 * 1024;
-  /* These are all the supported capabilities of the surfaces */
-  caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
-    DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
-      DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
-	DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
-#ifdef HAVE_MESAGL
-  caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
-  caps->dwCaps2 |=  DDCAPS2_NO2DDURING3DSCENE;
-  caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
-#endif
-}
-
-static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
-	LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
-)  {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
-
-	/* Put the same caps for the two capabilities */
-	fill_caps(caps1);
-	fill_caps(caps2);
-
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
-	LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-        IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
-	FIXME("(%p)->(%08lx,%p,%p),stub!\n",
-		This,x,ilpddclip,lpunk
-	);
-	*ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
-	(*ilpddclip)->ref = 1;
-	ICOM_VTBL(*ilpddclip) = &ddclipvt;
-	return DD_OK;
-}
-
-static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
-	IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
-) {
-	int size = 0;
-	  
-	if (TRACE_ON(ddraw))
-	  _dump_paletteformat(dwFlags);
-	
-	*lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
-	if (*lpddpal == NULL) return E_OUTOFMEMORY;
-	(*lpddpal)->ref = 1;
-	(*lpddpal)->ddraw = (IDirectDrawImpl*)This;
-	(*lpddpal)->installed = 0;
-
-	  if (dwFlags & DDPCAPS_1BIT)
-	    size = 2;
-	  else if (dwFlags & DDPCAPS_2BIT)
-	    size = 4;
-	  else if (dwFlags & DDPCAPS_4BIT)
-	    size = 16;
-	  else if (dwFlags & DDPCAPS_8BIT)
-	    size = 256;
-	  else
-	    ERR("unhandled palette format\n");
-	*psize = size;
-	
-        if (palent)
-        {
-	  /* Now, if we are in 'depth conversion mode', create the screen palette */
-	  if (This->d.palette_convert != NULL)	    
-	    This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
-
-	  memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
-        } else if (This->d.palette_convert != NULL) {
-	  /* In that case, put all 0xFF */
-	  memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
-	}
-	
-	return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
-	LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-        IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
-	HRESULT res;
-	int xsize = 0,i;
-
-	TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
-	res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
-	if (res != 0) return res;
-	ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
-	if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
-		(*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),X11DRV_GetVisual(),AllocAll);
-	} else {
-		FIXME("why are we doing CreatePalette in hi/truecolor?\n");
-		(*ilpddpal)->cm = 0;
-	}
-	if (((*ilpddpal)->cm)&&xsize) {
-	  for (i=0;i<xsize;i++) {
-		  XColor xc;
-
-		  xc.red = (*ilpddpal)->palents[i].peRed<<8;
-		  xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
-		  xc.green = (*ilpddpal)->palents[i].peGreen<<8;
-		  xc.flags = DoRed|DoBlue|DoGreen;
-		  xc.pixel = i;
-		  TSXStoreColor(display,(*ilpddpal)->cm,&xc);
-	  }
-	}
-	return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
-	LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-        IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
-	int xsize;
-	HRESULT res;
-
-	TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
-	res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
-	if (res != 0) return res;
-	ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
-	return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	TRACE("(%p)->()\n",This);
-	Sleep(1000);
-	TSXF86DGADirectVideo(display,DefaultScreen(display),0);
-#ifdef RESTORE_SIGNALS
-	SIGNAL_Init();
-#endif
-	return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	TRACE("(%p)->RestoreDisplayMode()\n", This);
-	Sleep(1000);
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
-	LPDIRECTDRAW2 iface,DWORD x,HANDLE h
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
-	return DD_OK;
-}
-
-static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-        TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
-
-	return ++(This->ref);
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-        TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-	if (!--(This->ref)) {
-#ifdef HAVE_LIBXXF86DGA2
-               if (This->e.dga.version == 2) {
-		 TRACE("Closing access to the FrameBuffer\n");
-                 TSXDGACloseFramebuffer(display, DefaultScreen(display));
-		 TRACE("Going back to normal X mode of operation\n");
-		 TSXDGASetMode(display, DefaultScreen(display), 0);
-
-                 /* Set the input handling back to absolute */
-                 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE);
-
-		 /* Remove the handling of DGA2 events */
-		 X11DRV_EVENT_SetDGAStatus(0, -1);
-
-		 /* Free the modes list */
-		 TSXFree(This->e.dga.modes);
-               } else
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-		 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
-		if (This->d.window && GetPropA(This->d.window,ddProp))
-			DestroyWindow(This->d.window);
-#ifdef HAVE_LIBXXF86VM
-		if (orig_mode) {
-			TSXF86VidModeSwitchToMode(
-				display,
-				DefaultScreen(display),
-				orig_mode);
-			if (orig_mode->privsize)
-				TSXFree(orig_mode->private);		
-			free(orig_mode);
-			orig_mode = NULL;
-		}
-#endif
-		
-#ifdef RESTORE_SIGNALS
-		SIGNAL_Init();
-#endif
-		HeapFree(GetProcessHeap(),0,This);
-		return S_OK;
-	}
-	return This->ref;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-        TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
-
-	if (!--(This->ref)) {
-		if (This->d.window && GetPropA(This->d.window,ddProp))
-			DestroyWindow(This->d.window);
-		HeapFree(GetProcessHeap(),0,This);
-		return S_OK;
-	}
-	/* FIXME: destroy window ... */
-	return This->ref;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
-	LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-
-	TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
-	if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
-		*obj = This;
-		IDirectDraw2_AddRef(iface);
-
-		TRACE("  Creating IUnknown interface (%p)\n", *obj);
-		
-		return S_OK;
-	}
-	if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
-		ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
-		IDirectDraw2_AddRef(iface);
-		*obj = This;
-
-		TRACE("  Creating IDirectDraw interface (%p)\n", *obj);
-		
-		return S_OK;
-	}
-	if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
-		ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
-		IDirectDraw2_AddRef(iface);
-		*obj = This;
-
-		TRACE("  Creating IDirectDraw2 interface (%p)\n", *obj);
-
-		return S_OK;
-	}
-	if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
-		ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
-		IDirectDraw2_AddRef(iface);
-		*obj = This;
-
-		TRACE("  Creating IDirectDraw4 interface (%p)\n", *obj);
-
-		return S_OK;
-	}
-	if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
-		IDirect3DImpl* d3d;
-
-		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-		d3d->ref = 1;
-		d3d->ddraw = (IDirectDrawImpl*)This;
-		IDirectDraw2_AddRef(iface);
-		ICOM_VTBL(d3d) = &d3dvt;
-		*obj = d3d;
-
-		TRACE("  Creating IDirect3D interface (%p)\n", *obj);
-		
-		return S_OK;
-	}
-	if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
-		IDirect3D2Impl*	d3d;
-
-		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-		d3d->ref = 1;
-		d3d->ddraw = (IDirectDrawImpl*)This;
-		IDirectDraw2_AddRef(iface);
-		ICOM_VTBL(d3d) = &d3d2vt;
-		*obj = d3d;
-
-		TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
-		
-		return S_OK;
-	}
-	WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
-        return OLE_E_ENUM_NOMORE;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
-	LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-
-	TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
-	if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
-		*obj = This;
-		IDirectDraw2_AddRef(iface);
-
-		TRACE("  Creating IUnknown interface (%p)\n", *obj);
-		
-		return S_OK;
-	}
-	if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
-		ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
-		IDirectDraw2_AddRef(iface);
-		*obj = This;
-
-		TRACE("  Creating IDirectDraw interface (%p)\n", *obj);
-		
-		return S_OK;
-	}
-	if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
-		ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
-		IDirectDraw2_AddRef(iface);
-		*obj = This;
-
-		TRACE("  Creating IDirectDraw2 interface (%p)\n", *obj);
-		
-		return S_OK;
-	}
-	if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
-		ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
-		IDirectDraw2_AddRef(iface);
-		*obj = This;
-
-		TRACE("  Creating IDirectDraw4 interface (%p)\n", *obj);
-
-		return S_OK;
-	}
-	if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
-		IDirect3DImpl* d3d;
-
-		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-		d3d->ref = 1;
-		d3d->ddraw = (IDirectDrawImpl*)This;
-		IDirectDraw2_AddRef(iface);
-		ICOM_VTBL(d3d) = &d3dvt;
-		*obj = d3d;
-
-		TRACE("  Creating IDirect3D interface (%p)\n", *obj);
-
-		return S_OK;
-	}
-	if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
-		IDirect3D2Impl* d3d;
-
-		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
-		d3d->ref = 1;
-		d3d->ddraw = (IDirectDrawImpl*)This;
-		IDirectDraw2_AddRef(iface);
-		ICOM_VTBL(d3d) = &d3d2vt;
-		*obj = d3d;
-
-		TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
-
-		return S_OK;
-	}
-	WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
-        return OLE_E_ENUM_NOMORE;
-}
-
-static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
-	LPDIRECTDRAW2 iface,BOOL *status
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-        TRACE("(%p)->(%p)\n",This,status);
-	*status = TRUE;
-	return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
-	LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	DDSURFACEDESC	ddsfd;
-	static struct {
-		int w,h;
-	} modes[5] = { /* some of the usual modes */
-		{512,384},
-		{640,400},
-		{640,480},
-		{800,600},
-		{1024,768},
-	};
-	static int depths[4] = {8,16,24,32};
-	int	i,j;
-
-	TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
-	ddsfd.dwSize = sizeof(ddsfd);
-	ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
-	if (dwFlags & DDEDM_REFRESHRATES) {
-		ddsfd.dwFlags |= DDSD_REFRESHRATE;
-		ddsfd.u.dwRefreshRate = 60;
-	}
-	ddsfd.ddsCaps.dwCaps = 0;
-	ddsfd.dwBackBufferCount = 1;
-
-#ifdef HAVE_LIBXXF86DGA2
-	if (This->e.dga.version == 2) {
-	  XDGAMode *modes = This->e.dga.modes;
-
-	  ddsfd.dwFlags |= DDSD_PITCH;
-	  for (i = 0; i < This->e.dga.num_modes; i++) {
-	    if (TRACE_ON(ddraw)) {
-	      DPRINTF("  Enumerating mode %d : %s (FB: %dx%d / VP: %dx%d) - depth %d -",
-		      modes[i].num,
-		      modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
-		      modes[i].viewportWidth, modes[i].viewportHeight,
-		      modes[i].depth);
-	      if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
-	      if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
-	      if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
-	      if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
-	      if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
-	      DPRINTF("\n");
-	    }
-	    /* Fill the pixel format */
-	    ddsfd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
-	    ddsfd.ddpfPixelFormat.dwFourCC = 0;
-	    ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
-	    ddsfd.ddpfPixelFormat.u.dwRGBBitCount = modes[i].bitsPerPixel;
-	    if (modes[i].depth == 8) {
-	      ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
-	      ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
-	      ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
-	      ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
-	      ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
-	    } else {
-	      ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
-	      ddsfd.ddpfPixelFormat.u1.dwRBitMask = modes[i].redMask;
-	      ddsfd.ddpfPixelFormat.u2.dwGBitMask = modes[i].greenMask;
-	      ddsfd.ddpfPixelFormat.u3.dwBBitMask = modes[i].blueMask;
-	    }
-	    
-	    ddsfd.dwWidth = modes[i].viewportWidth;
-	    ddsfd.dwHeight = modes[i].viewportHeight;
-	    ddsfd.lPitch = modes[i].imageWidth;
-	      
-	    /* Send mode to the application */
-	    if (!modescb(&ddsfd,context)) return DD_OK;
-	  }
-	} else {
-#endif
-	for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
-		ddsfd.dwBackBufferCount = 1;
-		ddsfd.ddpfPixelFormat.dwFourCC	= 0;
-		ddsfd.ddpfPixelFormat.dwFlags 	= DDPF_RGB;
-		ddsfd.ddpfPixelFormat.u.dwRGBBitCount	= depths[i];
-		/* FIXME: those masks would have to be set in depth > 8 */
-		if (depths[i]==8) {
-		ddsfd.ddpfPixelFormat.u1.dwRBitMask  	= 0;
-		ddsfd.ddpfPixelFormat.u2.dwGBitMask  	= 0;
-		ddsfd.ddpfPixelFormat.u3.dwBBitMask 	= 0;
-		ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
-			ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
-			ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
-		} else {
-		  ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
-		  
-		  /* FIXME: We should query those from X itself */
-		  switch (depths[i]) {
-		  case 16:
-		    ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
-		    ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
-		    ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
-		    break;
-		  case 24:
-		    ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
-		    ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
-		    ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
-		    break;
-		  case 32:
-		    ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
-		    ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
-		    ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
-		    break;
-		  }
-		}
-
-		ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
-		ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
-		TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
-		if (!modescb(&ddsfd,context)) return DD_OK;
-
-		for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
-			ddsfd.dwWidth	= modes[j].w;
-			ddsfd.dwHeight	= modes[j].h;
-			TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
-			if (!modescb(&ddsfd,context)) return DD_OK;
-		}
-
-		if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
-			/* modeX is not standard VGA */
-
-			ddsfd.dwHeight = 200;
-			ddsfd.dwWidth = 320;
-			TRACE(" enumerating (320x200x%d)\n",depths[i]);
-			if (!modescb(&ddsfd,context)) return DD_OK;
-		}
-	}
-#ifdef HAVE_LIBXXF86DGA2
-      }
-#endif
-	return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
-	LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
-) {
-  ICOM_THIS(IDirectDraw2Impl,iface);
-  XVisualInfo *vi;
-  XPixmapFormatValues *pf;
-  XVisualInfo vt;
-  int xbpp = 1, nvisuals, npixmap, i, emu;
-  int has_mode[]  = { 0,  0,  0,  0 };
-  int has_depth[] = { 8, 15, 16, 24 };
-  DDSURFACEDESC	ddsfd;
-  static struct {
-	int w,h;
-  } modes[] = { /* some of the usual modes */
-	{512,384},
-	{640,400},
-	{640,480},
-	{800,600},
-	{1024,768},
-	{1280,1024}
-  };
-  DWORD maxWidth, maxHeight;
-
-  TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
-  ddsfd.dwSize = sizeof(ddsfd);
-  ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_PITCH;
-  if (dwFlags & DDEDM_REFRESHRATES) {
-    ddsfd.dwFlags |= DDSD_REFRESHRATE;
-    ddsfd.u.dwRefreshRate = 60;
-  }
-  maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
-  maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
-  
-  vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
-  pf = XListPixmapFormats(display, &npixmap);
-
-  i = 0;
-  emu = 0;
-  while ((i < npixmap) || (emu != 4)) {
-    int mode_index = 0;
-    int send_mode = 0;
-    int j;
-
-    if (i < npixmap) {
-      for (j = 0; j < 4; j++) {
-	if (has_depth[j] == pf[i].depth) {
-	  mode_index = j;
-	  break;
-	}
-      }
-      if (j == 4) {
-	i++;
-	continue;
-      }
-      
-
-      if (has_mode[mode_index] == 0) {
-	if (mode_index == 0) {
-	  send_mode = 1;
-
-	  ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
-	  ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
-	  ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
-	  ddsfd.ddpfPixelFormat.dwFourCC = 0;
-	  ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
-	  ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
-	  ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
-	  ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
-	  ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
-
-	  xbpp = 1;
-	  
-	  has_mode[mode_index] = 1;
-	} else {
-      /* All the 'true color' depths (15, 16 and 24)
-	 First, find the corresponding visual to extract the bit masks */
-	  for (j = 0; j < nvisuals; j++) {
-	    if (vi[j].depth == pf[i].depth) {
-	      ddsfd.ddsCaps.dwCaps = 0;
-	      ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
-	      ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
-	      ddsfd.ddpfPixelFormat.dwFourCC = 0;
-	      ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
-	      ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
-	      ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
-	      ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
-	      ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
-
-	      xbpp = pf[i].bits_per_pixel/8;
-
-	      send_mode = 1;
-		  has_mode[mode_index] = 1;
-	      break;
-	    }
-	  }
-	  if (j == nvisuals)
-	    ERR("Did not find visual corresponding the the pixmap format !\n");
-	}
-      }
-      i++;
-    } else {
-      /* Now to emulated modes */
-      if (has_mode[emu] == 0) {
-	int c;
-	int l;
-	int depth = has_depth[emu];
-      
-	for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
-	  if (ModeEmulations[c].dest.depth == depth) {
-	    /* Found an emulation function, now tries to find a matching visual / pixel format pair */
-	    for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
-	      if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
-		  (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
-		int j;
-		for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
-		  if ((vi[j].depth == pf[l].depth) &&
-		      (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
-		      (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
-		      (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
-		    ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
-		    ddsfd.ddpfPixelFormat.dwFourCC = 0;
-		    if (depth == 8) {
-		      ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
-		      ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
-		      ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
-		      ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
-		      ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
-    } else {
-		      ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
-		      ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
-		      ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
-		      ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
-		      ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
-		    }
-		    ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
-		    send_mode = 1;
-		  }
-		  
-		  if (send_mode == 0)
-		    ERR("No visual corresponding to pixmap format !\n");
-		}
-	      }
-	    }
-          }
-	}
-      }
-
-      emu++;
-    }
-
-    if (send_mode) {
-      int mode;
-
-      if (TRACE_ON(ddraw)) {
-	TRACE("Enumerating with pixel format : \n");
-	_dump_pixelformat(&(ddsfd.ddpfPixelFormat));
-	DPRINTF("\n");
-      }
-      
-      for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
-	/* Do not enumerate modes we cannot handle anyway */
-	if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
-	  break;
-
-	ddsfd.dwWidth = modes[mode].w;
-	ddsfd.dwHeight= modes[mode].h;
-	ddsfd.lPitch  = ddsfd.dwWidth * xbpp;
-	
-	/* Now, send the mode description to the application */
-	TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
-	if (!modescb(&ddsfd, context))
-	  goto exit_enum;
-      }
-
-      if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
-	/* modeX is not standard VGA */
-	ddsfd.dwWidth = 320;
-	ddsfd.dwHeight = 200;
-	ddsfd.lPitch  = 320 * xbpp;
-	if (!modescb(&ddsfd, context))
-	  goto exit_enum;
-      }
-    }
-  }
- exit_enum:
-  TSXFree(vi);
-  TSXFree(pf);
-
-  return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
-	LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	TRACE("(%p)->(%p)\n",This,lpddsfd);
-	lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
-	lpddsfd->dwHeight = This->d.height;
-	lpddsfd->dwWidth = This->d.width;
-	lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
-	lpddsfd->dwBackBufferCount = 2;
-	lpddsfd->u.dwRefreshRate = 60;
-	lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
-	lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
-	if (TRACE_ON(ddraw)) {
-	  _dump_surface_desc(lpddsfd);
-	}
-	return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
-	LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
-	lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
-	lpddsfd->dwHeight = This->d.height;
-	lpddsfd->dwWidth = This->d.width;
-	lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
-	lpddsfd->dwBackBufferCount = 2;
-	lpddsfd->u.dwRefreshRate = 60;
-	lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
-	lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
-	if (TRACE_ON(ddraw)) {
-	  _dump_surface_desc(lpddsfd);
-	}
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	TRACE("(%p)->()\n",This);
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
-	LPDIRECTDRAW2 iface,LPDWORD freq
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
-	*freq = 60*100; /* 60 Hz */
-	return DD_OK;
-}
-
-/* what can we directly decompress? */
-static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
-	LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	FIXME("(%p,%p,%p), stub\n",This,x,y);
-	return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
-	LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
-) {
-  ICOM_THIS(IDirectDraw2Impl,iface);
-  FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw2Impl_Compact(
-          LPDIRECTDRAW2 iface )
-{
-  ICOM_THIS(IDirectDraw2Impl,iface);
-  FIXME("(%p)->()\n", This );
- 
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
-						 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
-  ICOM_THIS(IDirectDraw2Impl,iface);
-  FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
-					       LPDWORD lpdwScanLine) {
-  ICOM_THIS(IDirectDraw2Impl,iface);
-  FIXME("(%p)->(%p)\n", This, lpdwScanLine);
-
-  if (lpdwScanLine)
-	  *lpdwScanLine = 0;
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
-					      GUID *lpGUID) {
-  ICOM_THIS(IDirectDraw2Impl,iface);
-  FIXME("(%p)->(%p)\n", This, lpGUID);
-  
-  return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-
-/* Note: Hack so we can reuse the old functions without compiler warnings */
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)	(typeof(dga_ddvt.fn##fun))
-#else
-# define XCAST(fun)	(void *)
-#endif
-
-static ICOM_VTABLE(IDirectDraw) dga_ddvt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
-	XCAST(AddRef)IDirectDraw2Impl_AddRef,
-	XCAST(Release)DGA_IDirectDraw2Impl_Release,
-	XCAST(Compact)IDirectDraw2Impl_Compact,
-	XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
-	XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
-	XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
-	XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
-	XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
-	XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
-	XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
-	XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
-	XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
-	XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
-	XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
-	XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
-	XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
-	XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
-	XCAST(Initialize)IDirectDraw2Impl_Initialize,
-	XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
-#ifdef HAVE_LIBXXF86DGA2
-	XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel,
-#else
-	XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
-#endif
-	DGA_IDirectDrawImpl_SetDisplayMode,
-	XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
-};
-
-#undef XCAST
-
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-/* Note: Hack so we can reuse the old functions without compiler warnings */
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)	(typeof(xlib_ddvt.fn##fun))
-#else
-# define XCAST(fun)	(void *)
-#endif
-
-static ICOM_VTABLE(IDirectDraw) xlib_ddvt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
-	XCAST(AddRef)IDirectDraw2Impl_AddRef,
-	XCAST(Release)Xlib_IDirectDraw2Impl_Release,
-	XCAST(Compact)IDirectDraw2Impl_Compact,
-	XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
-	XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
-	XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
-	XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
-	XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
-	XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
-	XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
-	XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
-	XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
-	XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
-	XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
-	XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
-	XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
-	XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
-	XCAST(Initialize)IDirectDraw2Impl_Initialize,
-	XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
-	XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
-	Xlib_IDirectDrawImpl_SetDisplayMode,
-	XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
-};
-
-#undef XCAST
-
-/*****************************************************************************
- * 	IDirectDraw2
- *
- */
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
-	LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
-) {
-	FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags ); 
-	return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
-	LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
-) {
-	FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags ); 
-	return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
-	LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	TRACE("(%p)->(%p,%p,%p)\n",
-		This,ddscaps,total,free
-	);
-	if (total) *total = This->e.dga.fb_memsize * 1024;
-	if (free) *free = This->e.dga.fb_memsize * 1024;
-	return DD_OK;
-}
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
-	LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
-) {
-        ICOM_THIS(IDirectDraw2Impl,iface);
-	TRACE("(%p)->(%p,%p,%p)\n",
-		This,ddscaps,total,free
-	);
-	if (total) *total = 2048 * 1024;
-	if (free) *free = 2048 * 1024;
-	return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-static ICOM_VTABLE(IDirectDraw2) dga_dd2vt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	DGA_IDirectDraw2Impl_QueryInterface,
-	IDirectDraw2Impl_AddRef,
-	DGA_IDirectDraw2Impl_Release,
-	IDirectDraw2Impl_Compact,
-	IDirectDraw2Impl_CreateClipper,
-	DGA_IDirectDraw2Impl_CreatePalette,
-	DGA_IDirectDraw2Impl_CreateSurface,
-	IDirectDraw2Impl_DuplicateSurface,
-	DGA_IDirectDraw2Impl_EnumDisplayModes,
-	IDirectDraw2Impl_EnumSurfaces,
-	IDirectDraw2Impl_FlipToGDISurface,
-	DGA_IDirectDraw2Impl_GetCaps,
-	DGA_IDirectDraw2Impl_GetDisplayMode,
-	IDirectDraw2Impl_GetFourCCCodes,
-	IDirectDraw2Impl_GetGDISurface,
-	IDirectDraw2Impl_GetMonitorFrequency,
-	IDirectDraw2Impl_GetScanLine,
-	IDirectDraw2Impl_GetVerticalBlankStatus,
-	IDirectDraw2Impl_Initialize,
-	DGA_IDirectDraw2Impl_RestoreDisplayMode,
-	IDirectDraw2Impl_SetCooperativeLevel,
-	DGA_IDirectDraw2Impl_SetDisplayMode,
-	IDirectDraw2Impl_WaitForVerticalBlank,
-	DGA_IDirectDraw2Impl_GetAvailableVidMem
-};
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	Xlib_IDirectDraw2Impl_QueryInterface,
-	IDirectDraw2Impl_AddRef,
-	Xlib_IDirectDraw2Impl_Release,
-	IDirectDraw2Impl_Compact,
-	IDirectDraw2Impl_CreateClipper,
-	Xlib_IDirectDraw2Impl_CreatePalette,
-	Xlib_IDirectDraw2Impl_CreateSurface,
-	IDirectDraw2Impl_DuplicateSurface,
-	Xlib_IDirectDraw2Impl_EnumDisplayModes,
-	IDirectDraw2Impl_EnumSurfaces,
-	IDirectDraw2Impl_FlipToGDISurface,
-	Xlib_IDirectDraw2Impl_GetCaps,
-	Xlib_IDirectDraw2Impl_GetDisplayMode,
-	IDirectDraw2Impl_GetFourCCCodes,
-	IDirectDraw2Impl_GetGDISurface,
-	IDirectDraw2Impl_GetMonitorFrequency,
-	IDirectDraw2Impl_GetScanLine,
-	IDirectDraw2Impl_GetVerticalBlankStatus,
-	IDirectDraw2Impl_Initialize,
-	Xlib_IDirectDraw2Impl_RestoreDisplayMode,
-	IDirectDraw2Impl_SetCooperativeLevel,
-	Xlib_IDirectDraw2Impl_SetDisplayMode,
-	IDirectDraw2Impl_WaitForVerticalBlank,
-	Xlib_IDirectDraw2Impl_GetAvailableVidMem	
-};
-
-/*****************************************************************************
- * 	IDirectDraw4
- *
- */
-
-static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
-						    HDC hdc,
-						    LPDIRECTDRAWSURFACE *lpDDS) {
-  ICOM_THIS(IDirectDraw4Impl,iface);
-  FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
-  ICOM_THIS(IDirectDraw4Impl,iface);
-  FIXME("(%p)->()\n", This);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
-  ICOM_THIS(IDirectDraw4Impl,iface);
-  FIXME("(%p)->()\n", This);
-
-  return DD_OK;
-}
-
-static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
-						       LPDDDEVICEIDENTIFIER lpdddi,
-						       DWORD dwFlags) {
-  ICOM_THIS(IDirectDraw4Impl,iface);
-  FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
-  
-  return DD_OK;
-}
-
-#ifdef HAVE_LIBXXF86DGA
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)	(typeof(dga_dd4vt.fn##fun))
-#else
-# define XCAST(fun)	(void*)
-#endif
-
-static ICOM_VTABLE(IDirectDraw4) dga_dd4vt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
-	XCAST(AddRef)IDirectDraw2Impl_AddRef,
-	XCAST(Release)DGA_IDirectDraw2Impl_Release,
-	XCAST(Compact)IDirectDraw2Impl_Compact,
-	XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
-	XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
-	XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
-	XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
-	XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
-	XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
-	XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
-	XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
-	XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
-	XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
-	XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
-	XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
-	XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
-	XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
-	XCAST(Initialize)IDirectDraw2Impl_Initialize,
-	XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
-	XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
-	XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
-	XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
-	XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
-	IDirectDraw4Impl_GetSurfaceFromDC,
-	IDirectDraw4Impl_RestoreAllSurfaces,
-	IDirectDraw4Impl_TestCooperativeLevel,
-	IDirectDraw4Impl_GetDeviceIdentifier
-};
-
-#undef XCAST
-
-#endif /* defined(HAVE_LIBXXF86DGA) */
-
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
-# define XCAST(fun)	(typeof(xlib_dd4vt.fn##fun))
-#else
-# define XCAST(fun)	(void*)
-#endif
-
-static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
-	XCAST(AddRef)IDirectDraw2Impl_AddRef,
-	XCAST(Release)Xlib_IDirectDraw2Impl_Release,
-	XCAST(Compact)IDirectDraw2Impl_Compact,
-	XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
-	XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
-	XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
-	XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
-	XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
-	XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
-	XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
-	XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
-	XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
-	XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
-	XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
-	XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
-	XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
-	XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
-	XCAST(Initialize)IDirectDraw2Impl_Initialize,
-	XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
-	XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
-	XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
-	XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
-	XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
-	IDirectDraw4Impl_GetSurfaceFromDC,
-	IDirectDraw4Impl_RestoreAllSurfaces,
-	IDirectDraw4Impl_TestCooperativeLevel,
-	IDirectDraw4Impl_GetDeviceIdentifier
-};
-
-#undef XCAST
-
-/******************************************************************************
- * 				DirectDrawCreate
- */
-
-static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
-{
-   LRESULT ret;
-   IDirectDrawImpl* ddraw = NULL;
-   DWORD lastError;
-
-   /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
-
-   SetLastError( ERROR_SUCCESS );
-   ddraw  = (IDirectDrawImpl*)GetPropA( hwnd, ddProp );
-   if( (!ddraw)  && ( ( lastError = GetLastError() ) != ERROR_SUCCESS )) 
-   {
-     ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
-   }
-
-   if( ddraw )
-   {
-      /* Perform any special direct draw functions */
-      if (msg==WM_PAINT)
-        ddraw->d.paintable = 1;
-
-      /* Now let the application deal with the rest of this */
-      if( ddraw->d.mainWindow )
-      {
-    
-        /* Don't think that we actually need to call this but... 
-           might as well be on the safe side of things... */
-
-	/* I changed hwnd to ddraw->d.mainWindow as I did not see why
-	   it should be the procedures of our fake window that gets called
-	   instead of those of the window provided by the application.
-	   And with this patch, mouse clicks work with Monkey Island III
-	     - Lionel */
-	ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
-
-        if( !ret )
-        {
-          WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
-          /* We didn't handle the message - give it to the application */
-          if (ddraw && ddraw->d.mainWindow && tmpWnd)
-          {
-          	ret = CallWindowProcA(tmpWnd->winproc,
-               	                   ddraw->d.mainWindow, msg, wParam, lParam );
-	  }
-          WIN_ReleaseWndPtr(tmpWnd);
-
-        }
-        
-      } else {
-        ret = DefWindowProcA(hwnd, msg, wParam, lParam );
-      } 
-
-    }
-    else
-    {
-	ret = DefWindowProcA(hwnd,msg,wParam,lParam);
-    }
-
-    return ret;
-}
-
-static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
-#ifdef HAVE_LIBXXF86DGA
-        IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
-	int  memsize,banksize,major,minor,flags;
-	char *addr;
-	int  dga_version;
-	int  width, height;
-	  
-	/* Get DGA availability / version */
-	dga_version = DDRAW_DGA_Available();
-	
-	if (dga_version == 0) {
-	  MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
-	  return DDERR_GENERIC;
-	}
-
-	*ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
-	(*ilplpDD)->ref = 1;
-	ICOM_VTBL(*ilplpDD) = &dga_ddvt;
-#ifdef HAVE_LIBXXF86DGA2
-	if (dga_version == 1) {
-	  (*ilplpDD)->e.dga.version = 1;
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-	  TSXF86DGAQueryVersion(display,&major,&minor);
-	  TRACE("XF86DGA is version %d.%d\n",major,minor);
-	  TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
-	  if (!(flags & XF86DGADirectPresent))
-	    MESSAGE("direct video is NOT PRESENT.\n");
-	  TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
-	  (*ilplpDD)->e.dga.fb_width = width;
-	  TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
-	  TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
-	  (*ilplpDD)->e.dga.fb_height = height;
-	  TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
-		addr,width,banksize,memsize
-		);
-	  TRACE("viewport height: %d\n",height);
-	  /* Get the screen dimensions as seen by Wine.
-	     In that case, it may be better to ignore the -desktop mode and return the
-	     real screen size => print a warning */
-	  (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
-	  (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
-	  if (((*ilplpDD)->d.height != height) ||
-	      ((*ilplpDD)->d.width != width))
-	    WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
-	  (*ilplpDD)->e.dga.fb_addr = addr;
-	  (*ilplpDD)->e.dga.fb_memsize = memsize;
-	  (*ilplpDD)->e.dga.vpmask = 0;
-	  
-	  /* just assume the default depth is the DGA depth too */
-	  _common_depth_to_pixelformat(X11DRV_GetDepth(), &((*ilplpDD)->d.directdraw_pixelformat),
-                                       &((*ilplpDD)->d.screen_pixelformat), NULL);
-#ifdef RESTORE_SIGNALS
-	  SIGNAL_Init();
-#endif
-#ifdef HAVE_LIBXXF86DGA2
-	} else {
-	  XDGAMode *modes;
-	  int i, num_modes;
-	  int mode_to_use = 0;
-	  
-	  (*ilplpDD)->e.dga.version = 2;
-
-	  TSXDGAQueryVersion(display,&major,&minor);
-	  TRACE("XDGA is version %d.%d\n",major,minor);
-
-	  TRACE("Opening the frame buffer.\n");
-	  if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
-	    ERR("Error opening the frame buffer !!!\n");
-
-	    return DDERR_GENERIC;
-	  }
-
-	  /* List all available modes */
-	  modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
-	  (*ilplpDD)->e.dga.modes = modes;
-	  (*ilplpDD)->e.dga.num_modes = num_modes;
-	  if (TRACE_ON(ddraw)) {
-	    TRACE("Available modes :\n");
-	    for (i = 0; i < num_modes; i++) {
-	      DPRINTF("   %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
-		      modes[i].num,
-		      modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
-		      modes[i].viewportWidth, modes[i].viewportHeight,
-		      modes[i].depth);
-	      if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
-	      if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
-	      if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
-	      if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
-	      if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
-	      DPRINTF("\n");
-
-	      if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
-		  (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
-		  (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
-		mode_to_use = modes[i].num;
-	      }
-	    }
-	  }
-	  if (mode_to_use == 0) {
-	    ERR("Could not find mode !\n");
-	    mode_to_use = 1;
-	  } else {
-	    DPRINTF("Using mode number %d\n", mode_to_use);
-	  }
-
-	  /* Initialize the frame buffer */
-	  _DGA_Initialize_FrameBuffer(*ilplpDD, mode_to_use);
-	  /* Set the input handling for relative mouse movements */
-	  X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
-	}
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-	return DD_OK;
-#else /* defined(HAVE_LIBXXF86DGA) */
-	return DDERR_INVALIDDIRECTDRAWGUID;
-#endif /* defined(HAVE_LIBXXF86DGA) */
-}
-
-static BOOL
-DDRAW_XSHM_Available(void)
-{
-#ifdef HAVE_LIBXXSHM
-    if (get_option( "UseXShm", 1 ))
-    {
-        if (TSXShmQueryExtension(display))
-        {
-            int major, minor;
-            Bool shpix;
-            if (TSXShmQueryVersion(display, &major, &minor, &shpix)) return TRUE;
-        }
-    }
-#endif
-    return FALSE;
-}
-
-static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
-        IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
-
-	*ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
-	ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
-	(*ilplpDD)->ref = 1;
-	(*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
-
-	/* At DirectDraw creation, the depth is the default depth */
-	_common_depth_to_pixelformat(X11DRV_GetDepth(),
-				     &((*ilplpDD)->d.directdraw_pixelformat),
-				     &((*ilplpDD)->d.screen_pixelformat),
-				     &((*ilplpDD)->d.pixmap_depth));
-	(*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
-	(*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
-
-#ifdef HAVE_LIBXXSHM
-	/* Test if XShm is available. */
-	if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
-	  (*ilplpDD)->e.xlib.xshm_compl = 0;
-	  TRACE("Using XShm extension.\n");
-	}
-#endif
-	
-	return DD_OK;
-}
-
-HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
-        IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
-	WNDCLASSA	wc;
-        /* WND*            pParentWindow; */
-	HRESULT ret;
-
-	if (!HIWORD(lpGUID)) lpGUID = NULL;
-
-	TRACE("(%s,%p,%p)\n",debugstr_guid(lpGUID),ilplpDD,pUnkOuter);
-
-	if ( ( !lpGUID ) ||
-	     ( IsEqualGUID( &IID_IDirectDraw,  lpGUID ) ) ||
-	     ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
-	     ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
-		/* if they didn't request a particular interface, use the best
-		 * supported one */
-		if (DDRAW_DGA_Available())
-			lpGUID = &DGA_DirectDraw_GUID;
-		else
-			lpGUID = &XLIB_DirectDraw_GUID;
-	}
-
-	wc.style	= CS_GLOBALCLASS;
-	wc.lpfnWndProc	= Xlib_DDWndProc;
-	wc.cbClsExtra	= 0;
-	wc.cbWndExtra	= 0;
-
-        /* We can be a child of the desktop since we're really important */
-        /*
-         This code is not useful since hInstance is forced to 0 afterward
-        pParentWindow   = WIN_GetDesktop();
-	wc.hInstance	= pParentWindow ? pParentWindow->hwndSelf : 0;
-        */
-        wc.hInstance    = 0; 
-
-        
-	wc.hIcon	= 0;
-	wc.hCursor	= (HCURSOR)IDC_ARROWA;
-	wc.hbrBackground= NULL_BRUSH;
-	wc.lpszMenuName	= 0;
-	wc.lpszClassName= "WINE_DirectDraw";
-	RegisterClassA(&wc);
-
-	if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
-		ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
-	}
-	else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
-		ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
-	}
-	else {
-	  goto err;
-	}
-
-
-	(*ilplpDD)->d.winclass = RegisterClassA(&wc);
-	return ret;
-
-      err:
-	ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",
-            debugstr_guid(lpGUID),lplpDD,pUnkOuter);
-	return DDERR_INVALIDDIRECTDRAWGUID;
-}
-
-/*******************************************************************************
- * DirectDraw ClassFactory
- *
- *  Heavily inspired (well, can you say completely copied :-) ) from DirectSound
- *
- */
-typedef struct
-{
-    /* IUnknown fields */
-    ICOM_VFIELD(IClassFactory);
-    DWORD                       ref;
-} IClassFactoryImpl;
-
-static HRESULT WINAPI 
-DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
-	ICOM_THIS(IClassFactoryImpl,iface);
-
-	FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
-	return E_NOINTERFACE;
-}
-
-static ULONG WINAPI
-DDCF_AddRef(LPCLASSFACTORY iface) {
-	ICOM_THIS(IClassFactoryImpl,iface);
-	return ++(This->ref);
-}
-
-static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
-	ICOM_THIS(IClassFactoryImpl,iface);
-	/* static class, won't be  freed */
-	return --(This->ref);
-}
-
-static HRESULT WINAPI DDCF_CreateInstance(
-	LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
-) {
-	ICOM_THIS(IClassFactoryImpl,iface);
-
-	TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
-	if ( ( IsEqualGUID( &IID_IDirectDraw,  riid ) ) ||
-	     ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
-	     ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
-		/* FIXME: reuse already created DirectDraw if present? */
-		return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
-	}
-	return CLASS_E_CLASSNOTAVAILABLE;
-}
-
-static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
-	ICOM_THIS(IClassFactoryImpl,iface);
-	FIXME("(%p)->(%d),stub!\n",This,dolock);
-	return S_OK;
-}
-
-static ICOM_VTABLE(IClassFactory) DDCF_Vtbl = 
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	DDCF_QueryInterface,
-	DDCF_AddRef,
-	DDCF_Release,
-	DDCF_CreateInstance,
-	DDCF_LockServer
-};
-static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
-
-/*******************************************************************************
- * DllGetClassObject [DDRAW.13]
- * Retrieves class object from a DLL object
- *
- * NOTES
- *    Docs say returns STDAPI
- *
- * PARAMS
- *    rclsid [I] CLSID for the class object
- *    riid   [I] Reference to identifier of interface for class object
- *    ppv    [O] Address of variable to receive interface pointer for riid
- *
- * RETURNS
- *    Success: S_OK
- *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
- *             E_UNEXPECTED
- */
-DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
-{
-    TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
-    if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
-    	*ppv = (LPVOID)&DDRAW_CF;
-	IClassFactory_AddRef((IClassFactory*)*ppv);
-    return S_OK;
-    }
-    FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
-    return CLASS_E_CLASSNOTAVAILABLE;
-}
-
-
-/*******************************************************************************
- * DllCanUnloadNow [DDRAW.12]  Determines whether the DLL is in use.
- *
- * RETURNS
- *    Success: S_OK
- *    Failure: S_FALSE
- */
-DWORD WINAPI DDRAW_DllCanUnloadNow(void)
-{
-    FIXME("(void): stub\n");
-    return S_FALSE;
-}
-
-#else /* !defined(X_DISPLAY_MISSING) */
-
-#include "windef.h"
-#include "wtypes.h"
-
-#define DD_OK 0
-
-typedef void *LPUNKNOWN;
-typedef void *LPDIRECTDRAW;
-typedef void *LPDIRECTDRAWCLIPPER;
-typedef void *LPDDENUMCALLBACKA;
-typedef void *LPDDENUMCALLBACKEXA;
-typedef void *LPDDENUMCALLBACKEXW;
-typedef void *LPDDENUMCALLBACKW;
-
-/***********************************************************************
- *		DSoundHelp
- */
-HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z) 
-{
-  return DD_OK;
-}
-
-/***********************************************************************
- *		DirectDrawCreate
- */
-HRESULT WINAPI DirectDrawCreate(
-  LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) 
-{
-  return DD_OK;
-}
-
-/***********************************************************************
- *		DirectDrawCreateClipper
- */
-HRESULT WINAPI DirectDrawCreateClipper(
-  DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
-{
-  return DD_OK;
-}
-
-/***********************************************************************
- *		DirectDrawEnumerateA
- */
-HRESULT WINAPI DirectDrawEnumerateA(
-  LPDDENUMCALLBACKA lpCallback, LPVOID lpContext) 
-{
-  return DD_OK;
-}
-
-/***********************************************************************
- *		DirectDrawEnumerateExA
- */
-HRESULT WINAPI DirectDrawEnumerateExA(
-  LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
-{
-  return DD_OK;
-}
-
-/***********************************************************************
- *		DirectDrawEnumerateExW
- */
-HRESULT WINAPI DirectDrawEnumerateExW(
-  LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
-{
-  return DD_OK;
-}
-
-/***********************************************************************
- *		DirectDrawEnumerateW
- */
-HRESULT WINAPI DirectDrawEnumerateW(
-  LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) 
-{
-  return DD_OK;
-}
-
-/***********************************************************************
- *		DDRAW_DllGetClassObject
- */
-DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
-{
-    return CLASS_E_CLASSNOTAVAILABLE;
-}
-
-/***********************************************************************
- *		DDRAW_DllCanUnloadNow
- */
-DWORD WINAPI DDRAW_DllCanUnloadNow(void)
-{
-    return DD_OK;
-}
-
-#endif /* !defined(X_DISPLAY_MISSING) */
-
-
-
-
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 2f9da90..a16a342 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -1,30 +1,192 @@
-#ifndef __GRAPHICS_WINE_DDRAW_PRIVATE_H
-#define __GRAPHICS_WINE_DDRAW_PRIVATE_H
+#ifndef __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H
+#define __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H
 
-#include "config.h"
+/* MAY NOT CONTAIN X11 or DGA specific includes/defines/structs! */
 
-#ifdef HAVE_LIBXXF86DGA2
-#include "ts_xf86dga2.h"
-#endif /* defined(HAVE_LIBXXF86DGA2) */
-
-#include "ddraw.h"
+#include "wtypes.h"
+#include "winbase.h"
+#include "wingdi.h"
 #include "winuser.h"
+#include "ddraw.h"
+
+static WINE_UNUSED const char *ddProp = "WINE_DDRAW_Property";
+
+/****************************************************************************
+ * This is the main DirectDraw driver interface. It is supposed to be called
+ * only from the base functions and only used by those. It should neither be
+ * be called nor used within the interfaces.
+ */
+typedef struct ddraw_driver {
+	LPGUID	guid;		/*under which we are referenced and enumerated*/
+	CHAR	type[20];	/* type, usually "display" */
+	CHAR	name[40];	/* name, like "WINE Foobar DirectDraw Driver" */
+	int	preference;	/* how good we are. dga might get 100, xlib 50*/
+	HRESULT	(*createDDRAW)(LPDIRECTDRAW*); /* also check if arg is NULL */
+} ddraw_driver;
+
+extern void ddraw_register_driver(ddraw_driver*);
 
 /*****************************************************************************
- * Predeclare the interface implementation structures
+ * The implementation structures. They must not contain driver specific stuff.
+ * 
+ * For private data the "LPVOID private" pointer should be used.
  */
-typedef struct IDirectDrawPaletteImpl IDirectDrawPaletteImpl;
-typedef struct IDirectDrawClipperImpl IDirectDrawClipperImpl;
-typedef struct IDirectDrawImpl IDirectDrawImpl;
-typedef struct IDirectDraw2Impl IDirectDraw2Impl;
-typedef struct IDirectDraw4Impl IDirectDraw4Impl;
-typedef struct IDirectDrawSurfaceImpl IDirectDrawSurfaceImpl;
-typedef struct IDirectDrawSurface3Impl IDirectDrawSurface2Impl;
-typedef struct IDirectDrawSurface4Impl IDirectDrawSurface3Impl;
-typedef struct IDirectDrawSurface4Impl IDirectDrawSurface4Impl;
-typedef struct IDirectDrawColorControlImpl IDirectDrawColorControlImpl;
 
-#include "d3d_private.h"
+typedef struct IDirectDrawImpl	IDirectDrawImpl;
+typedef struct IDirectDraw2Impl	IDirectDraw2Impl;
+typedef struct IDirectDraw3Impl	IDirectDraw3Impl;
+typedef struct IDirectDraw4Impl	IDirectDraw4Impl;
+typedef struct IDirectDrawPaletteImpl	IDirectDrawPaletteImpl;
+typedef struct IDirectDrawClipperImpl	IDirectDrawClipperImpl;
+
+typedef struct IDirectDrawSurfaceImpl IDirectDrawSurfaceImpl;
+typedef struct IDirectDrawSurface2Impl IDirectDrawSurface2Impl;
+typedef struct IDirectDrawSurface4Impl IDirectDrawSurface4Impl;
+
+
+extern struct ICOM_VTABLE(IDirectDrawClipper)	ddclipvt;
+extern struct ICOM_VTABLE(IDirectDrawPalette)	ddraw_ddpalvt;
+
+/*****************************************************************************
+ * IDirectDraw implementation structure
+ */
+struct _common_directdrawdata
+{
+    DDPIXELFORMAT directdraw_pixelformat;
+    DDPIXELFORMAT screen_pixelformat;
+
+    int           pixmap_depth;
+    void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl *palette);
+    void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
+    DWORD         height,width;	/* set by SetDisplayMode */
+    HWND          mainWindow;   /* set by SetCooperativeLevel */
+
+    /* This is for the fake mainWindow */
+    ATOM          winclass;
+    HWND          window;
+    PAINTSTRUCT   ps;
+    int           paintable;
+};
+
+/*****************************************************************************
+ * IDirectDraw implementation structure
+ * 
+ * Note: All the IDirectDraw*Impl structures _MUST_ have IDENTICAL layout,
+ * 	 since we reuse functions across interface versions.
+ */
+struct IDirectDrawImpl
+{
+    /* IUnknown fields */
+    ICOM_VFIELD(IDirectDraw);
+    DWORD				ref;
+    /* IDirectDraw fields */
+    struct _common_directdrawdata	d;
+    LPVOID				private;
+};
+extern HRESULT WINAPI IDirectDrawImpl_SetDisplayMode(
+	LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
+);
+/*
+ * IDirectDraw2 implementation structure
+ */
+struct IDirectDraw2Impl
+{
+    /* IUnknown fields */
+    ICOM_VFIELD(IDirectDraw2);
+    DWORD				ref;
+
+    /* IDirectDraw2 fields */
+    struct _common_directdrawdata	d;
+    LPVOID				private;
+};
+extern HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
+	LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
+);
+extern HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
+	LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
+);
+extern HRESULT WINAPI IDirectDraw2Impl_GetCaps(
+	LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
+) ;
+extern HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
+    LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
+);
+extern HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
+    IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,
+    IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
+);
+extern HRESULT WINAPI IDirectDraw2Impl_CreatePalette(
+    LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
+);
+extern HRESULT WINAPI IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface);
+extern HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
+	LPDIRECTDRAW2 iface,DWORD x,HANDLE h
+);
+extern ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface);
+extern ULONG WINAPI IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface);
+extern HRESULT WINAPI IDirectDraw2Impl_QueryInterface(
+	LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
+);
+extern HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
+	LPDIRECTDRAW2 iface,BOOL *status
+);
+extern HRESULT WINAPI IDirectDraw2Impl_EnumDisplayModes(
+	LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
+);
+extern HRESULT WINAPI IDirectDraw2Impl_GetDisplayMode(
+	LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
+);
+extern HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface);
+extern HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
+    LPDIRECTDRAW2 iface,LPDWORD freq
+);
+extern HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
+    LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
+);
+extern HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
+    LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,
+    LPDDENUMSURFACESCALLBACK ddsfcb
+);
+extern HRESULT WINAPI IDirectDraw2Impl_Compact( LPDIRECTDRAW2 iface );
+extern HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(
+    LPDIRECTDRAW2 iface, LPDIRECTDRAWSURFACE *lplpGDIDDSSurface
+);
+extern HRESULT WINAPI IDirectDraw2Impl_GetScanLine(
+    LPDIRECTDRAW2 iface, LPDWORD lpdwScanLine
+);
+extern HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface, GUID *lpGUID);
+extern HRESULT WINAPI IDirectDraw2Impl_SetDisplayMode(
+    LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,
+    DWORD dwRefreshRate, DWORD dwFlags
+);
+extern HRESULT WINAPI IDirectDraw2Impl_GetAvailableVidMem(
+	LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
+);
+extern HRESULT common_off_screen_CreateSurface(
+	IDirectDraw2Impl* This,IDirectDrawSurfaceImpl* lpdsf
+);
+
+/*
+ * IDirectDraw4 implementation structure
+ */
+struct IDirectDraw4Impl
+{
+    /* IUnknown fields */
+    ICOM_VFIELD(IDirectDraw4);
+    DWORD				ref;
+    /* IDirectDraw4 fields */
+    struct _common_directdrawdata	d;
+    LPVOID				private;
+};
+extern HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(
+	LPDIRECTDRAW4 iface, HDC hdc, LPDIRECTDRAWSURFACE *lpDDS
+);
+extern HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface);
+extern HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface);
+extern HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
+						    LPDDDEVICEIDENTIFIER lpdddi,
+						    DWORD dwFlags
+);
 
 /*****************************************************************************
  * IDirectDrawPalette implementation structure
@@ -33,15 +195,28 @@
 {
     /* IUnknown fields */
     ICOM_VFIELD(IDirectDrawPalette);
-    DWORD                            ref;
+    DWORD		ref;
+
     /* IDirectDrawPalette fields */
-    IDirectDrawImpl* ddraw;
-    Colormap         cm;
-    PALETTEENTRY     palents[256];
-    int              installed;
+    IDirectDrawImpl*		ddraw;	/* direct draw, no referencecount */
+    PALETTEENTRY	palents[256];
+
     /* This is to store the palette in 'screen format' */
-    int              screen_palents[256];
+    int			screen_palents[256];
+    LPVOID		private;
 };
+extern HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(LPDIRECTDRAWPALETTE,DWORD,DWORD,DWORD,LPPALETTEENTRY);
+extern HRESULT WINAPI IDirectDrawPaletteImpl_SetEntries(LPDIRECTDRAWPALETTE,DWORD,DWORD,DWORD,LPPALETTEENTRY);
+extern ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE);
+extern ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE);
+extern HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(LPDIRECTDRAWPALETTE,LPDIRECTDRAW,DWORD,LPPALETTEENTRY);
+extern HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(LPDIRECTDRAWPALETTE,LPDWORD);
+extern HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(LPDIRECTDRAWPALETTE,REFIID,LPVOID *);
+
+extern HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
+    IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,
+    IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
+);
 
 /*****************************************************************************
  * IDirectDrawClipper implementation structure
@@ -57,99 +232,9 @@
 };
 
 /*****************************************************************************
- * IDirectDraw implementation structure
- */
-struct _common_directdrawdata
-{
-    DDPIXELFORMAT directdraw_pixelformat;
-    DDPIXELFORMAT screen_pixelformat;
-    int           pixmap_depth;
-    void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
-    void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
-    DWORD         height,width;	/* SetDisplayMode */
-    HWND          mainWindow;   /* SetCooperativeLevel */
-
-    /* This is for Wine's fake mainWindow.
-       We need it also in DGA mode to make some games (for example Monkey Island III work) */
-    ATOM          winclass;
-    HWND          window;
-    Window        drawable;
-    PAINTSTRUCT   ps;
-    int           paintable;
-};
-
-struct _dga_directdrawdata
-{
-    DWORD        fb_width,fb_height,fb_memsize;
-    void*        fb_addr;
-    unsigned int vpmask;
-#ifdef HAVE_LIBXXF86DGA2
-    int version;
-    XDGADevice *dev;
-    XDGAMode *modes;
-    int num_modes;
-#endif /* define(HAVE_LIBXXF86DGA2) */
-};
-
-struct _xlib_directdrawdata
-{
-#ifdef HAVE_LIBXXSHM
-    int xshm_active, xshm_compl;
-#endif /* defined(HAVE_LIBXXSHM) */
-    
-    /* are these needed for anything? (draw_surf is the active surface)
-    IDirectDrawSurfaceImpl* surfs;
-    DWORD		num_surfs, alloc_surfs, draw_surf; */
-};
-
-struct IDirectDrawImpl
-{
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirectDraw);
-    DWORD                     ref;
-    /* IDirectDraw fields */
-    struct _common_directdrawdata   d;
-    union {
-        struct _xlib_directdrawdata xlib;
-        struct _dga_directdrawdata  dga;
-    } e;
-};
-
-/*****************************************************************************
- * IDirectDraw2 implementation structure
- */
-struct IDirectDraw2Impl
-{
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirectDraw2);
-    DWORD                      ref;
-    /* IDirectDraw2 fields */
-    struct _common_directdrawdata   d;
-    union {
-        struct _xlib_directdrawdata xlib;
-        struct _dga_directdrawdata  dga;
-    } e;
-};
-
-/*****************************************************************************
- * IDirectDraw4 implementation structure
- */
-struct IDirectDraw4Impl
-{
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirectDraw4);
-    DWORD                      ref;
-    /* IDirectDraw4 fields */
-    struct _common_directdrawdata   d;
-    union {
-        struct _xlib_directdrawdata xlib;
-        struct _dga_directdrawdata  dga;
-    } e;
-};
-
-/*****************************************************************************
  * IDirectDrawSurface implementation structure
  */
+struct IDirect3DTexture2Impl;
 struct _common_directdrawsurface
 {
     IDirectDrawPaletteImpl*     palette;
@@ -160,45 +245,27 @@
     DDSURFACEDESC               surface_desc;
 
     /* For Get / Release DC methods */
-    HBITMAP DIBsection;
-    void *bitmap_data;
-    HDC hdc;
-    HGDIOBJ holdbitmap;
+    HBITMAP			DIBsection;
+    void			*bitmap_data;
+    HDC				hdc;
+    HGDIOBJ			holdbitmap;
+    LPDIRECTDRAWCLIPPER		lpClipper;
     
     /* Callback for loaded textures */
-    IDirect3DTexture2Impl*      texture;
-    HRESULT WINAPI            (*SetColorKey_cb)(IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ;
-
-    /* Storage for attached device (void * as it can be either a Device or a Device2) */
-    void                       *d3d_device;
-
-    LPDIRECTDRAWCLIPPER		lpClipper;
+    struct IDirect3DTexture2Impl*	texture;
+    HRESULT WINAPI		(*SetColorKey_cb)(struct IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ; 
 };
-
-struct _dga_directdrawsurface
-{
-    DWORD		fb_height;
-};
-
-struct _xlib_directdrawsurface
-{
-    XImage		*image;
-#ifdef HAVE_LIBXXSHM
-    XShmSegmentInfo	shminfo;
-#endif
-};
+extern IDirectDrawSurface4Impl* _common_find_flipto(IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto);
 
 struct IDirectDrawSurfaceImpl
 {
     /* IUnknown fields */
     ICOM_VFIELD(IDirectDrawSurface);
     DWORD                            ref;
+
     /* IDirectDrawSurface fields */
     struct _common_directdrawsurface	s;
-    union {
-	struct _dga_directdrawsurface	dga;
-	struct _xlib_directdrawsurface	xlib;
-    } t;
+    LPVOID private;
 };
 
 /*****************************************************************************
@@ -211,10 +278,7 @@
     DWORD                             ref;
     /* IDirectDrawSurface2 fields */
     struct _common_directdrawsurface	s;
-    union {
-	struct _dga_directdrawsurface	dga;
-	struct _xlib_directdrawsurface	xlib;
-    } t;
+    LPVOID private;
 };
 
 /*****************************************************************************
@@ -227,10 +291,7 @@
     DWORD                             ref;
     /* IDirectDrawSurface3 fields */
     struct _common_directdrawsurface	s;
-    union {
-	struct _dga_directdrawsurface	dga;
-	struct _xlib_directdrawsurface	xlib;
-    } t;
+    LPVOID private;
 };
 
 /*****************************************************************************
@@ -244,28 +305,104 @@
 
     /* IDirectDrawSurface4 fields */
     struct _common_directdrawsurface	s;
-    union {
-	struct _dga_directdrawsurface	dga;
-	struct _xlib_directdrawsurface	xlib;
-    } t;
+    LPVOID private;
 } ;
 
 struct _surface_chain {
 	IDirectDrawSurface4Impl	**surfaces;
 	int			nrofsurfaces;
 };
+extern HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,IDirectDrawSurfaceImpl* lpdsf);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_Lock(LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_Unlock( LPDIRECTDRAWSURFACE4 iface,LPVOID surface);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_Blt(LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd);
+extern ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE4 iface,LPRECT lpRect);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags,LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags,LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpfnCallback);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER* lplpDDClipper);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags,LPDDCOLORKEY lpDDColorKey);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE* lplpDDPalette);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(LPDIRECTDRAWSURFACE4 iface,LONG lX,LONG lY);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(LPDIRECTDRAWSURFACE4 iface,LPRECT lpSrcRect,LPDIRECTDRAWSURFACE4 lpDDDestSurface,LPRECT lpDestRect,DWORD dwFlags,LPDDOVERLAYFX lpDDOverlayFx);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags,LPDIRECTDRAWSURFACE4 lpDDSReference);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(LPDIRECTDRAWSURFACE4 iface,LPVOID* lplpDD);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC lpDDSD,DWORD dwFlags);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,REFGUID guidTag,LPVOID lpData,DWORD cbSize,DWORD dwFlags);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,REFGUID guidTag,LPVOID lpBuffer,LPDWORD lpcbBufferSize);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,REFGUID guidTag);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,LPDWORD lpValue);
+extern HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface);
 
-/*****************************************************************************
- * IDirectDrawColorControl implementation structure
+extern void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This);
+
+/* Get DDSCAPS of surface (shortcutmacro) */
+#define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
+/* Get the number of bytes per pixel for a given surface */
+#define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8))
+#define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
+
+extern int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat,DDPIXELFORMAT *screen_pixelformat, int *pix_depth);
+
+typedef struct {
+    unsigned short	bpp,depth;
+    unsigned int	rmask,gmask,bmask;
+} ConvertMode;
+
+typedef struct {
+    void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
+    void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
+} ConvertFuncs;
+
+typedef struct {
+    ConvertMode screen, dest;
+    ConvertFuncs funcs;
+} Convert;
+
+extern Convert ModeEmulations[5];
+extern int _common_depth_to_pixelformat(
+	DWORD depth,DDPIXELFORMAT *pixelformat,
+	DDPIXELFORMAT *screen_pixelformat, int *pix_depth
+);
+
+extern HRESULT create_direct3d(LPVOID *obj,IDirectDraw2Impl*);
+extern HRESULT create_direct3d2(LPVOID *obj,IDirectDraw2Impl*);
+
+/******************************************************************************
+ * Debugging / Flags output functions
  */
-struct IDirectDrawColorControlImpl
-{
-    /* IUnknown fields */
-    ICOM_VFIELD(IDirectDrawColorControl);
-    DWORD                                 ref;
-    /* IDirectDrawColorControl fields */
-    /* none */
-};
-
-
-#endif /* __GRAPHICS_WINE_DDRAW_PRIVATE_H */
+extern void _dump_DDBLTFX(DWORD flagmask);
+extern void _dump_DDBLTFAST(DWORD flagmask);
+extern void _dump_DDBLT(DWORD flagmask);
+extern void _dump_DDSCAPS(void *in);
+extern void _dump_pixelformat_flag(DWORD flagmask);
+extern void _dump_paletteformat(DWORD dwFlags);
+extern void _dump_pixelformat(void *in);
+extern void _dump_colorkeyflag(DWORD ck);
+extern void _dump_surface_desc(DDSURFACEDESC *lpddsd);
+extern void _dump_cooperativelevel(DWORD cooplevel);
+extern void _dump_surface_desc(DDSURFACEDESC *lpddsd);
+extern void _dump_DDCOLORKEY(void *in);
+#endif /* __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H */
diff --git a/dlls/ddraw/dga.c b/dlls/ddraw/dga.c
new file mode 100644
index 0000000..eb762d3
--- /dev/null
+++ b/dlls/ddraw/dga.c
@@ -0,0 +1,273 @@
+/*		DirectDraw using DGA
+ *
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
+ */
+/* XF86DGA:
+ * When DirectVideo mode is enabled you can no longer use 'normal' X 
+ * applications nor can you switch to a virtual console. Also, enabling
+ * only works, if you have switched to the screen where the application
+ * is running.
+ * Some ways to debug this stuff are:
+ * - A terminal connected to the serial port. Can be bought used for cheap.
+ *   (This is the method I am using.)
+ * - Another machine connected over some kind of network.
+ */
+
+#include "config.h"
+#include "winerror.h"
+
+#include <unistd.h>
+#include <assert.h>
+#ifdef HAVE_SYS_SIGNAL_H
+# include <sys/signal.h>
+#endif
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "gdi.h"
+#include "heap.h"
+#include "dc.h"
+#include "win.h"
+#include "wine/exception.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debugtools.h"
+#include "spy.h"
+#include "message.h"
+#include "options.h"
+#include "monitor.h"
+
+#include "dga_private.h"
+
+#define RESTORE__SIGNALS
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+#ifdef HAVE_LIBXXF86VM
+XF86VidModeModeInfo *orig_mode = NULL;
+#endif
+
+static inline BOOL get_option( const char *name, BOOL def ) {
+    return PROFILE_GetWineIniBool( "x11drv", name, def );
+}
+
+static BYTE
+DDRAW_DGA_Available(void)
+{
+    int fd, evbase, evret, majver, minver;
+    static BYTE return_value = 0xFF;
+
+    /* This prevents from probing X times for DGA */
+    if (return_value != 0xFF)
+	return return_value;
+
+    if (!get_option( "UseDGA", 1 )) {
+	TRACE("UseDGA disabled.\n");
+	return_value = 0;
+	return 0;
+    }
+
+    /* First, query the extenstion and its version */
+    if (!TSXF86DGAQueryExtension(display,&evbase,&evret)) {
+	TRACE("DGA extension not detected.\n");
+	return_value = 0;
+	return 0;
+    }
+
+    if (!TSXF86DGAQueryVersion(display,&majver,&minver)) {
+	TRACE("DGA version not detected.\n");
+	return_value = 0;
+	return 0;
+    }
+
+#ifdef HAVE_LIBXXF86DGA2
+    if (majver >= 2) {
+	/* We have DGA 2.0 available ! */
+	if (TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
+	    TSXDGACloseFramebuffer(display, DefaultScreen(display));
+	    return_value = 2;
+	} else
+	    return_value = 0;
+	return return_value;
+    }
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+
+    /* You don't have to be root to use DGA extensions. Simply having access
+     * to /dev/mem will do the trick
+     * This can be achieved by adding the user to the "kmem" group on
+     * Debian 2.x systems, don't know about 
+     * others. --stephenc
+     */
+    if ((fd = open("/dev/mem", O_RDWR)) != -1)
+	close(fd);
+
+    if (fd != -1)
+	return_value = 1;
+    else {
+	TRACE("You have no access to /dev/mem\n");
+	return_value = 0;
+    }
+    return return_value;
+}
+
+HRESULT 
+DGA_Create( LPDIRECTDRAW *lplpDD ) {
+    IDirectDrawImpl*		ddraw;
+    dga_dd_private*	dgpriv;
+    int  memsize,banksize,major,minor,flags;
+    char *addr;
+    int  depth;
+    int  dga_version;
+    int  width, height;
+      
+    /* Get DGA availability / version */
+    dga_version = DDRAW_DGA_Available();
+    if (dga_version == 0)
+	return DDERR_GENERIC;
+
+    /* If we were just testing ... return OK */
+    if (lplpDD == NULL)
+	return DD_OK;
+
+    ddraw = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
+    *lplpDD = (LPDIRECTDRAW)ddraw;
+    ddraw->ref = 1;
+    ICOM_VTBL(ddraw) = &dga_ddvt;
+    
+    ddraw->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(dga_dd_private));
+
+    dgpriv = (dga_dd_private*)ddraw->private;
+#ifdef HAVE_LIBXXF86DGA2
+    if (dga_version == 1) {
+	dgpriv->version = 1;
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+	TSXF86DGAQueryVersion(display,&major,&minor);
+	TRACE("XF86DGA is version %d.%d\n",major,minor);
+
+	TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
+	if (!(flags & XF86DGADirectPresent))
+	    MESSAGE("direct video is NOT PRESENT.\n");
+	TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
+	dgpriv->fb_width = width;
+	TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
+	TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
+	dgpriv->fb_height = height;
+	TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
+	    addr,width,banksize,memsize
+	);
+	TRACE("viewport height: %d\n",height);
+	/* Get the screen dimensions as seen by Wine.
+	 * In that case, it may be better to ignore the -desktop mode and
+	 * return the real screen size => print a warning
+	 */
+	ddraw->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
+	ddraw->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
+	if ((ddraw->d.height != height) || (ddraw->d.width  != width))
+		WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
+	dgpriv->fb_addr		= addr;
+	dgpriv->fb_memsize	= memsize;
+	dgpriv->vpmask		= 0;
+
+	/* just assume the default depth is the DGA depth too */
+	depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
+
+	_common_depth_to_pixelformat(depth, &(ddraw->d.directdraw_pixelformat), &(ddraw->d.screen_pixelformat), NULL);
+
+#ifdef RESTORE_SIGNALS
+	SIGNAL_Init();
+#endif
+#ifdef HAVE_LIBXXF86DGA2
+    } else {
+	XDGAMode *modes;
+	int i, num_modes;
+	int mode_to_use = 0;
+
+	dgpriv->version = 2;
+
+	TSXDGAQueryVersion(display,&major,&minor);
+	TRACE("XDGA is version %d.%d\n",major,minor);
+
+	TRACE("Opening the frame buffer.\n");
+	if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
+	    ERR("Error opening the frame buffer !!!\n");
+	    return DDERR_GENERIC;
+	}
+
+	/* List all available modes */
+	modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
+	dgpriv->modes		= modes;
+	dgpriv->num_modes	= num_modes;
+
+	    TRACE("Available modes :\n");
+	    for (i = 0; i < num_modes; i++) {
+		if (TRACE_ON(ddraw)) {
+		    DPRINTF("   %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
+			modes[i].num,
+			modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
+			modes[i].viewportWidth, modes[i].viewportHeight,
+			modes[i].depth
+		    );
+#define XX(x) if (modes[i].flags & x) DPRINTF(" "#x" ");
+		    XX(XDGAConcurrentAccess);
+		    XX(XDGASolidFillRect);
+		    XX(XDGABlitRect);
+		    XX(XDGABlitTransRect);
+		    XX(XDGAPixmap);
+#undef XX
+		    DPRINTF("\n");
+		}
+		if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
+		    (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
+		    (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)
+		) {
+		    mode_to_use = modes[i].num;
+		}
+	    }
+	}
+	if (mode_to_use == 0) {
+	    ERR("Could not find mode !\n");
+	    mode_to_use = 1;
+	} else {
+	    DPRINTF("Using mode number %d\n", mode_to_use);
+	}
+
+	/* Initialize the frame buffer */
+	_DGA_Initialize_FrameBuffer(*ilplpDD, mode_to_use);
+	/* Set the input handling for relative mouse movements */
+	X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
+    }
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+    return DD_OK;
+}
+
+/* Where do these GUIDs come from?  mkuuid.
+ * They exist solely to distinguish between the targets Wine support,
+ * and should be different than any other GUIDs in existence.
+ */
+static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
+    0xe2dcb020,
+    0xdc60,
+    0x11d1,
+    {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
+};
+
+ddraw_driver dga_driver = {
+    &DGA_DirectDraw_GUID,
+    "display",
+    "WINE XF86DGA DirectDraw Driver",
+    100,
+    DGA_Create
+}; 
+
+#ifdef __GNUC__
+static void DGA_register(void) __attribute__((constructor));
+#else /* defined(__GNUC__) */
+static void __asm__dummy_dll_init(void) {
+    asm("\t.section .init ,\"ax\"\n"
+	        "\tcall DGA_register\n"
+		    "\t.previous\n");
+}
+#endif /* defined(__GNUC__) */
+static void DGA_register(void) { ddraw_register_driver(&dga_driver); }
diff --git a/dlls/ddraw/dga_private.h b/dlls/ddraw/dga_private.h
new file mode 100644
index 0000000..30c9a31
--- /dev/null
+++ b/dlls/ddraw/dga_private.h
@@ -0,0 +1,40 @@
+#ifndef __WINE_DDRAW_DGA_PRIVATE_H
+#define __WINE_DDRAW_DGA_PRIVATE_H
+
+#include "ddraw_private.h"
+#include "x11_private.h"
+
+#include "ts_xf86dga.h"
+#ifdef HAVE_LIBXXF86DGA2
+# include "ts_xf86dga2.h"
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+
+#ifdef HAVE_LIBXXF86VM
+# include "ts_xf86vmode.h"
+extern XF86VidModeModeInfo *orig_mode;
+#endif /* defined(HAVE_LIBXXF86VM) */
+
+extern ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt;
+#ifdef HAVE_LIBXXF86DGA2
+extern ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt;
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+
+extern ICOM_VTABLE(IDirectDraw)		dga_ddvt;
+extern ICOM_VTABLE(IDirectDrawPalette)	dga_ddpalvt;
+
+typedef struct dga_dd_private {
+    DWORD	fb_height;		/* height of the viewport */
+    DWORD	fb_width;		/* width of the viewport */
+    caddr_t	fb_addr;		/* start address of the framebuffer */
+    DWORD	fb_memsize;		/* total memory on the card */
+    DWORD	vpmask;			/* viewports in use flag bitmap */
+    DWORD	version;		/* DGA version */
+} dga_dd_private;
+
+typedef x11_dp_private dga_dp_private;	/* reuse X11 palette stuff */
+
+typedef struct dga_ds_private {
+    DWORD	fb_height;
+} dga_ds_private;
+
+#endif /* __WINE_DDRAW_DGA_PRIVATE_H */
diff --git a/dlls/ddraw/direct3d/main.c b/dlls/ddraw/direct3d/main.c
new file mode 100644
index 0000000..7086ed0
--- /dev/null
+++ b/dlls/ddraw/direct3d/main.c
@@ -0,0 +1,280 @@
+#include "config.h"
+
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "winerror.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "message.h"
+#include "options.h"
+#include "monitor.h"
+#include "debugtools.h"
+
+#include "d3d_private.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+static ICOM_VTABLE(IDirect3D) d3dvt;
+static ICOM_VTABLE(IDirect3D2) d3d2vt;
+
+/*******************************************************************************
+ *				IDirect3D
+ */
+HRESULT WINAPI IDirect3DImpl_QueryInterface(
+    LPDIRECT3D iface,REFIID refiid,LPVOID *obj
+) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    /* FIXME: Not sure if this is correct */
+
+    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
+    if (( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
+	( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
+	( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
+    ) {
+	*obj = This->ddraw;
+	IDirect3D_AddRef(iface);
+	TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);
+	return S_OK;
+    }
+    if (( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
+	( IsEqualGUID( &IID_IUnknown,  refiid ) ) ) {
+	*obj = This;
+	IDirect3D_AddRef(iface);
+	TRACE("  Creating IDirect3D interface (%p)\n", *obj);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
+	IDirect3D2Impl*  d3d;
+
+	d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
+	d3d->ref = 1;
+	d3d->ddraw = This->ddraw;
+	IDirect3D_AddRef(iface);
+	ICOM_VTBL(d3d) = &d3d2vt;
+	*obj = d3d;
+	TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
+	return S_OK;
+    }
+    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
+    return OLE_E_ENUM_NOMORE;
+}
+
+ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
+
+    return ++(This->ref);
+}
+
+ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
+{
+    ICOM_THIS(IDirect3DImpl,iface);
+    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+
+    if (!--(This->ref)) {
+	IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
+	HeapFree(GetProcessHeap(),0,This);
+	return S_OK;
+    }
+    return This->ref;
+}
+
+HRESULT WINAPI IDirect3DImpl_Initialize(LPDIRECT3D iface,REFIID refiid) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    /* FIXME: Not sure if this is correct */
+    FIXME("(%p)->(%s):stub.\n",This,debugstr_guid(refiid));
+    return DDERR_ALREADYINITIALIZED;
+}
+
+HRESULT WINAPI IDirect3DImpl_EnumDevices(
+    LPDIRECT3D iface, LPD3DENUMDEVICESCALLBACK cb, LPVOID context
+) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3DImpl_CreateLight(
+    LPDIRECT3D iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    FIXME("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
+    return E_FAIL;
+}
+
+HRESULT WINAPI IDirect3DImpl_CreateMaterial(
+    LPDIRECT3D iface, LPDIRECT3DMATERIAL *lpmaterial, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    FIXME("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
+    return E_FAIL;
+}
+
+HRESULT WINAPI IDirect3DImpl_CreateViewport(
+    LPDIRECT3D iface, LPDIRECT3DVIEWPORT *lpviewport, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    FIXME("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
+
+    return E_FAIL;
+}
+
+HRESULT WINAPI IDirect3DImpl_FindDevice(
+    LPDIRECT3D iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
+    LPD3DFINDDEVICERESULT lpfinddevrst)
+{
+    ICOM_THIS(IDirect3DImpl,iface);
+    FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
+    return DD_OK;
+}
+
+/* This is for checking the correctness of the prototypes/functions.
+ * Do not remove.
+ */
+static WINE_UNUSED ICOM_VTABLE(IDirect3D) d3dvt = {
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IDirect3DImpl_QueryInterface,
+    IDirect3DImpl_AddRef,
+    IDirect3DImpl_Release,
+    IDirect3DImpl_Initialize,
+    IDirect3DImpl_EnumDevices,
+    IDirect3DImpl_CreateLight,
+    IDirect3DImpl_CreateMaterial,
+    IDirect3DImpl_CreateViewport,
+    IDirect3DImpl_FindDevice
+};
+
+/*******************************************************************************
+ *				IDirect3D2
+ */
+HRESULT WINAPI IDirect3D2Impl_QueryInterface(
+    LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {  
+    ICOM_THIS(IDirect3D2Impl,iface);
+
+    /* FIXME: Not sure if this is correct */
+
+    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
+    if ( ( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
+	 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
+	 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
+	*obj = This->ddraw;
+	IDirect3D2_AddRef(iface);
+
+	TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);
+	
+	return S_OK;
+    }
+    if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
+	 ( IsEqualGUID( &IID_IUnknown,   refiid ) ) ) {
+	*obj = This;
+	IDirect3D2_AddRef(iface);
+
+	TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
+
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
+	IDirect3DImpl*  d3d;
+
+	d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
+	d3d->ref = 1;
+	d3d->ddraw = This->ddraw;
+	IDirect3D2_AddRef(iface);
+	ICOM_VTBL(d3d) = &d3dvt;
+	*obj = d3d;
+	TRACE("  Creating IDirect3D interface (%p)\n", *obj);
+	return S_OK;
+    }
+    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
+    return OLE_E_ENUM_NOMORE;
+}
+
+ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
+    ICOM_THIS(IDirect3D2Impl,iface);
+    TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
+
+    return ++(This->ref);
+}
+
+ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
+    ICOM_THIS(IDirect3D2Impl,iface);
+    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+
+    if (!--(This->ref)) {
+	IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
+	HeapFree(GetProcessHeap(),0,This);
+	return S_OK;
+    }
+    return This->ref;
+}
+
+HRESULT WINAPI IDirect3D2Impl_EnumDevices(
+    LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
+) {
+    ICOM_THIS(IDirect3D2Impl,iface);
+    FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3D2Impl_CreateLight(
+    LPDIRECT3D2 iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3D2Impl,iface);
+    FIXME("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
+    return E_FAIL;
+}
+
+HRESULT WINAPI IDirect3D2Impl_CreateMaterial(
+    LPDIRECT3D2 iface, LPDIRECT3DMATERIAL2 *lpmaterial, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3D2Impl,iface);
+    FIXME("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
+    return E_FAIL;
+}
+
+HRESULT WINAPI IDirect3D2Impl_CreateViewport(
+    LPDIRECT3D2 iface, LPDIRECT3DVIEWPORT2 *lpviewport, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3D2Impl,iface);
+    FIXME("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
+    return E_FAIL;
+}
+
+HRESULT WINAPI IDirect3D2Impl_FindDevice(
+    LPDIRECT3D2 iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
+    LPD3DFINDDEVICERESULT lpfinddevrst)
+{
+    ICOM_THIS(IDirect3D2Impl,iface);
+    FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirect3D2Impl_CreateDevice(
+    LPDIRECT3D2 iface, REFCLSID rguid, LPDIRECTDRAWSURFACE surface,
+    LPDIRECT3DDEVICE2 *device)
+{
+    ICOM_THIS(IDirect3D2Impl,iface);
+    FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
+    return DDERR_INVALIDPARAMS;
+}
+
+/* This is for checking the correctness of the prototypes/functions.
+ * Do not remove.
+ */
+static WINE_UNUSED ICOM_VTABLE(IDirect3D2) d3d2vt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IDirect3D2Impl_QueryInterface,
+    IDirect3D2Impl_AddRef,
+    IDirect3D2Impl_Release,
+    IDirect3D2Impl_EnumDevices,
+    IDirect3D2Impl_CreateLight,
+    IDirect3D2Impl_CreateMaterial,
+    IDirect3D2Impl_CreateViewport,
+    IDirect3D2Impl_FindDevice,
+    IDirect3D2Impl_CreateDevice
+};
diff --git a/dlls/ddraw/direct3d/mesa.c b/dlls/ddraw/direct3d/mesa.c
new file mode 100644
index 0000000..8d81e6c
--- /dev/null
+++ b/dlls/ddraw/direct3d/mesa.c
@@ -0,0 +1,317 @@
+#include "config.h"
+
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "winerror.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "message.h"
+#include "options.h"
+#include "monitor.h"
+#include "debugtools.h"
+
+#include "mesa_private.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+/*******************************************************************************
+ *				IDirect3D
+ */
+static HRESULT WINAPI MESA_IDirect3DImpl_QueryInterface(
+    LPDIRECT3D iface,REFIID refiid,LPVOID *obj
+) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    /* FIXME: Not sure if this is correct */
+
+    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
+    if (( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
+	( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
+	( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
+    ) {
+	*obj = This->ddraw;
+	IDirect3D_AddRef(iface);
+	TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);
+	return S_OK;
+    }
+    if (( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
+	( IsEqualGUID( &IID_IUnknown,  refiid ) ) ) {
+	*obj = This;
+	IDirect3D_AddRef(iface);
+	TRACE("  Creating IDirect3D interface (%p)\n", *obj);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
+	IDirect3D2Impl*  d3d;
+
+	d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
+	d3d->ref = 1;
+	d3d->ddraw = This->ddraw;
+	IDirect3D_AddRef(iface);
+	ICOM_VTBL(d3d) = &mesa_d3d2vt;
+	*obj = d3d;
+	TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
+	return S_OK;
+    }
+    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
+    return OLE_E_ENUM_NOMORE;
+}
+
+static ULONG WINAPI MESA_IDirect3DImpl_Release(LPDIRECT3D iface)
+{
+    ICOM_THIS(IDirect3DImpl,iface);
+    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+
+    if (!--(This->ref)) {
+	IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
+	HeapFree(GetProcessHeap(),0,This);
+	return S_OK;
+    }
+    return This->ref;
+}
+
+static HRESULT WINAPI MESA_IDirect3DImpl_EnumDevices(
+    LPDIRECT3D iface, LPD3DENUMDEVICESCALLBACK cb, LPVOID context
+) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
+
+    /* Call functions defined in d3ddevices.c */
+    if (!d3d_OpenGL_dx3(cb, context))
+	return DD_OK;
+
+    return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3DImpl_CreateLight(
+    LPDIRECT3D iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
+
+    /* Call the creation function that is located in d3dlight.c */
+    *lplight = d3dlight_create_dx3(This);
+
+    return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3DImpl_CreateMaterial(
+    LPDIRECT3D iface, LPDIRECT3DMATERIAL *lpmaterial, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
+    /* Call the creation function that is located in d3dviewport.c */
+    *lpmaterial = d3dmaterial_create(This);
+    return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3DImpl_CreateViewport(
+    LPDIRECT3D iface, LPDIRECT3DVIEWPORT *lpviewport, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3DImpl,iface);
+    TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
+
+    /* Call the creation function that is located in d3dviewport.c */
+    *lpviewport = d3dviewport_create(This);
+
+    return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3DImpl_FindDevice(
+    LPDIRECT3D iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
+    LPD3DFINDDEVICERESULT lpfinddevrst)
+{
+    ICOM_THIS(IDirect3DImpl,iface);
+    FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
+
+    return DD_OK;
+}
+
+ICOM_VTABLE(IDirect3D) mesa_d3dvt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    MESA_IDirect3DImpl_QueryInterface,
+    IDirect3DImpl_AddRef,
+    MESA_IDirect3DImpl_Release,
+    IDirect3DImpl_Initialize,
+    MESA_IDirect3DImpl_EnumDevices,
+    MESA_IDirect3DImpl_CreateLight,
+    MESA_IDirect3DImpl_CreateMaterial,
+    MESA_IDirect3DImpl_CreateViewport,
+    MESA_IDirect3DImpl_FindDevice
+};
+
+/*******************************************************************************
+ *				IDirect3D2
+ */
+static HRESULT WINAPI MESA_IDirect3D2Impl_QueryInterface(
+    LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {  
+    ICOM_THIS(IDirect3D2Impl,iface);
+
+    /* FIXME: Not sure if this is correct */
+
+    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
+    if ( ( IsEqualGUID( &IID_IDirectDraw,  refiid ) ) ||
+	 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
+	 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
+	*obj = This->ddraw;
+	IDirect3D2_AddRef(iface);
+
+	TRACE("  Creating IDirectDrawX interface (%p)\n", *obj);
+	
+	return S_OK;
+    }
+    if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
+	 ( IsEqualGUID( &IID_IUnknown,   refiid ) ) ) {
+	*obj = This;
+	IDirect3D2_AddRef(iface);
+
+	TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
+
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
+	IDirect3DImpl*  d3d;
+
+	d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
+	d3d->ref = 1;
+	d3d->ddraw = This->ddraw;
+	IDirect3D2_AddRef(iface);
+	ICOM_VTBL(d3d) = &mesa_d3dvt;
+	*obj = d3d;
+	TRACE("  Creating IDirect3D interface (%p)\n", *obj);
+	return S_OK;
+    }
+    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
+    return OLE_E_ENUM_NOMORE;
+}
+
+static ULONG WINAPI MESA_IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
+    ICOM_THIS(IDirect3D2Impl,iface);
+    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+
+    if (!--(This->ref)) {
+	IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
+	HeapFree(GetProcessHeap(),0,This);
+	return S_OK;
+    }
+    return This->ref;
+}
+
+static HRESULT WINAPI MESA_IDirect3D2Impl_EnumDevices(
+    LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
+) {
+    ICOM_THIS(IDirect3D2Impl,iface);
+    FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
+
+    /* Call functions defined in d3ddevices.c */
+    if (!d3d_OpenGL(cb, context))
+	return DD_OK;
+    return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3D2Impl_CreateLight(
+    LPDIRECT3D2 iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3D2Impl,iface);
+    TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
+
+    /* Call the creation function that is located in d3dlight.c */
+    *lplight = d3dlight_create(This);
+
+    return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3D2Impl_CreateMaterial(
+    LPDIRECT3D2 iface, LPDIRECT3DMATERIAL2 *lpmaterial, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3D2Impl,iface);
+    TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
+
+    /* Call the creation function that is located in d3dviewport.c */
+    *lpmaterial = d3dmaterial2_create(This);
+
+    return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3D2Impl_CreateViewport(
+    LPDIRECT3D2 iface, LPDIRECT3DVIEWPORT2 *lpviewport, IUnknown *lpunk
+) {
+    ICOM_THIS(IDirect3D2Impl,iface);
+    TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
+
+    /* Call the creation function that is located in d3dviewport.c */
+    *lpviewport = d3dviewport2_create(This);
+
+    return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3D2Impl_FindDevice(
+    LPDIRECT3D2 iface, LPD3DFINDDEVICESEARCH lpfinddevsrc,
+    LPD3DFINDDEVICERESULT lpfinddevrst)
+{
+    ICOM_THIS(IDirect3D2Impl,iface);
+    FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
+    return DD_OK;
+}
+
+static HRESULT WINAPI MESA_IDirect3D2Impl_CreateDevice(
+    LPDIRECT3D2 iface, REFCLSID rguid, LPDIRECTDRAWSURFACE surface,
+    LPDIRECT3DDEVICE2 *device)
+{
+    ICOM_THIS(IDirect3D2Impl,iface);
+
+    FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
+
+    if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
+	IDirect3D2_AddRef(iface);
+	return DD_OK;
+    }
+
+    return DDERR_INVALIDPARAMS;
+}
+
+ICOM_VTABLE(IDirect3D2) mesa_d3d2vt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    MESA_IDirect3D2Impl_QueryInterface,
+    IDirect3D2Impl_AddRef,
+    MESA_IDirect3D2Impl_Release,
+    MESA_IDirect3D2Impl_EnumDevices,
+    MESA_IDirect3D2Impl_CreateLight,
+    MESA_IDirect3D2Impl_CreateMaterial,
+    MESA_IDirect3D2Impl_CreateViewport,
+    MESA_IDirect3D2Impl_FindDevice,
+    MESA_IDirect3D2Impl_CreateDevice
+};
+
+HRESULT create_direct3d(LPVOID *obj,IDirectDraw2Impl* ddraw) {
+    IDirect3DImpl* d3d;
+
+    d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
+    d3d->ref = 1;
+    d3d->ddraw = ddraw;
+    d3d->private = NULL; /* unused for now */
+    IDirectDraw_AddRef((LPDIRECTDRAW)ddraw);
+    ICOM_VTBL(d3d) = &mesa_d3dvt;
+    *obj = (LPUNKNOWN)d3d;
+    TRACE("  Created IDirect3D interface (%p)\n", *obj);
+    return S_OK;
+}
+
+HRESULT create_direct3d2(LPVOID *obj,IDirectDraw2Impl* ddraw) {
+    IDirect3D2Impl* d3d;
+
+    d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
+    d3d->ref = 1;
+    d3d->ddraw = ddraw;
+    d3d->private = NULL; /* unused for now */
+    IDirectDraw_AddRef((LPDIRECTDRAW)ddraw);
+    ICOM_VTBL(d3d) = &mesa_d3d2vt;
+    *obj = (LPUNKNOWN)d3d;
+    TRACE("  Creating IDirect3D2 interface (%p)\n", *obj);
+    return S_OK;
+}
diff --git a/dlls/ddraw/dpalette/dga.c b/dlls/ddraw/dpalette/dga.c
new file mode 100644
index 0000000..94a35b6
--- /dev/null
+++ b/dlls/ddraw/dpalette/dga.c
@@ -0,0 +1,76 @@
+/*		DirectDrawPalette XF86DGA implementation
+ *
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
+ */
+
+#include "config.h"
+#include "winerror.h"
+
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "debugtools.h"
+
+#include "dga_private.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+#define DPPRIVATE(x) dga_dp_private *dppriv = ((dga_dp_private*)(x)->private)
+#define DDPRIVATE(x) dga_dd_private *ddpriv = ((dga_dd_private*)(x)->private)
+
+HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
+    LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
+) {
+    ICOM_THIS(IDirectDrawPaletteImpl,iface);
+    DPPRIVATE(This);
+    XColor	xc;
+    Colormap	cm;
+    int		i;
+
+    TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",This,x,start,count,palent);
+    if (!dppriv->cm) /* should not happen */ {
+	FIXME("app tried to set colormap in non-palettized mode\n");
+	return DDERR_GENERIC;
+    }
+    /* FIXME: free colorcells instead of freeing whole map */
+    cm = dppriv->cm;
+    dppriv->cm = TSXCopyColormapAndFree(display,dppriv->cm);
+    TSXFreeColormap(display,cm);
+
+    for (i=0;i<count;i++) {
+	xc.red = palent[i].peRed<<8;
+	xc.blue = palent[i].peBlue<<8;
+	xc.green = palent[i].peGreen<<8;
+	xc.flags = DoRed|DoBlue|DoGreen;
+	xc.pixel = i+start;
+
+	TSXStoreColor(display,dppriv->cm,&xc);
+
+	This->palents[start+i].peRed = palent[i].peRed;
+	This->palents[start+i].peBlue = palent[i].peBlue;
+	This->palents[start+i].peGreen = palent[i].peGreen;
+	This->palents[start+i].peFlags = palent[i].peFlags;
+    }
+#ifdef HAVE_LIBXXF86DGA2
+    if (ddpriv->version == 2) {
+	DDPRIVATE(This->ddraw);
+	TSXDGAInstallColormap(display,DefaultScreen(display),dppriv->cm);
+    } else
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+	TSXF86DGAInstallColormap(display,DefaultScreen(display),dppriv->cm);
+    return DD_OK;
+}
+ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt = 
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	IDirectDrawPaletteImpl_QueryInterface,
+	IDirectDrawPaletteImpl_AddRef,
+	Xlib_IDirectDrawPaletteImpl_Release,
+	IDirectDrawPaletteImpl_GetCaps,
+	IDirectDrawPaletteImpl_GetEntries,
+	IDirectDrawPaletteImpl_Initialize,
+	DGA_IDirectDrawPaletteImpl_SetEntries
+};
diff --git a/dlls/ddraw/dpalette/main.c b/dlls/ddraw/dpalette/main.c
new file mode 100644
index 0000000..c7ce5dc
--- /dev/null
+++ b/dlls/ddraw/dpalette/main.c
@@ -0,0 +1,110 @@
+/*		DirectDraw - IDirectPalette base interface
+ *
+ * Copyright 1997-2000 Marcus Meissner
+ */
+
+#include "config.h"
+#include "winerror.h"
+
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "ddraw_private.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+/******************************************************************************
+ *			IDirectDrawPalette
+ */
+HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
+    LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
+) {
+    ICOM_THIS(IDirectDrawPaletteImpl,iface);
+    int	i;
+
+    TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",This,x,start,count,palent);
+
+    for (i=0;i<count;i++) {
+	palent[i].peRed   = This->palents[start+i].peRed;
+	palent[i].peBlue  = This->palents[start+i].peBlue;
+	palent[i].peGreen = This->palents[start+i].peGreen;
+	palent[i].peFlags = This->palents[start+i].peFlags;
+    }
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawPaletteImpl_SetEntries(
+    LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
+) {
+    ICOM_THIS(IDirectDrawPaletteImpl,iface);
+    int		i;
+
+    TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n", This,x,start,count,palent);
+    for (i=0;i<count;i++) {
+	This->palents[start+i].peRed = palent[i].peRed;
+	This->palents[start+i].peBlue = palent[i].peBlue;
+	This->palents[start+i].peGreen = palent[i].peGreen;
+	This->palents[start+i].peFlags = palent[i].peFlags;
+    }
+
+    /* Now, if we are in 'depth conversion mode', update the screen palette */
+    /* FIXME: we need to update the image or we won't get palette fading. */
+    if (This->ddraw->d.palette_convert != NULL)
+	This->ddraw->d.palette_convert(palent,This->screen_palents,start,count);
+    return DD_OK;
+}
+
+ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
+    ICOM_THIS(IDirectDrawPaletteImpl,iface);
+    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+    if (!--(This->ref)) {
+	    HeapFree(GetProcessHeap(),0,This);
+	    return S_OK;
+    }
+    return This->ref;
+}
+
+ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
+    ICOM_THIS(IDirectDrawPaletteImpl,iface);
+    TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
+    return ++(This->ref);
+}
+
+HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
+    LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
+) {
+    ICOM_THIS(IDirectDrawPaletteImpl,iface);
+    TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
+    return DDERR_ALREADYINITIALIZED;
+}
+
+HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
+     LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
+{
+   ICOM_THIS(IDirectDrawPaletteImpl,iface);
+   FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
+   return DD_OK;
+} 
+
+HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
+    LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj ) 
+{
+    ICOM_THIS(IDirectDrawPaletteImpl,iface);
+    FIXME("(%p)->(%s,%p) stub.\n",This,debugstr_guid(refiid),obj);
+    return S_OK;
+}
+
+ICOM_VTABLE(IDirectDrawPalette) ddraw_ddpalvt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IDirectDrawPaletteImpl_QueryInterface,
+    IDirectDrawPaletteImpl_AddRef,
+    IDirectDrawPaletteImpl_Release,
+    IDirectDrawPaletteImpl_GetCaps,
+    IDirectDrawPaletteImpl_GetEntries,
+    IDirectDrawPaletteImpl_Initialize,
+    IDirectDrawPaletteImpl_SetEntries
+};
diff --git a/dlls/ddraw/dpalette/x11.c b/dlls/ddraw/dpalette/x11.c
new file mode 100644
index 0000000..704518d
--- /dev/null
+++ b/dlls/ddraw/dpalette/x11.c
@@ -0,0 +1,85 @@
+/*		DirectDraw IDirectDrawPalette X11 implementation
+ *
+ * Copyright 1997-2000 Marcus Meissner
+ */
+
+#include "config.h"
+#include "winerror.h"
+
+
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "debugtools.h"
+
+#include "x11_private.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+#define DPPRIVATE(x) x11_dp_private *dppriv = ((x11_dp_private*)x->private)
+
+/******************************************************************************
+ *			IDirectDrawPalette
+ */
+
+HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
+    LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
+) {
+    ICOM_THIS(IDirectDrawPaletteImpl,iface);
+    XColor	xc;
+    int		i;
+    DPPRIVATE(This);
+
+    TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",This,x,start,count,palent);
+    for (i=0;i<count;i++) {
+	xc.red = palent[i].peRed<<8;
+	xc.blue = palent[i].peBlue<<8;
+	xc.green = palent[i].peGreen<<8;
+	xc.flags = DoRed|DoBlue|DoGreen;
+	xc.pixel = start+i;
+
+	if (dppriv->cm)
+	    TSXStoreColor(display,dppriv->cm,&xc);
+
+	This->palents[start+i].peRed = palent[i].peRed;
+	This->palents[start+i].peBlue = palent[i].peBlue;
+	This->palents[start+i].peGreen = palent[i].peGreen;
+	This->palents[start+i].peFlags = palent[i].peFlags;
+    }
+
+    /* Now, if we are in 'depth conversion mode', update the screen palette */
+    /* FIXME: we need to update the image or we won't get palette fading. */
+    if (This->ddraw->d.palette_convert != NULL) {
+	This->ddraw->d.palette_convert(palent,This->screen_palents,start,count);
+    }
+    return DD_OK;
+}
+
+ULONG WINAPI Xlib_IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
+    ICOM_THIS(IDirectDrawPaletteImpl,iface);
+    DPPRIVATE(This);
+    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+    if (!--(This->ref)) {
+	if (dppriv->cm) {
+	    TSXFreeColormap(display,dppriv->cm);
+	    dppriv->cm = 0;
+	}
+	HeapFree(GetProcessHeap(),0,This);
+	return S_OK;
+    }
+    return This->ref;
+}
+
+ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IDirectDrawPaletteImpl_QueryInterface,
+    IDirectDrawPaletteImpl_AddRef,
+    Xlib_IDirectDrawPaletteImpl_Release,
+    IDirectDrawPaletteImpl_GetCaps,
+    IDirectDrawPaletteImpl_GetEntries,
+    IDirectDrawPaletteImpl_Initialize,
+    Xlib_IDirectDrawPaletteImpl_SetEntries
+};
diff --git a/dlls/ddraw/dsurface/dga.c b/dlls/ddraw/dsurface/dga.c
new file mode 100644
index 0000000..2222f82
--- /dev/null
+++ b/dlls/ddraw/dsurface/dga.c
@@ -0,0 +1,270 @@
+/*		DirectDrawSurface XF86DGA implementation
+ *
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
+ */
+#include "config.h"
+#include "winerror.h"
+
+#include <unistd.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "debugtools.h"
+#include "dga_private.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+#define DDPRIVATE(x) dga_dd_private *ddpriv = ((dga_dd_private*)(x)->private)
+#define DPPRIVATE(x) dga_dp_private *dppriv = ((dga_dp_private*)(x)->private)
+#define DSPRIVATE(x) dga_ds_private *dspriv = ((dga_ds_private*)(x)->private)
+
+/******************************************************************************
+ *		IDirectDrawSurface methods
+ *
+ * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
+ * DDS and DDS2 use those functions. (Function calls did not change (except
+ * using different DirectDrawSurfaceX version), just added flags and functions)
+ */
+
+HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
+    LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    DSPRIVATE(This);
+    dga_ds_private	*fspriv;
+    IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
+    DWORD		xheight;
+    LPBYTE		surf;
+
+    TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
+    iflipto = _common_find_flipto(This,iflipto);
+
+    /* and flip! */
+    fspriv = (dga_ds_private*)iflipto->private;
+    TSXF86DGASetViewPort(display,DefaultScreen(display),0,fspriv->fb_height);
+    if (iflipto->s.palette) {
+	DPPRIVATE(iflipto);
+	
+	if (dppriv->cm)
+	    TSXF86DGAInstallColormap(display,DefaultScreen(display),dppriv->cm);
+    }
+    while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
+	/* EMPTY */
+    }
+    /* We need to switch the lowlevel surfaces, for DGA this is: */
+
+    /* The height within the framebuffer */
+    xheight		= dspriv->fb_height;
+    dspriv->fb_height	= fspriv->fb_height;
+    fspriv->fb_height	= xheight;
+
+    /* And the assciated surface pointer */
+    surf				= This->s.surface_desc.u1.lpSurface;
+    This->s.surface_desc.u1.lpSurface	= iflipto->s.surface_desc.u1.lpSurface;
+    iflipto->s.surface_desc.u1.lpSurface= surf;
+    return DD_OK;
+}
+
+#ifdef HAVE_LIBXXF86DGA2
+HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
+    LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
+    DWORD	xheight;
+    dga_ds_private	*fspriv;
+    LPBYTE	surf;
+
+    TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
+    iflipto = _common_find_flipto(This,iflipto);
+
+    /* and flip! */
+    fspriv = (dga_ds_private*)iflipto->private;
+    TSXDGASetViewport(display,DefaultScreen(display),0,fspriv->fb_height, XDGAFlipRetrace);
+    TSXDGASync(display,DefaultScreen(display));
+    TSXFlush(display);
+    if (iflipto->s.palette) {
+	DPPRIVATE(iflipto->s.palette);
+	if (dppriv->cm)
+	    TSXDGAInstallColormap(display,DefaultScreen(display),dppriv->cm);
+    }
+
+    /* We need to switch the lowlevel surfaces, for DGA this is: */
+    /* The height within the framebuffer */
+    xheight		= dspriv->fb_height;
+    dspriv->fb_height	= fspriv->fb_height;
+    fspriv->fb_height	= xheight;
+
+    /* And the assciated surface pointer */
+    surf	                         = This->s.surface_desc.u1.lpSurface;
+    This->s.surface_desc.u1.lpSurface    = iflipto->s.surface_desc.u1.lpSurface;
+    iflipto->s.surface_desc.u1.lpSurface = surf;
+
+    return DD_OK;
+}
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+
+HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
+    LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
+
+    TRACE("(%p)->(%p)\n",This,ipal);
+
+    /* According to spec, we are only supposed to 
+     * AddRef if this is not the same palette.
+     */
+    if( This->s.palette != ipal ) {
+	dga_dp_private	*fppriv;
+	if( ipal != NULL )
+	    IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
+	if( This->s.palette != NULL )
+	    IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
+	This->s.palette = ipal;
+	fppriv = (dga_dp_private*)This->s.palette->private;
+#ifdef HAVE_LIBXXF86DGA2
+	if (ddpriv->version == 2)
+	    TSXDGAInstallColormap(display,DefaultScreen(display),fppriv->cm);
+	else
+#endif /* defined(HAVE_LIBXXF86DGA2) */
+	    TSXF86DGAInstallColormap(display,DefaultScreen(display),fppriv->cm);
+    }
+    return DD_OK;
+}
+
+ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    DDPRIVATE(This->s.ddraw);
+    DSPRIVATE(This);
+
+    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
+
+    if (--(This->ref))
+    	return This->ref;
+
+    IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
+    /* clear out of surface list */
+    if (ddpriv->fb_height == -1)
+	HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
+    else
+	ddpriv->vpmask &= ~(1<<(dspriv->fb_height/ddpriv->fb_height));
+
+    /* Free the DIBSection (if any) */
+    if (This->s.hdc != 0) {
+	SelectObject(This->s.hdc, This->s.holdbitmap);
+	DeleteDC(This->s.hdc);
+	DeleteObject(This->s.DIBsection);
+    }
+    /* Free the clipper if attached to this surface */
+    if( This->s.lpClipper )
+	IDirectDrawClipper_Release(This->s.lpClipper);
+    HeapFree(GetProcessHeap(),0,This);
+    return S_OK;
+}
+
+ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IDirectDrawSurface4Impl_QueryInterface,
+    IDirectDrawSurface4Impl_AddRef,
+    DGA_IDirectDrawSurface4Impl_Release,
+    IDirectDrawSurface4Impl_AddAttachedSurface,
+    IDirectDrawSurface4Impl_AddOverlayDirtyRect,
+    IDirectDrawSurface4Impl_Blt,
+    IDirectDrawSurface4Impl_BltBatch,
+    IDirectDrawSurface4Impl_BltFast,
+    IDirectDrawSurface4Impl_DeleteAttachedSurface,
+    IDirectDrawSurface4Impl_EnumAttachedSurfaces,
+    IDirectDrawSurface4Impl_EnumOverlayZOrders,
+    DGA_IDirectDrawSurface4Impl_Flip,
+    IDirectDrawSurface4Impl_GetAttachedSurface,
+    IDirectDrawSurface4Impl_GetBltStatus,
+    IDirectDrawSurface4Impl_GetCaps,
+    IDirectDrawSurface4Impl_GetClipper,
+    IDirectDrawSurface4Impl_GetColorKey,
+    IDirectDrawSurface4Impl_GetDC,
+    IDirectDrawSurface4Impl_GetFlipStatus,
+    IDirectDrawSurface4Impl_GetOverlayPosition,
+    IDirectDrawSurface4Impl_GetPalette,
+    IDirectDrawSurface4Impl_GetPixelFormat,
+    IDirectDrawSurface4Impl_GetSurfaceDesc,
+    IDirectDrawSurface4Impl_Initialize,
+    IDirectDrawSurface4Impl_IsLost,
+    IDirectDrawSurface4Impl_Lock,
+    IDirectDrawSurface4Impl_ReleaseDC,
+    IDirectDrawSurface4Impl_Restore,
+    IDirectDrawSurface4Impl_SetClipper,
+    IDirectDrawSurface4Impl_SetColorKey,
+    IDirectDrawSurface4Impl_SetOverlayPosition,
+    DGA_IDirectDrawSurface4Impl_SetPalette,
+    IDirectDrawSurface4Impl_Unlock,
+    IDirectDrawSurface4Impl_UpdateOverlay,
+    IDirectDrawSurface4Impl_UpdateOverlayDisplay,
+    IDirectDrawSurface4Impl_UpdateOverlayZOrder,
+    IDirectDrawSurface4Impl_GetDDInterface,
+    IDirectDrawSurface4Impl_PageLock,
+    IDirectDrawSurface4Impl_PageUnlock,
+    IDirectDrawSurface4Impl_SetSurfaceDesc,
+    IDirectDrawSurface4Impl_SetPrivateData,
+    IDirectDrawSurface4Impl_GetPrivateData,
+    IDirectDrawSurface4Impl_FreePrivateData,
+    IDirectDrawSurface4Impl_GetUniquenessValue,
+    IDirectDrawSurface4Impl_ChangeUniquenessValue
+};
+
+#ifdef HAVE_LIBXXF86DGA2
+ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IDirectDrawSurface4Impl_QueryInterface,
+    IDirectDrawSurface4Impl_AddRef,
+    DGA_IDirectDrawSurface4Impl_Release,
+    IDirectDrawSurface4Impl_AddAttachedSurface,
+    IDirectDrawSurface4Impl_AddOverlayDirtyRect,
+    IDirectDrawSurface4Impl_Blt,
+    IDirectDrawSurface4Impl_BltBatch,
+    IDirectDrawSurface4Impl_BltFast,
+    IDirectDrawSurface4Impl_DeleteAttachedSurface,
+    IDirectDrawSurface4Impl_EnumAttachedSurfaces,
+    IDirectDrawSurface4Impl_EnumOverlayZOrders,
+    DGA2_IDirectDrawSurface4Impl_Flip,
+    IDirectDrawSurface4Impl_GetAttachedSurface,
+    IDirectDrawSurface4Impl_GetBltStatus,
+    IDirectDrawSurface4Impl_GetCaps,
+    IDirectDrawSurface4Impl_GetClipper,
+    IDirectDrawSurface4Impl_GetColorKey,
+    IDirectDrawSurface4Impl_GetDC,
+    IDirectDrawSurface4Impl_GetFlipStatus,
+    IDirectDrawSurface4Impl_GetOverlayPosition,
+    IDirectDrawSurface4Impl_GetPalette,
+    IDirectDrawSurface4Impl_GetPixelFormat,
+    IDirectDrawSurface4Impl_GetSurfaceDesc,
+    IDirectDrawSurface4Impl_Initialize,
+    IDirectDrawSurface4Impl_IsLost,
+    IDirectDrawSurface4Impl_Lock,
+    IDirectDrawSurface4Impl_ReleaseDC,
+    IDirectDrawSurface4Impl_Restore,
+    IDirectDrawSurface4Impl_SetClipper,
+    IDirectDrawSurface4Impl_SetColorKey,
+    IDirectDrawSurface4Impl_SetOverlayPosition,
+    DGA_IDirectDrawSurface4Impl_SetPalette,
+    IDirectDrawSurface4Impl_Unlock,
+    IDirectDrawSurface4Impl_UpdateOverlay,
+    IDirectDrawSurface4Impl_UpdateOverlayDisplay,
+    IDirectDrawSurface4Impl_UpdateOverlayZOrder,
+    IDirectDrawSurface4Impl_GetDDInterface,
+    IDirectDrawSurface4Impl_PageLock,
+    IDirectDrawSurface4Impl_PageUnlock,
+    IDirectDrawSurface4Impl_SetSurfaceDesc,
+    IDirectDrawSurface4Impl_SetPrivateData,
+    IDirectDrawSurface4Impl_GetPrivateData,
+    IDirectDrawSurface4Impl_FreePrivateData,
+    IDirectDrawSurface4Impl_GetUniquenessValue,
+    IDirectDrawSurface4Impl_ChangeUniquenessValue
+};
+#endif /* defined(HAVE_LIBXXF86DGA2) */
diff --git a/dlls/ddraw/dsurface/main.c b/dlls/ddraw/dsurface/main.c
new file mode 100644
index 0000000..13d8d6a
--- /dev/null
+++ b/dlls/ddraw/dsurface/main.c
@@ -0,0 +1,1145 @@
+/*		DirectDrawSurface base implementation
+ *
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
+ */
+#include "config.h"
+#include "winerror.h"
+
+
+#include <unistd.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "debugtools.h"
+#include "ddraw_private.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+/******************************************************************************
+ *		IDirectDrawSurface methods
+ *
+ * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
+ * DDS and DDS2 use those functions. (Function calls did not change (except
+ * using different DirectDrawSurfaceX version), just added flags and functions)
+ */
+
+HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
+    LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
+	This,lprect,lpddsd,flags,(DWORD)hnd);
+    if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
+	WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
+		 This,lprect,lpddsd,flags,(DWORD)hnd);
+
+    /* First, copy the Surface description */
+    *lpddsd = This->s.surface_desc;
+    TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
+	  lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
+
+    /* If asked only for a part, change the surface pointer */
+    if (lprect) {
+	TRACE("	lprect: %dx%d-%dx%d\n",
+		lprect->top,lprect->left,lprect->bottom,lprect->right
+	);
+	if ((lprect->top < 0) ||
+	    (lprect->left < 0) ||
+	    (lprect->bottom < 0) ||
+	    (lprect->right < 0)) {
+	  ERR(" Negative values in LPRECT !!!\n");
+	  return DDERR_INVALIDPARAMS;
+       }
+       
+	lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
+		(lprect->top*This->s.surface_desc.lPitch) +
+		lprect->left*GET_BPP(This->s.surface_desc));
+    } else {
+	assert(This->s.surface_desc.u1.lpSurface);
+    }
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_Unlock(
+    LPDIRECTDRAWSURFACE4 iface,LPVOID surface
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->Unlock(%p)\n",This,surface);
+    return DD_OK;
+}
+
+IDirectDrawSurface4Impl* _common_find_flipto(
+    IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
+) {
+    int	i,j,flipable=0;
+    struct _surface_chain	*chain = This->s.chain;
+
+    /* if there was no override flipto, look for current backbuffer */
+    if (!flipto) {
+	/* walk the flip chain looking for backbuffer */
+	for (i=0;i<chain->nrofsurfaces;i++) {
+	    if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
+	    	flipable++;
+	    if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
+		flipto = chain->surfaces[i];
+	}
+	/* sanity checks ... */
+	if (!flipto) {
+	    if (flipable>1) {
+		for (i=0;i<chain->nrofsurfaces;i++)
+		    if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
+		    	break;
+		if (i==chain->nrofsurfaces) {
+		    /* we do not have a frontbuffer either */
+		    for (i=0;i<chain->nrofsurfaces;i++)
+			if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
+			    SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
+			    break;
+			}
+		    for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
+		    	int k = j % chain->nrofsurfaces;
+			if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
+			    SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
+			    flipto = chain->surfaces[k];
+			    break;
+			}
+		    }
+		}
+	    }
+	    if (!flipto)
+		flipto = This;
+	}
+	TRACE("flipping to %p\n",flipto);
+    }
+    return flipto;
+}
+
+static HRESULT _Blt_ColorFill(
+    LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color
+) {
+    int x, y;
+    LPBYTE first;
+
+    /* Do first row */
+
+#define COLORFILL_ROW(type) { \
+    type *d = (type *) buf; \
+    for (x = 0; x < width; x++) \
+	d[x] = (type) color; \
+    break; \
+}
+
+    switch(bpp) {
+    case 1: COLORFILL_ROW(BYTE)
+    case 2: COLORFILL_ROW(WORD)
+    case 4: COLORFILL_ROW(DWORD)
+    default:
+	FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
+	return DDERR_UNSUPPORTED;
+    }
+
+#undef COLORFILL_ROW
+
+    /* Now copy first row */
+    first = buf;
+    for (y = 1; y < height; y++) {
+	buf += lPitch;
+	memcpy(buf, first, width * bpp);
+    }
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
+    LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,
+    DWORD dwFlags,LPDDBLTFX lpbltfx
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    RECT		xdst,xsrc;
+    DDSURFACEDESC	ddesc,sdesc;
+    HRESULT		ret = DD_OK;
+    int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
+    int x, y;
+    LPBYTE dbuf, sbuf;
+
+    TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
+
+    if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
+    IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
+
+    if (src && sdesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+	ERR("blitting FROM a primary surface? Hello?\n");
+    if (!(ddesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
+	ERR("NOT blitting into a primary surface? Hello?\n");
+
+    if (TRACE_ON(ddraw)) {
+	if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
+	if (rsrc) TRACE("\tsrcrect  :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
+	TRACE("\tflags: ");
+	_dump_DDBLT(dwFlags);
+	if (dwFlags & DDBLT_DDFX) {
+	    TRACE("\tblitfx: ");
+	    _dump_DDBLTFX(lpbltfx->dwDDFX);
+	}
+    }
+
+    if (rdst) {
+	if ((rdst->top < 0) ||
+	    (rdst->left < 0) ||
+	    (rdst->bottom < 0) ||
+	    (rdst->right < 0)) {
+	  ERR(" Negative values in LPRECT !!!\n");
+	  goto release;
+	}
+	memcpy(&xdst,rdst,sizeof(xdst));
+    } else {
+	xdst.top	= 0;
+	xdst.bottom	= ddesc.dwHeight;
+	xdst.left	= 0;
+	xdst.right	= ddesc.dwWidth;
+    }
+
+    if (rsrc) {
+	if ((rsrc->top < 0) ||
+	    (rsrc->left < 0) ||
+	    (rsrc->bottom < 0) ||
+	    (rsrc->right < 0)) {
+	  ERR(" Negative values in LPRECT !!!\n");
+	  goto release;
+	}
+	memcpy(&xsrc,rsrc,sizeof(xsrc));
+    } else {
+	if (src) {
+	    xsrc.top	= 0;
+	    xsrc.bottom	= sdesc.dwHeight;
+	    xsrc.left	= 0;
+	    xsrc.right	= sdesc.dwWidth;
+	} else {
+	    memset(&xsrc,0,sizeof(xsrc));
+	}
+    }
+    assert(xsrc.bottom <= sdesc.dwHeight);
+    assert(xdst.bottom <= ddesc.dwHeight);
+
+    bpp = GET_BPP(ddesc);
+    srcheight = xsrc.bottom - xsrc.top;
+    srcwidth = xsrc.right - xsrc.left;
+    dstheight = xdst.bottom - xdst.top;
+    dstwidth = xdst.right - xdst.left;
+    width = (xdst.right - xdst.left) * bpp;
+
+    assert(width <= ddesc.lPitch);
+
+    dbuf = (BYTE*)ddesc.u1.lpSurface+(xdst.top*ddesc.lPitch)+(xdst.left*bpp);
+
+    dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
+
+    /* First, all the 'source-less' blits */
+    if (dwFlags & DDBLT_COLORFILL) {
+	ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
+			     ddesc.lPitch, lpbltfx->u4.dwFillColor);
+	dwFlags &= ~DDBLT_COLORFILL;
+    }
+
+    if (dwFlags & DDBLT_DEPTHFILL)
+	FIXME("DDBLT_DEPTHFILL needs to be implemented!\n");
+    if (dwFlags & DDBLT_ROP) {
+	/* Catch some degenerate cases here */
+	switch(lpbltfx->dwROP) {
+	case BLACKNESS:
+	    ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.lPitch,0);
+	    break;
+	case 0xAA0029: /* No-op */
+	    break;
+	case WHITENESS:
+	    ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.lPitch,~0);
+	    break;
+	default: 
+	    FIXME("Unsupported raster op: %08lx  Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
+	    goto error;
+	}
+	dwFlags &= ~DDBLT_ROP;
+    }
+    if (dwFlags & DDBLT_DDROPS) {
+	FIXME("\tDdraw Raster Ops: %08lx  Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
+    }
+    /* Now the 'with source' blits */
+    if (src) {
+	LPBYTE sbase;
+	int sx, xinc, sy, yinc;
+
+	sbase = (BYTE*)sdesc.u1.lpSurface+(xsrc.top*sdesc.lPitch)+xsrc.left*bpp;
+	xinc = (srcwidth << 16) / dstwidth;
+	yinc = (srcheight << 16) / dstheight;
+
+	if (!dwFlags) {
+	    assert(ddesc.lPitch >= width);
+	    assert(sdesc.lPitch >= width);
+
+	    /* No effects, we can cheat here */
+	    if (dstwidth == srcwidth) {
+		if (dstheight == srcheight) {
+		    /* No stretching in either direction. This needs to be as
+		     * fast as possible */
+		    sbuf = sbase;
+		    for (y = 0; y < dstheight; y++) {
+			memcpy(dbuf, sbuf, width);
+			sbuf += sdesc.lPitch;
+			dbuf += ddesc.lPitch;
+		    }
+		} else {
+		    /* Stretching in Y direction only */
+		    for (y = sy = 0; y < dstheight; y++, sy += yinc) {
+			sbuf = sbase + (sy >> 16) * sdesc.lPitch;
+			memcpy(dbuf, sbuf, width);
+			dbuf += ddesc.lPitch;
+		    }
+		}
+	    } else {
+		/* Stretching in X direction */
+		int last_sy = -1;
+		for (y = sy = 0; y < dstheight; y++, sy += yinc) {
+		    sbuf = sbase + (sy >> 16) * sdesc.lPitch;
+
+		    assert((sy>>16) < srcheight);
+
+		    if ((sy >> 16) == (last_sy >> 16)) {
+			/* this sourcerow is the same as last sourcerow -
+			 * copy already stretched row
+			 */
+			memcpy(dbuf, dbuf - ddesc.lPitch, width);
+		    } else {
+#define STRETCH_ROW(type) { \
+		    type *s = (type *) sbuf, *d = (type *) dbuf; \
+		    for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
+		    d[x] = s[sx >> 16]; \
+		    break; }
+
+		    switch(bpp) {
+		    case 1: STRETCH_ROW(BYTE)
+		    case 2: STRETCH_ROW(WORD)
+		    case 4: STRETCH_ROW(DWORD)
+		    case 3: {
+			LPBYTE s,d = dbuf;
+			for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {
+			    DWORD pixel;
+
+			    s = sbuf+3*(sx>>16);
+			    pixel = (s[0]<<16)|(s[1]<<8)|s[2];
+			    d[0] = (pixel>>16)&0xff;
+			    d[1] = (pixel>> 8)&0xff;
+			    d[2] = (pixel    )&0xff;
+			    d+=3;
+			}
+			break;
+		    }
+		    default:
+			FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
+			ret = DDERR_UNSUPPORTED;
+			goto error;
+		    }
+#undef STRETCH_ROW
+		    }
+		    dbuf += ddesc.lPitch;
+		    last_sy = sy;
+		}
+	    }
+	} else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
+	    DWORD keylow, keyhigh;
+
+	    if (dwFlags & DDBLT_KEYSRC) {
+		keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
+		keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
+	    } else {
+		/* I'm not sure if this is correct */
+		FIXME("DDBLT_KEYDEST not fully supported yet.\n");
+		keylow  = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
+		keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
+	    }
+
+
+	    for (y = sy = 0; y < dstheight; y++, sy += yinc) {
+		sbuf = sbase + (sy >> 16) * sdesc.lPitch;
+
+#define COPYROW_COLORKEY(type) { \
+		type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
+		for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
+		    tmp = s[sx >> 16]; \
+		    if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
+		} \
+		break; }
+
+		switch (bpp) {
+		case 1: COPYROW_COLORKEY(BYTE)
+		case 2: COPYROW_COLORKEY(WORD)
+		case 4: COPYROW_COLORKEY(DWORD)
+		default:
+		    FIXME("%s color-keyed blit not implemented for bpp %d!\n",
+		    (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
+		    ret = DDERR_UNSUPPORTED;
+		    goto error;
+		}
+		dbuf += ddesc.lPitch;
+	    }
+#undef COPYROW_COLORKEY
+	    dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
+	}
+    }
+
+error:
+    if (dwFlags && FIXME_ON(ddraw)) {
+	FIXME("\tUnsupported flags: ");
+	_dump_DDBLT(dwFlags);
+    }
+
+release:
+    IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
+    if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
+    LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,
+    LPRECT rsrc,DWORD trans
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    int			bpp, w, h, x, y;
+    DDSURFACEDESC	ddesc,sdesc;
+    HRESULT		ret = DD_OK;
+    LPBYTE		sbuf, dbuf;
+    RECT		rsrc2;
+
+
+    if (TRACE_ON(ddraw)) {
+	FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
+		This,dstx,dsty,src,rsrc,trans
+	);
+	FIXME("	trans:");
+	if (FIXME_ON(ddraw))
+	  _dump_DDBLTFAST(trans);
+	if (rsrc)
+	  FIXME("\tsrcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
+	else
+	  FIXME(" srcrect: NULL\n");
+    }
+    
+    /* We need to lock the surfaces, or we won't get refreshes when done. */
+    IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
+    IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
+
+   if (!rsrc) {
+	   WARN("rsrc is NULL!\n");
+	   rsrc = &rsrc2;
+	   rsrc->left = rsrc->top = 0;
+	   rsrc->right = sdesc.dwWidth;
+	   rsrc->bottom = sdesc.dwHeight;
+   }
+
+    bpp = GET_BPP(This->s.surface_desc);
+    sbuf = (BYTE *)sdesc.u1.lpSurface+(rsrc->top*sdesc.lPitch)+rsrc->left*bpp;
+    dbuf = (BYTE *)ddesc.u1.lpSurface+(dsty*ddesc.lPitch)+dstx* bpp;
+
+
+    h=rsrc->bottom-rsrc->top;
+    if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
+    if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
+    if (h<0) h=0;
+
+    w=rsrc->right-rsrc->left;
+    if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
+    if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
+    if (w<0) w=0;
+
+    if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
+	DWORD keylow, keyhigh;
+	if (trans & DDBLTFAST_SRCCOLORKEY) {
+	    keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
+	    keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
+	} else {
+	    /* I'm not sure if this is correct */
+	    FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
+	    keylow  = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
+	    keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
+	}
+
+#define COPYBOX_COLORKEY(type) { \
+    type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
+    s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
+    d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
+    for (y = 0; y < h; y++) { \
+	for (x = 0; x < w; x++) { \
+	    tmp = s[x]; \
+	    if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
+	} \
+	(LPBYTE)s += sdesc.lPitch; \
+	(LPBYTE)d += ddesc.lPitch; \
+    } \
+    break; \
+}
+
+	switch (bpp) {
+	case 1: COPYBOX_COLORKEY(BYTE)
+	case 2: COPYBOX_COLORKEY(WORD)
+	case 4: COPYBOX_COLORKEY(DWORD)
+	default:
+	    FIXME("Source color key blitting not supported for bpp %d\n",bpp*8);
+	    ret = DDERR_UNSUPPORTED;
+	    goto error;
+	}
+#undef COPYBOX_COLORKEY
+    } else {
+	int width = w * bpp;
+
+	for (y = 0; y < h; y++) {
+	    memcpy(dbuf, sbuf, width);
+	    sbuf += sdesc.lPitch;
+	    dbuf += ddesc.lPitch;
+	}
+    }
+error:
+    IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
+    IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
+    return ret;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
+    LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",This,ddbltbatch,x,y);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
+    LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->GetCaps(%p)\n",This,caps);
+    caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
+    LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
+) { 
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
+  
+    /* Simply copy the surface description stored in the object */
+    *ddsd = This->s.surface_desc;
+  
+    if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
+
+    return DD_OK;
+}
+
+ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
+    return ++(This->ref);
+}
+
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
+    LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    int	i,found = 0,xstart;
+    struct _surface_chain	*chain;
+
+    TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
+    if (TRACE_ON(ddraw)) {
+	TRACE("	caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
+	DPRINTF("\n");
+    }
+    chain = This->s.chain;
+    if (!chain)
+    	return DDERR_NOTFOUND;
+
+    for (i=0;i<chain->nrofsurfaces;i++)
+    	if (chain->surfaces[i] == This)
+	    break;
+
+    xstart = i;
+    for (i=0;i<chain->nrofsurfaces;i++) {
+	if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
+#if 0
+	    if (found) /* may not find the same caps twice, (doc) */
+		return DDERR_INVALIDPARAMS;/*FIXME: correct? */
+#endif
+	    found = (i+1)+xstart;
+	}
+    }
+    if (!found)
+	return DDERR_NOTFOUND;
+    *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
+    /* FIXME: AddRef? */
+    TRACE("found %p\n",*lpdsf);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
+    LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
+
+    return DDERR_ALREADYINITIALIZED;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
+    LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->(%p)\n",This,pf);
+
+    *pf = This->s.surface_desc.ddpfPixelFormat;
+    if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
+    LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
+    LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->(%p)!\n",This,lpClipper);
+
+    if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
+    This->s.lpClipper = lpClipper;
+    if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
+    LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
+    int i;
+    struct _surface_chain *chain;
+
+    FIXME("(%p)->(%p)\n",This,surf);
+    chain = This->s.chain;
+
+    /* IDirectDrawSurface4_AddRef(surf); */
+    
+    if (chain) {
+	for (i=0;i<chain->nrofsurfaces;i++)
+	    if (chain->surfaces[i] == isurf)
+		FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
+    } else {
+    	chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
+	chain->nrofsurfaces = 1;
+	chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
+	chain->surfaces[0] = This;
+	This->s.chain = chain;
+    }
+
+    if (chain->surfaces)
+	chain->surfaces = HeapReAlloc(
+	    GetProcessHeap(),
+	    0,
+	    chain->surfaces,
+	    sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
+	);
+    else
+	chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
+    isurf->s.chain = chain;
+    chain->surfaces[chain->nrofsurfaces++] = isurf;
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    DDSURFACEDESC desc;
+    BITMAPINFO *b_info;
+    UINT usage;
+
+    FIXME("(%p)->GetDC(%p)\n",This,lphdc);
+
+    /* Creates a DIB Section of the same size / format as the surface */
+    IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
+
+    if (This->s.hdc == 0) {
+	switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
+	case 16:
+	case 32:
+#if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
+	    b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
+	    break;
+#endif
+
+	case 24:
+	    b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
+	    break;
+
+	default:
+	    b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+		    sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
+	    break;
+	}
+
+	b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+	b_info->bmiHeader.biWidth = desc.dwWidth;
+	b_info->bmiHeader.biHeight = desc.dwHeight;
+	b_info->bmiHeader.biPlanes = 1;
+	b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
+#if 0
+	if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
+	    (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
+#endif
+	b_info->bmiHeader.biCompression = BI_RGB;
+#if 0
+	else
+	b_info->bmiHeader.biCompression = BI_BITFIELDS;
+#endif
+	b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
+	b_info->bmiHeader.biXPelsPerMeter = 0;
+	b_info->bmiHeader.biYPelsPerMeter = 0;
+	b_info->bmiHeader.biClrUsed = 0;
+	b_info->bmiHeader.biClrImportant = 0;
+
+	switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
+	case 16:
+	case 32:
+#if 0
+	    {
+		DWORD *masks = (DWORD *) &(b_info->bmiColors);
+
+		usage = 0;
+		masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
+		masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
+		masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
+	    }
+	    break;
+#endif
+	case 24:
+	    /* Nothing to do */
+	    usage = DIB_RGB_COLORS;
+	    break;
+
+	default: {
+		int i;
+
+		/* Fill the palette */
+		usage = DIB_RGB_COLORS;
+
+		if (This->s.palette == NULL) {
+		    ERR("Bad palette !!!\n");
+		} else {
+		    RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
+		    PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
+
+		    for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
+			rgb[i].rgbBlue = pent[i].peBlue;
+			rgb[i].rgbRed = pent[i].peRed;
+			rgb[i].rgbGreen = pent[i].peGreen; 
+		    }
+		}
+	    }
+	    break;
+	}
+	This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
+	    b_info,
+	    usage,
+	    &(This->s.bitmap_data),
+	    0,
+	    0
+	);
+	EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
+	if (!This->s.DIBsection) {
+		ERR("CreateDIBSection failed!\n");
+		return E_FAIL;
+	}
+	TRACE("DIBSection at : %p\n", This->s.bitmap_data);
+
+	/* b_info is not useful anymore */
+	HeapFree(GetProcessHeap(), 0, b_info);
+
+	/* Create the DC */
+	This->s.hdc = CreateCompatibleDC(0);
+	This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
+    }
+
+    /* Copy our surface in the DIB section */
+    if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
+	memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
+    else
+	/* TODO */
+	FIXME("This case has to be done :/\n");
+
+    TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
+    *lphdc = This->s.hdc;
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+
+    FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
+    TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
+    /* Copy the DIB section to our surface */
+    if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
+	memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
+    } else {
+	/* TODO */
+	FIXME("This case has to be done :/\n");
+    }
+    /* Unlock the surface */
+    IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(
+    LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+
+    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
+    
+    /* All DirectDrawSurface versions (1, 2, 3 and 4) use
+     * the same interface. And IUnknown does that too of course.
+     */
+    if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid )	||
+	 IsEqualGUID( &IID_IDirectDrawSurface3, refiid )	||
+	 IsEqualGUID( &IID_IDirectDrawSurface2, refiid )	||
+	 IsEqualGUID( &IID_IDirectDrawSurface,  refiid )	||
+	 IsEqualGUID( &IID_IUnknown,            refiid )
+    ) {
+	    *obj = This;
+	    IDirectDrawSurface4_AddRef(iface);
+
+	    TRACE("  Creating IDirectDrawSurface interface (%p)\n", *obj);
+	    return S_OK;
+    }
+    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
+    return OLE_E_ENUM_NOMORE;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->(), stub!\n",This);
+    return DD_OK; /* hmm */
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(
+    LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    int i;
+    struct _surface_chain *chain = This->s.chain;
+
+    TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
+    for (i=0;i<chain->nrofsurfaces;i++) {
+      TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
+      if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
+	return DD_OK; /* FIXME: return value correct? */
+    }
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(),stub!\n",This);
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
+    LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey ) 
+{
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
+    if (TRACE_ON(ddraw)) {
+	_dump_colorkeyflag(dwFlags);
+	DPRINTF(" : ");
+	_dump_DDCOLORKEY((void *) ckey);
+	DPRINTF("\n");
+    }
+
+    /* If this surface was loaded as a texture, call also the texture
+     * SetColorKey callback. FIXME: hack approach :(
+     */
+    if (This->s.texture)
+	This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
+
+    if( dwFlags & DDCKEY_SRCBLT ) {
+	dwFlags &= ~DDCKEY_SRCBLT;
+	This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
+	memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
+    }
+
+    if( dwFlags & DDCKEY_DESTBLT ) {
+	dwFlags &= ~DDCKEY_DESTBLT;
+	This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
+	memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
+    }
+
+    if( dwFlags & DDCKEY_SRCOVERLAY ) {
+	dwFlags &= ~DDCKEY_SRCOVERLAY;
+	This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
+	memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );	   
+    }
+
+    if( dwFlags & DDCKEY_DESTOVERLAY ) {
+	dwFlags &= ~DDCKEY_DESTOVERLAY;
+	This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
+	memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );	   
+    }
+    if( dwFlags )
+	FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
+    LPDIRECTDRAWSURFACE4 iface, LPRECT lpRect
+) {
+  ICOM_THIS(IDirectDrawSurface4Impl,iface);
+  FIXME("(%p)->(%p),stub!\n",This,lpRect); 
+
+  return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
+    LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags,
+    LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    int i;
+    struct _surface_chain *chain;
+
+    TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
+    chain = This->s.chain;
+    for (i=0;i<chain->nrofsurfaces;i++) {
+	if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
+	    IDirectDrawSurface4_Release(lpDDSAttachedSurface);
+
+	    chain->surfaces[i]->s.chain = NULL;
+	    memcpy( chain->surfaces+i,
+		    chain->surfaces+(i+1),
+		    (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
+	    );
+	    chain->surfaces = HeapReAlloc(
+		GetProcessHeap(),
+		0,
+		chain->surfaces,
+		sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
+	    );
+	    chain->nrofsurfaces--;
+	    return DD_OK;
+	}
+    }
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
+    LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPVOID lpContext,
+    LPDDENUMSURFACESCALLBACK lpfnCallback
+) {
+  ICOM_THIS(IDirectDrawSurface4Impl,iface);
+  FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
+          lpContext, lpfnCallback );
+
+  return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
+    LPDIRECTDRAWSURFACE4 iface, LPDIRECTDRAWCLIPPER* lplpDDClipper
+) {
+  ICOM_THIS(IDirectDrawSurface4Impl,iface);
+  FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
+
+  return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
+    LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY lpDDColorKey
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
+
+    if( dwFlags & DDCKEY_SRCBLT )  {
+	dwFlags &= ~DDCKEY_SRCBLT;
+	memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
+    }
+    if( dwFlags & DDCKEY_DESTBLT ) {
+	dwFlags &= ~DDCKEY_DESTBLT;
+	memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
+    }
+    if( dwFlags & DDCKEY_SRCOVERLAY ) {
+	dwFlags &= ~DDCKEY_SRCOVERLAY;
+	memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
+    }
+    if( dwFlags & DDCKEY_DESTOVERLAY ) {
+	dwFlags &= ~DDCKEY_DESTOVERLAY;
+	memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
+    }
+    if( dwFlags )
+	FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
+    LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
+    LPDIRECTDRAWSURFACE4 iface, LPDIRECTDRAWPALETTE* lplpDDPalette
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
+
+    if (!This->s.palette)
+	return DDERR_NOPALETTEATTACHED;
+
+    IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
+    *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
+    LPDIRECTDRAWSURFACE4 iface, LONG lX, LONG lY
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
+    LPDIRECTDRAWSURFACE4 iface, LPRECT lpSrcRect,
+    LPDIRECTDRAWSURFACE4 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags,
+    LPDDOVERLAYFX lpDDOverlayFx
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
+	 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );  
+
+    return DD_OK;
+}
+ 
+HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
+    LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags); 
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
+    LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags,LPDIRECTDRAWSURFACE4 lpDDSReference
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
+    LPDIRECTDRAWSURFACE4 iface, LPVOID* lplpDD
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(%p),stub!\n", This, lplpDD);
+
+    /* Not sure about that... */
+    *lplpDD = (void *) This->s.ddraw;
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
+    LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
+    LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
+    LPDIRECTDRAWSURFACE4 iface, LPDDSURFACEDESC lpDDSD, DWORD dwFlags
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(
+    LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag, LPVOID lpData, DWORD cbSize,
+    DWORD dwFlags
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(
+    LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag, LPVOID lpBuffer,
+    LPDWORD lpcbBufferSize
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(
+    LPDIRECTDRAWSURFACE4 iface, REFGUID guidTag
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(%p)\n", This, guidTag);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(
+    LPDIRECTDRAWSURFACE4 iface, LPDWORD lpValue
+)  {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)->(%p)\n", This, lpValue);
+
+    return DD_OK;
+}
+
+HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(
+    LPDIRECTDRAWSURFACE4 iface
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    FIXME("(%p)\n", This);
+
+    return DD_OK;
+}
diff --git a/dlls/ddraw/dsurface/x11.c b/dlls/ddraw/dsurface/x11.c
new file mode 100644
index 0000000..bd7f28a
--- /dev/null
+++ b/dlls/ddraw/dsurface/x11.c
@@ -0,0 +1,423 @@
+/*		DirectDrawSurface Xlib implementation
+ *
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
+ */
+#include "config.h"
+#include "winerror.h"
+
+#include <unistd.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "options.h"
+#include "debugtools.h"
+#include "x11_private.h"
+
+#ifdef HAVE_MESAGL
+/* for d3d texture stuff */
+# include "mesa_private.h"
+#endif
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+#define VISIBLE(x) (SDDSCAPS(x) & (DDSCAPS_VISIBLE|DDSCAPS_PRIMARYSURFACE))
+
+#define DDPRIVATE(x) x11_dd_private *ddpriv = ((x11_dd_private*)(x)->private)
+#define DPPRIVATE(x) x11_dp_private *dppriv = ((x11_dp_private*)(x)->private)
+#define DSPRIVATE(x) x11_ds_private *dspriv = ((x11_ds_private*)(x)->private)
+
+/******************************************************************************
+ *		IDirectDrawSurface methods
+ *
+ * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
+ * DDS and DDS2 use those functions. (Function calls did not change (except
+ * using different DirectDrawSurfaceX version), just added flags and functions)
+ */
+HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_QueryInterface(
+    LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+
+    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
+    
+    /* All DirectDrawSurface versions (1, 2, 3 and 4) use
+     * the same interface. And IUnknown does that too of course.
+     */
+    if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid )	||
+	 IsEqualGUID( &IID_IDirectDrawSurface3, refiid )	||
+	 IsEqualGUID( &IID_IDirectDrawSurface2, refiid )	||
+	 IsEqualGUID( &IID_IDirectDrawSurface,  refiid )	||
+	 IsEqualGUID( &IID_IUnknown,            refiid )
+    ) {
+	    *obj = This;
+	    IDirectDrawSurface4_AddRef(iface);
+
+	    TRACE("  Creating IDirectDrawSurface interface (%p)\n", *obj);
+	    return S_OK;
+    }
+#ifdef HAVE_MESAGL
+    if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) ) {
+	/* Texture interface */
+	*obj = d3dtexture2_create(This);
+	IDirectDrawSurface4_AddRef(iface);
+	TRACE("  Creating IDirect3DTexture2 interface (%p)\n", *obj);
+	return S_OK;
+    }
+    if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) ) {
+	/* Texture interface */
+	*obj = d3dtexture_create(This);
+	IDirectDrawSurface4_AddRef(iface);
+	TRACE("  Creating IDirect3DTexture interface (%p)\n", *obj);
+	return S_OK;
+    }
+#endif /* HAVE_MESAGL */
+    FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
+    return OLE_E_ENUM_NOMORE;
+}
+
+HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Lock(
+    LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    DSPRIVATE(This);
+    DDPRIVATE(This->s.ddraw);
+    
+    IDirectDrawSurface4_AddRef(iface);
+    assert(HeapValidate(GetProcessHeap(),0,NULL));
+
+    TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",This,lprect,lpddsd,flags,(DWORD)hnd);
+    if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
+	WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
+		     This,lprect,lpddsd,flags,(DWORD)hnd);
+
+    /* First, copy the Surface description */
+    *lpddsd = This->s.surface_desc;
+    TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
+	  lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
+
+    /* If asked only for a part, change the surface pointer */
+    if (lprect) {
+	TRACE("	lprect: %dx%d-%dx%d\n",
+		lprect->top,lprect->left,lprect->bottom,lprect->right
+	);
+	if ((lprect->top < 0) ||
+	    (lprect->left < 0) ||
+	    (lprect->bottom < 0) ||
+	    (lprect->right < 0)) {
+	  ERR(" Negative values in LPRECT !!!\n");
+          IDirectDrawSurface4_Release(iface);
+	  return DDERR_INVALIDPARAMS;
+	}
+	lpddsd->u1.lpSurface=(LPVOID)((char*)This->s.surface_desc.u1.lpSurface+
+		(lprect->top*This->s.surface_desc.lPitch) +
+		lprect->left*GET_BPP(This->s.surface_desc));
+    } else
+	assert(This->s.surface_desc.u1.lpSurface);
+    /* wait for any previous operations to complete */
+#ifdef HAVE_LIBXXSHM
+    if (dspriv->image && VISIBLE(This) && ddpriv->xshm_active) {
+/*
+	int compl = InterlockedExchange( &(ddpriv->xshm_compl), 0 );
+	if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
+*/
+	X11DRV_EVENT_WaitShmCompletions( ddpriv->drawable );
+    }
+#endif
+    return DD_OK;
+}
+
+static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
+  DSPRIVATE(This);
+  DDPRIVATE(This->s.ddraw);
+  if (This->s.ddraw->d.pixel_convert != NULL)
+    This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
+				   dspriv->image->data,
+				   This->s.surface_desc.dwWidth,
+				   This->s.surface_desc.dwHeight,
+				   This->s.surface_desc.lPitch,
+				   This->s.palette);
+
+#ifdef HAVE_LIBXXSHM
+    if (ddpriv->xshm_active) {
+/*
+	X11DRV_EVENT_WaitReplaceShmCompletion( &(ddpriv->xshm_compl), This->s.ddraw->d.drawable );
+*/
+	/* let WaitShmCompletions track 'em for now */
+	/* (you may want to track it again whenever you implement DX7's partial
+	* surface locking, where threads have concurrent access) */
+	X11DRV_EVENT_PrepareShmCompletion( ddpriv->drawable );
+	TSXShmPutImage(display,
+	    ddpriv->drawable,
+	    DefaultGCOfScreen(X11DRV_GetXScreen()),
+	    dspriv->image,
+	    0, 0, 0, 0,
+	    dspriv->image->width,
+	    dspriv->image->height,
+	    True
+	);
+	/* make sure the image is transferred ASAP */
+	TSXFlush(display);
+    } else
+#endif
+	TSXPutImage(	
+	    display,
+	    ddpriv->drawable,
+	    DefaultGCOfScreen(X11DRV_GetXScreen()),
+	    dspriv->image,
+	    0, 0, 0, 0,
+	    dspriv->image->width,
+	    dspriv->image->height
+	);
+}
+
+HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
+    LPDIRECTDRAWSURFACE4 iface,LPVOID surface
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    DDPRIVATE(This->s.ddraw);
+    DSPRIVATE(This);
+    TRACE("(%p)->Unlock(%p)\n",This,surface);
+
+    /*if (!This->s.ddraw->d.paintable)
+	return DD_OK; */
+
+    /* Only redraw the screen when unlocking the buffer that is on screen */
+    if (dspriv->image && VISIBLE(This)) {
+	Xlib_copy_surface_on_screen(This);
+	if (This->s.palette) {
+    	    DPPRIVATE(This->s.palette);
+	    if(dppriv->cm)
+		TSXSetWindowColormap(display,ddpriv->drawable,dppriv->cm);
+	}
+    }
+    assert(HeapValidate(GetProcessHeap(),0,NULL));
+    IDirectDrawSurface4_Release(iface);
+    return DD_OK;
+}
+
+HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
+    LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    XImage	*image;
+    DDPRIVATE(This->s.ddraw);
+    DSPRIVATE(This);
+    x11_ds_private	*fspriv;
+    LPBYTE	surf;
+    IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
+
+    TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
+    if (!This->s.ddraw->d.paintable)
+	return DD_OK;
+
+    iflipto = _common_find_flipto(This,iflipto);
+    fspriv = (x11_ds_private*)iflipto->private;
+
+    /* We need to switch the lowlevel surfaces, for xlib this is: */
+    /* The surface pointer */
+    surf				= This->s.surface_desc.u1.lpSurface;
+    This->s.surface_desc.u1.lpSurface	= iflipto->s.surface_desc.u1.lpSurface;
+    iflipto->s.surface_desc.u1.lpSurface	= surf;
+
+    /* the associated ximage */
+    image		= dspriv->image;
+    dspriv->image	= fspriv->image;
+    fspriv->image	= image;
+
+#ifdef HAVE_LIBXXSHM
+    if (ddpriv->xshm_active) {
+/*
+	int compl = InterlockedExchange( &(ddpriv->xshm_compl), 0 );
+	if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
+*/
+	X11DRV_EVENT_WaitShmCompletions( ddpriv->drawable );
+    }
+#endif
+    Xlib_copy_surface_on_screen(This);
+    if (iflipto->s.palette) {
+        DPPRIVATE(iflipto->s.palette);
+	if (dppriv->cm)
+	    TSXSetWindowColormap(display,ddpriv->drawable,dppriv->cm);
+    }
+    return DD_OK;
+}
+
+/* The IDirectDrawSurface4::SetPalette method attaches the specified
+ * DirectDrawPalette object to a surface. The surface uses this palette for all
+ * subsequent operations. The palette change takes place immediately.
+ */
+HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
+    LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
+) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    DDPRIVATE(This->s.ddraw);
+    IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
+    x11_dp_private	*dppriv;
+    int i;
+
+    TRACE("(%p)->(%p)\n",This,ipal);
+
+    if (ipal == NULL) {
+	if( This->s.palette != NULL )
+	    IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
+	This->s.palette = ipal;
+	return DD_OK;
+    }
+    dppriv = (x11_dp_private*)ipal->private;
+
+    if (!dppriv->cm &&
+	(This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8)
+    ) {
+	dppriv->cm = TSXCreateColormap(
+	    display,
+	    ddpriv->drawable,
+	    DefaultVisualOfScreen(X11DRV_GetXScreen()),
+	    AllocAll
+	);
+	if (!Options.managed)
+	    TSXInstallColormap(display,dppriv->cm);
+
+	for (i=0;i<256;i++) {
+	    XColor xc;
+
+	    xc.red		= ipal->palents[i].peRed<<8;
+	    xc.blue		= ipal->palents[i].peBlue<<8;
+	    xc.green	= ipal->palents[i].peGreen<<8;
+	    xc.flags	= DoRed|DoBlue|DoGreen;
+	    xc.pixel	= i;
+	    TSXStoreColor(display,dppriv->cm,&xc);
+	}
+	TSXInstallColormap(display,dppriv->cm);
+    }
+    /* According to spec, we are only supposed to 
+     * AddRef if this is not the same palette.
+     */
+    if ( This->s.palette != ipal ) {
+	if( ipal != NULL )
+	    IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
+	if( This->s.palette != NULL )
+	    IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
+	This->s.palette = ipal; 
+	/* Perform the refresh */
+	TSXSetWindowColormap(display,ddpriv->drawable,dppriv->cm);
+    }
+    return DD_OK;
+}
+
+ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
+    ICOM_THIS(IDirectDrawSurface4Impl,iface);
+    DSPRIVATE(This);
+    DDPRIVATE(This->s.ddraw);
+
+    TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
+    if (--(This->ref))
+    	return This->ref;
+
+    IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
+
+    if (dspriv->image != NULL) {
+	if (This->s.ddraw->d.pixel_convert != NULL) {
+	    /* In pixel conversion mode, there are 2 buffers to release. */
+	    HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
+
+#ifdef HAVE_LIBXXSHM
+	    if (ddpriv->xshm_active) {
+		TSXShmDetach(display, &(dspriv->shminfo));
+		TSXDestroyImage(dspriv->image);
+		shmdt(dspriv->shminfo.shmaddr);
+	    } else
+#endif
+	    {
+		HeapFree(GetProcessHeap(),0,dspriv->image->data);
+		dspriv->image->data = NULL;
+		TSXDestroyImage(dspriv->image);
+	    }
+	} else {
+	    dspriv->image->data = NULL;
+
+#ifdef HAVE_LIBXXSHM
+	    if (ddpriv->xshm_active) {
+		TSXShmDetach(display, &(dspriv->shminfo));
+		TSXDestroyImage(dspriv->image);
+		shmdt(dspriv->shminfo.shmaddr);
+	    } else
+#endif
+	    {
+		HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
+		TSXDestroyImage(dspriv->image);
+	    }
+	}
+	dspriv->image = 0;
+    } else
+	HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
+
+    if (This->s.palette)
+	IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
+
+    /* Free the DIBSection (if any) */
+    if (This->s.hdc != 0) {
+	SelectObject(This->s.hdc, This->s.holdbitmap);
+	DeleteDC(This->s.hdc);
+	DeleteObject(This->s.DIBsection);
+    }
+
+    /* Free the clipper if present */
+    if(This->s.lpClipper)
+	IDirectDrawClipper_Release(This->s.lpClipper);
+    HeapFree(GetProcessHeap(),0,This);
+    return S_OK;
+}
+
+ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    Xlib_IDirectDrawSurface4Impl_QueryInterface,
+    IDirectDrawSurface4Impl_AddRef,
+    Xlib_IDirectDrawSurface4Impl_Release,
+    IDirectDrawSurface4Impl_AddAttachedSurface,
+    IDirectDrawSurface4Impl_AddOverlayDirtyRect,
+    IDirectDrawSurface4Impl_Blt,
+    IDirectDrawSurface4Impl_BltBatch,
+    IDirectDrawSurface4Impl_BltFast,
+    IDirectDrawSurface4Impl_DeleteAttachedSurface,
+    IDirectDrawSurface4Impl_EnumAttachedSurfaces,
+    IDirectDrawSurface4Impl_EnumOverlayZOrders,
+    Xlib_IDirectDrawSurface4Impl_Flip,
+    IDirectDrawSurface4Impl_GetAttachedSurface,
+    IDirectDrawSurface4Impl_GetBltStatus,
+    IDirectDrawSurface4Impl_GetCaps,
+    IDirectDrawSurface4Impl_GetClipper,
+    IDirectDrawSurface4Impl_GetColorKey,
+    IDirectDrawSurface4Impl_GetDC,
+    IDirectDrawSurface4Impl_GetFlipStatus,
+    IDirectDrawSurface4Impl_GetOverlayPosition,
+    IDirectDrawSurface4Impl_GetPalette,
+    IDirectDrawSurface4Impl_GetPixelFormat,
+    IDirectDrawSurface4Impl_GetSurfaceDesc,
+    IDirectDrawSurface4Impl_Initialize,
+    IDirectDrawSurface4Impl_IsLost,
+    Xlib_IDirectDrawSurface4Impl_Lock,
+    IDirectDrawSurface4Impl_ReleaseDC,
+    IDirectDrawSurface4Impl_Restore,
+    IDirectDrawSurface4Impl_SetClipper,
+    IDirectDrawSurface4Impl_SetColorKey,
+    IDirectDrawSurface4Impl_SetOverlayPosition,
+    Xlib_IDirectDrawSurface4Impl_SetPalette,
+    Xlib_IDirectDrawSurface4Impl_Unlock,
+    IDirectDrawSurface4Impl_UpdateOverlay,
+    IDirectDrawSurface4Impl_UpdateOverlayDisplay,
+    IDirectDrawSurface4Impl_UpdateOverlayZOrder,
+    IDirectDrawSurface4Impl_GetDDInterface,
+    IDirectDrawSurface4Impl_PageLock,
+    IDirectDrawSurface4Impl_PageUnlock,
+    IDirectDrawSurface4Impl_SetSurfaceDesc,
+    IDirectDrawSurface4Impl_SetPrivateData,
+    IDirectDrawSurface4Impl_GetPrivateData,
+    IDirectDrawSurface4Impl_FreePrivateData,
+    IDirectDrawSurface4Impl_GetUniquenessValue,
+    IDirectDrawSurface4Impl_ChangeUniquenessValue
+};
diff --git a/dlls/ddraw/helper.c b/dlls/ddraw/helper.c
new file mode 100644
index 0000000..366af36
--- /dev/null
+++ b/dlls/ddraw/helper.c
@@ -0,0 +1,343 @@
+
+/*		DirectDraw Base Functions
+ *
+ * Copyright 1997-1999 Marcus Meissner
+ * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "winerror.h"
+#include "gdi.h"
+#include "heap.h"
+#include "dc.h"
+#include "win.h"
+#include "wine/exception.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debugtools.h"
+#include "spy.h"
+#include "message.h"
+#include "options.h"
+#include "monitor.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+/******************************************************************************
+ *		debug output functions
+ */
+void _dump_DDBLTFX(DWORD flagmask) {
+    int	i;
+    const struct {
+	DWORD	mask;
+	char	*name;
+    } flags[] = {
+#define FE(x) { x, #x},
+	FE(DDBLTFX_ARITHSTRETCHY)
+	FE(DDBLTFX_MIRRORLEFTRIGHT)
+	FE(DDBLTFX_MIRRORUPDOWN)
+	FE(DDBLTFX_NOTEARING)
+	FE(DDBLTFX_ROTATE180)
+	FE(DDBLTFX_ROTATE270)
+	FE(DDBLTFX_ROTATE90)
+	FE(DDBLTFX_ZBUFFERRANGE)
+	FE(DDBLTFX_ZBUFFERBASEDEST)
+#undef FE
+    };
+    for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+	if (flags[i].mask & flagmask)
+	    DPRINTF("%s ",flags[i].name);
+    DPRINTF("\n");
+}
+
+void _dump_DDBLTFAST(DWORD flagmask) {
+    int	i;
+    const struct {
+	DWORD	mask;
+	char	*name;
+    } flags[] = {
+#define FE(x) { x, #x},
+	FE(DDBLTFAST_NOCOLORKEY)
+	FE(DDBLTFAST_SRCCOLORKEY)
+	FE(DDBLTFAST_DESTCOLORKEY)
+	FE(DDBLTFAST_WAIT)
+#undef FE
+    };
+    for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+	if (flags[i].mask & flagmask)
+	    DPRINTF("%s ",flags[i].name);
+    DPRINTF("\n");
+}
+
+void _dump_DDBLT(DWORD flagmask) {
+    int	i;
+    const struct {
+	DWORD	mask;
+	char	*name;
+    } flags[] = {
+#define FE(x) { x, #x},
+	FE(DDBLT_ALPHADEST)
+	FE(DDBLT_ALPHADESTCONSTOVERRIDE)
+	FE(DDBLT_ALPHADESTNEG)
+	FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
+	FE(DDBLT_ALPHAEDGEBLEND)
+	FE(DDBLT_ALPHASRC)
+	FE(DDBLT_ALPHASRCCONSTOVERRIDE)
+	FE(DDBLT_ALPHASRCNEG)
+	FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
+	FE(DDBLT_ASYNC)
+	FE(DDBLT_COLORFILL)
+	FE(DDBLT_DDFX)
+	FE(DDBLT_DDROPS)
+	FE(DDBLT_KEYDEST)
+	FE(DDBLT_KEYDESTOVERRIDE)
+	FE(DDBLT_KEYSRC)
+	FE(DDBLT_KEYSRCOVERRIDE)
+	FE(DDBLT_ROP)
+	FE(DDBLT_ROTATIONANGLE)
+	FE(DDBLT_ZBUFFER)
+	FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
+	FE(DDBLT_ZBUFFERDESTOVERRIDE)
+	FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
+	FE(DDBLT_ZBUFFERSRCOVERRIDE)
+	FE(DDBLT_WAIT)
+	FE(DDBLT_DEPTHFILL)
+#undef FE
+    };
+    for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+	if (flags[i].mask & flagmask)
+	    DPRINTF("%s ",flags[i].name);
+    DPRINTF("\n");
+}
+
+void _dump_DDSCAPS(void *in) {
+    int	i;
+    const struct {
+	DWORD	mask;
+	char	*name;
+    } flags[] = {
+#define FE(x) { x, #x},
+	FE(DDSCAPS_RESERVED1)
+	FE(DDSCAPS_ALPHA)
+	FE(DDSCAPS_BACKBUFFER)
+	FE(DDSCAPS_COMPLEX)
+	FE(DDSCAPS_FLIP)
+	FE(DDSCAPS_FRONTBUFFER)
+	FE(DDSCAPS_OFFSCREENPLAIN)
+	FE(DDSCAPS_OVERLAY)
+	FE(DDSCAPS_PALETTE)
+	FE(DDSCAPS_PRIMARYSURFACE)
+	FE(DDSCAPS_PRIMARYSURFACELEFT)
+	FE(DDSCAPS_SYSTEMMEMORY)
+	FE(DDSCAPS_TEXTURE)
+	FE(DDSCAPS_3DDEVICE)
+	FE(DDSCAPS_VIDEOMEMORY)
+	FE(DDSCAPS_VISIBLE)
+	FE(DDSCAPS_WRITEONLY)
+	FE(DDSCAPS_ZBUFFER)
+	FE(DDSCAPS_OWNDC)
+	FE(DDSCAPS_LIVEVIDEO)
+	FE(DDSCAPS_HWCODEC)
+	FE(DDSCAPS_MODEX)
+	FE(DDSCAPS_MIPMAP)
+	FE(DDSCAPS_RESERVED2)
+	FE(DDSCAPS_ALLOCONLOAD)
+	FE(DDSCAPS_VIDEOPORT)
+	FE(DDSCAPS_LOCALVIDMEM)
+	FE(DDSCAPS_NONLOCALVIDMEM)
+	FE(DDSCAPS_STANDARDVGAMODE)
+	FE(DDSCAPS_OPTIMIZED)
+#undef FE
+    };
+    DWORD flagmask = *((DWORD *) in);
+    for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+	if (flags[i].mask & flagmask)
+	    DPRINTF("%s ",flags[i].name);
+}
+
+void _dump_pixelformat_flag(DWORD flagmask) {
+    int	i;
+    const struct {
+	DWORD	mask;
+	char	*name;
+    } flags[] = {
+#define FE(x) { x, #x},
+	FE(DDPF_ALPHAPIXELS)
+	FE(DDPF_ALPHA)
+	FE(DDPF_FOURCC)
+	FE(DDPF_PALETTEINDEXED4)
+	FE(DDPF_PALETTEINDEXEDTO8)
+	FE(DDPF_PALETTEINDEXED8)
+	FE(DDPF_RGB)
+	FE(DDPF_COMPRESSED)
+	FE(DDPF_RGBTOYUV)
+	FE(DDPF_YUV)
+	FE(DDPF_ZBUFFER)
+	FE(DDPF_PALETTEINDEXED1)
+	FE(DDPF_PALETTEINDEXED2)
+	FE(DDPF_ZPIXELS)
+#undef FE
+    };
+    for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+	if (flags[i].mask & flagmask)
+	    DPRINTF("%s ",flags[i].name);
+}
+
+void _dump_paletteformat(DWORD dwFlags) {
+    int	i;
+    const struct {
+	DWORD	mask;
+	char	*name;
+    } flags[] = {
+#define FE(x) { x, #x},
+	FE(DDPCAPS_4BIT)
+	FE(DDPCAPS_8BITENTRIES)
+	FE(DDPCAPS_8BIT)
+	FE(DDPCAPS_INITIALIZE)
+	FE(DDPCAPS_PRIMARYSURFACE)
+	FE(DDPCAPS_PRIMARYSURFACELEFT)
+	FE(DDPCAPS_ALLOW256)
+	FE(DDPCAPS_VSYNC)
+	FE(DDPCAPS_1BIT)
+	FE(DDPCAPS_2BIT)
+	FE(DDPCAPS_ALPHA)
+#undef FE
+    };
+    for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+	if (flags[i].mask & dwFlags)
+	    DPRINTF("%s ",flags[i].name);
+    DPRINTF("\n");
+}
+
+void _dump_pixelformat(void *in) {
+    LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
+
+    DPRINTF("( ");
+    _dump_pixelformat_flag(pf->dwFlags);
+    if (pf->dwFlags & DDPF_FOURCC)
+	DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
+    if (pf->dwFlags & DDPF_RGB) {
+	char *cmd;
+	DPRINTF(", RGB bits: %ld, ", pf->u.dwRGBBitCount);
+	switch (pf->u.dwRGBBitCount) {
+	case 4: cmd = "%1lx"; break;
+	case 8: cmd = "%02lx"; break;
+	case 16: cmd = "%04lx"; break;
+	case 24: cmd = "%06lx"; break;
+	case 32: cmd = "%08lx"; break;
+	default: ERR("Unexpected bit depth !\n"); cmd = "%d"; break;
+	}
+	DPRINTF(" R "); DPRINTF(cmd, pf->u1.dwRBitMask);
+	DPRINTF(" G "); DPRINTF(cmd, pf->u2.dwGBitMask);
+	DPRINTF(" B "); DPRINTF(cmd, pf->u3.dwBBitMask);
+	if (pf->dwFlags & DDPF_ALPHAPIXELS)
+	    DPRINTF(" A "); DPRINTF(cmd, pf->u4.dwRGBAlphaBitMask);
+	if (pf->dwFlags & DDPF_ZPIXELS)
+	    DPRINTF(" Z "); DPRINTF(cmd, pf->u4.dwRGBZBitMask);
+    }
+    if (pf->dwFlags & DDPF_ZBUFFER)
+	DPRINTF(", Z bits : %ld", pf->u.dwZBufferBitDepth);
+    if (pf->dwFlags & DDPF_ALPHA)
+	DPRINTF(", Alpha bits : %ld", pf->u.dwAlphaBitDepth);
+    DPRINTF(")");
+}
+
+void _dump_colorkeyflag(DWORD ck) {
+    int	i;
+    const struct {
+	DWORD	mask;
+	char	*name;
+    } flags[] = {
+#define FE(x) { x, #x},
+	FE(DDCKEY_COLORSPACE)
+	FE(DDCKEY_DESTBLT)
+	FE(DDCKEY_DESTOVERLAY)
+	FE(DDCKEY_SRCBLT)
+	FE(DDCKEY_SRCOVERLAY)
+#undef FE
+    };
+    for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+	if (flags[i].mask & ck)
+	    DPRINTF("%s ",flags[i].name);
+}
+
+static void _dump_DWORD(void *in) {
+    DPRINTF("%ld", *((DWORD *) in));
+}
+static void _dump_PTR(void *in) {
+    DPRINTF("%p", *((void **) in));
+}
+void _dump_DDCOLORKEY(void *in) {
+    DDCOLORKEY *ddck = (DDCOLORKEY *) in;
+
+    DPRINTF(" Low : %ld  - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
+}
+
+void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
+    int	i;
+    struct {
+	DWORD	mask;
+	char	*name;
+	void (*func)(void *);
+	void	*elt;
+    } flags[16], *fe = flags;
+#define FE(x,f,e) do { fe->mask = x;  fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
+	FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps);
+	FE(DDSD_HEIGHT, _dump_DWORD, dwHeight);
+	FE(DDSD_WIDTH, _dump_DWORD, dwWidth);
+	FE(DDSD_PITCH, _dump_DWORD, lPitch);
+	FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount);
+	FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, u.dwZBufferBitDepth);
+	FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth);
+	FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat);
+	FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay);
+	FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt);
+	FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay);
+	FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt);
+	FE(DDSD_MIPMAPCOUNT, _dump_DWORD, u.dwMipMapCount);
+	FE(DDSD_REFRESHRATE, _dump_DWORD, u.dwRefreshRate);
+	FE(DDSD_LINEARSIZE, _dump_DWORD, u1.dwLinearSize);
+	FE(DDSD_LPSURFACE, _dump_PTR, u1.lpSurface);
+#undef FE
+
+    for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+	if (flags[i].mask & lpddsd->dwFlags) {
+	    DPRINTF(" - %s : ",flags[i].name);
+	    flags[i].func(flags[i].elt);
+	    DPRINTF("\n");  
+	}
+}
+void _dump_cooperativelevel(DWORD cooplevel) {
+    int i;
+    const struct {
+	int	mask;
+	char	*name;
+    } flags[] = {
+#define FE(x) { x, #x},
+	    FE(DDSCL_FULLSCREEN)
+	    FE(DDSCL_ALLOWREBOOT)
+	    FE(DDSCL_NOWINDOWCHANGES)
+	    FE(DDSCL_NORMAL)
+	    FE(DDSCL_ALLOWMODEX)
+	    FE(DDSCL_EXCLUSIVE)
+	    FE(DDSCL_SETFOCUSWINDOW)
+	    FE(DDSCL_SETDEVICEWINDOW)
+	    FE(DDSCL_CREATEDEVICEWINDOW)
+#undef FE
+    };
+
+    if (TRACE_ON(ddraw)) {
+	DPRINTF(" - ");
+	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+	    if (flags[i].mask & cooplevel)
+		DPRINTF("%s ",flags[i].name);
+	DPRINTF("\n");
+    }
+}
diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c
new file mode 100644
index 0000000..5f8269b
--- /dev/null
+++ b/dlls/ddraw/main.c
@@ -0,0 +1,424 @@
+/*		DirectDraw Base Functions
+ *
+ * Copyright 1997-1999 Marcus Meissner
+ * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "winerror.h"
+#include "heap.h"
+#include "dc.h"
+#include "win.h"
+#include "wine/exception.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debugtools.h"
+#include "message.h"
+#include "monitor.h"
+
+/* This for all the enumeration and creation of D3D-related objects */
+#include "ddraw_private.h"
+
+#define MAX_DDRAW_DRIVERS	3
+static ddraw_driver * ddraw_drivers[MAX_DDRAW_DRIVERS];
+static int nrof_ddraw_drivers			= 0;
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+/* register a direct draw driver. We better not use malloc for we are in 
+ * the ELF startup initialisation at this point.
+ */
+void ddraw_register_driver(ddraw_driver *driver) {
+    ddraw_drivers[nrof_ddraw_drivers++] = driver;
+
+    /* increase MAX_DDRAW_DRIVERS if the line below triggers */
+    assert(nrof_ddraw_drivers <= MAX_DDRAW_DRIVERS);
+}
+
+/**********************************************************************/
+
+typedef struct {
+    LPVOID lpCallback;
+    LPVOID lpContext; 
+} DirectDrawEnumerateProcData;
+
+/***********************************************************************
+ *		DirectDrawEnumerateExA (DDRAW.*)
+ */
+HRESULT WINAPI DirectDrawEnumerateExA(
+    LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
+{
+    int i;
+    TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
+
+    if (TRACE_ON(ddraw)) {
+	DPRINTF("  Flags : ");
+	if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
+	    DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
+	if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
+	    DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
+	if (dwFlags & DDENUM_NONDISPLAYDEVICES)
+	    DPRINTF("DDENUM_NONDISPLAYDEVICES ");
+	DPRINTF("\n");
+    }
+
+    if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
+	FIXME("no non-display devices supported.\n");
+	return DD_OK;
+    }
+/* Hmm. Leave this out.
+    if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES) {
+	FIXME("no attached secondary devices supported.\n");
+	return DD_OK;
+    }
+ */
+    if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES) {
+	FIXME("no detached secondary devices supported.\n");
+	return DD_OK;
+    }
+
+    for (i=0;i<MAX_DDRAW_DRIVERS;i++) {
+	if (!ddraw_drivers[i])
+	    continue;
+	if (ddraw_drivers[i]->createDDRAW(NULL)) /* !0 is failing */
+	    continue;
+        TRACE("Enumerating %s/%s interface\n",ddraw_drivers[i]->name,ddraw_drivers[i]->type);
+	if (!lpCallback(
+	    ddraw_drivers[i]->guid,
+	    (LPSTR)ddraw_drivers[i]->name,
+	    (LPSTR)ddraw_drivers[i]->type,
+	    lpContext,
+	    0		/* FIXME: flags not supported here */
+	))
+	    return DD_OK;
+    }
+    if (nrof_ddraw_drivers) {
+	TRACE("Enumerating the default interface\n");
+	if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
+	    return DD_OK;
+    }
+    return DD_OK;
+}
+
+/***********************************************************************
+ *		DirectDrawEnumerateExW (DDRAW.*)
+ */
+
+static BOOL CALLBACK DirectDrawEnumerateExProcW(
+    GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, 
+    LPVOID lpContext, HMONITOR hm)
+{
+    DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;
+    LPWSTR lpDriverDescriptionW =
+	HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
+    LPWSTR lpDriverNameW =
+	HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
+
+    BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
+	lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
+
+    HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
+    HeapFree(GetProcessHeap(), 0, lpDriverNameW);
+    return bResult;
+}
+
+/**********************************************************************/
+
+HRESULT WINAPI DirectDrawEnumerateExW(
+  LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
+{
+    DirectDrawEnumerateProcData epd;
+    epd.lpCallback = (LPVOID) lpCallback;
+    epd.lpContext = lpContext;
+
+    return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW, (LPVOID) &epd, 0);
+}
+
+/***********************************************************************
+ *		DirectDrawEnumerateA (DDRAW.*)
+ */
+
+static BOOL CALLBACK DirectDrawEnumerateProcA(
+	GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, 
+	LPVOID lpContext, HMONITOR hm)
+{
+    DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;
+
+    return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
+	lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
+}
+
+/**********************************************************************/
+
+HRESULT WINAPI DirectDrawEnumerateA(
+  LPDDENUMCALLBACKA lpCallback, LPVOID lpContext) 
+{
+    DirectDrawEnumerateProcData epd;  
+    epd.lpCallback = (LPVOID) lpCallback;
+    epd.lpContext = lpContext;
+
+    return DirectDrawEnumerateExA(DirectDrawEnumerateProcA, (LPVOID) &epd, 0);
+}
+
+/***********************************************************************
+ *		DirectDrawEnumerateW (DDRAW.*)
+ */
+
+static BOOL WINAPI DirectDrawEnumerateProcW(
+  GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName, 
+  LPVOID lpContext, HMONITOR hm)
+{
+    DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;
+  
+    return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
+	lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
+}
+
+/**********************************************************************/
+
+HRESULT WINAPI DirectDrawEnumerateW(
+  LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) 
+{
+    DirectDrawEnumerateProcData epd;
+    epd.lpCallback = (LPVOID) lpCallback;
+    epd.lpContext = lpContext;
+
+    return DirectDrawEnumerateExW(DirectDrawEnumerateProcW, (LPVOID) &epd, 0);
+}
+
+/******************************************************************************
+ * 				DirectDraw Window Procedure
+ */
+static LRESULT WINAPI DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+    LRESULT ret;
+    IDirectDrawImpl* ddraw = NULL;
+    DWORD lastError;
+
+    /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
+
+    SetLastError( ERROR_SUCCESS );
+    ddraw  = (IDirectDrawImpl*)GetPropA( hwnd, ddProp );
+    if( (!ddraw)  && ( ( lastError = GetLastError() ) != ERROR_SUCCESS )) 
+	ERR("Unable to retrieve this ptr from window. Error %08lx\n",lastError);
+
+    if( ddraw ) {
+    /* Perform any special direct draw functions */
+	if (msg==WM_PAINT)
+	    ddraw->d.paintable = 1;
+
+	/* Now let the application deal with the rest of this */
+	if( ddraw->d.mainWindow ) {
+
+	    /* Don't think that we actually need to call this but... 
+	     * might as well be on the safe side of things...
+	     */
+
+	    /* I changed hwnd to ddraw->d.mainWindow as I did not see why
+	     * it should be the procedures of our fake window that gets called
+	     * instead of those of the window provided by the application.
+	     * And with this patch, mouse clicks work with Monkey Island III
+	     * - Lionel
+	     */
+	    ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
+
+	    if( !ret ) {
+		WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
+		/* We didn't handle the message - give it to the application */
+		if (ddraw && ddraw->d.mainWindow && tmpWnd)
+		    ret = CallWindowProcA(tmpWnd->winproc,
+		ddraw->d.mainWindow, msg, wParam, lParam );
+		WIN_ReleaseWndPtr(tmpWnd);
+	    }
+	    return ret;
+	} /* else FALLTHROUGH */
+    } /* else FALLTHROUGH */
+    return DefWindowProcA(hwnd,msg,wParam,lParam);
+}
+
+HRESULT WINAPI DirectDrawCreate(
+	LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter
+) {
+    IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
+    WNDCLASSA	wc;
+    HRESULT	ret = 0;
+    int		i,drvindex=0;
+
+    struct ddraw_driver	*ddd = NULL;
+
+    if (!HIWORD(lpGUID)) lpGUID = NULL;
+
+    TRACE("(%s,%p,%p)\n",debugstr_guid(lpGUID),ilplpDD,pUnkOuter);
+
+    while (1) {
+	ddd = NULL;
+	if ( ( !lpGUID ) ||
+	     ( IsEqualGUID( &IID_IDirectDraw,  lpGUID ) ) ||
+	     ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
+	     ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) )
+	) {
+	    /* choose an interface out of the list */
+	    for (i=0;i<nrof_ddraw_drivers;i++) {
+		ddraw_driver *xddd = ddraw_drivers[i];
+		if (!xddd)
+		    continue;
+		if (!ddd || (ddd->preference<xddd->preference)) {
+		    drvindex = i;
+		    ddd = xddd;
+		}
+	    }
+	} else {
+	    for (i=0;i<nrof_ddraw_drivers;i++) {
+		if (!ddraw_drivers[i])
+		    continue;
+		if (IsEqualGUID(ddraw_drivers[i]->guid,lpGUID)) {
+		    drvindex = i;
+		    ddd = ddraw_drivers[i];
+		    break;
+		}
+	    }
+	}
+	if (!ddd) {
+	    if (!nrof_ddraw_drivers) {
+		ERR("DirectDrawCreate(%s,%p,%p): no DirectDraw drivers compiled in.\n",debugstr_guid(lpGUID),lplpDD,pUnkOuter);
+		return DDERR_NODIRECTDRAWHW;
+	    }
+	    ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID.\n",debugstr_guid(lpGUID),lplpDD,pUnkOuter);
+	    return DDERR_INVALIDDIRECTDRAWGUID;
+	}
+	TRACE("using \"%s\" driver, calling %p\n",ddd->name,ddd->createDDRAW);
+
+	ret = ddd->createDDRAW(lplpDD);
+	if (!ret)
+	    break;
+	ddraw_drivers[drvindex] = NULL; /* mark this one as unusable */
+    }
+    wc.style		= CS_GLOBALCLASS;
+    wc.lpfnWndProc	= DDWndProc;
+    wc.cbClsExtra	= 0;
+    wc.cbWndExtra	= 0;
+
+    /* We can be a child of the desktop since we're really important */
+    wc.hInstance= 0; 
+    wc.hIcon	= 0;
+    wc.hCursor	= (HCURSOR)IDC_ARROWA;
+    wc.hbrBackground	= NULL_BRUSH;
+    wc.lpszMenuName 	= 0;
+    wc.lpszClassName	= "WINE_DirectDraw";
+    (*ilplpDD)->d.winclass = RegisterClassA(&wc);
+    return ret;
+}
+
+/*******************************************************************************
+ * DirectDraw ClassFactory
+ *
+ *  Heavily inspired (well, can you say completely copied :-) ) from DirectSound
+ *
+ */
+typedef struct {
+    /* IUnknown fields */
+    ICOM_VFIELD(IClassFactory);
+    DWORD		ref;
+} IClassFactoryImpl;
+
+static HRESULT WINAPI 
+DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
+    ICOM_THIS(IClassFactoryImpl,iface);
+
+    FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI
+DDCF_AddRef(LPCLASSFACTORY iface) {
+    ICOM_THIS(IClassFactoryImpl,iface);
+    return ++(This->ref);
+}
+
+static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
+    ICOM_THIS(IClassFactoryImpl,iface);
+    /* static class, won't be  freed */
+    return --(This->ref);
+}
+
+static HRESULT WINAPI DDCF_CreateInstance(
+	LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
+) {
+    ICOM_THIS(IClassFactoryImpl,iface);
+
+    TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
+    if ( ( IsEqualGUID( &IID_IDirectDraw,  riid ) ) ||
+	 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
+	 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
+	    /* FIXME: reuse already created DirectDraw if present? */
+	    return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
+    }
+    return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
+    ICOM_THIS(IClassFactoryImpl,iface);
+    FIXME("(%p)->(%d),stub!\n",This,dolock);
+    return S_OK;
+}
+
+static ICOM_VTABLE(IClassFactory) DDCF_Vtbl = 
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    DDCF_QueryInterface,
+    DDCF_AddRef,
+    DDCF_Release,
+    DDCF_CreateInstance,
+    DDCF_LockServer
+};
+static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
+
+/*******************************************************************************
+ * DllGetClassObject [DDRAW.13]
+ * Retrieves class object from a DLL object
+ *
+ * NOTES
+ *    Docs say returns STDAPI
+ *
+ * PARAMS
+ *    rclsid [I] CLSID for the class object
+ *    riid   [I] Reference to identifier of interface for class object
+ *    ppv    [O] Address of variable to receive interface pointer for riid
+ *
+ * RETURNS
+ *    Success: S_OK
+ *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
+ *             E_UNEXPECTED
+ */
+DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
+{
+    TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+    if ( IsEqualGUID( &IID_IClassFactory, riid ) ) {
+    	*ppv = (LPVOID)&DDRAW_CF;
+	IClassFactory_AddRef((IClassFactory*)*ppv);
+	return S_OK;
+    }
+    FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+    return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+
+/*******************************************************************************
+ * DllCanUnloadNow [DDRAW.12]  Determines whether the DLL is in use.
+ *
+ * RETURNS
+ *    Success: S_OK
+ *    Failure: S_FALSE
+ */
+DWORD WINAPI DDRAW_DllCanUnloadNow(void) {
+    FIXME("(void): stub\n");
+    return S_FALSE;
+}
diff --git a/dlls/ddraw/mesa.c b/dlls/ddraw/mesa.c
new file mode 100644
index 0000000..aa8b782
--- /dev/null
+++ b/dlls/ddraw/mesa.c
@@ -0,0 +1,252 @@
+/* Direct3D Common functions
+   (c) 1998 Lionel ULMER
+   
+   This file contains all MESA common code */
+
+#include "windef.h"
+#include "wine/obj_base.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debugtools.h"
+
+#include "mesa_private.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw)
+    
+#define D3DTPRIVATE(x) mesa_d3dt_private *dtpriv = (mesa_d3dt_private*)(x)->private
+
+void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
+		      DWORD dwRenderState, RenderState *rs)
+{
+
+  if (TRACE_ON(ddraw))
+    _dump_renderstate(dwRenderStateType, dwRenderState);
+
+  /* First, all the stipple patterns */
+  if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) && 
+      (dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) {
+    ERR("Unhandled dwRenderStateType stipple %d!\n",dwRenderStateType);
+  } else {
+    ENTER_GL();
+    
+    /* All others state variables */
+    switch (dwRenderStateType) {
+
+    case D3DRENDERSTATE_TEXTUREHANDLE: {    /*  1 */
+      IDirect3DTexture2Impl* tex = (IDirect3DTexture2Impl*) dwRenderState;
+      D3DTPRIVATE(tex);
+      
+      if (tex == NULL) {
+	glBindTexture(GL_TEXTURE_2D, 0);
+	glDisable(GL_TEXTURE_2D);
+      } else {
+	TRACE("setting OpenGL texture handle : %d\n", dtpriv->tex_name);
+	glEnable(GL_TEXTURE_2D);
+	/* Default parameters */
+	glBindTexture(GL_TEXTURE_2D, dtpriv->tex_name);
+	/* To prevent state change, we could test here what are the parameters
+	   stored in the texture */
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, rs->mag);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, rs->min);
+      }
+    } break;
+
+    case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */
+      if (dwRenderState)
+	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+      else
+	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+      break;
+      
+    case D3DRENDERSTATE_ZENABLE:          /*  7 */
+      if (dwRenderState)
+	glEnable(GL_DEPTH_TEST);
+      else
+	glDisable(GL_DEPTH_TEST);
+      break;
+      
+    case D3DRENDERSTATE_FILLMODE:           /*  8 */
+      switch ((D3DFILLMODE) dwRenderState) {
+      case D3DFILL_SOLID:
+	break;
+
+      default:
+	ERR("Unhandled fill mode !\n");
+      }
+      break;
+
+    case D3DRENDERSTATE_SHADEMODE:          /*  9 */
+      switch ((D3DSHADEMODE) dwRenderState) {
+      case D3DSHADE_FLAT:
+	glShadeModel(GL_FLAT);
+	break;
+
+      case D3DSHADE_GOURAUD:
+	glShadeModel(GL_SMOOTH);
+	break;
+
+      default:
+	ERR("Unhandled shade mode !\n");
+      }
+      break;
+      
+    case D3DRENDERSTATE_ZWRITEENABLE:     /* 14 */
+      if (dwRenderState)
+	glDepthMask(GL_TRUE);
+      else
+	glDepthMask(GL_FALSE);
+      break;
+      
+    case D3DRENDERSTATE_TEXTUREMAG:         /* 17 */
+      switch ((D3DTEXTUREFILTER) dwRenderState) {
+      case D3DFILTER_NEAREST:
+	rs->mag = GL_NEAREST;
+	break;
+	
+      case D3DFILTER_LINEAR:
+	rs->mag = GL_LINEAR;
+	break;
+	
+      default:
+	ERR("Unhandled texture mag !\n");
+      }
+      break;
+
+    case D3DRENDERSTATE_TEXTUREMIN:         /* 18 */
+      switch ((D3DTEXTUREFILTER) dwRenderState) {
+      case D3DFILTER_NEAREST:
+	rs->min = GL_NEAREST;
+	break;
+	
+      case D3DFILTER_LINEAR:
+	rs->mag = GL_LINEAR;
+	break;
+	
+      default:
+	ERR("Unhandled texture min !\n");
+      }
+      break;
+      
+    case D3DRENDERSTATE_SRCBLEND:           /* 19 */
+      switch ((D3DBLEND) dwRenderState) {
+      case D3DBLEND_SRCALPHA:
+	rs->src = GL_SRC_ALPHA;
+	break;
+
+      default:
+	ERR("Unhandled blend mode !\n");
+      }
+      
+      glBlendFunc(rs->src, rs->dst);
+      break;
+      
+    case D3DRENDERSTATE_DESTBLEND:          /* 20 */
+      switch ((D3DBLEND) dwRenderState) {
+      case D3DBLEND_INVSRCALPHA:
+	rs->dst = GL_ONE_MINUS_SRC_ALPHA;
+	break;
+	
+      default:
+	ERR("Unhandled blend mode !\n");
+      }
+      
+      glBlendFunc(rs->src, rs->dst);
+      break;
+
+    case D3DRENDERSTATE_TEXTUREMAPBLEND:    /* 21 */
+      switch ((D3DTEXTUREBLEND) dwRenderState) {
+      case D3DTBLEND_MODULATE:
+      case D3DTBLEND_MODULATEALPHA:
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+	break;
+
+      default:
+	ERR("Unhandled texture environment !\n");
+      }
+      break;
+      
+    case D3DRENDERSTATE_CULLMODE:           /* 22 */
+      switch ((D3DCULL) dwRenderState) {
+      case D3DCULL_NONE:
+	glDisable(GL_CULL_FACE);
+	break;
+	
+      case D3DCULL_CW:
+	glEnable(GL_CULL_FACE);
+	glFrontFace(GL_CW);
+	break;
+	
+      case D3DCULL_CCW:
+	glEnable(GL_CULL_FACE);
+	glFrontFace(GL_CCW);
+	break;
+	
+      default:
+	ERR("Unhandled cull mode !\n");
+      }
+      break;
+      
+    case D3DRENDERSTATE_ZFUNC:            /* 23 */
+      switch ((D3DCMPFUNC) dwRenderState) {
+      case D3DCMP_NEVER:
+	glDepthFunc(GL_NEVER);
+	break;
+      case D3DCMP_LESS:
+	glDepthFunc(GL_LESS);
+	break;
+      case D3DCMP_EQUAL:
+	glDepthFunc(GL_EQUAL);
+	break;
+      case D3DCMP_LESSEQUAL:
+	glDepthFunc(GL_LEQUAL);
+	break;
+      case D3DCMP_GREATER:
+	glDepthFunc(GL_GREATER);
+	break;
+      case D3DCMP_NOTEQUAL:
+	glDepthFunc(GL_NOTEQUAL);
+	break;
+      case D3DCMP_GREATEREQUAL:
+	glDepthFunc(GL_GEQUAL);
+	break;
+      case D3DCMP_ALWAYS:
+	glDepthFunc(GL_ALWAYS);
+	break;
+
+      default:
+	ERR("Unexpected value\n");
+      }
+      break;
+      
+    case D3DRENDERSTATE_DITHERENABLE:     /* 26 */
+      if (dwRenderState)
+	glEnable(GL_DITHER);
+      else
+	glDisable(GL_DITHER);
+      break;
+      
+    case D3DRENDERSTATE_ALPHABLENDENABLE:   /* 27 */
+      if (dwRenderState)
+	glEnable(GL_BLEND);
+      else
+	glDisable(GL_BLEND);
+      break;
+
+    case D3DRENDERSTATE_COLORKEYENABLE:     /* 41 */
+      if (dwRenderState)
+	glEnable(GL_BLEND);
+      else
+	glDisable(GL_BLEND);
+      break;
+
+    case D3DRENDERSTATE_FLUSHBATCH:         /* 50 */
+      break;
+      
+    default:
+      ERR("Unhandled dwRenderStateType %d!\n",dwRenderStateType);
+      break;
+    }
+
+    LEAVE_GL();
+  }
+}
diff --git a/dlls/ddraw/mesa_private.h b/dlls/ddraw/mesa_private.h
new file mode 100644
index 0000000..aa0fb82
--- /dev/null
+++ b/dlls/ddraw/mesa_private.h
@@ -0,0 +1,159 @@
+/* MESA private include file
+   (c) 1998 Lionel ULMER
+   
+   This files contains all the structure that are not exported
+   through d3d.h and all common macros. */
+
+#ifndef __GRAPHICS_WINE_MESA_PRIVATE_H
+#define __GRAPHICS_WINE_MESA_PRIVATE_H
+
+#include "d3d_private.h"
+
+#include "wine_gl.h"
+#include "x11drv.h"
+
+#undef USE_OSMESA
+
+#include "x11_private.h"
+
+/*****************************************************************************
+ * IDirect3DLight MESA private structure
+ */
+typedef struct mesa_d3dl_private
+{
+    GLenum              light_num;
+} mesa_d3dl_private;
+
+/*****************************************************************************
+ * IDirect3DTexture2 MESA private structure
+ */
+typedef struct mesa_d3dt_private
+{
+    GLuint                   tex_name;
+} mesa_d3dt_private;
+
+/*****************************************************************************
+ * IDirect3DViewport2 implementation structure
+ */
+typedef struct mesa_d3dv_private
+{
+    GLenum                      nextlight;
+} mesa_d3dv_private;
+
+#ifdef USE_OSMESA
+# define LEAVE_GL() ;
+# define ENTER_GL() ;
+#else
+# define LEAVE_GL() LeaveCriticalSection( &X11DRV_CritSection )
+# define ENTER_GL() EnterCriticalSection( &X11DRV_CritSection )
+#endif
+
+/* Matrix copy WITH transposition */
+#define conv_mat2(mat,gl_mat)			\
+{						\
+    TRACE("%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \
+    TRACE("%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \
+    TRACE("%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \
+    TRACE("%f %f %f %f\n", (mat)->_41, (mat)->_42, (mat)->_43, (mat)->_44); \
+    (gl_mat)[ 0] = (mat)->_11;			\
+    (gl_mat)[ 1] = (mat)->_21;			\
+    (gl_mat)[ 2] = (mat)->_31;			\
+    (gl_mat)[ 3] = (mat)->_41;			\
+    (gl_mat)[ 4] = (mat)->_12;			\
+    (gl_mat)[ 5] = (mat)->_22;			\
+    (gl_mat)[ 6] = (mat)->_32;			\
+    (gl_mat)[ 7] = (mat)->_42;			\
+    (gl_mat)[ 8] = (mat)->_13;			\
+    (gl_mat)[ 9] = (mat)->_23;			\
+    (gl_mat)[10] = (mat)->_33;			\
+    (gl_mat)[11] = (mat)->_43;			\
+    (gl_mat)[12] = (mat)->_14;			\
+    (gl_mat)[13] = (mat)->_24;			\
+    (gl_mat)[14] = (mat)->_34;			\
+    (gl_mat)[15] = (mat)->_44;			\
+};
+
+/* Matrix copy WITHOUT transposition */
+#define conv_mat(mat,gl_mat)			\
+{                                               \
+    TRACE("%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \
+    TRACE("%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \
+    TRACE("%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \
+    TRACE("%f %f %f %f\n", (mat)->_41, (mat)->_42, (mat)->_43, (mat)->_44); \
+    memcpy(gl_mat, (mat), 16 * sizeof(float));      \
+};
+
+typedef struct render_state {
+  /* This is used for the device mode */
+  GLenum src, dst;
+  /* This is used for textures */
+  GLenum mag, min;
+} RenderState;
+
+typedef struct mesa_d3dd_private {
+#ifdef USE_OSMESA
+    OSMesaContext ctx;
+    unsigned char *buffer;
+#else
+    GLXContext ctx;
+#endif
+
+    /* The current render state */
+    RenderState rs;
+
+    /* The last type of vertex drawn */
+    D3DVERTEXTYPE vt;
+
+    D3DMATRIX *world_mat;
+    D3DMATRIX *view_mat;
+    D3DMATRIX *proj_mat;
+} mesa_d3dd_private;
+
+#define _dump_colorvalue(s,v)               \
+    TRACE(" " s " : %f %f %f %f\n",           \
+	    (v).r.r, (v).g.g, (v).b.b, (v).a.a);
+
+/* Common functions defined in d3dcommon.c */
+void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
+		      DWORD dwRenderState, RenderState *rs) ;
+
+/* All non-static functions 'exported' by various sub-objects */
+extern LPDIRECT3DTEXTURE2 d3dtexture2_create(IDirectDrawSurface4Impl* surf);
+extern LPDIRECT3DTEXTURE d3dtexture_create(IDirectDrawSurface4Impl* surf);
+
+extern LPDIRECT3DLIGHT d3dlight_create_dx3(IDirect3DImpl* d3d1);
+extern LPDIRECT3DLIGHT d3dlight_create(IDirect3D2Impl* d3d2);
+
+extern LPDIRECT3DEXECUTEBUFFER d3dexecutebuffer_create(IDirect3DDeviceImpl* d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc);
+
+extern LPDIRECT3DMATERIAL d3dmaterial_create(IDirect3DImpl* d3d1);
+extern LPDIRECT3DMATERIAL2 d3dmaterial2_create(IDirect3D2Impl* d3d2);
+
+extern LPDIRECT3DVIEWPORT d3dviewport_create(IDirect3DImpl* d3d1);
+extern LPDIRECT3DVIEWPORT2 d3dviewport2_create(IDirect3D2Impl* d3d2);
+
+extern int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device);
+extern int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) ;
+extern int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) ;
+extern int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d);
+
+extern LPDIRECT3DTEXTURE2 mesa_d3dtexture2_create(IDirectDrawSurface4Impl*);
+extern LPDIRECT3DTEXTURE mesa_d3dtexture_create(IDirectDrawSurface4Impl*);
+
+static const WINE_UNUSED GUID IID_D3DDEVICE2_OpenGL = {
+  0x39a0da38,
+  0x7e57,
+  0x11d2,
+  { 0x8b,0x7c,0x0e,0x4e,0xd8,0x3c,0x2b,0x3c }
+};
+
+static const WINE_UNUSED GUID IID_D3DDEVICE_OpenGL = {
+  0x31416d44,
+  0x86ae,
+  0x11d2,
+  { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
+};
+
+extern ICOM_VTABLE(IDirect3D) mesa_d3dvt;
+extern ICOM_VTABLE(IDirect3D2) mesa_d3d2vt;
+#endif /* __GRAPHICS_WINE_MESA_PRIVATE_H */
diff --git a/dlls/ddraw/x11.c b/dlls/ddraw/x11.c
new file mode 100644
index 0000000..fd14a71
--- /dev/null
+++ b/dlls/ddraw/x11.c
@@ -0,0 +1,116 @@
+/*		DirectDraw using DGA or Xlib(XSHM)
+ *
+ * Copyright 1997-1999 Marcus Meissner
+ * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
+ */
+#include "config.h"
+
+#include <unistd.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "winerror.h"
+#include "options.h"
+#include "monitor.h"
+#include "debugtools.h"
+#include "ddraw.h"
+
+DEFAULT_DEBUG_CHANNEL(ddraw);
+
+#include "x11_private.h"
+
+#ifdef HAVE_LIBXXSHM
+int XShmErrorFlag = 0;
+#endif
+
+static inline BOOL get_option( const char *name, BOOL def ) {
+    return PROFILE_GetWineIniBool( "x11drv", name, def );
+}
+
+static BOOL
+DDRAW_XSHM_Available(void) {
+#ifdef HAVE_LIBXXSHM
+    if (get_option( "UseXShm", 1 )) {
+	if (TSXShmQueryExtension(display)) {
+	    int		major,minor;
+	    Bool	shpix;
+
+	    if (TSXShmQueryVersion(display, &major, &minor, &shpix))
+		return TRUE;
+	}
+    }
+#endif
+    return FALSE;
+}
+
+static HRESULT X11_Create( LPDIRECTDRAW *lplpDD ) {
+    IDirectDrawImpl*	ddraw;
+    int			depth;
+    x11_dd_private	*x11priv;
+
+    if (lplpDD == NULL) /* Testing ... this driver works all the time */
+	return DD_OK;
+
+    *lplpDD = (LPDIRECTDRAW)HeapAlloc(
+	GetProcessHeap(),
+	HEAP_ZERO_MEMORY,
+	sizeof(IDirectDrawImpl)
+    );
+    ddraw = (IDirectDrawImpl*)*lplpDD;
+    ICOM_VTBL(ddraw)= &xlib_ddvt;
+    ddraw->ref	= 1;
+    ddraw->private	= HeapAlloc(
+	GetProcessHeap(),
+	HEAP_ZERO_MEMORY,
+	sizeof(x11_dd_private)
+    );
+    x11priv = (x11_dd_private*)ddraw->private;
+
+    /* At DirectDraw creation, the depth is the default depth */
+    depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
+    _common_depth_to_pixelformat(depth,
+				 &(ddraw->d.directdraw_pixelformat),
+				 &(ddraw->d.screen_pixelformat),
+				 &(ddraw->d.pixmap_depth));
+    ddraw->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
+    ddraw->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
+#ifdef HAVE_LIBXXSHM
+    /* Test if XShm is available. */
+    if ((x11priv->xshm_active = DDRAW_XSHM_Available())) {
+	x11priv->xshm_compl = 0;
+	TRACE("Using XShm extension.\n");
+    }
+#endif
+    return DD_OK;
+}
+
+/* Where do these GUIDs come from?  mkuuid.
+ * They exist solely to distinguish between the targets Wine support,
+ * and should be different than any other GUIDs in existence.
+ */
+static GUID X11_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
+    0x1574a740,
+    0xdc61,
+    0x11d1,
+    {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
+};
+
+ddraw_driver x11_driver = {
+    &X11_DirectDraw_GUID,
+    "display",
+    "WINE X11 DirectDraw Driver",
+    50,
+    X11_Create
+}; 
+
+#ifdef __GNUC__
+static void X11_register(void) __attribute__((constructor));
+#else /* defined(__GNUC__) */
+static void __asm__dummy_dll_init(void) {
+    asm("\t.section .init ,\"ax\"\n"
+	        "\tcall X11_register\n"
+		    "\t.previous\n");
+#endif /* defined(__GNUC__) */
+static void X11_register(void) { ddraw_register_driver(&x11_driver); }
diff --git a/dlls/ddraw/x11_private.h b/dlls/ddraw/x11_private.h
new file mode 100644
index 0000000..c3093e6
--- /dev/null
+++ b/dlls/ddraw/x11_private.h
@@ -0,0 +1,58 @@
+#ifndef __WINE_DDRAW_X11_PRIVATE_H
+#define __WINE_DDRAW_X11_PRIVATE_H
+
+/* This file contains all X11 private and specific definitions.
+ * It may also be used by all ports that reuse X11 stuff (like XF86 DGA)
+ */
+#include "ts_xlib.h"
+#include "ts_xutil.h"
+
+#ifdef HAVE_LIBXXSHM
+# include <sys/types.h>
+# ifdef HAVE_SYS_IPC_H
+#  include <sys/ipc.h>
+# endif
+# ifdef HAVE_SYS_SHM_H
+#  include <sys/shm.h>
+# endif
+# include "ts_xshm.h"
+#endif /* defined(HAVE_LIBXXSHM) */
+
+#include "x11drv.h"
+
+#include "ddraw_private.h"
+
+#include "wine_gl.h"
+
+extern ICOM_VTABLE(IDirectDraw)		xlib_ddvt;
+extern ICOM_VTABLE(IDirectDraw2)         xlib_dd2vt;
+extern ICOM_VTABLE(IDirectDraw4)        xlib_dd4vt;
+extern ICOM_VTABLE(IDirectDrawPalette)	xlib_ddpalvt;
+extern ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt;
+
+typedef struct x11_dd_private {
+#ifdef HAVE_LIBXXSHM
+    int xshm_active, xshm_compl;
+#endif /* defined(HAVE_LIBXXSHM) */
+    Window drawable;
+} x11_dd_private;
+
+typedef struct x11_dp_private {
+    BOOL	installed;	/* is colormap installed */
+    Colormap	cm;		/* the X11 Colormap associated */
+} x11_dp_private;
+
+extern HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(LPDIRECTDRAWPALETTE,DWORD,DWORD,DWORD,LPPALETTEENTRY);
+extern ULONG WINAPI Xlib_IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface);
+
+typedef struct x11_ds_private {
+    XImage	*image;
+#ifdef HAVE_LIBXXSHM
+    XShmSegmentInfo	shminfo;
+#endif
+} x11_ds_private;
+
+#ifdef HAVE_LIBXXSHM
+extern int XShmErrorFlag;
+#endif
+#endif /* __WINE_DDRAW_X11_PRIVATE_H */