1 /* DirectDraw IDirectDraw interface (generic)
3 * Copyright 1997-2000 Marcus Meissner
4 * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff)
8 * This file contains all the interface functions that are shared between
9 * all interfaces. Or better, it is a "common stub" library for the IDirectDraw*
24 #include "debugtools.h"
29 DEFAULT_DEBUG_CHANNEL(ddraw);
31 #include "ddraw_private.h"
33 HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
34 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
36 ICOM_THIS(IDirectDraw2Impl,iface);
37 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
38 *dst = src; /* FIXME */
42 HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
43 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
45 ICOM_THIS(IDirectDraw2Impl,iface);
47 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
48 _dump_cooperativelevel(cooplevel);
49 This->d.mainWindow = hwnd;
54 * Small helper to either use the cooperative window or create a new
55 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
57 * Note this just uses USER calls, so it is safe in here.
59 void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
62 /* Do destroy only our window */
63 if (This->d.window && GetPropA(This->d.window,ddProp)) {
64 DestroyWindow(This->d.window);
67 /* Sanity check cooperative window before assigning it to drawing. */
68 if (IsWindow(This->d.mainWindow) &&
69 IsWindowVisible(This->d.mainWindow)
71 GetWindowRect(This->d.mainWindow,&rect);
72 if ((((rect.right-rect.left) >= This->d.width) &&
73 ((rect.bottom-rect.top) >= This->d.height))
75 This->d.window = This->d.mainWindow;
76 /* FIXME: resizing is not windows compatible behaviour, need test */
77 /* SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOOWNERZORDER); */
78 This->d.paintable = 1; /* don't wait for WM_PAINT */
81 /* ... failed, create new one. */
82 if (!This->d.window) {
83 This->d.window = CreateWindowExA(
87 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME|WS_BORDER,
96 /*Store THIS with the window. We'll use it in the window procedure*/
97 SetPropA(This->d.window,ddProp,(LONG)This);
98 ShowWindow(This->d.window,TRUE);
99 UpdateWindow(This->d.window);
101 SetFocus(This->d.window);
104 HRESULT WINAPI IDirectDrawImpl_SetDisplayMode(
105 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
107 ICOM_THIS(IDirectDrawImpl,iface);
109 FIXME("(%p)->SetDisplayMode(%ld,%ld,%ld), needs to be implemented for your display adapter!\n",This,width,height,depth);
110 This->d.width = width;
111 This->d.height = height;
112 _common_IDirectDrawImpl_SetDisplayMode(This);
116 static void fill_caps(LPDDCAPS caps) {
117 /* This function tries to fill the capabilities of Wines DDraw
118 * implementation. Needs to be fixed, though.. */
122 caps->dwSize = sizeof(*caps);
123 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE /*| DDCAPS_NOHARDWARE*/;
124 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
125 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
127 caps->dwFXAlphaCaps = 0;
128 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
130 caps->dwZBufferBitDepths = DDBD_16;
131 /* I put here 8 Mo so that D3D applications will believe they have enough
132 * memory to put textures in video memory. BTW, is this only frame buffer
133 * memory or also texture memory (for Voodoo boards for example) ?
135 caps->dwVidMemTotal = 8192 * 1024;
136 caps->dwVidMemFree = 8192 * 1024;
137 /* These are all the supported capabilities of the surfaces */
138 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
139 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
140 /*DDSCAPS_OVERLAY |*/ DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
141 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
144 HRESULT WINAPI IDirectDraw2Impl_GetCaps(
145 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
147 ICOM_THIS(IDirectDraw2Impl,iface);
148 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
150 /* Put the same caps for the two capabilities */
157 HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
158 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
160 ICOM_THIS(IDirectDraw2Impl,iface);
161 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
162 FIXME("(%p)->(%08lx,%p,%p),stub!\n", This,x,ilpddclip,lpunk);
163 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
164 (*ilpddclip)->ref = 1;
165 ICOM_VTBL(*ilpddclip) = &ddclipvt;
169 HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
170 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,
171 IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
176 _dump_paletteformat(dwFlags);
178 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
179 if (*lpddpal == NULL) return E_OUTOFMEMORY;
181 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
183 if (dwFlags & DDPCAPS_1BIT)
185 else if (dwFlags & DDPCAPS_2BIT)
187 else if (dwFlags & DDPCAPS_4BIT)
189 else if (dwFlags & DDPCAPS_8BIT)
192 ERR("unhandled palette format\n");
196 /* Now, if we are in depth conversion mode, create the screen palette */
197 if (This->d.palette_convert != NULL)
198 This->d.palette_convert(palent,(*lpddpal)->screen_palents,0,size);
200 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
201 } else if (This->d.palette_convert != NULL) {
202 /* In that case, put all 0xFF */
203 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
208 HRESULT WINAPI IDirectDraw2Impl_CreatePalette(
209 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
211 ICOM_THIS(IDirectDraw2Impl,iface);
212 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
216 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
217 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
218 if (res != 0) return res;
219 ICOM_VTBL(*ilpddpal) = &ddraw_ddpalvt;
223 HRESULT WINAPI IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
224 ICOM_THIS(IDirectDraw2Impl,iface);
225 TRACE("(%p)->RestoreDisplayMode()\n", This);
230 HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
231 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
233 ICOM_THIS(IDirectDraw2Impl,iface);
234 FIXME("(%p)->(flags=0x%08lx,handle=0x%08x)\n",This,x,h);
238 ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
239 ICOM_THIS(IDirectDraw2Impl,iface);
240 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
242 return ++(This->ref);
245 ULONG WINAPI IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
246 ICOM_THIS(IDirectDraw2Impl,iface);
247 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
249 if (!--(This->ref)) {
250 if (This->d.window && GetPropA(This->d.window,ddProp))
251 DestroyWindow(This->d.window);
252 HeapFree(GetProcessHeap(),0,This);
258 HRESULT WINAPI IDirectDraw2Impl_QueryInterface(
259 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
261 ICOM_THIS(IDirectDraw2Impl,iface);
263 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
265 IDirectDraw2_AddRef(iface);
266 TRACE(" Creating IUnknown interface (%p)\n", *obj);
269 ERR("(%p)->(%s,%p), must be implemented by display interface!\n",This,debugstr_guid(refiid),obj);
270 return OLE_E_ENUM_NOMORE;
273 HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
274 LPDIRECTDRAW2 iface,BOOL *status
276 ICOM_THIS(IDirectDraw2Impl,iface);
277 TRACE("(%p)->(%p)\n",This,status);
282 HRESULT WINAPI IDirectDraw2Impl_EnumDisplayModes(
283 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,
284 LPDDENUMMODESCALLBACK modescb
286 ICOM_THIS(IDirectDraw2Impl,iface);
290 } modes[5] = { /* some of the usual modes */
297 static int depths[4] = {8,16,24,32};
300 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
301 ddsfd.dwSize = sizeof(ddsfd);
302 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
303 if (dwFlags & DDEDM_REFRESHRATES) {
304 ddsfd.dwFlags |= DDSD_REFRESHRATE;
305 ddsfd.u.dwRefreshRate = 60;
307 ddsfd.ddsCaps.dwCaps = 0;
308 ddsfd.dwBackBufferCount = 1;
310 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
311 ddsfd.dwBackBufferCount = 1;
312 ddsfd.ddpfPixelFormat.dwFourCC = 0;
313 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
314 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
315 /* FIXME: those masks would have to be set in depth > 8 */
317 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
318 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
319 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
320 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
321 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
322 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
324 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
326 /* FIXME: We should query those from X itself */
329 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
330 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
331 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
334 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
335 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
336 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
339 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
340 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
341 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
346 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
347 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
348 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
349 if (!modescb(&ddsfd,context)) return DD_OK;
351 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
352 ddsfd.dwWidth = modes[j].w;
353 ddsfd.dwHeight = modes[j].h;
354 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
355 if (!modescb(&ddsfd,context)) return DD_OK;
358 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
359 /* modeX is not standard VGA */
361 ddsfd.dwHeight = 200;
363 TRACE(" enumerating (320x200x%d)\n",depths[i]);
364 if (!modescb(&ddsfd,context)) return DD_OK;
370 HRESULT WINAPI IDirectDraw2Impl_GetDisplayMode(
371 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
373 ICOM_THIS(IDirectDraw2Impl,iface);
374 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
375 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
376 lpddsfd->dwHeight = This->d.height;
377 lpddsfd->dwWidth = This->d.width;
378 lpddsfd->lPitch =lpddsfd->dwWidth*PFGET_BPP(This->d.directdraw_pixelformat);
379 lpddsfd->dwBackBufferCount = 2;
380 lpddsfd->u.dwRefreshRate = 60;
381 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
382 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
384 _dump_surface_desc(lpddsfd);
388 HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
389 ICOM_THIS(IDirectDraw2Impl,iface);
390 FIXME("(%p)->()\n",This);
394 HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
395 LPDIRECTDRAW2 iface,LPDWORD freq
397 ICOM_THIS(IDirectDraw2Impl,iface);
398 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
399 *freq = 60*100; /* 60 Hz */
403 HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
404 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
406 ICOM_THIS(IDirectDraw2Impl,iface);
407 FIXME("(%p,%p,%p), stub\n",This,x,y);
411 HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
412 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,
413 LPDDENUMSURFACESCALLBACK ddsfcb
415 ICOM_THIS(IDirectDraw2Impl,iface);
416 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
420 HRESULT WINAPI IDirectDraw2Impl_Compact( LPDIRECTDRAW2 iface ) {
421 ICOM_THIS(IDirectDraw2Impl,iface);
422 FIXME("(%p)->()\n", This );
426 HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(
427 LPDIRECTDRAW2 iface, LPDIRECTDRAWSURFACE *lplpGDIDDSSurface
429 ICOM_THIS(IDirectDraw2Impl,iface);
430 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
434 HRESULT WINAPI IDirectDraw2Impl_GetScanLine(
435 LPDIRECTDRAW2 iface, LPDWORD lpdwScanLine
437 ICOM_THIS(IDirectDraw2Impl,iface);
438 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
445 HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface, GUID *lpGUID) {
446 ICOM_THIS(IDirectDraw2Impl,iface);
447 FIXME("(%p)->(%p)\n", This, lpGUID);
451 /*****************************************************************************
454 * We only need to list the changed/new functions.
456 HRESULT WINAPI IDirectDraw2Impl_SetDisplayMode(
457 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,
458 DWORD dwRefreshRate, DWORD dwFlags
460 FIXME("Ignoring parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
461 return IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
464 HRESULT WINAPI IDirectDraw2Impl_GetAvailableVidMem(
465 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
467 ICOM_THIS(IDirectDraw2Impl,iface);
468 TRACE("(%p)->(%p,%p,%p)\n", This,ddscaps,total,free);
470 /* We have 16 MB videomemory */
471 if (total) *total= 16*1024*1024;
472 if (free) *free = 16*1024*1024;
476 /*****************************************************************************
481 HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(
482 LPDIRECTDRAW4 iface, HDC hdc, LPDIRECTDRAWSURFACE *lpDDS
484 ICOM_THIS(IDirectDraw4Impl,iface);
485 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
490 HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
491 ICOM_THIS(IDirectDraw4Impl,iface);
492 FIXME("(%p)->()\n", This);
497 HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
498 ICOM_THIS(IDirectDraw4Impl,iface);
499 FIXME("(%p)->()\n", This);
504 HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(
505 LPDIRECTDRAW4 iface,LPDDDEVICEIDENTIFIER lpdddi,DWORD dwFlags
507 ICOM_THIS(IDirectDraw4Impl,iface);
508 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
510 /* just guessing values */
511 strcpy(lpdddi->szDriver,"directdraw");
512 strcpy(lpdddi->szDescription,"WINE DirectDraw");
513 lpdddi->liDriverVersion.s.HighPart = 7;
514 lpdddi->liDriverVersion.s.LowPart = 0;
515 /* Do I smell PCI ids here ? -MM */
516 lpdddi->dwVendorId = 0;
517 lpdddi->dwDeviceId = 0;
518 lpdddi->dwSubSysId = 0;
519 lpdddi->dwRevision = 1;
520 memset(&(lpdddi->guidDeviceIdentifier),0,sizeof(lpdddi->guidDeviceIdentifier));
524 HRESULT common_off_screen_CreateSurface(
525 IDirectDraw2Impl* This,IDirectDrawSurfaceImpl* lpdsf
529 /* The surface was already allocated when entering in this function */
530 TRACE("using system memory for a surface (%p) \n", lpdsf);
532 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
533 /* This is a Z Buffer */
534 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
535 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
537 /* This is a standard image */
538 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
539 /* No pixel format => use DirectDraw's format */
540 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
541 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
543 bpp = GET_BPP(lpdsf->s.surface_desc);
546 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE)
547 ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
549 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
550 lpdsf->s.surface_desc.u1.lpSurface =(LPBYTE)VirtualAlloc(
552 lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp,
553 MEM_RESERVE | MEM_COMMIT,
556 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;