Only create an X window for top-level windows, not for child windows.
[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             } else if (strcmp(ThisExtn, "GL_ARB_vertex_blend") == 0) {
367                 TRACE_(d3d_caps)(" FOUND: ARB Vertex Blend support\n");
368                 gl_info->supported[ARB_VERTEX_BLEND] = TRUE;
369             } else if (strcmp(ThisExtn, "GL_ARB_vertex_buffer_object") == 0) {
370                 TRACE_(d3d_caps)(" FOUND: ARB Vertex Buffer support\n");
371                 gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] = TRUE;
372
373             /**
374              * EXT
375              */
376             } else if (strcmp(ThisExtn, "GL_EXT_fog_coord") == 0) {
377                 TRACE_(d3d_caps)(" FOUND: EXT Fog coord support\n");
378                 gl_info->supported[EXT_FOG_COORD] = TRUE;
379             } else if (strcmp(ThisExtn, "GL_EXT_paletted_texture") == 0) { /* handle paletted texture extensions */
380                 TRACE_(d3d_caps)(" FOUND: EXT Paletted texture support\n");
381                 gl_info->supported[EXT_PALETTED_TEXTURE] = TRUE;
382             } else if (strcmp(ThisExtn, "GL_EXT_point_parameters") == 0) {
383                 TRACE_(d3d_caps)(" FOUND: EXT Point parameters support\n");
384                 gl_info->supported[EXT_POINT_PARAMETERS] = TRUE;
385             } else if (strcmp(ThisExtn, "GL_EXT_secondary_color") == 0) {
386                 TRACE_(d3d_caps)(" FOUND: EXT Secondary coord support\n");
387                 gl_info->supported[EXT_SECONDARY_COLOR] = TRUE;
388             } else if (strcmp(ThisExtn, "GL_EXT_stencil_wrap") == 0) {
389                 TRACE_(d3d_caps)(" FOUND: EXT Stencil wrap support\n");
390                 gl_info->supported[EXT_STENCIL_WRAP] = TRUE;
391             } else if (strcmp(ThisExtn, "GL_EXT_texture_compression_s3tc") == 0) {
392                 TRACE_(d3d_caps)(" FOUND: EXT Texture S3TC compression support\n");
393                 gl_info->supported[EXT_TEXTURE_COMPRESSION_S3TC] = TRUE;
394             } else if (strcmp(ThisExtn, "GL_EXT_texture_env_add") == 0) {
395                 TRACE_(d3d_caps)(" FOUND: EXT Texture Env Add support\n");
396                 gl_info->supported[EXT_TEXTURE_ENV_ADD] = TRUE;
397             } else if (strcmp(ThisExtn, "GL_EXT_texture_env_combine") == 0) {
398                 TRACE_(d3d_caps)(" FOUND: EXT Texture Env combine support\n");
399                 gl_info->supported[EXT_TEXTURE_ENV_COMBINE] = TRUE;
400             } else if (strcmp(ThisExtn, "GL_EXT_texture_env_dot3") == 0) {
401                 TRACE_(d3d_caps)(" FOUND: EXT Dot3 support\n");
402                 gl_info->supported[EXT_TEXTURE_ENV_DOT3] = TRUE;
403             } else if (strcmp(ThisExtn, "GL_EXT_texture_filter_anisotropic") == 0) {
404                 TRACE_(d3d_caps)(" FOUND: EXT Texture Anisotropic filter support\n");
405                 gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] = TRUE;
406             } else if (strcmp(ThisExtn, "GL_EXT_texture_lod") == 0) {
407                 TRACE_(d3d_caps)(" FOUND: EXT Texture LOD support\n");
408                 gl_info->supported[EXT_TEXTURE_LOD] = TRUE;
409             } else if (strcmp(ThisExtn, "GL_EXT_texture_lod_bias") == 0) {
410                 TRACE_(d3d_caps)(" FOUND: EXT Texture LOD bias support\n");
411                 gl_info->supported[EXT_TEXTURE_LOD_BIAS] = TRUE;
412             } else if (strcmp(ThisExtn, "GL_EXT_vertex_weighting") == 0) {
413                 TRACE_(d3d_caps)(" FOUND: EXT Vertex weighting support\n");
414                 gl_info->supported[EXT_VERTEX_WEIGHTING] = TRUE;
415
416             /**
417              * NVIDIA 
418              */
419             } else if (strstr(ThisExtn, "GL_NV_fog_distance")) {
420                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Fog Distance support\n");
421                 gl_info->supported[NV_FOG_DISTANCE] = TRUE;
422             } else if (strstr(ThisExtn, "GL_NV_fragment_program")) {
423                 gl_info->ps_nv_version = PS_VERSION_11;
424                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", gl_info->ps_nv_version);
425             } else if (strcmp(ThisExtn, "GL_NV_register_combiners") == 0) {
426                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Register combiners (1) support\n");
427                 gl_info->supported[NV_REGISTER_COMBINERS] = TRUE;
428             } else if (strcmp(ThisExtn, "GL_NV_register_combiners2") == 0) {
429                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Register combiners (2) support\n");
430                 gl_info->supported[NV_REGISTER_COMBINERS2] = TRUE;
431             } else if (strcmp(ThisExtn, "GL_NV_texgen_reflection") == 0) {
432                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Gen Reflection support\n");
433                 gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
434             } else if (strcmp(ThisExtn, "GL_NV_texture_env_combine4") == 0) {
435                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Env combine (4) support\n");
436                 gl_info->supported[NV_TEXTURE_ENV_COMBINE4] = TRUE;
437             } else if (strcmp(ThisExtn, "GL_NV_texture_shader") == 0) {
438                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Shader (1) support\n");
439                 gl_info->supported[NV_TEXTURE_SHADER] = TRUE;
440             } else if (strcmp(ThisExtn, "GL_NV_texture_shader2") == 0) {
441                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Shader (2) support\n");
442                 gl_info->supported[NV_TEXTURE_SHADER2] = TRUE;
443             } else if (strcmp(ThisExtn, "GL_NV_texture_shader3") == 0) {
444                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Texture Shader (3) support\n");
445                 gl_info->supported[NV_TEXTURE_SHADER3] = TRUE;
446             } else if (strstr(ThisExtn, "GL_NV_vertex_program")) {
447                 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);
448                 gl_info->vs_nv_version = max(gl_info->vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program2"))   ? VS_VERSION_20 : VS_VERSION_10);
449                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", gl_info->vs_nv_version);
450                 gl_info->supported[NV_VERTEX_PROGRAM] = TRUE;
451
452             /**
453              * ATI
454              */
455             /** TODO */
456             } else if (strcmp(ThisExtn, "GL_ATI_texture_env_combine3") == 0) {
457                 TRACE_(d3d_caps)(" FOUND: ATI Texture Env combine (3) support\n");
458                 gl_info->supported[ATI_TEXTURE_ENV_COMBINE3] = TRUE;
459             } else if (strcmp(ThisExtn, "GL_ATI_texture_mirror_once") == 0) {
460                 TRACE_(d3d_caps)(" FOUND: ATI Texture Mirror Once support\n");
461                 gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] = TRUE;
462             } else if (strcmp(ThisExtn, "GL_EXT_vertex_shader") == 0) {
463                 gl_info->vs_ati_version = VS_VERSION_11;
464                 TRACE_(d3d_caps)(" FOUND: ATI (EXT) Vertex Shader support - version=%02x\n", gl_info->vs_ati_version);
465                 gl_info->supported[EXT_VERTEX_SHADER] = TRUE;
466             }
467
468
469             if (*GL_Extensions == ' ') GL_Extensions++;
470         }
471     }
472
473 #define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) glXGetProcAddressARB(#pfn);
474     GL_EXT_FUNCS_GEN;
475 #undef USE_GL_FUNC
476
477     if (display != NULL) {
478         GLX_Extensions = glXQueryExtensionsString(display, DefaultScreen(display));
479         TRACE_(d3d_caps)("GLX_Extensions reported:\n");  
480     
481         if (NULL == GLX_Extensions) {
482             ERR("   GLX_Extensions returns NULL\n");      
483         } else {
484             while (*GLX_Extensions != 0x00) {
485                 const char *Start = GLX_Extensions;
486                 char ThisExtn[256];
487            
488                 memset(ThisExtn, 0x00, sizeof(ThisExtn));
489                 while (*GLX_Extensions != ' ' && *GLX_Extensions != 0x00) {
490                     GLX_Extensions++;
491                 }
492                 memcpy(ThisExtn, Start, (GLX_Extensions - Start));
493                 TRACE_(d3d_caps)("- %s\n", ThisExtn);
494                 if (*GLX_Extensions == ' ') GLX_Extensions++;
495             }
496         }
497     }
498
499 #define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) glXGetProcAddressARB(#pfn);
500     GLX_EXT_FUNCS_GEN;
501 #undef USE_GL_FUNC
502
503     /* Only save the values obtained when a display is provided */
504     if (display != NULL) {
505         return TRUE;
506     } else {
507         return FALSE;
508     }
509 }
510
511 /**********************************************************
512  * IWineD3D implementation follows
513  **********************************************************/
514
515 UINT     WINAPI  IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
516     IWineD3DImpl *This = (IWineD3DImpl *)iface;
517
518     /* FIXME: Set to one for now to imply the display */
519     TRACE_(d3d_caps)("(%p): Mostly stub, only returns primary display\n", This);
520     return 1;
521 }
522
523 HRESULT  WINAPI  IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void* pInitializeFunction) {
524     IWineD3DImpl *This = (IWineD3DImpl *)iface;
525     FIXME("(%p)->(%p): stub\n", This, pInitializeFunction);
526     return D3D_OK;
527 }
528
529 HMONITOR WINAPI  IWineD3DImpl_GetAdapterMonitor(IWineD3D *iface, UINT Adapter) {
530     IWineD3DImpl *This = (IWineD3DImpl *)iface;
531     FIXME_(d3d_caps)("(%p)->(Adptr:%d)\n", This, Adapter);
532     if (Adapter >= IWineD3DImpl_GetAdapterCount(iface)) {
533         return NULL;
534     }
535     return D3D_OK;
536 }
537
538 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes 
539      of the same bpp but different resolutions                                  */
540
541 /* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
542 UINT     WINAPI  IWineD3DImpl_GetAdapterModeCount(IWineD3D *iface, UINT Adapter, D3DFORMAT Format) {
543     IWineD3DImpl *This = (IWineD3DImpl *)iface;
544     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Format: %s)\n", This, Adapter, debug_d3dformat(Format));
545
546     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
547         return 0;
548     }
549
550     if (Adapter == 0) { /* Display */
551         int i = 0;
552         int j = 0;
553 #if !defined( DEBUG_SINGLE_MODE )
554         DEVMODEW DevModeW;
555
556         /* Work out the current screen bpp */
557         HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
558         int bpp = GetDeviceCaps(hdc, BITSPIXEL);
559         DeleteDC(hdc);
560
561         while (EnumDisplaySettingsExW(NULL, j, &DevModeW, 0)) {
562             j++;
563             switch (Format)
564             {
565             case D3DFMT_UNKNOWN: 
566                    i++; 
567                    break;
568             case D3DFMT_X8R8G8B8:   
569             case D3DFMT_A8R8G8B8:    
570                    if (min(DevModeW.dmBitsPerPel, bpp) == 32) i++; 
571                    if (min(DevModeW.dmBitsPerPel, bpp) == 24) i++; 
572                    break;
573             case D3DFMT_X1R5G5B5:
574             case D3DFMT_A1R5G5B5:
575             case D3DFMT_R5G6B5:
576                    if (min(DevModeW.dmBitsPerPel, bpp) == 16) i++; 
577                    break;
578             default:
579                    /* Skip other modes as they do not match requested format */
580                    break;
581             }
582         }
583 #else
584         i = 1;
585         j = 1;
586 #endif
587         TRACE_(d3d_caps)("(%p}->(Adapter: %d) => %d (out of %d)\n", This, Adapter, i, j);
588         return i;
589     } else {
590         FIXME_(d3d_caps)("Adapter not primary display\n");
591     }
592     return 0;
593 }
594
595 /* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
596 HRESULT WINAPI IWineD3DImpl_EnumAdapterModes(IWineD3D *iface, UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) {
597     IWineD3DImpl *This = (IWineD3DImpl *)iface;
598     TRACE_(d3d_caps)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This, Adapter, Mode, pMode, debug_d3dformat(Format));
599
600     /* Validate the parameters as much as possible */
601     if (NULL == pMode || 
602         Adapter >= IWineD3DImpl_GetAdapterCount(iface) ||
603         Mode    >= IWineD3DImpl_GetAdapterModeCount(iface, Adapter, Format)) {
604         return D3DERR_INVALIDCALL;
605     }
606
607     if (Adapter == 0) { /* Display */
608 #if !defined( DEBUG_SINGLE_MODE )
609         DEVMODEW DevModeW;
610         int ModeIdx = 0;
611             
612         /* Work out the current screen bpp */
613         HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
614         int bpp = GetDeviceCaps(hdc, BITSPIXEL);
615         DeleteDC(hdc);
616
617         /* If we are filtering to a specific format, then need to skip all unrelated
618            modes, but if mode is irrelevant, then we can use the index directly      */
619         if (Format == D3DFMT_UNKNOWN) 
620         {
621             ModeIdx = Mode;
622         } else {
623             int i = 0;
624             int j = 0;
625             DEVMODEW DevModeWtmp;
626
627
628             while (i<(Mode+1) && EnumDisplaySettingsExW(NULL, j, &DevModeWtmp, 0)) {
629                 j++;
630                 switch (Format)
631                 {
632                 case D3DFMT_UNKNOWN: 
633                        i++; 
634                        break;
635                 case D3DFMT_X8R8G8B8:   
636                 case D3DFMT_A8R8G8B8:   
637                        if (min(DevModeWtmp.dmBitsPerPel, bpp) == 32) i++; 
638                        if (min(DevModeWtmp.dmBitsPerPel, bpp) == 24) i++; 
639                        break;
640                 case D3DFMT_X1R5G5B5:
641                 case D3DFMT_A1R5G5B5:
642                 case D3DFMT_R5G6B5:
643                        if (min(DevModeWtmp.dmBitsPerPel, bpp) == 16) i++; 
644                        break;
645                 default:
646                        /* Skip other modes as they do not match requested format */
647                        break;
648                 }
649             }
650             ModeIdx = j;
651         }
652
653         /* Now get the display mode via the calculated index */
654         if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0)) 
655         {
656             pMode->Width        = DevModeW.dmPelsWidth;
657             pMode->Height       = DevModeW.dmPelsHeight;
658             bpp                 = min(DevModeW.dmBitsPerPel, bpp);
659             pMode->RefreshRate  = D3DADAPTER_DEFAULT;
660             if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
661             {
662                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
663             }
664
665             if (Format == D3DFMT_UNKNOWN)
666             {
667                 switch (bpp) {
668                 case  8: pMode->Format = D3DFMT_R3G3B2;   break;
669                 case 16: pMode->Format = D3DFMT_R5G6B5;   break;
670                 case 24: /* pMode->Format = D3DFMT_R5G6B5;   break;*/ /* Make 24bit appear as 32 bit */
671                 case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
672                 default: pMode->Format = D3DFMT_UNKNOWN;
673                 }
674             } else {
675                 pMode->Format = Format;
676             }
677         }
678         else
679         {
680             TRACE_(d3d_caps)("Requested mode out of range %d\n", Mode);
681             return D3DERR_INVALIDCALL;
682         }
683
684 #else
685         /* Return one setting of the format requested */
686         if (Mode > 0) return D3DERR_INVALIDCALL;
687         pMode->Width        = 800;
688         pMode->Height       = 600;
689         pMode->RefreshRate  = D3DADAPTER_DEFAULT;
690         pMode->Format       = (Format==D3DFMT_UNKNOWN)?D3DFMT_A8R8G8B8:Format;
691         bpp = 32;
692 #endif
693         TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode->Width, pMode->Height, 
694                  pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format), bpp);
695
696     } else {
697         FIXME_(d3d_caps)("Adapter not primary display\n");
698     }
699
700     return D3D_OK;
701 }
702
703 HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode(IWineD3D *iface, UINT Adapter, D3DDISPLAYMODE* pMode) {
704     IWineD3DImpl *This = (IWineD3DImpl *)iface;
705     TRACE_(d3d_caps)("(%p}->(Adapter: %d, pMode: %p)\n", This, Adapter, pMode);
706
707     if (NULL == pMode || 
708         Adapter >= IWineD3D_GetAdapterCount(iface)) {
709         return D3DERR_INVALIDCALL;
710     }
711
712     if (Adapter == 0) { /* Display */
713         int bpp = 0;
714         DEVMODEW DevModeW;
715
716         EnumDisplaySettingsExW(NULL, (DWORD)-1, &DevModeW, 0);
717         pMode->Width        = DevModeW.dmPelsWidth;
718         pMode->Height       = DevModeW.dmPelsHeight;
719         bpp                 = DevModeW.dmBitsPerPel;
720         pMode->RefreshRate  = D3DADAPTER_DEFAULT;
721         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
722         {
723             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
724         }
725
726         switch (bpp) {
727         case  8: pMode->Format       = D3DFMT_R3G3B2;   break;
728         case 16: pMode->Format       = D3DFMT_R5G6B5;   break;
729         case 24: /*pMode->Format       = D3DFMT_R5G6B5;   break;*/ /* Make 24bit appear as 32 bit */
730         case 32: pMode->Format       = D3DFMT_A8R8G8B8; break;
731         default: pMode->Format       = D3DFMT_UNKNOWN;
732         }
733
734     } else {
735         FIXME_(d3d_caps)("Adapter not primary display\n");
736     }
737
738     TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode->Width,
739           pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
740     return D3D_OK;
741 }
742
743 /* Note due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
744    and fields being inserted in the middle, a new structure is used in place    */
745 HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Adapter, DWORD Flags, 
746                                                    WINED3DADAPTER_IDENTIFIER* pIdentifier) {
747     IWineD3DImpl *This = (IWineD3DImpl *)iface;
748
749     TRACE_(d3d_caps)("(%p}->(Adapter: %d, Flags: %lx, pId=%p)\n", This, Adapter, Flags, pIdentifier);
750
751     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
752         return D3DERR_INVALIDCALL;
753     }
754
755     if (Adapter == 0) { /* Display - only device supported for now */
756         
757         BOOL isGLInfoValid = This->isGLInfoValid;
758
759         /* FillGLCaps updates gl_info, but we only want to store and 
760            reuse the values once we have a context which is valid. Values from
761            a temporary context may differ from the final ones                 */
762         if (isGLInfoValid == FALSE) {
763         
764           /* If we don't know the device settings, go query them now via a 
765              fake context                                                   */
766           WineD3D_Context* ctx = WineD3D_CreateFakeGLContext();
767           if (NULL != ctx) {
768               isGLInfoValid = IWineD3DImpl_FillGLCaps(&This->gl_info, ctx->display);
769               WineD3D_ReleaseFakeGLContext(ctx);
770           }
771         }
772
773         /* If it worked, return the information requested */
774         if (isGLInfoValid) {
775           TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
776           strcpy(pIdentifier->Driver, "Display");
777           strcpy(pIdentifier->Description, "Direct3D HAL");
778
779           /* Note dx8 doesn't supply a DeviceName */
780           if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
781           pIdentifier->DriverVersion->u.HighPart = 0xa;
782           pIdentifier->DriverVersion->u.LowPart = This->gl_info.gl_driver_version;
783           *(pIdentifier->VendorId) = This->gl_info.gl_vendor;
784           *(pIdentifier->DeviceId) = This->gl_info.gl_card;
785           *(pIdentifier->SubSysId) = 0;
786           *(pIdentifier->Revision) = 0;
787
788         } else {
789
790           /* If it failed, return dummy values from an NVidia driver */
791           WARN_(d3d_caps)("Cannot get GLCaps for device/Vendor Name and Version detection using FillGLCaps, currently using NVIDIA identifiers\n");
792           strcpy(pIdentifier->Driver, "Display");
793           strcpy(pIdentifier->Description, "Direct3D HAL");
794           if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
795           pIdentifier->DriverVersion->u.HighPart = 0xa;
796           pIdentifier->DriverVersion->u.LowPart = MAKEDWORD_VERSION(53, 96); /* last Linux Nvidia drivers */
797           *(pIdentifier->VendorId) = VENDOR_NVIDIA;
798           *(pIdentifier->DeviceId) = CARD_NVIDIA_GEFORCE4_TI4600;
799           *(pIdentifier->SubSysId) = 0;
800           *(pIdentifier->Revision) = 0;
801         }
802
803         /*FIXME: memcpy(&pIdentifier->DeviceIdentifier, ??, sizeof(??GUID)); */
804         if (Flags & D3DENUM_NO_WHQL_LEVEL) {
805             *(pIdentifier->WHQLLevel) = 0;
806         } else {
807             *(pIdentifier->WHQLLevel) = 1;
808         }
809
810     } else {
811         FIXME_(d3d_caps)("Adapter not primary display\n");
812     }
813
814     return D3D_OK;
815 }
816
817 HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch(IWineD3D *iface, UINT Adapter, D3DDEVTYPE DeviceType, 
818                 D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) {
819     IWineD3DImpl *This = (IWineD3DImpl *)iface;
820     WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n", 
821            This, Adapter, 
822            DeviceType, debug_d3ddevicetype(DeviceType),
823            AdapterFormat, debug_d3dformat(AdapterFormat),
824            RenderTargetFormat, debug_d3dformat(RenderTargetFormat), 
825            DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
826
827     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
828         return D3DERR_INVALIDCALL;
829     }
830
831     return D3D_OK;
832 }
833
834 HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D *iface,
835                 UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat,
836                 BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) {
837     
838     IWineD3DImpl *This = (IWineD3DImpl *)iface;
839     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n", 
840           This, 
841           Adapter, 
842           DeviceType, debug_d3ddevicetype(DeviceType),
843           SurfaceFormat, debug_d3dformat(SurfaceFormat),
844           Windowed, 
845           MultiSampleType,
846           pQualityLevels);
847   
848     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
849         return D3DERR_INVALIDCALL;
850     }
851
852     if (pQualityLevels != NULL) {
853       static int s_single_shot = 0;
854       if (!s_single_shot) {
855         FIXME("Quality levels unsupported at present\n");
856         s_single_shot = 1;
857       }
858       *pQualityLevels = 1; /* Guess at a value! */
859     }
860
861     if (D3DMULTISAMPLE_NONE == MultiSampleType)
862       return D3D_OK;
863     return D3DERR_NOTAVAILABLE;
864 }
865
866 HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface,
867                 UINT Adapter, D3DDEVTYPE CheckType, D3DFORMAT DisplayFormat,
868                 D3DFORMAT BackBufferFormat, BOOL Windowed) {
869
870     IWineD3DImpl *This = (IWineD3DImpl *)iface;
871     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n", 
872           This, 
873           Adapter, 
874           CheckType, debug_d3ddevicetype(CheckType),
875           DisplayFormat, debug_d3dformat(DisplayFormat),
876           BackBufferFormat, debug_d3dformat(BackBufferFormat),
877           Windowed);
878
879     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
880         return D3DERR_INVALIDCALL;
881     }
882
883     switch (DisplayFormat) {
884       /*case D3DFMT_R5G6B5:*/
885     case D3DFMT_R3G3B2:
886       return D3DERR_NOTAVAILABLE;
887     default:
888       break;
889     }
890     return D3D_OK;
891 }
892
893 HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface,
894                 UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
895                 DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) {
896     IWineD3DImpl *This = (IWineD3DImpl *)iface;
897     TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%lu,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s)) ", 
898           This, 
899           Adapter, 
900           DeviceType, debug_d3ddevicetype(DeviceType), 
901           AdapterFormat, debug_d3dformat(AdapterFormat), 
902           Usage, debug_d3dusage(Usage),
903           RType, debug_d3dresourcetype(RType), 
904           CheckFormat, debug_d3dformat(CheckFormat));
905
906     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
907         return D3DERR_INVALIDCALL;
908     }
909
910     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
911         switch (CheckFormat) {
912         case D3DFMT_DXT1:
913         case D3DFMT_DXT3:
914         case D3DFMT_DXT5:
915           TRACE_(d3d_caps)("[OK]\n");
916           return D3D_OK;
917         default:
918             break; /* Avoid compiler warnings */
919         }
920     }
921
922     switch (CheckFormat) {
923     /*****
924      * check supported using GL_SUPPORT 
925      */
926     case D3DFMT_DXT1:
927     case D3DFMT_DXT2:
928     case D3DFMT_DXT3:
929     case D3DFMT_DXT4:
930     case D3DFMT_DXT5: 
931
932     /*****
933      *  supported 
934      */
935       /*case D3DFMT_R5G6B5: */
936       /*case D3DFMT_X1R5G5B5:*/
937       /*case D3DFMT_A1R5G5B5: */
938       /*case D3DFMT_A4R4G4B4:*/
939
940     /*****
941      * unsupported 
942      */
943
944       /* color buffer */
945       /*case D3DFMT_X8R8G8B8:*/
946     case D3DFMT_A8R3G3B2:
947
948       /* Paletted */
949     case D3DFMT_P8:
950     case D3DFMT_A8P8:
951
952       /* Luminance */
953     case D3DFMT_L8:
954     case D3DFMT_A8L8:
955     case D3DFMT_A4L4:
956
957       /* Bump */
958 #if 0
959     case D3DFMT_V8U8:
960     case D3DFMT_V16U16:
961 #endif
962     case D3DFMT_L6V5U5:
963     case D3DFMT_X8L8V8U8:
964     case D3DFMT_Q8W8V8U8:
965     case D3DFMT_W11V11U10:
966
967     /****
968      * currently hard to support 
969      */
970     case D3DFMT_UYVY:
971     case D3DFMT_YUY2:
972
973       /* Since we do not support these formats right now, don't pretend to. */
974       TRACE_(d3d_caps)("[FAILED]\n");
975       return D3DERR_NOTAVAILABLE;
976     default:
977       break;
978     }
979
980     TRACE_(d3d_caps)("[OK]\n");
981     return D3D_OK;
982 }
983
984 HRESULT  WINAPI  IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) {
985     IWineD3DImpl *This = (IWineD3DImpl *)iface;
986
987     FIXME_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))",
988           This, 
989           Adapter, 
990           DeviceType, debug_d3ddevicetype(DeviceType), 
991           SourceFormat, debug_d3dformat(SourceFormat), 
992           TargetFormat, debug_d3dformat(TargetFormat));
993     return D3D_OK;
994 }
995
996 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true 
997       subset of a D3DCAPS9 structure. However, it has to come via a void * 
998       as the d3d8 interface cannot import the d3d9 header                  */
999 HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, D3DDEVTYPE DeviceType, WINED3DCAPS* pCapsIn) {
1000
1001     IWineD3DImpl    *This = (IWineD3DImpl *)iface;
1002     BOOL             gotContext  = FALSE;
1003     GLint            gl_tex_size = 0;    
1004     WineD3D_Context *fake_ctx = NULL;
1005     D3DCAPS9        *pCaps = (D3DCAPS9 *)pCapsIn;
1006
1007     TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
1008
1009     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1010         return D3DERR_INVALIDCALL;
1011     }
1012
1013     /* Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
1014        ie there is no GL Context - Get a default rendering context to enable the 
1015        function query some info from GL                                           */    
1016     if (glXGetCurrentContext() == NULL) {
1017         fake_ctx = WineD3D_CreateFakeGLContext();
1018         if (NULL != fake_ctx) gotContext = TRUE;
1019     } else {
1020         gotContext = TRUE;
1021     }
1022
1023     if (gotContext == FALSE) {
1024
1025         FIXME_(d3d_caps)("GetDeviceCaps called but no GL Context - Returning dummy values\n");
1026         gl_tex_size=65535;
1027         pCaps->MaxTextureBlendStages = 2;
1028         pCaps->MaxSimultaneousTextures = 2;
1029         pCaps->MaxUserClipPlanes = 8;
1030         pCaps->MaxActiveLights = 8;
1031         pCaps->MaxVertexBlendMatrices = 0;
1032         pCaps->MaxVertexBlendMatrixIndex = 1;
1033         pCaps->MaxAnisotropy = 0;
1034         pCaps->MaxPointSize = 255.0;
1035     } else {
1036         glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_tex_size);
1037     }
1038
1039     /* If we don't know the device settings, go query them now */
1040     if (This->isGLInfoValid == FALSE) {
1041         BOOL rc = IWineD3DImpl_FillGLCaps(&This->gl_info, NULL);
1042
1043         /* If we are running off a real context, save the values */
1044         if (rc && ((NULL != fake_ctx))) This->isGLInfoValid = TRUE;
1045     }
1046
1047     /* ------------------------------------------------
1048        The following fields apply to both d3d8 and d3d9
1049        ------------------------------------------------ */
1050     pCaps->DeviceType = (DeviceType == D3DDEVTYPE_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
1051     pCaps->AdapterOrdinal = Adapter;
1052
1053     pCaps->Caps = 0;
1054     pCaps->Caps2 = D3DCAPS2_CANRENDERWINDOWED;
1055     pCaps->Caps3 = D3DDEVCAPS_HWTRANSFORMANDLIGHT;
1056     pCaps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE;
1057
1058     pCaps->CursorCaps = 0;
1059
1060     pCaps->DevCaps = D3DDEVCAPS_DRAWPRIMTLVERTEX    | 
1061                      D3DDEVCAPS_HWTRANSFORMANDLIGHT |
1062                      D3DDEVCAPS_PUREDEVICE;
1063
1064     pCaps->PrimitiveMiscCaps = D3DPMISCCAPS_CULLCCW               | 
1065                                D3DPMISCCAPS_CULLCW                | 
1066                                D3DPMISCCAPS_COLORWRITEENABLE      |
1067                                D3DPMISCCAPS_CLIPTLVERTS           |
1068                                D3DPMISCCAPS_CLIPPLANESCALEDPOINTS | 
1069                                D3DPMISCCAPS_MASKZ; 
1070                                /*NOT: D3DPMISCCAPS_TSSARGTEMP*/
1071
1072     pCaps->RasterCaps = D3DPRASTERCAPS_DITHER   | 
1073                         D3DPRASTERCAPS_PAT      | 
1074                         D3DPRASTERCAPS_WFOG |
1075                         D3DPRASTERCAPS_ZFOG |
1076                         D3DPRASTERCAPS_FOGVERTEX |
1077                         D3DPRASTERCAPS_FOGTABLE  |
1078                         D3DPRASTERCAPS_FOGRANGE;
1079
1080     if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
1081       pCaps->RasterCaps |= D3DPRASTERCAPS_ANISOTROPY;
1082     }
1083                         /* FIXME Add:
1084                            D3DPRASTERCAPS_MIPMAPLODBIAS
1085                            D3DPRASTERCAPS_ZBIAS
1086                            D3DPRASTERCAPS_COLORPERSPECTIVE
1087                            D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
1088                            D3DPRASTERCAPS_ANTIALIASEDGES
1089                            D3DPRASTERCAPS_ZBUFFERLESSHSR
1090                            D3DPRASTERCAPS_WBUFFER */
1091
1092     pCaps->ZCmpCaps = D3DPCMPCAPS_ALWAYS       | 
1093                       D3DPCMPCAPS_EQUAL        | 
1094                       D3DPCMPCAPS_GREATER      | 
1095                       D3DPCMPCAPS_GREATEREQUAL |
1096                       D3DPCMPCAPS_LESS         | 
1097                       D3DPCMPCAPS_LESSEQUAL    | 
1098                       D3DPCMPCAPS_NEVER        |
1099                       D3DPCMPCAPS_NOTEQUAL;
1100
1101     pCaps->SrcBlendCaps  = 0xFFFFFFFF;   /*FIXME: Tidy up later */
1102     pCaps->DestBlendCaps = 0xFFFFFFFF;   /*FIXME: Tidy up later */
1103     pCaps->AlphaCmpCaps  = 0xFFFFFFFF;   /*FIXME: Tidy up later */
1104
1105     pCaps->ShadeCaps = D3DPSHADECAPS_SPECULARGOURAUDRGB | 
1106                        D3DPSHADECAPS_COLORGOURAUDRGB;
1107
1108     pCaps->TextureCaps =  D3DPTEXTURECAPS_ALPHA        | 
1109                           D3DPTEXTURECAPS_ALPHAPALETTE | 
1110                           D3DPTEXTURECAPS_POW2         | 
1111                           D3DPTEXTURECAPS_VOLUMEMAP    | 
1112                           D3DPTEXTURECAPS_MIPMAP       |
1113                           D3DPTEXTURECAPS_PROJECTED;
1114
1115     if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1116       pCaps->TextureCaps |= D3DPTEXTURECAPS_CUBEMAP      | 
1117                             D3DPTEXTURECAPS_MIPCUBEMAP   | 
1118                             D3DPTEXTURECAPS_CUBEMAP_POW2;
1119     }
1120
1121     pCaps->TextureFilterCaps = D3DPTFILTERCAPS_MAGFLINEAR | 
1122                                D3DPTFILTERCAPS_MAGFPOINT  | 
1123                                D3DPTFILTERCAPS_MINFLINEAR | 
1124                                D3DPTFILTERCAPS_MINFPOINT  |
1125                                D3DPTFILTERCAPS_MIPFLINEAR | 
1126                                D3DPTFILTERCAPS_MIPFPOINT;
1127
1128     pCaps->CubeTextureFilterCaps = 0;
1129     pCaps->VolumeTextureFilterCaps = 0;
1130
1131     pCaps->TextureAddressCaps =  D3DPTADDRESSCAPS_BORDER | 
1132                                  D3DPTADDRESSCAPS_CLAMP  | 
1133                                  D3DPTADDRESSCAPS_WRAP;
1134
1135     if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
1136       pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_BORDER;
1137     }
1138     if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
1139       pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRROR;
1140     }
1141     if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
1142       pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
1143     }
1144
1145     pCaps->VolumeTextureAddressCaps = 0;
1146
1147     pCaps->LineCaps = D3DLINECAPS_TEXTURE | 
1148                       D3DLINECAPS_ZTEST;
1149                       /* FIXME: Add 
1150                          D3DLINECAPS_BLEND
1151                          D3DLINECAPS_ALPHACMP
1152                          D3DLINECAPS_FOG */
1153
1154     pCaps->MaxTextureWidth = gl_tex_size;
1155     pCaps->MaxTextureHeight = gl_tex_size;
1156
1157     pCaps->MaxVolumeExtent = 0;
1158
1159     pCaps->MaxTextureRepeat = 32768;
1160     pCaps->MaxTextureAspectRatio = 32768;
1161     pCaps->MaxVertexW = 1.0;
1162
1163     pCaps->GuardBandLeft = 0;
1164     pCaps->GuardBandTop = 0;
1165     pCaps->GuardBandRight = 0;
1166     pCaps->GuardBandBottom = 0;
1167
1168     pCaps->ExtentsAdjust = 0;
1169
1170     pCaps->StencilCaps =  D3DSTENCILCAPS_DECRSAT | 
1171                           D3DSTENCILCAPS_INCRSAT | 
1172                           D3DSTENCILCAPS_INVERT  | 
1173                           D3DSTENCILCAPS_KEEP    | 
1174                           D3DSTENCILCAPS_REPLACE | 
1175                           D3DSTENCILCAPS_ZERO;
1176     if (GL_SUPPORT(EXT_STENCIL_WRAP)) {
1177       pCaps->StencilCaps |= D3DSTENCILCAPS_DECR    | 
1178                             D3DSTENCILCAPS_INCR;
1179     }
1180
1181     pCaps->FVFCaps = D3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
1182
1183     pCaps->TextureOpCaps =  D3DTEXOPCAPS_ADD         | 
1184                             D3DTEXOPCAPS_ADDSIGNED   | 
1185                             D3DTEXOPCAPS_ADDSIGNED2X |
1186                             D3DTEXOPCAPS_MODULATE    | 
1187                             D3DTEXOPCAPS_MODULATE2X  | 
1188                             D3DTEXOPCAPS_MODULATE4X  |
1189                             D3DTEXOPCAPS_SELECTARG1  | 
1190                             D3DTEXOPCAPS_SELECTARG2  | 
1191                             D3DTEXOPCAPS_DISABLE;
1192 #if defined(GL_VERSION_1_3)
1193     pCaps->TextureOpCaps |= D3DTEXOPCAPS_DOTPRODUCT3 | 
1194                             D3DTEXOPCAPS_SUBTRACT;
1195 #endif
1196     if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) || 
1197         GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) || 
1198         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1199       pCaps->TextureOpCaps |= D3DTEXOPCAPS_BLENDDIFFUSEALPHA |
1200                               D3DTEXOPCAPS_BLENDTEXTUREALPHA | 
1201                               D3DTEXOPCAPS_BLENDFACTORALPHA  |
1202                               D3DTEXOPCAPS_BLENDCURRENTALPHA |
1203                               D3DTEXOPCAPS_LERP;
1204     }
1205     if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1206       pCaps->TextureOpCaps |= D3DTEXOPCAPS_ADDSMOOTH | 
1207                               D3DTEXOPCAPS_MULTIPLYADD |
1208                               D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
1209                               D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
1210                               D3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
1211     }
1212     
1213 #if 0
1214     pCaps->TextureOpCaps |= D3DTEXOPCAPS_BUMPENVMAP;
1215                             /* FIXME: Add 
1216                               D3DTEXOPCAPS_BUMPENVMAPLUMINANCE 
1217                               D3DTEXOPCAPS_PREMODULATE */
1218 #endif
1219
1220     if (gotContext) {
1221         GLint gl_max;
1222         GLfloat gl_float;
1223 #if defined(GL_VERSION_1_3)
1224         glGetIntegerv(GL_MAX_TEXTURE_UNITS, &gl_max);
1225 #else
1226         glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
1227 #endif
1228         TRACE_(d3d_caps)("GLCaps: GL_MAX_TEXTURE_UNITS_ARB=%d\n", gl_max);
1229         pCaps->MaxTextureBlendStages = min(8, gl_max);
1230         pCaps->MaxSimultaneousTextures = min(8, gl_max);
1231
1232         glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
1233         pCaps->MaxUserClipPlanes = min(D3DMAXUSERCLIPPLANES, gl_max);
1234         TRACE_(d3d_caps)("GLCaps: GL_MAX_CLIP_PLANES=%ld\n", pCaps->MaxUserClipPlanes);
1235
1236         glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
1237         pCaps->MaxActiveLights = gl_max;
1238         TRACE_(d3d_caps)("GLCaps: GL_MAX_LIGHTS=%ld\n", pCaps->MaxActiveLights);
1239
1240         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
1241            glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
1242            pCaps->MaxVertexBlendMatrices = gl_max;
1243            pCaps->MaxVertexBlendMatrixIndex = 1;
1244         } else {
1245            pCaps->MaxVertexBlendMatrices = 0;
1246            pCaps->MaxVertexBlendMatrixIndex = 1;
1247         }
1248
1249         if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
1250           glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
1251           pCaps->MaxAnisotropy = gl_max;
1252         } else {
1253           pCaps->MaxAnisotropy = 0;
1254         }
1255
1256         glGetFloatv(GL_POINT_SIZE_RANGE, &gl_float);
1257         pCaps->MaxPointSize = gl_float;
1258     }
1259
1260     pCaps->VertexProcessingCaps = D3DVTXPCAPS_DIRECTIONALLIGHTS | 
1261                                   D3DVTXPCAPS_MATERIALSOURCE7   | 
1262                                   D3DVTXPCAPS_POSITIONALLIGHTS  | 
1263                                   D3DVTXPCAPS_LOCALVIEWER |
1264                                   D3DVTXPCAPS_TEXGEN;
1265                                   /* FIXME: Add 
1266                                      D3DVTXPCAPS_TWEENING */
1267
1268     pCaps->MaxPrimitiveCount = 0xFFFFFFFF;
1269     pCaps->MaxVertexIndex = 0xFFFFFFFF;
1270     pCaps->MaxStreams = MAX_STREAMS;
1271     pCaps->MaxStreamStride = 1024;
1272
1273     if (((vs_mode == VS_HW) && GL_SUPPORT(ARB_VERTEX_PROGRAM)) || (vs_mode == VS_SW) || (DeviceType == D3DDEVTYPE_REF)) {
1274       pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
1275       
1276       if (This->gl_info.gl_vendor == VENDOR_MESA || 
1277           This->gl_info.gl_vendor == VENDOR_WINE) {
1278         pCaps->MaxVertexShaderConst = 95;
1279       } else {
1280         pCaps->MaxVertexShaderConst = WINED3D_VSHADER_MAX_CONSTANTS;
1281       }
1282     } else {
1283       pCaps->VertexShaderVersion = 0;
1284       pCaps->MaxVertexShaderConst = 0;
1285     }
1286
1287     if ((ps_mode == PS_HW) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM) && (DeviceType != D3DDEVTYPE_REF)) {
1288         pCaps->PixelShaderVersion = D3DPS_VERSION(1,4);
1289         pCaps->MaxPixelShaderValue = 1.0;
1290     } else {
1291         pCaps->PixelShaderVersion = 0;
1292         pCaps->MaxPixelShaderValue = 0.0;
1293     }
1294
1295     /* ------------------------------------------------
1296        The following fields apply to d3d9 only
1297        ------------------------------------------------ */
1298     if (This->dxVersion > 8) {
1299         FIXME("Caps support for directx9 is non-existent at the moment!\n");
1300         pCaps->DevCaps2 = 0;
1301         pCaps->MaxNpatchTessellationLevel = 0;
1302         pCaps->MasterAdapterOrdinal = 0;
1303         pCaps->AdapterOrdinalInGroup = 0;
1304         pCaps->NumberOfAdaptersInGroup = 1;
1305         pCaps->DeclTypes = 0;
1306         pCaps->NumSimultaneousRTs = 0;
1307         pCaps->StretchRectFilterCaps = 0;
1308         pCaps->VS20Caps.Caps = 0;
1309         pCaps->PS20Caps.Caps = 0;
1310         pCaps->VertexTextureFilterCaps = 0;
1311         pCaps->MaxVShaderInstructionsExecuted = 0;
1312         pCaps->MaxPShaderInstructionsExecuted = 0;
1313         pCaps->MaxVertexShader30InstructionSlots = 0;
1314         pCaps->MaxPixelShader30InstructionSlots = 0;
1315     }
1316
1317     /* If we created a dummy context, throw it away */
1318     if (NULL != fake_ctx) WineD3D_ReleaseFakeGLContext(fake_ctx);
1319     return D3D_OK;
1320 }
1321
1322 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
1323    and fields being inserted in the middle, a new structure is used in place    */
1324 HRESULT  WINAPI  IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
1325                                            DWORD BehaviourFlags, WINED3DPRESENT_PARAMETERS* pPresentationParameters,
1326                                            IWineD3DDevice** ppReturnedDeviceInterface, IUnknown *parent, D3DCB_CREATERENDERTARGETFN D3DCB_CreateRenderTarget) {
1327
1328     HWND                whichHWND;
1329     HDC                 hDc;
1330     IWineD3DDeviceImpl *object  = NULL;
1331     IWineD3DImpl       *This    = (IWineD3DImpl *)iface;
1332     int                 num;
1333     XVisualInfo         template;
1334
1335     /* Validate the adapter number */
1336     if (Adapter >= IWineD3D_GetAdapterCount(iface)) {
1337         return D3DERR_INVALIDCALL;
1338     }
1339
1340     /* Create a WineD3DDevice object */
1341     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DDeviceImpl));
1342     *ppReturnedDeviceInterface = (IWineD3DDevice *)object;
1343     TRACE("Created WineD3DDevice object @ %p \n", object);
1344     if (NULL == object) {
1345       return D3DERR_OUTOFVIDEOMEMORY;
1346     }
1347
1348     /* Set up initial COM information */
1349     object->lpVtbl  = &IWineD3DDevice_Vtbl;
1350     object->ref     = 1;
1351     object->wineD3D = iface;
1352     IWineD3D_AddRef(object->wineD3D);
1353     object->parent  = parent;
1354     
1355     TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %lx, PresParms: %p, RetDevInt: %p)\n", This, Adapter, DeviceType,
1356           hFocusWindow, BehaviourFlags, pPresentationParameters, ppReturnedDeviceInterface);
1357     TRACE("(%p)->(DepthStencil:(%u,%s), BackBufferFormat:(%u,%s))\n", This, 
1358           *(pPresentationParameters->AutoDepthStencilFormat), debug_d3dformat(*(pPresentationParameters->AutoDepthStencilFormat)),
1359           *(pPresentationParameters->BackBufferFormat), debug_d3dformat(*(pPresentationParameters->BackBufferFormat)));
1360
1361     /* Save the creation parameters */
1362     object->createParms.AdapterOrdinal = Adapter;
1363     object->createParms.DeviceType     = DeviceType;
1364     object->createParms.hFocusWindow   = hFocusWindow;
1365     object->createParms.BehaviorFlags  = BehaviourFlags;
1366
1367     /* Initialize other useful values */
1368     object->presentParms.BackBufferCount = 1; /* Opengl only supports one? */
1369     object->adapterNo                    = Adapter;
1370     object->devType                      = DeviceType;
1371
1372     /* Setup hwnd we are using, plus which display this equates to */
1373     whichHWND = *(pPresentationParameters->hDeviceWindow);
1374     if (!whichHWND) {
1375         whichHWND = hFocusWindow;
1376     }
1377     object->win_handle = whichHWND;
1378     object->win        = (Window)GetPropA( whichHWND, "__wine_x11_whole_window" );
1379     hDc                = GetDC(whichHWND);
1380     object->display    = get_display(hDc);
1381     ReleaseDC(whichHWND, hDc);
1382
1383     /* FIXME: Use for dx8 code eventually too! */
1384     /* Deliberately no indentation here, as this if will be removed when dx8 support merged in */
1385     if (This->dxVersion > 8) {   
1386
1387     /* Create a context based off the properties of the existing visual */
1388     /*   Note the visual is chosen as the window is created and the glcontext cannot
1389          use different properties after that point in time. FIXME: How to handle when requested format 
1390          doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
1391          it chooses is identical to the one already being used!                                        */
1392     /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */
1393     ENTER_GL();
1394     template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
1395     object->visInfo   = XGetVisualInfo(object->display, VisualIDMask, &template, &num);
1396     if (NULL == object->visInfo) {
1397         ERR("cannot really get XVisual\n"); 
1398         LEAVE_GL();
1399         return D3DERR_NOTAVAILABLE;
1400     }
1401     object->glCtx = glXCreateContext(object->display, object->visInfo, NULL, GL_TRUE);
1402     if (NULL == object->glCtx) {
1403         ERR("cannot create glxContext\n"); 
1404         LEAVE_GL();
1405         return D3DERR_NOTAVAILABLE;
1406     }
1407     LEAVE_GL();
1408
1409     if (object->glCtx == NULL) {
1410         ERR("Error in context creation !\n");
1411         return D3DERR_INVALIDCALL;
1412     } else {
1413         TRACE("Context created (HWND=%p, glContext=%p, Window=%ld, VisInfo=%p)\n",
1414                 whichHWND, object->glCtx, object->win, object->visInfo);
1415     }
1416
1417     /* If not windowed, need to go fullscreen, and resize the HWND to the appropriate  */
1418     /*        dimensions                                                               */
1419     if (!*(pPresentationParameters->Windowed)) {
1420
1421         DEVMODEW devmode;
1422         HDC      hdc;
1423         int      bpp = 0;
1424
1425         /* Get info on the current display setup */
1426         hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
1427         bpp = GetDeviceCaps(hdc, BITSPIXEL);
1428         DeleteDC(hdc);
1429
1430         /* Change the display settings */
1431         memset(&devmode, 0, sizeof(DEVMODEW));
1432         devmode.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 
1433         devmode.dmBitsPerPel = (bpp >= 24) ? 32 : bpp;   /*Stupid XVidMode cannot change bpp D3DFmtGetBpp(object, pPresentationParameters->BackBufferFormat);*/
1434         devmode.dmPelsWidth  = *(pPresentationParameters->BackBufferWidth);
1435         devmode.dmPelsHeight = *(pPresentationParameters->BackBufferHeight);
1436         MultiByteToWideChar(CP_ACP, 0, "Gamers CG", -1, devmode.dmDeviceName, CCHDEVICENAME);
1437         ChangeDisplaySettingsExW(devmode.dmDeviceName, &devmode, object->win_handle, CDS_FULLSCREEN, NULL);
1438
1439         /* Make popup window */
1440         SetWindowLongA(whichHWND, GWL_STYLE, WS_POPUP);
1441         SetWindowPos(object->win_handle, HWND_TOP, 0, 0, 
1442                      *(pPresentationParameters->BackBufferWidth),
1443                      *(pPresentationParameters->BackBufferHeight), SWP_SHOWWINDOW | SWP_FRAMECHANGED);
1444     }
1445
1446     /* MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
1447        then the corresponding dimension of the client area of the hDeviceWindow
1448        (or the focus window, if hDeviceWindow is NULL) is taken. */
1449     if (*(pPresentationParameters->Windowed) && 
1450         ((*(pPresentationParameters->BackBufferWidth)  == 0) ||
1451          (*(pPresentationParameters->BackBufferHeight) == 0))) {
1452
1453         RECT Rect;
1454         GetClientRect(whichHWND, &Rect);
1455
1456         if (*(pPresentationParameters->BackBufferWidth) == 0) {
1457            *(pPresentationParameters->BackBufferWidth) = Rect.right;
1458            TRACE("Updating width to %d\n", *(pPresentationParameters->BackBufferWidth));
1459         }
1460         if (*(pPresentationParameters->BackBufferHeight) == 0) {
1461            *(pPresentationParameters->BackBufferHeight) = Rect.bottom;
1462            TRACE("Updating height to %d\n", *(pPresentationParameters->BackBufferHeight));
1463         }
1464     }
1465
1466     /* Save the presentation parms now filled in correctly */
1467     object->presentParms.BackBufferWidth                = *(pPresentationParameters->BackBufferWidth);
1468     object->presentParms.BackBufferHeight               = *(pPresentationParameters->BackBufferHeight);           
1469     object->presentParms.BackBufferFormat               = *(pPresentationParameters->BackBufferFormat);           
1470     object->presentParms.BackBufferCount                = *(pPresentationParameters->BackBufferCount);            
1471     object->presentParms.MultiSampleType                = *(pPresentationParameters->MultiSampleType);            
1472     object->presentParms.MultiSampleQuality             = *(pPresentationParameters->MultiSampleQuality);         
1473     object->presentParms.SwapEffect                     = *(pPresentationParameters->SwapEffect);                 
1474     object->presentParms.hDeviceWindow                  = *(pPresentationParameters->hDeviceWindow);              
1475     object->presentParms.Windowed                       = *(pPresentationParameters->Windowed);                   
1476     object->presentParms.EnableAutoDepthStencil         = *(pPresentationParameters->EnableAutoDepthStencil);     
1477     object->presentParms.AutoDepthStencilFormat         = *(pPresentationParameters->AutoDepthStencilFormat);     
1478     object->presentParms.Flags                          = *(pPresentationParameters->Flags);                      
1479     object->presentParms.FullScreen_RefreshRateInHz     = *(pPresentationParameters->FullScreen_RefreshRateInHz); 
1480     object->presentParms.PresentationInterval           = *(pPresentationParameters->PresentationInterval);       
1481
1482     /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
1483     IWineD3DDevice_CreateStateBlock((IWineD3DDevice *)object, 
1484                                     (D3DSTATEBLOCKTYPE) 0, 
1485                                     (IWineD3DStateBlock **)&object->stateBlock,
1486                                     NULL);   /* Note: No parent needed for initial internal stateblock */
1487     object->updateStateBlock = object->stateBlock;
1488
1489     /* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */
1490     TRACE("Creating initial device surfaces\n");
1491
1492     /* We need to 'magic' either d3d8 or d3d9 surfaces for the front and backbuuffer 
1493        but the respective CreateRenderTarget functions take a differing number of
1494        parms. Fix this by passing in a function to call which takes identical parms
1495        and handles the differences at the d3dx layer, and returns the IWineD3DSurface
1496        pointer rather than the created D3D8/9 one                                      */
1497     D3DCB_CreateRenderTarget((IUnknown *) parent,
1498                              *(pPresentationParameters->BackBufferWidth),
1499                              *(pPresentationParameters->BackBufferHeight),
1500                              *(pPresentationParameters->BackBufferFormat),
1501                              *(pPresentationParameters->MultiSampleType),
1502                              *(pPresentationParameters->MultiSampleQuality),
1503                              TRUE,
1504                              (IWineD3DSurface **) &object->frontBuffer,
1505                              NULL);
1506
1507     D3DCB_CreateRenderTarget((IUnknown *) parent,
1508                              *(pPresentationParameters->BackBufferWidth),
1509                              *(pPresentationParameters->BackBufferHeight),
1510                              *(pPresentationParameters->BackBufferFormat),
1511                              *(pPresentationParameters->MultiSampleType),
1512                              *(pPresentationParameters->MultiSampleQuality),
1513                              TRUE,
1514                              (IWineD3DSurface **) &object->backBuffer,
1515                              NULL);
1516
1517 /* TODO: 
1518     if (*(pPresentationParameters->EnableAutoDepthStencil)) {
1519        IWineD3DDevice_CreateDepthStencilSurface((IWineD3DDevice *) object,
1520                                                 *(pPresentationParameters->BackBufferWidth),
1521                                                 *(pPresentationParameters->BackBufferHeight),
1522                                                 *(pPresentationParameters->AutoDepthStencilFormat,
1523                                                 D3DMULTISAMPLE_NONE,
1524                                                 (IWineD3DSurface *) &object->depthStencilBuffer);
1525     } else {
1526       object->depthStencilBuffer = NULL;
1527     }
1528     TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil @ %p\n",object->frontBuffer, object->backBuffer, object->depthStencilBuffer);
1529 */    
1530
1531     /* init the default renderTarget management */
1532     object->drawable     = object->win;
1533     object->render_ctx   = object->glCtx;
1534     object->renderTarget = object->backBuffer;
1535     
1536     IWineD3DSurface_AddRef((IWineD3DSurface *) object->renderTarget);
1537 /* TODO: Depth Stencil support
1538     object->stencilBufferTarget = object->depthStencilBuffer;
1539     if (NULL != object->stencilBufferTarget) {
1540       IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->stencilBufferTarget);
1541     }
1542 */    
1543
1544     /* Set up some starting GL setup */
1545     ENTER_GL();
1546
1547     if (glXMakeCurrent(object->display, object->win, object->glCtx) == False) {
1548       ERR("Error in setting current context (context %p drawable %ld)!\n", object->glCtx, object->win);
1549     }
1550     checkGLcall("glXMakeCurrent");
1551
1552     /* Clear the screen */
1553     glClearColor(1.0, 0.0, 0.0, 0.0);
1554     checkGLcall("glClearColor");
1555     glColor3f(1.0, 1.0, 1.0);
1556     checkGLcall("glColor3f");
1557
1558     glEnable(GL_LIGHTING);
1559     checkGLcall("glEnable");
1560
1561     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1562     checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
1563
1564     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
1565     checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
1566
1567     glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1568     checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
1569
1570     /* 
1571      * Initialize openGL extension related variables
1572      *  with Default values 
1573      */
1574     This->isGLInfoValid = IWineD3DImpl_FillGLCaps(&This->gl_info, object->display);
1575
1576     /* Setup all the devices defaults */
1577     IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)object->stateBlock); 
1578
1579     LEAVE_GL();
1580
1581     { /* Set a default viewport */
1582        D3DVIEWPORT9 vp;
1583        vp.X      = 0;
1584        vp.Y      = 0;
1585        vp.Width  = *(pPresentationParameters->BackBufferWidth);
1586        vp.Height = *(pPresentationParameters->BackBufferHeight);
1587        vp.MinZ   = 0.0f;
1588        vp.MaxZ   = 1.0f;
1589        IWineD3DDevice_SetViewport((IWineD3DDevice *)object, &vp);
1590     }
1591
1592     /* Initialize the current view state */
1593     object->modelview_valid = 1;
1594     object->proj_valid = 0;
1595     object->view_ident = 1;
1596     object->last_was_rhw = 0;
1597     glGetIntegerv(GL_MAX_LIGHTS, &object->maxConcurrentLights);
1598     TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This, Adapter, object);
1599
1600     /* Clear the screen */
1601     IWineD3DDevice_Clear((IWineD3DDevice *) object, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
1602
1603     } /* End of FIXME: remove when dx8 merged in */
1604
1605     return D3D_OK;
1606 }
1607
1608 HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
1609     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1610     IUnknown_AddRef(This->parent);
1611     *pParent = This->parent;
1612     return D3D_OK;
1613 }
1614
1615 /**********************************************************
1616  * IUnknown parts follows
1617  **********************************************************/
1618
1619 HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
1620 {
1621     return E_NOINTERFACE;
1622 }
1623
1624 ULONG WINAPI IWineD3DImpl_AddRef(IWineD3D *iface) {
1625     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1626     ULONG refCount = InterlockedIncrement(&This->ref);
1627
1628     TRACE("(%p) : AddRef increasing from %ld\n", This, refCount - 1);
1629     return refCount;
1630 }
1631
1632 ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
1633     IWineD3DImpl *This = (IWineD3DImpl *)iface;
1634     ULONG refCount = InterlockedDecrement(&This->ref);
1635
1636     TRACE("(%p) : Releasing from %ld\n", This, refCount + 1);
1637
1638     if (!refCount) HeapFree(GetProcessHeap(), 0, This);
1639     return refCount;
1640 }
1641
1642 /**********************************************************
1643  * IWineD3D VTbl follows
1644  **********************************************************/
1645
1646 IWineD3DVtbl IWineD3D_Vtbl =
1647 {
1648     IWineD3DImpl_QueryInterface,
1649     IWineD3DImpl_AddRef,
1650     IWineD3DImpl_Release,
1651     IWineD3DImpl_GetParent,
1652     IWineD3DImpl_GetAdapterCount,
1653     IWineD3DImpl_RegisterSoftwareDevice,
1654     IWineD3DImpl_GetAdapterMonitor,
1655     IWineD3DImpl_GetAdapterModeCount,
1656     IWineD3DImpl_EnumAdapterModes,
1657     IWineD3DImpl_GetAdapterDisplayMode,
1658     IWineD3DImpl_GetAdapterIdentifier,
1659     IWineD3DImpl_CheckDeviceMultiSampleType,
1660     IWineD3DImpl_CheckDepthStencilMatch,
1661     IWineD3DImpl_CheckDeviceType,
1662     IWineD3DImpl_CheckDeviceFormat,
1663     IWineD3DImpl_CheckDeviceFormatConversion,
1664     IWineD3DImpl_GetDeviceCaps,
1665     IWineD3DImpl_CreateDevice
1666 };