Started implementing support for the SubSystemTib field in the TEB of
[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_add") == 0) {
773           FIXME(" FOUND: ARB Texture Env Add support\n");
774           This->gl_info.supported[ARB_TEXTURE_ENV_ADD] = TRUE;
775         } else if (strcmp(ThisExtn, "GL_ARB_texture_env_combine") == 0) {
776           FIXME(" FOUND: ARB Texture Env combine support\n");
777           This->gl_info.supported[ARB_TEXTURE_ENV_COMBINE] = TRUE;
778         } else if (strcmp(ThisExtn, "GL_ARB_texture_env_dot3") == 0) {
779           FIXME(" FOUND: ARB Dot3 support\n");
780           This->gl_info.supported[ARB_TEXTURE_ENV_DOT3] = TRUE;
781         } else if (strcmp(ThisExtn, "GL_ARB_texture_border_clamp") == 0) {
782           FIXME(" FOUND: ARB Texture border clamp support\n");
783           This->gl_info.supported[ARB_TEXTURE_BORDER_CLAMP] = TRUE;
784         } else if (strstr(ThisExtn, "GL_ARB_vertex_program")) {
785           This->gl_info.vs_arb_version = VS_VERSION_11;
786           FIXME(" FOUND: ARB Vertex Shader support - version=%02x\n", This->gl_info.vs_arb_version);
787           This->gl_info.supported[ARB_VERTEX_PROGRAM] = TRUE;
788
789         /**
790          * EXT
791          */
792         } else if (strcmp(ThisExtn, "GL_EXT_fog_coord") == 0) {
793           FIXME(" FOUND: EXT Fog coord support\n");
794           This->gl_info.supported[EXT_FOG_COORD] = TRUE;
795         } else if (strcmp(ThisExtn, "GL_EXT_paletted_texture") == 0) { /* handle paletted texture extensions */
796           FIXME(" FOUND: EXT Paletted texture support\n");
797           This->gl_info.supported[EXT_PALETTED_TEXTURE] = TRUE;
798         } else if (strcmp(ThisExtn, "GL_EXT_point_parameters") == 0) {
799           FIXME(" FOUND: EXT Point parameters support\n");
800           This->gl_info.supported[EXT_POINT_PARAMETERS] = TRUE;
801         } else if (strcmp(ThisExtn, "GL_EXT_secondary_color") == 0) {
802           FIXME(" FOUND: EXT Secondary coord support\n");
803           This->gl_info.supported[EXT_SECONDARY_COLOR] = TRUE;
804 #if defined(GL_EXT_texture_compression_s3tc)
805         } else if (strcmp(ThisExtn, "GL_EXT_texture_compression_s3tc") == 0) {
806           FIXME(" FOUND: EXT Texture S3TC compression support\n");
807           This->gl_info.supported[EXT_TEXTURE_COMPRESSION_S3TC] = TRUE;
808 #endif
809         } else if (strcmp(ThisExtn, "GL_EXT_texture_env_add") == 0) {
810           FIXME(" FOUND: EXT Texture Env Add support\n");
811           This->gl_info.supported[EXT_TEXTURE_ENV_ADD] = TRUE;
812         } else if (strcmp(ThisExtn, "GL_EXT_texture_env_combine") == 0) {
813           FIXME(" FOUND: EXT Texture Env combine support\n");
814           This->gl_info.supported[EXT_TEXTURE_ENV_COMBINE] = TRUE;
815         } else if (strcmp(ThisExtn, "GL_EXT_texture_env_dot3") == 0) {
816           FIXME(" FOUND: EXT Dot3 support\n");
817           This->gl_info.supported[EXT_TEXTURE_ENV_DOT3] = TRUE;
818         } else if (strcmp(ThisExtn, "GL_EXT_texture_filter_anisotropic") == 0) {
819           FIXME(" FOUND: EXT Texture Anisotropic filter support\n");
820           This->gl_info.supported[EXT_TEXTURE_FILTER_ANISOTROPIC] = TRUE;
821         } else if (strcmp(ThisExtn, "GL_EXT_texture_lod") == 0) {
822           FIXME(" FOUND: EXT Texture LOD support\n");
823           This->gl_info.supported[EXT_TEXTURE_LOD] = TRUE;
824         } else if (strcmp(ThisExtn, "GL_EXT_texture_lod_bias") == 0) {
825           FIXME(" FOUND: EXT Texture LOD bias support\n");
826           This->gl_info.supported[EXT_TEXTURE_LOD_BIAS] = TRUE;
827         } else if (strcmp(ThisExtn, "GL_EXT_vertex_weighting") == 0) {
828           FIXME(" FOUND: EXT Vertex weighting support\n");
829           This->gl_info.supported[EXT_VERTEX_WEIGHTING] = TRUE;
830
831         /**
832          * NVIDIA 
833          */
834         } else if (strcmp(ThisExtn, "GL_NV_texture_env_combine4") == 0) {
835           FIXME(" FOUND: NVIDIA (NV) Texture Env combine (4) support\n");
836           This->gl_info.supported[NV_TEXTURE_ENV_COMBINE4] = TRUE;
837         } else if (strstr(ThisExtn, "GL_NV_fragment_program")) {
838           This->gl_info.ps_nv_version = PS_VERSION_11;
839           FIXME(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", This->gl_info.ps_nv_version);
840           This->gl_info.supported[NV_FRAGMENT_PROGRAM] = TRUE;
841         } else if (strstr(ThisExtn, "GL_NV_vertex_program")) {
842           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);
843           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);
844           FIXME(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", This->gl_info.vs_nv_version);
845           This->gl_info.supported[NV_VERTEX_PROGRAM] = TRUE;
846
847         /**
848          * ATI
849          */
850         /** TODO */
851         } else if (strcmp(ThisExtn, "GL_ATI_texture_env_combine3") == 0) {
852           FIXME(" FOUND: ATI Texture Env combine (3) support\n");
853           This->gl_info.supported[ATI_TEXTURE_ENV_COMBINE3] = TRUE;
854         } else if (strcmp(ThisExtn, "GL_ATI_texture_mirror_once") == 0) {
855           FIXME(" FOUND: ATI Texture Mirror Once support\n");
856           This->gl_info.supported[ATI_TEXTURE_MIRROR_ONCE] = TRUE;
857         } else if (strcmp(ThisExtn, "GL_EXT_vertex_shader") == 0) {
858           This->gl_info.vs_ati_version = VS_VERSION_11;
859           FIXME(" FOUND: ATI (EXT) Vertex Shader support - version=%02x\n", This->gl_info.vs_ati_version);
860           This->gl_info.supported[EXT_VERTEX_SHADER] = TRUE;
861         }
862
863
864         if (*GL_Extensions == ' ') GL_Extensions++;
865       }
866     }
867
868 #define USE_GL_FUNC(type, pfn) This->gl_info.pfn = (type) glXGetProcAddressARB(#pfn);
869     GL_EXT_FUNCS_GEN;
870 #undef USE_GL_FUNC
871
872     if (display != NULL) {
873         GLX_Extensions = glXQueryExtensionsString(display, DefaultScreen(display));
874         FIXME("GLX_Extensions reported:\n");  
875     
876         if (NULL == GLX_Extensions) {
877           ERR("   GLX_Extensions returns NULL\n");      
878         } else {
879           while (*GLX_Extensions != 0x00) {
880             const char *Start = GLX_Extensions;
881             char ThisExtn[256];
882            
883             memset(ThisExtn, 0x00, sizeof(ThisExtn));
884             while (*GLX_Extensions != ' ' && *GLX_Extensions != 0x00) {
885               GLX_Extensions++;
886             }
887             memcpy(ThisExtn, Start, (GLX_Extensions - Start));
888             FIXME("- %s\n", ThisExtn);
889             if (*GLX_Extensions == ' ') GLX_Extensions++;
890           }
891         }
892     }
893
894 #define USE_GL_FUNC(type, pfn) This->gl_info.pfn = (type) glXGetProcAddressARB(#pfn);
895     GLX_EXT_FUNCS_GEN;
896 #undef USE_GL_FUNC
897
898     /* Only save the values obtained when a display is provided */
899     if (display != NULL) This->isGLInfoValid = TRUE;
900
901 }
902
903 HRESULT  WINAPI  IDirect3D8Impl_CreateDevice               (LPDIRECT3D8 iface,
904                                                             UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
905                                                             DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
906                                                             IDirect3DDevice8** ppReturnedDeviceInterface) {
907     IDirect3DDevice8Impl *object;
908     HWND whichHWND;
909     int num;
910     XVisualInfo template;
911     HDC hDc;
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 - Note the visual is chosen as the window is created and the glcontext cannot
947          use different properties after that point in time. FIXME: How to handle when requested format 
948          doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
949          it chooses is identical to the one already being used!                                        */
950     /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */
951
952     /* Which hwnd are we using? */
953     whichHWND = pPresentationParameters->hDeviceWindow;
954     if (!whichHWND) {
955         whichHWND = hFocusWindow;
956     }
957     object->win_handle = whichHWND;
958     object->win     = (Window)GetPropA( whichHWND, "__wine_x11_client_window" );
959
960     hDc = GetDC(whichHWND);
961     object->display = get_display(hDc);
962
963     TRACE("(%p)->(DepthStencil:(%u,%s), BackBufferFormat:(%u,%s))\n", This, 
964           pPresentationParameters->AutoDepthStencilFormat, debug_d3dformat(pPresentationParameters->AutoDepthStencilFormat),
965           pPresentationParameters->BackBufferFormat, debug_d3dformat(pPresentationParameters->BackBufferFormat));
966
967     ENTER_GL();
968
969     /* Create a context based off the properties of the existing visual */
970     template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
971     object->visInfo = XGetVisualInfo(object->display, VisualIDMask, &template, &num);
972     if (NULL == object->visInfo) {
973         ERR("cannot really get XVisual\n"); 
974         LEAVE_GL();
975         return D3DERR_NOTAVAILABLE;
976      }
977     object->glCtx = glXCreateContext(object->display, object->visInfo, NULL, GL_TRUE);
978     if (NULL == object->glCtx) {
979       ERR("cannot create glxContext\n"); 
980       LEAVE_GL();
981       return D3DERR_NOTAVAILABLE;
982      }
983     LEAVE_GL();
984
985     ReleaseDC(whichHWND, hDc);
986     
987     if (object->glCtx == NULL) {
988         ERR("Error in context creation !\n");
989         return D3DERR_INVALIDCALL;
990     } else {
991         TRACE("Context created (HWND=%p, glContext=%p, Window=%ld, VisInfo=%p)\n",
992               whichHWND, object->glCtx, object->win, object->visInfo);
993     }
994
995     /* If not windowed, need to go fullscreen, and resize the HWND to the appropriate  */
996     /*        dimensions                                                               */
997     if (!pPresentationParameters->Windowed) {
998 #if 1
999         DEVMODEW devmode;
1000         HDC hdc;
1001         int bpp = 0;
1002         memset(&devmode, 0, sizeof(DEVMODEW));
1003         devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 
1004         MultiByteToWideChar(CP_ACP, 0, "Gamers CG", -1, devmode.dmDeviceName, CCHDEVICENAME);
1005         hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
1006         bpp = GetDeviceCaps(hdc, BITSPIXEL);
1007         DeleteDC(hdc);
1008         devmode.dmBitsPerPel = (bpp >= 24) ? 32 : bpp;/*Stupid XVidMode cannot change bpp D3DFmtGetBpp(object, pPresentationParameters->BackBufferFormat);*/
1009         devmode.dmPelsWidth  = pPresentationParameters->BackBufferWidth;
1010         devmode.dmPelsHeight = pPresentationParameters->BackBufferHeight;
1011         ChangeDisplaySettingsExW(devmode.dmDeviceName, &devmode, object->win_handle, CDS_FULLSCREEN, NULL);
1012 #else
1013         FIXME("Requested full screen support not implemented, expect windowed operation\n");
1014 #endif
1015
1016         /* Make popup window */
1017         ShowWindow(whichHWND, SW_HIDE);
1018         SetWindowLongA(whichHWND, GWL_STYLE, WS_POPUP);
1019         SetWindowPos(object->win_handle, HWND_TOP, 0, 0, 
1020                      pPresentationParameters->BackBufferWidth,
1021                      pPresentationParameters->BackBufferHeight, SWP_SHOWWINDOW | SWP_FRAMECHANGED);
1022         ShowWindow(whichHWND, SW_SHOW);
1023     }
1024
1025     TRACE("Creating back buffer\n");
1026     /* MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
1027        then the corresponding dimension of the client area of the hDeviceWindow
1028        (or the focus window, if hDeviceWindow is NULL) is taken. */
1029     if (pPresentationParameters->Windowed && ((pPresentationParameters->BackBufferWidth  == 0) ||
1030                                               (pPresentationParameters->BackBufferHeight == 0))) {
1031         RECT Rect;
1032
1033         GetClientRect(whichHWND, &Rect);
1034
1035         if (pPresentationParameters->BackBufferWidth == 0) {
1036            pPresentationParameters->BackBufferWidth = Rect.right;
1037            TRACE("Updating width to %d\n", pPresentationParameters->BackBufferWidth);
1038         }
1039         if (pPresentationParameters->BackBufferHeight == 0) {
1040            pPresentationParameters->BackBufferHeight = Rect.bottom;
1041            TRACE("Updating height to %d\n", pPresentationParameters->BackBufferHeight);
1042         }
1043     }
1044
1045     /* Save the presentation parms now filled in correctly */
1046     memcpy(&object->PresentParms, pPresentationParameters, sizeof(D3DPRESENT_PARAMETERS));
1047
1048
1049     IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object,
1050                                             pPresentationParameters->BackBufferWidth,
1051                                             pPresentationParameters->BackBufferHeight,
1052                                             pPresentationParameters->BackBufferFormat,
1053                                             pPresentationParameters->MultiSampleType,
1054                                             TRUE,
1055                                             (LPDIRECT3DSURFACE8*) &object->frontBuffer);
1056
1057     IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object,
1058                                             pPresentationParameters->BackBufferWidth,
1059                                             pPresentationParameters->BackBufferHeight,
1060                                             pPresentationParameters->BackBufferFormat,
1061                                             pPresentationParameters->MultiSampleType,
1062                                             TRUE,
1063                                             (LPDIRECT3DSURFACE8*) &object->backBuffer);
1064
1065     if (pPresentationParameters->EnableAutoDepthStencil) {
1066        IDirect3DDevice8Impl_CreateDepthStencilSurface((LPDIRECT3DDEVICE8) object,
1067                                                       pPresentationParameters->BackBufferWidth,
1068                                                       pPresentationParameters->BackBufferHeight,
1069                                                       pPresentationParameters->AutoDepthStencilFormat,
1070                                                       D3DMULTISAMPLE_NONE,
1071                                                       (LPDIRECT3DSURFACE8*) &object->depthStencilBuffer);
1072     } else {
1073       object->depthStencilBuffer = NULL;
1074     }
1075     TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil @ %p\n",object->frontBuffer, object->backBuffer, object->depthStencilBuffer);
1076
1077     /* init the default renderTarget management */
1078     object->drawable = object->win;
1079     object->render_ctx = object->glCtx;
1080     object->renderTarget = object->frontBuffer;
1081     IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->renderTarget);
1082     object->stencilBufferTarget = object->depthStencilBuffer;
1083     if (NULL != object->stencilBufferTarget) {
1084       IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->stencilBufferTarget);
1085     }
1086
1087     ENTER_GL();
1088
1089     if (glXMakeCurrent(object->display, object->win, object->glCtx) == False) {
1090       ERR("Error in setting current context (context %p drawable %ld)!\n", object->glCtx, object->win);
1091     }
1092     checkGLcall("glXMakeCurrent");
1093
1094     /* Clear the screen */
1095     glClearColor(1.0, 0.0, 0.0, 0.0);
1096     checkGLcall("glClearColor");
1097     glColor3f(1.0, 1.0, 1.0);
1098     checkGLcall("glColor3f");
1099
1100     glEnable(GL_LIGHTING);
1101     checkGLcall("glEnable");
1102
1103     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1104     checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
1105
1106     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
1107     checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
1108
1109     glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1110     checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
1111
1112     /* 
1113      * Initialize openGL extension related variables
1114      *  with Default values 
1115      */
1116     IDirect3D8Impl_FillGLCaps(iface, object->display);
1117
1118     /* Setup all the devices defaults */
1119     IDirect3DDeviceImpl_InitStartupStateBlock(object);
1120
1121     LEAVE_GL();
1122
1123     { /* Set a default viewport */
1124        D3DVIEWPORT8 vp;
1125        vp.X      = 0;
1126        vp.Y      = 0;
1127        vp.Width  = pPresentationParameters->BackBufferWidth;
1128        vp.Height = pPresentationParameters->BackBufferHeight;
1129        vp.MinZ   = 0.0f;
1130        vp.MaxZ   = 1.0f;
1131        IDirect3DDevice8Impl_SetViewport((LPDIRECT3DDEVICE8) object, &vp);
1132     }
1133
1134     /* Initialize the current view state */
1135     object->modelview_valid = 1;
1136     object->proj_valid = 0;
1137     object->view_ident = 1;
1138     object->last_was_rhw = 0;
1139     glGetIntegerv(GL_MAX_LIGHTS, &object->maxConcurrentLights);
1140     TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This, Adapter, object);
1141     return D3D_OK;
1142 }
1143
1144 ICOM_VTABLE(IDirect3D8) Direct3D8_Vtbl =
1145 {
1146     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1147     IDirect3D8Impl_QueryInterface,
1148     IDirect3D8Impl_AddRef,
1149     IDirect3D8Impl_Release,
1150     IDirect3D8Impl_RegisterSoftwareDevice,
1151     IDirect3D8Impl_GetAdapterCount,
1152     IDirect3D8Impl_GetAdapterIdentifier,
1153     IDirect3D8Impl_GetAdapterModeCount,
1154     IDirect3D8Impl_EnumAdapterModes,
1155     IDirect3D8Impl_GetAdapterDisplayMode,
1156     IDirect3D8Impl_CheckDeviceType,
1157     IDirect3D8Impl_CheckDeviceFormat,
1158     IDirect3D8Impl_CheckDeviceMultiSampleType,
1159     IDirect3D8Impl_CheckDepthStencilMatch,
1160     IDirect3D8Impl_GetDeviceCaps,
1161     IDirect3D8Impl_GetAdapterMonitor,
1162     IDirect3D8Impl_CreateDevice
1163 };