Added a secur32.dll that loads other SSP DLLs and forwards calls to
[wine] / dlls / d3d8 / directx.c
1 /*
2  * IDirect3D8 implementation
3  *
4  * Copyright 2002 Jason Edmeades
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
33
34 #include "d3d8_private.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
37
38 /* x11drv GDI escapes */
39 #define X11DRV_ESCAPE 6789
40 enum x11drv_escape_codes
41 {
42     X11DRV_GET_DISPLAY,   /* get X11 display for a DC */
43     X11DRV_GET_DRAWABLE,  /* get current drawable for a DC */
44     X11DRV_GET_FONT,      /* get current X font for a DC */
45 };
46
47 #define NUM_FORMATS 7
48 static const D3DFORMAT device_formats[NUM_FORMATS] = {
49   D3DFMT_P8,
50   D3DFMT_R3G3B2,
51   D3DFMT_R5G6B5, 
52   D3DFMT_X1R5G5B5,
53   D3DFMT_X4R4G4B4,
54   D3DFMT_R8G8B8,
55   D3DFMT_X8R8G8B8
56 };
57
58 static void IDirect3D8Impl_FillGLCaps(LPDIRECT3D8 iface, Display* display);
59
60 /* retrieve the X display to use on a given DC */
61 inline static Display *get_display( HDC hdc )
62 {
63     Display *display;
64     enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
65
66     if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
67                     sizeof(display), (LPSTR)&display )) display = NULL;
68     return display;
69 }
70
71
72 /* IDirect3D IUnknown parts follow: */
73 HRESULT WINAPI IDirect3D8Impl_QueryInterface(LPDIRECT3D8 iface,REFIID riid,LPVOID *ppobj)
74 {
75     ICOM_THIS(IDirect3D8Impl,iface);
76
77     if (IsEqualGUID(riid, &IID_IUnknown)
78         || IsEqualGUID(riid, &IID_IDirect3D8)) {
79         IDirect3D8Impl_AddRef(iface);
80         *ppobj = This;
81         return D3D_OK;
82     }
83
84     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
85     return E_NOINTERFACE;
86 }
87
88 ULONG WINAPI IDirect3D8Impl_AddRef(LPDIRECT3D8 iface) {
89     ICOM_THIS(IDirect3D8Impl,iface);
90     TRACE("(%p) : AddRef from %ld\n", This, This->ref);
91     return ++(This->ref);
92 }
93
94 ULONG WINAPI IDirect3D8Impl_Release(LPDIRECT3D8 iface) {
95     ICOM_THIS(IDirect3D8Impl,iface);
96     ULONG ref = --This->ref;
97     TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
98     if (ref == 0)
99         HeapFree(GetProcessHeap(), 0, This);
100     return ref;
101 }
102
103 /* IDirect3D Interface follow: */
104 HRESULT  WINAPI  IDirect3D8Impl_RegisterSoftwareDevice     (LPDIRECT3D8 iface, void* pInitializeFunction) {
105     ICOM_THIS(IDirect3D8Impl,iface);
106     FIXME("(%p)->(%p): stub\n", This, pInitializeFunction);
107     return D3D_OK;
108 }
109
110 UINT     WINAPI  IDirect3D8Impl_GetAdapterCount            (LPDIRECT3D8 iface) {
111     ICOM_THIS(IDirect3D8Impl,iface);
112     /* FIXME: Set to one for now to imply the display */
113     TRACE("(%p): Mostly stub, only returns primary display\n", This);
114     return 1;
115 }
116
117 HRESULT  WINAPI  IDirect3D8Impl_GetAdapterIdentifier       (LPDIRECT3D8 iface,
118                                                             UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER8* pIdentifier) {
119     ICOM_THIS(IDirect3D8Impl,iface);
120
121     TRACE("(%p}->(Adapter: %d, Flags: %lx, pId=%p)\n", This, Adapter, Flags, pIdentifier);
122
123     if (Adapter >= IDirect3D8Impl_GetAdapterCount(iface)) {
124         return D3DERR_INVALIDCALL;
125     }
126
127     if (Adapter == 0) { /* Display */
128         strcpy(pIdentifier->Driver, "Display");
129         strcpy(pIdentifier->Description, "Direct3D Display");
130         pIdentifier->DriverVersion.u.HighPart = 1;
131         pIdentifier->DriverVersion.u.LowPart = 0;
132         pIdentifier->VendorId = 0;
133         pIdentifier->DeviceId = 0;
134         pIdentifier->SubSysId = 0;
135         pIdentifier->Revision = 0;
136         /*FIXME: memcpy(&pIdentifier->DeviceIdentifier, ??, sizeof(??GUID)); */
137         if (Flags & D3DENUM_NO_WHQL_LEVEL) {
138             pIdentifier->WHQLLevel = 0;
139         } else {
140             pIdentifier->WHQLLevel = 1;
141         }
142     } else {
143         FIXME("Adapter not primary display\n");
144     }
145
146     return D3D_OK;
147 }
148
149 UINT     WINAPI  IDirect3D8Impl_GetAdapterModeCount        (LPDIRECT3D8 iface,
150                                                             UINT Adapter) {
151     ICOM_THIS(IDirect3D8Impl,iface);
152
153     TRACE("(%p}->(Adapter: %d)\n", This, Adapter);
154
155     if (Adapter >= IDirect3D8Impl_GetAdapterCount(iface)) {
156         return D3DERR_INVALIDCALL;
157     }
158
159     if (Adapter == 0) { /* Display */
160         DEVMODEW DevModeW;
161         int i = 0;
162
163         while (EnumDisplaySettingsExW(NULL, i, &DevModeW, 0)) {
164             i++;
165         }
166         TRACE("(%p}->(Adapter: %d) => %d\n", This, Adapter, i);
167         return i;
168     } else {
169         FIXME("Adapter not primary display\n");
170     }
171
172     return 0;
173 }
174
175 HRESULT  WINAPI  IDirect3D8Impl_EnumAdapterModes           (LPDIRECT3D8 iface,
176                                                             UINT Adapter, UINT Mode, D3DDISPLAYMODE* pMode) {
177     ICOM_THIS(IDirect3D8Impl,iface);
178
179     TRACE("(%p}->(Adapter:%d, mode:%d, pMode:%p)\n", This, Adapter, Mode, pMode);
180
181     if (Adapter >= IDirect3D8Impl_GetAdapterCount(iface)) {
182         return D3DERR_INVALIDCALL;
183     }
184
185     if (Adapter == 0) { /* Display */
186         HDC hdc;
187         int bpp = 0;
188         DEVMODEW DevModeW;
189
190         if (EnumDisplaySettingsExW(NULL, Mode, &DevModeW, 0)) 
191         {
192             pMode->Width        = DevModeW.dmPelsWidth;
193             pMode->Height       = DevModeW.dmPelsHeight;
194             bpp                 = DevModeW.dmBitsPerPel;
195             pMode->RefreshRate  = D3DADAPTER_DEFAULT;
196             if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
197             {
198                 pMode->RefreshRate = DevModeW.dmDisplayFrequency;
199             }
200         }
201         else
202         {
203             TRACE("Requested mode out of range %d\n", Mode);
204             return D3DERR_INVALIDCALL;
205         }
206
207         hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
208         bpp = min(GetDeviceCaps(hdc, BITSPIXEL), bpp);
209         DeleteDC(hdc);
210
211         switch (bpp) {
212         case  8: pMode->Format = D3DFMT_R3G3B2;   break;
213         case 16: pMode->Format = D3DFMT_R5G6B5;   break;
214         case 24: /* pMode->Format = D3DFMT_R5G6B5;   break;*/ /* Make 24bit appear as 32 bit */
215         case 32: pMode->Format = D3DFMT_A8R8G8B8; break;
216         default: pMode->Format = D3DFMT_UNKNOWN;
217         }
218         TRACE("W %d H %d rr %d fmt (%x,%s) bpp %u\n", pMode->Width, pMode->Height, pMode->RefreshRate, pMode->Format, debug_d3dformat(pMode->Format), bpp);
219
220     } else {
221         FIXME("Adapter not primary display\n");
222     }
223
224     return D3D_OK;
225 }
226
227 HRESULT  WINAPI  IDirect3D8Impl_GetAdapterDisplayMode      (LPDIRECT3D8 iface,
228                                                             UINT Adapter, D3DDISPLAYMODE* pMode) {
229     ICOM_THIS(IDirect3D8Impl,iface);
230     TRACE("(%p}->(Adapter: %d, pMode: %p)\n", This, Adapter, pMode);
231
232     if (Adapter >= IDirect3D8Impl_GetAdapterCount(iface)) {
233         return D3DERR_INVALIDCALL;
234     }
235
236     if (Adapter == 0) { /* Display */
237         int bpp = 0;
238         DEVMODEW DevModeW;
239
240         EnumDisplaySettingsExW(NULL, (DWORD)-1, &DevModeW, 0);
241         pMode->Width        = DevModeW.dmPelsWidth;
242         pMode->Height       = DevModeW.dmPelsHeight;
243         bpp                 = DevModeW.dmBitsPerPel;
244         pMode->RefreshRate  = D3DADAPTER_DEFAULT;
245         if (DevModeW.dmFields&DM_DISPLAYFREQUENCY)
246         {
247             pMode->RefreshRate = DevModeW.dmDisplayFrequency;
248         }
249
250         switch (bpp) {
251         case  8: pMode->Format       = D3DFMT_R3G3B2;   break;
252         case 16: pMode->Format       = D3DFMT_R5G6B5;   break;
253         case 24: /*pMode->Format       = D3DFMT_R5G6B5;   break;*/ /* Make 24bit appear as 32 bit */
254         case 32: pMode->Format       = D3DFMT_A8R8G8B8; break;
255         default: pMode->Format       = D3DFMT_UNKNOWN;
256         }
257
258     } else {
259         FIXME("Adapter not primary display\n");
260     }
261
262     TRACE("returning w:%d, h:%d, ref:%d, fmt:%x\n", pMode->Width,
263           pMode->Height, pMode->RefreshRate, pMode->Format);
264     return D3D_OK;
265 }
266
267 HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceType            (LPDIRECT3D8 iface,
268                                                             UINT Adapter, D3DDEVTYPE CheckType, D3DFORMAT DisplayFormat,
269                                                             D3DFORMAT BackBufferFormat, BOOL Windowed) {
270     ICOM_THIS(IDirect3D8Impl,iface);
271     FIXME("(%p)->(Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n", 
272           This, 
273           Adapter, 
274           CheckType, debug_d3ddevicetype(CheckType),
275           DisplayFormat, debug_d3dformat(DisplayFormat),
276           BackBufferFormat, debug_d3dformat(BackBufferFormat),
277           Windowed);
278     return D3D_OK;
279 }
280
281 HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceFormat          (LPDIRECT3D8 iface,
282                                                             UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
283                                                             DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) {
284     ICOM_THIS(IDirect3D8Impl,iface);
285     FIXME("(%p)->(Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%lu,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n", 
286           This, 
287           Adapter, 
288           DeviceType, debug_d3ddevicetype(DeviceType), 
289           AdapterFormat, debug_d3dformat(AdapterFormat), 
290           Usage, debug_d3dusage(Usage),
291           RType, debug_d3dressourcetype(RType), 
292           CheckFormat, debug_d3dformat(CheckFormat));
293
294     if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
295         switch (CheckFormat) {
296         case D3DFMT_DXT1:
297         case D3DFMT_DXT3:
298         case D3DFMT_DXT5:
299             return D3D_OK;
300         default:
301             break; /* Avoid compiler warnings */
302         }
303     }
304
305     switch (CheckFormat) {
306     case D3DFMT_UYVY:
307     case D3DFMT_YUY2:
308     case D3DFMT_DXT1:
309     case D3DFMT_DXT2:
310     case D3DFMT_DXT3:
311     case D3DFMT_DXT4:
312     case D3DFMT_DXT5:
313     case D3DFMT_X8L8V8U8:
314     case D3DFMT_L6V5U5:
315     case D3DFMT_V8U8:
316       /* Since we do not support these formats right now, don't pretend to. */
317       return D3DERR_NOTAVAILABLE;
318     default:
319       break;
320     }
321
322     return D3D_OK;
323 }
324
325 HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceMultiSampleType(LPDIRECT3D8 iface,
326                                                            UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat,
327                                                            BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType) {
328     ICOM_THIS(IDirect3D8Impl,iface);
329     FIXME("(%p)->(Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x)\n", 
330           This, 
331           Adapter, 
332           DeviceType, debug_d3ddevicetype(DeviceType),
333           SurfaceFormat, debug_d3dformat(SurfaceFormat),
334           Windowed, 
335           MultiSampleType);
336   
337     if (D3DMULTISAMPLE_NONE == MultiSampleType)
338       return D3D_OK;
339     return D3DERR_NOTAVAILABLE;
340 }
341
342 HRESULT  WINAPI  IDirect3D8Impl_CheckDepthStencilMatch(LPDIRECT3D8 iface, 
343                                                        UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
344                                                        D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) {
345     ICOM_THIS(IDirect3D8Impl,iface);
346     FIXME("(%p)->(Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n", 
347           This, 
348           Adapter, 
349           DeviceType, debug_d3ddevicetype(DeviceType),
350           AdapterFormat, debug_d3dformat(AdapterFormat),
351           RenderTargetFormat, debug_d3dformat(RenderTargetFormat), 
352           DepthStencilFormat, debug_d3dformat(DepthStencilFormat));
353
354 #if 0
355     switch (DepthStencilFormat) {
356     case D3DFMT_D24X4S4:
357     case D3DFMT_D24X8: 
358     case D3DFMT_D24S8: 
359     case D3DFMT_D32:
360       /**
361        * as i don't know how to really check hard caps of graphics cards
362        * i prefer to not permit 32bit zbuffers enumeration (as few cards can do it)
363        */
364       return D3DERR_NOTAVAILABLE;
365     default:
366       break;
367     }
368 #endif
369     return D3D_OK;
370 }
371
372 HRESULT  WINAPI  IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS8* pCaps) {
373
374     BOOL        gotContext  = FALSE;
375     BOOL        created     = FALSE;
376     GLint       gl_tex_size = 0;    
377     GLXContext  gl_context  = 0;
378     Display    *display     = NULL;
379     ICOM_THIS(IDirect3D8Impl,iface);
380
381     TRACE("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
382
383     /* Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
384         ie there is no GL Context - Get a default rendering context to enable the 
385         function query some info from GL                                           */    
386     if (glXGetCurrentContext() == NULL) {
387
388         XVisualInfo  template;
389         XVisualInfo *vis;
390         HDC          device_context;
391         Visual      *visual;
392         Drawable     drawable = (Drawable) GetPropA(GetDesktopWindow(), "__wine_x11_whole_window");
393         XWindowAttributes win_attr;
394         BOOL         failed = FALSE;
395         int          num;
396
397         /* Get the display */
398         device_context = GetDC(0);
399         display = get_display(device_context);
400         ReleaseDC(0, device_context);
401
402         /* Get the X visual */
403         ENTER_GL();
404         if (XGetWindowAttributes(display, drawable, &win_attr)) {
405             visual = win_attr.visual;
406         } else {
407             visual = DefaultVisual(display, DefaultScreen(display));
408         }
409         template.visualid = XVisualIDFromVisual(visual);
410         vis = XGetVisualInfo(display, VisualIDMask, &template, &num);
411         if (vis == NULL) {
412             LEAVE_GL();
413             WARN("Error creating visual info for capabilities initialization\n");
414             failed = TRUE;
415         }
416
417         /* Create a GL context */
418         if (!failed) {
419            gl_context = glXCreateContext(display, vis, NULL, GL_TRUE);
420
421            if (gl_context == NULL) {
422               LEAVE_GL();
423               WARN("Error creating default context for capabilities initialization\n");
424               failed = TRUE;
425            }
426         }
427
428         /* Make it the current GL context */
429         if (!failed && glXMakeCurrent(display, drawable, gl_context) == False) {
430             glXDestroyContext(display, gl_context);
431             LEAVE_GL();
432             WARN("Error setting default context as current for capabilities initialization\n");
433             failed = TRUE;      
434         }
435
436         /* It worked! Wow... */
437         if (!failed) {
438            gotContext = TRUE;
439            created = TRUE;
440         }
441     } else {
442         gotContext = TRUE;
443     }
444
445     if (gotContext == FALSE) {
446
447         FIXME("GetDeviceCaps called but no GL Context - Returning dummy values\n");
448         gl_tex_size=65535;
449         pCaps->MaxTextureBlendStages = 2;
450         pCaps->MaxSimultaneousTextures = 2;
451         pCaps->MaxUserClipPlanes = 8;
452         pCaps->MaxActiveLights = 8;
453         pCaps->MaxVertexBlendMatrices = 0;
454         pCaps->MaxVertexBlendMatrixIndex = 1;
455         pCaps->MaxAnisotropy = 0;
456         pCaps->MaxPointSize = 255.0;
457     } else {
458         glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_tex_size);
459     }
460
461     /* If we don't know the device settings, go query them now */
462     if (This->isGLInfoValid == FALSE) IDirect3D8Impl_FillGLCaps(iface, NULL);
463
464     pCaps->DeviceType = (DeviceType == D3DDEVTYPE_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF;  /* Not quite true, but use h/w supported by opengl I suppose */
465     pCaps->AdapterOrdinal = Adapter;
466
467     pCaps->Caps = 0;
468     pCaps->Caps2 = D3DCAPS2_CANRENDERWINDOWED;
469     pCaps->Caps3 = D3DDEVCAPS_HWTRANSFORMANDLIGHT;
470     pCaps->PresentationIntervals = D3DPRESENT_INTERVAL_IMMEDIATE;
471
472     pCaps->CursorCaps = 0;
473
474     pCaps->DevCaps = D3DDEVCAPS_DRAWPRIMTLVERTEX    | 
475                      D3DDEVCAPS_HWTRANSFORMANDLIGHT |
476                      D3DDEVCAPS_PUREDEVICE;
477
478     pCaps->PrimitiveMiscCaps = D3DPMISCCAPS_CULLCCW               | 
479                                D3DPMISCCAPS_CULLCW                | 
480                                D3DPMISCCAPS_COLORWRITEENABLE      |
481                                D3DPMISCCAPS_CLIPTLVERTS           |
482                                D3DPMISCCAPS_CLIPPLANESCALEDPOINTS | 
483                                D3DPMISCCAPS_MASKZ; 
484                                /*NOT: D3DPMISCCAPS_TSSARGTEMP*/
485
486     pCaps->RasterCaps = D3DPRASTERCAPS_DITHER   | 
487                         D3DPRASTERCAPS_PAT      | 
488                         D3DPRASTERCAPS_FOGRANGE;
489                         /* FIXME Add:
490                            D3DPRASTERCAPS_FOGVERTEX
491                            D3DPRASTERCAPS_FOGTABLE
492                            D3DPRASTERCAPS_MIPMAPLODBIAS
493                            D3DPRASTERCAPS_ZBIAS
494                            D3DPRASTERCAPS_ANISOTROPY
495                            D3DPRASTERCAPS_WFOG
496                            D3DPRASTERCAPS_ZFOG 
497                            D3DPRASTERCAPS_COLORPERSPECTIVE
498                            D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
499                            D3DPRASTERCAPS_ANTIALIASEDGES
500                            D3DPRASTERCAPS_ZBUFFERLESSHSR
501                            D3DPRASTERCAPS_WBUFFER */
502
503     pCaps->ZCmpCaps = D3DPCMPCAPS_ALWAYS       | 
504                       D3DPCMPCAPS_EQUAL        | 
505                       D3DPCMPCAPS_GREATER      | 
506                       D3DPCMPCAPS_GREATEREQUAL |
507                       D3DPCMPCAPS_LESS         | 
508                       D3DPCMPCAPS_LESSEQUAL    | 
509                       D3DPCMPCAPS_NEVER        |
510                       D3DPCMPCAPS_NOTEQUAL;
511
512     pCaps->SrcBlendCaps  = 0xFFFFFFFF;   /*FIXME: Tidy up later */
513     pCaps->DestBlendCaps = 0xFFFFFFFF;   /*FIXME: Tidy up later */
514     pCaps->AlphaCmpCaps  = 0xFFFFFFFF;   /*FIXME: Tidy up later */
515
516     pCaps->ShadeCaps = D3DPSHADECAPS_SPECULARGOURAUDRGB | 
517                        D3DPSHADECAPS_COLORGOURAUDRGB;
518
519     pCaps->TextureCaps =  D3DPTEXTURECAPS_ALPHA        | 
520                           D3DPTEXTURECAPS_ALPHAPALETTE | 
521                           D3DPTEXTURECAPS_POW2         | 
522                           D3DPTEXTURECAPS_VOLUMEMAP    | 
523                           D3DPTEXTURECAPS_MIPMAP;
524 #if defined(GL_VERSION_1_3) || defined(GL_ARB_texture_cube_map)
525     pCaps->TextureCaps |= D3DPTEXTURECAPS_CUBEMAP      | 
526                           D3DPTEXTURECAPS_MIPCUBEMAP   | 
527                           D3DPTEXTURECAPS_CUBEMAP_POW2;
528 #endif
529
530     pCaps->TextureFilterCaps = D3DPTFILTERCAPS_MAGFLINEAR | 
531                                D3DPTFILTERCAPS_MAGFPOINT  | 
532                                D3DPTFILTERCAPS_MINFLINEAR | 
533                                D3DPTFILTERCAPS_MINFPOINT  |
534                                D3DPTFILTERCAPS_MIPFLINEAR | 
535                                D3DPTFILTERCAPS_MIPFPOINT;
536
537     pCaps->CubeTextureFilterCaps = 0;
538     pCaps->VolumeTextureFilterCaps = 0;
539
540     pCaps->TextureAddressCaps =  D3DPTADDRESSCAPS_BORDER | 
541                                  D3DPTADDRESSCAPS_CLAMP  | 
542                                  D3DPTADDRESSCAPS_WRAP;
543 #if defined(GL_VERSION_1_3)
544     pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRROR;
545 #endif
546                                  /* FIXME: Add 
547                                     D3DPTADDRESSCAPS_BORDER
548                                     D3DPTADDRESSCAPS_MIRRORONCE */
549
550     pCaps->VolumeTextureAddressCaps = 0;
551
552     pCaps->LineCaps = D3DLINECAPS_TEXTURE | 
553                       D3DLINECAPS_ZTEST;
554                       /* FIXME: Add 
555                          D3DLINECAPS_BLEND
556                          D3DLINECAPS_ALPHACMP
557                          D3DLINECAPS_FOG */
558
559     pCaps->MaxTextureWidth = gl_tex_size;
560     pCaps->MaxTextureHeight = gl_tex_size;
561
562     pCaps->MaxVolumeExtent = 0;
563
564     pCaps->MaxTextureRepeat = 32768;
565     pCaps->MaxTextureAspectRatio = 32768;
566     pCaps->MaxVertexW = 1.0;
567
568     pCaps->GuardBandLeft = 0;
569     pCaps->GuardBandTop = 0;
570     pCaps->GuardBandRight = 0;
571     pCaps->GuardBandBottom = 0;
572
573     pCaps->ExtentsAdjust = 0;
574
575     pCaps->StencilCaps =  D3DSTENCILCAPS_DECRSAT | 
576                           D3DSTENCILCAPS_INCRSAT | 
577                           D3DSTENCILCAPS_INVERT  | 
578                           D3DSTENCILCAPS_KEEP    | 
579                           D3DSTENCILCAPS_REPLACE | 
580                           D3DSTENCILCAPS_ZERO;
581 #if defined(GL_VERSION_1_4) || defined(GL_EXT_stencil_wrap)
582     pCaps->StencilCaps |= D3DSTENCILCAPS_DECR    | 
583                           D3DSTENCILCAPS_INCR;
584 #endif
585
586     pCaps->FVFCaps = D3DFVFCAPS_PSIZE | 0x80000;
587
588     pCaps->TextureOpCaps =  D3DTEXOPCAPS_ADD         | 
589                             D3DTEXOPCAPS_ADDSIGNED   | 
590                             D3DTEXOPCAPS_ADDSIGNED2X |
591                             D3DTEXOPCAPS_MODULATE    | 
592                             D3DTEXOPCAPS_MODULATE2X  | 
593                             D3DTEXOPCAPS_MODULATE4X  |
594                             D3DTEXOPCAPS_SELECTARG1  | 
595                             D3DTEXOPCAPS_SELECTARG2  | 
596                             D3DTEXOPCAPS_DISABLE;
597 #if defined(GL_VERSION_1_3)
598     pCaps->TextureOpCaps |= D3DTEXOPCAPS_DOTPRODUCT3 | 
599                             D3DTEXOPCAPS_SUBTRACT;
600 #endif
601                             /* FIXME: Add 
602                               D3DTEXOPCAPS_ADDSMOOTH
603                               D3DTEXOPCAPS_BLENDCURRENTALPHA 
604                               D3DTEXOPCAPS_BLENDDIFFUSEALPHA 
605                               D3DTEXOPCAPS_BLENDFACTORALPHA 
606                               D3DTEXOPCAPS_BLENDTEXTUREALPHA 
607                               D3DTEXOPCAPS_BLENDTEXTUREALPHAPM 
608                               D3DTEXOPCAPS_BUMPENVMAP
609                               D3DTEXOPCAPS_BUMPENVMAPLUMINANCE 
610                               D3DTEXOPCAPS_LERP 
611                               D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR 
612                               D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA 
613                               D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR 
614                               D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA
615                               D3DTEXOPCAPS_MULTIPLYADD 
616                               D3DTEXOPCAPS_PREMODULATE */
617
618     if (gotContext) {
619         GLint gl_max;
620         GLfloat gl_float;
621 #if defined(GL_VERSION_1_3)
622         glGetIntegerv(GL_MAX_TEXTURE_UNITS, &gl_max);
623 #else
624         glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
625 #endif
626         TRACE("GLCaps: GL_MAX_TEXTURE_UNITS_ARB=%d\n", gl_max);
627         pCaps->MaxTextureBlendStages = min(8, gl_max);
628         pCaps->MaxSimultaneousTextures = min(8, gl_max);
629
630         glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
631         pCaps->MaxUserClipPlanes = min(MAX_CLIPPLANES, gl_max);
632         TRACE("GLCaps: GL_MAX_CLIP_PLANES=%ld\n", pCaps->MaxUserClipPlanes);
633
634         glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
635         pCaps->MaxActiveLights = gl_max;
636         TRACE("GLCaps: GL_MAX_LIGHTS=%ld\n", pCaps->MaxActiveLights);
637
638         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
639            glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
640            pCaps->MaxVertexBlendMatrices = gl_max;
641            pCaps->MaxVertexBlendMatrixIndex = 1;
642         } else {
643            pCaps->MaxVertexBlendMatrices = 0;
644            pCaps->MaxVertexBlendMatrixIndex = 1;
645         }
646
647 #if defined(GL_EXT_texture_filter_anisotropic)
648         glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
649         pCaps->MaxAnisotropy = gl_max;
650 #else
651         pCaps->MaxAnisotropy = 0;
652 #endif
653
654         glGetFloatv(GL_POINT_SIZE_RANGE, &gl_float);
655         pCaps->MaxPointSize = gl_float;
656     }
657
658     pCaps->VertexProcessingCaps = D3DVTXPCAPS_DIRECTIONALLIGHTS | 
659                                   D3DVTXPCAPS_MATERIALSOURCE7   | 
660                                   D3DVTXPCAPS_POSITIONALLIGHTS  | 
661                                   D3DVTXPCAPS_TEXGEN;
662                                   /* FIXME: Add 
663                                      D3DVTXPCAPS_LOCALVIEWER 
664                                      D3DVTXPCAPS_TWEENING */
665
666     pCaps->MaxPrimitiveCount = 0xFFFFFFFF;
667     pCaps->MaxVertexIndex = 0xFFFFFFFF;
668     pCaps->MaxStreams = MAX_STREAMS;
669     pCaps->MaxStreamStride = 1024;
670
671 #if 1
672     pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
673     pCaps->MaxVertexShaderConst = D3D8_VSHADER_MAX_CONSTANTS;
674 #else
675     pCaps->VertexShaderVersion = 0;
676     pCaps->MaxVertexShaderConst = D3D8_VSHADER_MAX_CONSTANTS;
677 #endif
678
679 #if 0
680     pCaps->PixelShaderVersion = D3DPS_VERSION(1,1);
681     pCaps->MaxPixelShaderValue = 1.0;
682 #else
683     pCaps->PixelShaderVersion = 0;
684     pCaps->MaxPixelShaderValue = 0.0;
685 #endif
686
687     /* If we created a dummy context, throw it away */
688     if (created) {
689         glXMakeCurrent(display, None, NULL);
690         glXDestroyContext(display, gl_context);
691         LEAVE_GL();
692     }
693     return D3D_OK;
694 }
695
696 HMONITOR WINAPI  IDirect3D8Impl_GetAdapterMonitor(LPDIRECT3D8 iface, UINT Adapter) {
697     ICOM_THIS(IDirect3D8Impl,iface);
698     FIXME("(%p)->(Adptr:%d)\n", This, Adapter);
699     return D3D_OK;
700 }
701
702
703 static void IDirect3D8Impl_FillGLCaps(LPDIRECT3D8 iface, Display* display) {
704     const char *GL_Extensions = NULL;
705     const char *GLX_Extensions = NULL;
706     GLint gl_max;
707     ICOM_THIS(IDirect3D8Impl,iface);
708
709     /* 
710      * Initialize openGL extension related variables
711      *  with Default values 
712      */
713     memset(&This->gl_info.supported, 0, sizeof(This->gl_info.supported));
714     This->gl_info.max_textures   = 1;
715     This->gl_info.ps_arb_version = PS_VERSION_NOT_SUPPORTED;
716     This->gl_info.vs_arb_version = VS_VERSION_NOT_SUPPORTED;
717     This->gl_info.vs_nv_version  = VS_VERSION_NOT_SUPPORTED;
718     This->gl_info.vs_ati_version = VS_VERSION_NOT_SUPPORTED;
719
720 #define USE_GL_FUNC(type, pfn) This->gl_info.pfn = NULL;
721     GL_EXT_FUNCS_GEN;
722 #undef USE_GL_FUNC
723
724     /* Retrieve opengl defaults */
725     glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
726     This->gl_info.max_clipplanes = min(MAX_CLIPPLANES, gl_max);
727     TRACE("ClipPlanes support - num Planes=%d\n", gl_max);
728
729     glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
730     This->gl_info.max_lights = gl_max;
731     TRACE("Lights support - max lights=%d\n", gl_max);
732
733     /* Parse the gl supported features, in theory enabling parts of our code appropriately */
734     GL_Extensions = glGetString(GL_EXTENSIONS);
735     FIXME("GL_Extensions reported:\n");  
736     
737     if (NULL == GL_Extensions) {
738       ERR("   GL_Extensions returns NULL\n");      
739     } else {
740       while (*GL_Extensions != 0x00) {
741         const char *Start = GL_Extensions;
742         char ThisExtn[256];
743
744         memset(ThisExtn, 0x00, sizeof(ThisExtn));
745         while (*GL_Extensions != ' ' && *GL_Extensions != 0x00) {
746           GL_Extensions++;
747         }
748         memcpy(ThisExtn, Start, (GL_Extensions - Start));
749         FIXME("- %s\n", ThisExtn);
750
751         /**
752          * ARB 
753          */
754         if (strcmp(ThisExtn, "GL_ARB_fragment_program") == 0) {
755           This->gl_info.ps_arb_version = PS_VERSION_11;
756           FIXME(" FOUND: ARB Pixel Shader support - version=%02x\n", This->gl_info.ps_arb_version);
757           This->gl_info.supported[ARB_FRAGMENT_PROGRAM] = TRUE;
758         } else if (strcmp(ThisExtn, "GL_ARB_multisample") == 0) {
759           FIXME(" FOUND: ARB Multisample support\n");
760           This->gl_info.supported[ARB_MULTISAMPLE] = TRUE;
761         } else if (strcmp(ThisExtn, "GL_ARB_multitexture") == 0) {
762           glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
763           FIXME(" FOUND: ARB Multitexture support - GL_MAX_TEXTURE_UNITS_ARB=%u\n", gl_max);
764           This->gl_info.supported[ARB_MULTITEXTURE] = TRUE;
765           This->gl_info.max_textures = min(8, gl_max);
766         } else if (strcmp(ThisExtn, "GL_ARB_texture_cube_map") == 0) {
767           FIXME(" FOUND: ARB Texture Cube Map support\n");
768           This->gl_info.supported[ARB_TEXTURE_CUBE_MAP] = TRUE;
769         } else if (strcmp(ThisExtn, "GL_ARB_texture_compression") == 0) {
770           FIXME(" FOUND: ARB Texture Compression support\n");
771           This->gl_info.supported[ARB_TEXTURE_COMPRESSION] = TRUE;
772         } else if (strcmp(ThisExtn, "GL_ARB_texture_env_combine") == 0) {
773           FIXME(" FOUND: EXT Texture Env combine support\n");
774           This->gl_info.supported[ARB_TEXTURE_ENV_COMBINE] = TRUE;
775         } else if (strcmp(ThisExtn, "GL_ARB_texture_env_dot3") == 0) {
776           if (FALSE == This->gl_info.supported[ARB_TEXTURE_ENV_DOT3]) {
777             FIXME(" FOUND: EXT Dot3 support\n");
778             This->gl_info.supported[ARB_TEXTURE_ENV_DOT3] = TRUE;
779           }
780         } else if (strstr(ThisExtn, "GL_ARB_vertex_program")) {
781           This->gl_info.vs_arb_version = VS_VERSION_11;
782           FIXME(" FOUND: ARB Vertex Shader support - version=%02x\n", This->gl_info.vs_arb_version);
783           This->gl_info.supported[ARB_VERTEX_PROGRAM] = TRUE;
784
785         /**
786          * EXT
787          */
788         } else if (strcmp(ThisExtn, "GL_EXT_fog_coord") == 0) {
789           FIXME(" FOUND: EXT Fog coord support\n");
790           This->gl_info.supported[EXT_FOG_COORD] = TRUE;
791         } else if (strcmp(ThisExtn, "GL_EXT_paletted_texture") == 0) { /* handle paletted texture extensions */
792           FIXME(" FOUND: EXT Paletted texture support\n");
793           This->gl_info.supported[EXT_PALETTED_TEXTURE] = TRUE;
794         } else if (strcmp(ThisExtn, "GL_EXT_point_parameters") == 0) {
795           FIXME(" FOUND: EXT Point parameters support\n");
796           This->gl_info.supported[EXT_POINT_PARAMETERS] = TRUE;
797         } else if (strcmp(ThisExtn, "GL_EXT_secondary_color") == 0) {
798           FIXME(" FOUND: EXT Secondary coord support\n");
799           This->gl_info.supported[EXT_SECONDARY_COLOR] = TRUE;
800 #if defined(GL_EXT_texture_compression_s3tc)
801         } else if (strcmp(ThisExtn, "GL_EXT_texture_compression_s3tc") == 0) {
802           FIXME(" FOUND: EXT Texture S3TC compression support\n");
803           This->gl_info.supported[EXT_TEXTURE_COMPRESSION_S3TC] = TRUE;
804 #endif
805         } else if (strcmp(ThisExtn, "GL_EXT_texture_env_dot3") == 0) {
806           if (FALSE == This->gl_info.supported[ARB_TEXTURE_ENV_DOT3]) {
807             FIXME(" FOUND: EXT Dot3 support\n");
808             This->gl_info.supported[ARB_TEXTURE_ENV_DOT3] = TRUE;
809           }
810         } else if (strcmp(ThisExtn, "GL_EXT_texture_filter_anisotropic") == 0) {
811           FIXME(" FOUND: EXT Texture Anisotropic filter support\n");
812           This->gl_info.supported[EXT_TEXTURE_FILTER_ANISOTROPIC] = TRUE;
813         } else if (strcmp(ThisExtn, "GL_EXT_texture_lod") == 0) {
814           FIXME(" FOUND: EXT Texture LOD support\n");
815           This->gl_info.supported[EXT_TEXTURE_LOD] = TRUE;
816         } else if (strcmp(ThisExtn, "GL_EXT_texture_lod_bias") == 0) {
817           FIXME(" FOUND: EXT Texture LOD bias support\n");
818           This->gl_info.supported[EXT_TEXTURE_LOD_BIAS] = TRUE;
819         } else if (strcmp(ThisExtn, "GL_EXT_vertex_weighting") == 0) {
820           FIXME(" FOUND: EXT Vertex weighting support\n");
821           This->gl_info.supported[EXT_VERTEX_WEIGHTING] = TRUE;
822
823         /**
824          * NVIDIA 
825          */
826         } else if (strstr(ThisExtn, "GL_NV_fragment_program")) {
827           This->gl_info.ps_nv_version = PS_VERSION_11;
828           FIXME(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", This->gl_info.ps_nv_version);
829           This->gl_info.supported[NV_FRAGMENT_PROGRAM] = TRUE;
830         } else if (strstr(ThisExtn, "GL_NV_vertex_program")) {
831           This->gl_info.vs_nv_version = max(This->gl_info.vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program1_1")) ? VS_VERSION_11 : VS_VERSION_10);
832           This->gl_info.vs_nv_version = max(This->gl_info.vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program2"))   ? VS_VERSION_20 : VS_VERSION_10);
833           FIXME(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", This->gl_info.vs_nv_version);
834           This->gl_info.supported[NV_VERTEX_PROGRAM] = TRUE;
835
836         /**
837          * ATI
838          */
839         /** TODO */
840         } else if (strcmp(ThisExtn, "GL_EXT_vertex_shader") == 0) {
841           This->gl_info.vs_ati_version = VS_VERSION_11;
842           FIXME(" FOUND: ATI (EXT) Vertex Shader support - version=%02x\n", This->gl_info.vs_ati_version);
843           This->gl_info.supported[EXT_VERTEX_SHADER] = TRUE;
844         }
845
846
847         if (*GL_Extensions == ' ') GL_Extensions++;
848       }
849     }
850
851 #define USE_GL_FUNC(type, pfn) This->gl_info.pfn = (type) glXGetProcAddressARB(#pfn);
852     GL_EXT_FUNCS_GEN;
853 #undef USE_GL_FUNC
854
855     if (display != NULL) {
856         GLX_Extensions = glXQueryExtensionsString(display, DefaultScreen(display));
857         FIXME("GLX_Extensions reported:\n");  
858     
859         if (NULL == GLX_Extensions) {
860           ERR("   GLX_Extensions returns NULL\n");      
861         } else {
862           while (*GLX_Extensions != 0x00) {
863             const char *Start = GLX_Extensions;
864             char ThisExtn[256];
865            
866             memset(ThisExtn, 0x00, sizeof(ThisExtn));
867             while (*GLX_Extensions != ' ' && *GLX_Extensions != 0x00) {
868               GLX_Extensions++;
869             }
870             memcpy(ThisExtn, Start, (GLX_Extensions - Start));
871             FIXME("- %s\n", ThisExtn);
872             if (*GLX_Extensions == ' ') GLX_Extensions++;
873           }
874         }
875     }
876
877 #define USE_GL_FUNC(type, pfn) This->gl_info.pfn = (type) glXGetProcAddressARB(#pfn);
878     GLX_EXT_FUNCS_GEN;
879 #undef USE_GL_FUNC
880
881     /* Only save the values obtained when a display is provided */
882     if (display != NULL) This->isGLInfoValid = TRUE;
883
884 }
885
886 HRESULT  WINAPI  IDirect3D8Impl_CreateDevice               (LPDIRECT3D8 iface,
887                                                             UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
888                                                             DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
889                                                             IDirect3DDevice8** ppReturnedDeviceInterface) {
890     IDirect3DDevice8Impl *object;
891     HWND whichHWND;
892     int num;
893     XVisualInfo template;
894     HDC hDc;
895
896     ICOM_THIS(IDirect3D8Impl,iface);
897     TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %lx, PresParms: %p, RetDevInt: %p)\n", This, Adapter, DeviceType,
898           hFocusWindow, BehaviourFlags, pPresentationParameters, ppReturnedDeviceInterface);
899
900     /* Allocate the storage for the device */
901     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDevice8Impl));
902     if (NULL == object) {
903       return D3DERR_OUTOFVIDEOMEMORY;
904     }
905     object->lpVtbl = &Direct3DDevice8_Vtbl;
906     object->ref = 1;
907     object->direct3d8 = This;
908     /** The device AddRef the direct3d8 Interface else crash in propers clients codes */
909     IDirect3D8_AddRef((LPDIRECT3D8) object->direct3d8);
910
911     /** use StateBlock Factory here, for creating the startup stateBlock */
912     object->StateBlock = NULL;
913     IDirect3DDeviceImpl_CreateStateBlock(object, D3DSBT_ALL, NULL);
914     object->UpdateStateBlock = object->StateBlock;
915
916     /* Save the creation parameters */
917     object->CreateParms.AdapterOrdinal = Adapter;
918     object->CreateParms.DeviceType = DeviceType;
919     object->CreateParms.hFocusWindow = hFocusWindow;
920     object->CreateParms.BehaviorFlags = BehaviourFlags;
921
922     *ppReturnedDeviceInterface = (LPDIRECT3DDEVICE8) object;
923
924     /* Initialize settings */
925     object->PresentParms.BackBufferCount = 1; /* Opengl only supports one? */
926     object->adapterNo = Adapter;
927     object->devType = DeviceType;
928
929     /* Initialize openGl - Note the visual is chosen as the window is created and the glcontext cannot
930          use different properties after that point in time. FIXME: How to handle when requested format 
931          doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
932          it chooses is identical to the one already being used!                                        */
933     /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */
934
935     /* Which hwnd are we using? */
936     whichHWND = pPresentationParameters->hDeviceWindow;
937     if (!whichHWND) {
938         whichHWND = hFocusWindow;
939     }
940     object->win_handle = whichHWND;
941     object->win     = (Window)GetPropA( whichHWND, "__wine_x11_client_window" );
942
943     hDc = GetDC(whichHWND);
944     object->display = get_display(hDc);
945
946     TRACE("(%p)->(DepthStencil:(%u,%s), BackBufferFormat:(%u,%s))\n", This, 
947           pPresentationParameters->AutoDepthStencilFormat, debug_d3dformat(pPresentationParameters->AutoDepthStencilFormat),
948           pPresentationParameters->BackBufferFormat, debug_d3dformat(pPresentationParameters->BackBufferFormat));
949
950     ENTER_GL();
951
952     /* Create a context based off the properties of the existing visual */
953     template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
954     object->visInfo = XGetVisualInfo(object->display, VisualIDMask, &template, &num);
955     if (NULL == object->visInfo) {
956         ERR("cannot really get XVisual\n"); 
957         LEAVE_GL();
958         return D3DERR_NOTAVAILABLE;
959      }
960     object->glCtx = glXCreateContext(object->display, object->visInfo, NULL, GL_TRUE);
961     if (NULL == object->glCtx) {
962       ERR("cannot create glxContext\n"); 
963       LEAVE_GL();
964       return D3DERR_NOTAVAILABLE;
965      }
966     LEAVE_GL();
967
968     ReleaseDC(whichHWND, hDc);
969     
970     if (object->glCtx == NULL) {
971         ERR("Error in context creation !\n");
972         return D3DERR_INVALIDCALL;
973     } else {
974         TRACE("Context created (HWND=%p, glContext=%p, Window=%ld, VisInfo=%p)\n",
975               whichHWND, object->glCtx, object->win, object->visInfo);
976     }
977
978     /* If not windowed, need to go fullscreen, and resize the HWND to the appropriate  */
979     /*        dimensions                                                               */
980     if (!pPresentationParameters->Windowed) {
981 #if 1
982         DEVMODEW devmode;
983         HDC hdc;
984         int bpp = 0;
985         memset(&devmode, 0, sizeof(DEVMODEW));
986         devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 
987         MultiByteToWideChar(CP_ACP, 0, "Gamers CG", -1, devmode.dmDeviceName, CCHDEVICENAME);
988         hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
989         bpp = GetDeviceCaps(hdc, BITSPIXEL);
990         DeleteDC(hdc);
991         devmode.dmBitsPerPel = (bpp >= 24) ? 32 : bpp;/*Stupid XVidMode cannot change bpp D3DFmtGetBpp(object, pPresentationParameters->BackBufferFormat);*/
992         devmode.dmPelsWidth  = pPresentationParameters->BackBufferWidth;
993         devmode.dmPelsHeight = pPresentationParameters->BackBufferHeight;
994         ChangeDisplaySettingsExW(devmode.dmDeviceName, &devmode, object->win_handle, CDS_FULLSCREEN, NULL);
995 #else
996         FIXME("Requested full screen support not implemented, expect windowed operation\n");
997 #endif
998
999         /* Make popup window */
1000         ShowWindow(whichHWND, SW_HIDE);
1001         SetWindowLongA(whichHWND, GWL_STYLE, WS_POPUP);
1002         SetWindowPos(object->win_handle, HWND_TOP, 0, 0, 
1003                      pPresentationParameters->BackBufferWidth,
1004                      pPresentationParameters->BackBufferHeight, SWP_SHOWWINDOW | SWP_FRAMECHANGED);
1005         ShowWindow(whichHWND, SW_SHOW);
1006     }
1007
1008     TRACE("Creating back buffer\n");
1009     /* MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
1010        then the corresponding dimension of the client area of the hDeviceWindow
1011        (or the focus window, if hDeviceWindow is NULL) is taken. */
1012     if (pPresentationParameters->Windowed && ((pPresentationParameters->BackBufferWidth  == 0) ||
1013                                               (pPresentationParameters->BackBufferHeight == 0))) {
1014         RECT Rect;
1015
1016         GetClientRect(whichHWND, &Rect);
1017
1018         if (pPresentationParameters->BackBufferWidth == 0) {
1019            pPresentationParameters->BackBufferWidth = Rect.right;
1020            TRACE("Updating width to %d\n", pPresentationParameters->BackBufferWidth);
1021         }
1022         if (pPresentationParameters->BackBufferHeight == 0) {
1023            pPresentationParameters->BackBufferHeight = Rect.bottom;
1024            TRACE("Updating height to %d\n", pPresentationParameters->BackBufferHeight);
1025         }
1026     }
1027
1028     /* Save the presentation parms now filled in correctly */
1029     memcpy(&object->PresentParms, pPresentationParameters, sizeof(D3DPRESENT_PARAMETERS));
1030
1031
1032     IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object,
1033                                             pPresentationParameters->BackBufferWidth,
1034                                             pPresentationParameters->BackBufferHeight,
1035                                             pPresentationParameters->BackBufferFormat,
1036                                             pPresentationParameters->MultiSampleType,
1037                                             TRUE,
1038                                             (LPDIRECT3DSURFACE8*) &object->frontBuffer);
1039
1040     IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object,
1041                                             pPresentationParameters->BackBufferWidth,
1042                                             pPresentationParameters->BackBufferHeight,
1043                                             pPresentationParameters->BackBufferFormat,
1044                                             pPresentationParameters->MultiSampleType,
1045                                             TRUE,
1046                                             (LPDIRECT3DSURFACE8*) &object->backBuffer);
1047
1048     if (pPresentationParameters->EnableAutoDepthStencil) {
1049        IDirect3DDevice8Impl_CreateDepthStencilSurface((LPDIRECT3DDEVICE8) object,
1050                                                       pPresentationParameters->BackBufferWidth,
1051                                                       pPresentationParameters->BackBufferHeight,
1052                                                       pPresentationParameters->AutoDepthStencilFormat,
1053                                                       D3DMULTISAMPLE_NONE,
1054                                                       (LPDIRECT3DSURFACE8*) &object->depthStencilBuffer);
1055     } else {
1056       object->depthStencilBuffer = NULL;
1057     }
1058     TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil @ %p\n",object->frontBuffer, object->backBuffer, object->depthStencilBuffer);
1059
1060     /* init the default renderTarget management */
1061     object->drawable = object->win;
1062     object->render_ctx = object->glCtx;
1063     object->renderTarget = object->frontBuffer;
1064     IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->renderTarget);
1065     object->stencilBufferTarget = object->depthStencilBuffer;
1066     if (NULL != object->stencilBufferTarget) {
1067       IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->stencilBufferTarget);
1068     }
1069
1070     ENTER_GL();
1071
1072     if (glXMakeCurrent(object->display, object->win, object->glCtx) == False) {
1073       ERR("Error in setting current context (context %p drawable %ld)!\n", object->glCtx, object->win);
1074     }
1075     checkGLcall("glXMakeCurrent");
1076
1077     /* Clear the screen */
1078     glClearColor(1.0, 0.0, 0.0, 0.0);
1079     checkGLcall("glClearColor");
1080     glColor3f(1.0, 1.0, 1.0);
1081     checkGLcall("glColor3f");
1082
1083     glEnable(GL_LIGHTING);
1084     checkGLcall("glEnable");
1085
1086     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1087     checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
1088
1089     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
1090     checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
1091
1092     glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1093     checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
1094
1095     /* 
1096      * Initialize openGL extension related variables
1097      *  with Default values 
1098      */
1099     IDirect3D8Impl_FillGLCaps(iface, object->display);
1100
1101     /* Setup all the devices defaults */
1102     IDirect3DDeviceImpl_InitStartupStateBlock(object);
1103
1104     LEAVE_GL();
1105
1106     { /* Set a default viewport */
1107        D3DVIEWPORT8 vp;
1108        vp.X      = 0;
1109        vp.Y      = 0;
1110        vp.Width  = pPresentationParameters->BackBufferWidth;
1111        vp.Height = pPresentationParameters->BackBufferHeight;
1112        vp.MinZ   = 0.0f;
1113        vp.MaxZ   = 1.0f;
1114        IDirect3DDevice8Impl_SetViewport((LPDIRECT3DDEVICE8) object, &vp);
1115     }
1116
1117     /* Initialize the current view state */
1118     object->modelview_valid = 1;
1119     object->proj_valid = 0;
1120     object->view_ident = 1;
1121     object->last_was_rhw = 0;
1122     glGetIntegerv(GL_MAX_LIGHTS, &object->maxConcurrentLights);
1123     TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This, Adapter, object);
1124     return D3D_OK;
1125 }
1126
1127 ICOM_VTABLE(IDirect3D8) Direct3D8_Vtbl =
1128 {
1129     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1130     IDirect3D8Impl_QueryInterface,
1131     IDirect3D8Impl_AddRef,
1132     IDirect3D8Impl_Release,
1133     IDirect3D8Impl_RegisterSoftwareDevice,
1134     IDirect3D8Impl_GetAdapterCount,
1135     IDirect3D8Impl_GetAdapterIdentifier,
1136     IDirect3D8Impl_GetAdapterModeCount,
1137     IDirect3D8Impl_EnumAdapterModes,
1138     IDirect3D8Impl_GetAdapterDisplayMode,
1139     IDirect3D8Impl_CheckDeviceType,
1140     IDirect3D8Impl_CheckDeviceFormat,
1141     IDirect3D8Impl_CheckDeviceMultiSampleType,
1142     IDirect3D8Impl_CheckDepthStencilMatch,
1143     IDirect3D8Impl_GetDeviceCaps,
1144     IDirect3D8Impl_GetAdapterMonitor,
1145     IDirect3D8Impl_CreateDevice
1146 };