Removed some unnecessary #includes and dll dependencies.
[wine/multimedia.git] / dlls / ddraw / ddraw / dga.c
blob686d1019486d6d49e366ae72c1952d7bf5c0d94f
1 /* DirectDraw IDirectDraw XF86DGA interface
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
5 */
6 /* XF86DGA:
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
10 * is running.
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
18 * This file contains the XF86 DGA specific interface functions.
19 * We are 'allowed' to call X11 specific IDirectDraw functions.
22 #include "config.h"
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <assert.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <stdlib.h>
31 #include "winerror.h"
32 #include "wine/exception.h"
33 #include "ddraw.h"
34 #include "d3d.h"
35 #include "debugtools.h"
36 #include "options.h"
38 #define RESTORE_SIGNALS
40 DEFAULT_DEBUG_CHANNEL(ddraw);
42 #include "dga_private.h"
44 struct ICOM_VTABLE(IDirectDraw) dga_ddvt;
45 struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt;
46 struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt;
48 #ifdef HAVE_LIBXXF86VM
49 static XF86VidModeModeInfo *orig_mode = NULL;
50 #endif
52 #define DDPRIVATE(x) dga_dd_private *ddpriv = ((dga_dd_private*)(x)->d->private)
53 #define DPPRIVATE(x) dga_dp_private *dppriv = ((dga_dp_private*)(x)->private)
55 /*******************************************************************************
56 * IDirectDraw
59 /* This function is used both by DGA and DGA2 drivers, thus the virtual function table
60 is not set here, but in the calling function */
61 HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface_with_VT(
62 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,
63 IUnknown *lpunk, void *vtable
64 ) {
65 ICOM_THIS(IDirectDraw2Impl,iface);
66 IDirectDrawSurfaceImpl* dsurf;
67 DDPRIVATE(This);
68 dga_ds_private *dspriv;
69 int i, fbheight = ddpriv->fb_height;
71 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,lpdsf,lpunk);
72 if (TRACE_ON(ddraw)) _dump_surface_desc(lpddsd);
74 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(
75 GetProcessHeap(),
76 HEAP_ZERO_MEMORY,
77 sizeof(IDirectDrawSurfaceImpl)
79 dsurf = *(IDirectDrawSurfaceImpl**)lpdsf;
80 dsurf->private = (dga_ds_private*)HeapAlloc(
81 GetProcessHeap(),
82 HEAP_ZERO_MEMORY,
83 sizeof(dga_ds_private)
85 ICOM_VTBL(dsurf) = (ICOM_VTABLE(IDirectDrawSurface)*)vtable;
87 dspriv = (dga_ds_private*)dsurf->private;
88 IDirectDraw2_AddRef(iface);
90 dsurf->ref = 1;
91 dsurf->s.ddraw = This;
92 dsurf->s.palette = NULL;
93 dspriv->fb_height = -1; /* This is to have non-on screen surfaces freed */
94 dsurf->s.lpClipper = NULL;
96 /* Copy the surface description */
97 dsurf->s.surface_desc = *lpddsd;
99 if (!(lpddsd->dwFlags & DDSD_WIDTH))
100 dsurf->s.surface_desc.dwWidth = This->d->width;
101 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
102 dsurf->s.surface_desc.dwHeight = This->d->height;
104 dsurf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
106 /* Check if this a 'primary surface' or not */
107 if ((lpddsd->dwFlags & DDSD_CAPS) &&
108 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
109 /* This is THE primary surface => there is DGA-specific code */
111 /* Find a viewport */
112 for (i=0;i<32;i++)
113 if (!(ddpriv->vpmask & (1<<i)))
114 break;
115 TRACE("using viewport %d for a primary surface\n",i);
116 /* if i == 32 or maximum ... return error */
117 ddpriv->vpmask|=(1<<i);
118 lpddsd->lPitch = dsurf->s.surface_desc.lPitch =
119 ddpriv->fb_width*PFGET_BPP(This->d->directdraw_pixelformat);
121 dsurf->s.surface_desc.u1.lpSurface =
122 ddpriv->fb_addr + i*fbheight*lpddsd->lPitch;
124 dspriv->fb_height = i*fbheight;
126 /* Add flags if there were not present */
127 dsurf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
128 dsurf->s.surface_desc.dwWidth = This->d->width;
129 dsurf->s.surface_desc.dwHeight = This->d->height;
130 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d->width,This->d->height,lpddsd->lPitch);
131 /* We put our surface always in video memory */
132 SDDSCAPS(dsurf) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
133 dsurf->s.surface_desc.ddpfPixelFormat = This->d->directdraw_pixelformat;
134 dsurf->s.chain = NULL;
136 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
137 IDirectDrawSurface4Impl* back;
138 dga_ds_private *bspriv;
139 int bbc;
141 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
142 int i;
144 back = (IDirectDrawSurface4Impl*)HeapAlloc(
145 GetProcessHeap(),
146 HEAP_ZERO_MEMORY,
147 sizeof(IDirectDrawSurface4Impl)
149 IDirectDraw2_AddRef(iface);
150 back->ref = 1;
151 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)vtable;
152 back->private = HeapAlloc(
153 GetProcessHeap(),
154 HEAP_ZERO_MEMORY,
155 sizeof(dga_ds_private)
157 bspriv = (dga_ds_private*)back->private;
159 for (i=0;i<32;i++)
160 if (!(ddpriv->vpmask & (1<<i)))
161 break;
162 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
163 /* if i == 32 or maximum ... return error */
164 ddpriv->vpmask|=(1<<i);
166 bspriv->fb_height = i*fbheight;
167 /* Copy the surface description from the front buffer */
168 back->s.surface_desc = dsurf->s.surface_desc;
169 /* Change the parameters that are not the same */
170 back->s.surface_desc.u1.lpSurface =
171 ddpriv->fb_addr + i*fbheight*lpddsd->lPitch;
173 back->s.ddraw = This;
174 /* Add relevant info to front and back buffers */
175 /* FIXME: backbuffer/frontbuffer handling broken here, but
176 * will be fixed up in _Flip().
178 SDDSCAPS(dsurf) |= DDSCAPS_FRONTBUFFER;
179 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
180 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
181 SDDSCAPS(back) &= ~(DDSCAPS_VISIBLE|DDSCAPS_PRIMARYSURFACE);
182 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*lpdsf),(LPDIRECTDRAWSURFACE4)back);
185 } else {
186 /* There is no DGA-specific code here...
187 * Go to the common surface creation function
189 return common_off_screen_CreateSurface(This, dsurf);
191 return DD_OK;
194 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
195 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,
196 IUnknown *lpunk
198 HRESULT ret;
200 ret = DGA_IDirectDraw2Impl_CreateSurface_with_VT(iface, lpddsd, lpdsf, lpunk, &dga_dds4vt);
202 return ret;
206 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
207 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
209 ICOM_THIS(IDirectDrawImpl,iface);
210 DDPRIVATE(This);
211 int i,mode_count;
213 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
215 /* We hope getting the asked for depth */
216 if ( _common_depth_to_pixelformat(depth,iface) != -1 ) {
217 /* I.e. no visual found or emulated */
218 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
219 return DDERR_UNSUPPORTEDMODE;
222 if (This->d->width < width) {
223 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d->width);
224 return DDERR_UNSUPPORTEDMODE;
226 This->d->width = width;
227 This->d->height = height;
229 /* adjust fb_height, so we don't overlap */
230 if (ddpriv->fb_height < height)
231 ddpriv->fb_height = height;
232 _common_IDirectDrawImpl_SetDisplayMode(This);
234 #ifdef HAVE_LIBXXF86VM
236 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
237 XF86VidModeModeLine mod_tmp;
238 /* int dotclock_tmp; */
240 /* save original video mode and set fullscreen if available*/
241 orig_mode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
242 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
243 orig_mode->hdisplay = mod_tmp.hdisplay;
244 orig_mode->hsyncstart = mod_tmp.hsyncstart;
245 orig_mode->hsyncend = mod_tmp.hsyncend;
246 orig_mode->htotal = mod_tmp.htotal;
247 orig_mode->vdisplay = mod_tmp.vdisplay;
248 orig_mode->vsyncstart = mod_tmp.vsyncstart;
249 orig_mode->vsyncend = mod_tmp.vsyncend;
250 orig_mode->vtotal = mod_tmp.vtotal;
251 orig_mode->flags = mod_tmp.flags;
252 orig_mode->private = mod_tmp.private;
254 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
255 for (i=0;i<mode_count;i++) {
256 if (all_modes[i]->hdisplay == width &&
257 all_modes[i]->vdisplay == height
259 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
260 *vidmode = *(all_modes[i]);
261 break;
262 } else
263 TSXFree(all_modes[i]->private);
265 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
266 TSXFree(all_modes);
268 if (!vidmode)
269 WARN("Fullscreen mode not available!\n");
271 if (vidmode) {
272 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
273 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
274 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
275 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
276 #endif
279 #endif
281 /* FIXME: this function OVERWRITES several signal handlers.
282 * can we save them? and restore them later? In a way that
283 * it works for the library too?
285 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
286 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
288 #ifdef RESTORE_SIGNALS
289 SIGNAL_Init();
290 #endif
291 return DD_OK;
294 HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
295 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
297 ICOM_THIS(IDirectDraw2Impl,iface);
298 DDPRIVATE(This);
300 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
301 if (!caps1 && !caps2)
302 return DDERR_INVALIDPARAMS;
303 if (caps1) {
304 caps1->dwVidMemTotal = ddpriv->fb_memsize;
305 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
306 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
308 if (caps2) {
309 caps2->dwVidMemTotal = ddpriv->fb_memsize;
310 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
311 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
313 return DD_OK;
316 #if 0 /* Not used as of now.... */
317 static void fill_caps(LPDDCAPS caps) {
318 /* This function tries to fill the capabilities of Wine's DDraw
319 * implementation. Needs to be fixed, though.. */
320 if (caps == NULL)
321 return;
323 caps->dwSize = sizeof(*caps);
324 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE /*| DDCAPS_NOHARDWARE*/;
325 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
326 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
327 caps->dwFXCaps = 0;
328 caps->dwFXAlphaCaps = 0;
329 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
330 caps->dwSVCaps = 0;
331 caps->dwZBufferBitDepths = DDBD_16;
332 /* I put here 8 Mo so that D3D applications will believe they have enough
333 * memory to put textures in video memory.
334 * BTW, is this only frame buffer memory or also texture memory (for Voodoo
335 * boards for example) ?
337 caps->dwVidMemTotal = 8192 * 1024;
338 caps->dwVidMemFree = 8192 * 1024;
339 /* These are all the supported capabilities of the surfaces */
340 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
341 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
342 /*DDSCAPS_OVERLAY |*/ DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
343 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
344 #ifdef HAVE_OPENGL
345 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
346 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
347 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
348 #endif
350 #endif
352 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
353 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
355 ICOM_THIS(IDirectDraw2Impl,iface);
356 IDirectDrawPaletteImpl* ddpal;
357 dga_dp_private *dppriv;
358 HRESULT res;
359 int xsize = 0,i;
361 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,lpddpal,lpunk);
362 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,(IDirectDrawPaletteImpl**)lpddpal,lpunk,&xsize);
363 if (res != 0)
364 return res;
365 ddpal = *(IDirectDrawPaletteImpl**)lpddpal;
366 ddpal->private = HeapAlloc(
367 GetProcessHeap(),
368 HEAP_ZERO_MEMORY,
369 sizeof(dga_dp_private)
371 dppriv = (dga_dp_private*)ddpal->private;
373 ICOM_VTBL(ddpal)= &dga_ddpalvt;
374 if (This->d->directdraw_pixelformat.u.dwRGBBitCount<=8) {
375 dppriv->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
376 } else {
377 ERR("why are we doing CreatePalette in hi/truecolor?\n");
378 dppriv->cm = 0;
380 if (dppriv->cm && xsize) {
381 for (i=0;i<xsize;i++) {
382 XColor xc;
384 xc.red = ddpal->palents[i].peRed<<8;
385 xc.blue = ddpal->palents[i].peBlue<<8;
386 xc.green = ddpal->palents[i].peGreen<<8;
387 xc.flags = DoRed|DoBlue|DoGreen;
388 xc.pixel = i;
389 TSXStoreColor(display,dppriv->cm,&xc);
392 return DD_OK;
395 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
396 ICOM_THIS(IDirectDraw2Impl,iface);
397 TRACE("(%p)->()\n",This);
398 Sleep(1000);
399 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
400 #ifdef RESTORE_SIGNALS
401 SIGNAL_Init();
402 #endif
403 return DD_OK;
406 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
407 ICOM_THIS(IDirectDraw2Impl,iface);
408 DDPRIVATE(This);
409 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
411 if (!--(This->ref)) {
412 if (!--(This->d->ref)) {
413 VirtualFree(ddpriv->fb_addr, 0, MEM_RELEASE);
414 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
415 if (This->d->window && GetPropA(This->d->window,ddProp))
416 DestroyWindow(This->d->window);
417 #ifdef HAVE_LIBXXF86VM
418 if (orig_mode) {
419 TSXF86VidModeSwitchToMode(
420 display,
421 DefaultScreen(display),
422 orig_mode
424 if (orig_mode->privsize)
425 TSXFree(orig_mode->private);
426 free(orig_mode);
427 orig_mode = NULL;
429 #endif
431 #ifdef RESTORE_SIGNALS
432 SIGNAL_Init();
433 #endif
434 HeapFree(GetProcessHeap(),0,This->d);
436 HeapFree(GetProcessHeap(),0,This);
437 return S_OK;
439 return This->ref;
442 HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
443 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
445 ICOM_THIS(IDirectDraw2Impl,iface);
447 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
448 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
449 *obj = This;
450 IDirectDraw2_AddRef(iface);
452 TRACE(" Creating IUnknown interface (%p)\n", *obj);
454 return S_OK;
456 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
457 IDirectDrawImpl *dd = HeapAlloc(GetProcessHeap(),0,sizeof(*dd));
458 ICOM_VTBL(dd) = &dga_ddvt;dd->ref = 1;dd->d = This->d;This->d++;
459 *obj = dd;
461 IDirectDraw2_AddRef(iface);
462 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
464 return S_OK;
466 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
467 IDirectDraw2Impl *dd = HeapAlloc(GetProcessHeap(),0,sizeof(*dd));
468 ICOM_VTBL(dd) = &dga_dd2vt;dd->ref = 1;dd->d = This->d;This->d++;
469 *obj = dd;
471 IDirectDraw2_AddRef(iface);
472 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
473 return S_OK;
475 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
476 IDirectDraw2Impl *dd = HeapAlloc(GetProcessHeap(),0,sizeof(*dd));
477 ICOM_VTBL(dd) = &dga_dd2vt;dd->ref = 1;dd->d = This->d;This->d++;
478 *obj = dd;
480 IDirectDraw2_AddRef(iface);
481 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
482 return S_OK;
484 FIXME("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
485 return OLE_E_ENUM_NOMORE;
488 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
489 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
491 ICOM_THIS(IDirectDraw2Impl,iface);
492 DDSURFACEDESC ddsfd;
493 static struct {
494 int w,h;
495 } modes[5] = { /* some usual modes */
496 {512,384},
497 {640,400},
498 {640,480},
499 {800,600},
500 {1024,768},
502 static int depths[4] = {8,16,24,32};
503 int i,j;
505 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
506 ddsfd.dwSize = sizeof(ddsfd);
507 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
508 if (dwFlags & DDEDM_REFRESHRATES) {
509 ddsfd.dwFlags |= DDSD_REFRESHRATE;
510 ddsfd.u.dwRefreshRate = 60;
512 ddsfd.ddsCaps.dwCaps = 0;
513 ddsfd.dwBackBufferCount = 1;
515 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
516 ddsfd.dwBackBufferCount = 1;
517 ddsfd.ddpfPixelFormat.dwFourCC = 0;
518 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
519 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
520 /* FIXME: those masks would have to be set in depth > 8 */
521 if (depths[i]==8) {
522 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
523 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
524 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
525 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
526 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
527 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
528 } else {
529 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
531 /* FIXME: We should query those from X itself */
532 switch (depths[i]) {
533 case 16:
534 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
535 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
536 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
537 break;
538 case 24:
539 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
540 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
541 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
542 break;
543 case 32:
544 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
545 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
546 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
547 break;
551 ddsfd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
552 ddsfd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
553 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
554 if (!modescb(&ddsfd,context)) return DD_OK;
556 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
557 ddsfd.dwWidth = modes[j].w;
558 ddsfd.dwHeight = modes[j].h;
559 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
560 if (!modescb(&ddsfd,context)) return DD_OK;
563 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
564 /* modeX is not standard VGA */
566 ddsfd.dwHeight = 200;
567 ddsfd.dwWidth = 320;
568 TRACE(" enumerating (320x200x%d)\n",depths[i]);
569 if (!modescb(&ddsfd,context)) return DD_OK;
573 return DD_OK;
576 HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
577 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
579 ICOM_THIS(IDirectDraw2Impl,iface);
580 DDPRIVATE(This);
582 TRACE("(%p)->(%p)\n",This,lpddsfd);
583 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
584 lpddsfd->dwHeight = This->d->height;
585 lpddsfd->dwWidth = This->d->width;
586 lpddsfd->lPitch = ddpriv->fb_width*PFGET_BPP(This->d->directdraw_pixelformat);
587 lpddsfd->dwBackBufferCount = 2;
588 lpddsfd->u.dwRefreshRate = 60;
589 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
590 lpddsfd->ddpfPixelFormat = This->d->directdraw_pixelformat;
591 if (TRACE_ON(ddraw))
592 _dump_surface_desc(lpddsfd);
593 return DD_OK;
596 /* Note: Hack so we can reuse the old functions without compiler warnings */
597 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
598 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
599 #else
600 # define XCAST(fun) (void *)
601 #endif
603 struct ICOM_VTABLE(IDirectDraw) dga_ddvt =
605 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
606 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
607 XCAST(AddRef)IDirectDraw2Impl_AddRef,
608 XCAST(Release)DGA_IDirectDraw2Impl_Release,
609 XCAST(Compact)IDirectDraw2Impl_Compact,
610 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
611 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
612 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
613 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
614 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
615 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
616 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
617 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
618 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
619 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
620 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
621 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
622 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
623 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
624 XCAST(Initialize)IDirectDraw2Impl_Initialize,
625 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
626 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
627 DGA_IDirectDrawImpl_SetDisplayMode,
628 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
630 #undef XCAST
632 /*****************************************************************************
633 * IDirectDraw2
637 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
638 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
640 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
641 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
644 HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
645 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
647 ICOM_THIS(IDirectDraw2Impl,iface);
648 DDPRIVATE(This);
650 TRACE("(%p)->(%p,%p,%p)\n",This,ddscaps,total,free);
651 if (total) *total = ddpriv->fb_memsize * 1024;
652 if (free) *free = ddpriv->fb_memsize * 1024;
653 return DD_OK;
656 ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
658 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
659 DGA_IDirectDraw2Impl_QueryInterface,
660 IDirectDraw2Impl_AddRef,
661 DGA_IDirectDraw2Impl_Release,
662 IDirectDraw2Impl_Compact,
663 IDirectDraw2Impl_CreateClipper,
664 DGA_IDirectDraw2Impl_CreatePalette,
665 DGA_IDirectDraw2Impl_CreateSurface,
666 IDirectDraw2Impl_DuplicateSurface,
667 DGA_IDirectDraw2Impl_EnumDisplayModes,
668 IDirectDraw2Impl_EnumSurfaces,
669 IDirectDraw2Impl_FlipToGDISurface,
670 DGA_IDirectDraw2Impl_GetCaps,
671 DGA_IDirectDraw2Impl_GetDisplayMode,
672 IDirectDraw2Impl_GetFourCCCodes,
673 IDirectDraw2Impl_GetGDISurface,
674 IDirectDraw2Impl_GetMonitorFrequency,
675 IDirectDraw2Impl_GetScanLine,
676 IDirectDraw2Impl_GetVerticalBlankStatus,
677 IDirectDraw2Impl_Initialize,
678 DGA_IDirectDraw2Impl_RestoreDisplayMode,
679 IDirectDraw2Impl_SetCooperativeLevel,
680 DGA_IDirectDraw2Impl_SetDisplayMode,
681 IDirectDraw2Impl_WaitForVerticalBlank,
682 DGA_IDirectDraw2Impl_GetAvailableVidMem
685 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
686 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
687 #else
688 # define XCAST(fun) (void*)
689 #endif
691 ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
693 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
694 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
695 XCAST(AddRef)IDirectDraw2Impl_AddRef,
696 XCAST(Release)DGA_IDirectDraw2Impl_Release,
697 XCAST(Compact)IDirectDraw2Impl_Compact,
698 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
699 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
700 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
701 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
702 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
703 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
704 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
705 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
706 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
707 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
708 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
709 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
710 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
711 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
712 XCAST(Initialize)IDirectDraw2Impl_Initialize,
713 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
714 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
715 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
716 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
717 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
718 IDirectDraw4Impl_GetSurfaceFromDC,
719 IDirectDraw4Impl_RestoreAllSurfaces,
720 IDirectDraw4Impl_TestCooperativeLevel,
721 IDirectDraw4Impl_GetDeviceIdentifier
723 #undef XCAST