Add Get/Set Transform support, plus BeginScene (does nothing).
[wine] / dlls / wined3d / directx.c
1 /*
2  * IWineD3D implementation
3  *
4  * Copyright 2002-2004 Jason Edmeades
5  * Copyright 2003-2004 Raphael Junqueira
6  * Copyright 2004 Christian Costa
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 /* Compile time diagnostics: */
24
25 /* Uncomment this to force only a single display mode to be exposed: */
26 /*#define DEBUG_SINGLE_MODE*/
27
28
29 #include "config.h"
30 #include "wined3d_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
33 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
34 #define GLINFO_LOCATION This->gl_info
35
36 /**********************************************************
37  * Utility functions follow
38  **********************************************************/
39
40 /* x11drv GDI escapes */
41 #define X11DRV_ESCAPE 6789
42 enum x11drv_escape_codes
43 {
44     X11DRV_GET_DISPLAY,   /* get X11 display for a DC */
45     X11DRV_GET_DRAWABLE,  /* get current drawable for a DC */
46     X11DRV_GET_FONT,      /* get current X font for a DC */
47 };
48
49 /* retrieve the X display to use on a given DC */
50 inline static Display *get_display( HDC hdc )
51 {
52     Display *display;
53     enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
54
55     if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
56                     sizeof(display), (LPSTR)&display )) display = NULL;
57     return display;
58 }
59
60 /**
61  * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
62  * ie there is no GL Context - Get a default rendering context to enable the 
63  * function query some info from GL                                     
64  */    
65 static WineD3D_Context* WineD3D_CreateFakeGLContext(void) {
66     static WineD3D_Context ctx = { NULL, NULL, NULL, 0, 0 };
67     WineD3D_Context* ret = NULL;
68
69     if (glXGetCurrentContext() == NULL) {
70        BOOL         gotContext  = FALSE;
71        BOOL         created     = FALSE;
72        XVisualInfo  template;
73        HDC          device_context;
74        Visual*      visual;
75        BOOL         failed = FALSE;
76        int          num;
77        XWindowAttributes win_attr;
78      
79        TRACE_(d3d_caps)("Creating Fake GL Context\n");
80
81        ctx.drawable = (Drawable) GetPropA(GetDesktopWindow(), "__wine_x11_whole_window");
82
83        /* Get the display */
84        device_context = GetDC(0);
85        ctx.display = get_display(device_context);
86        ReleaseDC(0, device_context);
87      
88        /* Get the X visual */
89        ENTER_GL();
90        if (XGetWindowAttributes(ctx.display, ctx.drawable, &win_attr)) {
91            visual = win_attr.visual;
92        } else {
93            visual = DefaultVisual(ctx.display, DefaultScreen(ctx.display));
94        }
95        template.visualid = XVisualIDFromVisual(visual);
96        ctx.visInfo = XGetVisualInfo(ctx.display, VisualIDMask, &template, &num);
97        if (ctx.visInfo == NULL) {
98            LEAVE_GL();
99            WARN_(d3d_caps)("Error creating visual info for capabilities initialization\n");
100            failed = TRUE;
101        }
102      
103        /* Create a GL context */
104        if (!failed) {
105            ctx.glCtx = glXCreateContext(ctx.display, ctx.visInfo, NULL, GL_TRUE);
106        
107            if (ctx.glCtx == NULL) {
108                LEAVE_GL();
109                WARN_(d3d_caps)("Error creating default context for capabilities initialization\n");
110                failed = TRUE;
111            }
112        }
113      
114        /* Make it the current GL context */
115        if (!failed && glXMakeCurrent(ctx.display, ctx.drawable, ctx.glCtx) == False) {
116            glXDestroyContext(ctx.display, ctx.glCtx);
117            LEAVE_GL();
118            WARN_(d3d_caps)("Error setting default context as current for capabilities initialization\n");
119            failed = TRUE;        
120        }
121      
122        /* It worked! Wow... */
123        if (!failed) {
124            gotContext = TRUE;
125            created = TRUE;
126            ret = &ctx;
127        } else {
128            ret = NULL;
129        }
130
131    } else {
132      if (ctx.ref > 0) ret = &ctx;
133    }
134
135    if (NULL != ret) InterlockedIncrement(&ret->ref);
136    return ret;
137 }
138
139 static void WineD3D_ReleaseFakeGLContext(WineD3D_Context* ctx) {
140     /* If we created a dummy context, throw it away */
141     if (NULL != ctx) {
142         if (0 == InterlockedDecrement(&ctx->ref)) {
143             glXMakeCurrent(ctx->display, None, NULL);
144             glXDestroyContext(ctx->display, ctx->glCtx);
145             ctx->display = NULL;
146             ctx->glCtx = NULL;
147             LEAVE_GL();
148         }
149     }
150 }
151
152 static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info, Display* display) {
153     const char *GL_Extensions    = NULL;
154     const char *GLX_Extensions   = NULL;
155     const char *gl_string        = NULL;
156     const char *gl_string_cursor = NULL;
157     GLint       gl_max;
158     Bool        test = 0;
159     int         major, minor;
160
161     TRACE_(d3d_caps)("(%p, %p)\n", gl_info, display);
162
163     /* Fill in the GL info retrievable depending on the display */
164     if (NULL != display) {
165         test = glXQueryVersion(display, &major, &minor);
166         gl_info->glx_version = ((major & 0x0000FFFF) << 16) | (minor & 0x0000FFFF);
167         gl_string = glXGetClientString(display, GLX_VENDOR);
168     } else {
169         gl_string = glGetString(GL_VENDOR);
170     }
171     
172     /* Fill in the GL vendor */
173     if (strstr(gl_string, "NVIDIA")) {
174         gl_info->gl_vendor = VENDOR_NVIDIA;
175     } else if (strstr(gl_string, "ATI")) {
176         gl_info->gl_vendor = VENDOR_ATI;
177     } else {
178         gl_info->gl_vendor = VENDOR_WINE;
179     }
180    
181     TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string), gl_info->gl_vendor);
182     
183     /* Parse the GL_VERSION field into major and minor information */
184     gl_string = glGetString(GL_VERSION);
185     switch (gl_info->gl_vendor) {
186     case VENDOR_NVIDIA:
187         gl_string_cursor = strstr(gl_string, "NVIDIA");
188         gl_string_cursor = strstr(gl_string_cursor, " ");
189         while (*gl_string_cursor && ' ' == *gl_string_cursor) ++gl_string_cursor;
190         if (*gl_string_cursor) {
191             char tmp[16];
192             int cursor = 0;
193
194             while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
195                 tmp[cursor++] = *gl_string_cursor;
196                 ++gl_string_cursor;
197             }
198             tmp[cursor] = 0;
199             major = atoi(tmp);
200         
201             if (*gl_string_cursor != '.') WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
202             ++gl_string_cursor;
203
204             while (*gl_string_cursor <= '9' && *gl_string_cursor >= '0') {
205                 tmp[cursor++] = *gl_string_cursor;
206                 ++gl_string_cursor;
207             }
208             tmp[cursor] = 0;
209             minor = atoi(tmp);
210         }
211         break;
212
213     case VENDOR_ATI:
214         major = minor = 0;
215         gl_string_cursor = strchr(gl_string, '-');
216         if (gl_string_cursor++) {
217             int error = 0;
218
219             /* Check if version number is of the form x.y.z */
220             if (*gl_string_cursor > '9' && *gl_string_cursor < '0')
221                 error = 1;
222             if (!error && *(gl_string_cursor+2) > '9' && *(gl_string_cursor+2) < '0')
223                 error = 1;
224             if (!error && *(gl_string_cursor+4) > '9' && *(gl_string_cursor+4) < '0')
225                 error = 1;
226             if (!error && *(gl_string_cursor+1) != '.' && *(gl_string_cursor+3) != '.')
227                 error = 1;
228
229             /* Mark version number as malformed */
230             if (error)
231                 gl_string_cursor = 0;
232         }
233
234         if (!gl_string_cursor)
235             WARN_(d3d_caps)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string));
236         else {
237             major = *gl_string_cursor - '0';
238             minor = (*(gl_string_cursor+2) - '0') * 256 + (*(gl_string_cursor+4) - '0');
239         }      
240         break;
241
242     default:
243         major = 0;
244         minor = 9;
245     }
246     gl_info->gl_driver_version = MAKEDWORD_VERSION(major, minor);
247     TRACE_(d3d_caps)("found GL_VERSION  (%s)->(0x%08lx)\n", debugstr_a(gl_string), gl_info->gl_driver_version);
248
249     /* Fill in the renderer information */
250     gl_string = glGetString(GL_RENDERER);
251     strcpy(gl_info->gl_renderer, gl_string);
252
253     switch (gl_info->gl_vendor) {
254     case VENDOR_NVIDIA:
255         if (strstr(gl_info->gl_renderer, "GeForce4 Ti")) {
256             gl_info->gl_card = CARD_NVIDIA_GEFORCE4_TI4600;
257         } else if (strstr(gl_info->gl_renderer, "GeForceFX")) {
258             gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5900ULTRA;
259         } else {
260             gl_info->gl_card = CARD_NVIDIA_GEFORCE4_TI4600;
261         }
262         break;
263
264     case VENDOR_ATI:
265         if (strstr(gl_info->gl_renderer, "RADEON 9800 PRO")) {
266             gl_info->gl_card = CARD_ATI_RADEON_9800PRO;
267         } else if (strstr(gl_info->gl_renderer, "RADEON 9700 PRO")) {
268             gl_info->gl_card = CARD_ATI_RADEON_9700PRO;
269         } else {
270             gl_info->gl_card = CARD_ATI_RADEON_8500;
271         }
272         break;
273
274     default:
275         gl_info->gl_card = CARD_WINE;
276         break;
277     }
278
279     TRACE_(d3d_caps)("found GL_RENDERER (%s)->(0x%04x)\n", debugstr_a(gl_info->gl_renderer), gl_info->gl_card);
280
281     /*
282      * Initialize openGL extension related variables
283      *  with Default values
284      */
285     memset(&gl_info->supported, 0, sizeof(gl_info->supported));
286     gl_info->max_textures   = 1;
287     gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED;
288     gl_info->vs_arb_version = VS_VERSION_NOT_SUPPORTED;
289     gl_info->vs_nv_version  = VS_VERSION_NOT_SUPPORTED;
290     gl_info->vs_ati_version = VS_VERSION_NOT_SUPPORTED;
291
292     /* Now work out what GL support this card really has */
293 #define USE_GL_FUNC(type, pfn) gl_info->pfn = NULL;
294     GL_EXT_FUNCS_GEN;
295 #undef USE_GL_FUNC
296
297     /* Retrieve opengl defaults */
298     glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
299     gl_info->max_clipplanes = min(D3DMAXUSERCLIPPLANES, gl_max);
300     TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
301
302     glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
303     gl_info->max_lights = gl_max;
304     TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
305
306     /* Parse the gl supported features, in theory enabling parts of our code appropriately */
307     GL_Extensions = glGetString(GL_EXTENSIONS);
308     TRACE_(d3d_caps)("GL_Extensions reported:\n");  
309     
310     if (NULL == GL_Extensions) {
311         ERR("   GL_Extensions returns NULL\n");      
312     } else {
313         while (*GL_Extensions != 0x00) {
314             const char *Start = GL_Extensions;
315             char        ThisExtn[256];
316
317             memset(ThisExtn, 0x00, sizeof(ThisExtn));
318             while (*GL_Extensions != ' ' && *GL_Extensions != 0x00) {
319                 GL_Extensions++;
320             }
321             memcpy(ThisExtn, Start, (GL_Extensions - Start));
322             TRACE_(d3d_caps)("- %s\n", ThisExtn);
323
324             /**
325              * ARB 
326              */
327             if (strcmp(ThisExtn, "GL_ARB_fragment_program") == 0) {
328                 gl_info->ps_arb_version = PS_VERSION_11;
329                 TRACE_(d3d_caps)(" FOUND: ARB Pixel Shader support - version=%02x\n", gl_info->ps_arb_version);
330                 gl_info->supported[ARB_FRAGMENT_PROGRAM] = TRUE;
331             } else if (strcmp(ThisExtn, "GL_ARB_multisample") == 0) {
332                 TRACE_(d3d_caps)(" FOUND: ARB Multisample support\n");
333                 gl_info->supported[ARB_MULTISAMPLE] = TRUE;
334             } else if (strcmp(ThisExtn, "GL_ARB_multitexture") == 0) {
335                 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
336                 TRACE_(d3d_caps)(" FOUND: ARB Multitexture support - GL_MAX_TEXTURE_UNITS_ARB=%u\n", gl_max);
337                 gl_info->supported[ARB_MULTITEXTURE] = TRUE;
338                 gl_info->max_textures = min(8, gl_max);
339             } else if (strcmp(ThisExtn, "GL_ARB_texture_cube_map") == 0) {
340                 TRACE_(d3d_caps)(" FOUND: ARB Texture Cube Map support\n");
341                 gl_info->supported[ARB_TEXTURE_CUBE_MAP] = TRUE;
342                 TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support\n");
343                 gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
344             } else if (strcmp(ThisExtn, "GL_ARB_texture_compression") == 0) {
345                 TRACE_(d3d_caps)(" FOUND: ARB Texture Compression support\n");
346                 gl_info->supported[ARB_TEXTURE_COMPRESSION] = TRUE;
347             } else if (strcmp(ThisExtn, "GL_ARB_texture_env_add") == 0) {
348                 TRACE_(d3d_caps)(" FOUND: ARB Texture Env Add support\n");
349                 gl_info->supported[ARB_TEXTURE_ENV_ADD] = TRUE;
350             } else if (strcmp(ThisExtn, "GL_ARB_texture_env_combine") == 0) {
351                 TRACE_(d3d_caps)(" FOUND: ARB Texture Env combine support\n");
352                 gl_info->supported[ARB_TEXTURE_ENV_COMBINE] = TRUE;
353             } else if (strcmp(ThisExtn, "GL_ARB_texture_env_dot3") == 0) {
354                 TRACE_(d3d_caps)(" FOUND: ARB Dot3 support\n");
355                 gl_info->supported[ARB_TEXTURE_ENV_DOT3] = TRUE;
356             } else if (strcmp(ThisExtn, "GL_ARB_texture_border_clamp") == 0) {
357                 TRACE_(d3d_caps)(" FOUND: ARB Texture border clamp support\n");
358                 gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] = TRUE;
359             } else if (strcmp(ThisExtn, "GL_ARB_texture_mirrored_repeat") == 0) {
360                 TRACE_(d3d_caps)(" FOUND: ARB Texture mirrored repeat support\n");
361                 gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] = TRUE;
362             } else if (strstr(ThisExtn, "GL_ARB_vertex_program")) {
363                 gl_info->vs_arb_version = VS_VERSION_11;
364                 TRACE_(d3d_caps)(" FOUND: ARB Vertex Shader support - version=%02x\n", gl_info->vs_arb_version);
365                 gl_info->supported[ARB_VERTEX_PROGRAM] = TRUE;
366
367             /**
368              * EXT
369              */
370             } else if (strcmp(ThisExtn, "GL_EXT_fog_coord") == 0) {
371                 TRACE_(d3d_caps)(" FOUND: EXT Fog coord support\n");
372                 gl_info->supported[EXT_FOG_COORD] = TRUE;
373             } else if (strcmp(ThisExtn, "GL_EXT_paletted_texture") == 0) { /* handle paletted texture extensions */
374                 TRACE_(d3d_caps)(" FOUND: EXT Paletted texture support\n");
375                 gl_info->supported[EXT_PALETTED_TEXTURE] = TRUE;
376             } else if (strcmp(ThisExtn, "GL_EXT_point_parameters") == 0) {
377                 TRACE_(d3d_caps)(" FOUND: EXT Point parameters support\n");
378                 gl_info->supported[EXT_POINT_PARAMETERS] = TRUE;
379             } else if (strcmp(ThisExtn, "GL_EXT_secondary_color") == 0) {
380                 TRACE_(d3d_caps)(" FOUND: EXT Secondary coord support\n");
381                 gl_info->supported[EXT_SECONDARY_COLOR] = TRUE;
382             } else if (strcmp(ThisExtn, "GL_EXT_stencil_wrap") == 0) {
383                 TRACE_(d3d_caps)(" FOUND: EXT Stencil wrap support\n");
384                 gl_info->supported[EXT_STENCIL_WRAP] = TRUE;
385             } else if (strcmp(ThisExtn, "GL_EXT_texture_compression_s3tc") == 0) {
386                 TRACE_(d3d_caps)(" FOUND: EXT Texture S3TC compression support\n");
387                 gl_info->supported[EXT_TEXTURE_COMPRESSION_S3TC] = TRUE;
388             } else if (strcmp(ThisExtn, "GL_EXT_texture_env_add") == 0) {
389                 TRACE_(d3d_caps)(" FOUND: EXT Texture Env Add support\n");
390                 gl_info->supported[EXT_TEXTURE_ENV_ADD] = TRUE;
391             } else if (strcmp(ThisExtn, "GL_EXT_texture_env_combine") == 0) {
392                 TRACE_(d3d_caps)(" FOUND: EXT Texture Env combine support\n");
393                 gl_info->supported[EXT_TEXTURE_ENV_COMBINE] = TRUE;
394             } else if (strcmp(ThisExtn, "GL_EXT_texture_env_dot3") == 0) {
395                 TRACE_(d3d_caps)(" FOUND: EXT Dot3 support\n");
396                 gl_info->supported[EXT_TEXTURE_ENV_DOT3] = TRUE;
397             } else if (strcmp(ThisExtn, "GL_EXT_texture_filter_anisotropic") == 0) {
398                 TRACE_(d3d_caps)(" FOUND: EXT Texture Anisotropic filter support\n");
399                 gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] = TRUE;
400             } else if (strcmp(ThisExtn, "GL_EXT_texture_lod") == 0) {
401                 TRACE_(d3d_caps)(" FOUND: EXT Texture LOD support\n");
402                 gl_info->supported[EXT_TEXTURE_LOD] = TRUE;
403             } else if (strcmp(ThisExtn, "GL_EXT_texture_lod_bias") == 0) {
404                 TRACE_(d3d_caps)(" FOUND: EXT Texture LOD bias support\n");
405                 gl_info->supported[EXT_TEXTURE_LOD_BIAS] = TRUE;
406             } else if (strcmp(ThisExtn, "GL_EXT_vertex_weighting") == 0) {
407                 TRACE_(d3d_caps)(" FOUND: EXT Vertex weighting support\n");
408                 gl_info->supported[EXT_VERTEX_WEIGHTING] = TRUE;
409
410             /**
411              * NVIDIA 
412              */
413             } else if (strstr(ThisExtn, "GL_NV_fog_distance")) {
414                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Fog Distance support\n");
415                 gl_info->supported[NV_FOG_DISTANCE] = TRUE;
416             } else if (strstr(ThisExtn, "GL_NV_fragment_program")) {
417                 gl_info->ps_nv_version = PS_VERSION_11;
418                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", gl_info->ps_nv_version);
419             } else if (strcmp(ThisExtn, "GL_NV_register_combiners") == 0) {
420                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Register combiners (1) support\n");
421                 gl_info->supported[NV_REGISTER_COMBINERS] = TRUE;
422             } else if (strcmp(ThisExtn, "GL_NV_register_combiners2") == 0) {
423                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Register combiners (2) support\n");
424                 gl_info->supported[NV_REGISTER_COMBINERS2] = TRUE;
425             } else if (strcmp(ThisExtn, "GL_NV_texgen_reflection") == 0) {
426                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Gen Reflection support\n");
427                 gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
428             } else if (strcmp(ThisExtn, "GL_NV_texture_env_combine4") == 0) {
429                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Env combine (4) support\n");
430                 gl_info->supported[NV_TEXTURE_ENV_COMBINE4] = TRUE;
431             } else if (strcmp(ThisExtn, "GL_NV_texture_shader") == 0) {
432                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Shader (1) support\n");
433                 gl_info->supported[NV_TEXTURE_SHADER] = TRUE;
434             } else if (strcmp(ThisExtn, "GL_NV_texture_shader2") == 0) {
435                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Shader (2) support\n");
436                 gl_info->supported[NV_TEXTURE_SHADER2] = TRUE;
437             } else if (strcmp(ThisExtn, "GL_NV_texture_shader3") == 0) {
438                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Shader (3) support\n");
439                 gl_info->supported[NV_TEXTURE_SHADER3] = TRUE;
440             } else if (strstr(ThisExtn, "GL_NV_vertex_program")) {
441                 gl_info->vs_nv_version = max(gl_info->vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program1_1")) ? VS_VERSION_11 : VS_VERSION_10);
442                 gl_info->vs_nv_version = max(gl_info->vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program2"))   ? VS_VERSION_20 : VS_VERSION_10);
443                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", gl_info->vs_nv_version);
444                 gl_info->supported[NV_VERTEX_PROGRAM] = TRUE;
445
446             /**
447              * ATI
448              */
449             /** TODO */
450             } else if (strcmp(ThisExtn, "GL_ATI_texture_env_combine3") == 0) {
451                 TRACE_(d3d_caps)(" FOUND: ATI Texture Env combine (3) support\n");
452                 gl_info->supported[ATI_TEXTURE_ENV_COMBINE3] = TRUE;
453             } else if (strcmp(ThisExtn, "GL_ATI_texture_mirror_once") == 0) {
454                 TRACE_(d3d_caps)(" FOUND: ATI Texture Mirror Once support\n");
455                 gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] = TRUE;
456             } else if (strcmp(ThisExtn, "GL_EXT_vertex_shader") == 0) {
457                 gl_info->vs_ati_version = VS_VERSION_11;
458                 TRACE_(d3d_caps)(" FOUND: ATI (EXT) Vertex Shader support - version=%02x\n", gl_info->vs_ati_version);
459                 gl_info->supported[EXT_VERTEX_SHADER] = TRUE;
460             }
461
462
463             if (*GL_Extensions == ' ') GL_Extensions++;
464         }
465     }
466
467 #define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) glXGetProcAddressARB(#pfn);
468     GL_EXT_FUNCS_GEN;
469 #undef USE_GL_FUNC
470
471     if (display != NULL) {
472         GLX_Extensions = glXQueryExtensionsString(display, DefaultScreen(display));
473         TRACE_(d3d_caps)("GLX_Extensions reported:\n");  
474     
475         if (NULL == GLX_Extensions) {
476             ERR("   GLX_Extensions returns NULL\n");      
477         } else {
478             while (*GLX_Extensions != 0x00) {
479                 const char *Start = GLX_Extensions;
480                 char ThisExtn[256];
481            
482                 memset(ThisExtn, 0x00, sizeof(ThisExtn));
483                 while (*GLX_Extensions != ' ' && *GLX_Extensions != 0x00) {
484                     GLX_Extensions++;
485                 }
486                 memcpy(ThisExtn, Start, (GLX_Extensions - Start));
487                 TRACE_(d3d_caps)("- %s\n", ThisExtn);
488                 if (*GLX_Extensions == ' ') GLX_Extensions++;
489             }
490         }
491     }
492
493 #define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) glXGetProcAddressARB(#pfn);
494     GLX_EXT_FUNCS_GEN;
495 #undef USE_GL_FUNC
496
497     /* Only save the values obtained when a display is provided */
498     if (display != NULL) {
499         return TRUE;
500     } else {
501         return FALSE;
502     }
503 }
504
505 /**********************************************************
506  * IWineD3D implementation follows
507  **********************************************************/
508
509 UINT     WINAPI  IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
510     IWineD3DImpl *This = (IWineD3DImpl *)iface;
511
512     /* FIXME: Set to one for now to imply the display */
513     TRACE_(d3d_caps)("(%p): Mostly stub, only returns primary display\n", This);
514     return 1;
515 }
516
517 HRESULT  WINAPI  IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void* pInitializeFunction) {
518     IWineD3DImpl *This = (IWineD3DImpl *)iface;
519     FIXME("(%p)->(%p): stub\n", This, pInitializeFunction);
520     return D3D_OK;
521 }
522
523 HMONITOR WINAPI  IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
524     IWineD3DImpl *This = (IWineD3DImpl *)iface;
525     FIXME_(d3d_caps)("(%p)->(Adptr:%d)\n", This, Adapter);
526     if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
527         return NULL;
528     }
529     return D3D_OK;
530 }
531
532 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes 
533      of the same bpp but different resolutions                                  */
534
535 /* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
536 UINT     WINAPI  IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, D3DFORMAT Format) {
537     IWineD3DImpl *This = (IWineD3DImpl *)iface;
538     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
539
540     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
541         return 0;
542     }
543
544     if (Adapter == 0) { /* Display */
545         int i = 0;
546         int j = 0;
547 #if !defined( DEBUG_SINGLE_MODE )
548         DEVMODEW DevModeW;
549
550         /* Work out the current screen bpp */
551         HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
552         int bpp = GetDeviceCaps(hdc, BITSPIXEL);
553         DeleteDC(hdc);
554
555         while (EnumDisplaySettingsExW(NULL, j, &DevModeW, 0)) {
556             j++;
557             switch (Format)
558             {
559             case D3DFMT_UNKNOWN: 
560                    i++; 
561                    break;
562             case D3DFMT_X8R8G8B8:   
563             case D3DFMT_A8R8G8B8:   
564                    if (min(DevModeW.dmBitsPerPel, bpp) == 32) i++; 
565                    break;
566             case D3DFMT_X1R5G5B5:
567             case D3DFMT_A1R5G5B5:
568             case D3DFMT_R5G6B5:
569                    if (min(DevModeW.dmBitsPerPel, bpp) == 16) i++; 
570                    break;
571             default:
572                    /* Skip other modes as they do not match requested format */
573                    break;
574             }
575         }
576 #else
577         i = 1;
578         j = 1;
579 #endif
580         TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
581         return i;
582     } else {
583         FIXME_(d3d_caps)("Adapter not primary display\n");
584     }
585     return 0;
586 }
587
588 /* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
589 HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) {
590     IWineD3DImpl *This = (IWineD3DImpl *)iface;
591     TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
592
593     /* Validate the parameters as much as possible */
594     if (NULL == pMode || 
595         Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
596         Mode    >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
597         return D3DERR_INVALIDCALL;
598     }
599
600     if (Adapter == 0) { /* Display */
601 #if !defined( DEBUG_SINGLE_MODE )
602         DEVMODEW DevModeW;
603         int ModeIdx = 0;
604             
605         /* Work out the current screen bpp */
606         HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
607         int bpp = GetDeviceCaps(hdc, BITSPIXEL);
608         DeleteDC(hdc);
609
610         /* If we are filtering to a specific format, then need to skip all unrelated
611            modes, but if mode is irrelevant, then we can use the index directly      */
612         if (Format == D3DFMT_UNKNOWN) 
613         {
614             ModeIdx = Mode;
615         } else {
616             int i = 0;
617             int j = 0;
618             DEVMODEW DevModeWtmp;
619             
620             
621             while ((Mode+1) < i && EnumDisplaySettingsExW(NULL, j, &DevModeWtmp, 0)) {
622                 j++;
623                 switch (Format)
624                 {
625                 case D3DFMT_UNKNOWN: 
626                        i++; 
627                        break;
628                 case D3DFMT_X8R8G8B8:   
629                 case D3DFMT_A8R8G8B8:   
630                        if (min(DevModeWtmp.dmBitsPerPel, bpp) == 32) i++; 
631                        break;
632                 case D3DFMT_X1R5G5B5:
633                 case D3DFMT_A1R5G5B5:
634                 case D3DFMT_R5G6B5:
635                        if (min(DevModeWtmp.dmBitsPerPel, bpp) == 16) i++; 
636                        break;
637                 default:
638                        /* Skip other modes as they do not match requested format */
639                        break;
640                 }
641             }
642             ModeIdx = j;
643         }
644
645         /* Now get the display mode via the calculated index */
646         if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) 
647         {
648             pMode->Width        = DevModeW.dmPelsWidth;
649             pMode->Height       = DevModeW.dmPelsHeight;
650             bpp                 = min(DevModeW.dmBitsPerPel, bpp);
651             pMode->RefreshRate  = D3DADAPTER_DEFAULT;
652             if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
653             {
654                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
655             }
656
657             if (Format == D3DFMT_UNKNOWN)
658             {
659                 switch (bpp) {
660                 case  8: pMode->Format = D3DFMT_R3G3B2;   break;
661                 case 16: pMode->Format = D3DFMT_R5G6B5;   break;
662                 case 24: /* pMode->Format = D3DFMT_R5G6B5;   break;*/ /* Make 24bit appear as 32 bit */
663                 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
664                 default: pMode->Format = D3DFMT_UNKNOWN;
665                 }
666             } else {
667                 pMode->Format = Format;
668             }
669         }
670         else
671         {
672             TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
673             return D3DERR_INVALIDCALL;
674         }
675
676 #else
677         /* Return one setting of the format requested */
678         if (Mode > 0) return D3DERR_INVALIDCALL;
679         pMode->Width        = 800;
680         pMode->Height       = 600;
681         pMode->RefreshRate  = D3DADAPTER_DEFAULT;
682         pMode->Format       = (Format==D3DFMT_UNKNOWN)?D3DFMT_A8R8G8B8:Format;
683         bpp = 32;
684 #endif
685         TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height, 
686                  pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format), bpp);
687
688     } else {
689         FIXME_(d3d_caps)("Adapter not primary display\n");
690     }
691
692     return D3D_OK;
693 }
694
695 HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, D3DDISPLAYMODE* pMode) {
696     IWineD3DImpl *This = (IWineD3DImpl *)iface;
697     TRACE_(d3d_caps)("(%p}->(Adapter: %d, pMode: %p)\n", This, Adapter, pMode);
698
699     if (NULL == pMode || 
700         Adapter >= IWineD3D_GetAdapterCount(iface)) {
701         return D3DERR_INVALIDCALL;
702     }
703
704     if (Adapter == 0) { /* Display */
705         int bpp = 0;
706         DEVMODEW DevModeW;
707
708         EnumDisplaySettingsExW(NULL, (DWORD)-1, &DevModeW, 0);
709         pMode->Width        = DevModeW.dmPelsWidth;
710         pMode->Height       = DevModeW.dmPelsHeight;
711         bpp                 = DevModeW.dmBitsPerPel;
712         pMode->RefreshRate  = D3DADAPTER_DEFAULT;
713         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
714         {
715             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
716         }
717
718         switch (bpp) {
719         case  8: pMode->Format       = D3DFMT_R3G3B2;   break;
720         case 16: pMode->Format       = D3DFMT_R5G6B5;   break;
721         case 24: /*pMode->Format       = D3DFMT_R5G6B5;   break;*/ /* Make 24bit appear as 32 bit */
722         case 32: pMode->Format       = D3DFMT_A8R8G8B8; break;
723         default: pMode->Format       = D3DFMT_UNKNOWN;
724         }
725
726     } else {
727         FIXME_(d3d_caps)("Adapter not primary display\n");
728     }
729
730     TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
731           pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
732     return D3D_OK;
733 }
734
735 /* Note due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
736    and fields being inserted in the middle, a new structure is used in place    */
737 HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags, 
738                                                    WINED3DADAPTER_IDENTIFIER* pIdentifier) {
739     IWineD3DImpl *This = (IWineD3DImpl *)iface;
740
741     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %lx, pId=%p)\n", This, Adapter, Flags, pIdentifier);
742
743     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
744         return D3DERR_INVALIDCALL;
745     }
746
747     if (Adapter == 0) { /* Display - only device supported for now */
748         
749         BOOL isGLInfoValid = This->isGLInfoValid;
750
751         /* FillGLCaps updates gl_info, but we only want to store and 
752            reuse the values once we have a context which is valid. Values from
753            a temporary context may differ from the final ones                 */
754         if (isGLInfoValid == FALSE) {
755         
756           /* If we don't know the device settings, go query them now via a 
757              fake context                                                   */
758           WineD3D_Context* ctx = WineD3D_CreateFakeGLContext();
759           if (NULL != ctx) {
760               isGLInfoValid = IWineD3DImpl_FillGLCaps(&This->gl_info, ctx->display);
761               WineD3D_ReleaseFakeGLContext(ctx);
762           }
763         }
764
765         /* If it worked, return the information requested */
766         if (isGLInfoValid == TRUE) {
767           TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
768           strcpy(pIdentifier->Driver, "Display");
769           strcpy(pIdentifier->Description, "Direct3D HAL");
770
771           /* Note dx8 doesn't supply a DeviceName */
772           if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
773           pIdentifier->DriverVersion->u.HighPart = 0xa;
774           pIdentifier->DriverVersion->u.LowPart = This->gl_info.gl_driver_version;
775           *(pIdentifier->VendorId) = This->gl_info.gl_vendor;
776           *(pIdentifier->DeviceId) = This->gl_info.gl_card;
777           *(pIdentifier->SubSysId) = 0;
778           *(pIdentifier->Revision) = 0;
779
780         } else {
781
782           /* If it failed, return dummy values from an NVidia driver */
783           WARN_(d3d_caps)("Cannot get GLCaps for device/Vendor Name and Version detection using FillGLCaps, currently using NVIDIA identifiers\n");
784           strcpy(pIdentifier->Driver, "Display");
785           strcpy(pIdentifier->Description, "Direct3D HAL");
786           if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
787           pIdentifier->DriverVersion->u.HighPart = 0xa;
788           pIdentifier->DriverVersion->u.LowPart = MAKEDWORD_VERSION(53, 96); /* last Linux Nvidia drivers */
789           *(pIdentifier->VendorId) = VENDOR_NVIDIA;
790           *(pIdentifier->DeviceId) = CARD_NVIDIA_GEFORCE4_TI4600;
791           *(pIdentifier->SubSysId) = 0;
792           *(pIdentifier->Revision) = 0;
793         }
794
795         /*FIXME: memcpy(&pIdentifier->DeviceIdentifier, ??, sizeof(??GUID)); */
796         if (Flags & D3DENUM_NO_WHQL_LEVEL) {
797             *(pIdentifier->WHQLLevel) = 0;
798         } else {
799             *(pIdentifier->WHQLLevel) = 1;
800         }
801
802     } else {
803         FIXME_(d3d_caps)("Adapter not primary display\n");
804     }
805
806     return D3D_OK;
807 }
808
809 HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT Adapter, D3DDEVTYPE DeviceType, 
810                 D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) {
811     IWineD3DImpl *This = (IWineD3DImpl *)iface;
812     WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n", 
813            This, Adapter, 
814            DeviceType, debug_d3ddevicetype(DeviceType),
815            AdapterFormat, debug_d3dformat(AdapterFormat),
816            RenderTargetFormat, debug_d3dformat(RenderTargetFormat), 
817            DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
818
819     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
820         return D3DERR_INVALIDCALL;
821     }
822
823     return D3D_OK;
824 }
825
826 HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface,
827                 UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat,
828                 BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) {
829     
830     IWineD3DImpl *This = (IWineD3DImpl *)iface;
831     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n", 
832           This, 
833           Adapter, 
834           DeviceType, debug_d3ddevicetype(DeviceType),
835           SurfaceFormat, debug_d3dformat(SurfaceFormat),
836           Windowed, 
837           MultiSampleType,
838           pQualityLevels);
839   
840     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
841         return D3DERR_INVALIDCALL;
842     }
843
844     if (pQualityLevels != NULL) {
845         FIXME("Quality levels unsupported at present\n");
846         *pQualityLevels = 1; /* Guess at a value! */
847     }
848
849     if (D3DMULTISAMPLE_NONE == MultiSampleType)
850       return D3D_OK;
851     return D3DERR_NOTAVAILABLE;
852 }
853
854 HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface,
855                 UINT Adapter, D3DDEVTYPE CheckType, D3DFORMAT DisplayFormat,
856                 D3DFORMAT BackBufferFormat, BOOL Windowed) {
857
858     IWineD3DImpl *This = (IWineD3DImpl *)iface;
859     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n", 
860           This, 
861           Adapter, 
862           CheckType, debug_d3ddevicetype(CheckType),
863           DisplayFormat, debug_d3dformat(DisplayFormat),
864           BackBufferFormat, debug_d3dformat(BackBufferFormat),
865           Windowed);
866
867     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
868         return D3DERR_INVALIDCALL;
869     }
870
871     switch (DisplayFormat) {
872       /*case D3DFMT_R5G6B5:*/
873     case D3DFMT_R3G3B2:
874       return D3DERR_NOTAVAILABLE;
875     default:
876       break;
877     }
878     return D3D_OK;
879 }
880
881 HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface,
882                 UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
883                 DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) {
884     IWineD3DImpl *This = (IWineD3DImpl *)iface;
885     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%lu,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s)) ", 
886           This, 
887           Adapter, 
888           DeviceType, debug_d3ddevicetype(DeviceType), 
889           AdapterFormat, debug_d3dformat(AdapterFormat), 
890           Usage, debug_d3dusage(Usage),
891           RType, debug_d3dresourcetype(RType), 
892           CheckFormat, debug_d3dformat(CheckFormat));
893
894     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
895         return D3DERR_INVALIDCALL;
896     }
897
898     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
899         switch (CheckFormat) {
900         case D3DFMT_DXT1:
901         case D3DFMT_DXT3:
902         case D3DFMT_DXT5:
903           TRACE_(d3d_caps)("[OK]\n");
904           return D3D_OK;
905         default:
906             break; /* Avoid compiler warnings */
907         }
908     }
909
910     switch (CheckFormat) {
911     /*****
912      * check supported using GL_SUPPORT 
913      */
914     case D3DFMT_DXT1:
915     case D3DFMT_DXT2:
916     case D3DFMT_DXT3:
917     case D3DFMT_DXT4:
918     case D3DFMT_DXT5: 
919
920     /*****
921      *  supported 
922      */
923       /*case D3DFMT_R5G6B5: */
924       /*case D3DFMT_X1R5G5B5:*/
925       /*case D3DFMT_A1R5G5B5: */
926       /*case D3DFMT_A4R4G4B4:*/
927
928     /*****
929      * unsupported 
930      */
931
932       /* color buffer */
933       /*case D3DFMT_X8R8G8B8:*/
934     case D3DFMT_A8R3G3B2:
935
936       /* Paletted */
937     case D3DFMT_P8:
938     case D3DFMT_A8P8:
939
940       /* Luminance */
941     case D3DFMT_L8:
942     case D3DFMT_A8L8:
943     case D3DFMT_A4L4:
944
945       /* Bump */
946 #if 0
947     case D3DFMT_V8U8:
948     case D3DFMT_V16U16:
949 #endif
950     case D3DFMT_L6V5U5:
951     case D3DFMT_X8L8V8U8:
952     case D3DFMT_Q8W8V8U8:
953     case D3DFMT_W11V11U10:
954
955     /****
956      * currently hard to support 
957      */
958     case D3DFMT_UYVY:
959     case D3DFMT_YUY2:
960
961       /* Since we do not support these formats right now, don't pretend to. */
962       TRACE_(d3d_caps)("[FAILED]\n");
963       return D3DERR_NOTAVAILABLE;
964     default:
965       break;
966     }
967
968     TRACE_(d3d_caps)("[OK]\n");
969     return D3D_OK;
970 }
971
972 HRESULT  WINAPI  IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) {
973     IWineD3DImpl *This = (IWineD3DImpl *)iface;
974
975     FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))",
976           This, 
977           Adapter, 
978           DeviceType, debug_d3ddevicetype(DeviceType), 
979           SourceFormat, debug_d3dformat(SourceFormat), 
980           TargetFormat, debug_d3dformat(TargetFormat));
981     return D3D_OK;
982 }
983
984 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true 
985       subset of a D3DCAPS9 structure. However, it has to come via a void * 
986       as the d3d8 interface cannot import the d3d9 header                  */
987 HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, D3DDEVTYPE DeviceType, void* pCapsIn) {
988
989     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
990     BOOL             gotContext  = FALSE;
991     GLint            gl_tex_size = 0;    
992     WineD3D_Context *fake_ctx = NULL;
993     D3DCAPS9        *pCaps = (D3DCAPS9 *)pCapsIn;
994
995     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
996
997     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
998         return D3DERR_INVALIDCALL;
999     }
1000
1001     /* Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
1002        ie there is no GL Context - Get a default rendering context to enable the 
1003        function query some info from GL                                           */    
1004     if (glXGetCurrentContext() == NULL) {
1005         fake_ctx = WineD3D_CreateFakeGLContext();
1006         if (NULL != fake_ctx) gotContext = TRUE;
1007     } else {
1008         gotContext = TRUE;
1009     }
1010
1011     if (gotContext == FALSE) {
1012
1013         FIXME_(d3d_caps)("GetDeviceCaps called but no GL Context - Returning dummy values\n");
1014         gl_tex_size=65535;
1015         pCaps->MaxTextureBlendStages = 2;
1016         pCaps->MaxSimultaneousTextures = 2;
1017         pCaps->MaxUserClipPlanes = 8;
1018         pCaps->MaxActiveLights = 8;
1019         pCaps->MaxVertexBlendMatrices = 0;
1020         pCaps->MaxVertexBlendMatrixIndex = 1;
1021         pCaps->MaxAnisotropy = 0;
1022         pCaps->MaxPointSize = 255.0;
1023     } else {
1024         glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_tex_size);
1025     }
1026
1027     /* If we don't know the device settings, go query them now */
1028     if (This->isGLInfoValid == FALSE) {
1029         BOOL rc = IWineD3DImpl_FillGLCaps(&This->gl_info, NULL);
1030
1031         /* If we are running off a real context, save the values */
1032         if ((rc == TRUE) && ((NULL != fake_ctx))) This->isGLInfoValid = TRUE;
1033     }
1034
1035     /* ------------------------------------------------
1036        The following fields apply to both d3d8 and d3d9
1037        ------------------------------------------------ */
1038     pCaps->DeviceType = (DeviceType == D3DDEVTYPE_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
1039     pCaps->AdapterOrdinal = Adapter;
1040
1041     pCaps->Caps = 0;
1042     pCaps->Caps2 = D3DCAPS2_CANRENDERWINDOWED;
1043     pCaps->Caps3 = D3DDEVCAPS_HWTRANSFORMANDLIGHT;
1044     pCaps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE;
1045
1046     pCaps->CursorCaps = 0;
1047
1048     pCaps->DevCaps = D3DDEVCAPS_DRAWPRIMTLVERTEX    | 
1049                      D3DDEVCAPS_HWTRANSFORMANDLIGHT |
1050                      D3DDEVCAPS_PUREDEVICE;
1051
1052     pCaps->PrimitiveMiscCaps = D3DPMISCCAPS_CULLCCW               | 
1053                                D3DPMISCCAPS_CULLCW                | 
1054                                D3DPMISCCAPS_COLORWRITEENABLE      |
1055                                D3DPMISCCAPS_CLIPTLVERTS           |
1056                                D3DPMISCCAPS_CLIPPLANESCALEDPOINTS | 
1057                                D3DPMISCCAPS_MASKZ; 
1058                                /*NOT: D3DPMISCCAPS_TSSARGTEMP*/
1059
1060     pCaps->RasterCaps = D3DPRASTERCAPS_DITHER   | 
1061                         D3DPRASTERCAPS_PAT      | 
1062                         D3DPRASTERCAPS_WFOG |
1063                         D3DPRASTERCAPS_ZFOG |
1064                         D3DPRASTERCAPS_FOGVERTEX |
1065                         D3DPRASTERCAPS_FOGTABLE  |
1066                         D3DPRASTERCAPS_FOGRANGE;
1067
1068     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
1069       pCaps->RasterCaps |= D3DPRASTERCAPS_ANISOTROPY;
1070     }
1071                         /* FIXME Add:
1072                            D3DPRASTERCAPS_MIPMAPLODBIAS
1073                            D3DPRASTERCAPS_ZBIAS
1074                            D3DPRASTERCAPS_COLORPERSPECTIVE
1075                            D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
1076                            D3DPRASTERCAPS_ANTIALIASEDGES
1077                            D3DPRASTERCAPS_ZBUFFERLESSHSR
1078                            D3DPRASTERCAPS_WBUFFER */
1079
1080     pCaps->ZCmpCaps = D3DPCMPCAPS_ALWAYS       | 
1081                       D3DPCMPCAPS_EQUAL        | 
1082                       D3DPCMPCAPS_GREATER      | 
1083                       D3DPCMPCAPS_GREATEREQUAL |
1084                       D3DPCMPCAPS_LESS         | 
1085                       D3DPCMPCAPS_LESSEQUAL    | 
1086                       D3DPCMPCAPS_NEVER        |
1087                       D3DPCMPCAPS_NOTEQUAL;
1088
1089     pCaps->SrcBlendCaps  = 0xFFFFFFFF;   /*FIXME: Tidy up later */
1090     pCaps->DestBlendCaps = 0xFFFFFFFF;   /*FIXME: Tidy up later */
1091     pCaps->AlphaCmpCaps  = 0xFFFFFFFF;   /*FIXME: Tidy up later */
1092
1093     pCaps->ShadeCaps = D3DPSHADECAPS_SPECULARGOURAUDRGB | 
1094                        D3DPSHADECAPS_COLORGOURAUDRGB;
1095
1096     pCaps->TextureCaps =  D3DPTEXTURECAPS_ALPHA        | 
1097                           D3DPTEXTURECAPS_ALPHAPALETTE | 
1098                           D3DPTEXTURECAPS_POW2         | 
1099                           D3DPTEXTURECAPS_VOLUMEMAP    | 
1100                           D3DPTEXTURECAPS_MIPMAP       |
1101                           D3DPTEXTURECAPS_PROJECTED;
1102
1103     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1104       pCaps->TextureCaps |= D3DPTEXTURECAPS_CUBEMAP      | 
1105                             D3DPTEXTURECAPS_MIPCUBEMAP   | 
1106                             D3DPTEXTURECAPS_CUBEMAP_POW2;
1107     }
1108
1109     pCaps->TextureFilterCaps = D3DPTFILTERCAPS_MAGFLINEAR | 
1110                                D3DPTFILTERCAPS_MAGFPOINT  | 
1111                                D3DPTFILTERCAPS_MINFLINEAR | 
1112                                D3DPTFILTERCAPS_MINFPOINT  |
1113                                D3DPTFILTERCAPS_MIPFLINEAR | 
1114                                D3DPTFILTERCAPS_MIPFPOINT;
1115
1116     pCaps->CubeTextureFilterCaps = 0;
1117     pCaps->VolumeTextureFilterCaps = 0;
1118
1119     pCaps->TextureAddressCaps =  D3DPTADDRESSCAPS_BORDER | 
1120                                  D3DPTADDRESSCAPS_CLAMP  | 
1121                                  D3DPTADDRESSCAPS_WRAP;
1122
1123     if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
1124       pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_BORDER;
1125     }
1126     if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
1127       pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRROR;
1128     }
1129     if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
1130       pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
1131     }
1132
1133     pCaps->VolumeTextureAddressCaps = 0;
1134
1135     pCaps->LineCaps = D3DLINECAPS_TEXTURE | 
1136                       D3DLINECAPS_ZTEST;
1137                       /* FIXME: Add 
1138                          D3DLINECAPS_BLEND
1139                          D3DLINECAPS_ALPHACMP
1140                          D3DLINECAPS_FOG */
1141
1142     pCaps->MaxTextureWidth = gl_tex_size;
1143     pCaps->MaxTextureHeight = gl_tex_size;
1144
1145     pCaps->MaxVolumeExtent = 0;
1146
1147     pCaps->MaxTextureRepeat = 32768;
1148     pCaps->MaxTextureAspectRatio = 32768;
1149     pCaps->MaxVertexW = 1.0;
1150
1151     pCaps->GuardBandLeft = 0;
1152     pCaps->GuardBandTop = 0;
1153     pCaps->GuardBandRight = 0;
1154     pCaps->GuardBandBottom = 0;
1155
1156     pCaps->ExtentsAdjust = 0;
1157
1158     pCaps->StencilCaps =  D3DSTENCILCAPS_DECRSAT | 
1159                           D3DSTENCILCAPS_INCRSAT | 
1160                           D3DSTENCILCAPS_INVERT  | 
1161                           D3DSTENCILCAPS_KEEP    | 
1162                           D3DSTENCILCAPS_REPLACE | 
1163                           D3DSTENCILCAPS_ZERO;
1164     if (GL_SUPPORT(EXT_STENCIL_WRAP)) {
1165       pCaps->StencilCaps |= D3DSTENCILCAPS_DECR    | 
1166                             D3DSTENCILCAPS_INCR;
1167     }
1168
1169     pCaps->FVFCaps = D3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
1170
1171     pCaps->TextureOpCaps =  D3DTEXOPCAPS_ADD         | 
1172                             D3DTEXOPCAPS_ADDSIGNED   | 
1173                             D3DTEXOPCAPS_ADDSIGNED2X |
1174                             D3DTEXOPCAPS_MODULATE    | 
1175                             D3DTEXOPCAPS_MODULATE2X  | 
1176                             D3DTEXOPCAPS_MODULATE4X  |
1177                             D3DTEXOPCAPS_SELECTARG1  | 
1178                             D3DTEXOPCAPS_SELECTARG2  | 
1179                             D3DTEXOPCAPS_DISABLE;
1180 #if defined(GL_VERSION_1_3)
1181     pCaps->TextureOpCaps |= D3DTEXOPCAPS_DOTPRODUCT3 | 
1182                             D3DTEXOPCAPS_SUBTRACT;
1183 #endif
1184     if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) || 
1185         GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) || 
1186         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1187       pCaps->TextureOpCaps |= D3DTEXOPCAPS_BLENDDIFFUSEALPHA |
1188                               D3DTEXOPCAPS_BLENDTEXTUREALPHA | 
1189                               D3DTEXOPCAPS_BLENDFACTORALPHA  |
1190                               D3DTEXOPCAPS_BLENDCURRENTALPHA |
1191                               D3DTEXOPCAPS_LERP;
1192     }
1193     if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1194       pCaps->TextureOpCaps |= D3DTEXOPCAPS_ADDSMOOTH | 
1195                               D3DTEXOPCAPS_MULTIPLYADD |
1196                               D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
1197                               D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
1198                               D3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
1199     }
1200     
1201 #if 0
1202     pCaps->TextureOpCaps |= D3DTEXOPCAPS_BUMPENVMAP;
1203                             /* FIXME: Add 
1204                               D3DTEXOPCAPS_BUMPENVMAPLUMINANCE 
1205                               D3DTEXOPCAPS_PREMODULATE */
1206 #endif
1207
1208     if (gotContext) {
1209         GLint gl_max;
1210         GLfloat gl_float;
1211 #if defined(GL_VERSION_1_3)
1212         glGetIntegerv(GL_MAX_TEXTURE_UNITS, &gl_max);
1213 #else
1214         glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
1215 #endif
1216         TRACE_(d3d_caps)("GLCaps: GL_MAX_TEXTURE_UNITS_ARB=%d\n", gl_max);
1217         pCaps->MaxTextureBlendStages = min(8, gl_max);
1218         pCaps->MaxSimultaneousTextures = min(8, gl_max);
1219
1220         glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
1221         pCaps->MaxUserClipPlanes = min(D3DMAXUSERCLIPPLANES, gl_max);
1222         TRACE_(d3d_caps)("GLCaps: GL_MAX_CLIP_PLANES=%ld\n", pCaps->MaxUserClipPlanes);
1223
1224         glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
1225         pCaps->MaxActiveLights = gl_max;
1226         TRACE_(d3d_caps)("GLCaps: GL_MAX_LIGHTS=%ld\n", pCaps->MaxActiveLights);
1227
1228         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
1229            glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
1230            pCaps->MaxVertexBlendMatrices = gl_max;
1231            pCaps->MaxVertexBlendMatrixIndex = 1;
1232         } else {
1233            pCaps->MaxVertexBlendMatrices = 0;
1234            pCaps->MaxVertexBlendMatrixIndex = 1;
1235         }
1236
1237         if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
1238           glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
1239           pCaps->MaxAnisotropy = gl_max;
1240         } else {
1241           pCaps->MaxAnisotropy = 0;
1242         }
1243
1244         glGetFloatv(GL_POINT_SIZE_RANGE, &gl_float);
1245         pCaps->MaxPointSize = gl_float;
1246     }
1247
1248     pCaps->VertexProcessingCaps = D3DVTXPCAPS_DIRECTIONALLIGHTS | 
1249                                   D3DVTXPCAPS_MATERIALSOURCE7   | 
1250                                   D3DVTXPCAPS_POSITIONALLIGHTS  | 
1251                                   D3DVTXPCAPS_LOCALVIEWER |
1252                                   D3DVTXPCAPS_TEXGEN;
1253                                   /* FIXME: Add 
1254                                      D3DVTXPCAPS_TWEENING */
1255
1256     pCaps->MaxPrimitiveCount = 0xFFFFFFFF;
1257     pCaps->MaxVertexIndex = 0xFFFFFFFF;
1258     pCaps->MaxStreams = MAX_STREAMS;
1259     pCaps->MaxStreamStride = 1024;
1260
1261     if (((vs_mode == VS_HW) && GL_SUPPORT(ARB_VERTEX_PROGRAM)) || (vs_mode == VS_SW) || (DeviceType == D3DDEVTYPE_REF)) {
1262       pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
1263       
1264       if (This->gl_info.gl_vendor == VENDOR_MESA || 
1265           This->gl_info.gl_vendor == VENDOR_WINE) {
1266         pCaps->MaxVertexShaderConst = 95;
1267       } else {
1268         pCaps->MaxVertexShaderConst = WINED3D_VSHADER_MAX_CONSTANTS;
1269       }
1270     } else {
1271       pCaps->VertexShaderVersion = 0;
1272       pCaps->MaxVertexShaderConst = 0;
1273     }
1274
1275     if ((ps_mode == PS_HW) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM) && (DeviceType != D3DDEVTYPE_REF)) {
1276         pCaps->PixelShaderVersion = D3DPS_VERSION(1,4);
1277         pCaps->MaxPixelShaderValue = 1.0;
1278     } else {
1279         pCaps->PixelShaderVersion = 0;
1280         pCaps->MaxPixelShaderValue = 0.0;
1281     }
1282
1283     /* ------------------------------------------------
1284        The following fields apply to d3d9 only
1285        ------------------------------------------------ */
1286     if (This->dxVersion > 8) {
1287         FIXME("Caps support for directx9 is non-existent at the moment!\n");
1288         pCaps->DevCaps2 = 0;
1289         pCaps->MaxNpatchTessellationLevel = 0;
1290         pCaps->MasterAdapterOrdinal = 0;
1291         pCaps->AdapterOrdinalInGroup = 0;
1292         pCaps->NumberOfAdaptersInGroup = 1;
1293         pCaps->DeclTypes = 0;
1294         pCaps->NumSimultaneousRTs = 0;
1295         pCaps->StretchRectFilterCaps = 0;
1296         pCaps->VS20Caps.Caps = 0;
1297         pCaps->PS20Caps.Caps = 0;
1298         pCaps->VertexTextureFilterCaps = 0;
1299         pCaps->MaxVShaderInstructionsExecuted = 0;
1300         pCaps->MaxPShaderInstructionsExecuted = 0;
1301         pCaps->MaxVertexShader30InstructionSlots = 0;
1302         pCaps->MaxPixelShader30InstructionSlots = 0;
1303     }
1304
1305     /* If we created a dummy context, throw it away */
1306     if (NULL != fake_ctx) WineD3D_ReleaseFakeGLContext(fake_ctx);
1307     return D3D_OK;
1308 }
1309
1310 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
1311    and fields being inserted in the middle, a new structure is used in place    */
1312 HRESULT  WINAPI  IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
1313                                            DWORD BehaviourFlags, WINED3DPRESENT_PARAMETERS* pPresentationParameters,
1314                                            IWineD3DDevice** ppReturnedDeviceInterface, IUnknown *parent) {
1315
1316     HWND                whichHWND;
1317     HDC                 hDc;
1318     IWineD3DDeviceImpl *object  = NULL;
1319     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
1320     int                 num;
1321     XVisualInfo         template;
1322
1323     /* Validate the adapter number */
1324     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1325         return D3DERR_INVALIDCALL;
1326     }
1327
1328     /* Create a WineD3DDevice object */
1329     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DDeviceImpl));
1330     *ppReturnedDeviceInterface = (IWineD3DDevice *)object;
1331     TRACE("Created WineD3DDevice object @ %p \n", object);
1332     if (NULL == object) {
1333       return D3DERR_OUTOFVIDEOMEMORY;
1334     }
1335
1336     /* Set up initial COM information */
1337     object->lpVtbl  = &IWineD3DDevice_Vtbl;
1338     object->ref     = 1;
1339     object->wineD3D = iface;
1340     IWineD3D_AddRef(object->wineD3D);
1341     object->parent  = parent;
1342     
1343     TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %lx, PresParms: %p, RetDevInt: %p)\n", This, Adapter, DeviceType,
1344           hFocusWindow, BehaviourFlags, pPresentationParameters, ppReturnedDeviceInterface);
1345     TRACE("(%p)->(DepthStencil:(%u,%s), BackBufferFormat:(%u,%s))\n", This, 
1346           *(pPresentationParameters->AutoDepthStencilFormat), debug_d3dformat(*(pPresentationParameters->AutoDepthStencilFormat)),
1347           *(pPresentationParameters->BackBufferFormat), debug_d3dformat(*(pPresentationParameters->BackBufferFormat)));
1348
1349     /* Save the creation parameters */
1350     object->createParms.AdapterOrdinal = Adapter;
1351     object->createParms.DeviceType     = DeviceType;
1352     object->createParms.hFocusWindow   = hFocusWindow;
1353     object->createParms.BehaviorFlags  = BehaviourFlags;
1354
1355     /* Initialize other useful values */
1356     object->presentParms.BackBufferCount = 1; /* Opengl only supports one? */
1357     object->adapterNo                    = Adapter;
1358     object->devType                      = DeviceType;
1359
1360     /* Setup hwnd we are using, plus which display this equates to */
1361     whichHWND = *(pPresentationParameters->hDeviceWindow);
1362     if (!whichHWND) {
1363         whichHWND = hFocusWindow;
1364     }
1365     object->win_handle = whichHWND;
1366     object->win        = (Window)GetPropA( whichHWND, "__wine_x11_client_window" );
1367     hDc                = GetDC(whichHWND);
1368     object->display    = get_display(hDc);
1369     ReleaseDC(whichHWND, hDc);
1370
1371     /* FIXME: Use for dx8 code eventually too! */
1372     /* Deliberately no indentation here, as this if will be removed when dx8 support merged in */
1373     if (This->dxVersion > 8) {   
1374
1375     /* Create a context based off the properties of the existing visual */
1376     /*   Note the visual is chosen as the window is created and the glcontext cannot
1377          use different properties after that point in time. FIXME: How to handle when requested format 
1378          doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
1379          it chooses is identical to the one already being used!                                        */
1380     /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */
1381     ENTER_GL();
1382     template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
1383     object->visInfo   = XGetVisualInfo(object->display, VisualIDMask, &template, &num);
1384     if (NULL == object->visInfo) {
1385         ERR("cannot really get XVisual\n"); 
1386         LEAVE_GL();
1387         return D3DERR_NOTAVAILABLE;
1388     }
1389     object->glCtx = glXCreateContext(object->display, object->visInfo, NULL, GL_TRUE);
1390     if (NULL == object->glCtx) {
1391         ERR("cannot create glxContext\n"); 
1392         LEAVE_GL();
1393         return D3DERR_NOTAVAILABLE;
1394     }
1395     LEAVE_GL();
1396
1397     if (object->glCtx == NULL) {
1398         ERR("Error in context creation !\n");
1399         return D3DERR_INVALIDCALL;
1400     } else {
1401         TRACE("Context created (HWND=%p, glContext=%p, Window=%ld, VisInfo=%p)\n",
1402                 whichHWND, object->glCtx, object->win, object->visInfo);
1403     }
1404
1405     /* If not windowed, need to go fullscreen, and resize the HWND to the appropriate  */
1406     /*        dimensions                                                               */
1407     if (!*(pPresentationParameters->Windowed)) {
1408
1409         DEVMODEW devmode;
1410         HDC      hdc;
1411         int      bpp = 0;
1412
1413         /* Get info on the current display setup */
1414         hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
1415         bpp = GetDeviceCaps(hdc, BITSPIXEL);
1416         DeleteDC(hdc);
1417
1418         /* Change the display settings */
1419         memset(&devmode, 0, sizeof(DEVMODEW));
1420         devmode.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 
1421         devmode.dmBitsPerPel = (bpp >= 24) ? 32 : bpp;   /*Stupid XVidMode cannot change bpp D3DFmtGetBpp(object, pPresentationParameters->BackBufferFormat);*/
1422         devmode.dmPelsWidth  = *(pPresentationParameters->BackBufferWidth);
1423         devmode.dmPelsHeight = *(pPresentationParameters->BackBufferHeight);
1424         MultiByteToWideChar(CP_ACP, 0, "Gamers CG", -1, devmode.dmDeviceName, CCHDEVICENAME);
1425         ChangeDisplaySettingsExW(devmode.dmDeviceName, &devmode, object->win_handle, CDS_FULLSCREEN, NULL);
1426
1427         /* Make popup window */
1428         SetWindowLongA(whichHWND, GWL_STYLE, WS_POPUP);
1429         SetWindowPos(object->win_handle, HWND_TOP, 0, 0, 
1430                      *(pPresentationParameters->BackBufferWidth),
1431                      *(pPresentationParameters->BackBufferHeight), SWP_SHOWWINDOW | SWP_FRAMECHANGED);
1432     }
1433
1434     /* MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
1435        then the corresponding dimension of the client area of the hDeviceWindow
1436        (or the focus window, if hDeviceWindow is NULL) is taken. */
1437     if (*(pPresentationParameters->Windowed) && 
1438         ((*(pPresentationParameters->BackBufferWidth)  == 0) ||
1439          (*(pPresentationParameters->BackBufferHeight) == 0))) {
1440
1441         RECT Rect;
1442         GetClientRect(whichHWND, &Rect);
1443
1444         if (*(pPresentationParameters->BackBufferWidth) == 0) {
1445            *(pPresentationParameters->BackBufferWidth) = Rect.right;
1446            TRACE("Updating width to %d\n", *(pPresentationParameters->BackBufferWidth));
1447         }
1448         if (*(pPresentationParameters->BackBufferHeight) == 0) {
1449            *(pPresentationParameters->BackBufferHeight) = Rect.bottom;
1450            TRACE("Updating height to %d\n", *(pPresentationParameters->BackBufferHeight));
1451         }
1452     }
1453
1454     /* Save the presentation parms now filled in correctly */
1455     object->presentParms.BackBufferWidth                = *(pPresentationParameters->BackBufferWidth);
1456     object->presentParms.BackBufferHeight               = *(pPresentationParameters->BackBufferHeight);           
1457     object->presentParms.BackBufferFormat               = *(pPresentationParameters->BackBufferFormat);           
1458     object->presentParms.BackBufferCount                = *(pPresentationParameters->BackBufferCount);            
1459     object->presentParms.MultiSampleType                = *(pPresentationParameters->MultiSampleType);            
1460     object->presentParms.MultiSampleQuality             = *(pPresentationParameters->MultiSampleQuality);         
1461     object->presentParms.SwapEffect                     = *(pPresentationParameters->SwapEffect);                 
1462     object->presentParms.hDeviceWindow                  = *(pPresentationParameters->hDeviceWindow);              
1463     object->presentParms.Windowed                       = *(pPresentationParameters->Windowed);                   
1464     object->presentParms.EnableAutoDepthStencil         = *(pPresentationParameters->EnableAutoDepthStencil);     
1465     object->presentParms.AutoDepthStencilFormat         = *(pPresentationParameters->AutoDepthStencilFormat);     
1466     object->presentParms.Flags                          = *(pPresentationParameters->Flags);                      
1467     object->presentParms.FullScreen_RefreshRateInHz     = *(pPresentationParameters->FullScreen_RefreshRateInHz); 
1468     object->presentParms.PresentationInterval           = *(pPresentationParameters->PresentationInterval);       
1469
1470     /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
1471     IWineD3DDevice_CreateStateBlock((IWineD3DDevice *)object, 
1472                                     (D3DSTATEBLOCKTYPE) 0, 
1473                                     (IWineD3DStateBlock **)&object->stateBlock,
1474                                     NULL);   /* Note: No parent needed for initial internal stateblock */
1475     object->updateStateBlock = object->stateBlock;
1476
1477     /* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */
1478     TRACE("Creating initial device surfaces\n");
1479
1480 /* TODO:
1481     IWineD3DDevice_CreateRenderTarget((IWineD3DDevice *) object,
1482                                       *(pPresentationParameters->BackBufferWidth),
1483                                       *(pPresentationParameters->BackBufferHeight),
1484                                       *(pPresentationParameters->BackBufferFormat),
1485                                       *(pPresentationParameters->MultiSampleType),
1486                                       TRUE,
1487                                       (IWineD3DSurface *) &object->frontBuffer);
1488
1489     IWineD3DDevice_CreateRenderTarget((IWineD3DDevice *) object,
1490                                       *(pPresentationParameters->BackBufferWidth),
1491                                       *(pPresentationParameters->BackBufferHeight),
1492                                       *(pPresentationParameters->BackBufferFormat),
1493                                       *(pPresentationParameters->MultiSampleType),
1494                                       TRUE,
1495                                       (IWineD3DSurface *) &object->backBuffer);
1496
1497     if (*(pPresentationParameters->EnableAutoDepthStencil)) {
1498        IWineD3DDevice_CreateDepthStencilSurface((IWineD3DDevice *) object,
1499                                                 *(pPresentationParameters->BackBufferWidth),
1500                                                 *(pPresentationParameters->BackBufferHeight),
1501                                                 *(pPresentationParameters->AutoDepthStencilFormat,
1502                                                 D3DMULTISAMPLE_NONE,
1503                                                 (IWineD3DSurface *) &object->depthStencilBuffer);
1504     } else {
1505       object->depthStencilBuffer = NULL;
1506     }
1507     TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil @ %p\n",object->frontBuffer, object->backBuffer, object->depthStencilBuffer);
1508 */    
1509
1510     /* init the default renderTarget management */
1511     object->drawable     = object->win;
1512     object->render_ctx   = object->glCtx;
1513 /* TODO:
1514     object->renderTarget = object->backBuffer;
1515     
1516     IWineD3DSurface_AddRef((IWineD3DSurface *) object->renderTarget);
1517     object->stencilBufferTarget = object->depthStencilBuffer;
1518     if (NULL != object->stencilBufferTarget) {
1519       IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->stencilBufferTarget);
1520     }
1521 */    
1522
1523     /* Set up some starting GL setup */
1524     ENTER_GL();
1525
1526     if (glXMakeCurrent(object->display, object->win, object->glCtx) == False) {
1527       ERR("Error in setting current context (context %p drawable %ld)!\n", object->glCtx, object->win);
1528     }
1529     checkGLcall("glXMakeCurrent");
1530
1531     /* Clear the screen */
1532     glClearColor(1.0, 0.0, 0.0, 0.0);
1533     checkGLcall("glClearColor");
1534     glColor3f(1.0, 1.0, 1.0);
1535     checkGLcall("glColor3f");
1536
1537     glEnable(GL_LIGHTING);
1538     checkGLcall("glEnable");
1539
1540     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1541     checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
1542
1543     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
1544     checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
1545
1546     glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1547     checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
1548
1549     /* 
1550      * Initialize openGL extension related variables
1551      *  with Default values 
1552      */
1553     This->isGLInfoValid = IWineD3DImpl_FillGLCaps(&This->gl_info, object->display);
1554
1555     /* Setup all the devices defaults */
1556     IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)object->stateBlock); 
1557
1558     LEAVE_GL();
1559
1560     { /* Set a default viewport */
1561        D3DVIEWPORT9 vp;
1562        vp.X      = 0;
1563        vp.Y      = 0;
1564        vp.Width  = *(pPresentationParameters->BackBufferWidth);
1565        vp.Height = *(pPresentationParameters->BackBufferHeight);
1566        vp.MinZ   = 0.0f;
1567        vp.MaxZ   = 1.0f;
1568        /* TODO: IWineD3DDevice_SetViewport((LPDIRECT3DDEVICE9) object, &vp); */
1569     }
1570
1571     /* Initialize the current view state */
1572     object->modelview_valid = 1;
1573     object->proj_valid = 0;
1574     object->view_ident = 1;
1575     object->last_was_rhw = 0;
1576     glGetIntegerv(GL_MAX_LIGHTS, &object->maxConcurrentLights);
1577     TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This, Adapter, object);
1578
1579     /* Clear the screen */
1580     /* TODO: IDirect3DDevice8Impl_Clear((LPDIRECT3DDEVICE8) object, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0); */
1581
1582     } /* End of FIXME: remove when dx8 merged in */
1583
1584     return D3D_OK;
1585 }
1586
1587 HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
1588     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1589     IUnknown_AddRef(This->parent);
1590     *pParent = This->parent;
1591     return D3D_OK;
1592 }
1593
1594 /**********************************************************
1595  * IUnknown parts follows
1596  **********************************************************/
1597
1598 HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
1599 {
1600     return E_NOINTERFACE;
1601 }
1602
1603 ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) {
1604     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1605     TRACE("(%p) : AddRef increasing from %ld\n", This, This->ref);
1606     return InterlockedIncrement(&This->ref);
1607 }
1608
1609 ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
1610     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1611     ULONG ref;
1612     TRACE("(%p) : Releasing from %ld\n", This, This->ref);
1613     ref = InterlockedDecrement(&This->ref);
1614     if (ref == 0) HeapFree(GetProcessHeap(), 0, This);
1615     return ref;
1616 }
1617
1618 /**********************************************************
1619  * IWineD3D VTbl follows
1620  **********************************************************/
1621
1622 IWineD3DVtbl IWineD3D_Vtbl =
1623 {
1624     IWineD3DImpl_QueryInterface,
1625     IWineD3DImpl_AddRef,
1626     IWineD3DImpl_Release,
1627     IWineD3DImpl_GetParent,
1628     IWineD3DImpl_GetAdapterCount,
1629     IWineD3DImpl_RegisterSoftwareDevice,
1630     IWineD3DImpl_GetAdapterMonitor,
1631     IWineD3DImpl_GetAdapterModeCount,
1632     IWineD3DImpl_EnumAdapterModes,
1633     IWineD3DImpl_GetAdapterDisplayMode,
1634     IWineD3DImpl_GetAdapterIdentifier,
1635     IWineD3DImpl_CheckDeviceMultiSampleType,
1636     IWineD3DImpl_CheckDepthStencilMatch,
1637     IWineD3DImpl_CheckDeviceType,
1638     IWineD3DImpl_CheckDeviceFormat,
1639     IWineD3DImpl_CheckDeviceFormatConversion,
1640     IWineD3DImpl_GetDeviceCaps,
1641     IWineD3DImpl_CreateDevice
1642 };