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