1 /* DirectDraw using DGA
3 * Copyright 1997,1998 Marcus Meissner
5 /* When DirectVideo mode is enabled you can no longer use 'normal' X
6 * applications nor can you switch to a virtual console. Also, enabling
7 * only works, if you have switched to the screen where the application
9 * Some ways to debug this stuff are:
10 * - A terminal connected to the serial port. Can be bought used for cheap.
11 * (This is the method I am using.)
12 * - Another machine connected over some kind of network.
14 /* Progress on following programs:
16 * - Diablo [640x480x8]:
17 * The movies play. The game doesn't work, it somehow tries to write
18 * into 2 lines _BEFORE_ the start of the surface. Don't know why.
20 * - WingCommander 4 / Win95 Patch [640x480x8]:
21 * The intromovie plays, in 8 bit mode (to reconfigure wc4, run wine
22 * "wc4w.exe -I"). The 16bit mode looks broken, but I think this is due to
23 * my Matrox Mystique which uses 565 (rgb) colorweight instead of the usual
24 * 555. Specifying it in DDPIXELFORMAT didn't help.
25 * Requires to be run in 640x480xdepth mode (doesn't seem to heed
26 * DDSURFACEDESC.lPitch). You can fly the first mission with Maniac, but
27 * it crashes as soon as you arrive at Blue Point Station...
29 * - Monkey Island 3 [640x480x8]:
30 * Goes to the easy/hard selection screen, then hangs due to MT problems.
32 * - DiscWorld 2 [640x480x8]:
33 * [Crashes with 'cli' in released version. Yes. Privileged instructions
34 * in 32bit code. Will they ever learn...]
35 * Plays through nearly all intro movies. Sound and animation skip a lot of
36 * stuff (possible DirectSound problem).
39 * Shows the splash screen, then fails with missing Joystick.
41 * - Tomb Raider 2 Demo (using 8 bit renderer) [640x480x8]:
42 * Playable. Sound is weird.
44 * - WingCommander Prophecy Demo (using software renderer) [640x480x16]:
45 * [Crashes with an invalid opcode (outb) in the release version.]
46 * Plays intromovie, hangs in selection screen (no keyboard input, probably
47 * DirectInput problem).
54 #include <sys/signal.h>
58 #include "interfaces.h"
69 #ifdef HAVE_LIBXXF86DGA
70 #include <X11/extensions/xf86dga.h>
73 /* restore signal handlers overwritten by XF86DGA
74 * this is a define, for it will only work in emulator mode
76 #undef RESTORE_SIGNALS
78 static struct IDirectDrawSurface3_VTable dds3vt;
79 static struct IDirectDrawSurface2_VTable dds2vt;
80 static struct IDirectDrawSurface_VTable ddsvt;
81 static struct IDirectDraw_VTable ddvt;
82 static struct IDirectDraw2_VTable dd2vt;
83 static struct IDirect3D_VTable d3dvt;
84 static struct IDirect3D2_VTable d3d2vt;
88 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
89 /* we have just one display driver right now ... */
90 ddenumproc(0,"WINE Display","display",data);
95 DSoundHelp(DWORD x,DWORD y,DWORD z) {
96 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
101 #ifdef HAVE_LIBXXF86DGA
103 /******************************************************************************
104 * internal helper functions
106 static void _dump_DDBLTFX(DWORD flagmask) {
112 #define FE(x) { x, #x},
113 FE(DDBLTFX_ARITHSTRETCHY)
114 FE(DDBLTFX_MIRRORLEFTRIGHT)
115 FE(DDBLTFX_MIRRORUPDOWN)
116 FE(DDBLTFX_NOTEARING)
117 FE(DDBLTFX_ROTATE180)
118 FE(DDBLTFX_ROTATE270)
120 FE(DDBLTFX_ZBUFFERRANGE)
121 FE(DDBLTFX_ZBUFFERBASEDEST)
123 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
124 if (flags[i].mask & flagmask) {
125 DUMP("%s ",flags[i].name);
132 static void _dump_DDBLTFAST(DWORD flagmask) {
138 #define FE(x) { x, #x},
139 FE(DDBLTFAST_NOCOLORKEY)
140 FE(DDBLTFAST_SRCCOLORKEY)
141 FE(DDBLTFAST_DESTCOLORKEY)
144 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
145 if (flags[i].mask & flagmask)
146 DUMP("%s ",flags[i].name);
150 static void _dump_DDBLT(DWORD flagmask) {
156 #define FE(x) { x, #x},
158 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
159 FE(DDBLT_ALPHADESTNEG)
160 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
161 FE(DDBLT_ALPHAEDGEBLEND)
163 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
164 FE(DDBLT_ALPHASRCNEG)
165 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
171 FE(DDBLT_KEYDESTOVERRIDE)
173 FE(DDBLT_KEYSRCOVERRIDE)
175 FE(DDBLT_ROTATIONANGLE)
177 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
178 FE(DDBLT_ZBUFFERDESTOVERRIDE)
179 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
180 FE(DDBLT_ZBUFFERSRCOVERRIDE)
184 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
185 if (flags[i].mask & flagmask)
186 DUMP("%s ",flags[i].name);
189 static void _dump_DDSCAPS(DWORD flagmask) {
195 #define FE(x) { x, #x},
196 FE(DDSCAPS_RESERVED1)
198 FE(DDSCAPS_BACKBUFFER)
201 FE(DDSCAPS_FRONTBUFFER)
202 FE(DDSCAPS_OFFSCREENPLAIN)
205 FE(DDSCAPS_PRIMARYSURFACE)
206 FE(DDSCAPS_PRIMARYSURFACELEFT)
207 FE(DDSCAPS_SYSTEMMEMORY)
210 FE(DDSCAPS_VIDEOMEMORY)
212 FE(DDSCAPS_WRITEONLY)
215 FE(DDSCAPS_LIVEVIDEO)
219 FE(DDSCAPS_RESERVED2)
220 FE(DDSCAPS_ALLOCONLOAD)
221 FE(DDSCAPS_VIDEOPORT)
222 FE(DDSCAPS_LOCALVIDMEM)
223 FE(DDSCAPS_NONLOCALVIDMEM)
224 FE(DDSCAPS_STANDARDVGAMODE)
225 FE(DDSCAPS_OPTIMIZED)
227 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
228 if (flags[i].mask & flagmask)
229 DUMP("%s ",flags[i].name);
233 void _dump_DDCAPS(DWORD flagmask) {
239 #define FE(x) { x, #x},
241 FE(DDCAPS_ALIGNBOUNDARYDEST)
242 FE(DDCAPS_ALIGNSIZEDEST)
243 FE(DDCAPS_ALIGNBOUNDARYSRC)
244 FE(DDCAPS_ALIGNSIZESRC)
245 FE(DDCAPS_ALIGNSTRIDE)
249 FE(DDCAPS_BLTSTRETCH)
252 FE(DDCAPS_OVERLAYCANTCLIP)
253 FE(DDCAPS_OVERLAYFOURCC)
254 FE(DDCAPS_OVERLAYSTRETCH)
256 FE(DDCAPS_PALETTEVSYNC)
257 FE(DDCAPS_READSCANLINE)
258 FE(DDCAPS_STEREOVIEW)
264 FE(DDCAPS_COLORKEYHWASSIST)
265 FE(DDCAPS_NOHARDWARE)
266 FE(DDCAPS_BLTCOLORFILL)
267 FE(DDCAPS_BANKSWITCHED)
268 FE(DDCAPS_BLTDEPTHFILL)
270 FE(DDCAPS_CANCLIPSTRETCHED)
271 FE(DDCAPS_CANBLTSYSMEM)
273 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
274 if (flags[i].mask & flagmask)
275 DUMP("%s ",flags[i].name);
279 static void _dump_DDSD(DWORD flagmask) {
289 FE(DDSD_BACKBUFFERCOUNT)
290 FE(DDSD_ZBUFFERBITDEPTH)
291 FE(DDSD_ALPHABITDEPTH)
293 FE(DDSD_CKDESTOVERLAY)
295 FE(DDSD_CKSRCOVERLAY)
302 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
303 if (flags[i].mask & flagmask)
304 DUMP("%s ",flags[i].name);
308 static int _getpixelformat(LPDIRECTDRAW ddraw,LPDDPIXELFORMAT pf) {
309 static XVisualInfo *vi;
314 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
317 if (ddraw->d.depth==8) {
318 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
319 pf->x.dwRGBBitCount = 8;
320 pf->y.dwRBitMask = 0;
321 pf->z.dwGBitMask = 0;
322 pf->xx.dwBBitMask = 0;
323 pf->xy.dwRGBAlphaBitMask= 0;
326 if (ddraw->d.depth==16) {
327 pf->dwFlags = DDPF_RGB;
328 pf->x.dwRGBBitCount = 16;
329 pf->y.dwRBitMask = vi[0].red_mask;
330 pf->z.dwGBitMask = vi[0].green_mask;
331 pf->xx.dwBBitMask = vi[0].blue_mask;
332 pf->xy.dwRGBAlphaBitMask= 0;
335 FIXME(ddraw,"_getpixelformat:oops?\n");
336 return DDERR_GENERIC;
339 /******************************************************************************
343 static HRESULT WINAPI IDirectDrawSurface_Lock(
344 LPDIRECTDRAWSURFACE this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
346 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
347 this,lprect,lpddsd,flags,(DWORD)hnd);
348 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
349 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
350 this,lprect,lpddsd,flags,(DWORD)hnd);
353 TRACE(ddraw," lprect: %dx%d-%dx%d\n",
354 lprect->top,lprect->left,lprect->bottom,lprect->right
356 lpddsd->y.lpSurface = this->s.surface+
357 (lprect->top*this->s.lpitch)+
358 (lprect->left*(this->s.ddraw->d.depth/8));
360 lpddsd->y.lpSurface = this->s.surface;
361 lpddsd->dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_LPSURFACE;
362 lpddsd->dwWidth = this->s.width;
363 lpddsd->dwHeight = this->s.height;
364 lpddsd->lPitch = this->s.lpitch;
365 _getpixelformat(this->s.ddraw,&(lpddsd->ddpfPixelFormat));
369 static HRESULT WINAPI IDirectDrawSurface_Unlock(
370 LPDIRECTDRAWSURFACE this,LPVOID surface
372 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
376 static HRESULT WINAPI IDirectDrawSurface_Flip(
377 LPDIRECTDRAWSURFACE this,LPDIRECTDRAWSURFACE flipto,DWORD dwFlags
379 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
381 if (this->s.backbuffer)
382 flipto = this->s.backbuffer;
386 XF86DGASetViewPort(display,DefaultScreen(display),0,flipto->s.fb_height);
387 if (flipto->s.palette && flipto->s.palette->cm)
388 XF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
389 while (!XF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
395 tmp = this->s.fb_height;
396 this->s.fb_height = flipto->s.fb_height;
397 flipto->s.fb_height = tmp;
399 ptmp = this->s.surface;
400 this->s.surface = flipto->s.surface;
401 flipto->s.surface = ptmp;
406 static HRESULT WINAPI IDirectDrawSurface_SetPalette(
407 LPDIRECTDRAWSURFACE this,LPDIRECTDRAWPALETTE pal
409 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
410 this->s.palette = pal; /* probably addref it too */
414 static HRESULT WINAPI IDirectDrawSurface_Blt(
415 LPDIRECTDRAWSURFACE this,LPRECT32 rdst,LPDIRECTDRAWSURFACE src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
421 memcpy(&xdst,rdst,sizeof(xdst));
424 xdst.bottom = this->s.height;
426 xdst.right = this->s.width;
429 memcpy(&xsrc,rsrc,sizeof(xsrc));
432 xsrc.bottom = src->s.height;
434 xsrc.right = src->s.width;
437 if (dwFlags & DDBLT_COLORFILL) {
438 int bpp = this->s.ddraw->d.depth/8;
441 xline = (LPBYTE)this->s.surface+xdst.top*this->s.lpitch;
442 for (i=xdst.top;i<xdst.bottom;i++) {
443 xpixel = xline+bpp*xdst.left;
445 for (j=xdst.left;j<xdst.right;j++) {
446 /* FIXME: this only works on little endian
447 * architectures, where DWORD starts with low
450 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
453 xline += this->s.lpitch;
455 dwFlags &= ~(DDBLT_COLORFILL);
457 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
458 if ( (xsrc.top ==0) && (xsrc.bottom ==this->s.height) &&
459 (xsrc.left==0) && (xsrc.right ==this->s.width) &&
460 (xdst.top ==0) && (xdst.bottom ==this->s.height) &&
461 (xdst.left==0) && (xdst.right ==this->s.width) &&
464 memcpy(this->s.surface,src->s.surface,this->s.height*this->s.lpitch);
468 FIXME(ddraw,"(%p)->(%p,%p,%p,%08lx,%p),stub!\n",
469 this,rdst,src,rsrc,dwFlags,lpbltfx
471 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
472 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
473 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
475 if (dwFlags & DDBLT_DDFX) {
476 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
481 static HRESULT WINAPI IDirectDrawSurface_BltFast(
482 LPDIRECTDRAWSURFACE this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE src,LPRECT32 rsrc,DWORD trans
485 if (TRACE_ON(ddraw)) {
486 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx),stub!\n",
487 this,dstx,dsty,src,rsrc,trans
489 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
490 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
492 bpp = this->s.ddraw->d.depth/8;
493 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
494 memcpy( this->s.surface+((i+dsty)*this->s.width*bpp)+dstx*bpp,
495 src->s.surface +(rsrc->top+i)*src->s.width*bpp+rsrc->left*bpp,
496 (rsrc->right-rsrc->left)*bpp
502 static HRESULT WINAPI IDirectDrawSurface_BltBatch(
503 LPDIRECTDRAWSURFACE this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
505 TRACE(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
511 static HRESULT WINAPI IDirectDrawSurface_GetCaps(
512 LPDIRECTDRAWSURFACE this,LPDDSCAPS caps
514 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
515 caps->dwCaps = DDCAPS_PALETTE; /* probably more */
519 static HRESULT WINAPI IDirectDrawSurface_GetSurfaceDesc(
520 LPDIRECTDRAWSURFACE this,LPDDSURFACEDESC ddsd
522 if (TRACE_ON(ddraw)) {
523 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
525 fprintf(stderr," flags: ");
526 _dump_DDSD(ddsd->dwFlags);
527 fprintf(stderr,"\n");
530 ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
531 ddsd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
532 ddsd->dwBackBufferCount = 1;
533 ddsd->dwHeight = this->s.height;
534 ddsd->dwWidth = this->s.width;
535 ddsd->lPitch = this->s.lpitch;
536 if (this->s.backbuffer)
537 ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
538 _getpixelformat(this->s.ddraw,&(ddsd->ddpfPixelFormat));
543 static ULONG WINAPI IDirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE this) {
544 TRACE(ddraw,"(%p)->AddRef()\n",this);
545 return ++(this->ref);
548 static ULONG WINAPI IDirectDrawSurface_Release(LPDIRECTDRAWSURFACE this) {
549 TRACE(ddraw,"(%p)->Release()\n",this);
550 if (!--(this->ref)) {
551 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
552 /* clear out of surface list */
553 if (this->s.fb_height == -1) {
554 HeapFree(GetProcessHeap(),0,this->s.surface);
556 this->s.ddraw->d.vpmask &= ~(1<<(this->s.fb_height/this->s.ddraw->d.fb_height));
558 HeapFree(GetProcessHeap(),0,this);
564 static HRESULT WINAPI IDirectDrawSurface_GetAttachedSurface(
565 LPDIRECTDRAWSURFACE this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE *lpdsf
567 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
568 this, lpddsd, lpdsf);
569 if (TRACE_ON(ddraw)) {
570 TRACE(ddraw," caps ");
571 _dump_DDSCAPS(lpddsd->dwCaps);
573 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
574 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
577 /* FIXME: should handle more than one backbuffer */
578 *lpdsf = this->s.backbuffer;
582 static HRESULT WINAPI IDirectDrawSurface_Initialize(
583 LPDIRECTDRAWSURFACE this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
585 return DDERR_ALREADYINITIALIZED;
588 static HRESULT WINAPI IDirectDrawSurface_GetPixelFormat(
589 LPDIRECTDRAWSURFACE this,LPDDPIXELFORMAT pf
591 return _getpixelformat(this->s.ddraw,pf);
594 static HRESULT WINAPI IDirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE this,DWORD dwFlags) {
595 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",
601 static HRESULT WINAPI IDirectDrawSurface_GetOverlayPosition(
602 LPDIRECTDRAWSURFACE this,LPLONG x1,LPLONG x2
604 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",
610 static HRESULT WINAPI IDirectDrawSurface_SetClipper(
611 LPDIRECTDRAWSURFACE this,LPDIRECTDRAWCLIPPER clipper
613 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
617 static HRESULT WINAPI IDirectDrawSurface_AddAttachedSurface(
618 LPDIRECTDRAWSURFACE this,LPDIRECTDRAWSURFACE surf
620 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
621 this->s.backbuffer = surf;
625 static HRESULT WINAPI IDirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE this,HDC32* lphdc) {
626 FIXME(ddraw,"(%p)->GetDC(%p),stub!\n",this,lphdc);
630 static HRESULT WINAPI IDirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE this,REFIID refiid,LPVOID *obj) {
633 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
634 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
636 /* thats version 3 (DirectX 5) */
637 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID_IDirectDrawSurface3))) {
638 this->lpvtbl->fnAddRef(this);
639 this->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dds3vt;
643 /* thats version 2 (DirectX 3) */
644 if ( !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID_IDirectDrawSurface2))) {
645 this->lpvtbl->fnAddRef(this);
646 this->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dds2vt;
651 if (!memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID_IDirectDrawSurface))) {
652 this->lpvtbl->fnAddRef(this);
656 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
657 return OLE_E_ENUM_NOMORE;
660 static HRESULT WINAPI IDirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE this) {
664 static struct IDirectDrawSurface_VTable ddsvt = {
665 IDirectDrawSurface_QueryInterface,
666 IDirectDrawSurface_AddRef,
667 IDirectDrawSurface_Release,
668 IDirectDrawSurface_AddAttachedSurface,
670 IDirectDrawSurface_Blt,
671 IDirectDrawSurface_BltBatch,
672 IDirectDrawSurface_BltFast,
676 IDirectDrawSurface_Flip,
677 IDirectDrawSurface_GetAttachedSurface,
678 IDirectDrawSurface_GetBltStatus,
679 IDirectDrawSurface_GetCaps,
682 IDirectDrawSurface_GetDC,
684 IDirectDrawSurface_GetOverlayPosition,
686 IDirectDrawSurface_GetPixelFormat,
687 IDirectDrawSurface_GetSurfaceDesc,
688 IDirectDrawSurface_Initialize,
689 IDirectDrawSurface_IsLost,
690 IDirectDrawSurface_Lock,
693 IDirectDrawSurface_SetClipper,
696 IDirectDrawSurface_SetPalette,
697 IDirectDrawSurface_Unlock,
703 /******************************************************************************
704 * IDirectDrawSurface2
706 * calls IDirectDrawSurface methods where possible
708 static HRESULT WINAPI IDirectDrawSurface2_Lock(
709 LPDIRECTDRAWSURFACE2 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
711 return IDirectDrawSurface_Lock((LPDIRECTDRAWSURFACE)this,lprect,lpddsd,flags,hnd);
714 static HRESULT WINAPI IDirectDrawSurface2_Unlock(
715 LPDIRECTDRAWSURFACE2 this,LPVOID surface
717 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
721 static HRESULT WINAPI IDirectDrawSurface2_SetPalette(
722 LPDIRECTDRAWSURFACE2 this,LPDIRECTDRAWPALETTE pal
724 return IDirectDrawSurface_SetPalette((LPDIRECTDRAWSURFACE)this,pal);
727 static ULONG WINAPI IDirectDrawSurface2_AddRef(LPDIRECTDRAWSURFACE2 this) {
728 TRACE(ddraw,"(%p)->AddRef()\n",this);
729 return ++(this->ref);
732 static ULONG WINAPI IDirectDrawSurface2_Release(LPDIRECTDRAWSURFACE2 this) {
733 return IDirectDrawSurface_Release((LPDIRECTDRAWSURFACE)this);
736 static HRESULT WINAPI IDirectDrawSurface2_GetAttachedSurface(
737 LPDIRECTDRAWSURFACE2 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE2 *lpdsf
739 HRESULT ret = IDirectDrawSurface_GetAttachedSurface((LPDIRECTDRAWSURFACE)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf);
742 (*lpdsf)->lpvtbl = &dds2vt;
746 static HRESULT WINAPI IDirectDrawSurface2_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE2 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
747 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
751 static HRESULT WINAPI IDirectDrawSurface2_QueryInterface(
752 LPDIRECTDRAWSURFACE2 this,REFIID riid,LPVOID *ppobj
754 return IDirectDrawSurface_QueryInterface((LPDIRECTDRAWSURFACE)this,riid,ppobj);
757 static HRESULT WINAPI IDirectDrawSurface2_IsLost(LPDIRECTDRAWSURFACE2 this) {
762 static struct IDirectDrawSurface2_VTable dds2vt = {
763 IDirectDrawSurface2_QueryInterface,
764 IDirectDrawSurface2_AddRef,
765 IDirectDrawSurface2_Release,
768 (void*)6/*IDirectDrawSurface_Blt*/,
769 (void*)7/*IDirectDrawSurface_BltBatch*/,
772 IDirectDrawSurface2_EnumAttachedSurfaces,
775 IDirectDrawSurface2_GetAttachedSurface,
777 (void*)15/*IDirectDrawSurface_GetCaps*/,
785 (void*)23/*IDirectDrawSurface_GetSurfaceDesc*/,
787 IDirectDrawSurface2_IsLost,
788 IDirectDrawSurface2_Lock,
794 IDirectDrawSurface2_SetPalette,
795 IDirectDrawSurface2_Unlock,
804 /******************************************************************************
805 * IDirectDrawSurface3
807 static HRESULT WINAPI IDirectDrawSurface3_SetPalette(
808 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
810 return IDirectDrawSurface_SetPalette((LPDIRECTDRAWSURFACE)this,pal);
813 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
814 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
816 return _getpixelformat(this->s.ddraw,pf);
819 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
820 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
822 HRESULT ret = IDirectDrawSurface_GetAttachedSurface((LPDIRECTDRAWSURFACE)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf);
825 (*lpdsf)->lpvtbl = &dds3vt;
829 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
830 TRACE(ddraw,"(%p)->AddRef()\n",this);
831 return ++(this->ref);
834 static ULONG WINAPI IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
835 TRACE(ddraw,"(%p)->Release()\n",this);
836 if (!--(this->ref)) {
837 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
838 this->s.ddraw->d.vpmask &= ~(1<<(this->s.fb_height/this->s.ddraw->d.fb_height));
839 HeapFree(GetProcessHeap(),0,this);
845 static HRESULT WINAPI IDirectDrawSurface3_Blt(
846 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,
847 LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
849 return IDirectDrawSurface_Blt((LPDIRECTDRAWSURFACE)this,rdst,(LPDIRECTDRAWSURFACE)src,rsrc,dwFlags,lpbltfx);
852 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
856 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
860 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(
861 LPDIRECTDRAWSURFACE3 this,DWORD dwflags
863 return IDirectDrawSurface_GetBltStatus((LPDIRECTDRAWSURFACE)this,dwflags);
866 static HRESULT WINAPI IDirectDrawSurface3_Flip(
867 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
869 return IDirectDrawSurface_Flip((LPDIRECTDRAWSURFACE)this,(LPDIRECTDRAWSURFACE)flipto,dwFlags);
872 static HRESULT WINAPI IDirectDrawSurface3_Lock(
873 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
875 return IDirectDrawSurface_Lock((LPDIRECTDRAWSURFACE)this,lprect,lpddsd,flags,hnd);
878 static HRESULT WINAPI IDirectDrawSurface3_Unlock(
879 LPDIRECTDRAWSURFACE3 this,LPVOID surface
881 return IDirectDrawSurface_Unlock((LPDIRECTDRAWSURFACE)this,surface);
884 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
885 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
889 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
890 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
892 return IDirectDrawSurface_SetClipper((LPDIRECTDRAWSURFACE)this,clipper);
895 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(
896 LPDIRECTDRAWSURFACE3 this,REFIID riid,LPVOID *ppobj
898 return IDirectDrawSurface_QueryInterface((LPDIRECTDRAWSURFACE)this,riid,ppobj);
901 static struct IDirectDrawSurface3_VTable dds3vt = {
902 IDirectDrawSurface3_QueryInterface,
903 IDirectDrawSurface3_AddRef,
904 IDirectDrawSurface3_Release,
907 IDirectDrawSurface3_Blt,
911 IDirectDrawSurface3_EnumAttachedSurfaces,
913 IDirectDrawSurface3_Flip,
914 IDirectDrawSurface3_GetAttachedSurface,
915 IDirectDrawSurface3_GetBltStatus,
923 IDirectDrawSurface3_GetPixelFormat,
926 IDirectDrawSurface3_IsLost,
927 IDirectDrawSurface3_Lock,
929 IDirectDrawSurface3_Restore,
930 IDirectDrawSurface3_SetClipper,
933 IDirectDrawSurface3_SetPalette,
934 IDirectDrawSurface3_Unlock,
945 /******************************************************************************
948 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
949 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
951 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
955 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
959 HeapFree(GetProcessHeap(),0,this);
963 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
964 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
966 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
971 static struct IDirectDrawClipper_VTable ddclipvt = {
974 IDirectDrawClipper_Release,
975 IDirectDrawClipper_GetClipList,
980 IDirectDrawClipper_SetHwnd
983 /******************************************************************************
986 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
987 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent
991 FIXME(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p),stub!\n",
992 this,x,start,end,palent
994 for (i=start;i<end;i++) {
995 palent[i-start].peRed = i;
996 palent[i-start].peGreen = i;
997 palent[i-start].peBlue = i;
1002 static HRESULT WINAPI IDirectDrawPalette_SetEntries(
1003 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent
1008 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1009 this,x,start,end,palent
1011 if (!this->cm) /* should not happen */ {
1012 ERR(ddraw,"no colormap in SetEntries???\n");
1013 return DDERR_GENERIC;
1015 /* FIXME: free colorcells instead of freeing whole map */
1016 TSXFreeColormap(display,this->cm);
1017 this->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
1019 xc.red = xc.blue = xc.green = 0; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 0; TSXStoreColor(display,this->cm,&xc);
1020 this->palents[0].peRed = 0;
1021 this->palents[0].peBlue = 0;
1022 this->palents[0].peGreen = 0;
1025 xc.red = xc.blue = xc.green = 0xffff; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 255; TSXStoreColor(display,this->cm,&xc);
1026 this->palents[255].peRed = 255;
1027 this->palents[255].peBlue = 255;
1028 this->palents[255].peGreen = 255;
1030 for (i=start;i<end;i++) {
1031 xc.red = palent[i-start].peRed<<8;
1032 xc.blue = palent[i-start].peBlue<<8;
1033 xc.green = palent[i-start].peGreen<<8;
1034 xc.flags = DoRed|DoBlue|DoGreen;
1036 TSXStoreColor(display,this->cm,&xc);
1037 this->palents[i].peRed = palent[i-start].peRed;
1038 this->palents[i].peBlue = palent[i-start].peBlue;
1039 this->palents[i].peGreen = palent[i-start].peGreen;
1042 /* Insomnia's (Stea Greene's) Mods Start Here */
1043 /* FIXME: Still should free individual cells, but this fixes loss of */
1044 /* unchange sections of old palette */
1046 for (i=0;i<start;i++) {
1047 xc.red = this->palents[i].peRed<<8;
1048 xc.blue = this->palents[i].peBlue<<8;
1049 xc.green = this->palents[i].peGreen<<8;
1050 xc.flags = DoRed|DoBlue|DoGreen;
1052 TSXStoreColor(display,this->cm,&xc);
1054 for (i=end;i<256;i++) {
1055 xc.red = this->palents[i].peRed<<8;
1056 xc.blue = this->palents[i].peBlue<<8;
1057 xc.green = this->palents[i].peGreen<<8;
1058 xc.flags = DoRed|DoBlue|DoGreen;
1060 TSXStoreColor(display,this->cm,&xc);
1062 /* End Insomnia's Mods */
1064 XF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1068 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1069 if (!--(this->ref)) {
1071 TSXFreeColormap(display,this->cm);
1074 HeapFree(GetProcessHeap(),0,this);
1080 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1081 return ++(this->ref);
1084 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1085 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1087 return DDERR_ALREADYINITIALIZED;
1090 static struct IDirectDrawPalette_VTable ddpalvt = {
1092 IDirectDrawPalette_AddRef,
1093 IDirectDrawPalette_Release,
1095 IDirectDrawPalette_GetEntries,
1096 IDirectDrawPalette_Initialize,
1097 IDirectDrawPalette_SetEntries
1100 /*******************************************************************************
1103 static struct IDirect3D_VTable d3dvt = {
1115 /*******************************************************************************
1118 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1121 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1122 HeapFree(GetProcessHeap(),0,this);
1128 static HRESULT WINAPI IDirect3D2_EnumDevices(
1129 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1131 D3DDEVICEDESC d1,d2;
1133 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1134 d1.dwSize = sizeof(d1);
1137 d2.dwSize = sizeof(d2);
1139 cb(&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1143 static struct IDirect3D2_VTable d3d2vt = {
1147 IDirect3D2_EnumDevices,
1155 /*******************************************************************************
1158 static HRESULT WINAPI IDirectDraw_CreateSurface(
1159 LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1163 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",
1164 this,lpddsd,lpdsf,lpunk);
1165 if (TRACE_ON(ddraw)) {
1166 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1167 _dump_DDSD(lpddsd->dwFlags);
1168 fprintf(stderr,"caps ");
1169 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1170 fprintf(stderr,"]\n");
1173 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1174 this->lpvtbl->fnAddRef(this);
1176 (*lpdsf)->lpvtbl = &ddsvt;
1177 if ( (lpddsd->dwFlags & DDSD_CAPS) &&
1178 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
1180 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1181 lpddsd->dwWidth = this->d.fb_width;
1182 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1183 lpddsd->dwWidth = this->d.fb_height;
1184 (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1185 (*lpdsf)->s.fb_height = -1;
1186 (*lpdsf)->s.lpitch = lpddsd->dwWidth*this->d.depth/8;
1187 TRACE(ddraw,"using system memory for a primary surface\n");
1190 if (!(this->d.vpmask & (1<<i)))
1192 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1193 /* if i == 32 or maximum ... return error */
1194 this->d.vpmask|=(1<<i);
1195 (*lpdsf)->s.surface = this->d.fb_addr+((i*this->d.fb_height)*this->d.fb_width*this->d.depth/8);
1196 (*lpdsf)->s.fb_height = i*this->d.fb_height;
1197 (*lpdsf)->s.lpitch = this->d.fb_width*this->d.depth/8;
1200 lpddsd->lPitch = (*lpdsf)->s.lpitch;
1202 (*lpdsf)->s.width = this->d.width;
1203 (*lpdsf)->s.height = this->d.height;
1204 (*lpdsf)->s.ddraw = this;
1205 (*lpdsf)->s.backbuffer = NULL;
1206 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1207 LPDIRECTDRAWSURFACE back;
1209 if (lpddsd->dwBackBufferCount>1)
1210 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1212 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1213 this->lpvtbl->fnAddRef(this);
1215 back->lpvtbl = &ddsvt;
1217 if (!(this->d.vpmask & (1<<i)))
1219 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1220 /* if i == 32 or maximum ... return error */
1221 this->d.vpmask|=(1<<i);
1222 back->s.surface = this->d.fb_addr+((i*this->d.fb_height)*this->d.fb_width*this->d.depth/8);
1223 back->s.fb_height = i*this->d.fb_height;
1225 back->s.width = this->d.width;
1226 back->s.height = this->d.height;
1227 back->s.ddraw = this;
1228 back->s.lpitch = this->d.fb_width*this->d.depth/8;
1229 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1235 static HRESULT WINAPI IDirectDraw_DuplicateSurface(
1236 LPDIRECTDRAW this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1238 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1239 *dst = src; /* FIXME */
1243 static HRESULT WINAPI IDirectDraw_SetCooperativeLevel(
1244 LPDIRECTDRAW this,HWND32 hwnd,DWORD cooplevel
1251 FE(DDSCL_FULLSCREEN)
1252 FE(DDSCL_ALLOWREBOOT)
1253 FE(DDSCL_NOWINDOWCHANGES)
1255 FE(DDSCL_ALLOWMODEX)
1257 FE(DDSCL_SETFOCUSWINDOW)
1258 FE(DDSCL_SETDEVICEWINDOW)
1259 FE(DDSCL_CREATEDEVICEWINDOW)
1262 TRACE(ddraw,"(%p)->(%08lx,%08lx)\n",
1263 this,(DWORD)hwnd,cooplevel
1265 if(TRACE_ON(ddraw)){
1266 dbg_decl_str(ddraw, 512);
1267 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1268 if (flagmap[i].mask & cooplevel)
1269 dsprintf(ddraw, "%s ", flagmap[i].name);
1270 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1272 this->d.mainwindow = hwnd;
1277 static HRESULT WINAPI IDirectDraw_SetDisplayMode(
1278 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1280 int i,*depths,depcount;
1282 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n",
1283 this, width, height, depth);
1285 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1286 for (i=0;i<depcount;i++)
1287 if (depths[i]==depth)
1290 if (i==depcount) {/* not found */
1291 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
1292 return DDERR_UNSUPPORTEDMODE;
1294 if (this->d.fb_width < width) {
1295 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.fb_width);
1296 return DDERR_UNSUPPORTEDMODE;
1298 this->d.width = width;
1299 this->d.height = height;
1300 /* adjust fb_height, so we don't overlap */
1301 if (this->d.fb_height < height)
1302 this->d.fb_height = height;
1303 this->d.depth = depth;
1305 /* FIXME: this function OVERWRITES several signal handlers.
1306 * can we save them? and restore them later? In a way that
1307 * it works for the library too?
1309 XF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
1311 XF86DGASetViewPort(display,DefaultScreen(display),0,this->d.fb_height);
1314 #ifdef RESTORE_SIGNALS
1315 SIGNAL_InitEmulator();
1320 static HRESULT WINAPI IDirectDraw_GetCaps(
1321 LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2
1323 TRACE(ddraw,"(%p)->(%p,%p)\n",this,caps1,caps2);
1324 caps1->dwVidMemTotal = this->d.fb_memsize;
1325 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1326 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1328 caps2->dwVidMemTotal = this->d.fb_memsize;
1329 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1330 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1335 static HRESULT WINAPI IDirectDraw_CreateClipper(
1336 LPDIRECTDRAW this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
1338 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
1339 this,x,lpddclip,lpunk
1341 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1342 (*lpddclip)->ref = 1;
1343 (*lpddclip)->lpvtbl = &ddclipvt;
1347 static HRESULT WINAPI IDirectDraw_CreatePalette(
1348 LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1350 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",
1351 this,x,palent,lpddpal,lpunk
1353 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1354 (*lpddpal)->ref = 1;
1355 (*lpddpal)->lpvtbl = &ddpalvt;
1356 (*lpddpal)->ddraw = this;
1357 if (this->d.depth<=8) {
1358 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
1359 } else /* we don't want palettes in hicolor or truecolor */
1365 static HRESULT WINAPI IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) {
1366 TRACE(ddraw, "(%p)->()\n",
1369 XF86DGADirectVideo(display,DefaultScreen(display),0);
1370 #ifdef RESTORE_SIGNALS
1371 SIGNAL_InitEmulator();
1377 static HRESULT WINAPI IDirectDraw_WaitForVerticalBlank(
1378 LPDIRECTDRAW this,DWORD x,HANDLE32 h
1380 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
1384 static ULONG WINAPI IDirectDraw_AddRef(LPDIRECTDRAW this) {
1385 return ++(this->ref);
1388 static ULONG WINAPI IDirectDraw_Release(LPDIRECTDRAW this) {
1389 if (!--(this->ref)) {
1390 XF86DGADirectVideo(display,DefaultScreen(display),0);
1391 #ifdef RESTORE_SIGNALS
1392 SIGNAL_InitEmulator();
1394 HeapFree(GetProcessHeap(),0,this);
1400 static HRESULT WINAPI IDirectDraw_QueryInterface(
1401 LPDIRECTDRAW this,REFIID refiid,LPVOID *obj
1405 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1406 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1407 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1409 this->lpvtbl->fnAddRef(this);
1412 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
1414 this->lpvtbl->fnAddRef(this);
1417 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
1418 this->lpvtbl = (LPDIRECTDRAW_VTABLE)&dd2vt;
1419 this->lpvtbl->fnAddRef(this);
1423 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1426 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1429 this->lpvtbl->fnAddRef(this);
1430 d3d->lpvtbl = &d3dvt;
1434 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1437 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1440 this->lpvtbl->fnAddRef(this);
1441 d3d->lpvtbl = &d3d2vt;
1445 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
1446 return OLE_E_ENUM_NOMORE;
1449 static HRESULT WINAPI IDirectDraw_GetVerticalBlankStatus(
1450 LPDIRECTDRAW this,BOOL32 *status
1452 TRACE(ddraw,"(%p)->(%p)\n",this,status);
1457 static HRESULT WINAPI IDirectDraw_EnumDisplayModes(
1458 LPDIRECTDRAW this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
1460 DDSURFACEDESC ddsfd;
1462 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
1465 _getpixelformat(this,&(ddsfd.ddpfPixelFormat));
1466 ddsfd.dwSize = sizeof(ddsfd);
1467 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1468 if (dwFlags & DDEDM_REFRESHRATES) {
1469 ddsfd.dwFlags |= DDSD_REFRESHRATE;
1470 ddsfd.x.dwRefreshRate = 60;
1473 ddsfd.dwWidth = 640;
1474 ddsfd.dwHeight = 480;
1475 ddsfd.dwBackBufferCount = 1;
1476 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
1478 if (!modescb(&ddsfd,context)) return 0;
1480 ddsfd.dwWidth = 800;
1481 ddsfd.dwHeight = 600;
1482 if (!modescb(&ddsfd,context)) return 0;
1484 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
1485 /* modeX is not standard VGA */
1487 ddsfd.dwHeight = 200;
1488 ddsfd.dwWidth = 320;
1489 if (!modescb(&ddsfd,context)) return 0;
1494 static HRESULT WINAPI IDirectDraw_GetDisplayMode(
1495 LPDIRECTDRAW this,LPDDSURFACEDESC lpddsfd
1497 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
1498 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1499 lpddsfd->dwHeight = screenHeight;
1500 lpddsfd->dwWidth = screenWidth;
1501 lpddsfd->lPitch = this->d.fb_width*this->d.depth/8;
1502 lpddsfd->dwBackBufferCount = 1;
1503 lpddsfd->x.dwRefreshRate = 60;
1504 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
1505 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
1509 static HRESULT WINAPI IDirectDraw_FlipToGDISurface(LPDIRECTDRAW this) {
1510 TRACE(ddraw,"(%p)->()\n",this);
1514 static HRESULT WINAPI IDirectDraw_GetMonitorFrequency(
1515 LPDIRECTDRAW this,LPDWORD freq
1517 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
1518 *freq = 60*100; /* 60 Hz */
1522 /* what can we directly decompress? */
1523 static HRESULT WINAPI IDirectDraw_GetFourCCCodes(
1524 LPDIRECTDRAW this,LPDWORD x,LPDWORD y
1526 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
1530 static IDirectDraw_VTable ddvt = {
1531 IDirectDraw_QueryInterface,
1533 IDirectDraw_Release,
1535 IDirectDraw_CreateClipper,
1536 IDirectDraw_CreatePalette,
1537 IDirectDraw_CreateSurface,
1538 IDirectDraw_DuplicateSurface,
1539 IDirectDraw_EnumDisplayModes,
1541 IDirectDraw_FlipToGDISurface,
1542 IDirectDraw_GetCaps,
1543 IDirectDraw_GetDisplayMode,
1544 IDirectDraw_GetFourCCCodes,
1546 IDirectDraw_GetMonitorFrequency,
1548 IDirectDraw_GetVerticalBlankStatus,
1550 IDirectDraw_RestoreDisplayMode,
1551 IDirectDraw_SetCooperativeLevel,
1552 IDirectDraw_SetDisplayMode,
1553 IDirectDraw_WaitForVerticalBlank,
1556 /*****************************************************************************
1560 static HRESULT WINAPI IDirectDraw2_CreateClipper(
1561 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
1563 return IDirectDraw_CreateClipper((LPDIRECTDRAW)this,x,lpddclip,lpunk);
1566 static HRESULT WINAPI IDirectDraw2_CreateSurface(
1567 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1569 return IDirectDraw_CreateSurface((LPDIRECTDRAW)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf,lpunk);
1572 static HRESULT WINAPI IDirectDraw2_QueryInterface(
1573 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
1575 return IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj);
1578 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
1579 return IDirectDraw_AddRef((LPDIRECTDRAW)this);
1582 static ULONG WINAPI IDirectDraw2_Release(LPDIRECTDRAW2 this) {
1583 return IDirectDraw_Release((LPDIRECTDRAW)this);
1586 static HRESULT WINAPI IDirectDraw2_GetCaps(
1587 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1589 return IDirectDraw_GetCaps((LPDIRECTDRAW)this,caps1,caps2);
1592 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1593 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD x
1595 return IDirectDraw_SetCooperativeLevel((LPDIRECTDRAW)this,hwnd,x);
1598 static HRESULT WINAPI IDirectDraw2_CreatePalette(
1599 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1601 return IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk);
1605 static HRESULT WINAPI IDirectDraw2_SetDisplayMode(
1606 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
1608 TRACE(ddraw,"(%p)->(%ld,%ld,%ld,%08lx,%08lx)\n",
1609 this, width, height, depth, xx, yy);
1611 return IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
1614 static HRESULT WINAPI IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1615 return IDirectDraw_RestoreDisplayMode((LPDIRECTDRAW)this);
1618 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
1619 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
1621 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
1625 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
1626 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
1628 return IDirectDraw_EnumDisplayModes((LPDIRECTDRAW)this,dwFlags,lpddsfd,context,modescb);
1631 static HRESULT WINAPI IDirectDraw2_GetDisplayMode(
1632 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
1634 return IDirectDraw_GetDisplayMode((LPDIRECTDRAW)this,lpddsfd);
1637 static HRESULT WINAPI IDirectDraw2_GetAvailableVidMem(
1638 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
1640 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
1641 this,ddscaps,total,free
1643 if (total) *total = this->d.fb_memsize * 1024;
1644 if (free) *free = this->d.fb_memsize * 1024;
1648 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
1649 LPDIRECTDRAW2 this,LPDWORD freq
1651 return IDirectDraw_GetMonitorFrequency((LPDIRECTDRAW)this,freq);
1654 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
1655 LPDIRECTDRAW2 this,BOOL32 *status
1657 return IDirectDraw_GetVerticalBlankStatus((LPDIRECTDRAW)this,status);
1660 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
1661 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
1663 return IDirectDraw_WaitForVerticalBlank((LPDIRECTDRAW)this,x,h);
1666 static IDirectDraw2_VTable dd2vt = {
1667 IDirectDraw2_QueryInterface,
1668 IDirectDraw2_AddRef,
1669 IDirectDraw2_Release,
1671 IDirectDraw2_CreateClipper,
1672 IDirectDraw2_CreatePalette,
1673 IDirectDraw2_CreateSurface,
1675 IDirectDraw2_EnumDisplayModes,
1676 IDirectDraw2_EnumSurfaces,
1678 IDirectDraw2_GetCaps,
1679 IDirectDraw2_GetDisplayMode,
1682 IDirectDraw2_GetMonitorFrequency,
1684 IDirectDraw2_GetVerticalBlankStatus,
1686 IDirectDraw2_RestoreDisplayMode,
1687 IDirectDraw2_SetCooperativeLevel,
1688 IDirectDraw2_SetDisplayMode,
1689 IDirectDraw2_WaitForVerticalBlank,
1690 IDirectDraw2_GetAvailableVidMem
1694 /******************************************************************************
1698 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
1701 int memsize,banksize,width,evbase,evret,major,minor,flags,height;
1705 WINE_StringFromCLSID(lpGUID,xclsid);
1707 strcpy(xclsid,"<null>");
1709 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
1711 MSG("Must be root to use XF86DGA!\n");
1712 MessageBox32A(0,"Using the XF86DGA extension requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
1713 return E_UNEXPECTED;
1715 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
1716 (*lplpDD)->lpvtbl = &ddvt;
1718 if (!XF86DGAQueryExtension(display,&evbase,&evret)) {
1719 MSG("Wine DirectDraw: No XF86DGA detected.\n");
1722 XF86DGAQueryVersion(display,&major,&minor);
1723 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
1724 XF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
1725 if (!(flags & XF86DGADirectPresent))
1726 MSG("direct video is NOT ENABLED.\n");
1727 XF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
1728 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
1729 addr,width,banksize,memsize
1731 (*lplpDD)->d.fb_width = width;
1732 (*lplpDD)->d.fb_addr = addr;
1733 (*lplpDD)->d.fb_memsize = memsize;
1734 (*lplpDD)->d.fb_banksize = banksize;
1736 XF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
1737 XF86DGASetViewPort(display,DefaultScreen(display),0,0);
1738 (*lplpDD)->d.vp_width = width;
1739 (*lplpDD)->d.vp_height = height;
1740 (*lplpDD)->d.fb_height = screenHeight;
1741 (*lplpDD)->d.vpmask = 0;
1743 /* just assume the default depth is the DGA depth too */
1744 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
1745 #ifdef RESTORE_SIGNALS
1746 SIGNAL_InitEmulator();
1752 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
1753 MessageBox32A(0,"WINE DirectDraw needs the XF86DGA extensions compiled in. (libXxf86dga.a).","WINE DirectDraw",MB_OK|MB_ICONSTOP);
1754 return E_OUTOFMEMORY;