- beginning of implementation of Direct3D2 (DX 5.0) and associated classes
- some basic code for Direct3D and Direct3DExecuteBuffer (DX 3.0)
- added stretching to Blt function

diff --git a/configure b/configure
index d01cfcf..6f2682e 100755
--- a/configure
+++ b/configure
@@ -2451,6 +2451,49 @@
   echo "$ac_t""no" 1>&6
 fi
 
+        echo $ac_n "checking for OSMesaCreateContext in -lMesaGL""... $ac_c" 1>&6
+echo "configure:2456: checking for OSMesaCreateContext in -lMesaGL" >&5
+ac_lib_var=`echo MesaGL'_'OSMesaCreateContext | 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="-lMesaGL $X_LIBS -lXext -lX11 -lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2464 "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
+    builtin and then its argument prototype would still apply.  */
+char OSMesaCreateContext();
+
+int main() {
+OSMesaCreateContext()
+; return 0; }
+EOF
+if { (eval echo configure:2475: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_MESAGL 1
+EOF
+ X_PRE_LIBS="$X_PRE_LIBS -lMesaGL"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
 else
     XLIB=""
     X_CFLAGS=""
@@ -2458,7 +2501,7 @@
 fi
 
 echo $ac_n "checking for waddch in -lncurses""... $ac_c" 1>&6
-echo "configure:2462: checking for waddch in -lncurses" >&5
+echo "configure:2505: 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
@@ -2466,7 +2509,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lncurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2470 "configure"
+#line 2513 "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
@@ -2477,7 +2520,7 @@
 waddch()
 ; return 0; }
 EOF
-if { (eval echo configure:2481: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2524: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2508,7 +2551,7 @@
 then :
 else
     echo $ac_n "checking for waddch in -lcurses""... $ac_c" 1>&6
-echo "configure:2512: checking for waddch in -lcurses" >&5
+echo "configure:2555: 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
@@ -2516,7 +2559,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lcurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2520 "configure"
+#line 2563 "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
@@ -2527,7 +2570,7 @@
 waddch()
 ; return 0; }
 EOF
-if { (eval echo configure:2531: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2574: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2557,12 +2600,12 @@
 fi
 
 echo $ac_n "checking "for GNU style IPX support"""... $ac_c" 1>&6
-echo "configure:2561: checking "for GNU style IPX support"" >&5
+echo "configure:2604: 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 2566 "configure"
+#line 2609 "configure"
 #include "confdefs.h"
 #include <sys/socket.h>
     #include <netipx/ipx.h>
@@ -2570,7 +2613,7 @@
 ((struct sockaddr_ipx *)0)->sipx_family == AF_IPX
 ; return 0; }
 EOF
-if { (eval echo configure:2574: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2617: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   cat >> confdefs.h <<\EOF
 #define HAVE_IPX_GNU 1
@@ -2592,12 +2635,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:2596: checking "for linux style IPX support"" >&5
+echo "configure:2639: 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 2601 "configure"
+#line 2644 "configure"
 #include "confdefs.h"
 #include <sys/socket.h>
      #include <asm/types.h>
@@ -2606,7 +2649,7 @@
 ((struct sockaddr_ipx *)0)->sipx_family == AF_IPX
 ; return 0; }
 EOF
-if { (eval echo configure:2610: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2653: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   cat >> confdefs.h <<\EOF
 #define HAVE_IPX_LINUX 1
@@ -2630,17 +2673,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2634: checking for $ac_hdr" >&5
+echo "configure:2677: 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 2639 "configure"
+#line 2682 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2644: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2687: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2668,12 +2711,12 @@
 
 
 echo $ac_n "checking "for Open Sound System"""... $ac_c" 1>&6
-echo "configure:2672: checking "for Open Sound System"" >&5
+echo "configure:2715: 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 2677 "configure"
+#line 2720 "configure"
 #include "confdefs.h"
 
 	#if defined(HAVE_SYS_SOUNDCARD_H)
@@ -2694,7 +2737,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2698: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2741: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_opensoundsystem="yes"
 else
@@ -2718,12 +2761,12 @@
 
 
 echo $ac_n "checking "for union semun"""... $ac_c" 1>&6
-echo "configure:2722: checking "for union semun"" >&5
+echo "configure:2765: checking "for union semun"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_union_semun'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2727 "configure"
+#line 2770 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/sem.h>
@@ -2731,7 +2774,7 @@
 union semun foo
 ; return 0; }
 EOF
-if { (eval echo configure:2735: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2778: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_union_semun="yes"
 else
@@ -2759,7 +2802,7 @@
 then
   CFLAGS="$CFLAGS -Wall"
   echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6
-echo "configure:2763: checking "for gcc strength-reduce bug"" >&5
+echo "configure:2806: 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
@@ -2767,7 +2810,7 @@
   ac_cv_c_gcc_strength_bug="yes"
 else
   cat > conftest.$ac_ext <<EOF
-#line 2771 "configure"
+#line 2814 "configure"
 #include "confdefs.h"
 
 int main(void) {
@@ -2778,7 +2821,7 @@
   exit( Array[1] != -2 );
 }
 EOF
-if { (eval echo configure:2782: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_gcc_strength_bug="no"
 else
@@ -2801,7 +2844,7 @@
 
 
 echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6
-echo "configure:2805: checking "whether external symbols need an underscore prefix"" >&5
+echo "configure:2848: 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
@@ -2813,14 +2856,14 @@
 	.long 0
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2817 "configure"
+#line 2860 "configure"
 #include "confdefs.h"
 extern int ac_test;
 int main() {
 if (ac_test) return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2824: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_extern_prefix="yes"
 else
@@ -2844,7 +2887,7 @@
 
 
 echo $ac_n "checking "whether assembler accepts .string"""... $ac_c" 1>&6
-echo "configure:2848: checking "whether assembler accepts .string"" >&5
+echo "configure:2891: 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
@@ -2854,14 +2897,14 @@
 	.string "test"
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2858 "configure"
+#line 2901 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:2865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_asm_string="yes"
 else
@@ -2889,21 +2932,21 @@
 if test "$LIB_TARGET" = "libwine.so.1.0"
 then
   echo $ac_n "checking "whether we can build a Linux dll"""... $ac_c" 1>&6
-echo "configure:2893: checking "whether we can build a Linux dll"" >&5
+echo "configure:2936: 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 2900 "configure"
+#line 2943 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2907: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2950: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_dll_linux="yes"
 else
@@ -2924,21 +2967,21 @@
     LDSHARED="\$(CC) -shared -Wl,-soname,libwine.so"
   else
     echo $ac_n "checking "whether we can build a NetBSD dll"""... $ac_c" 1>&6
-echo "configure:2928: checking "whether we can build a NetBSD dll"" >&5
+echo "configure:2971: 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 2935 "configure"
+#line 2978 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2942: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2985: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_dll_netbsd="yes"
 else
@@ -2969,7 +3012,7 @@
 
 
 echo $ac_n "checking "for reentrant libc"""... $ac_c" 1>&6
-echo "configure:2973: checking "for reentrant libc"" >&5
+echo "configure:3016: checking "for reentrant libc"" >&5
 if eval "test \"`echo '$''{'wine_cv_libc_reentrant'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2977,14 +3020,14 @@
   wine_cv_libc_reentrant=yes 
 else
   cat > conftest.$ac_ext <<EOF
-#line 2981 "configure"
+#line 3024 "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:2988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   wine_cv_libc_reentrant=yes
 else
@@ -3009,7 +3052,7 @@
 
 
 echo $ac_n "checking "for reentrant X libraries"""... $ac_c" 1>&6
-echo "configure:3013: checking "for reentrant X libraries"" >&5
+echo "configure:3056: 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
@@ -3054,12 +3097,12 @@
 for ac_func in clone getpagesize memmove sendmsg sigaltstack strerror stricmp tcgetattr timegm usleep wait4 waitpid vfscanf
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3058: checking for $ac_func" >&5
+echo "configure:3101: 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 3063 "configure"
+#line 3106 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3082,7 +3125,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:3086: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3110,17 +3153,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3114: checking for $ac_hdr" >&5
+echo "configure:3157: 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 3119 "configure"
+#line 3162 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3124: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3167: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3147,12 +3190,12 @@
 done
 
 echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:3151: checking whether stat file-mode macros are broken" >&5
+echo "configure:3194: 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 3156 "configure"
+#line 3199 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -3203,12 +3246,12 @@
 fi
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:3207: checking for working const" >&5
+echo "configure:3250: 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 3212 "configure"
+#line 3255 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -3257,7 +3300,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:3261: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3304: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -3278,12 +3321,12 @@
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:3282: checking for ANSI C header files" >&5
+echo "configure:3325: 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 3287 "configure"
+#line 3330 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -3291,7 +3334,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3295: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3338: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3308,7 +3351,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 3312 "configure"
+#line 3355 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -3326,7 +3369,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 3330 "configure"
+#line 3373 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -3347,7 +3390,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 3351 "configure"
+#line 3394 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -3358,7 +3401,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:3362: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -3382,12 +3425,12 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:3386: checking for size_t" >&5
+echo "configure:3429: 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 3391 "configure"
+#line 3434 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -3415,7 +3458,7 @@
 fi
 
 echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:3419: checking size of long long" >&5
+echo "configure:3462: 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
@@ -3423,7 +3466,7 @@
   ac_cv_sizeof_long_long=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 3427 "configure"
+#line 3470 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -3434,7 +3477,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:3438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3481: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long_long=`cat conftestval`
 else
@@ -3457,7 +3500,7 @@
 
 if test $ac_cv_func_sendmsg = no; then
     echo $ac_n "checking for sendmsg in -lsocket""... $ac_c" 1>&6
-echo "configure:3461: checking for sendmsg in -lsocket" >&5
+echo "configure:3504: checking for sendmsg in -lsocket" >&5
 ac_lib_var=`echo socket'_'sendmsg | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3465,7 +3508,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3469 "configure"
+#line 3512 "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
@@ -3476,7 +3519,7 @@
 sendmsg()
 ; return 0; }
 EOF
-if { (eval echo configure:3480: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3523: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3509,12 +3552,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:3513: checking "whether sys/vfs.h defines statfs"" >&5
+echo "configure:3556: 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 3518 "configure"
+#line 3561 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -3531,7 +3574,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:3535: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3578: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_vfs_has_statfs=yes
 else
@@ -3558,12 +3601,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:3562: checking "whether sys/statfs.h defines statfs"" >&5
+echo "configure:3605: 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 3567 "configure"
+#line 3610 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -3578,7 +3621,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:3582: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3625: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_statfs_has_statfs=yes
 else
@@ -3605,12 +3648,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:3609: checking "whether sys/mount.h defines statfs"" >&5
+echo "configure:3652: 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 3614 "configure"
+#line 3657 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -3625,7 +3668,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:3629: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3672: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_sys_mount_has_statfs=yes
 else
@@ -3651,7 +3694,7 @@
 
 
 echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6
-echo "configure:3655: checking "for statfs.f_bfree"" >&5
+echo "configure:3698: 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
@@ -3660,7 +3703,7 @@
         wine_cv_statfs_bfree=no
     else
     	cat > conftest.$ac_ext <<EOF
-#line 3664 "configure"
+#line 3707 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -3687,7 +3730,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:3691: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3734: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_statfs_bfree=yes
 else
@@ -3711,7 +3754,7 @@
 fi
 
 echo $ac_n "checking "for statfs.f_bavail"""... $ac_c" 1>&6
-echo "configure:3715: checking "for statfs.f_bavail"" >&5
+echo "configure:3758: 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
@@ -3720,7 +3763,7 @@
         wine_cv_statfs_bavail=no
     else
     	cat > conftest.$ac_ext <<EOF
-#line 3724 "configure"
+#line 3767 "configure"
 #include "confdefs.h"
 
 	#include <sys/types.h>
@@ -3747,7 +3790,7 @@
 	
 ; return 0; }
 EOF
-if { (eval echo configure:3751: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3794: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   wine_cv_statfs_bavail=yes
 else
@@ -3772,7 +3815,7 @@
 
 
 echo $ac_n "checking "for working sigaltstack"""... $ac_c" 1>&6
-echo "configure:3776: checking "for working sigaltstack"" >&5
+echo "configure:3819: 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
@@ -3781,7 +3824,7 @@
 
 else
   cat > conftest.$ac_ext <<EOF
-#line 3785 "configure"
+#line 3828 "configure"
 #include "confdefs.h"
 
 	#include <stdio.h>
@@ -3819,7 +3862,7 @@
 	}
 	
 EOF
-if { (eval echo configure:3823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3866: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_working_sigaltstack="yes"
 else
@@ -3846,12 +3889,12 @@
 
 
 echo $ac_n "checking "for msg_accrights in struct msghdr"""... $ac_c" 1>&6
-echo "configure:3850: checking "for msg_accrights in struct msghdr"" >&5
+echo "configure:3893: 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 3855 "configure"
+#line 3898 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -3859,7 +3902,7 @@
 struct msghdr hdr; hdr.msg_accrights=0
 ; return 0; }
 EOF
-if { (eval echo configure:3863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3906: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_msg_accrights="yes"
 else
diff --git a/configure.in b/configure.in
index 12c8036..194029b 100644
--- a/configure.in
+++ b/configure.in
@@ -106,6 +106,8 @@
     AC_CHECK_LIB(Xxf86dga,XF86DGAQueryExtension,AC_DEFINE(HAVE_LIBXXF86DGA) X_PRE_LIBS="$X_PRE_LIBS -lXxf86dga",,$X_LIBS -lXext -lX11)
     dnl Check for XFree86 VMODE extension
     AC_CHECK_LIB(Xxf86vm,XF86VidModeQueryExtension,AC_DEFINE(HAVE_LIBXXF86VM) X_PRE_LIBS="$X_PRE_LIBS -lXxf86vm",,$X_LIBS -lXext -lX11)
+    dnl Check for the presence of Mesa
+    AC_CHECK_LIB(MesaGL,OSMesaCreateContext,AC_DEFINE(HAVE_MESAGL) X_PRE_LIBS="$X_PRE_LIBS -lMesaGL",,$X_LIBS -lXext -lX11 -lm)
 else
     XLIB=""
     X_CFLAGS=""
diff --git a/documentation/status/direct3D b/documentation/status/direct3D
new file mode 100644
index 0000000..b73d30d
--- /dev/null
+++ b/documentation/status/direct3D
@@ -0,0 +1,55 @@
+Introduction
+------------
+
+This file contains information about Wine's implementation of
+Direct3D. 
+
+The current version requires :
+ * Mesa (tested with version 3.1 beta)
+ * a display in 16bpp
+
+To minimize the impact on DirectDraw (i.e. to reuse most of the code
+already done for DirectDraw), I decided not to start with an
+implementation based on GLX, but on OSMesa. This way, all the OpenGL
+rendering are done in a 'private' memory buffer, buffer that will
+copied back to the DirectDraw Surface each time a 3D scene
+finishes. It is not optimal for execution speed (on each frame, the
+OpenGL buffer is converted from 32 to 16 bpp and copied onto the
+screen) but is for development (I had almost nothing to change in
+DirectDraw). Moreover, 99 % of the code in the Direct3D implementation
+is 'device independant' (i.e. GLX / OSMesa / whatever), so that
+changing to GLX will have only a minor impact on Direct3D's code.
+
+Code structure
+--------------
+
+TODO (well, once the code will be put in the dll/ddraw directory)
+
+Status
+------
+
+I tested this code with two programs (all using Direct3D 5.0) :
+
+ * BOIDS.EXE that comes with the 5.2 DirectX SDK : works great. Only
+   thing missing is the texturing and transparency on the spinning
+   gobes. Lighting seems to be a bit different than the Real One.
+
+ * Tomb Raider II : works quite well (without texturing).
+
+TODO
+----
+ * finish working on Execute Buffers (i.e. Direct3D 3.0)
+ * texture mapping / blending effects
+ * real GLX implementation (will need a complete rewrite of DirectDraw
+   also) to have 3DFx support
+ * restructuration of all the DDRAW.DLL (put that in the dll
+   directory, better separation of 'drivers, ...)
+ * start looking into DirectX 6.0
+ * inquire on Mesa / XFree86 mailing lists about direct access to 
+   display hardware (for games such as Tomb Raider II that displays 
+   vertices that are already in screen coordinates)
+ * look into thread safeness...
+
+-- 
+Lionel Ulmer - ulmer@directprovider.net
+Last updated : Sun Jan 03 1999
diff --git a/documentation/status/directdraw b/documentation/status/directdraw
index a19ca49..ae69d70 100644
--- a/documentation/status/directdraw
+++ b/documentation/status/directdraw
@@ -1,5 +1,5 @@
 This file contains information on the current implementation of the DirectDraw
-API.
+API. Information specific to Direct3D is in the direct3D file.
 
 The DirectDraw API is being used in a lot of current computergames. Its API
 layer is represented by the functions in the Win32 DLL ddraw.dll and the
diff --git a/graphics/Makefile.in b/graphics/Makefile.in
index 10b5418..eb7bacb 100644
--- a/graphics/Makefile.in
+++ b/graphics/Makefile.in
@@ -8,6 +8,13 @@
 C_SRCS = \
 	bitblt.c \
 	cache.c \
+	d3dcommon.c \
+	d3ddevices.c \
+	d3dexecutebuffer.c \
+	d3dlight.c \
+	d3dmaterial.c \
+	d3dtexture.c \
+	d3dviewport.c \
 	ddraw.c \
 	dispdib.c \
 	driver.c \
diff --git a/graphics/d3d_private.h b/graphics/d3d_private.h
new file mode 100644
index 0000000..c5f81ae
--- /dev/null
+++ b/graphics/d3d_private.h
@@ -0,0 +1,110 @@
+/* Direct3D 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 _WINE_D3D_PRIVATE_H
+#define _WINE_D3D_PRIVATE_H
+
+#ifdef HAVE_MESAGL
+
+#include "d3d.h"
+#include "wine_gl.h"
+
+/* Matrix copy WITH transposition */
+#define conv_mat2(mat,gl_mat)			\
+{						\
+  TRACE(ddraw, "%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \
+  TRACE(ddraw, "%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \
+  TRACE(ddraw, "%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \
+  TRACE(ddraw, "%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(ddraw, "%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \
+  TRACE(ddraw, "%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \
+  TRACE(ddraw, "%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \
+  TRACE(ddraw, "%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(ddraw, "%f %f %f %f\n", (mat)->_11, (mat)->_12, (mat)->_13, (mat)->_14); \
+  TRACE(ddraw, "%f %f %f %f\n", (mat)->_21, (mat)->_22, (mat)->_23, (mat)->_24); \
+  TRACE(ddraw, "%f %f %f %f\n", (mat)->_31, (mat)->_32, (mat)->_33, (mat)->_34); \
+  TRACE(ddraw, "%f %f %f %f\n", (mat)->_41, (mat)->_42, (mat)->_43, (mat)->_44);
+
+typedef struct OpenGL_IDirect3DDevice2 {
+  IDirect3DDevice2 common;
+  
+  /* These are the OpenGL-specific variables */
+  OSMesaContext ctx;
+  unsigned char *buffer;
+  
+  float world_mat[16];
+  float view_mat[16];
+  float proj_mat[16];
+} OpenGL_IDirect3DDevice2;
+
+typedef struct OpenGL_IDirect3DDevice {
+  IDirect3DDevice common;
+  
+  /* These are the OpenGL-specific variables */
+  OSMesaContext ctx;
+  unsigned char *buffer;
+  
+  D3DMATRIX *world_mat;
+  D3DMATRIX *view_mat;
+  D3DMATRIX *proj_mat;
+} OpenGL_IDirect3DDevice;
+
+#define _dump_colorvalue(s,v)                      \
+  TRACE(ddraw, " " s " : %f %f %f %f\n",           \
+	(v).r.r, (v).g.g, (v).b.b, (v).a.a);
+
+#endif /* HAVE_MESAGL */
+
+/* Common functions defined in d3dcommon.c */
+void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
+		      DWORD dwRenderState) ;
+
+/* All non-static functions 'exported' by various sub-objects */
+extern LPDIRECT3DTEXTURE2 d3dtexture2_create(LPDIRECTDRAWSURFACE3 surf) ;
+extern LPDIRECT3DTEXTURE d3dtexture_create(LPDIRECTDRAWSURFACE3 surf) ;
+
+extern LPDIRECT3DLIGHT d3dlight_create_dx3(LPDIRECT3D d3d) ;
+extern LPDIRECT3DLIGHT d3dlight_create(LPDIRECT3D2 d3d) ;
+
+extern LPDIRECT3DEXECUTEBUFFER d3dexecutebuffer_create(LPDIRECT3DDEVICE d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc) ;
+
+extern LPDIRECT3DMATERIAL d3dmaterial_create(LPDIRECT3D d3d) ;
+extern LPDIRECT3DMATERIAL2 d3dmaterial2_create(LPDIRECT3D2 d3d) ;
+
+extern LPDIRECT3DVIEWPORT d3dviewport_create(LPDIRECT3D d3d) ;
+extern LPDIRECT3DVIEWPORT2 d3dviewport2_create(LPDIRECT3D2 d3d) ;
+
+extern int is_OpenGL_dx3(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device) ;
+extern int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) ;
+extern int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) ;
+extern int is_OpenGL(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 d3d) ;
+
+#endif /* _WINE_D3D_PRIVATE_H */
diff --git a/graphics/d3dcommon.c b/graphics/d3dcommon.c
new file mode 100644
index 0000000..8fa6c8b
--- /dev/null
+++ b/graphics/d3dcommon.c
@@ -0,0 +1,185 @@
+/* Direct3D Common functions
+   (c) 1998 Lionel ULMER
+   
+   This file contains all common miscellaneous code that spans
+   different 'objects' */
+
+#include "config.h"
+#include "windows.h"
+#include "wintypes.h"
+#include "interfaces.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debug.h"
+
+#include "d3d_private.h"
+
+#ifdef HAVE_MESAGL
+
+static void _dump_renderstate(D3DRENDERSTATETYPE type,
+			      DWORD value) {
+  char *states[] = {
+    NULL,
+    "D3DRENDERSTATE_TEXTUREHANDLE",
+    "D3DRENDERSTATE_ANTIALIAS",
+    "D3DRENDERSTATE_TEXTUREADDRESS",
+    "D3DRENDERSTATE_TEXTUREPERSPECTIVE",
+    "D3DRENDERSTATE_WRAPU",
+    "D3DRENDERSTATE_WRAPV",
+    "D3DRENDERSTATE_ZENABLE",
+    "D3DRENDERSTATE_FILLMODE",
+    "D3DRENDERSTATE_SHADEMODE",
+    "D3DRENDERSTATE_LINEPATTERN",
+    "D3DRENDERSTATE_MONOENABLE",
+    "D3DRENDERSTATE_ROP2",
+    "D3DRENDERSTATE_PLANEMASK",
+    "D3DRENDERSTATE_ZWRITEENABLE",
+    "D3DRENDERSTATE_ALPHATESTENABLE",
+    "D3DRENDERSTATE_LASTPIXEL",
+    "D3DRENDERSTATE_TEXTUREMAG",
+    "D3DRENDERSTATE_TEXTUREMIN",
+    "D3DRENDERSTATE_SRCBLEND",
+    "D3DRENDERSTATE_DESTBLEND",
+    "D3DRENDERSTATE_TEXTUREMAPBLEND",
+    "D3DRENDERSTATE_CULLMODE",
+    "D3DRENDERSTATE_ZFUNC",
+    "D3DRENDERSTATE_ALPHAREF",
+    "D3DRENDERSTATE_ALPHAFUNC",
+    "D3DRENDERSTATE_DITHERENABLE",
+    "D3DRENDERSTATE_ALPHABLENDENABLE",
+    "D3DRENDERSTATE_FOGENABLE",
+    "D3DRENDERSTATE_SPECULARENABLE",
+    "D3DRENDERSTATE_ZVISIBLE",
+    "D3DRENDERSTATE_SUBPIXEL",
+    "D3DRENDERSTATE_SUBPIXELX",
+    "D3DRENDERSTATE_STIPPLEDALPHA",
+    "D3DRENDERSTATE_FOGCOLOR",
+    "D3DRENDERSTATE_FOGTABLEMODE",
+    "D3DRENDERSTATE_FOGTABLESTART",
+    "D3DRENDERSTATE_FOGTABLEEND",
+    "D3DRENDERSTATE_FOGTABLEDENSITY",
+    "D3DRENDERSTATE_STIPPLEENABLE",
+    "D3DRENDERSTATE_EDGEANTIALIAS",
+    "D3DRENDERSTATE_COLORKEYENABLE",
+    "D3DRENDERSTATE_BORDERCOLOR",
+    "D3DRENDERSTATE_TEXTUREADDRESSU",
+    "D3DRENDERSTATE_TEXTUREADDRESSV",
+    "D3DRENDERSTATE_MIPMAPLODBIAS",
+    "D3DRENDERSTATE_ZBIAS",
+    "D3DRENDERSTATE_RANGEFOGENABLE",
+    "D3DRENDERSTATE_ANISOTROPY",
+    "D3DRENDERSTATE_FLUSHBATCH",
+    "D3DRENDERSTATE_STIPPLEPATTERN00",
+    "D3DRENDERSTATE_STIPPLEPATTERN01",
+    "D3DRENDERSTATE_STIPPLEPATTERN02",
+    "D3DRENDERSTATE_STIPPLEPATTERN03",
+    "D3DRENDERSTATE_STIPPLEPATTERN04",
+    "D3DRENDERSTATE_STIPPLEPATTERN05",
+    "D3DRENDERSTATE_STIPPLEPATTERN06",
+    "D3DRENDERSTATE_STIPPLEPATTERN07",
+    "D3DRENDERSTATE_STIPPLEPATTERN08",
+    "D3DRENDERSTATE_STIPPLEPATTERN09",
+    "D3DRENDERSTATE_STIPPLEPATTERN10",
+    "D3DRENDERSTATE_STIPPLEPATTERN11",
+    "D3DRENDERSTATE_STIPPLEPATTERN12",
+    "D3DRENDERSTATE_STIPPLEPATTERN13",
+    "D3DRENDERSTATE_STIPPLEPATTERN14",
+    "D3DRENDERSTATE_STIPPLEPATTERN15",
+    "D3DRENDERSTATE_STIPPLEPATTERN16",
+    "D3DRENDERSTATE_STIPPLEPATTERN17",
+    "D3DRENDERSTATE_STIPPLEPATTERN18",
+    "D3DRENDERSTATE_STIPPLEPATTERN19",
+    "D3DRENDERSTATE_STIPPLEPATTERN20",
+    "D3DRENDERSTATE_STIPPLEPATTERN21",
+    "D3DRENDERSTATE_STIPPLEPATTERN22",
+    "D3DRENDERSTATE_STIPPLEPATTERN23",
+    "D3DRENDERSTATE_STIPPLEPATTERN24",
+    "D3DRENDERSTATE_STIPPLEPATTERN25",
+    "D3DRENDERSTATE_STIPPLEPATTERN26",
+    "D3DRENDERSTATE_STIPPLEPATTERN27",
+    "D3DRENDERSTATE_STIPPLEPATTERN28",
+    "D3DRENDERSTATE_STIPPLEPATTERN29",
+    "D3DRENDERSTATE_STIPPLEPATTERN30",
+    "D3DRENDERSTATE_STIPPLEPATTERN31"
+  };
+
+  DUMP(" %s = 0x%08lx\n", states[type], value);
+}
+
+
+void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
+		      DWORD dwRenderState)
+{
+
+  if (TRACE_ON(ddraw))
+    _dump_renderstate(dwRenderStateType, dwRenderState);
+
+  /* First, all the stipple patterns */
+  if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) && 
+      (dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN31)) {
+
+  } else {
+    /* All others state variables */
+    switch (dwRenderStateType) {
+    case D3DRENDERSTATE_ZENABLE:          /*  7 */
+      if (dwRenderState)
+	glEnable(GL_DEPTH_TEST);
+      else
+	glDisable(GL_DEPTH_TEST);
+      break;
+      
+    case D3DRENDERSTATE_ZWRITEENABLE:     /* 14 */
+      if (dwRenderState)
+	glDepthMask(GL_TRUE);
+      else
+	glDepthMask(GL_FALSE);
+      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(ddraw, "Unexpected value\n");
+      }
+      break;
+      
+    case D3DRENDERSTATE_DITHERENABLE:     /* 26 */
+      if (dwRenderState)
+	glEnable(GL_DITHER);
+      else
+	glDisable(GL_DITHER);
+      break;
+      
+    default:
+      FIXME(ddraw, "Unhandled Render State\n");
+      break;
+    }
+  }
+}
+
+
+#endif /* HAVE_MESAGL */
diff --git a/graphics/d3ddevices.c b/graphics/d3ddevices.c
new file mode 100644
index 0000000..dcbdc0c
--- /dev/null
+++ b/graphics/d3ddevices.c
@@ -0,0 +1,1499 @@
+/* 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 "config.h"
+#include "windows.h"
+#include "wintypes.h"
+#include "winerror.h"
+#include "interfaces.h"
+#include "heap.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debug.h"
+
+#include "d3d_private.h"
+
+#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 IDirect3DDevice2_VTable OpenGL_vtable;
+static IDirect3DDevice_VTable OpenGL_vtable_dx3;
+
+/*******************************************************************************
+ *				OpenGL static functions
+ */
+static void set_context(LPDIRECT3DDEVICE2 this) {
+  OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
+
+  OSMesaMakeCurrent(odev->ctx, odev->buffer,
+		    GL_UNSIGNED_BYTE,
+		    this->surface->s.surface_desc.dwWidth,
+		    this->surface->s.surface_desc.dwHeight);
+}
+
+static void set_context_dx3(LPDIRECT3DDEVICE this) {
+  OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this;
+
+  OSMesaMakeCurrent(odev->ctx, odev->buffer,
+		    GL_UNSIGNED_BYTE,
+		    this->surface->s.surface_desc.dwWidth,
+		    this->surface->s.surface_desc.dwHeight);
+}
+
+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_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;
+  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->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(ddraw," 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, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 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
+    };
+    
+    *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice2));
+    odev = (OpenGL_IDirect3DDevice2 *) (*device);
+    (*device)->ref = 1;
+    (*device)->lpvtbl = &OpenGL_vtable;
+    (*device)->d3d = d3d;
+    (*device)->surface = surface;
+    
+    (*device)->viewport_list = NULL;
+    (*device)->current_viewport = NULL;
+    
+    (*device)->set_context = set_context;
+    
+    TRACE(ddraw, "OpenGL device created \n");
+    
+    /* Create the OpenGL context */
+    odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
+    odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
+			     surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
+    
+    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 */
+    (*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 0;
+}
+
+/*******************************************************************************
+ *				Common IDirect3DDevice2
+ */
+
+static HRESULT WINAPI IDirect3DDevice2_QueryInterface(LPDIRECT3DDEVICE2 this,
+						      REFIID riid,
+						      LPVOID* ppvObj)
+{
+  char xrefiid[50];
+  
+  WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
+  FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
+  
+  return S_OK;
+}
+
+
+
+static ULONG WINAPI IDirect3DDevice2_AddRef(LPDIRECT3DDEVICE2 this)
+{
+  TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
+  
+  return ++(this->ref);
+}
+
+
+
+static ULONG WINAPI IDirect3DDevice2_Release(LPDIRECT3DDEVICE2 this)
+{
+  FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+  
+  if (!--(this->ref)) {
+    HeapFree(GetProcessHeap(),0,this);
+    return 0;
+  }
+  
+  return this->ref;
+}
+
+
+/*** IDirect3DDevice2 methods ***/
+static HRESULT WINAPI IDirect3DDevice2_GetCaps(LPDIRECT3DDEVICE2 this,
+					       LPD3DDEVICEDESC lpdescsoft,
+					       LPD3DDEVICEDESC lpdeschard)
+{
+  FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpdescsoft, lpdeschard);
+  
+  fill_opengl_caps(lpdescsoft, lpdeschard);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_SwapTextureHandles(LPDIRECT3DDEVICE2 this,
+							  LPDIRECT3DTEXTURE2 lptex1,
+							  LPDIRECT3DTEXTURE2 lptex2)
+{
+  FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lptex1, lptex2);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_GetStats(LPDIRECT3DDEVICE2 this,
+						LPD3DSTATS lpstats)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpstats);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_AddViewport(LPDIRECT3DDEVICE2 this,
+						   LPDIRECT3DVIEWPORT2 lpvp)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
+  
+  /* Adds this viewport to the viewport list */
+  lpvp->next = this->viewport_list;
+  this->viewport_list = lpvp;
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_DeleteViewport(LPDIRECT3DDEVICE2 this,
+						      LPDIRECT3DVIEWPORT2 lpvp)
+{
+  LPDIRECT3DVIEWPORT2 cur, prev;
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
+  
+  /* Finds this viewport in the list */
+  prev = NULL;
+  cur = this->viewport_list;
+  while ((cur != NULL) && (cur != lpvp)) {
+    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 IDirect3DDevice2_NextViewport(LPDIRECT3DDEVICE2 this,
+						    LPDIRECT3DVIEWPORT2 lpvp,
+						    LPDIRECT3DVIEWPORT2* lplpvp,
+						    DWORD dwFlags)
+{
+  FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpvp, lpvp, dwFlags);
+  
+  switch (dwFlags) {
+  case D3DNEXT_NEXT:
+    *lplpvp = lpvp->next;
+    break;
+    
+  case D3DNEXT_HEAD:
+    *lplpvp = this->viewport_list;
+    break;
+    
+  case D3DNEXT_TAIL:
+    lpvp = this->viewport_list;
+    while (lpvp->next != NULL)
+      lpvp = lpvp->next;
+    
+    *lplpvp = lpvp;
+    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(ddraw, "Enumerating GL_RGBA (32)\n");
+  pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
+  pformat->x.dwRGBBitCount = 32;
+  pformat->y.dwRBitMask =  0x00FF0000;
+  pformat->z.dwGBitMask =  0x0000FF00;
+  pformat->xx.dwBBitMask = 0x000000FF;
+  pformat->xy.dwRGBAlphaBitMask = 0xFF000000;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+
+  TRACE(ddraw, "Enumerating GL_RGB (24)\n");
+  pformat->dwFlags = DDPF_RGB;
+  pformat->x.dwRGBBitCount = 24;
+  pformat->y.dwRBitMask =  0x00FF0000;
+  pformat->z.dwGBitMask =  0x0000FF00;
+  pformat->xx.dwBBitMask = 0x000000FF;
+  pformat->xy.dwRGBAlphaBitMask = 0x00000000;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+
+  TRACE(ddraw, "Enumerating GL_RGB (16)\n");
+  pformat->dwFlags = DDPF_RGB;
+  pformat->x.dwRGBBitCount = 16;
+  pformat->y.dwRBitMask =  0x0000F800;
+  pformat->z.dwGBitMask =  0x000007E0;
+  pformat->xx.dwBBitMask = 0x0000001F;
+  pformat->xy.dwRGBAlphaBitMask = 0x00000000;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+
+  TRACE(ddraw, "Enumerating Paletted (8)\n");
+  pformat->dwFlags = DDPF_PALETTEINDEXED8;
+  pformat->x.dwRGBBitCount = 8;
+  pformat->y.dwRBitMask =  0x00000000;
+  pformat->z.dwGBitMask =  0x00000000;
+  pformat->xx.dwBBitMask = 0x00000000;
+  pformat->xy.dwRGBAlphaBitMask = 0x00000000;
+  if (cb(&sdesc, context) == 0)
+    return DD_OK;
+  
+  TRACE(ddraw, "End of enumeration\n");
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DDevice2_EnumTextureFormats(LPDIRECT3DDEVICE2 this,
+							  LPD3DENUMTEXTUREFORMATSCALLBACK cb,
+							  LPVOID context)
+{
+  FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, cb, context);
+  
+  return enum_texture_format_OpenGL(cb, context);
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_BeginScene(LPDIRECT3DDEVICE2 this)
+{
+  OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
+  
+  FIXME(ddraw, "(%p)->(): stub\n", this);
+  
+  /* Here, we should get the DDraw surface and 'copy it' to the
+     OpenGL surface.... */
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_EndScene(LPDIRECT3DDEVICE2 this)
+{
+  OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
+  LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) this->surface;
+  DDSURFACEDESC sdesc;
+  int x,y;
+  unsigned char *src;
+  unsigned short *dest;
+  
+  FIXME(ddraw, "(%p)->(): stub\n", this);
+
+  /* Here we copy back the OpenGL scene to the the DDraw surface */
+  /* First, lock the surface */
+  surf->lpvtbl->fnLock(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 */
+  surf->lpvtbl->fnUnlock(surf,sdesc.y.lpSurface);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_GetDirect3D(LPDIRECT3DDEVICE2 this, LPDIRECT3D2 *lpd3d2)
+{
+  TRACE(ddraw, "(%p)->(%p): stub\n", this, lpd3d2);
+  
+  *lpd3d2 = this->d3d;
+  
+  return DD_OK;
+}
+
+
+
+/*** DrawPrimitive API ***/
+static HRESULT WINAPI IDirect3DDevice2_SetCurrentViewport(LPDIRECT3DDEVICE2 this,
+							  LPDIRECT3DVIEWPORT2 lpvp)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
+  
+  /* Should check if the viewport was added or not */
+  
+  /* Set this viewport as the current viewport */
+  this->current_viewport = lpvp;
+  
+  /* Activate this viewport */
+  lpvp->device.active_device2 = this;
+  lpvp->activate(lpvp);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_GetCurrentViewport(LPDIRECT3DDEVICE2 this,
+							  LPDIRECT3DVIEWPORT2 *lplpvp)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lplpvp);
+  
+  /* Returns the current viewport */
+  *lplpvp = this->current_viewport;
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_SetRenderTarget(LPDIRECT3DDEVICE2 this,
+						       LPDIRECTDRAWSURFACE lpdds,
+						       DWORD dwFlags)
+{
+  FIXME(ddraw, "(%p)->(%p,%08lx): stub\n", this, lpdds, dwFlags);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_GetRenderTarget(LPDIRECT3DDEVICE2 this,
+						       LPDIRECTDRAWSURFACE *lplpdds)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lplpdds);
+  
+  /* Returns the current rendering target (the surface on wich we render) */
+  *lplpdds = this->surface;
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_Begin(LPDIRECT3DDEVICE2 this,
+					     D3DPRIMITIVETYPE d3dp,
+					     D3DVERTEXTYPE d3dv,
+					     DWORD dwFlags)
+{
+  FIXME(ddraw, "(%p)->(%d,%d,%08lx): stub\n", this, d3dp, d3dv, dwFlags);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_BeginIndexed(LPDIRECT3DDEVICE2 this,
+						    D3DPRIMITIVETYPE d3dp,
+						    D3DVERTEXTYPE d3dv,
+						    LPVOID lpvert,
+						    DWORD numvert,
+						    DWORD dwFlags)
+{
+  FIXME(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvert, numvert, dwFlags);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_Vertex(LPDIRECT3DDEVICE2 this,
+					      LPVOID lpvert)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvert);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_Index(LPDIRECT3DDEVICE2 this,
+					     WORD index)
+{
+  FIXME(ddraw, "(%p)->(%d): stub\n", this, index);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_End(LPDIRECT3DDEVICE2 this,
+					   DWORD dwFlags)
+{
+  FIXME(ddraw, "(%p)->(%08lx): stub\n", this, dwFlags);
+  
+  return DD_OK;
+}
+
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_GetRenderState(LPDIRECT3DDEVICE2 this,
+						      D3DRENDERSTATETYPE d3drs,
+						      LPDWORD lprstate)
+{
+  FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3drs, lprstate);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_SetRenderState(LPDIRECT3DDEVICE2 this,
+						      D3DRENDERSTATETYPE dwRenderStateType,
+						      DWORD dwRenderState)
+{
+  TRACE(ddraw, "(%p)->(%d,%ld)\n", this, dwRenderStateType, dwRenderState);
+  
+  /* Call the render state functions */
+  set_render_state(dwRenderStateType, dwRenderState);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_GetLightState(LPDIRECT3DDEVICE2 this,
+						     D3DLIGHTSTATETYPE d3dls,
+						     LPDWORD lplstate)
+{
+  FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dls, lplstate);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_SetLightState(LPDIRECT3DDEVICE2 this,
+						     D3DLIGHTSTATETYPE dwLightStateType,
+						     DWORD dwLightState)
+{
+  FIXME(ddraw, "(%p)->(%d,%08lx): stub\n", this, dwLightStateType, dwLightState);
+  
+  switch (dwLightStateType) {
+  case D3DLIGHTSTATE_MATERIAL: {  /* 1 */
+    LPDIRECT3DMATERIAL2 mat = (LPDIRECT3DMATERIAL2) dwLightState;
+    
+    if (mat != NULL) {
+      mat->activate(mat);
+    } else {
+      TRACE(ddraw, "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;
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
+  } 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(ddraw, "Unexpected Light State Type\n");
+    return DDERR_INVALIDPARAMS;
+  }
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_SetTransform(LPDIRECT3DDEVICE2 this,
+						    D3DTRANSFORMSTATETYPE d3dts,
+						    LPD3DMATRIX lpmatrix)
+{
+  OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
+  
+  FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
+  
+  /* 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;
+  }
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_GetTransform(LPDIRECT3DDEVICE2 this,
+						    D3DTRANSFORMSTATETYPE d3dts,
+						    LPD3DMATRIX lpmatrix)
+{
+  FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_MultiplyTransform(LPDIRECT3DDEVICE2 this,
+							 D3DTRANSFORMSTATETYPE d3dts,
+							 LPD3DMATRIX lpmatrix)
+{
+  FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_DrawPrimitive(LPDIRECT3DDEVICE2 this,
+						     D3DPRIMITIVETYPE d3dp,
+						     D3DVERTEXTYPE d3dv,
+						     LPVOID lpvertex,
+						     DWORD vertcount,
+						     DWORD dwFlags)
+{
+  int vx_index;
+  
+  TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvertex, vertcount, dwFlags);
+
+  /* Puts GL in the correct lighting mode */
+  switch (d3dv) {
+  case D3DVT_VERTEX:
+    TRACE(ddraw, "Standard Vertex\n");
+    glEnable(GL_LIGHTING);
+    break;
+    
+  case D3DVT_LVERTEX:
+    TRACE(ddraw, "Lighted Vertex\n");
+    glDisable(GL_LIGHTING);
+    break;
+    
+  case D3DVT_TLVERTEX: {
+    GLdouble height, width;
+    
+    TRACE(ddraw, "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(ddraw, "No current viewport !\n");
+      /* Using standard values */
+      height = 640.0;
+      width = 480.0;
+    } else {
+      if (this->current_viewport->use_vp2) {
+	height = (GLdouble) this->current_viewport->viewport.vp2.dwHeight;
+	width  = (GLdouble) this->current_viewport->viewport.vp2.dwWidth;
+      } else {
+	height = (GLdouble) this->current_viewport->viewport.vp1.dwHeight;
+	width  = (GLdouble) this->current_viewport->viewport.vp1.dwWidth;
+      }
+    }
+
+    glOrtho(0.0, width, height, 0.0, 1.5, -1.5);
+  } break;
+    
+  default:
+    TRACE(ddraw, "Unhandled vertex type\n");
+    break;
+  }
+
+  switch (d3dp) {
+  case D3DPT_POINTLIST:
+    TRACE(ddraw, "Start POINTS\n");
+    glBegin(GL_POINTS);
+    break;
+
+  case D3DPT_LINELIST:
+    TRACE(ddraw, "Start LINES\n");
+    glBegin(GL_LINES);
+    break;
+    
+  case D3DPT_LINESTRIP:
+    TRACE(ddraw, "Start LINE_STRIP\n");
+    glBegin(GL_LINE_STRIP);
+    break;
+    
+  case D3DPT_TRIANGLELIST:
+    TRACE(ddraw, "Start TRIANGLES\n");
+    glBegin(GL_TRIANGLES);
+    break;
+
+  case D3DPT_TRIANGLESTRIP:
+    TRACE(ddraw, "Start TRIANGLE_STRIP\n");
+    glBegin(GL_TRIANGLE_STRIP);
+    break;
+
+  case D3DPT_TRIANGLEFAN:
+    TRACE(ddraw, "Start TRIANGLE_FAN\n");
+    glBegin(GL_TRIANGLE_FAN);
+    break;
+    
+  default:
+    TRACE(ddraw, "Unhandled primitive\n");
+    break;
+  }
+  
+  /* Draw the primitives */
+  for (vx_index = 0; vx_index < vertcount; vx_index++) {
+    switch (d3dv) {
+    case D3DVT_VERTEX: {
+      D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + vx_index;
+      
+      glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz);
+      glVertex3f(vx->x.x, vx->y.y, vx->z.z);
+      TRACE(ddraw, "   V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z);
+    } break;
+      
+    case D3DVT_LVERTEX: {
+      D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + vx_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(ddraw, "  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) + vx_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.sx, vx->y.sy, vx->z.sz);
+      TRACE(ddraw, " TLV: %f %f %f (%02lx %02lx %02lx)\n",
+	    vx->x.sx, vx->y.sy, vx->z.sz,
+	    ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF));
+    } break;
+      
+    default:
+      TRACE(ddraw, "Unhandled vertex type\n");
+      break;
+    }
+  }
+  
+  glEnd();
+  TRACE(ddraw, "End\n");
+   
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 this,
+							    D3DPRIMITIVETYPE d3dp,
+							    D3DVERTEXTYPE d3dv,
+							    LPVOID lpvertex,
+							    DWORD vertcount,
+							    LPWORD lpindexes,
+							    DWORD indexcount,
+							    DWORD dwFlags)
+{
+  int vx_index;
+  
+  TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
+  
+  /* Puts GL in the correct lighting mode */
+  switch (d3dv) {
+  case D3DVT_VERTEX:
+    glEnable(GL_LIGHTING);
+    break;
+    
+  case D3DVT_LVERTEX:
+  case D3DVT_TLVERTEX:
+    glDisable(GL_LIGHTING);
+    break;
+    
+  default:
+    break;
+  }
+  
+  switch (d3dp) {
+  case D3DPT_LINESTRIP:
+    TRACE(ddraw, "Start LINE_STRIP\n");
+    glBegin(GL_LINE_STRIP);
+    break;
+    
+  case D3DPT_TRIANGLELIST:
+    TRACE(ddraw, "Start TRIANGLES\n");
+    glBegin(GL_TRIANGLES);
+    break;
+    
+  default:
+    break;
+  }
+  
+  /* Draw the primitives */
+  for (vx_index = 0; vx_index < indexcount; vx_index++) {
+    switch (d3dv) {
+    case D3DVT_VERTEX: {
+      D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + lpindexes[vx_index];
+      
+      glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz);
+      glVertex3f(vx->x.x, vx->y.y, vx->z.z);
+      TRACE(ddraw, "   V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z);
+    } break;
+      
+    case D3DVT_LVERTEX: {
+      D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + lpindexes[vx_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(ddraw, "  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;
+      
+    default:
+      break;
+    }
+  }
+  
+  glEnd();
+  TRACE(ddraw, "End\n");
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_SetClipStatus(LPDIRECT3DDEVICE2 this,
+						     LPD3DCLIPSTATUS lpcs)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpcs);
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice2_GetClipStatus(LPDIRECT3DDEVICE2 this,
+						     LPD3DCLIPSTATUS lpcs)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpcs);
+  
+  return DD_OK;
+}
+
+
+
+/*******************************************************************************
+ *				OpenGL-specific IDirect3DDevice2
+ */
+
+/*******************************************************************************
+ *				OpenGL-specific VTable
+ */
+
+static IDirect3DDevice2_VTable OpenGL_vtable = {
+  IDirect3DDevice2_QueryInterface,
+  IDirect3DDevice2_AddRef,
+  IDirect3DDevice2_Release,
+  /*** IDirect3DDevice2 methods ***/
+  IDirect3DDevice2_GetCaps,
+  IDirect3DDevice2_SwapTextureHandles,
+  IDirect3DDevice2_GetStats,
+  IDirect3DDevice2_AddViewport,
+  IDirect3DDevice2_DeleteViewport,
+  IDirect3DDevice2_NextViewport,
+  IDirect3DDevice2_EnumTextureFormats,
+  IDirect3DDevice2_BeginScene,
+  IDirect3DDevice2_EndScene,
+  IDirect3DDevice2_GetDirect3D,
+  
+  /*** DrawPrimitive API ***/
+  IDirect3DDevice2_SetCurrentViewport,
+  IDirect3DDevice2_GetCurrentViewport,
+  
+  IDirect3DDevice2_SetRenderTarget,
+  IDirect3DDevice2_GetRenderTarget,
+  
+  IDirect3DDevice2_Begin,
+  IDirect3DDevice2_BeginIndexed,
+  IDirect3DDevice2_Vertex,
+  IDirect3DDevice2_Index,
+  IDirect3DDevice2_End,
+  
+  IDirect3DDevice2_GetRenderState,
+  IDirect3DDevice2_SetRenderState,
+  IDirect3DDevice2_GetLightState,
+  IDirect3DDevice2_SetLightState,
+  IDirect3DDevice2_SetTransform,
+  IDirect3DDevice2_GetTransform,
+  IDirect3DDevice2_MultiplyTransform,
+  
+  IDirect3DDevice2_DrawPrimitive,
+  IDirect3DDevice2_DrawIndexedPrimitive,
+  
+  IDirect3DDevice2_SetClipStatus,
+  IDirect3DDevice2_GetClipStatus,
+};
+
+/*******************************************************************************
+ *				Direct3DDevice
+ */
+int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
+  D3DDEVICEDESC	d1,d2;
+  
+  TRACE(ddraw," 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, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device)
+{
+  if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
+    OpenGL_IDirect3DDevice *odev;
+       
+    *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice));
+    odev = (OpenGL_IDirect3DDevice *) (*device);
+    (*device)->ref = 1;
+    (*device)->lpvtbl = &OpenGL_vtable_dx3;
+    (*device)->d3d = NULL;
+    (*device)->surface = surface;
+    
+    (*device)->viewport_list = NULL;
+    (*device)->current_viewport = NULL;
+    
+    (*device)->set_context = set_context_dx3;
+    
+    TRACE(ddraw, "OpenGL device created \n");
+    
+    /* Create the OpenGL context */
+    odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
+    odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
+			     surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
+
+    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 IDirect3DDevice_QueryInterface(LPDIRECT3DDEVICE this,
+						     REFIID riid,
+						     LPVOID* ppvObj)
+{
+  char xrefiid[50];
+  
+  WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
+  FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
+  
+  return S_OK;
+}
+
+
+
+static ULONG WINAPI IDirect3DDevice_AddRef(LPDIRECT3DDEVICE this)
+{
+  TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
+  
+  return ++(this->ref);
+}
+
+
+
+static ULONG WINAPI IDirect3DDevice_Release(LPDIRECT3DDEVICE this)
+{
+  FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+  
+  if (!--(this->ref)) {
+    HeapFree(GetProcessHeap(),0,this);
+    return 0;
+  }
+  
+  return this->ref;
+}
+
+static HRESULT WINAPI IDirect3DDevice_Initialize(LPDIRECT3DDEVICE this,
+						 LPDIRECT3D lpd3d,
+						 LPGUID lpGUID,
+						 LPD3DDEVICEDESC lpd3ddvdesc)
+{
+  TRACE(ddraw, "(%p)->(%p,%p,%p): stub\n", this, lpd3d,lpGUID, lpd3ddvdesc);
+  
+  return DDERR_ALREADYINITIALIZED;
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_GetCaps(LPDIRECT3DDEVICE this,
+					      LPD3DDEVICEDESC lpD3DHWDevDesc,
+					      LPD3DDEVICEDESC lpD3DSWDevDesc)
+{
+  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DHWDevDesc, lpD3DSWDevDesc);
+
+  fill_opengl_caps(lpD3DHWDevDesc, lpD3DSWDevDesc);  
+  
+  return DD_OK;
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_SwapTextureHandles(LPDIRECT3DDEVICE this,
+							 LPDIRECT3DTEXTURE lpD3DTex1,
+							 LPDIRECT3DTEXTURE lpD3DTex2)
+{
+  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DTex1, lpD3DTex2);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DDevice_CreateExecuteBuffer(LPDIRECT3DDEVICE this,
+							  LPD3DEXECUTEBUFFERDESC lpDesc,
+							  LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer,
+							  IUnknown *pUnkOuter)
+{
+  TRACE(ddraw, "(%p)->(%p,%p,%p)\n", this, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
+
+  *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(this, lpDesc);
+  
+  return DD_OK;
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_GetStats(LPDIRECT3DDEVICE this,
+					       LPD3DSTATS lpD3DStats)
+{
+  TRACE(ddraw, "(%p)->(%p): stub\n", this, lpD3DStats);
+  
+  return DD_OK;
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_Execute(LPDIRECT3DDEVICE this,
+					      LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
+					      LPDIRECT3DVIEWPORT lpDirect3DViewport,
+					      DWORD dwFlags)
+{
+  TRACE(ddraw, "(%p)->(%p,%p,%08ld): stub\n", this, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
+
+  /* Put this as the default context */
+
+  /* Execute... */
+  lpDirect3DExecuteBuffer->execute(lpDirect3DExecuteBuffer, this, lpDirect3DViewport);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DDevice_AddViewport(LPDIRECT3DDEVICE this,
+						  LPDIRECT3DVIEWPORT lpvp)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
+  
+  /* Adds this viewport to the viewport list */
+  lpvp->next = this->viewport_list;
+  this->viewport_list = lpvp;
+  
+  return DD_OK;
+}
+
+
+
+static HRESULT WINAPI IDirect3DDevice_DeleteViewport(LPDIRECT3DDEVICE this,
+						     LPDIRECT3DVIEWPORT lpvp)
+{
+  LPDIRECT3DVIEWPORT cur, prev;
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
+  
+  /* Finds this viewport in the list */
+  prev = NULL;
+  cur = this->viewport_list;
+  while ((cur != NULL) && (cur != lpvp)) {
+    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 IDirect3DDevice_NextViewport(LPDIRECT3DDEVICE this,
+						   LPDIRECT3DVIEWPORT lpvp,
+						   LPDIRECT3DVIEWPORT* lplpvp,
+						   DWORD dwFlags)
+{
+  FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpvp, lpvp, dwFlags);
+  
+  switch (dwFlags) {
+  case D3DNEXT_NEXT:
+    *lplpvp = lpvp->next;
+    break;
+    
+  case D3DNEXT_HEAD:
+    *lplpvp = this->viewport_list;
+    break;
+    
+  case D3DNEXT_TAIL:
+    lpvp = this->viewport_list;
+    while (lpvp->next != NULL)
+      lpvp = lpvp->next;
+    
+    *lplpvp = lpvp;
+    break;
+    
+  default:
+    return DDERR_INVALIDPARAMS;
+  }
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DDevice_Pick(LPDIRECT3DDEVICE this,
+					   LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
+					   LPDIRECT3DVIEWPORT lpDirect3DViewport,
+					   DWORD dwFlags,
+					   LPD3DRECT lpRect)
+{
+  TRACE(ddraw, "(%p)->(%p,%p,%08lx,%p): stub\n", this, lpDirect3DExecuteBuffer, lpDirect3DViewport,
+	dwFlags, lpRect);
+  
+  return DD_OK;
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_GetPickRecords(LPDIRECT3DDEVICE this,
+						     LPDWORD lpCount,
+						     LPD3DPICKRECORD lpD3DPickRec)
+{
+  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpCount, lpD3DPickRec);
+  
+  return DD_OK;
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_EnumTextureFormats(LPDIRECT3DDEVICE this,
+							 LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
+							 LPVOID lpArg)
+{
+  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpd3dEnumTextureProc, lpArg);
+  
+  return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg);
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_CreateMatrix(LPDIRECT3DDEVICE this,
+						   LPD3DMATRIXHANDLE lpD3DMatHandle)
+{
+  TRACE(ddraw, "(%p)->(%p)\n", this, lpD3DMatHandle);
+
+  *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX));
+  
+  return DD_OK;
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_SetMatrix(LPDIRECT3DDEVICE this,
+						D3DMATRIXHANDLE d3dMatHandle,
+						const LPD3DMATRIX lpD3DMatrix)
+{
+  TRACE(ddraw, "(%p)->(%08lx,%p)\n", this, d3dMatHandle, lpD3DMatrix);
+
+  dump_mat(lpD3DMatrix);
+  *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
+  
+  return DD_OK;
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_GetMatrix(LPDIRECT3DDEVICE this,
+						D3DMATRIXHANDLE D3DMatHandle,
+						LPD3DMATRIX lpD3DMatrix)
+{
+  TRACE(ddraw, "(%p)->(%08lx,%p)\n", this, D3DMatHandle, lpD3DMatrix);
+
+  *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
+  
+  return DD_OK;
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_DeleteMatrix(LPDIRECT3DDEVICE this,
+						   D3DMATRIXHANDLE d3dMatHandle)
+{
+  TRACE(ddraw, "(%p)->(%08lx)\n", this, d3dMatHandle);
+
+  HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle);
+  
+  return DD_OK;
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_BeginScene(LPDIRECT3DDEVICE this)
+{
+  OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this;
+  
+  FIXME(ddraw, "(%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 IDirect3DDevice_EndScene(LPDIRECT3DDEVICE this)
+{
+  OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this;
+  LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) this->surface;
+  DDSURFACEDESC sdesc;
+  int x,y;
+  unsigned char *src;
+  unsigned short *dest;
+  
+  FIXME(ddraw, "(%p)->(): stub\n", this);
+
+  /* Here we copy back the OpenGL scene to the the DDraw surface */
+  /* First, lock the surface */
+  surf->lpvtbl->fnLock(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 */
+  surf->lpvtbl->fnUnlock(surf,sdesc.y.lpSurface);
+  
+  return DD_OK;  
+}
+
+
+static HRESULT WINAPI IDirect3DDevice_GetDirect3D(LPDIRECT3DDEVICE this,
+						  LPDIRECT3D *lpDirect3D)
+{
+  TRACE(ddraw, "(%p)->(%p): stub\n", this, lpDirect3D);
+
+  return DD_OK;
+}
+
+
+
+/*******************************************************************************
+ *				Direct3DDevice VTable
+ */
+static IDirect3DDevice_VTable OpenGL_vtable_dx3 = {
+  IDirect3DDevice_QueryInterface,
+  IDirect3DDevice_AddRef,
+  IDirect3DDevice_Release,
+  IDirect3DDevice_Initialize,
+  IDirect3DDevice_GetCaps,
+  IDirect3DDevice_SwapTextureHandles,
+  IDirect3DDevice_CreateExecuteBuffer,
+  IDirect3DDevice_GetStats,
+  IDirect3DDevice_Execute,
+  IDirect3DDevice_AddViewport,
+  IDirect3DDevice_DeleteViewport,
+  IDirect3DDevice_NextViewport,
+  IDirect3DDevice_Pick,
+  IDirect3DDevice_GetPickRecords,
+  IDirect3DDevice_EnumTextureFormats,
+  IDirect3DDevice_CreateMatrix,
+  IDirect3DDevice_SetMatrix,
+  IDirect3DDevice_GetMatrix,
+  IDirect3DDevice_DeleteMatrix,
+  IDirect3DDevice_BeginScene,
+  IDirect3DDevice_EndScene,
+  IDirect3DDevice_GetDirect3D,
+};
+
+#else /* HAVE_MESAGL */
+
+int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
+  return 0;
+}
+
+int is_OpenGL(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 d3d)
+{
+  return 0;
+}
+
+int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
+  return 0;
+}
+
+int is_OpenGL_dx3(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device)
+{
+  return 0;
+}
+
+#endif /* HAVE_MESAGL */
diff --git a/graphics/d3dexecutebuffer.c b/graphics/d3dexecutebuffer.c
new file mode 100644
index 0000000..4fe4f04
--- /dev/null
+++ b/graphics/d3dexecutebuffer.c
@@ -0,0 +1,578 @@
+/* Direct3D ExecuteBuffer
+   (c) 1998 Lionel ULMER
+   
+   This files contains the implementation of Direct3DExecuteBuffer. */
+
+
+#include "config.h"
+#include "windows.h"
+#include "wintypes.h"
+#include "winerror.h"
+#include "interfaces.h"
+#include "heap.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debug.h"
+
+#include "d3d_private.h"
+
+#ifdef HAVE_MESAGL
+
+static IDirect3DExecuteBuffer_VTable executebuffer_vtable;
+
+/*******************************************************************************
+ *				ExecuteBuffer static functions
+ */
+void _dump_d3dstatus(LPD3DSTATUS lpStatus) {
+  
+}
+
+void _dump_executedata(LPD3DEXECUTEDATA lpData) {
+  DUMP("dwSize : %ld\n", lpData->dwSize);
+  DUMP("Vertex      Offset : %ld  Count  : %ld\n", lpData->dwVertexOffset, lpData->dwVertexCount);
+  DUMP("Instruction Offset : %ld  Length : %ld\n", lpData->dwInstructionOffset, lpData->dwInstructionLength);
+  DUMP("HVertex     Offset : %ld\n", lpData->dwHVertexOffset);
+  _dump_d3dstatus(&(lpData->dsStatus));
+}
+
+#define DO_VERTEX(index) 			\
+  glNormal3f(tvert[index].nx.nx,		\
+	     tvert[index].ny.ny,		\
+	     tvert[index].nz.nz);		\
+  glVertex3f(tvert[index].x.x,			\
+	     tvert[index].y.y,			\
+	     tvert[index].z.z);
+
+
+static void execute(LPDIRECT3DEXECUTEBUFFER lpBuff,
+		    LPDIRECT3DDEVICE dev,
+		    LPDIRECT3DVIEWPORT vp) {
+  DWORD bs = lpBuff->desc.dwBufferSize;
+  DWORD vs = lpBuff->data.dwVertexOffset;
+  DWORD vc = lpBuff->data.dwVertexCount;
+  DWORD is = lpBuff->data.dwInstructionOffset;
+  DWORD il = lpBuff->data.dwInstructionLength;
+  
+  unsigned char *instr = lpBuff->desc.lpData + is;
+  LPD3DVERTEX vert = (LPD3DVERTEX) (lpBuff->desc.lpData + vs);
+  LPD3DVERTEX tvert = lpBuff->vertex_data;
+  OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) dev;
+  
+  TRACE(ddraw, "ExecuteData : \n");
+  _dump_executedata(&(lpBuff->data));
+  
+  while (1) {
+    LPD3DINSTRUCTION current = (LPD3DINSTRUCTION) instr;
+    BYTE size;
+    WORD count;
+
+    count = current->wCount;
+    size = current->bSize;
+    instr += sizeof(D3DINSTRUCTION);
+    
+    switch (current->bOpcode) {
+    case D3DOP_POINT: {
+      TRACE(ddraw, "POINT-s          (%d)\n", count);
+
+      instr += count * size;
+    } break;
+      
+    case D3DOP_LINE: {
+      TRACE(ddraw, "LINE-s           (%d)\n", count);
+
+      instr += count * size;
+    } break;
+      
+    case D3DOP_TRIANGLE: {
+      int i;
+      TRACE(ddraw, "TRIANGLE         (%d)\n", count);
+
+      /* Use given matrixes */
+      glMatrixMode(GL_MODELVIEW);
+      glLoadIdentity(); /* The model transformation was done during the
+			   transformation phase */
+      glMatrixMode(GL_PROJECTION);
+      glLoadMatrixf((float *) odev->proj_mat);
+      glMultMatrixf((float *) odev->view_mat);
+
+      for (i = 0; i < count; i++) {
+	LPD3DTRIANGLE ci = (LPD3DTRIANGLE) instr;
+
+	TRACE(ddraw, "  v1: %d  v2: %d  v3: %d\n",
+	      ci->v1.v1, ci->v2.v2, ci->v3.v3);
+	TRACE(ddraw, "  Flags : ");
+	if (TRACE_ON(ddraw)) {
+	  /* Wireframe */
+	  if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1)
+	    DUMP("EDGEENABLE1 ");
+	  if (ci->wFlags & D3DTRIFLAG_EDGEENABLE2)
+	    DUMP("EDGEENABLE2 ");
+	  if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1)
+	    DUMP("EDGEENABLE3 ");
+
+	  /* Strips / Fans */
+	  if (ci->wFlags == D3DTRIFLAG_EVEN)
+	    DUMP("EVEN ");
+	  if (ci->wFlags == D3DTRIFLAG_ODD)
+	    DUMP("ODD ");
+	  if (ci->wFlags == D3DTRIFLAG_START)
+	    DUMP("START ");
+	  if ((ci->wFlags > 0) && (ci->wFlags < 30))
+	    DUMP("STARTFLAT(%d) ", ci->wFlags);
+	  DUMP("\n");
+	}
+
+	glBegin(GL_TRIANGLES); {
+	  DO_VERTEX(ci->v1.v1);
+	  DO_VERTEX(ci->v2.v2);
+	  DO_VERTEX(ci->v3.v3);
+	} glEnd();
+	
+	instr += size;
+      }
+    } break;
+    
+    case D3DOP_MATRIXLOAD: {
+      TRACE(ddraw, "MATRIXLOAD-s     (%d)\n", count);
+
+      instr += count * size;
+    } break;
+      
+    case D3DOP_MATRIXMULTIPLY: {
+      int i;
+      TRACE(ddraw, "MATRIXMULTIPLY   (%d)\n", count);
+
+      for (i = 0; i < count; i++) {
+	LPD3DMATRIXMULTIPLY ci = (LPD3DMATRIXMULTIPLY) instr;
+	LPD3DMATRIX a = (LPD3DMATRIX) ci->hDestMatrix;
+	LPD3DMATRIX b = (LPD3DMATRIX) ci->hSrcMatrix1;
+	LPD3DMATRIX c = (LPD3DMATRIX) ci->hSrcMatrix2;
+	
+	TRACE(ddraw, "  Dest : %08lx  Src1 : %08lx  Src2 : %08lx\n",
+	      ci->hDestMatrix, ci->hSrcMatrix1, ci->hSrcMatrix2);
+
+	/* Do the multiplication..
+	   As I am VERY lazy, I let OpenGL do the multiplication for me */
+	glMatrixMode(GL_PROJECTION);
+	/* Save the current matrix */
+	glPushMatrix();
+	/* Load Matrix one and do the multiplication */
+	glLoadMatrixf((float *) ci->hSrcMatrix1);
+	glMultMatrixf((float *) ci->hSrcMatrix2);
+	glGetFloatv(GL_PROJECTION_MATRIX, (float *) ci->hDestMatrix);
+	/* Restore the current matrix */
+	glPopMatrix();
+	
+	instr += size;
+      }
+    } break;
+      
+    case D3DOP_STATETRANSFORM: {
+      int i;
+      TRACE(ddraw, "STATETRANSFORM   (%d)\n", count);
+
+      for (i = 0; i < count; i++) {
+	LPD3DSTATE ci = (LPD3DSTATE) instr;
+
+	/* Handle the state transform */
+	switch (ci->t.dtstTransformStateType) {
+	case D3DTRANSFORMSTATE_WORLD: {
+	  TRACE(ddraw, "  WORLD (%p)\n", (D3DMATRIX*) ci->v.dwArg[0]);
+	  odev->world_mat = (D3DMATRIX*) ci->v.dwArg[0];
+	} break;
+
+	case D3DTRANSFORMSTATE_VIEW: {
+	  TRACE(ddraw, "  VIEW (%p)\n", (D3DMATRIX*) ci->v.dwArg[0]);
+	  odev->view_mat = (D3DMATRIX*) ci->v.dwArg[0];
+	} break;
+
+	case D3DTRANSFORMSTATE_PROJECTION: {
+    	  TRACE(ddraw, "  PROJECTION (%p)\n", (D3DMATRIX*) ci->v.dwArg[0]);
+	  odev->proj_mat = (D3DMATRIX*) ci->v.dwArg[0];
+	} break;
+
+	default:
+	  ERR(ddraw, "  Unhandled state transformation !! (%d)\n", (int) ci->t.dtstTransformStateType);
+	  break;
+	  
+	}
+	
+	instr += size;
+      }
+    } break;
+      
+    case D3DOP_STATELIGHT: {
+      int i;
+      TRACE(ddraw, "STATELIGHT       (%d)\n", count);
+
+      for (i = 0; i < count; i++) {
+	LPD3DSTATE ci = (LPD3DSTATE) instr;
+	
+	/* Handle the state transform */
+	switch (ci->t.dlstLightStateType) {
+	case D3DLIGHTSTATE_MATERIAL: {
+	  LPDIRECT3DMATERIAL mat = (LPDIRECT3DMATERIAL) ci->v.dwArg[0];
+	  TRACE(ddraw, "  MATERIAL\n");
+	  
+	  if (mat != NULL) {
+	    mat->activate(mat);
+	  } else {
+	    TRACE(ddraw, "    bad Material Handle\n");
+	  }
+	} break ;
+	  
+	case D3DLIGHTSTATE_AMBIENT: {
+	  float light[4];
+	  DWORD dwLightState = ci->v.dwArg[0];
+	  TRACE(ddraw, "  AMBIENT\n");
+	  
+	  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;
+	  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
+
+	  TRACE(ddraw, "    R:%02lx G:%02lx B:%02lx A:%02lx\n",
+		((dwLightState >> 16) & 0xFF),
+		((dwLightState >>  8) & 0xFF),
+		((dwLightState >>  0) & 0xFF),
+		((dwLightState >> 24) & 0xFF));
+	} break ;
+	  
+	case D3DLIGHTSTATE_COLORMODEL: {
+	  TRACE(ddraw, "  COLORMODEL\n");
+	} break ;
+	  
+	case D3DLIGHTSTATE_FOGMODE: {
+	  TRACE(ddraw, "  FOGMODE\n");
+	} break ;
+	  
+	case D3DLIGHTSTATE_FOGSTART: {
+	  TRACE(ddraw, "  FOGSTART\n");
+	} break ;
+	  
+	case D3DLIGHTSTATE_FOGEND: {
+	  TRACE(ddraw, "  FOGEND\n");
+	} break ;
+	  
+	case D3DLIGHTSTATE_FOGDENSITY: {
+	  TRACE(ddraw, "  FOGDENSITY\n");
+	} break ;
+	  
+	default:
+	  ERR(ddraw, "  Unhandled light state !! (%d)\n", (int) ci->t.dlstLightStateType);
+	  break;
+	}
+	instr += size;
+      }
+    } break;
+      
+    case D3DOP_STATERENDER: {
+      int i;
+      TRACE(ddraw, "STATERENDER      (%d)\n", count);
+      
+      for (i = 0; i < count; i++) {
+	LPD3DSTATE ci = (LPD3DSTATE) instr;
+	
+	/* Handle the state transform */
+	set_render_state(ci->t.drstRenderStateType, ci->v.dwArg[0]);
+
+	instr += size;
+      }
+    } break;
+      
+    case D3DOP_PROCESSVERTICES: {
+      int i;
+      TRACE(ddraw, "PROCESSVERTICES  (%d)\n", count);
+      
+      for (i = 0; i < count; i++) {
+	LPD3DPROCESSVERTICES ci = (LPD3DPROCESSVERTICES) instr;
+	
+	TRACE(ddraw, "  Start : %d Dest : %d Count : %ld\n",
+	      ci->wStart, ci->wDest, ci->dwCount);
+	TRACE(ddraw, "  Flags : ");
+	if (TRACE_ON(ddraw)) {
+	  if (ci->dwFlags & D3DPROCESSVERTICES_COPY)
+	    DUMP("COPY ");
+	  if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR)
+	    DUMP("NOCOLOR ");
+	  if (ci->dwFlags == D3DPROCESSVERTICES_OPMASK)
+	    DUMP("OPMASK ");
+	  if (ci->dwFlags & D3DPROCESSVERTICES_TRANSFORM)
+	    DUMP("TRANSFORM ");
+	  if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT)
+	    DUMP("TRANSFORMLIGHT ");
+	  if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS)
+	    DUMP("UPDATEEXTENTS ");
+	  DUMP("\n");
+	}
+
+	/* This is where doing Direct3D on top on OpenGL is quite difficult.
+	   This method transforms a set of vertices using the CURRENT state
+	   (lighting, projection, ...) but does not rasterize them.
+	   They will oinly be put on screen later (with the POINT / LINE and
+	   TRIANGLE op-codes). The problem is that you can have a triangle
+	   with each point having been transformed using another state...
+
+	   In this implementation, I will emulate only ONE thing : each
+	   vertex can have its own "WORLD" transformation (this is used in the
+	   TWIST.EXE demo of the 5.2 SDK). I suppose that all vertices of the 
+	   execute buffer use the same state.
+
+	   If I find applications that change other states, I will try to do a
+	   more 'fine-tuned' state emulation (but I may become quite tricky if 
+	   it changes a light position in the middle of a triangle).
+	   
+	   In this case, a 'direct' approach (i.e. without using OpenGL, but
+	   writing our own 3D rasterizer) would be easier. */
+
+	/* The current method (with the hypothesis that only the WORLD matrix
+	   will change between two points) is like this :
+	    - I transform 'manually' all the vertices with the current WORLD
+	      matrix and store them in the vertex buffer
+	    - during the rasterization phase, the WORLD matrix will be set to
+	      the Identity matrix */
+
+	/* Enough for the moment */
+	if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT) {
+	  /* Enable lighting, so that when the rasterization will take place,
+	     the correct LIGHTING state is active. */
+	  glEnable(GL_LIGHTING);
+
+	  /* */
+	}
+	
+	instr += size;
+      }
+    } break;
+      
+    case D3DOP_TEXTURELOAD: {
+      TRACE(ddraw, "TEXTURELOAD-s    (%d)\n", count);
+
+      instr += count * size;
+    } break;
+      
+    case D3DOP_EXIT: {
+      TRACE(ddraw, "EXIT             (%d)\n", count);
+      /* We did this instruction */
+      instr += size;
+      /* Exit this loop */
+      goto end_of_buffer;
+    } break;
+      
+    case D3DOP_BRANCHFORWARD: {
+      TRACE(ddraw, "BRANCHFORWARD-s  (%d)\n", count);
+
+      instr += count * size;
+    } break;
+      
+    case D3DOP_SPAN: {
+      TRACE(ddraw, "SPAN-s           (%d)\n", count);
+
+      instr += count * size;
+    } break;
+      
+    case D3DOP_SETSTATUS: {
+      TRACE(ddraw, "SETSTATUS-s      (%d)\n", count);
+
+      instr += count * size;
+    } break;
+
+    default:
+      ERR(ddraw, "Unhandled OpCode !!!\n");
+      /* Try to save ... */
+      instr += count * size;
+      break;
+    }
+  }
+
+ end_of_buffer:
+}
+
+/*******************************************************************************
+ *				ExecuteBuffer Creation functions
+ */
+LPDIRECT3DEXECUTEBUFFER d3dexecutebuffer_create(LPDIRECT3DDEVICE d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc)
+{
+  LPDIRECT3DEXECUTEBUFFER eb;
+  
+  eb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DExecuteBuffer));
+  eb->ref = 1;
+  eb->lpvtbl = &executebuffer_vtable;
+  eb->d3ddev = d3ddev;
+
+  /* Initializes memory */
+  eb->desc = *lpDesc;
+
+  /* No buffer given */
+  if (!(eb->desc.dwFlags & D3DDEB_LPDATA))
+    eb->desc.lpData = NULL;
+
+  /* No buffer size given */
+  if (!(lpDesc->dwFlags & D3DDEB_BUFSIZE))
+    eb->desc.dwBufferSize = 0;
+
+  /* Create buffer if asked */
+  if ((eb->desc.lpData == NULL) && (eb->desc.dwBufferSize > 0)) {
+    eb->need_free = TRUE;
+    eb->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,eb->desc.dwBufferSize);
+  } else {
+    eb->need_free = FALSE;
+  }
+    
+  /* No vertices for the moment */
+  eb->vertex_data = NULL;
+
+  eb->desc.dwFlags |= D3DDEB_LPDATA;
+
+  eb->execute = execute;
+  
+  return eb;
+}
+
+/*******************************************************************************
+ *				IDirect3DLight methods
+ */
+
+static HRESULT WINAPI IDirect3DExecuteBuffer_QueryInterface(LPDIRECT3DEXECUTEBUFFER this,
+							    REFIID riid,
+							    LPVOID* ppvObj)
+{
+  char xrefiid[50];
+  
+  WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
+  FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
+  
+  return S_OK;
+}
+
+
+
+static ULONG WINAPI IDirect3DExecuteBuffer_AddRef(LPDIRECT3DEXECUTEBUFFER this)
+{
+  TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
+  
+  return ++(this->ref);
+}
+
+
+
+static ULONG WINAPI IDirect3DExecuteBuffer_Release(LPDIRECT3DEXECUTEBUFFER this)
+{
+  FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+  
+  if (!--(this->ref)) {
+    if ((this->desc.lpData != NULL) && this->need_free)
+      HeapFree(GetProcessHeap(),0,this->desc.lpData);
+
+    if (this->vertex_data != NULL)
+      HeapFree(GetProcessHeap(),0,this->vertex_data);
+
+    HeapFree(GetProcessHeap(),0,this);
+    return 0;
+  }
+  
+  return this->ref;
+}
+
+static HRESULT WINAPI IDirect3DExecuteBuffer_Initialize(LPDIRECT3DEXECUTEBUFFER this,
+							LPDIRECT3DDEVICE lpDirect3DDevice,
+							LPD3DEXECUTEBUFFERDESC lpDesc)
+{
+  FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpDirect3DDevice, lpDesc);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DExecuteBuffer_Lock(LPDIRECT3DEXECUTEBUFFER this,
+						  LPD3DEXECUTEBUFFERDESC lpDesc)
+{
+  TRACE(ddraw, "(%p)->(%p)\n", this, lpDesc);
+
+  /* Copies the buffer description */
+  *lpDesc = this->desc;
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DExecuteBuffer_Unlock(LPDIRECT3DEXECUTEBUFFER this)
+{
+  TRACE(ddraw, "(%p)->()\n", this);
+
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DExecuteBuffer_SetExecuteData(LPDIRECT3DEXECUTEBUFFER this,
+							    LPD3DEXECUTEDATA lpData)
+{
+  DWORD nbvert;
+
+  TRACE(ddraw, "(%p)->(%p)\n", this, lpData);
+
+  this->data = *lpData;
+
+  /* Get the number of vertices in the execute buffer */
+  nbvert = this->data.dwVertexCount;
+    
+  /* Prepares the transformed vertex buffer */
+  if (this->vertex_data != NULL)
+    HeapFree(GetProcessHeap(), 0, this->vertex_data);
+  this->vertex_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,nbvert * sizeof(D3DVERTEX));
+
+
+  if (TRACE_ON(ddraw)) {
+    _dump_executedata(lpData);
+  }
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DExecuteBuffer_GetExecuteData(LPDIRECT3DEXECUTEBUFFER this,
+							    LPD3DEXECUTEDATA lpData)
+{
+  TRACE(ddraw, "(%p)->(%p): stub\n", this, lpData);
+
+  *lpData = this->data;
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DExecuteBuffer_Validate(LPDIRECT3DEXECUTEBUFFER this,
+						      LPDWORD lpdwOffset,
+						      LPD3DVALIDATECALLBACK lpFunc,
+						      LPVOID lpUserArg,
+						      DWORD dwReserved)
+{
+  TRACE(ddraw, "(%p)->(%p,%p,%p,%lu)\n", this, lpdwOffset, lpFunc, lpUserArg, dwReserved);
+
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DExecuteBuffer_Optimize(LPDIRECT3DEXECUTEBUFFER this,
+						      DWORD dwReserved)
+{
+  TRACE(ddraw, "(%p)->(%lu)\n", this, dwReserved);
+
+  return DD_OK;
+}
+
+
+/*******************************************************************************
+ *				IDirect3DLight VTable
+ */
+static IDirect3DExecuteBuffer_VTable executebuffer_vtable = {
+  /*** IUnknown methods ***/
+  IDirect3DExecuteBuffer_QueryInterface,
+  IDirect3DExecuteBuffer_AddRef,
+  IDirect3DExecuteBuffer_Release,
+  /*** IDirect3DExecuteBuffer methods ***/
+  IDirect3DExecuteBuffer_Initialize,
+  IDirect3DExecuteBuffer_Lock,
+  IDirect3DExecuteBuffer_Unlock,
+  IDirect3DExecuteBuffer_SetExecuteData,
+  IDirect3DExecuteBuffer_GetExecuteData,
+  IDirect3DExecuteBuffer_Validate,
+  IDirect3DExecuteBuffer_Optimize
+};
+
+#endif /* HAVE_MESAGL */
diff --git a/graphics/d3dlight.c b/graphics/d3dlight.c
new file mode 100644
index 0000000..7b19124
--- /dev/null
+++ b/graphics/d3dlight.c
@@ -0,0 +1,260 @@
+/* Direct3D Light
+   (c) 1998 Lionel ULMER
+   
+   This files contains the implementation of Direct3DLight. */
+
+
+#include "config.h"
+#include "windows.h"
+#include "wintypes.h"
+#include "winerror.h"
+#include "interfaces.h"
+#include "heap.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debug.h"
+
+#include "d3d_private.h"
+
+#ifdef HAVE_MESAGL
+
+static IDirect3DLight_VTable light_vtable;
+
+enum {
+  D3D_1,
+  D3D_2
+};
+
+/*******************************************************************************
+ *				Light static functions
+ */
+static const float zero_value[] = {
+  0.0, 0.0, 0.0, 0.0
+};
+
+static void update(LPDIRECT3DLIGHT this) {
+  switch (this->light.dltType) {
+  case D3DLIGHT_POINT:         /* 1 */
+    TRACE(ddraw, "Activating POINT\n");
+    break;
+    
+  case D3DLIGHT_SPOT:          /* 2 */
+    TRACE(ddraw, "Activating SPOT\n");
+    break;
+    
+  case D3DLIGHT_DIRECTIONAL: {  /* 3 */
+    float direction[4];
+    
+    TRACE(ddraw, "Activating DIRECTIONAL\n");
+    TRACE(ddraw, "  direction : %f %f %f\n",
+	  this->light.dvDirection.x.x,
+	  this->light.dvDirection.y.y,
+	  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));
+
+    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);
+  } break;
+    
+  case D3DLIGHT_PARALLELPOINT:  /* 4 */
+    TRACE(ddraw, "Activating PARRALLEL-POINT\n");
+    break;
+
+  default:
+    TRACE(ddraw, "Not a know Light Type\n");
+    break;
+  }
+}
+
+static void activate(LPDIRECT3DLIGHT this) {
+  update(this);
+
+  /* If was not active, activate it */
+  if (this->is_active == 0) {
+    glEnable(this->light_num);
+
+    this->is_active = 1;
+  }
+
+  return ;
+}
+
+/*******************************************************************************
+ *				Light Creation functions
+ */
+LPDIRECT3DLIGHT d3dlight_create(LPDIRECT3D2 d3d)
+{
+  LPDIRECT3DLIGHT mat;
+  
+  mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLight));
+  mat->ref = 1;
+  mat->lpvtbl = &light_vtable;
+  mat->d3d.d3d2 = d3d;
+  mat->type = D3D_2;
+
+  mat->next = NULL;
+  mat->prev = NULL;
+  mat->activate = activate;
+  mat->is_active = 0;
+  
+  return mat;
+}
+
+LPDIRECT3DLIGHT d3dlight_create_dx3(LPDIRECT3D d3d)
+{
+  LPDIRECT3DLIGHT mat;
+  
+  mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLight));
+  mat->ref = 1;
+  mat->lpvtbl = &light_vtable;
+  
+  mat->d3d.d3d = d3d;
+  mat->type = D3D_1;
+  
+  mat->next = NULL;
+  mat->prev = NULL;
+  mat->activate = activate;
+  mat->is_active = 0;
+  
+  return mat;
+}
+
+/*******************************************************************************
+ *				IDirect3DLight methods
+ */
+
+static HRESULT WINAPI IDirect3DLight_QueryInterface(LPDIRECT3DLIGHT this,
+						    REFIID riid,
+						    LPVOID* ppvObj)
+{
+  char xrefiid[50];
+  
+  WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
+  FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
+  
+  return S_OK;
+}
+
+
+
+static ULONG WINAPI IDirect3DLight_AddRef(LPDIRECT3DLIGHT this)
+{
+  TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
+  
+  return ++(this->ref);
+}
+
+
+
+static ULONG WINAPI IDirect3DLight_Release(LPDIRECT3DLIGHT this)
+{
+  FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+  
+  if (!--(this->ref)) {
+    HeapFree(GetProcessHeap(),0,this);
+    return 0;
+  }
+  
+  return this->ref;
+}
+
+/*** IDirect3DLight methods ***/
+static void dump_light(LPD3DLIGHT light)
+{
+  fprintf(stderr, "  dwSize : %ld\n", light->dwSize);
+}
+
+static HRESULT WINAPI IDirect3DLight_GetLight(LPDIRECT3DLIGHT this,
+					      LPD3DLIGHT lpLight)
+{
+  TRACE(ddraw, "(%p)->(%p)\n", this, lpLight);
+  if (TRACE_ON(ddraw))
+    dump_light(lpLight);
+  
+  /* Copies the light structure */
+  switch (this->type) {
+  case D3D_1:
+    *((LPD3DLIGHT)lpLight) = *((LPD3DLIGHT) &(this->light));
+    break;
+  case D3D_2:
+    *((LPD3DLIGHT2)lpLight) = *((LPD3DLIGHT2) &(this->light));
+    break;
+  }
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DLight_SetLight(LPDIRECT3DLIGHT this,
+					      LPD3DLIGHT lpLight)
+{
+  TRACE(ddraw, "(%p)->(%p)\n", this, lpLight);
+  if (TRACE_ON(ddraw))
+    dump_light(lpLight);
+  
+  /* Stores the light */
+  switch (this->type) {
+  case D3D_1:
+    *((LPD3DLIGHT) &(this->light)) = *((LPD3DLIGHT)lpLight);
+    break;
+  case D3D_2:
+    *((LPD3DLIGHT2) &(this->light)) = *((LPD3DLIGHT2)lpLight);
+    break;
+  }
+  
+  if (this->is_active)
+    update(this);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DLight_Initialize(LPDIRECT3DLIGHT this,
+						LPDIRECT3D lpDirect3D)
+
+{
+  TRACE(ddraw, "(%p)->(%p)\n", this, lpDirect3D);
+
+  return DDERR_ALREADYINITIALIZED;
+}
+
+
+/*******************************************************************************
+ *				IDirect3DLight VTable
+ */
+static IDirect3DLight_VTable light_vtable = {
+  /*** IUnknown methods ***/
+  IDirect3DLight_QueryInterface,
+  IDirect3DLight_AddRef,
+  IDirect3DLight_Release,
+  /*** IDirect3DLight methods ***/
+  IDirect3DLight_Initialize,
+  IDirect3DLight_SetLight,
+  IDirect3DLight_GetLight
+};
+
+#else /* HAVE_MESAGL */
+
+/* These function should never be called if MesaGL is not present */
+LPDIRECT3DLIGHT d3dlight_create_dx3(LPDIRECT3D d3d) {
+  ERR(ddraw, "Should not be called...\n");
+  return NULL;
+}
+
+LPDIRECT3DLIGHT d3dlight_create(LPDIRECT3D2 d3d) {
+  ERR(ddraw, "Should not be called...\n");
+  return NULL;
+}
+
+#endif /* HAVE_MESAGL */
diff --git a/graphics/d3dmaterial.c b/graphics/d3dmaterial.c
new file mode 100644
index 0000000..de45b02
--- /dev/null
+++ b/graphics/d3dmaterial.c
@@ -0,0 +1,251 @@
+/* Direct3D Material
+   (c) 1998 Lionel ULMER
+   
+   This files contains the implementation of Direct3DMaterial2. */
+
+#include "config.h"
+#include "windows.h"
+#include "wintypes.h"
+#include "winerror.h"
+#include "interfaces.h"
+#include "heap.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debug.h"
+
+#include "d3d_private.h"
+
+#ifdef HAVE_MESAGL
+
+static IDirect3DMaterial2_VTable material2_vtable;
+static IDirect3DMaterial_VTable material_vtable;
+
+/*******************************************************************************
+ *				Matrial2 static functions
+ */
+static void activate(LPDIRECT3DMATERIAL2 this) {
+  TRACE(ddraw, "Activating material %p\n", this);
+  
+  /* First, set the rendering context */
+  if (this->use_d3d2)
+    this->device.active_device2->set_context(this->device.active_device2);
+  else
+    this->device.active_device1->set_context(this->device.active_device1);
+
+  /* Set the current Material */
+  _dump_colorvalue("Diffuse", this->mat.a.diffuse);
+  glMaterialfv(GL_FRONT,
+	       GL_DIFFUSE,
+	       (float *) &(this->mat.a.diffuse));
+  _dump_colorvalue("Ambient", this->mat.b.ambient);
+  glMaterialfv(GL_FRONT,
+	       GL_AMBIENT,
+	       (float *) &(this->mat.b.ambient));
+  _dump_colorvalue("Specular", this->mat.c.specular);
+  glMaterialfv(GL_FRONT,
+	       GL_SPECULAR,
+	       (float *) &(this->mat.c.specular));
+  _dump_colorvalue("Emissive", this->mat.d.emissive);
+  glMaterialfv(GL_FRONT,
+	       GL_EMISSION,
+	       (float *) &(this->mat.d.emissive));
+  
+  TRACE(ddraw, "Size  : %ld\n", this->mat.dwSize);
+  TRACE(ddraw, "Power : %f\n", this->mat.e.power);
+  
+  return ;
+}
+
+/*******************************************************************************
+ *				Matrial2 Creation functions
+ */
+LPDIRECT3DMATERIAL2 d3dmaterial2_create(LPDIRECT3D2 d3d)
+{
+  LPDIRECT3DMATERIAL2 mat;
+  
+  mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DMaterial2));
+  mat->ref = 1;
+  mat->lpvtbl = &material2_vtable;
+
+  mat->use_d3d2 = 1;
+  mat->d3d.d3d2 = d3d;
+
+  mat->activate = activate;
+  
+  return mat;
+}
+
+LPDIRECT3DMATERIAL d3dmaterial_create(LPDIRECT3D d3d)
+{
+  LPDIRECT3DMATERIAL2 mat;
+  
+  mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DMaterial2));
+  mat->ref = 1;
+  mat->lpvtbl = (LPDIRECT3DMATERIAL2_VTABLE) &material_vtable;
+
+  mat->use_d3d2 = 0;
+  mat->d3d.d3d1 = d3d;
+
+  mat->activate = activate;
+  
+  return (LPDIRECT3DMATERIAL) mat;
+}
+
+/*******************************************************************************
+ *				IDirect3DMaterial2 methods
+ */
+
+static HRESULT WINAPI IDirect3DMaterial2_QueryInterface(LPDIRECT3DMATERIAL2 this,
+							REFIID riid,
+							LPVOID* ppvObj)
+{
+  char xrefiid[50];
+  
+  WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
+  FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
+  
+  return S_OK;
+}
+
+
+
+static ULONG WINAPI IDirect3DMaterial2_AddRef(LPDIRECT3DMATERIAL2 this)
+{
+  TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
+  
+  return ++(this->ref);
+}
+
+
+
+static ULONG WINAPI IDirect3DMaterial2_Release(LPDIRECT3DMATERIAL2 this)
+{
+  FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+  
+  if (!--(this->ref)) {
+    HeapFree(GetProcessHeap(),0,this);
+    return 0;
+  }
+  
+  return this->ref;
+}
+
+/*** IDirect3DMaterial2 methods ***/
+static void dump_material(LPD3DMATERIAL mat)
+{
+  fprintf(stderr, "  dwSize : %ld\n", mat->dwSize);
+}
+
+static HRESULT WINAPI IDirect3DMaterial2_GetMaterial(LPDIRECT3DMATERIAL2 this,
+						     LPD3DMATERIAL lpMat)
+{
+  TRACE(ddraw, "(%p)->(%p)\n", this, lpMat);
+  if (TRACE_ON(ddraw))
+    dump_material(lpMat);
+  
+  /* Copies the material structure */
+  *lpMat = this->mat;
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DMaterial2_SetMaterial(LPDIRECT3DMATERIAL2 this,
+						     LPD3DMATERIAL lpMat)
+{
+  TRACE(ddraw, "(%p)->(%p)\n", this, lpMat);
+  if (TRACE_ON(ddraw))
+    dump_material(lpMat);
+  
+  /* Stores the material */
+  this->mat = *lpMat;
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DMaterial2_GetHandle(LPDIRECT3DMATERIAL2 this,
+						   LPDIRECT3DDEVICE2 lpD3DDevice2,
+						   LPD3DMATERIALHANDLE lpMatHandle)
+
+{
+  FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DDevice2, lpMatHandle);
+
+  if (this->use_d3d2)
+    this->device.active_device2 = lpD3DDevice2;
+  else
+    this->device.active_device1 = (LPDIRECT3DDEVICE) lpD3DDevice2;
+  
+  *lpMatHandle = (DWORD) this; /* lpD3DDevice2->store_material(this); */
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DMaterial_Reserve(LPDIRECT3DMATERIAL this)
+{
+  FIXME(ddraw, "(%p)->(): stub\n", this);
+
+  return DDERR_INVALIDPARAMS;
+}
+						  
+static HRESULT WINAPI IDirect3DMaterial_Unreserve(LPDIRECT3DMATERIAL this)
+{
+  FIXME(ddraw, "(%p)->(): stub\n", this);
+
+  return DDERR_INVALIDPARAMS;
+}
+
+static HRESULT WINAPI IDirect3DMaterial_Initialize(LPDIRECT3DMATERIAL this,
+						   LPDIRECT3D lpDirect3D)
+
+{
+  TRACE(ddraw, "(%p)->(%p)\n", this, lpDirect3D);
+  
+  return DDERR_ALREADYINITIALIZED;
+}
+
+
+/*******************************************************************************
+ *				IDirect3DMaterial VTable
+ */
+static IDirect3DMaterial_VTable material_vtable = {
+  /*** IUnknown methods ***/
+  IDirect3DMaterial2_QueryInterface,
+  IDirect3DMaterial2_AddRef,
+  IDirect3DMaterial2_Release,
+  /*** IDirect3DMaterial methods ***/
+  IDirect3DMaterial_Initialize,
+  IDirect3DMaterial2_SetMaterial,
+  IDirect3DMaterial2_GetMaterial,
+  IDirect3DMaterial2_GetHandle,
+  IDirect3DMaterial_Reserve,
+  IDirect3DMaterial_Unreserve
+};
+
+
+/*******************************************************************************
+ *				IDirect3DMaterial2 VTable
+ */
+static IDirect3DMaterial2_VTable material2_vtable = {
+  /*** IUnknown methods ***/
+  IDirect3DMaterial2_QueryInterface,
+  IDirect3DMaterial2_AddRef,
+  IDirect3DMaterial2_Release,
+  /*** IDirect3DMaterial methods ***/
+  IDirect3DMaterial2_SetMaterial,
+  IDirect3DMaterial2_GetMaterial,
+  IDirect3DMaterial2_GetHandle
+};
+
+#else /* HAVE_MESAGL */
+
+LPDIRECT3DMATERIAL d3dmaterial_create(LPDIRECT3D d3d) {
+  ERR(ddraw, "Should not be called...\n");
+  return NULL;
+}
+
+LPDIRECT3DMATERIAL2 d3dmaterial2_create(LPDIRECT3D2 d3d) {
+  ERR(ddraw, "Should not be called...\n");
+  return NULL;
+}
+
+
+#endif /* HAVE_MESAGL */
diff --git a/graphics/d3dtexture.c b/graphics/d3dtexture.c
new file mode 100644
index 0000000..f79ba15
--- /dev/null
+++ b/graphics/d3dtexture.c
@@ -0,0 +1,200 @@
+/* Direct3D Texture
+   (c) 1998 Lionel ULMER
+   
+   This files contains the implementation of interface Direct3DTexture2. */
+
+
+#include "config.h"
+#include "windows.h"
+#include "wintypes.h"
+#include "winerror.h"
+#include "interfaces.h"
+#include "heap.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debug.h"
+
+#include "d3d_private.h"
+
+#ifdef HAVE_MESAGL
+
+static IDirect3DTexture2_VTable texture2_vtable;
+static IDirect3DTexture_VTable texture_vtable;
+
+/*******************************************************************************
+ *				Texture2 Creation functions
+ */
+LPDIRECT3DTEXTURE2 d3dtexture2_create(LPDIRECTDRAWSURFACE3 surf)
+{
+  LPDIRECT3DTEXTURE2 mat;
+  
+  mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture2));
+  mat->ref = 1;
+  mat->lpvtbl = &texture2_vtable;
+  mat->surface = surf;
+  
+  return mat;
+}
+
+/*******************************************************************************
+ *				Texture Creation functions
+ */
+LPDIRECT3DTEXTURE d3dtexture_create(LPDIRECTDRAWSURFACE3 surf)
+{
+  LPDIRECT3DTEXTURE mat;
+  
+  mat = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DTexture));
+  mat->ref = 1;
+  mat->lpvtbl = (IDirect3DTexture2_VTable*) &texture_vtable;
+  mat->surface = surf;
+  
+  return mat;
+}
+
+
+/*******************************************************************************
+ *				IDirect3DTexture2 methods
+ */
+
+static HRESULT WINAPI IDirect3DTexture2_QueryInterface(LPDIRECT3DTEXTURE2 this,
+							REFIID riid,
+							LPVOID* ppvObj)
+{
+  char xrefiid[50];
+  
+  WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
+  FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
+  
+  return S_OK;
+}
+
+
+
+static ULONG WINAPI IDirect3DTexture2_AddRef(LPDIRECT3DTEXTURE2 this)
+{
+  TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
+  
+  return ++(this->ref);
+}
+
+
+
+static ULONG WINAPI IDirect3DTexture2_Release(LPDIRECT3DTEXTURE2 this)
+{
+  FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+  
+  if (!--(this->ref)) {
+    HeapFree(GetProcessHeap(),0,this);
+    return 0;
+  }
+  
+  return this->ref;
+}
+
+/*** IDirect3DTexture methods ***/
+static HRESULT WINAPI IDirect3DTexture_GetHandle(LPDIRECT3DTEXTURE this,
+						 LPDIRECT3DDEVICE lpD3DDevice,
+						 LPD3DTEXTUREHANDLE lpHandle)
+{
+  FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DDevice, lpHandle);
+
+  *lpHandle = (DWORD) this->surface;
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DTexture_Initialize(LPDIRECT3DTEXTURE this,
+						  LPDIRECT3DDEVICE lpD3DDevice,
+						  LPDIRECTDRAWSURFACE lpSurface)
+{
+  TRACE(ddraw, "(%p)->(%p,%p)\n", this, lpD3DDevice, lpSurface);
+
+  return DDERR_ALREADYINITIALIZED;
+}
+
+static HRESULT WINAPI IDirect3DTexture_Unload(LPDIRECT3DTEXTURE this)
+{
+  FIXME(ddraw, "(%p)->(): stub\n", this);
+
+  return DD_OK;
+}
+
+/*** IDirect3DTexture2 methods ***/
+static HRESULT WINAPI IDirect3DTexture2_GetHandle(LPDIRECT3DTEXTURE2 this,
+						  LPDIRECT3DDEVICE2 lpD3DDevice2,
+						  LPD3DTEXTUREHANDLE lpHandle)
+{
+  FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DDevice2, lpHandle);
+
+  *lpHandle = (DWORD) this->surface; /* lpD3DDevice2->store_texture(this); */
+  
+  return DD_OK;
+}
+
+/* Common methods */
+static HRESULT WINAPI IDirect3DTexture2_PaletteChanged(LPDIRECT3DTEXTURE2 this,
+						       DWORD dwStart,
+						       DWORD dwCount)
+{
+  FIXME(ddraw, "(%p)->(%8ld,%8ld): stub\n", this, dwStart, dwCount);
+
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DTexture2_Load(LPDIRECT3DTEXTURE2 this,
+					     LPDIRECT3DTEXTURE2 lpD3DTexture2)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpD3DTexture2);
+
+  /* Hack ? */
+  FIXME(ddraw, "Sthis %p / Sload %p\n", this->surface, lpD3DTexture2->surface);
+  this->surface->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
+  
+  return DD_OK;
+}
+
+
+/*******************************************************************************
+ *				IDirect3DTexture2 VTable
+ */
+static IDirect3DTexture2_VTable texture2_vtable = {
+  /*** IUnknown methods ***/
+  IDirect3DTexture2_QueryInterface,
+  IDirect3DTexture2_AddRef,
+  IDirect3DTexture2_Release,
+  /*** IDirect3DTexture methods ***/
+  IDirect3DTexture2_GetHandle,
+  IDirect3DTexture2_PaletteChanged,
+  IDirect3DTexture2_Load
+};
+
+/*******************************************************************************
+ *				IDirect3DTexture VTable
+ */
+static IDirect3DTexture_VTable texture_vtable = {
+  /*** IUnknown methods ***/
+  IDirect3DTexture2_QueryInterface,
+  IDirect3DTexture2_AddRef,
+  IDirect3DTexture2_Release,
+  /*** IDirect3DTexture methods ***/
+  IDirect3DTexture_Initialize,
+  IDirect3DTexture_GetHandle,
+  IDirect3DTexture2_PaletteChanged,
+  IDirect3DTexture2_Load,
+  IDirect3DTexture_Unload
+};
+
+#else /* HAVE_MESAGL */
+
+/* These function should never be called if MesaGL is not present */
+LPDIRECT3DTEXTURE2 d3dtexture2_create(LPDIRECTDRAWSURFACE3 surf) {
+  ERR(ddraw, "Should not be called...\n");
+  return NULL;
+}
+
+LPDIRECT3DTEXTURE d3dtexture_create(LPDIRECTDRAWSURFACE3 surf) {
+  ERR(ddraw, "Should not be called...\n");
+  return NULL;
+}
+
+#endif /* HAVE_MESAGL */
diff --git a/graphics/d3dviewport.c b/graphics/d3dviewport.c
new file mode 100644
index 0000000..754d410
--- /dev/null
+++ b/graphics/d3dviewport.c
@@ -0,0 +1,350 @@
+/* Direct3D Viewport
+   (c) 1998 Lionel ULMER
+   
+   This files contains the implementation of Direct3DViewport2. */
+
+#include "config.h"
+#include "windows.h"
+#include "wintypes.h"
+#include "winerror.h"
+#include "interfaces.h"
+#include "heap.h"
+#include "ddraw.h"
+#include "d3d.h"
+#include "debug.h"
+
+#include "d3d_private.h"
+
+
+#ifdef HAVE_MESAGL
+
+static IDirect3DViewport2_VTable viewport2_vtable;
+
+/*******************************************************************************
+ *				Viewport1/2 static functions
+ */
+static void activate(LPDIRECT3DVIEWPORT2 this) {
+  LPDIRECT3DLIGHT l;
+  
+  /* Activate all the lights associated with this context */
+  l = this->lights;
+
+  while (l != NULL) {
+    l->activate(l);
+    l = l->next;
+  }
+}
+
+/*******************************************************************************
+ *				Viewport1/2 Creation functions
+ */
+LPDIRECT3DVIEWPORT2 d3dviewport2_create(LPDIRECT3D2 d3d)
+{
+  LPDIRECT3DVIEWPORT2 vp;
+  
+  vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2));
+  vp->ref = 1;
+  vp->lpvtbl = &viewport2_vtable;
+  vp->d3d.d3d2 = d3d;
+  vp->use_d3d2 = 1;
+
+  vp->device.active_device2 = NULL;
+  vp->activate = activate;
+
+  vp->lights = NULL;
+
+  vp->nextlight = GL_LIGHT0;
+  
+  return vp;
+}
+
+LPDIRECT3DVIEWPORT d3dviewport_create(LPDIRECT3D d3d)
+{
+  LPDIRECT3DVIEWPORT2 vp;
+  
+  vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2));
+  vp->ref = 1;
+  vp->lpvtbl = &viewport2_vtable;
+  vp->d3d.d3d1 = d3d;
+  vp->use_d3d2 = 0;
+
+  vp->device.active_device1 = NULL;
+  vp->activate = activate;
+
+  vp->lights = NULL;
+
+  vp->nextlight = GL_LIGHT0;
+  
+  return (LPDIRECT3DVIEWPORT) vp;
+}
+
+/*******************************************************************************
+ *				IDirect3DViewport2 methods
+ */
+
+static HRESULT WINAPI IDirect3DViewport2_QueryInterface(LPDIRECT3DVIEWPORT2 this,
+							REFIID riid,
+							LPVOID* ppvObj)
+{
+  char xrefiid[50];
+  
+  WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
+  FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
+  
+  return S_OK;
+}
+
+
+
+static ULONG WINAPI IDirect3DViewport2_AddRef(LPDIRECT3DVIEWPORT2 this)
+{
+  TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
+  
+  return ++(this->ref);
+}
+
+
+
+static ULONG WINAPI IDirect3DViewport2_Release(LPDIRECT3DVIEWPORT2 this)
+{
+  FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
+  
+  if (!--(this->ref)) {
+    HeapFree(GetProcessHeap(),0,this);
+    return 0;
+  }
+  
+  return this->ref;
+}
+
+/*** IDirect3DViewport methods ***/
+static HRESULT WINAPI IDirect3DViewport2_Initialize(LPDIRECT3DVIEWPORT2 this,
+						    LPDIRECT3D d3d)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, d3d);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_GetViewport(LPDIRECT3DVIEWPORT2 this,
+						     LPD3DVIEWPORT lpvp)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
+  
+  if (this->use_vp2 != 0)
+    return DDERR_INVALIDPARAMS;
+
+  *lpvp = this->viewport.vp1;
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_SetViewport(LPDIRECT3DVIEWPORT2 this,
+						     LPD3DVIEWPORT lpvp)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
+
+  this->use_vp2 = 0;
+  this->viewport.vp1 = *lpvp;
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_TransformVertices(LPDIRECT3DVIEWPORT2 this,
+							   DWORD dwVertexCount,
+							   LPD3DTRANSFORMDATA lpData,
+							   DWORD dwFlags,
+							   LPDWORD lpOffScreen)
+{
+  FIXME(ddraw, "(%p)->(%8ld,%p,%08lx,%p): stub\n",
+	this, dwVertexCount, lpData, dwFlags, lpOffScreen);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_LightElements(LPDIRECT3DVIEWPORT2 this,
+						       DWORD dwElementCount,
+						       LPD3DLIGHTDATA lpData)
+{
+  FIXME(ddraw, "(%p)->(%8ld,%p): stub\n", this, dwElementCount, lpData);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_SetBackground(LPDIRECT3DVIEWPORT2 this,
+						       D3DMATERIALHANDLE hMat)
+{
+  FIXME(ddraw, "(%p)->(%08x): stub\n", this, hMat);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_GetBackground(LPDIRECT3DVIEWPORT2 this,
+						       LPD3DMATERIALHANDLE lphMat,
+						       LPBOOL lpValid)
+{
+  FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lphMat, lpValid);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_SetBackgroundDepth(LPDIRECT3DVIEWPORT2 this,
+							    LPDIRECTDRAWSURFACE lpDDSurface)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpDDSurface);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_GetBackgroundDepth(LPDIRECT3DVIEWPORT2 this,
+							    LPDIRECTDRAWSURFACE* lplpDDSurface,
+							    LPBOOL lpValid)
+{
+  FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lplpDDSurface, lpValid);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_Clear(LPDIRECT3DVIEWPORT2 this,
+					       DWORD dwCount,
+					       LPD3DRECT lpRects,
+					       DWORD dwFlags)
+{
+  FIXME(ddraw, "(%p)->(%8ld,%p,%08lx): stub\n", this, dwCount, lpRects, dwFlags);
+
+  /* For the moment, ignore the rectangles */
+  if (this->device.active_device1 != NULL) {
+    /* Get the rendering context */
+    if (this->use_d3d2)
+      this->device.active_device2->set_context(this->device.active_device2);
+    else
+      this->device.active_device1->set_context(this->device.active_device1);
+
+    /* Clears the screen */
+    glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  }
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_AddLight(LPDIRECT3DVIEWPORT2 this,
+						  LPDIRECT3DLIGHT lpLight)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpLight);
+
+  /* Add the light in the 'linked' chain */
+  lpLight->next = this->lights;
+  this->lights = lpLight;
+
+  /* If active, activate the light */
+  if (this->device.active_device1 != NULL) {
+    /* Get the rendering context */
+    if (this->use_d3d2)
+      this->device.active_device2->set_context(this->device.active_device2);
+    else
+      this->device.active_device1->set_context(this->device.active_device1);
+    
+    /* Activate the light */
+    lpLight->light_num = this->nextlight++;
+    lpLight->activate(lpLight);
+  }
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_DeleteLight(LPDIRECT3DVIEWPORT2 this,
+						     LPDIRECT3DLIGHT lpLight)
+{
+  FIXME(ddraw, "(%p)->(%p): stub\n", this, lpLight);
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_NextLight(LPDIRECT3DVIEWPORT2 this,
+						   LPDIRECT3DLIGHT lpLight,
+						   LPDIRECT3DLIGHT* lplpLight,
+						   DWORD dwFlags)
+{
+  FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpLight, lplpLight, dwFlags);
+  
+  return DD_OK;
+}
+
+/*** IDirect3DViewport2 methods ***/
+static HRESULT WINAPI IDirect3DViewport2_GetViewport2(LPDIRECT3DVIEWPORT2 this,
+						      LPD3DVIEWPORT2 lpViewport2)
+{
+  TRACE(ddraw, "(%p)->(%p)\n", this, lpViewport2);
+
+  if (this->use_vp2 != 1)
+    return DDERR_INVALIDPARAMS;
+
+  *lpViewport2 = this->viewport.vp2;
+  
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3DViewport2_SetViewport2(LPDIRECT3DVIEWPORT2 this,
+						      LPD3DVIEWPORT2 lpViewport2)
+{
+  TRACE(ddraw, "(%p)->(%p)\n", this, lpViewport2);
+
+  TRACE(ddraw, "dwSize = %ld   dwX = %ld   dwY = %ld\n",
+	lpViewport2->dwSize, lpViewport2->dwX, lpViewport2->dwY);
+  TRACE(ddraw, "dwWidth = %ld   dwHeight = %ld\n",
+	lpViewport2->dwWidth, lpViewport2->dwHeight);
+  TRACE(ddraw, "dvClipX = %f   dvClipY = %f\n",
+	lpViewport2->dvClipX, lpViewport2->dvClipY);
+  TRACE(ddraw, "dvClipWidth = %f   dvClipHeight = %f\n",
+	lpViewport2->dvClipWidth, lpViewport2->dvClipHeight);
+  TRACE(ddraw, "dvMinZ = %f   dvMaxZ = %f\n",
+	lpViewport2->dvMinZ, lpViewport2->dvMaxZ);
+
+  this->viewport.vp2 = *lpViewport2;
+  this->use_vp2 = 1;
+  
+  return DD_OK;
+}
+
+
+/*******************************************************************************
+ *				IDirect3DViewport1/2 VTable
+ */
+static IDirect3DViewport2_VTable viewport2_vtable = {
+  /*** IUnknown methods ***/
+  IDirect3DViewport2_QueryInterface,
+  IDirect3DViewport2_AddRef,
+  IDirect3DViewport2_Release,
+  /*** IDirect3DViewport methods ***/
+  IDirect3DViewport2_Initialize,
+  IDirect3DViewport2_GetViewport,
+  IDirect3DViewport2_SetViewport,
+  IDirect3DViewport2_TransformVertices,
+  IDirect3DViewport2_LightElements,
+  IDirect3DViewport2_SetBackground,
+  IDirect3DViewport2_GetBackground,
+  IDirect3DViewport2_SetBackgroundDepth,
+  IDirect3DViewport2_GetBackgroundDepth,
+  IDirect3DViewport2_Clear,
+  IDirect3DViewport2_AddLight,
+  IDirect3DViewport2_DeleteLight,
+  IDirect3DViewport2_NextLight,
+  /*** IDirect3DViewport2 methods ***/
+  IDirect3DViewport2_GetViewport2,
+  IDirect3DViewport2_SetViewport2
+};
+
+#else /* HAVE_MESAGL */
+
+LPDIRECT3DVIEWPORT d3dviewport_create(LPDIRECT3D d3d) {
+  ERR(ddraw, "Should not be called...\n");
+  return NULL;
+}
+
+LPDIRECT3DVIEWPORT2 d3dviewport2_create(LPDIRECT3D2 d3d) {
+  ERR(ddraw, "Should not be called...\n");
+  return NULL;
+}
+
+#endif /* HAVE_MESAGL */
diff --git a/graphics/ddraw.c b/graphics/ddraw.c
index 474d2b0..e0a61b3 100644
--- a/graphics/ddraw.c
+++ b/graphics/ddraw.c
@@ -1,6 +1,7 @@
 /*		DirectDraw using DGA or Xlib(XSHM)
  *
  * Copyright 1997,1998 Marcus Meissner
+ * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
  */
 /* XF86DGA:
  * When DirectVideo mode is enabled you can no longer use 'normal' X 
@@ -59,6 +60,9 @@
 #include "ts_xshm.h"
 #endif
 
+/* This for all the enumeration and creation of D3D-related objects */
+#include "d3d_private.h"
+
 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
 #undef DIABLO_HACK
 
@@ -121,10 +125,13 @@
 HRESULT WINAPI
 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
 	if (DDRAW_DGA_Available()) {
+	  TRACE(ddraw, "Enumerating DGA interface\n");
 		ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
 	}
+	TRACE(ddraw, "Enumerating Xlib interface\n");
 	ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
-	ddenumproc(NULL,"WINE","display",data);
+	TRACE(ddraw, "Enumerating Default interface\n");
+	ddenumproc(NULL,"WINE (default)","display",data);
 	return DD_OK;
 }
 
@@ -324,9 +331,11 @@
 }
 
 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
+  DUMP("Size : %ld\n", pf->dwSize);
+  if (pf->dwFlags)
   _dump_DDCOLORKEY(pf->dwFlags);
   DUMP("dwFourCC : %ld\n", pf->dwFourCC);
-  DUMP("RBG bit cbout : %ld\n", pf->x.dwRGBBitCount);
+  DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
   DUMP("Masks : R %08lx  G %08lx  B %08lx  A %08lx\n",
        pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
 }
@@ -340,6 +349,7 @@
 		vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
 
 	pf->dwFourCC = 0;
+	pf->dwSize = sizeof(DDPIXELFORMAT);
 	if (ddraw->d.depth==8) {
 		pf->dwFlags 		= DDPF_RGB|DDPF_PALETTEINDEXED8;
 		pf->x.dwRGBBitCount	= 8;
@@ -585,7 +595,7 @@
 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
 	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
 ) {
-	TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
+	TRACE(ddraw,"(%p)->(%p)\n",this,pal);
 #ifdef HAVE_LIBXXF86DGA
         /* According to spec, we are only supposed to 
          * AddRef if this is not the same palette.
@@ -701,16 +711,49 @@
 		       ddesc.dwHeight * ddesc.lPitch);
 	} else {
 	  int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
-	  int height = xsrc.bottom - xsrc.top;
+	  int srcheight = xsrc.bottom - xsrc.top;
+	  int srcwidth = xsrc.right - xsrc.left;
+	  int dstheight = xdst.bottom - xdst.top;
+	  int dstwidth = xdst.right - xdst.left;
 	  int width = (xsrc.right - xsrc.left) * bpp;
 	  int h;
 
-	  for (h = 0; h < height; h++) {
+	  /* Sanity check for rectangle sizes */
+	  if ((srcheight != dstheight) || (srcwidth  != dstwidth)) {
+	    int x, y;
+	    
+	    /* I think we should do a Blit with 'stretching' here....
+	       Tomb Raider II uses this to display the background during the menu selection
+	       when the screen resolution is != than 40x480 */
+	    TRACE(ddraw, "Blt with stretching\n");
+
+	    /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
+	    if (bpp == 1) {
+	      /* In this case, we cannot do any anti-aliasing */
+	      for (y = xdst.top; y < xdst.bottom; y++) {
+		for (x = xdst.left; x < xdst.right; x++) {
+		  double sx, sy;
+		  unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
+		  unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
+
+		  sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
+		  sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
+		  
+		  dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
+		}
+	      }
+	    } else {
+	      FIXME(ddraw, "Not done yet for depth != 8\n");
+	    }
+	  } else {
+	    /* Same size => fast blit */
+	    for (h = 0; h < srcheight; h++) {
 	    memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
 		   sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
 		   width);
 	  }
 	}
+	}
 	
 	if (dwFlags && FIXME_ON(ddraw)) {
 	  FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
@@ -956,8 +999,41 @@
 	) {
 		*obj = this;
 		this->lpvtbl->fnAddRef(this);
+
+		TRACE(ddraw, "  Creating IDirect3DSurfaceX interface (%p)\n", *obj);
+		
 		return S_OK;
 	}
+	else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
+	  {
+	    /* Texture interface */
+	    *obj = d3dtexture2_create(this);
+	    this->lpvtbl->fnAddRef(this);
+	    
+	    TRACE(ddraw, "  Creating IDirect3DTexture2 interface (%p)\n", *obj);
+	    
+	    return S_OK;
+	  }
+	else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
+	  {
+	    /* Texture interface */
+	    *obj = d3dtexture_create(this);
+	    this->lpvtbl->fnAddRef(this);
+	    
+	    TRACE(ddraw, "  Creating IDirect3DTexture interface (%p)\n", *obj);
+	    
+	    return S_OK;
+	  }
+	else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj))
+	  {
+	    /* It is the OpenGL Direct3D Device */
+	    this->lpvtbl->fnAddRef(this);
+
+	    TRACE(ddraw, "  Creating IDirect3DDevice interface (%p)\n", *obj);
+			
+		return S_OK;
+	}
+	
 	FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
 	return OLE_E_ENUM_NOMORE;
 }
@@ -1159,6 +1235,9 @@
 {
   FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
 
+  /* Not sure about that... */
+  *lplpDD = (void *) this->s.ddraw;
+  
   return DD_OK;
 }
 
@@ -1554,6 +1633,9 @@
         if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
                 *obj = this;
                 this->lpvtbl->fnAddRef(this);
+
+		TRACE(ddraw, "  Creating IUnknown interface (%p)\n", *obj);
+		
                 return S_OK;
         }
         if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
@@ -1565,6 +1647,9 @@
                 this->lpvtbl->fnAddRef(this);
                 d3d->lpvtbl = &d3dvt;
                 *obj = d3d;
+
+		TRACE(ddraw, "  Creating IDirect3D interface (%p)\n", *obj);
+
                 return S_OK;
         }
         if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
@@ -1576,6 +1661,9 @@
                 this->lpvtbl->fnAddRef(this);
                 d3d->lpvtbl = &d3d2vt;
                 *obj = d3d;
+
+		TRACE(ddraw, "  Creating IDirect3D2 interface (%p)\n", *obj);
+
                 return S_OK;
         }
         FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
@@ -1612,61 +1700,63 @@
   return DDERR_ALREADYINITIALIZED;
 }
 
-static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,LPDIRECT3DLIGHT *light,IUnknown* lpunk) {
-    FIXME(ddraw,"(%p)->(%p,%p)\n",this,light,lpunk);
-    return E_FAIL;
-}
+static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this,
+					    LPD3DENUMDEVICESCALLBACK cb,
+					    LPVOID context) {
+  FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
 
-typedef LPVOID LPDIRECT3DDEVICE;
+  /* Call functions defined in d3ddevices.c */
+  if (d3d_OpenGL_dx3(cb, context))
+    return DD_OK;
 
-static HRESULT WINAPI IDirect3D_CreateDevice(LPDIRECT3D this,LPCLSID rclsid,LPDIRECTDRAWSURFACE surf,LPDIRECT3DDEVICE *d3dev) {
-  char    xclsid[50];
-
-  WINE_StringFromCLSID(rclsid,xclsid);
-  FIXME(ddraw,"(%p)->(%s,%p,%p), no Direct3D devices implemented yet!\n",this,xclsid,surf,d3dev);
-  return E_FAIL; /* D3DERR_INVALID_DEVICE probably */
-}
-
-static HRESULT WINAPI IDirect3D_EnumDevices(
-         LPDIRECT3D this,
-         LPD3DENUMDEVICESCALLBACK a,
-         LPVOID b )
-{
-  FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
   return DD_OK;
 }
 
-static HRESULT WINAPI IDirect3D_CreateMaterial(
-         LPDIRECT3D this,
-         LPDIRECT3DMATERIAL* a,
-         IUnknown* b)
+static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,
+					    LPDIRECT3DLIGHT *lplight,
+					    IUnknown *lpunk)
 {
-  FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
+  TRACE(ddraw, "(%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 IDirect3D_CreateViewport(
-         LPDIRECT3D this,
-         LPDIRECT3DVIEWPORT* a,
-         IUnknown* b )
+static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this,
+					       LPDIRECT3DMATERIAL *lpmaterial,
+					       IUnknown *lpunk)
 {
-  FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
+  TRACE(ddraw, "(%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 IDirect3D_FindDevice(
-         LPDIRECT3D this,
-         LPD3DFINDDEVICESEARCH a,
-         LPD3DFINDDEVICERESULT b )
+static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this,
+					       LPDIRECT3DVIEWPORT *lpviewport,
+					       IUnknown *lpunk)
 {
-  FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
+  TRACE(ddraw, "(%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 IDirect3D_FindDevice(LPDIRECT3D this,
+					   LPD3DFINDDEVICESEARCH lpfinddevsrc,
+					   LPD3DFINDDEVICERESULT lpfinddevrst)
+{
+  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
+  
+  return DD_OK;
+}
 
-/*******************************************************************************
- *				IDirect3D
- */
 static struct IDirect3D_VTable d3dvt = {
         IDirect3D_QueryInterface,
         IDirect3D_AddRef,
@@ -1676,12 +1766,26 @@
         IDirect3D_CreateLight,
         IDirect3D_CreateMaterial,
         IDirect3D_CreateViewport,
-        IDirect3D_FindDevice,
+	IDirect3D_FindDevice
 };
 
 /*******************************************************************************
  *				IDirect3D2
  */
+static HRESULT WINAPI IDirect3D2_QueryInterface(
+        LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) {
+  /* For the moment, we use the same function as in IDirect3D */
+  TRACE(ddraw, "Calling IDirect3D enumerating function.\n");
+  
+  return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj);
+}
+
+static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) {
+        TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
+
+        return ++(this->ref);
+}
+
 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
 
@@ -1696,43 +1800,88 @@
 static HRESULT WINAPI IDirect3D2_EnumDevices(
 	LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
 ) {
-	D3DDEVICEDESC	d1,d2;
-
 	FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
-#if 0
-	d1.dwSize	= sizeof(d1);
-	d1.dwFlags	= 0;
 
-	d2.dwSize	= sizeof(d2);
-	d2.dwFlags	= 0;
-	cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
-#endif
+	/* Call functions defined in d3ddevices.c */
+	if (d3d_OpenGL(cb, context))
+	  return DD_OK;
+
 	return DD_OK;
 }
 
-static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,REFCLSID rclsid,LPDIRECTDRAWSURFACE surf,LPDIRECT3DDEVICE2 *d3dev) {
-  char    xclsid[50];
+static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,
+					     LPDIRECT3DLIGHT *lplight,
+					     IUnknown *lpunk)
+{
+  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
 
-  WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
-  FIXME(ddraw,"(%p)->(%s,%p,%p), no Direct3D devices implemented yet!\n",this,xclsid,surf,d3dev);
-  return E_FAIL; /* D3DERR_INVALID_DEVICE probably */
+  /* Call the creation function that is located in d3dlight.c */
+  *lplight = d3dlight_create(this);
+  
+	return DD_OK;
 }
 
-static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,LPDIRECT3DLIGHT *light,IUnknown* lpunk) {
-    FIXME(ddraw,"(%p)->(%p,%p)\n",this,light,lpunk);
-    return E_FAIL;
+static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this,
+						LPDIRECT3DMATERIAL2 *lpmaterial,
+						IUnknown *lpunk)
+{
+  TRACE(ddraw, "(%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 IDirect3D2_CreateViewport(LPDIRECT3D2 this,
+						LPDIRECT3DVIEWPORT2 *lpviewport,
+						IUnknown *lpunk)
+{
+  TRACE(ddraw, "(%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 IDirect3D2_FindDevice(LPDIRECT3D2 this,
+					    LPD3DFINDDEVICESEARCH lpfinddevsrc,
+					    LPD3DFINDDEVICERESULT lpfinddevrst)
+{
+  TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
+
+  return DD_OK;
+}
+
+static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,
+					      REFCLSID rguid,
+					      LPDIRECTDRAWSURFACE surface,
+					      LPDIRECT3DDEVICE2 *device)
+{
+  char	xbuf[50];
+  
+  WINE_StringFromCLSID(rguid,xbuf);
+  FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device);
+
+  if (is_OpenGL(rguid, surface, device, this)) {
+    this->lpvtbl->fnAddRef(this);
+    return DD_OK;
+}
+
+  return DDERR_INVALIDPARAMS;
 }
 
 static struct IDirect3D2_VTable d3d2vt = {
-        (void*)IDirect3D_QueryInterface,
-        (void*)IDirect3D_AddRef,
+	IDirect3D2_QueryInterface,
+	IDirect3D2_AddRef,
         IDirect3D2_Release,
         IDirect3D2_EnumDevices,
-        (void*)IDirect3D_EnumDevices,
-        (void*)IDirect3D_CreateLight,
-        (void*)IDirect3D_CreateMaterial,
-        (void*)IDirect3D_CreateViewport,
-        (void*)IDirect3D_FindDevice,
+	IDirect3D2_CreateLight,
+	IDirect3D2_CreateMaterial,
+	IDirect3D2_CreateViewport,
+	IDirect3D2_FindDevice,
+	IDirect3D2_CreateDevice
 };
 
 /*******************************************************************************
@@ -1751,6 +1900,13 @@
   int bpp;
   
   /* The surface was already allocated when entering in this function */
+  TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
+
+  if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
+    /* This is a Z Buffer */
+    bpp = lpddsd->x.dwZBufferBitDepth;
+  } else {
+    /* This is a standard image */
   if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
     /* No pixel format => use DirectDraw's format */
     _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
@@ -1761,8 +1917,13 @@
       _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
     }
   }
+  }
 
+  if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
+    bpp = 1;
+  } else {
   bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
+  }
 
   /* Copy the surface description */
   lpdsf->s.surface_desc = *lpddsd;
@@ -1771,8 +1932,6 @@
   lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
   lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
   
-  TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
-
   return DD_OK;
 }
 
@@ -2085,6 +2244,11 @@
 	  TRACE(ddraw,"	cooperative level %s\n", dbg_str(ddraw));
 	}
         this->d.mainWindow = hwnd;
+
+	/* This will be overwritten in the case of Full Screen mode.
+	   Windowed games could work with that :-) */
+	this->e.xlib.drawable  = ((X11DRV_WND_DATA *) WIN_FindWndPtr(hwnd)->pDriverData)->window;
+
 	return DD_OK;
 }
 
@@ -2276,20 +2440,45 @@
 #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_3D | DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
+    DDCAPS_CANBLTSYSMEM | DDCAPS_PALETTE | DDCAPS_ZBLTS;
+  caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NO2DDURING3DSCENE | DDCAPS2_NOPAGELOCKREQUIRED |
+    DDCAPS2_WIDESURFACES;
+  caps->dwCKeyCaps = 0;
+  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_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
+    DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
+      DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE |
+	DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE | DDSCAPS_ZBUFFER;
+}
+
 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
 	LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
 )  {
 	TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
-	/* FIXME: Xlib */
-	caps1->dwVidMemTotal = 2048*1024;
-	caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
-	caps1->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
-	if (caps2) {
-		caps2->dwVidMemTotal = 2048*1024;
-		caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
-		caps2->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
-	}
-	/* END FIXME: Xlib */
+
+	/* Put the same caps for the two capabilities */
+	fill_caps(caps1);
+	fill_caps(caps2);
+
 	return DD_OK;
 }
 
@@ -2325,7 +2514,6 @@
                 /* Initialize the palette based on the passed palent struct */
                 FIXME(ddraw,"needs to handle palent (%p)\n",palent);
         }
-
 	return DD_OK;
 }
 
@@ -2370,7 +2558,7 @@
 #ifdef RESTORE_SIGNALS
 	SIGNAL_InitEmulator();
 #endif
-	return 0;
+	return DD_OK;
 #else /* defined(HAVE_LIBXXF86DGA) */
 	return E_UNEXPECTED;
 #endif
@@ -2442,18 +2630,27 @@
 	if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
 		*obj = this;
 		this->lpvtbl->fnAddRef(this);
+
+		TRACE(ddraw, "  Creating IUnknown interface (%p)\n", *obj);
+		
 		return S_OK;
 	}
 	if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
 		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
 		this->lpvtbl->fnAddRef(this);
 		*obj = this;
+
+		TRACE(ddraw, "  Creating IDirectDraw interface (%p)\n", *obj);
+		
 		return S_OK;
 	}
 	if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
 		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
 		this->lpvtbl->fnAddRef(this);
 		*obj = this;
+
+		TRACE(ddraw, "  Creating IDirectDraw2 interface (%p)\n", *obj);
+
 		return S_OK;
 	}
 	if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
@@ -2465,6 +2662,9 @@
 		this->lpvtbl->fnAddRef(this);
 		d3d->lpvtbl = &d3dvt;
 		*obj = d3d;
+
+		TRACE(ddraw, "  Creating IDirect3D interface (%p)\n", *obj);
+		
 		return S_OK;
 	}
 	if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
@@ -2476,6 +2676,9 @@
 		this->lpvtbl->fnAddRef(this);
 		d3d->lpvtbl = &d3d2vt;
 		*obj = d3d;
+
+		TRACE(ddraw, "  Creating IDirect3D2 interface (%p)\n", *obj);
+		
 		return S_OK;
 	}
 	WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
@@ -2492,18 +2695,27 @@
 	if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
 		*obj = this;
 		this->lpvtbl->fnAddRef(this);
+
+		TRACE(ddraw, "  Creating IUnknown interface (%p)\n", *obj);
+		
 		return S_OK;
 	}
 	if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
 		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
 		this->lpvtbl->fnAddRef(this);
 		*obj = this;
+
+		TRACE(ddraw, "  Creating IDirectDraw interface (%p)\n", *obj);
+		
 		return S_OK;
 	}
 	if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
 		this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
 		this->lpvtbl->fnAddRef(this);
 		*obj = this;
+
+		TRACE(ddraw, "  Creating IDirectDraw2 interface (%p)\n", *obj);
+		
 		return S_OK;
 	}
 	if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
@@ -2515,6 +2727,9 @@
 		this->lpvtbl->fnAddRef(this);
 		d3d->lpvtbl = &d3dvt;
 		*obj = d3d;
+
+		TRACE(ddraw, "  Creating IDirect3D interface (%p)\n", *obj);
+
 		return S_OK;
 	}
 	if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
@@ -2526,6 +2741,9 @@
 		this->lpvtbl->fnAddRef(this);
 		d3d->lpvtbl = &d3d2vt;
 		*obj = d3d;
+
+		TRACE(ddraw, "  Creating IDirect3D2 interface (%p)\n", *obj);
+
 		return S_OK;
 	}
 	WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
@@ -2683,10 +2901,8 @@
 
 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
 	LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
-) 
-{
+) {
   FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
-
   return DD_OK;
 }
 
diff --git a/include/acconfig.h b/include/acconfig.h
index f1cf877..35c7acf 100644
--- a/include/acconfig.h
+++ b/include/acconfig.h
@@ -72,3 +72,5 @@
 /* Define if IPX includes are taken from Linux kernel */
 #undef HAVE_IPX_LINUX
 
+/* Define if Mesa is present on the system or not */
+#undef HAVE_MESAGL
diff --git a/include/config.h.in b/include/config.h.in
index 309b5f2..75367e9 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -75,6 +75,9 @@
 /* Define if IPX includes are taken from Linux kernel */
 #undef HAVE_IPX_LINUX
 
+/* Define if Mesa is present on the system or not */
+#undef HAVE_MESAGL
+
 /* The number of bytes in a long long.  */
 #undef SIZEOF_LONG_LONG
 
diff --git a/include/d3d.h b/include/d3d.h
index 3cc1857..d572933 100644
--- a/include/d3d.h
+++ b/include/d3d.h
@@ -3,9 +3,13 @@
 
 #include "ddraw.h"
 
-typedef LPVOID LPDIRECT3DMATERIAL,LPDIRECT3DVIEWPORT;
-typedef LPVOID LPDIRECT3DMATERIAL2,LPDIRECT3DVIEWPORT2;
-typedef LPVOID LPDIRECT3DDEVICE2;
+/* This is needed for GL_LIGHT */
+#ifdef HAVE_MESAGL
+#include "wine_gl.h"
+#endif
+
+typedef BOOL32 *LPBOOL;
+typedef BOOL32 BOOL;
 
 DEFINE_GUID(IID_IDirect3D,		0x3BBA0080,0x2421,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56 );
 DEFINE_GUID(IID_IDirect3D2,		0x6aae1ec1,0x662a,0x11d0,0x88,0x9d,0x00,0xaa,0x00,0xbb,0xb7,0x6a);
@@ -29,6 +33,169 @@
 typedef struct IDirect3D	IDirect3D ,*LPDIRECT3D ;
 typedef struct IDirect3D2	IDirect3D2,*LPDIRECT3D2;
 typedef struct IDirect3DLight	IDirect3DLight,*LPDIRECT3DLIGHT;
+typedef struct IDirect3DDevice        IDirect3DDevice, *LPDIRECT3DDEVICE;
+typedef struct IDirect3DDevice2       IDirect3DDevice2, *LPDIRECT3DDEVICE2;
+typedef struct IDirect3DViewport2     IDirect3DViewport, IDirect3DViewport2, *LPDIRECT3DVIEWPORT2, *LPDIRECT3DVIEWPORT;
+typedef struct IDirect3DMaterial2     IDirect3DMaterial, *LPDIRECT3DMATERIAL, IDirect3DMaterial2, *LPDIRECT3DMATERIAL2;
+typedef struct IDirect3DTexture2      IDirect3DTexture, *LPDIRECT3DTEXTURE, IDirect3DTexture2,  *LPDIRECT3DTEXTURE2;
+typedef struct IDirect3DExecuteBuffer IDirect3DExecuteBuffer, *LPDIRECT3DEXECUTEBUFFER;
+
+/* ********************************************************************
+   Enums
+   ******************************************************************** */
+#define D3DNEXT_NEXT 0x01l
+#define D3DNEXT_HEAD 0x02l
+#define D3DNEXT_TAIL 0x04l
+
+typedef enum {
+  D3DLIGHT_POINT          = 1,
+  D3DLIGHT_SPOT           = 2,
+  D3DLIGHT_DIRECTIONAL    = 3,
+  D3DLIGHT_PARALLELPOINT  = 4,
+  D3DLIGHT_FORCE_DWORD    = 0x7fffffff, /* force 32-bit size enum */
+} D3DLIGHTTYPE;
+
+typedef enum {
+  D3DPT_POINTLIST     = 1,
+  D3DPT_LINELIST      = 2,
+  D3DPT_LINESTRIP     = 3,
+  D3DPT_TRIANGLELIST  = 4,
+  D3DPT_TRIANGLESTRIP = 5,
+  D3DPT_TRIANGLEFAN   = 6,
+  D3DPT_FORCE_DWORD   = 0x7fffffff, /* force 32-bit size enum */
+} D3DPRIMITIVETYPE;
+
+typedef enum {
+  D3DRENDERSTATE_TEXTUREHANDLE      = 1,    /* Texture handle */
+  D3DRENDERSTATE_ANTIALIAS          = 2,    /* D3DANTIALIASMODE */
+  D3DRENDERSTATE_TEXTUREADDRESS     = 3,    /* D3DTEXTUREADDRESS      */
+  D3DRENDERSTATE_TEXTUREPERSPECTIVE = 4,    /* TRUE for perspective correction */
+  D3DRENDERSTATE_WRAPU              = 5,    /* TRUE for wrapping in u */
+  D3DRENDERSTATE_WRAPV              = 6,    /* TRUE for wrapping in v */
+  D3DRENDERSTATE_ZENABLE            = 7,    /* TRUE to enable z test */
+  D3DRENDERSTATE_FILLMODE           = 8,    /* D3DFILL_MODE            */
+  D3DRENDERSTATE_SHADEMODE          = 9,    /* D3DSHADEMODE */
+  D3DRENDERSTATE_LINEPATTERN        = 10,   /* D3DLINEPATTERN */
+  D3DRENDERSTATE_MONOENABLE         = 11,   /* TRUE to enable mono rasterization */
+  D3DRENDERSTATE_ROP2               = 12,   /* ROP2 */
+  D3DRENDERSTATE_PLANEMASK          = 13,   /* DWORD physical plane mask */
+  D3DRENDERSTATE_ZWRITEENABLE       = 14,   /* TRUE to enable z writes */
+  D3DRENDERSTATE_ALPHATESTENABLE    = 15,   /* TRUE to enable alpha tests */
+  D3DRENDERSTATE_LASTPIXEL          = 16,   /* TRUE for last-pixel on lines */
+  D3DRENDERSTATE_TEXTUREMAG         = 17,   /* D3DTEXTUREFILTER */
+  D3DRENDERSTATE_TEXTUREMIN         = 18,   /* D3DTEXTUREFILTER */
+  D3DRENDERSTATE_SRCBLEND           = 19,   /* D3DBLEND */
+  D3DRENDERSTATE_DESTBLEND          = 20,   /* D3DBLEND */
+  D3DRENDERSTATE_TEXTUREMAPBLEND    = 21,   /* D3DTEXTUREBLEND */
+  D3DRENDERSTATE_CULLMODE           = 22,   /* D3DCULL */
+  D3DRENDERSTATE_ZFUNC              = 23,   /* D3DCMPFUNC */
+  D3DRENDERSTATE_ALPHAREF           = 24,   /* D3DFIXED */
+  D3DRENDERSTATE_ALPHAFUNC          = 25,   /* D3DCMPFUNC */
+  D3DRENDERSTATE_DITHERENABLE       = 26,   /* TRUE to enable dithering */
+  D3DRENDERSTATE_ALPHABLENDENABLE   = 27,   /* TRUE to enable alpha blending */
+  D3DRENDERSTATE_FOGENABLE          = 28,   /* TRUE to enable fog */
+  D3DRENDERSTATE_SPECULARENABLE     = 29,   /* TRUE to enable specular */
+  D3DRENDERSTATE_ZVISIBLE           = 30,   /* TRUE to enable z checking */
+  D3DRENDERSTATE_SUBPIXEL           = 31,   /* TRUE to enable subpixel correction */
+  D3DRENDERSTATE_SUBPIXELX          = 32,   /* TRUE to enable correction in X only */
+  D3DRENDERSTATE_STIPPLEDALPHA      = 33,   /* TRUE to enable stippled alpha */
+  D3DRENDERSTATE_FOGCOLOR           = 34,   /* D3DCOLOR */
+  D3DRENDERSTATE_FOGTABLEMODE       = 35,   /* D3DFOGMODE */
+  D3DRENDERSTATE_FOGTABLESTART      = 36,   /* Fog table start        */
+  D3DRENDERSTATE_FOGTABLEEND        = 37,   /* Fog table end          */
+  D3DRENDERSTATE_FOGTABLEDENSITY    = 38,   /* Fog table density      */
+  D3DRENDERSTATE_STIPPLEENABLE      = 39,   /* TRUE to enable stippling */
+  D3DRENDERSTATE_EDGEANTIALIAS      = 40,   /* TRUE to enable edge antialiasing */
+  D3DRENDERSTATE_COLORKEYENABLE     = 41,   /* TRUE to enable source colorkeyed textures */
+  D3DRENDERSTATE_BORDERCOLOR        = 43,   /* Border color for texturing w/border */
+  D3DRENDERSTATE_TEXTUREADDRESSU    = 44,   /* Texture addressing mode for U coordinate */
+  D3DRENDERSTATE_TEXTUREADDRESSV    = 45,   /* Texture addressing mode for V coordinate */
+  D3DRENDERSTATE_MIPMAPLODBIAS      = 46,   /* D3DVALUE Mipmap LOD bias */
+  D3DRENDERSTATE_ZBIAS              = 47,   /* LONG Z bias */
+  D3DRENDERSTATE_RANGEFOGENABLE     = 48,   /* Enables range-based fog */
+  D3DRENDERSTATE_ANISOTROPY         = 49,   /* Max. anisotropy. 1 = no anisotropy */
+  D3DRENDERSTATE_FLUSHBATCH         = 50,   /* Explicit flush for DP batching (DX5 Only) */
+  D3DRENDERSTATE_STIPPLEPATTERN00   = 64,   /* Stipple pattern 01...  */
+  D3DRENDERSTATE_STIPPLEPATTERN01   = 65,
+  D3DRENDERSTATE_STIPPLEPATTERN02   = 66,
+  D3DRENDERSTATE_STIPPLEPATTERN03   = 67,
+  D3DRENDERSTATE_STIPPLEPATTERN04   = 68,
+  D3DRENDERSTATE_STIPPLEPATTERN05   = 69,
+  D3DRENDERSTATE_STIPPLEPATTERN06   = 70,
+  D3DRENDERSTATE_STIPPLEPATTERN07   = 71,
+  D3DRENDERSTATE_STIPPLEPATTERN08   = 72,
+  D3DRENDERSTATE_STIPPLEPATTERN09   = 73,
+  D3DRENDERSTATE_STIPPLEPATTERN10   = 74,
+  D3DRENDERSTATE_STIPPLEPATTERN11   = 75,
+  D3DRENDERSTATE_STIPPLEPATTERN12   = 76,
+  D3DRENDERSTATE_STIPPLEPATTERN13   = 77,
+  D3DRENDERSTATE_STIPPLEPATTERN14   = 78,
+  D3DRENDERSTATE_STIPPLEPATTERN15   = 79,
+  D3DRENDERSTATE_STIPPLEPATTERN16   = 80,
+  D3DRENDERSTATE_STIPPLEPATTERN17   = 81,
+  D3DRENDERSTATE_STIPPLEPATTERN18   = 82,
+  D3DRENDERSTATE_STIPPLEPATTERN19   = 83,
+  D3DRENDERSTATE_STIPPLEPATTERN20   = 84,
+  D3DRENDERSTATE_STIPPLEPATTERN21   = 85,
+  D3DRENDERSTATE_STIPPLEPATTERN22   = 86,
+  D3DRENDERSTATE_STIPPLEPATTERN23   = 87,
+  D3DRENDERSTATE_STIPPLEPATTERN24   = 88,
+  D3DRENDERSTATE_STIPPLEPATTERN25   = 89,
+  D3DRENDERSTATE_STIPPLEPATTERN26   = 90,
+  D3DRENDERSTATE_STIPPLEPATTERN27   = 91,
+  D3DRENDERSTATE_STIPPLEPATTERN28   = 92,
+  D3DRENDERSTATE_STIPPLEPATTERN29   = 93,
+  D3DRENDERSTATE_STIPPLEPATTERN30   = 94,
+  D3DRENDERSTATE_STIPPLEPATTERN31   = 95,
+  D3DRENDERSTATE_FORCE_DWORD        = 0x7fffffff, /* force 32-bit size enum */
+} D3DRENDERSTATETYPE;
+
+typedef enum { 
+  D3DCMP_NEVER        = 1, 
+  D3DCMP_LESS         = 2, 
+  D3DCMP_EQUAL        = 3, 
+  D3DCMP_LESSEQUAL    = 4, 
+  D3DCMP_GREATER      = 5, 
+  D3DCMP_NOTEQUAL     = 6, 
+  D3DCMP_GREATEREQUAL = 7, 
+  D3DCMP_ALWAYS       = 8, 
+  D3DCMP_FORCE_DWORD  = 0x7fffffff
+} D3DCMPFUNC; 
+
+typedef enum {
+  D3DLIGHTSTATE_MATERIAL      = 1,
+  D3DLIGHTSTATE_AMBIENT       = 2,
+  D3DLIGHTSTATE_COLORMODEL    = 3,
+  D3DLIGHTSTATE_FOGMODE       = 4,
+  D3DLIGHTSTATE_FOGSTART      = 5,
+  D3DLIGHTSTATE_FOGEND        = 6,
+  D3DLIGHTSTATE_FOGDENSITY    = 7,
+  D3DLIGHTSTATE_FORCE_DWORD   = 0x7fffffff, /* force 32-bit size enum */
+} D3DLIGHTSTATETYPE;
+
+typedef enum {
+  D3DVT_VERTEX        = 1,
+  D3DVT_LVERTEX       = 2,
+  D3DVT_TLVERTEX      = 3,
+  D3DVT_FORCE_DWORD   = 0x7fffffff, /* force 32-bit size enum */
+} D3DVERTEXTYPE;
+
+typedef enum {
+  D3DTRANSFORMSTATE_WORLD           = 1,
+  D3DTRANSFORMSTATE_VIEW            = 2,
+  D3DTRANSFORMSTATE_PROJECTION      = 3,
+  D3DTRANSFORMSTATE_FORCE_DWORD     = 0x7fffffff, /* force 32-bit size enum */
+} D3DTRANSFORMSTATETYPE;
+
+/* ********************************************************************
+   Types and structures
+   ******************************************************************** */
+typedef DWORD D3DMATERIALHANDLE, *LPD3DMATERIALHANDLE;
+typedef DWORD D3DTEXTUREHANDLE,  *LPD3DTEXTUREHANDLE;
+typedef DWORD D3DVIEWPORTHANDLE, *LPD3DVIEWPORTHANDLE;
+typedef DWORD D3DMATRIXHANDLE,   *LPD3DMATRIXHANDLE;
+
+typedef DWORD D3DCOLOR, *LPD3DCOLOR;
 
 typedef struct {
 	DWORD	dwSize;
@@ -203,6 +370,7 @@
 #define D3DDD_MAXVERTEXCOUNT		0x00000400
 
 /* D3DDEVICEDESC.dwDevCaps */
+#define D3DDEVCAPS_FLOATTLVERTEX        0x00000001
 #define D3DDEVCAPS_SORTINCREASINGZ      0x00000002
 #define D3DDEVCAPS_SORTDECREASINGZ      0X00000004
 #define D3DDEVCAPS_SORTEXACT            0x00000008
@@ -238,6 +406,8 @@
 } D3DDEVICEDESC,*LPD3DDEVICEDESC;
  
 typedef HRESULT (CALLBACK * LPD3DENUMDEVICESCALLBACK)(LPGUID lpGuid,LPSTR lpDeviceDescription,LPSTR lpDeviceName,LPD3DDEVICEDESC,LPD3DDEVICEDESC,LPVOID);
+typedef HRESULT (CALLBACK* LPD3DVALIDATECALLBACK)(LPVOID lpUserArg, DWORD dwOffset);
+
 
 /* dwflags for FindDevice */
 #define D3DFDS_COLORMODEL		0x00000001
@@ -279,11 +449,61 @@
 #define D3DDivide(a, b)		(float)((double) (a) / (double) (b))
 #define D3DMultiply(a, b)	((a) * (b))
 
-#if 0
-/* This causes lots o' problems */
 typedef struct {
+  DWORD         dwFlags;        /* Homogeneous clipping flags */
 	union {
-		D3DVALUE x;
+    D3DVALUE    hx;
+    D3DVALUE    dvHX;
+  } x;
+  union {
+    D3DVALUE    hy;
+    D3DVALUE    dvHY;
+  } y;
+  union {
+    D3DVALUE    hz;
+    D3DVALUE    dvHZ;
+  } z;
+} D3DHVERTEX, *LPD3DHVERTEX;
+/*
+ * Transformed/lit vertices
+ */
+typedef struct {
+  union {
+    D3DVALUE    sx;             /* Screen coordinates */
+    D3DVALUE    dvSX;
+  } x;
+  union {
+    D3DVALUE    sy;
+    D3DVALUE    dvSY;
+  } y;
+  union {
+    D3DVALUE    sz;
+    D3DVALUE    dvSZ;
+  } z;
+  union {
+    D3DVALUE    rhw;            /* Reciprocal of homogeneous w */
+    D3DVALUE    dvRHW;
+  } r;
+  union {
+    D3DCOLOR    color;          /* Vertex color */
+    D3DCOLOR    dcColor;
+  } c;
+  union {
+    D3DCOLOR    specular;       /* Specular component of vertex */
+    D3DCOLOR    dcSpecular;
+  } s;
+  union {
+    D3DVALUE    tu;             /* Texture coordinates */
+    D3DVALUE    dvTU;
+  } u;
+  union {
+    D3DVALUE    tv;
+    D3DVALUE    dvTV;
+  } v;
+} D3DTLVERTEX, *LPD3DTLVERTEX;
+typedef struct {
+  union {
+    D3DVALUE     x;             /* Homogeneous coordinates */
 		D3DVALUE dvX;
 	} x;
 	union {
@@ -294,23 +514,100 @@
 		D3DVALUE z;
 		D3DVALUE dvZ;
 	} z;
-	/* the c++ variant has operator overloads etc. too */
-} D3DVECTOR,*LPD3DVECTOR;
-#endif
+  DWORD            dwReserved;
+  union {
+    D3DCOLOR     color;         /* Vertex color */
+    D3DCOLOR     dcColor;
+  } c;
+  union {
+    D3DCOLOR     specular;      /* Specular component of vertex */
+    D3DCOLOR     dcSpecular;
+  } s;
+  union {
+    D3DVALUE     tu;            /* Texture coordinates */
+    D3DVALUE     dvTU;
+  } u;
+  union {
+    D3DVALUE     tv;
+    D3DVALUE     dvTV;
+  } v;
+} D3DLVERTEX, *LPD3DLVERTEX;
+typedef struct {
+  union {
+    D3DVALUE     x;             /* Homogeneous coordinates */
+    D3DVALUE     dvX;
+  } x;
+  union {
+    D3DVALUE     y;
+    D3DVALUE     dvY;
+  } y;
+  union {
+    D3DVALUE     z;
+    D3DVALUE     dvZ;
+  } z;
+  union {
+    D3DVALUE     nx;            /* Normal */
+    D3DVALUE     dvNX;
+  } nx;
+  union {
+    D3DVALUE     ny;
+    D3DVALUE     dvNY;
+  } ny;
+  union {
+    D3DVALUE     nz;
+    D3DVALUE     dvNZ;
+  } nz;
+  union {
+    D3DVALUE     tu;            /* Texture coordinates */
+    D3DVALUE     dvTU;
+  } u;
+  union {
+    D3DVALUE     tv;
+    D3DVALUE     dvTV;
+  } v;
+} D3DVERTEX, *LPD3DVERTEX;
 
-typedef struct _D3DVECTOR {
+typedef struct {
+  union {
+    LONG x1;
+    LONG lX1;
+  } x1;
+  union {
+    LONG y1;
+    LONG lY1;
+  } y1;
+  union {
+    LONG x2;
+    LONG lX2;
+  } x2;
+  union {
+    LONG y2;
+    LONG lY2;
+  } y2;
+} D3DRECT, *LPD3DRECT;
+
+typedef struct {
+  union {
 	D3DVALUE	x;
+    D3DVALUE dvX;
+  } x;
+  union {
 	D3DVALUE	y;
+    D3DVALUE dvY;
+  } y;
+  union {
 	D3DVALUE	z;
+    D3DVALUE dvZ;
+  } z;
+  /* the c++ variant has operator overloads etc. too */
 } D3DVECTOR,*LPD3DVECTOR;
 
-typedef enum {
-    D3DLIGHT_POINT          = 1,
-    D3DLIGHT_SPOT           = 2,
-    D3DLIGHT_DIRECTIONAL    = 3,
-    D3DLIGHT_PARALLELPOINT  = 4,
-    D3DLIGHT_FORCE_DWORD    = 0x7fffffff /* force 32-bit size enum */
-} D3DLIGHTTYPE;
+typedef struct {
+  D3DVALUE        _11, _12, _13, _14;
+  D3DVALUE        _21, _22, _23, _24;
+  D3DVALUE        _31, _32, _33, _34;
+  D3DVALUE        _41, _42, _43, _44;
+} D3DMATRIX, *LPD3DMATRIX;
 
 typedef struct _D3DCOLORVALUE {
 	union {
@@ -350,7 +647,370 @@
 #define D3DLIGHT_ACTIVE		0x00000001
 #define D3DLIGHT_NO_SPECULAR	0x00000002
 
+/* Textures */
+typedef HRESULT (CALLBACK* LPD3DENUMTEXTUREFORMATSCALLBACK)(LPDDSURFACEDESC lpDdsd, LPVOID lpContext);
 
+
+/* Statistics structure */
+typedef struct {
+  DWORD        dwSize;
+  DWORD        dwTrianglesDrawn;
+  DWORD        dwLinesDrawn;
+  DWORD        dwPointsDrawn;
+  DWORD        dwSpansDrawn;
+  DWORD        dwVerticesProcessed;
+} D3DSTATS, *LPD3DSTATS;
+
+/* Clipping */
+typedef struct _D3DCLIPSTATUS {
+  DWORD dwFlags; /* Do we set 2d extents, 3D extents or status */
+  DWORD dwStatus; /* Clip status */
+  float minx, maxx; /* X extents */
+  float miny, maxy; /* Y extents */
+  float minz, maxz; /* Z extents */
+} D3DCLIPSTATUS, *LPD3DCLIPSTATUS;
+
+typedef struct {
+  DWORD               dwSize;
+  union {
+    D3DCOLORVALUE   diffuse;        /* Diffuse color RGBA */
+    D3DCOLORVALUE   dcvDiffuse;
+  } a;
+  union {
+    D3DCOLORVALUE   ambient;        /* Ambient color RGB */
+    D3DCOLORVALUE   dcvAmbient;
+  } b;
+  union {
+    D3DCOLORVALUE   specular;       /* Specular 'shininess' */
+    D3DCOLORVALUE   dcvSpecular;
+  } c;
+  union {
+    D3DCOLORVALUE   emissive;       /* Emissive color RGB */
+    D3DCOLORVALUE   dcvEmissive;
+  } d;
+  union {
+    D3DVALUE        power;          /* Sharpness if specular highlight */
+    D3DVALUE        dvPower;
+  } e;
+  D3DTEXTUREHANDLE    hTexture;       /* Handle to texture map */
+  DWORD               dwRampSize;
+} D3DMATERIAL, *LPD3DMATERIAL;
+
+typedef struct {
+  D3DVECTOR dvPosition;  /* Lightable point in model space */
+  D3DVECTOR dvNormal;    /* Normalised unit vector */
+} D3DLIGHTINGELEMENT, *LPD3DLIGHTINGELEMENT;
+
+typedef struct {
+  DWORD       dwSize;
+  DWORD       dwX;
+  DWORD       dwY;            /* Top left */
+  DWORD       dwWidth;
+  DWORD       dwHeight;       /* Dimensions */
+  D3DVALUE    dvScaleX;       /* Scale homogeneous to screen */
+  D3DVALUE    dvScaleY;       /* Scale homogeneous to screen */
+  D3DVALUE    dvMaxX;         /* Min/max homogeneous x coord */
+  D3DVALUE    dvMaxY;         /* Min/max homogeneous y coord */
+  D3DVALUE    dvMinZ;
+  D3DVALUE    dvMaxZ;         /* Min/max homogeneous z coord */
+} D3DVIEWPORT, *LPD3DVIEWPORT;
+
+typedef struct {
+  DWORD       dwSize;
+  DWORD       dwX;
+  DWORD       dwY;            /* Viewport Top left */
+  DWORD       dwWidth;
+  DWORD       dwHeight;       /* Viewport Dimensions */
+  D3DVALUE    dvClipX;        /* Top left of clip volume */
+  D3DVALUE    dvClipY;
+  D3DVALUE    dvClipWidth;    /* Clip Volume Dimensions */
+  D3DVALUE    dvClipHeight;
+  D3DVALUE    dvMinZ;         /* Min/max of clip Volume */
+  D3DVALUE    dvMaxZ;
+} D3DVIEWPORT2, *LPD3DVIEWPORT2;
+
+#define D3DTRANSFORM_CLIPPED       0x00000001l
+#define D3DTRANSFORM_UNCLIPPED     0x00000002l
+
+typedef struct {
+  DWORD           dwSize;
+  LPVOID          lpIn;           /* Input vertices */
+  DWORD           dwInSize;       /* Stride of input vertices */
+  LPVOID          lpOut;          /* Output vertices */
+  DWORD           dwOutSize;      /* Stride of output vertices */
+  LPD3DHVERTEX    lpHOut;         /* Output homogeneous vertices */
+  DWORD           dwClip;         /* Clipping hint */
+  DWORD           dwClipIntersection;
+  DWORD           dwClipUnion;    /* Union of all clip flags */
+  D3DRECT         drExtent;       /* Extent of transformed vertices */
+} D3DTRANSFORMDATA, *LPD3DTRANSFORMDATA;
+
+/* flags bits */
+#define D3DLIGHT_ACTIVE         0x00000001
+#define D3DLIGHT_NO_SPECULAR    0x00000002
+
+/* maximum valid light range */
+#define D3DLIGHT_RANGE_MAX              ((float)sqrt(FLT_MAX))
+
+typedef struct _D3DLIGHT2 {
+  DWORD           dwSize;
+  D3DLIGHTTYPE    dltType;            /* Type of light source */
+  D3DCOLORVALUE   dcvColor;           /* Color of light */
+  D3DVECTOR       dvPosition;         /* Position in world space */
+  D3DVECTOR       dvDirection;        /* Direction in world space */
+  D3DVALUE        dvRange;            /* Cutoff range */
+  D3DVALUE        dvFalloff;          /* Falloff */
+  D3DVALUE        dvAttenuation0;     /* Constant attenuation */
+  D3DVALUE        dvAttenuation1;     /* Linear attenuation */
+  D3DVALUE        dvAttenuation2;     /* Quadratic attenuation */
+  D3DVALUE        dvTheta;            /* Inner angle of spotlight cone */
+  D3DVALUE        dvPhi;              /* Outer angle of spotlight cone */
+  DWORD           dwFlags;
+} D3DLIGHT2, *LPD3DLIGHT2;
+
+typedef struct _D3DLIGHTDATA {
+  DWORD                dwSize;
+  LPD3DLIGHTINGELEMENT lpIn;          /* Input positions and normals */
+  DWORD                dwInSize;      /* Stride of input elements */
+  LPD3DTLVERTEX        lpOut;         /* Output colors */
+  DWORD                dwOutSize;     /* Stride of output colors */
+} D3DLIGHTDATA, *LPD3DLIGHTDATA;
+
+typedef struct _D3DPICKRECORD {
+  BYTE     bOpcode;
+  BYTE     bPad;
+  DWORD    dwOffset;
+  D3DVALUE dvZ;
+} D3DPICKRECORD, *LPD3DPICKRECORD;
+
+
+typedef struct _D3DExecuteBufferDesc { 
+  DWORD  dwSize; 
+  DWORD  dwFlags; 
+  DWORD  dwCaps; 
+  DWORD  dwBufferSize; 
+  LPVOID lpData; 
+} D3DEXECUTEBUFFERDESC; 
+typedef D3DEXECUTEBUFFERDESC *LPD3DEXECUTEBUFFERDESC; 
+
+#define D3DDEB_BUFSIZE          0x00000001l     /* buffer size valid */
+#define D3DDEB_CAPS             0x00000002l     /* caps valid */
+#define D3DDEB_LPDATA           0x00000004l     /* lpData valid */
+
+#define D3DDEBCAPS_SYSTEMMEMORY 0x00000001l     /* buffer in system memory */
+#define D3DDEBCAPS_VIDEOMEMORY  0x00000002l     /* buffer in device memory */
+#define D3DDEBCAPS_MEM (D3DDEBCAPS_SYSTEMMEMORY|D3DDEBCAPS_VIDEOMEMORY)
+
+/*
+ * Values for d3d status.
+ */
+#define D3DSTATUS_CLIPUNIONLEFT                 D3DCLIP_LEFT
+#define D3DSTATUS_CLIPUNIONRIGHT                D3DCLIP_RIGHT
+#define D3DSTATUS_CLIPUNIONTOP                  D3DCLIP_TOP
+#define D3DSTATUS_CLIPUNIONBOTTOM               D3DCLIP_BOTTOM
+#define D3DSTATUS_CLIPUNIONFRONT                D3DCLIP_FRONT
+#define D3DSTATUS_CLIPUNIONBACK                 D3DCLIP_BACK
+#define D3DSTATUS_CLIPUNIONGEN0                 D3DCLIP_GEN0
+#define D3DSTATUS_CLIPUNIONGEN1                 D3DCLIP_GEN1
+#define D3DSTATUS_CLIPUNIONGEN2                 D3DCLIP_GEN2
+#define D3DSTATUS_CLIPUNIONGEN3                 D3DCLIP_GEN3
+#define D3DSTATUS_CLIPUNIONGEN4                 D3DCLIP_GEN4
+#define D3DSTATUS_CLIPUNIONGEN5                 D3DCLIP_GEN5
+
+#define D3DSTATUS_CLIPINTERSECTIONLEFT          0x00001000L
+#define D3DSTATUS_CLIPINTERSECTIONRIGHT         0x00002000L
+#define D3DSTATUS_CLIPINTERSECTIONTOP           0x00004000L
+#define D3DSTATUS_CLIPINTERSECTIONBOTTOM        0x00008000L
+#define D3DSTATUS_CLIPINTERSECTIONFRONT         0x00010000L
+#define D3DSTATUS_CLIPINTERSECTIONBACK          0x00020000L
+#define D3DSTATUS_CLIPINTERSECTIONGEN0          0x00040000L
+#define D3DSTATUS_CLIPINTERSECTIONGEN1          0x00080000L
+#define D3DSTATUS_CLIPINTERSECTIONGEN2          0x00100000L
+#define D3DSTATUS_CLIPINTERSECTIONGEN3          0x00200000L
+#define D3DSTATUS_CLIPINTERSECTIONGEN4          0x00400000L
+#define D3DSTATUS_CLIPINTERSECTIONGEN5          0x00800000L
+#define D3DSTATUS_ZNOTVISIBLE                   0x01000000L
+
+#define D3DSTATUS_CLIPUNIONALL  (               \
+            D3DSTATUS_CLIPUNIONLEFT     |       \
+            D3DSTATUS_CLIPUNIONRIGHT    |       \
+            D3DSTATUS_CLIPUNIONTOP      |       \
+            D3DSTATUS_CLIPUNIONBOTTOM   |       \
+            D3DSTATUS_CLIPUNIONFRONT    |       \
+            D3DSTATUS_CLIPUNIONBACK     |       \
+            D3DSTATUS_CLIPUNIONGEN0     |       \
+            D3DSTATUS_CLIPUNIONGEN1     |       \
+            D3DSTATUS_CLIPUNIONGEN2     |       \
+            D3DSTATUS_CLIPUNIONGEN3     |       \
+            D3DSTATUS_CLIPUNIONGEN4     |       \
+            D3DSTATUS_CLIPUNIONGEN5             \
+            )
+
+#define D3DSTATUS_CLIPINTERSECTIONALL   (               \
+            D3DSTATUS_CLIPINTERSECTIONLEFT      |       \
+            D3DSTATUS_CLIPINTERSECTIONRIGHT     |       \
+            D3DSTATUS_CLIPINTERSECTIONTOP       |       \
+            D3DSTATUS_CLIPINTERSECTIONBOTTOM    |       \
+            D3DSTATUS_CLIPINTERSECTIONFRONT     |       \
+            D3DSTATUS_CLIPINTERSECTIONBACK      |       \
+            D3DSTATUS_CLIPINTERSECTIONGEN0      |       \
+            D3DSTATUS_CLIPINTERSECTIONGEN1      |       \
+            D3DSTATUS_CLIPINTERSECTIONGEN2      |       \
+            D3DSTATUS_CLIPINTERSECTIONGEN3      |       \
+            D3DSTATUS_CLIPINTERSECTIONGEN4      |       \
+            D3DSTATUS_CLIPINTERSECTIONGEN5              \
+            )
+
+#define D3DSTATUS_DEFAULT       (                       \
+            D3DSTATUS_CLIPINTERSECTIONALL       |       \
+            D3DSTATUS_ZNOTVISIBLE)
+
+
+typedef struct _D3DSTATUS { 
+  DWORD   dwFlags; 
+  DWORD   dwStatus; 
+  D3DRECT drExtent; 
+} D3DSTATUS, *LPD3DSTATUS; 
+ 
+
+typedef struct _D3DEXECUTEDATA { 
+  DWORD     dwSize; 
+  DWORD     dwVertexOffset; 
+  DWORD     dwVertexCount; 
+  DWORD     dwInstructionOffset; 
+  DWORD     dwInstructionLength; 
+  DWORD     dwHVertexOffset; 
+  D3DSTATUS dsStatus; 
+} D3DEXECUTEDATA, *LPD3DEXECUTEDATA; 
+
+typedef enum _D3DOPCODE { 
+  D3DOP_POINT           = 1, 
+  D3DOP_LINE            = 2, 
+  D3DOP_TRIANGLE        = 3, 
+  D3DOP_MATRIXLOAD      = 4, 
+  D3DOP_MATRIXMULTIPLY  = 5, 
+  D3DOP_STATETRANSFORM  = 6, 
+  D3DOP_STATELIGHT      = 7, 
+  D3DOP_STATERENDER     = 8, 
+  D3DOP_PROCESSVERTICES = 9, 
+  D3DOP_TEXTURELOAD     = 10, 
+  D3DOP_EXIT            = 11, 
+  D3DOP_BRANCHFORWARD   = 12, 
+  D3DOP_SPAN            = 13, 
+  D3DOP_SETSTATUS       = 14, 
+  
+  D3DOP_FORCE_DWORD     = 0x7fffffff, 
+} D3DOPCODE; 
+
+typedef struct _D3DPOINT { 
+  WORD wCount; 
+  WORD wFirst; 
+} D3DPOINT, *LPD3DPOINT; 
+
+typedef struct _D3DLINE { 
+  union { 
+    WORD v1; 
+    WORD wV1; 
+  } v1; 
+  union { 
+    WORD v2; 
+    WORD wV2; 
+  } v2; 
+} D3DLINE, *LPD3DLINE; 
+
+#define D3DTRIFLAG_START                        0x00000000L
+#define D3DTRIFLAG_STARTFLAT(len) (len)         /* 0 < len < 30 */
+#define D3DTRIFLAG_ODD                          0x0000001eL
+#define D3DTRIFLAG_EVEN                         0x0000001fL
+
+#define D3DTRIFLAG_EDGEENABLE1                  0x00000100L /* v0-v1 edge */
+#define D3DTRIFLAG_EDGEENABLE2                  0x00000200L /* v1-v2 edge */
+#define D3DTRIFLAG_EDGEENABLE3                  0x00000400L /* v2-v0 edge */
+#define D3DTRIFLAG_EDGEENABLETRIANGLE \
+        (D3DTRIFLAG_EDGEENABLE1 | D3DTRIFLAG_EDGEENABLE2 | D3DTRIFLAG_EDGEENABLE3)
+
+typedef struct _D3DTRIANGLE { 
+  union { 
+    WORD v1; 
+    WORD wV1; 
+  } v1; 
+  union { 
+    WORD v2; 
+    WORD wV2; 
+  } v2; 
+  union { 
+    WORD v3; 
+    WORD wV3; 
+  } v3; 
+  WORD     wFlags; 
+} D3DTRIANGLE, *LPD3DTRIANGLE; 
+
+typedef struct _D3DMATRIXLOAD { 
+  D3DMATRIXHANDLE hDestMatrix; 
+  D3DMATRIXHANDLE hSrcMatrix; 
+} D3DMATRIXLOAD, *LPD3DMATRIXLOAD; 
+
+typedef struct _D3DMATRIXMULTIPLY { 
+  D3DMATRIXHANDLE hDestMatrix; 
+  D3DMATRIXHANDLE hSrcMatrix1; 
+  D3DMATRIXHANDLE hSrcMatrix2; 
+} D3DMATRIXMULTIPLY, *LPD3DMATRIXMULTIPLY; 
+
+typedef struct _D3DSTATE { 
+  union { 
+    D3DTRANSFORMSTATETYPE dtstTransformStateType; 
+    D3DLIGHTSTATETYPE     dlstLightStateType; 
+    D3DRENDERSTATETYPE    drstRenderStateType; 
+  } t; 
+  union { 
+    DWORD                 dwArg[1]; 
+    D3DVALUE              dvArg[1]; 
+  } v; 
+} D3DSTATE, *LPD3DSTATE; 
+
+#define D3DPROCESSVERTICES_TRANSFORMLIGHT       0x00000000L
+#define D3DPROCESSVERTICES_TRANSFORM            0x00000001L
+#define D3DPROCESSVERTICES_COPY                 0x00000002L
+#define D3DPROCESSVERTICES_OPMASK               0x00000007L
+
+#define D3DPROCESSVERTICES_UPDATEEXTENTS        0x00000008L
+#define D3DPROCESSVERTICES_NOCOLOR              0x00000010L
+
+typedef struct _D3DPROCESSVERTICES { 
+  DWORD dwFlags; 
+  WORD  wStart; 
+  WORD  wDest; 
+  DWORD dwCount; 
+  DWORD dwReserved; 
+} D3DPROCESSVERTICES, *LPD3DPROCESSVERTICES; 
+
+typedef struct _D3DTEXTURELOAD { 
+  D3DTEXTUREHANDLE hDestTexture; 
+  D3DTEXTUREHANDLE hSrcTexture; 
+} D3DTEXTURELOAD, *LPD3DTEXTURELOAD; 
+
+typedef struct _D3DBRANCH { 
+  DWORD dwMask; 
+  DWORD dwValue; 
+  BOOL  bNegate; 
+  DWORD dwOffset; 
+} D3DBRANCH, *LPD3DBRANCH; 
+
+typedef struct _D3DSPAN { 
+  WORD wCount; 
+  WORD wFirst; 
+} D3DSPAN, *LPD3DSPAN; 
+
+typedef struct _D3DINSTRUCTION { 
+  BYTE bOpcode; 
+  BYTE bSize; 
+  WORD wCount; 
+} D3DINSTRUCTION, *LPD3DINSTRUCTION; 
+
+
+/* ********************************************************************
+   Direct3D
+   ******************************************************************** */
 #define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn)
 #define STDMETHOD_(ret,xfn) ret (CALLBACK *fn##xfn)
 #define PURE
@@ -379,6 +1039,9 @@
 };
 #undef THIS
 
+/* ********************************************************************
+   Direct3D2
+   ******************************************************************** */
 #define THIS LPDIRECT3D2 this
 typedef struct IDirect3D2_VTable {
 	/*** IUnknown methods ***/
@@ -401,6 +1064,9 @@
 };
 #undef THIS
 
+/* ********************************************************************
+   Direct3DLight
+   ******************************************************************** */
 #define THIS LPDIRECT3DLIGHT this
 typedef struct IDirect3DLight_VTable {
 	/*** IUnknown methods ***/
@@ -416,10 +1082,381 @@
 struct IDirect3DLight {
 	LPDIRECT3DLIGHT_VTABLE	lpvtbl;
 	DWORD			ref;
+
+  union {
+    LPDIRECT3D            d3d;
+    LPDIRECT3D2           d3d2;
+  } d3d;
+  int type;
+  
+  D3DLIGHT2               light;
+
+  /* Chained list used for adding / removing from viewports */
+  LPDIRECT3DLIGHT next, prev;
+
+  /* Activation function */
+  void (*activate)(THIS);
+  int is_active;
+  
+  /* Awful OpenGL code !!! */
+#ifdef HAVE_MESAGL
+  GLenum light_num;
+#endif
 };
 
 #undef THIS
 
+/* ********************************************************************
+   Direct3DMaterial
+   ******************************************************************** */
+#define THIS LPDIRECT3DMATERIAL this
+typedef struct IDirect3DMaterial_VTable {
+  /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+  STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+  STDMETHOD_(ULONG, Release) (THIS) PURE;
+  /*** IDirect3DMaterial2 methods ***/
+  STDMETHOD(Initialize) (THIS_ LPDIRECT3D) PURE;
+  STDMETHOD(SetMaterial) (THIS_ LPD3DMATERIAL) PURE;
+  STDMETHOD(GetMaterial) (THIS_ LPD3DMATERIAL) PURE;
+  STDMETHOD(GetHandle) (THIS_ LPDIRECT3DDEVICE2, LPD3DMATERIALHANDLE) PURE;
+  STDMETHOD_(HRESULT, Reserve) (THIS) PURE;
+  STDMETHOD_(HRESULT, Unreserve) (THIS) PURE;
+} IDirect3DMaterial_VTable,*LPDIRECT3DMATERIAL_VTABLE;
+
+#undef THIS
+
+
+/* ********************************************************************
+   Direct3DMaterial2
+   ******************************************************************** */
+#define THIS LPDIRECT3DMATERIAL2 this
+typedef struct IDirect3DMaterial2_VTable {
+  /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+  STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+  STDMETHOD_(ULONG, Release) (THIS) PURE;
+  /*** IDirect3DMaterial2 methods ***/
+  STDMETHOD(SetMaterial) (THIS_ LPD3DMATERIAL) PURE;
+  STDMETHOD(GetMaterial) (THIS_ LPD3DMATERIAL) PURE;
+  STDMETHOD(GetHandle) (THIS_ LPDIRECT3DDEVICE2, LPD3DMATERIALHANDLE) PURE;
+} IDirect3DMaterial2_VTable,*LPDIRECT3DMATERIAL2_VTABLE;
+
+struct IDirect3DMaterial2 {
+  LPDIRECT3DMATERIAL2_VTABLE  lpvtbl;
+  DWORD                       ref;
+
+  union {
+    LPDIRECT3D                d3d1;
+    LPDIRECT3D2               d3d2;
+  } d3d;
+  union {
+    LPDIRECT3DDEVICE  active_device1;
+    LPDIRECT3DDEVICE2 active_device2;
+  } device;
+  int use_d3d2;
+  
+  D3DMATERIAL                 mat;
+  
+  void (*activate)(LPDIRECT3DMATERIAL2 this);
+};
+
+#undef THIS
+
+/* ********************************************************************
+   Direct3DTexture
+   ******************************************************************** */
+#define THIS LPDIRECT3DTEXTURE this
+typedef struct IDirect3DTexture_VTable {
+  /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+  STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+  STDMETHOD_(ULONG, Release) (THIS) PURE;
+  /*** IDirect3DTexture methods ***/
+  STDMETHOD(Initialize) (THIS_ LPDIRECT3DDEVICE, LPDIRECTDRAWSURFACE) PURE;
+  STDMETHOD(GetHandle) (THIS_ LPDIRECT3DDEVICE, LPD3DTEXTUREHANDLE) PURE;
+  STDMETHOD(PaletteChanged) (THIS_ DWORD, DWORD) PURE;
+  STDMETHOD(Load) (THIS_ LPDIRECT3DTEXTURE) PURE;
+  STDMETHOD_(HRESULT, Unload) (THIS) PURE;
+} IDirect3DTexture_VTable,*LPDIRECT3DTEXTURE_VTABLE;
+
+/* The structure is the same as for Direct3DTexture2 */
+
+#undef THIS
+
+/* ********************************************************************
+   Direct3DTexture2
+   ******************************************************************** */
+#define THIS LPDIRECT3DTEXTURE2 this
+typedef struct IDirect3DTexture2_VTable {
+  /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+  STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+  STDMETHOD_(ULONG, Release) (THIS) PURE;
+  /*** IDirect3DTexture2 methods ***/
+  STDMETHOD(GetHandle) (THIS_ LPDIRECT3DDEVICE2, LPD3DTEXTUREHANDLE) PURE;
+  STDMETHOD(PaletteChanged) (THIS_ DWORD, DWORD) PURE;
+  STDMETHOD(Load) (THIS_ LPDIRECT3DTEXTURE2) PURE;  
+} IDirect3DTexture2_VTable,*LPDIRECT3DTEXTURE2_VTABLE;
+
+struct IDirect3DTexture2 {
+  LPDIRECT3DTEXTURE2_VTABLE  lpvtbl;
+  DWORD                      ref;
+  
+  LPDIRECTDRAWSURFACE3       surface;
+};
+
+#undef THIS
+
+
+/* ********************************************************************
+   Direct3DViewport
+   ******************************************************************** */
+#define THIS LPDIRECT3DVIEWPORT this
+typedef struct IDirect3Viewport_VTable {
+  /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+  STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+  STDMETHOD_(ULONG, Release) (THIS) PURE;
+  /*** IDirect3DViewport methods ***/
+  STDMETHOD(Initialize) (THIS_ LPDIRECT3D) PURE;
+  STDMETHOD(GetViewport) (THIS_ LPD3DVIEWPORT) PURE;
+  STDMETHOD(SetViewport) (THIS_ LPD3DVIEWPORT) PURE;
+  STDMETHOD(TransformVertices) (THIS_ DWORD, LPD3DTRANSFORMDATA, DWORD, LPDWORD) PURE;
+  STDMETHOD(LightElements) (THIS_ DWORD, LPD3DLIGHTDATA) PURE;
+  STDMETHOD(SetBackground) (THIS_ D3DMATERIALHANDLE) PURE;
+  STDMETHOD(GetBackground) (THIS_ LPD3DMATERIALHANDLE, LPBOOL) PURE;
+  STDMETHOD(SetBackgroundDepth) (THIS_ LPDIRECTDRAWSURFACE) PURE;
+  STDMETHOD(GetBackgroundDepth) (THIS_ LPDIRECTDRAWSURFACE*, LPBOOL) PURE;
+  STDMETHOD(Clear) (THIS_ DWORD, LPD3DRECT, DWORD) PURE;
+  STDMETHOD(AddLight) (THIS_ LPDIRECT3DLIGHT) PURE;
+  STDMETHOD(DeleteLight) (THIS_ LPDIRECT3DLIGHT) PURE;
+  STDMETHOD(NextLight) (THIS_ LPDIRECT3DLIGHT, LPDIRECT3DLIGHT*, DWORD) PURE;
+} IDirect3DViewport_VTable,*LPDIRECT3DVIEWPORT_VTABLE;
+
+#undef THIS
+
+
+/* ********************************************************************
+   Direct3DViewport2
+   ******************************************************************** */
+#define THIS LPDIRECT3DVIEWPORT2 this
+typedef struct IDirect3Viewport2_VTable {
+  /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+  STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+  STDMETHOD_(ULONG, Release) (THIS) PURE;
+  /*** IDirect3DViewport methods ***/
+  STDMETHOD(Initialize) (THIS_ LPDIRECT3D) PURE;
+  STDMETHOD(GetViewport) (THIS_ LPD3DVIEWPORT) PURE;
+  STDMETHOD(SetViewport) (THIS_ LPD3DVIEWPORT) PURE;
+  STDMETHOD(TransformVertices) (THIS_ DWORD, LPD3DTRANSFORMDATA, DWORD, LPDWORD) PURE;
+  STDMETHOD(LightElements) (THIS_ DWORD, LPD3DLIGHTDATA) PURE;
+  STDMETHOD(SetBackground) (THIS_ D3DMATERIALHANDLE) PURE;
+  STDMETHOD(GetBackground) (THIS_ LPD3DMATERIALHANDLE, LPBOOL) PURE;
+  STDMETHOD(SetBackgroundDepth) (THIS_ LPDIRECTDRAWSURFACE) PURE;
+  STDMETHOD(GetBackgroundDepth) (THIS_ LPDIRECTDRAWSURFACE*, LPBOOL) PURE;
+  STDMETHOD(Clear) (THIS_ DWORD, LPD3DRECT, DWORD) PURE;
+  STDMETHOD(AddLight) (THIS_ LPDIRECT3DLIGHT) PURE;
+  STDMETHOD(DeleteLight) (THIS_ LPDIRECT3DLIGHT) PURE;
+  STDMETHOD(NextLight) (THIS_ LPDIRECT3DLIGHT, LPDIRECT3DLIGHT*, DWORD) PURE;
+  /*** IDirect3DViewport2 methods ***/
+  STDMETHOD(GetViewport2) (THIS_ LPD3DVIEWPORT2) PURE;
+  STDMETHOD(SetViewport2) (THIS_ LPD3DVIEWPORT2) PURE;
+} IDirect3DViewport2_VTable,*LPDIRECT3DVIEWPORT2_VTABLE;
+
+struct IDirect3DViewport2 {
+  LPDIRECT3DVIEWPORT2_VTABLE  lpvtbl;
+  DWORD                       ref;
+
+  union {
+    LPDIRECT3D                d3d1;
+    LPDIRECT3D2               d3d2;
+  } d3d;
+  /* If this viewport is active for one device, put the device here */
+  union {
+    LPDIRECT3DDEVICE  active_device1;
+    LPDIRECT3DDEVICE2 active_device2;
+  } device;
+  int use_d3d2;
+
+  union {
+    D3DVIEWPORT              vp1;
+    D3DVIEWPORT2             vp2;
+  } viewport;
+  int use_vp2;
+
+  /* Activation function */
+  void (*activate)(THIS);
+  
+  /* Field used to chain viewports together */
+  LPDIRECT3DVIEWPORT2 next;
+
+  /* Lights list */
+  LPDIRECT3DLIGHT lights;
+
+  /* OpenGL code */
+#ifdef HAVE_MESAGL
+  GLenum nextlight;
+#endif
+};
+
+#undef THIS
+
+/* ********************************************************************
+   Direct3DExecuteBuffer
+   ******************************************************************** */
+#define THIS LPDIRECT3DEXECUTEBUFFER this
+typedef struct IDirect3DExecuteBuffer_VTable {
+  /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+  STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+  STDMETHOD_(ULONG, Release) (THIS) PURE;
+  /*** IDirect3DExecuteBuffer methods ***/
+  STDMETHOD(Initialize) (THIS_ LPDIRECT3DDEVICE, LPD3DEXECUTEBUFFERDESC) PURE;
+  STDMETHOD(Lock) (THIS_ LPD3DEXECUTEBUFFERDESC) PURE;
+  STDMETHOD_(HRESULT, Unlock) (THIS) PURE;
+  STDMETHOD(SetExecuteData) (THIS_ LPD3DEXECUTEDATA) PURE;
+  STDMETHOD(GetExecuteData) (THIS_ LPD3DEXECUTEDATA) PURE;
+  STDMETHOD(Validate) (THIS_ LPDWORD, LPD3DVALIDATECALLBACK, LPVOID, DWORD) PURE;
+  STDMETHOD(Optimize) (THIS_ DWORD) PURE;
+} *LPDIRECT3DEXECUTEBUFFER_VTABLE,IDirect3DExecuteBuffer_VTable;
+
+struct IDirect3DExecuteBuffer {
+  LPDIRECT3DEXECUTEBUFFER_VTABLE lpvtbl;
+  DWORD ref;
+  
+  LPDIRECT3DDEVICE d3ddev;
+
+  D3DEXECUTEBUFFERDESC desc;
+  D3DEXECUTEDATA data;
+
+  /* This buffer will store the transformed vertices */
+  D3DVERTEX *vertex_data;
+
+  /* This flags is set to TRUE if we allocated ourselves the
+     data buffer */
+  BOOL need_free;
+
+  void (*execute)(LPDIRECT3DEXECUTEBUFFER this,
+		  LPDIRECT3DDEVICE dev,
+		  LPDIRECT3DVIEWPORT vp);
+};
+
+#undef THIS
+
+/* ********************************************************************
+   Direct3DDevice
+   ******************************************************************** */
+#define THIS LPDIRECT3DDEVICE this
+typedef struct IDirect3DDevice_VTable {
+  /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+  STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+  STDMETHOD_(ULONG, Release) (THIS) PURE;
+  /*** IDirect3DDevice methods ***/
+  STDMETHOD(Initialize) (THIS_ LPDIRECT3D, LPGUID, LPD3DDEVICEDESC) PURE;
+  STDMETHOD(GetCaps) (THIS_ LPD3DDEVICEDESC, LPD3DDEVICEDESC) PURE;
+  STDMETHOD(SwapTextureHandles) (THIS_ LPDIRECT3DTEXTURE, LPDIRECT3DTEXTURE) PURE;
+  STDMETHOD(CreateExecuteBuffer) (THIS_ LPD3DEXECUTEBUFFERDESC, LPDIRECT3DEXECUTEBUFFER*, IUnknown*) PURE;
+  STDMETHOD(GetStats) (THIS_ LPD3DSTATS) PURE;
+  STDMETHOD(Execute) (THIS_ LPDIRECT3DEXECUTEBUFFER, LPDIRECT3DVIEWPORT, DWORD) PURE;
+  STDMETHOD(AddViewport) (THIS_ LPDIRECT3DVIEWPORT) PURE;
+  STDMETHOD(DeleteViewport) (THIS_ LPDIRECT3DVIEWPORT) PURE;
+  STDMETHOD(NextViewport) (THIS_ LPDIRECT3DVIEWPORT, LPDIRECT3DVIEWPORT*, DWORD) PURE;
+  STDMETHOD(Pick) (THIS_ LPDIRECT3DEXECUTEBUFFER, LPDIRECT3DVIEWPORT, DWORD, LPD3DRECT) PURE;
+  STDMETHOD(GetPickRecords)(THIS_ LPDWORD, LPD3DPICKRECORD) PURE;
+  STDMETHOD(EnumTextureFormats) (THIS_ LPD3DENUMTEXTUREFORMATSCALLBACK, LPVOID) PURE;
+  STDMETHOD(CreateMatrix) (THIS_ LPD3DMATRIXHANDLE) PURE;
+  STDMETHOD(SetMatrix) (THIS_ D3DMATRIXHANDLE, const LPD3DMATRIX) PURE;
+  STDMETHOD(GetMatrix) (THIS_ D3DMATRIXHANDLE, LPD3DMATRIX) PURE;
+  STDMETHOD(DeleteMatrix) (THIS_ D3DMATRIXHANDLE) PURE;
+  STDMETHOD_(HRESULT, BeginScene) (THIS) PURE;
+  STDMETHOD_(HRESULT, EndScene) (THIS) PURE;
+  STDMETHOD(GetDirect3D) (THIS_ LPDIRECT3D*) PURE;
+} *LPDIRECT3DDEVICE_VTABLE,IDirect3DDevice_VTable;
+
+struct IDirect3DDevice {
+  /* This are the fields common to all Direct3DDevice implementations */
+  LPDIRECT3DDEVICE_VTABLE lpvtbl;
+  DWORD ref;
+  
+  LPDIRECT3D d3d;
+  LPDIRECTDRAWSURFACE surface;
+
+  LPDIRECT3DVIEWPORT viewport_list;
+  LPDIRECT3DVIEWPORT current_viewport;
+
+  void (*set_context)(THIS) ;
+};
+
+#undef THIS
+
+/* ********************************************************************
+   Direct3DDevice2
+   ******************************************************************** */
+#define THIS LPDIRECT3DDEVICE2 this
+typedef struct IDirect3DDevice2_VTable {
+  /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+  STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+  STDMETHOD_(ULONG, Release) (THIS) PURE;
+  /*** IDirect3DDevice2 methods ***/
+  STDMETHOD(GetCaps) (THIS_ LPD3DDEVICEDESC, LPD3DDEVICEDESC) PURE;
+  STDMETHOD(SwapTextureHandles) (THIS_ LPDIRECT3DTEXTURE2, LPDIRECT3DTEXTURE2) PURE;
+  STDMETHOD(GetStats) (THIS_ LPD3DSTATS) PURE;
+  STDMETHOD(AddViewport) (THIS_ LPDIRECT3DVIEWPORT2) PURE;
+  STDMETHOD(DeleteViewport) (THIS_ LPDIRECT3DVIEWPORT2) PURE;
+  STDMETHOD(NextViewport) (THIS_ LPDIRECT3DVIEWPORT2, LPDIRECT3DVIEWPORT2*, DWORD) PURE;
+  STDMETHOD(EnumTextureFormats) (THIS_ LPD3DENUMTEXTUREFORMATSCALLBACK, LPVOID) PURE;
+  STDMETHOD_(HRESULT, BeginScene) (THIS) PURE;
+  STDMETHOD_(HRESULT, EndScene) (THIS) PURE;
+  STDMETHOD(GetDirect3D) (THIS_ LPDIRECT3D2*) PURE;
+  
+  /*** DrawPrimitive API ***/
+  STDMETHOD(SetCurrentViewport) (THIS_ LPDIRECT3DVIEWPORT2) PURE;
+  STDMETHOD(GetCurrentViewport) (THIS_ LPDIRECT3DVIEWPORT2 *) PURE;
+  
+  STDMETHOD(SetRenderTarget) (THIS_ LPDIRECTDRAWSURFACE, DWORD) PURE;
+  STDMETHOD(GetRenderTarget) (THIS_ LPDIRECTDRAWSURFACE *) PURE;
+  
+  STDMETHOD(Begin) (THIS_ D3DPRIMITIVETYPE, D3DVERTEXTYPE, DWORD) PURE;
+  STDMETHOD(BeginIndexed) (THIS_ D3DPRIMITIVETYPE, D3DVERTEXTYPE, LPVOID, DWORD, DWORD) PURE;
+  STDMETHOD(Vertex) (THIS_ LPVOID) PURE;
+  STDMETHOD(Index) (THIS_ WORD) PURE;
+  STDMETHOD(End) (THIS_ DWORD) PURE;
+  
+  STDMETHOD(GetRenderState) (THIS_ D3DRENDERSTATETYPE, LPDWORD) PURE;
+  STDMETHOD(SetRenderState) (THIS_ D3DRENDERSTATETYPE, DWORD) PURE;
+  STDMETHOD(GetLightState) (THIS_ D3DLIGHTSTATETYPE, LPDWORD) PURE;
+  STDMETHOD(SetLightState) (THIS_ D3DLIGHTSTATETYPE, DWORD) PURE;
+  STDMETHOD(SetTransform) (THIS_ D3DTRANSFORMSTATETYPE, LPD3DMATRIX) PURE;
+  STDMETHOD(GetTransform) (THIS_ D3DTRANSFORMSTATETYPE, LPD3DMATRIX) PURE;
+  STDMETHOD(MultiplyTransform) (THIS_ D3DTRANSFORMSTATETYPE, LPD3DMATRIX) PURE;
+  
+  STDMETHOD(DrawPrimitive) (THIS_ D3DPRIMITIVETYPE, D3DVERTEXTYPE, LPVOID, DWORD, DWORD) PURE;
+  STDMETHOD(DrawIndexedPrimitive) (THIS_ D3DPRIMITIVETYPE, D3DVERTEXTYPE, LPVOID, DWORD, LPWORD, DWORD, DWORD) PURE;
+  
+  STDMETHOD(SetClipStatus) (THIS_ LPD3DCLIPSTATUS) PURE;
+  STDMETHOD(GetClipStatus) (THIS_ LPD3DCLIPSTATUS) PURE;
+} *LPDIRECT3DDEVICE2_VTABLE,IDirect3DDevice2_VTable;
+
+struct IDirect3DDevice2 {
+  /* This are the fields common to all Direct3DDevice2 implementations */
+  LPDIRECT3DDEVICE2_VTABLE lpvtbl;
+  DWORD ref;
+  
+  LPDIRECT3D2 d3d;
+  LPDIRECTDRAWSURFACE surface;
+
+  LPDIRECT3DVIEWPORT2 viewport_list;
+  LPDIRECT3DVIEWPORT2 current_viewport;
+
+  void (*set_context)(THIS) ;
+};
+#undef THIS
+
+
 #undef THIS_
 #undef STDMETHOD
 #undef STDMETHOD_
diff --git a/include/wine_gl.h b/include/wine_gl.h
new file mode 100644
index 0000000..3fc7c9c
--- /dev/null
+++ b/include/wine_gl.h
@@ -0,0 +1,32 @@
+/* Wrapper for OpenGL includes...
+     Copyright 1998 - Lionel Ulmer
+
+   This wrapper is needed because Mesa uses also the CALLBACK / WINAPI
+   constants. */
+
+#ifndef __WINE_GL_H
+#define __WINE_GL_H
+
+#ifdef HAVE_MESAGL
+
+#undef APIENTRY
+#undef CALLBACK
+#undef WINAPI
+
+#include <GL/gl.h>
+/* These will need to have some #ifdef / #endif added to support
+   more than the X11 using OSMesa target */
+#include <GL/osmesa.h>
+
+#undef APIENTRY
+#undef CALLBACK
+#undef WINAPI
+
+/* Redefines the constants */
+#define CALLBACK    __stdcall
+#define WINAPI      __stdcall
+#define APIENTRY    WINAPI
+
+#endif /* HAVE_MESAGL */
+
+#endif /* __WINE_GL_H */
diff --git a/multimedia/dsound.c b/multimedia/dsound.c
index 1b5fb0f..e37a572 100644
--- a/multimedia/dsound.c
+++ b/multimedia/dsound.c
@@ -1211,17 +1211,17 @@
 		ds3db->lpvtbl = &ds3dbvt;
 		(*ppdsb)->ds3db = ds3db;
 		ds3db->ds3db.dwSize = sizeof(DS3DBUFFER);
-		ds3db->ds3db.vPosition.x = 0.0;
-		ds3db->ds3db.vPosition.y = 0.0;
-		ds3db->ds3db.vPosition.z = 0.0;
-		ds3db->ds3db.vVelocity.x = 0.0;
-		ds3db->ds3db.vVelocity.y = 0.0;
-		ds3db->ds3db.vVelocity.z = 0.0;
+		ds3db->ds3db.vPosition.x.x = 0.0;
+		ds3db->ds3db.vPosition.y.y = 0.0;
+		ds3db->ds3db.vPosition.z.z = 0.0;
+		ds3db->ds3db.vVelocity.x.x = 0.0;
+		ds3db->ds3db.vVelocity.y.y = 0.0;
+		ds3db->ds3db.vVelocity.z.z = 0.0;
 		ds3db->ds3db.dwInsideConeAngle = DS3D_DEFAULTCONEANGLE;
 		ds3db->ds3db.dwOutsideConeAngle = DS3D_DEFAULTCONEANGLE;
-		ds3db->ds3db.vConeOrientation.x = 0.0;
-		ds3db->ds3db.vConeOrientation.y = 0.0;
-		ds3db->ds3db.vConeOrientation.z = 0.0;
+		ds3db->ds3db.vConeOrientation.x.x = 0.0;
+		ds3db->ds3db.vConeOrientation.y.y = 0.0;
+		ds3db->ds3db.vConeOrientation.z.z = 0.0;
 		ds3db->ds3db.lConeOutsideVolume = DS3D_DEFAULTCONEOUTSIDEVOLUME;
 		ds3db->ds3db.flMinDistance = DS3D_DEFAULTMINDISTANCE;
 		ds3db->ds3db.flMaxDistance = DS3D_DEFAULTMAXDISTANCE;
@@ -1355,18 +1355,18 @@
 		this->listener->lpvtbl = &ds3dlvt;
 		this->lpvtbl->fnAddRef(this);
 		this->listener->ds3dl.dwSize = sizeof(DS3DLISTENER);
-		this->listener->ds3dl.vPosition.x = 0.0;
-		this->listener->ds3dl.vPosition.y = 0.0;
-		this->listener->ds3dl.vPosition.z = 0.0;
-		this->listener->ds3dl.vVelocity.x = 0.0;
-		this->listener->ds3dl.vVelocity.y = 0.0;
-		this->listener->ds3dl.vVelocity.z = 0.0;
-		this->listener->ds3dl.vOrientFront.x = 0.0;
-		this->listener->ds3dl.vOrientFront.y = 0.0;
-		this->listener->ds3dl.vOrientFront.z = 1.0;
-		this->listener->ds3dl.vOrientTop.x = 0.0;
-		this->listener->ds3dl.vOrientTop.y = 1.0;
-		this->listener->ds3dl.vOrientTop.z = 0.0;
+		this->listener->ds3dl.vPosition.x.x = 0.0;
+		this->listener->ds3dl.vPosition.y.y = 0.0;
+		this->listener->ds3dl.vPosition.z.z = 0.0;
+		this->listener->ds3dl.vVelocity.x.x = 0.0;
+		this->listener->ds3dl.vVelocity.y.y = 0.0;
+		this->listener->ds3dl.vVelocity.z.z = 0.0;
+		this->listener->ds3dl.vOrientFront.x.x = 0.0;
+		this->listener->ds3dl.vOrientFront.y.y = 0.0;
+		this->listener->ds3dl.vOrientFront.z.z = 1.0;
+		this->listener->ds3dl.vOrientTop.x.x = 0.0;
+		this->listener->ds3dl.vOrientTop.y.y = 1.0;
+		this->listener->ds3dl.vOrientTop.z.z = 0.0;
 		this->listener->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
 		this->listener->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
 		this->listener->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;