source: trunk/src/ddraw/surface.cpp

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 116.5 KB
Line 
1/* $Id: surface.cpp,v 1.4 2002-12-30 14:05:43 sandervl Exp $ */
2
3/*
4 * DirectDraw Surface class implementaion
5 *
6 * Copyright 1999 Markus Montkowski
7 * Copyright 2000 Michal Necasek
8 * Copyright 1998-2001 Sander van Leeuwen
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13
14#define _OS2WIN_H
15#define FAR
16
17#include <odin.h>
18#include <winbase.h>
19#include <stdlib.h>
20#include <string.h>
21#include <memory.h>
22#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
23 ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \
24 ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
25#include <fourcc.h>
26
27#define CINTERFACE
28#include "ddraw2d.h"
29#include "clipper.h"
30#include "palette.h"
31#include "surface.h"
32#include "surfacehlp.h"
33#include "os2util.h"
34#include "rectangle.h"
35#include <misc.h>
36#include "asmutil.h"
37#include "bltFunc.h"
38#include "colorconv.h"
39#include "fillfunc.h"
40#include <winerror.h>
41#include <os2win.h>
42#include <cpuhlp.h>
43#include "asmutil.h"
44#include "wndproc.h"
45
46#ifdef __IBMC__
47 #include <builtin.h>
48#endif
49
50extern IDirectDrawSurface4Vtbl DDrawSurfaceV4Table;
51extern IDirectDrawSurface3Vtbl DDrawSurfaceV3Table;
52extern IDirectDrawSurface2Vtbl DDrawSurfaceV2Table;
53
54//******************************************************************************
55//******************************************************************************
56OS2IDirectDrawSurface::OS2IDirectDrawSurface(OS2IDirectDraw *lpDirectDraw,
57 LPDDSURFACEDESC2 lpDDSurfaceDesc, BOOL Implicit, BOOL Mainchain) :
58 Referenced(0), lastError(DD_OK),
59 diveBufNr(-1), lpClipper(NULL),
60 lpPalette(NULL), lpDraw(NULL),
61 fLocked(FALSE), hdcImage(NULL),
62 hbmImage(NULL),
63 pFrameBuffer(NULL),Updated(FALSE),
64 fOverlayValid(FALSE),
65 BackBuffer(NULL),FrontBuffer(NULL),
66 pDBreal(NULL),pFBreal(NULL), hwndFullScreen(0)
67
68{
69 DWORD rc;
70 DDSURFACEDESC2 ComplexSurfaceDesc;
71 OS2IDirectDrawSurface *MipMapSurface;
72
73 memset(&sBlt, 0, sizeof(sBlt));
74
75 lpVtbl = &Vtbl2;
76 lpVtbl2 = &Vtbl2;
77 dwUnknownData = 0xDEADDEAD;
78
79 //copy DirectDraw V2, V3 & V4 tables
80 Vtbl = DDrawSurfaceV4Table;
81 Vtbl3 = DDrawSurfaceV3Table;
82 Vtbl2 = DDrawSurfaceV2Table;
83
84 lpDraw = lpDirectDraw;
85 lpDraw->Vtbl.fnAddRef(lpDraw);
86
87 ImplicitSurface = Implicit;
88
89 hDive = lpDirectDraw->GetDiveInstance();
90 hDiveCC = lpDirectDraw->GetCCDiveInstance();
91 surfaceType = DDSCAPS_OFFSCREENPLAIN;
92 memcpy((char *)&DDSurfaceDesc, (char *)lpDDSurfaceDesc, sizeof(DDSURFACEDESC2));
93
94 dprintf(("Pixel format:"));
95 _dump_pixelformat(&lpDDSurfaceDesc->ddpfPixelFormat);
96 dprintf(("Capabilities"));
97 _dump_DDSCAPS(lpDDSurfaceDesc->ddsCaps.dwCaps);
98 _dump_DDSCAPS2(lpDDSurfaceDesc->ddsCaps.dwCaps2);
99
100 if(lpDraw->dCaps.ulDepth != 15)
101 {
102 if(lpDraw->dCaps.ulDepth >= 8)
103 dwBytesPPDive = lpDraw->dCaps.ulDepth >> 3;
104 else
105 dwBytesPPDive = 1; // not sure if this is the case
106 }
107 else
108 dwBytesPPDive = 2; // 2 bytes for 15Bit
109
110 // Setting up Cursors for handling attached Surfaces
111
112 DPA_SurfaceMipMaps = DPA_Create(8);
113 if(NULL==DPA_SurfaceMipMaps)
114 {
115 dprintf(("DDRAW: Internal : Error creating DPA for MipMaps\n"));
116 lastError = DDERR_OUTOFMEMORY ;
117 return;
118 }
119
120 DPA_SurfaceAttached = DPA_Create(8);
121 if(NULL==DPA_SurfaceAttached)
122 {
123 dprintf(("DDRAW: Internal : Error creating DPA for attached surfaces\n"));
124 lastError = DDERR_OUTOFMEMORY ;
125 return;
126 }
127
128 DPA_LockedRects = DPA_Create(8);
129 if(NULL==DPA_LockedRects)
130 {
131 dprintf(("DDRAW: Internal : Error creating DPA for Locked Rectangles\n"));
132 lastError = DDERR_OUTOFMEMORY ;
133 return;
134 }
135
136 DPA_SurfacePrivateData = DPA_Create(8);
137 if(NULL==DPA_SurfacePrivateData)
138 {
139 dprintf(("DDRAW: Internal : Error creating DPA for private surface Data\n"));
140 lastError = DDERR_OUTOFMEMORY ;
141 return;
142 }
143
144 switch(lpDraw->GetScreenBpp())
145 {
146 case 8:
147 switch(lpDraw->dCaps.ulDepth)
148 {
149 case 8:
150 BltSolid = &BltSolid8to8;
151 ColorConv = NULL;
152 ColorFill = &Fill8on8;
153 break;
154 case 16:
155 BltSolid = &BltSolid8to16;
156 ColorConv = &Conv8to16;
157 ColorFill = &Fill8on16;
158 break;
159 case 24:
160 BltSolid = &BltSolid8to24;
161 ColorConv = &Conv8to24;
162 ColorFill = &Fill8on24;
163 break;
164 case 32:
165 BltSolid = &BltSolid8to32;
166 ColorConv = &Conv8to32;
167 ColorFill = &Fill8on32;
168 break;
169 default:
170 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
171 BltSolid = NULL;
172 ColorConv = NULL;
173 ColorFill = NULL;
174 break;
175 }
176 break;
177 case 16:
178 switch(lpDraw->dCaps.ulDepth)
179 {
180 case 8:
181 BltSolid = &BltSolid16to8;
182 ColorConv = &Conv16to8;
183 ColorFill = &Fill16on8;
184 break;
185 case 16:
186 BltSolid = &BltSolid16to16;
187 ColorConv = NULL;
188 ColorFill = &Fill16on16;
189 break;
190 case 24:
191 BltSolid = &BltSolid16to24;
192 ColorConv = &Conv16to24;
193 ColorFill = &Fill16on24;
194 break;
195 case 32:
196 BltSolid = &BltSolid16to32;
197 ColorConv = &Conv16to32;
198 ColorFill = &Fill16on32;
199 break;
200 default:
201 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
202 BltSolid = NULL;
203 ColorConv = NULL;
204 ColorFill = NULL;
205 break;
206 }
207 break;
208 case 24:
209 switch(lpDraw->dCaps.ulDepth)
210 {
211 case 8:
212 BltSolid = &BltSolid24to8;
213 ColorConv = &Conv24to8;
214 ColorFill = &Fill24on8;
215 break;
216 case 16:
217 BltSolid = &BltSolid24to16;
218 ColorConv = &Conv24to16;
219 ColorFill = &Fill24on16;
220 break;
221 case 24:
222 BltSolid = &BltSolid24to24;
223 ColorConv = NULL;
224 ColorFill = &Fill24on24;
225 break;
226 case 32:
227 BltSolid = &BltSolid24to32;
228 ColorConv = &Conv24to32;
229 ColorFill = &Fill24on32;
230 break;
231 default:
232 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
233 BltSolid = NULL;
234 ColorConv = NULL;
235 ColorFill = NULL;
236 break;
237 }
238 break;
239 case 32:
240 switch(lpDraw->dCaps.ulDepth)
241 {
242 case 8:
243 BltSolid = &BltSolid32to8;
244 ColorConv = &Conv32to8;
245 ColorFill = &Fill32on8;
246 break;
247 case 16:
248 BltSolid = &BltSolid32to16;
249 ColorConv = &Conv32to16;
250 ColorFill = &Fill32on16;
251 break;
252 case 24:
253 BltSolid = &BltSolid32to24;
254 ColorConv = &Conv32to24;
255 ColorFill = &Fill32on24;
256 break;
257 case 32:
258 BltSolid = &BltSolid32to32;
259 ColorConv = NULL;
260 ColorFill = &Fill32on32;
261 break;
262 default:
263 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
264 BltSolid = NULL;
265 ColorConv = NULL;
266 ColorFill = NULL;
267 break;
268 }
269 break;
270 default:
271 dprintf(("DDRAW: Unsupported DX ColorDepth %d",lpDraw->GetScreenBpp()));
272 BltSolid = NULL;
273 ColorConv = NULL;
274 ColorFill = NULL;
275 break;
276 }
277 // hack set DDSD_CAPS if the value is other than 0
278 if( DDSurfaceDesc.ddsCaps.dwCaps)
279 DDSurfaceDesc.dwFlags |= DDSD_CAPS;
280
281 if( DDSurfaceDesc.dwFlags & DDSD_CAPS )
282 {
283#if 0
284//TODO: Docs say this is done, but does it really happen in windows?
285 // check for invalid flag combinations
286 switch(lpDDSurfaceDesc->ddsCaps.dwCaps2 & (DDSCAPS2_OPAQUE|DDSCAPS2_HINTDYNAMIC|DDSCAPS2_HINTSTATIC))
287 {
288 case 0:
289 case DDSCAPS2_OPAQUE:
290 case DDSCAPS2_HINTDYNAMIC:
291 case DDSCAPS2_HINTSTATIC:
292 break;
293
294 default:
295 dprintf(("DDRAW: Internal : illegal ddscaps2 flag combination (static/dynamic/opaque)"));
296 lastError = DDERR_INVALIDCAPS ;
297 return;
298 }
299#endif
300
301 // First check if we want to create a primary surface while the ddraw object already has one
302 surfaceType = DDSurfaceDesc.ddsCaps.dwCaps;
303
304 if( surfaceType & DDSCAPS_PRIMARYSURFACE)
305 {
306 dprintf(("DDRAW: Primary surface!\n"));
307 if( lpDraw->HasPrimarySurface())
308 {
309 dprintf(("DDRAW: Primary surface already exits!\n"));
310 lastError = DDERR_PRIMARYSURFACEALREADYEXISTS;
311 return;
312 }
313
314 if( (DDSurfaceDesc.dwFlags & DDSD_HEIGHT) ||
315 (DDSurfaceDesc.dwFlags & DDSD_WIDTH) ||
316 (DDSurfaceDesc.dwFlags & DDSD_PIXELFORMAT)
317 )
318 {
319 // Dx doc says passing width,height etc. for primary surface in not permitted!!
320 dprintf(("DDRAW: Invalid parameters\n\n"));
321 lastError = DDERR_INVALIDPARAMS;
322 return;
323 }
324
325 // Check if OS/2 is running in the requested colormode
326
327 diveBufNr = DIVE_BUFFER_SCREEN;
328 if( lpDraw->dCaps.ulDepth == lpDraw->GetScreenBpp() )
329 {
330 dprintf(("DDRAW: Direct Screen Access possible\n"));
331
332 // Yes so direct access to framebuffer is possible
333
334 pFrameBuffer = lpDraw->GetFrameBuffer();
335 pDiveBuffer = pFrameBuffer;
336 dwPitchDB = lpDraw->dCaps.ulScanLineBytes;
337 dwPitchFB = dwPitchDB;
338 DDSurfaceDesc.lPitch = dwPitchDB;
339 }
340 else
341 {
342 // No so we create a virtual framebuffer which the program can access
343 // and blit to the real framebuffer on Unlock to do color conversion
344
345 dprintf( ("Need Color conversion %d => %d Bit\n",
346 lpDraw->GetScreenBpp(),
347 lpDraw->dCaps.ulDepth
348 ));
349
350 dwPitchFB = (lpDraw->GetScreenWidth() * lpDraw->GetScreenBpp() +7) & ~7;
351 DDSurfaceDesc.lPitch = dwPitchFB;
352
353 // 24 byte more to enable alignment and speed up blitting
354
355 pFBreal = (char*)malloc( lpDraw->GetScreenHeight() * dwPitchFB + 24);
356 pFrameBuffer = (char*)(((int)pFBreal + 7) & ~7); // align to QWORD
357
358 // DiveBuffer points to real framebuffer
359 dwPitchDB = lpDraw->dCaps.ulScanLineBytes;
360 pDiveBuffer = lpDraw->GetFrameBuffer();
361
362 }
363
364 // Update passed in and local Surface description
365
366 dprintf(("DDRAW: Setting up Surface\n"));
367 DDSurfaceDesc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT |
368 DDSD_PITCH | DDSD_LPSURFACE |
369 DDSD_PIXELFORMAT;
370 DDSurfaceDesc.dwHeight = lpDraw->GetScreenHeight();
371 DDSurfaceDesc.dwWidth = lpDraw->GetScreenWidth();
372 DDSurfaceDesc.lpSurface = pFrameBuffer;
373 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
374 lpDraw->SetPrimarySurface(TRUE);
375 DDSurfaceDesc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
376 DDSurfaceDesc.ddpfPixelFormat.dwFourCC = (DWORD) lpDraw->GetScreenFourCC();
377 DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = lpDraw->GetScreenBpp();
378
379 switch(DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
380 {
381 case 4:
382 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4 | DDPF_RGB;
383 break;
384 case 8:
385 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_FOURCC | DDPF_RGB;
386 break;
387 case 16:
388 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
389 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x0000F800;
390 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x000007E0;
391 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x0000001F;
392 break;
393 case 24:
394 case 32:
395 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
396 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
397 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
398 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x000000FF;
399 break;
400 default:
401 // Remove the Pixelformat flag
402 DDSurfaceDesc.dwFlags &= ~DDSD_PIXELFORMAT;
403 dprintf(("DDRAW: Unexpected BitDepth : %d\n",lpDraw->GetScreenBpp()));
404 break;
405 } // end switch
406
407 dprintf(("DDRAW: Surface set up, checking other Caps\n"));
408
409 if( DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
410 {
411 dprintf(("DDRAW: Complex Surface\n"));
412
413 if(DDSurfaceDesc.dwFlags & DDSD_BACKBUFFERCOUNT)
414 {
415 dprintf(("DDRAW: Backbuffer # = %d\n",DDSurfaceDesc.dwBackBufferCount));
416 memset( &ComplexSurfaceDesc,
417 0,
418 sizeof(DDSURFACEDESC2));
419
420 ComplexSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
421 ComplexSurfaceDesc.dwFlags = DDSD_CAPS |
422 DDSD_WIDTH |
423 DDSD_HEIGHT |
424 DDSD_PIXELFORMAT;
425 ComplexSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
426 ComplexSurfaceDesc.dwHeight = DDSurfaceDesc.dwHeight;
427 ComplexSurfaceDesc.dwWidth = DDSurfaceDesc.dwWidth;
428 ComplexSurfaceDesc.ddpfPixelFormat.dwFlags = DDSurfaceDesc.ddpfPixelFormat.dwFlags;
429 ComplexSurfaceDesc.ddpfPixelFormat.dwRBitMask = DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
430 ComplexSurfaceDesc.ddpfPixelFormat.dwGBitMask = DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
431 ComplexSurfaceDesc.ddpfPixelFormat.dwBBitMask = DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
432 ComplexSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
433
434 if(DDSurfaceDesc.dwBackBufferCount>1)
435 {
436 ComplexSurfaceDesc.dwFlags |=DDSD_BACKBUFFERCOUNT;
437 ComplexSurfaceDesc.dwBackBufferCount = DDSurfaceDesc.dwBackBufferCount -1;
438 ComplexSurfaceDesc.ddsCaps.dwCaps|= DDSCAPS_COMPLEX;
439 }
440
441 BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, TRUE);
442 BackBuffer->Vtbl.fnAddRef((IDirectDrawSurface *)BackBuffer);
443
444 if (BackBuffer->GetLastError()==DD_OK)
445 {
446 dprintf(("DDRAW: created backbuffer"));
447 // Our Primary Buffer is also the frontbuffer of a flipchain
448 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER | DDSCAPS_FLIP;
449 BackBuffer->SetFrontBuffer(this);
450 }
451 else
452 {
453 dprintf(("DDRAW: Error creating backbuffer"));
454 }
455 }
456 else
457 {
458 dprintf(("DDRAW: Unsupported Complex Surface\n"));
459 _dump_DDSCAPS(DDSurfaceDesc.dwFlags);
460
461 lastError = DDERR_OUTOFMEMORY;
462 return;
463 } //endif Backbuffer
464 } // endif DDSCAPS_COMPLEX
465
466 width = DDSurfaceDesc.dwWidth;
467 height = DDSurfaceDesc.dwHeight;
468
469 lpDraw->pPrimSurf = this;
470
471 lastError = DD_OK;
472
473#if 0
474//NOTE: This isn't working at all (interferes with mouse messages for application
475// window)
476 //If in fullscreen mode, create transparent window covering the entire desktop
477 if(lpDraw->GetCooperativeLevel() & DDSCL_FULLSCREEN)
478 {
479 DirectDrawSurface_RegisterClass();
480 hwndFullScreen = DirectDrawSurface_CreateWindow(DDSurfaceDesc.dwWidth,
481 DDSurfaceDesc.dwHeight,
482 lpDraw->GetClientWindow());
483
484 if(hwndFullScreen == 0) {
485 DebugInt3();
486 lastError = DDERR_OUTOFMEMORY;
487 }
488 dprintf(("DDRAW: Created fullscreen transparent window %x", hwndFullScreen));
489 }
490#endif
491 return;
492 } // endif DDSCAPS_PRIMARYSURFACE
493
494 //
495 // ToDo : Do better calulation of Bitmap Size to support the compressed Bitmaps in Dx6
496 //
497
498 if( (DDSurfaceDesc.dwFlags & DDSD_HEIGHT) &&
499 (DDSurfaceDesc.dwFlags & DDSD_WIDTH)
500 )
501
502 {
503 DWORD dwBpp;
504 DWORD dwCaps;
505 dprintf(( " Requested Size %dx%d\n",
506 DDSurfaceDesc.dwWidth,
507 DDSurfaceDesc.dwHeight));
508
509 if(DDSurfaceDesc.dwFlags & DDSD_PIXELFORMAT) // Pixelformat passed in ?
510 {
511 dprintf(("DDRAW: Pixelformat requested :"));
512 // YES use it
513 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_RGB)
514 {
515 dwBpp = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
516 }
517 else
518 {
519 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
520 dwBpp = 8;
521 else
522 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
523 dwBpp = 4;
524 else
525 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
526 dprintf(("DDRAW: Pixelformat FOURCC %4s", &DDSurfaceDesc.ddpfPixelFormat.dwFourCC));
527 switch(DDSurfaceDesc.ddpfPixelFormat.dwFourCC) {
528 case FOURCC_RGB3:
529 dwBpp = 24;
530 break;
531 case FOURCC_RGB4:
532 dwBpp = 32;
533 break;
534 default:
535 dprintf(("DDRAW: Unsupported FOURCC!"));
536 lastError = DDERR_UNSUPPORTEDFORMAT;
537 return;
538 }
539 }
540 }
541 }
542 else
543 {
544 dprintf(("DDRAW: Use Screen Format :"));
545 dwBpp = lpDraw->GetScreenBpp(); // No use Screenformat
546 DDSurfaceDesc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
547 DDSurfaceDesc.ddpfPixelFormat.dwFourCC = (DWORD) lpDraw->GetScreenFourCC();
548 DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = dwBpp;
549 switch(DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
550 {
551 case 4:
552 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4 | DDPF_RGB;
553 break;
554 case 8:
555 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_FOURCC | DDPF_RGB;
556 break;
557 case 16:
558 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
559 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x0000F800;
560 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x000007E0;
561 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x0000001F;
562 break;
563 case 24:
564 case 32:
565 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
566 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
567 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
568 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x000000FF;
569 break;
570 default:
571 // Remove the Pixelformat flag
572 DDSurfaceDesc.dwFlags &= ~DDSD_PIXELFORMAT;
573 dprintf(("DDRAW: Unexpected BitDepth : %d\n",lpDraw->GetScreenBpp()));
574 break;
575 } // end switch
576
577 }
578
579 dprintf(("DDRAW: %d Bits\n",dwBpp));
580
581 // three possible situaltions
582 // 1. User supplied pointer to surface -> use it
583 // 2. Delayed allocation of a texture -> don't alloc
584 // 3. Normal allocation
585 // After this check for complex flag.
586
587 dwCaps = DDSurfaceDesc.ddsCaps.dwCaps;
588
589 if(DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
590 {
591 // 1.
592
593 dprintf(("DDRAW: Usersupplied Surface\n"));
594
595 if(NULL==DDSurfaceDesc.lpSurface)
596 {
597 // pointer is NULL! Stupid user ;)
598 lastError = DDERR_INVALIDPARAMS;
599 return;
600 }
601
602 // User allocated the Buffer for the surface so we don't have to
603
604 Updated = TRUE; // Set Flag to indicate User supplied buffer so we don't free it
605
606 // As we allready copied the surface description we are done if the # of colors
607 // of the surface is the same then the screen
608
609 pFrameBuffer = (char*)DDSurfaceDesc.lpSurface;
610 diveBufNr = -1;
611 dwPitchFB = DDSurfaceDesc.lPitch;
612
613 if( lpDraw->dCaps.ulDepth == dwBpp )
614 {
615 // Yes No Colorconversion is needed so point to the same buffer
616 dwPitchDB = dwPitchFB;
617 pDiveBuffer = pFrameBuffer;
618 }
619 else
620 {
621 // No so we must create the Divebuffer to do the color conversion
622 // and blit to the real framebuffer on Unlock to do color conversion
623
624 dwPitchDB = (DDSurfaceDesc.dwWidth * dwBytesPPDive +7) & ~7;
625
626 // 24 byte more to enable alignment and speed up blitting
627
628 pDBreal = (char*)malloc( DDSurfaceDesc.dwHeight * dwPitchDB + 24);
629 pDiveBuffer = (char*)(((int)pDBreal + 7) & ~7); // align to QWORD
630
631 // Not sure if that is ok but we need this for translation
632 // I hope no game uses YUV or such a crap
633
634 DDSurfaceDesc.ddpfPixelFormat.dwFourCC = SupportedFourCCs[dwBpp>>3];
635 }
636
637 }
638 else
639 {
640
641 if(dwCaps & DDSCAPS_ALLOCONLOAD)
642 {
643 // 2.
644
645 dprintf(("DDRAW: Alloc on Load Texture?!\n"));
646
647 dwCaps &= ~DDSCAPS_ALLOCONLOAD; // remove flag
648
649 // only allow this flag for textures
650 if(!dwCaps & DDSCAPS_TEXTURE)
651 {
652 lastError = DDERR_INVALIDPARAMS;
653 return;
654 }
655
656 dwCaps &= ~DDSCAPS_TEXTURE; // remove flag
657 pFrameBuffer = NULL;
658 pDiveBuffer = NULL;
659
660 // This surface isn't allocated yet, but when the texture is loaded
661 dprintf(("DDRAW: Warning : Delayed memory allocation on request\n"));
662 DDSurfaceDesc.lpSurface = NULL;
663 }
664 else
665 {
666 // 3.
667
668 dprintf(("DDRAW: Alloc now!\n"));
669
670 DDSurfaceDesc.dwFlags = DDSurfaceDesc.dwFlags;
671
672 dwPitchFB = DDSurfaceDesc.dwWidth * (dwBpp<8?1:dwBpp/8);
673//SvL:
674//align on dword boundary; makes it easier to deal with GetDIBits/SetDIBits (they
675//expect dword alignment)
676 dwPitchFB = (dwPitchFB + 3) & ~3; // Align on DWords
677//// dwPitchFB = (dwPitchFB +7) & ~7; // Align on QWords
678 DDSurfaceDesc.lPitch = dwPitchFB;
679 if(dwBpp<8)
680 {
681 dprintf(("DDRAW: 1 or 4 Bit Surface encountered may not work !"));
682 }
683
684
685 // 24 byte more to enable alignment and speed up blitting
686
687 pFBreal = (char*)malloc( DDSurfaceDesc.dwHeight * dwPitchFB + 24);
688
689 if(NULL==pFBreal)
690 {
691 lastError = DDERR_OUTOFMEMORY;
692 return;
693 }
694
695 pFrameBuffer = (char*)(((int)pFBreal + 7) & ~7); // align to QWORD
696
697 dprintf(("DDRAW: Framebuffer @ %08X QWAligned @ %08X with a Pitch of %d\n",
698 pFBreal, pFrameBuffer, dwPitchFB));
699
700 DDSurfaceDesc.lpSurface = pFrameBuffer;
701
702 if( (lpDraw->dCaps.ulDepth ) == dwBpp )
703 {
704 dprintf(("DDRAW: No CC_Buffer needed\n"));
705 // Yes => No Colorconversion is needed so point to the same buffer
706 pDiveBuffer = pFrameBuffer;
707 dwPitchDB = dwPitchFB;
708 }
709 else
710 {
711 dwPitchDB = (DDSurfaceDesc.dwWidth * (lpDraw->dCaps.ulDepth/8) +7) & ~7;
712 dprintf( ("DDRAW: Alloc CCBuf with malloc (%dx%d) Pitch %d ",
713 DDSurfaceDesc.dwHeight,
714 DDSurfaceDesc.dwWidth,
715 dwPitchDB));
716 // No so we must create the Divebuffer to do the colortranslation
717 // and blit to the real framebuffer on Unlock to do color conversion
718 pDBreal = (char*)malloc( DDSurfaceDesc.dwHeight *
719 dwPitchDB + 24);
720 pDiveBuffer = (char*)(((int)pDBreal + 7) & ~7); // align to QWORD
721 dprintf(( " @ %08X\n", pDiveBuffer));
722
723 }
724
725// if(Mainchain)
726// {
727 diveBufNr = 0;
728 rc = DiveAllocImageBuffer( hDive,
729 &diveBufNr,
730 lpDraw->dCaps.fccColorEncoding,
731 DDSurfaceDesc.dwWidth,
732 DDSurfaceDesc.dwHeight,
733 dwPitchDB,
734 (PBYTE)pDiveBuffer);
735 dprintf(("DDRAW: DiveAllocImageBuffer %x -> %d (rc=%d)",pDiveBuffer, diveBufNr, rc));
736// }
737
738 } // end of 3rd case
739 } // End of alloc surfaces
740
741 width = DDSurfaceDesc.dwWidth;
742 height = DDSurfaceDesc.dwHeight;
743
744 if( dwCaps & DDSCAPS_COMPLEX)
745 {
746 // remove the flag
747 dwCaps &= ~DDSCAPS_COMPLEX;
748 dprintf(("DDRAW: Complex Surface\n"));
749
750 if(DDSurfaceDesc.dwFlags & DDSD_BACKBUFFERCOUNT)
751 {
752 dprintf(("DDRAW: Backbuffer # = %d\n",DDSurfaceDesc.dwBackBufferCount));
753
754#if 1
755 memset( &ComplexSurfaceDesc,
756 0,
757 sizeof(DDSURFACEDESC2));
758
759 ComplexSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
760 ComplexSurfaceDesc.dwFlags = DDSD_CAPS |
761 DDSD_WIDTH |
762 DDSD_HEIGHT |
763 DDSD_PIXELFORMAT;
764 ComplexSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
765 ComplexSurfaceDesc.dwHeight = DDSurfaceDesc.dwHeight;
766 ComplexSurfaceDesc.dwWidth = DDSurfaceDesc.dwWidth;
767 ComplexSurfaceDesc.ddpfPixelFormat.dwFlags = DDSurfaceDesc.ddpfPixelFormat.dwFlags;
768 ComplexSurfaceDesc.ddpfPixelFormat.dwRBitMask = DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
769 ComplexSurfaceDesc.ddpfPixelFormat.dwGBitMask = DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
770 ComplexSurfaceDesc.ddpfPixelFormat.dwBBitMask = DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
771 ComplexSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
772
773 if(DDSurfaceDesc.dwBackBufferCount>1)
774 {
775 ComplexSurfaceDesc.dwFlags |=DDSD_BACKBUFFERCOUNT;
776 ComplexSurfaceDesc.dwBackBufferCount = DDSurfaceDesc.dwBackBufferCount -1;
777 ComplexSurfaceDesc.ddsCaps.dwCaps|= DDSCAPS_COMPLEX;
778 }
779
780 BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, TRUE);
781 BackBuffer->Vtbl.fnAddRef((IDirectDrawSurface *)BackBuffer);
782
783 if (BackBuffer->GetLastError()==DD_OK)
784 {
785 dprintf(("DDRAW: created backbuffer"));
786 DDSurfaceDesc.dwFlags |= DDSCAPS_FLIP;
787 BackBuffer->SetFrontBuffer(this);
788 }
789 else
790 {
791 dprintf(("DDRAW: Error creating backbuffer"));
792 }
793#else
794 memcpy( &ComplexSurfaceDesc,
795 &DDSurfaceDesc,
796 sizeof(DDSURFACEDESC2));
797 ComplexSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
798 ComplexSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP; // set flip
799 ComplexSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; // remove backbuffer
800
801 if(ComplexSurfaceDesc.dwBackBufferCount>1)
802 {
803 ComplexSurfaceDesc.dwBackBufferCount--;
804 }
805 else
806 {
807 ComplexSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
808 ComplexSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_COMPLEX;
809 }
810 BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, Mainchain);
811 BackBuffer->Vtbl.fnAddRef((IDirectDrawSurface *)BackBuffer);
812
813 if (BackBuffer->GetLastError()==DD_OK)
814 {
815 DDSurfaceDesc.dwFlags |= DDSCAPS_FLIP;
816 BackBuffer->SetFrontBuffer(this);
817 }
818#endif
819 }
820
821 // MipMap Surfaces are handled here
822 if( (DDSurfaceDesc.dwFlags & DDSD_MIPMAPCOUNT) &&
823 (dwCaps & DDSCAPS_TEXTURE) &&
824 (dwCaps & DDSCAPS_MIPMAP) )
825 {
826 dwCaps &= ~ (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP);
827
828 dprintf(("DDRAW: Mipmpa # = %d\n",DDSurfaceDesc.dwMipMapCount));
829 memcpy( &ComplexSurfaceDesc,
830 &DDSurfaceDesc,
831 sizeof(DDSURFACEDESC2));
832 ComplexSurfaceDesc.dwMipMapCount = 0;
833 ComplexSurfaceDesc.dwFlags &= ~DDSD_MIPMAPCOUNT;
834
835 for(int i =0; i < DDSurfaceDesc.dwMipMapCount; i++)
836 {
837 dprintf(("DDRAW: Creating MipMap %d\n",i));
838 // Mpmaps shirnk by 2
839 ComplexSurfaceDesc.dwWidth /= 2;
840 ComplexSurfaceDesc.dwHeight /= 2;
841
842 MipMapSurface = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE);
843 MipMapSurface->Vtbl.fnAddRef((IDirectDrawSurface *)MipMapSurface);
844
845 DPA_InsertPtr( DPA_SurfaceMipMaps,
846 DPA_GetPtrCount(DPA_SurfaceMipMaps),
847 MipMapSurface);
848
849 if(MipMapSurface->GetLastError() != DD_OK)
850 {
851 lastError = MipMapSurface->GetLastError();
852 dprintf(("DDRAW: Attached surface creation returned error %d\n",lastError));
853 return;
854 } // Endif Errorcheck
855 } //End for(i =0; i < DDSurfaceDesc.dwMipMapCount; i++)
856 } // End of MipMaps
857
858 #if 0
859 if(DDSurfaceDesc.dwFlags)
860 dprintf(("DDRAW: Unsupported Complex Surface\n"));
861 #endif
862 } // Endif DDSCAPS_COMPLEX
863 }
864 else
865 {
866 lastError = DDERR_INVALIDPARAMS;
867 }
868 } // Endif DDCAPS is valid
869 else
870 {
871 dprintf(("DDRAW: CAPS not valid\n"));
872 lastError = DDERR_INVALIDPARAMS;
873 }
874 dprintf(("DDRAW: Buf %X Screen Caps (%d,%d), bitcount %d\n\n", this, lpDraw->GetScreenHeight(), lpDraw->GetScreenWidth(),
875 lpDraw->dCaps.ulDepth));
876 if(DD_OK!=lastError)
877 {
878 dprintf(("DDRAW: Some Error Check Flags\n"));
879 _dump_DDSCAPS(DDSurfaceDesc.dwFlags);
880 }
881}
882//******************************************************************************
883//******************************************************************************
884HRESULT OS2IDirectDrawSurface::DoColorFill(LPRECT lpDestRect,DWORD dwFillColor)
885{
886
887 int FillWidth, FillHeight, Top, Left;
888 DWORD *pPal24;
889 WORD *pPal16;
890 dprintf(("DDRAW: ColorFill with %08X\n", dwFillColor));
891
892 if(NULL!=lpDestRect)
893 {
894 dprintf(("DDRAW: Fill only Rect(%d,%d)(%d,%d) (%d,%d)", lpDestRect->left, lpDestRect->top,
895 lpDestRect->right, lpDestRect->bottom, width, height));
896 FillWidth = RECT_WIDTH(lpDestRect);
897 FillHeight = RECT_HEIGHT(lpDestRect);
898 Top = lpDestRect->top;
899 Left = lpDestRect->left;
900 if(Top + FillHeight > height) {
901 FillHeight = height - Top;
902 dprintf(("correcting FillHeight to %d", FillHeight));
903 }
904 if(Left + FillWidth > width) {
905 FillWidth = width - Left;
906 dprintf(("correcting FillWidth to %d", FillWidth));
907 }
908 }
909 else
910 {
911 dprintf(("DDRAW: Fill all at addr "));
912 Top = 0;
913 Left = 0;
914 FillWidth = width;
915 FillHeight = height;
916 //pLine = pDiveBuffer;
917 }
918 //dprintf(("DDRAW: 0x%08X (%d/%d) at\n", pLine,FillWidth,FillHeight));
919
920 // Better safe than sorry
921 if (FillHeight <= 0)
922 return(DD_OK);
923
924 if(pDiveBuffer!=pFrameBuffer)
925 {
926 if( (NULL== lpDraw->pPrimSurf) ||
927 (NULL== ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette) )
928 {
929 if(!fPalInit)
930 {
931 for(DWORD i=0;i<256;i++)
932 {
933 wDefaultPalete16[i] = (DefaultPalette[i*3+2]>>3) +
934 ((DefaultPalette[i*3+1]>>2) <<5) +
935 ((DefaultPalette[i*3]>>3) << 11);
936 dwDefaultPalete24[i]= ((DefaultPalette[i*3+2]>>3) <<8)+
937 ((DefaultPalette[i*3+1]>>2) <<16) +
938 ((DefaultPalette[i*3]>>3) << 24);
939 dprintf(( " # %d : RGB=%02X/%02X/%02X => %04X\n",
940 i,
941 DefaultPalette[i*3],
942 DefaultPalette[i*3+1],
943 DefaultPalette[i*3+2],
944 wDefaultPalete16[i]));
945 // aPal24[i] = (lpColorTable[i].peBlue <<8) +
946 // (lpColorTable[i].peGreen<<16) +
947 // (lpColorTable[i].peRed<<24);
948 }
949 fPalInit = TRUE;
950 }
951 pPal16 = &wDefaultPalete16[0];
952 pPal24 = &dwDefaultPalete24[0];
953 }
954 else
955 {
956 pPal16 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal16;
957 pPal24 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal24;
958 }
959 }
960
961 if(NULL!=ColorFill) {
962 ColorFill( pDiveBuffer, pFrameBuffer, Top, Left,
963 FillWidth, FillHeight, dwPitchDB,dwPitchFB,
964 dwFillColor,(16==lpDraw->dCaps.ulDepth)?(VOID*)pPal16:(VOID*)pPal24);
965 SurfChangeUniquenessValue(this);
966 }
967 else
968 {
969 dprintf(("DDRAW: ColorFill function is NULL!!"));
970 }
971
972 return(DD_OK);
973}
974//******************************************************************************
975//******************************************************************************
976void OS2IDirectDrawSurface::ColorConversion(LPRECT lpRect)
977{
978 //char *pSrc,*pDst,*pSLine,*pDLine;
979 DWORD CCwidth,CCheight,x,y;
980 DWORD *pPal24;
981 WORD *pPal16;
982
983 if( (NULL== lpDraw->pPrimSurf) ||
984 (NULL== ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette) )
985 {
986 if(!fPalInit)
987 {
988 for(DWORD i=0;i<256;i++)
989 {
990 wDefaultPalete16[i] = (DefaultPalette[i*3+2]>>3) +
991 ((DefaultPalette[i*3+1]>>2) <<5) +
992 ((DefaultPalette[i*3]>>3) << 11);
993 dwDefaultPalete24[i]= ((DefaultPalette[i*3+2]>>3) <<8)+
994 ((DefaultPalette[i*3+1]>>2) <<16) +
995 ((DefaultPalette[i*3]>>3) << 24);
996 dprintf(( " # %d : RGB=%02X/%02X/%02X => %04X\n",
997 i,
998 DefaultPalette[i*3],
999 DefaultPalette[i*3+1],
1000 DefaultPalette[i*3+2],
1001 wDefaultPalete16[i]));
1002 // aPal24[i] = (lpColorTable[i].peBlue <<8) +
1003 // (lpColorTable[i].peGreen<<16) +
1004 // (lpColorTable[i].peRed<<24);
1005 }
1006 fPalInit = TRUE;
1007 }
1008 pPal16 = &wDefaultPalete16[0];
1009 pPal24 = &dwDefaultPalete24[0];
1010 }
1011 else
1012 {
1013 pPal16 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal16;
1014 pPal24 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal24;
1015 }
1016
1017 if(NULL==lpRect)
1018 {
1019 //pSrc = pFrameBuffer;
1020 //pDst = pDiveBuffer;
1021 CCwidth = width;
1022 CCheight = height;
1023 x = 0;
1024 y = 0;
1025 }
1026 else
1027 {
1028 // ToDo: Check why the top/bottom values come in swaped here
1029 // for now simply reverse them with the following 3 lines
1030 y = lpRect->top;
1031 lpRect->top = lpRect->bottom;
1032 lpRect->bottom = y;
1033 // end of hack
1034 #if 0
1035 pSrc = pFrameBuffer +
1036 (lpRect->top * dwPitchFB) +
1037 (lpRect->left* (lpDraw->dCaps.ulDepth/8));
1038 pDst = pDiveBuffer +
1039 (lpRect->top * dwPitchDB) +
1040 (lpRect->left* dwBytesPPDive);
1041 #endif
1042 y = lpRect->top;
1043 x = lpRect->left;
1044 CCwidth = lpRect->right - lpRect->left;
1045 CCheight = lpRect->bottom - lpRect->top;
1046
1047 }
1048
1049// dprintf( ("H: %d W: %d\n SRC @ %08X\n DST @ %08X\n",
1050// CCheight, CCwidth, pSrc,pDst));
1051 if(NULL!=ColorConv)
1052 ColorConv( pDiveBuffer, pFrameBuffer, y, x,
1053 CCwidth, CCheight, dwPitchDB,dwPitchFB,
1054 16==lpDraw->dCaps.ulDepth?(VOID*)pPal16:(VOID*)pPal24);
1055 else
1056 {
1057 dprintf(("DDRAW: ColorConv function is NULL!!"));
1058 }
1059
1060/*
1061 pSLine = pSrc;
1062 pDLine = pDst;
1063
1064 switch(lpDraw->dCaps.ulDepth)
1065 {
1066 case 8:
1067 dprintf(("DDRAW: 8Bit target CC not implemented\n"));
1068 break;
1069 case 15:
1070 dprintf(("DDRAW: 15 Bit not implemented using 16bit might look ugly\n"));
1071 case 16:
1072 if(8==lpDraw->GetScreenBpp())
1073 {
1074 dprintf(("DDRAW: 8->16Bit CC\n"));
1075 for(y=0;CCheight;CCheight--,y++)
1076 {
1077 for(x=0;x<width;x++)
1078 {
1079 *(((WORD*)pDLine)+x) = pPal16[pSLine[x]];
1080
1081 }
1082 pSLine += dwPitchFB;
1083 pDLine += dwPitchDB;
1084 }
1085 }
1086 else
1087 {
1088 dprintf(("DDRAW: %d ->16Bit Not implemented",lpDraw->GetScreenBpp()));
1089 }
1090 break;
1091 case 24:
1092 if(8==lpDraw->GetScreenBpp())
1093 {
1094 dprintf(("DDRAW: 8->24Bit CC"));
1095 for(y=0;CCheight;CCheight--,y++)
1096 {
1097 char *pIter;
1098 for(x=0,pIter=pDLine;x<width;x++,pIter=pDLine)
1099 {
1100 *((DWORD*)pIter) = pPal24[pSLine[x]];
1101 pIter+=3;
1102 }
1103 pSLine += dwPitchFB;
1104 pDLine += dwPitchDB;
1105 }
1106 }
1107 else
1108 {
1109 dprintf(("DDRAW: %d ->24Bit Not implemented",lpDraw->GetScreenBpp()));
1110 }
1111 break;
1112 case 32:
1113 if(8==lpDraw->GetScreenBpp())
1114 {
1115 dprintf(("DDRAW: 8->32Bit CC"));
1116 for(y=0;CCheight;CCheight--,y++)
1117 {
1118 for(x=0;x<width;x++)
1119 {
1120 *(((DWORD*)pDLine)+x) = pPal24[pSLine[x]];
1121
1122 }
1123 pSLine += dwPitchFB;
1124 pDLine += dwPitchDB;
1125 }
1126 }
1127 else
1128 {
1129 dprintf(("DDRAW: %d ->32Bit Not implemented",lpDraw->GetScreenBpp()));
1130 }
1131 break;
1132 default:
1133 dprintf( ("Unexpected Screen Bitdepth %d\n",
1134 lpDraw->dCaps.ulDepth));
1135 break;
1136 }
1137*/
1138}
1139//******************************************************************************
1140//******************************************************************************
1141// Internal callbacks uses by destructor
1142INT CALLBACK DestroyRects(LPVOID lpItem, DWORD dwRes)
1143{
1144 DDRectangle *pItem = (DDRectangle*) lpItem;
1145 delete(pItem);
1146 return 1;
1147}
1148
1149INT CALLBACK ReleaseSurfaces(LPVOID lpItem, DWORD dwRes)
1150{
1151 OS2IDirectDrawSurface *pSurf;
1152 pSurf = (OS2IDirectDrawSurface *)lpItem;
1153 pSurf->Vtbl.fnRelease(pSurf);
1154 return 1;
1155}
1156//******************************************************************************
1157//******************************************************************************
1158OS2IDirectDrawSurface::~OS2IDirectDrawSurface()
1159{
1160 if(hwndFullScreen) {
1161 DestroyWindow(hwndFullScreen);
1162 }
1163
1164 if(DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1165 {
1166 lpDraw->SetPrimarySurface(FALSE);
1167 if(lpPalette)
1168 lpPalette->RestorePhysPalette();
1169
1170 }
1171 else
1172 {
1173 if( diveBufNr != -1)
1174 {
1175 if(fLocked)
1176 DiveEndImageBufferAccess(hDive, diveBufNr);
1177 DiveFreeImageBuffer(hDive, diveBufNr);
1178
1179 }
1180
1181 fLocked = FALSE;
1182 diveBufNr = -1;
1183 }
1184 // Free Buffers if they have been allocated
1185 // DIVE Buffer
1186
1187 if(NULL!=pDBreal)
1188 free(pDBreal);
1189
1190 // FrameBuffer
1191
1192 if(NULL!=pFBreal)
1193 free(pFBreal);
1194
1195 // Clear the list of locked rectangles
1196 if (DPA_GetPtrCount(DPA_LockedRects)>0)
1197 {
1198 DPA_DestroyCallback( DPA_LockedRects,
1199 DestroyRects,
1200 0);
1201 }
1202
1203 if(lpClipper)
1204 {
1205 lpClipper->Vtbl.fnRelease((IDirectDrawClipper*)lpClipper);
1206 lpClipper = NULL;
1207 }
1208
1209 if(lpPalette)
1210 {
1211 lpPalette->Vtbl.fnRelease((IDirectDrawPalette*)lpPalette);
1212 lpPalette = NULL;
1213 }
1214
1215 if(hbmImage)
1216 DeleteObject(hbmImage);
1217
1218 if(hdcImage)
1219 DeleteDC(hdcImage);
1220
1221 if (NULL!=BackBuffer)
1222 BackBuffer->Vtbl.fnRelease(BackBuffer);
1223
1224 if (DPA_GetPtrCount(DPA_SurfaceMipMaps)>0)
1225 {
1226 DPA_DestroyCallback( DPA_SurfaceMipMaps,
1227 ReleaseSurfaces,
1228 0);
1229 }
1230
1231 if (DPA_GetPtrCount(DPA_SurfaceAttached)>0)
1232 {
1233 DPA_DestroyCallback( DPA_SurfaceAttached,
1234 ReleaseSurfaces,
1235 0);
1236 }
1237
1238 lpDraw->Vtbl.fnRelease(lpDraw);
1239}
1240
1241//******************************************************************************
1242//******************************************************************************
1243inline void OS2IDirectDrawSurface::SetFrontBuffer( OS2IDirectDrawSurface* NewFBuffer)
1244{
1245 FrontBuffer = NewFBuffer;
1246 if (NULL==NewFBuffer)
1247 {
1248
1249 dprintf(("DDRAW: Remove Frontbuffer\n"));
1250
1251 // The real Frontbuffer was removed check if I'm now the one
1252 if(NULL!=BackBuffer)
1253 {
1254 dprintf(("DDRAW: We have the a backbuffer so we're the Frontbuffer\n"));
1255 NextFlip = BackBuffer;
1256 DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER;
1257 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1258 BackBuffer->SetFrontBuffer(this);
1259 }
1260 else
1261 {
1262 // Flipchain is destroyed
1263 dprintf(("DDRAW: No longer part of a flipchain\n"));
1264 DDSurfaceDesc.ddsCaps.dwCaps &= ~(DDSCAPS_BACKBUFFER | DDSCAPS_FLIP);
1265 }
1266 }
1267 else
1268 {
1269 dprintf(("DDRAW: Set new Frontbuffer to 0x%08X\n",NewFBuffer));
1270 if(NULL==NewFBuffer->GetFrontBuffer())
1271 {
1272 dprintf(("DDRAW: We're the 1st backbuffer\n"));
1273 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
1274 FrontBuffer->NextFlip = this;
1275 }
1276 else
1277 {
1278 dprintf(("DDRAW: We are one of many buffers\n"));
1279 DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER ;
1280 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
1281 }
1282
1283 if(NULL!=BackBuffer)
1284 BackBuffer->SetFrontBuffer(this);
1285
1286 DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER;
1287 }
1288}
1289//******************************************************************************
1290//******************************************************************************
1291HRESULT WIN32API SurfQueryInterface(THIS This, REFIID riid, LPVOID FAR * ppvObj)
1292{
1293 // ToDo: Add Interface handling for D3D Textures
1294 HRESULT rc;
1295 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1296
1297 dprintf(("DDRAW: OS2IDirectDrawSurface::SurfQueryInterface\n"));
1298
1299 if(NULL==ppvObj)
1300 {
1301 rc = DDERR_INVALIDPARAMS;
1302 goto RetFn;
1303 }
1304
1305 rc = E_NOINTERFACE;
1306 *ppvObj = NULL;
1307
1308 if(IsEqualGUID(riid, &IID_IDirectDrawSurface))
1309 {
1310 *ppvObj = &me->lpVtbl; // ToDo DO a real V1 table
1311 rc = DD_OK;
1312 goto RetFn;
1313 }
1314 if(IsEqualGUID(riid, &IID_IDirectDrawSurface2))
1315 {
1316 *ppvObj = &me->lpVtbl2;
1317 rc = DD_OK;
1318 goto RetFn;
1319 }
1320 if(IsEqualGUID(riid, &IID_IDirectDrawSurface3))
1321 {
1322 *ppvObj = &me->Vtbl3;
1323 rc = DD_OK;
1324 goto RetFn;
1325 }
1326 if(IsEqualGUID(riid, &IID_IDirectDrawSurface4))
1327 {
1328 *ppvObj = This;
1329 rc =DD_OK;
1330 }
1331
1332 //if(IsEqualGUID(riid, &IID_IUnknown)) ...
1333
1334RetFn:
1335
1336 if(DD_OK==rc)
1337 SurfAddRef(This);
1338
1339 return(rc);
1340}
1341//******************************************************************************
1342//******************************************************************************
1343ULONG WIN32API SurfAddRef(THIS This)
1344{
1345 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1346
1347 dprintf(("DDRAW: OS2IDirectDrawSurface::SurfAddRef %d\n", me->Referenced+1));
1348
1349 return ++me->Referenced;
1350}
1351//******************************************************************************
1352//******************************************************************************
1353ULONG WIN32API SurfRelease(THIS This)
1354{
1355 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1356
1357 dprintf(("DDRAW: OS2IDirectDrawSurface::SurfRelease %d\n", me->Referenced-1));
1358 dprintf(("DDRAW: OS2IDirectDrawSurface::Surface %X\n", me));
1359 if(me->Referenced)
1360 {
1361 me->Referenced--;
1362 if(me->Referenced == 0)
1363 {
1364 delete( me);
1365 #ifndef __WATCOMC__
1366 //_interrupt(3);
1367 #endif
1368 return(0);
1369 }
1370 else
1371 return me->Referenced;
1372 }
1373 else
1374 return(0);
1375}
1376//******************************************************************************
1377//******************************************************************************
1378HRESULT WIN32API SurfAddAttachedSurface(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurface)
1379{
1380
1381 dprintf(("DDRAW: SurfAddAttachedSurface\n"));
1382 return SurfAddAttachedSurface4(This, (LPDIRECTDRAWSURFACE4)lpDDSurface);
1383}
1384//******************************************************************************
1385//******************************************************************************
1386HRESULT WIN32API SurfAddAttachedSurface3(THIS This, LPDIRECTDRAWSURFACE3 lpDDSurface)
1387{
1388
1389 dprintf(("DDRAW: SurfAddAttachedSurface\n"));
1390 return SurfAddAttachedSurface4(This, (LPDIRECTDRAWSURFACE4)lpDDSurface);
1391}
1392//******************************************************************************
1393//******************************************************************************
1394HRESULT WIN32API SurfAddAttachedSurface4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurface)
1395{
1396 OS2IDirectDrawSurface *AttachedSurface;
1397 OS2IDirectDrawSurface *BBCursor;
1398 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1399 int rc;
1400
1401 dprintf(("DDRAW: SurfAddAttachedSurface4\n"));
1402
1403 if (NULL==lpDDSurface)
1404 return DDERR_INVALIDPARAMS;
1405
1406 AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface;
1407
1408 if(AttachedSurface->IsImplicitSurface())
1409 {
1410 dprintf(("DDRAW: Internal : Can't attach an implicitly created surface to another surface\n"));
1411 return(DDERR_CANNOTATTACHSURFACE);
1412 }
1413
1414 if(This == AttachedSurface)
1415 {
1416 dprintf(("DDRAW: Can't attach a surface to itself\n"));
1417 return(DDERR_CANNOTATTACHSURFACE);
1418 }
1419
1420 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)
1421 {
1422 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1423 {
1424 if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1425 {
1426 rc = DPA_InsertPtr( me->DPA_SurfaceMipMaps,
1427 DPA_GetPtrCount(me->DPA_SurfaceMipMaps),
1428 AttachedSurface);
1429
1430 if( rc>=0)
1431 {
1432 me->DDSurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT;
1433 me->DDSurfaceDesc.dwMipMapCount++;
1434
1435 AttachedSurface->Vtbl.fnAddRef(AttachedSurface);
1436 }
1437 else
1438 {
1439 dprintf(("DDRAW: Internal : Error attaching to MipMap\n"));
1440 return(DDERR_CANNOTATTACHSURFACE);
1441 }
1442 }
1443 else
1444 {
1445 dprintf(("DDRAW: Target Surface isn't a MipMap\n"));
1446 return(DDERR_CANNOTATTACHSURFACE);
1447 }
1448 }
1449 else
1450 {
1451 rc = DPA_InsertPtr( me->DPA_SurfaceAttached,
1452 DPA_GetPtrCount(me->DPA_SurfaceAttached),
1453 AttachedSurface);
1454
1455 if(rc>=0)
1456 {
1457 AttachedSurface->Vtbl.fnAddRef(AttachedSurface);
1458 }
1459 else
1460 {
1461 dprintf(("DDRAW: Internal : Error attaching to general Set\n"));
1462 return(DDERR_CANNOTATTACHSURFACE);
1463 }
1464 }
1465 } // endif DDSCAPS_TEXTURE
1466 else
1467 {
1468 if( (AttachedSurface->DDSurfaceDesc.dwWidth != me->DDSurfaceDesc.dwWidth)
1469 || (AttachedSurface->DDSurfaceDesc.dwHeight != me->DDSurfaceDesc.dwHeight)
1470 // || (AttachedSurface->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount !=
1471 // me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
1472 )
1473 {
1474 dprintf(("DDRAW: Surfaces don't have equal dimensions\n"));
1475 return(DDERR_CANNOTATTACHSURFACE);
1476 }
1477 else
1478 {
1479 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)
1480 {
1481 if( (AttachedSurface->GetFrontBuffer()!=NULL) || (AttachedSurface->BackBuffer!= NULL))
1482 {
1483 dprintf(("DDRAW: Surface already has a front/backbuffer\n"));
1484 return(DDERR_SURFACEALREADYATTACHED);
1485 }
1486
1487 if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
1488 {
1489 if(NULL!=me->BackBuffer)
1490 {
1491 BBCursor = me->BackBuffer;
1492 while(NULL!=BBCursor)
1493 {
1494 BBCursor->DDSurfaceDesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
1495 BBCursor->DDSurfaceDesc.dwBackBufferCount++;
1496 BBCursor->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
1497 BBCursor = BBCursor->BackBuffer;
1498 }
1499 BBCursor->BackBuffer = AttachedSurface;
1500 AttachedSurface->SetFrontBuffer(BBCursor);
1501 }
1502 else
1503 {
1504 me->BackBuffer = AttachedSurface;
1505 AttachedSurface->SetFrontBuffer(me);
1506 }
1507 me->DDSurfaceDesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
1508 me->DDSurfaceDesc.dwBackBufferCount++;
1509 me->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
1510
1511 AttachedSurface->Vtbl.fnAddRef(AttachedSurface);
1512 return (DD_OK);
1513 }
1514 else
1515 {
1516 dprintf(("DDRAW: Can't attach backbuffer to anything but a frontbuffer\n"));
1517 return(DDERR_CANNOTATTACHSURFACE);
1518 }
1519 }
1520 else
1521 {
1522 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1523 {
1524 if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1525 {
1526 if( DPA_InsertPtr( me->DPA_SurfaceMipMaps,
1527 DPA_GetPtrCount(me->DPA_SurfaceMipMaps),
1528 AttachedSurface) >=0)
1529 {
1530 me->DDSurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT;
1531 me->DDSurfaceDesc.dwMipMapCount++;
1532 me->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1533
1534 AttachedSurface->Vtbl.fnAddRef(AttachedSurface);
1535 }
1536 else
1537 {
1538 dprintf(("DDRAW: Internal : Error attaching to MipMap\n"));
1539 return(DDERR_CANNOTATTACHSURFACE);
1540 }
1541 }
1542 else
1543 {
1544 dprintf(("DDRAW: Target Surface isn't a MipMap\n"));
1545 return(DDERR_CANNOTATTACHSURFACE);
1546 }
1547 }
1548 else
1549 {
1550 if( DPA_InsertPtr( me->DPA_SurfaceAttached,
1551 DPA_GetPtrCount(me->DPA_SurfaceAttached),
1552 AttachedSurface) >=0)
1553 {
1554 AttachedSurface->Vtbl.fnAddRef(AttachedSurface);
1555 }
1556 else
1557 {
1558 dprintf(("DDRAW: Internal : Error attaching to general Set\n"));
1559 return(DDERR_CANNOTATTACHSURFACE);
1560 }
1561 }
1562 }// End if not DDSCAPS_BACKBUFFER
1563 }
1564 }
1565 dprintf(("DDRAW: Surface attached\n"));
1566 return(DD_OK);
1567}
1568//******************************************************************************
1569//******************************************************************************
1570HRESULT WIN32API SurfDeleteAttachedSurface(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSurface)
1571{
1572 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1573 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
1574
1575 return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface));
1576}
1577//******************************************************************************
1578//******************************************************************************
1579HRESULT WIN32API SurfDeleteAttachedSurface3(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSurface)
1580{
1581 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1582 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
1583
1584 return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface));
1585}
1586//******************************************************************************
1587//******************************************************************************
1588HRESULT WIN32API SurfDeleteAttachedSurface4(THIS This, DWORD dwFlags , LPDIRECTDRAWSURFACE4 lpDDSurface)
1589{
1590
1591 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1592 OS2IDirectDrawSurface *AttachedSurface;
1593 OS2IDirectDrawSurface *SurfaceCursor;
1594 int i;
1595
1596 BOOL Found = FALSE;
1597 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
1598
1599 if((0!=dwFlags)||(NULL==lpDDSurface))
1600 return(DDERR_INVALIDPARAMS);
1601
1602 AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface;
1603 if (AttachedSurface->IsImplicitSurface())
1604 return (DDERR_CANNOTDETACHSURFACE);
1605
1606 if ( (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP | DDSCAPS_BACKBUFFER)) &&
1607 !(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) )
1608 {
1609 // Surface seams to be a backbuffer in a flipchain search it
1610
1611 // Goto top of list
1612 if(me->FrontBuffer!=NULL)
1613 {
1614 SurfaceCursor = me->FrontBuffer;
1615 while(SurfaceCursor->GetFrontBuffer()!=NULL)
1616 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
1617 }
1618 else
1619 SurfaceCursor = me;
1620
1621 // now iterrate through the list skip first in list as we don't remove the frontbuffer
1622
1623 SurfaceCursor = SurfaceCursor->BackBuffer;
1624 while((SurfaceCursor!= AttachedSurface)&&(SurfaceCursor!=NULL))
1625 SurfaceCursor = SurfaceCursor->BackBuffer;
1626
1627 if(SurfaceCursor!=NULL)
1628 {
1629 Found = TRUE;
1630 // remove the Surface from the list
1631 SurfaceCursor->FrontBuffer->BackBuffer = SurfaceCursor->BackBuffer;
1632 if(SurfaceCursor->BackBuffer!=NULL)
1633 {
1634 SurfaceCursor->BackBuffer->SetFrontBuffer(SurfaceCursor->FrontBuffer);
1635
1636 }
1637 else
1638 {
1639 // we were the last buffer in the list have we been the only backbuffer?
1640 if(SurfaceCursor->FrontBuffer->FrontBuffer == NULL)
1641 {
1642 // Yepp so "destroy" the flipchain
1643 SurfaceCursor->FrontBuffer->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
1644 SurfaceCursor->FrontBuffer->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1645 }
1646 }
1647 // decrement the backbuffer count of all buffers in the chain in front of us
1648 while(SurfaceCursor->GetFrontBuffer()!=NULL)
1649 {
1650 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
1651 SurfaceCursor->DDSurfaceDesc.dwBackBufferCount-- ;
1652 }
1653
1654 AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
1655 AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1656 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
1657 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; // Set this flag as adding to the chain removed it
1658 AttachedSurface->lpVtbl->fnRelease(AttachedSurface);
1659
1660 }
1661 } //endif delete back/frontbuffers
1662
1663 if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP & DDSCAPS_FRONTBUFFER)) )
1664 {
1665 // seams like someone wants a new frontbuffer
1666
1667 // Goto top of list
1668
1669 if(me->FrontBuffer!=NULL)
1670 {
1671 SurfaceCursor = me->FrontBuffer;
1672 while(SurfaceCursor->GetFrontBuffer()!=NULL)
1673 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
1674 }
1675 else
1676 SurfaceCursor = me;
1677
1678 if(SurfaceCursor == AttachedSurface)
1679 {
1680 Found = TRUE;
1681 SurfaceCursor->BackBuffer->SetFrontBuffer(NULL);
1682 AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
1683 AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1684 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
1685 AttachedSurface->lpVtbl->fnRelease(AttachedSurface);
1686 }
1687
1688 }
1689
1690
1691 if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP ) )
1692 {
1693 // Surface seams to be a mipmap
1694 i = 0;
1695 while((DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>i ) && !Found)
1696 {
1697 if (DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i) == AttachedSurface)
1698 {
1699 Found = TRUE;
1700 DPA_DeletePtr(me->DPA_SurfaceMipMaps,i);
1701 AttachedSurface->lpVtbl->fnRelease(AttachedSurface);
1702 // adjust our info
1703 me->DDSurfaceDesc.dwMipMapCount-- ;
1704 if (!me->DDSurfaceDesc.dwMipMapCount)
1705 {
1706 me->DDSurfaceDesc.dwFlags &= ~DDSD_MIPMAPCOUNT;
1707 }
1708 }
1709 i++;
1710 }
1711 }
1712
1713 if(!Found)
1714 {
1715 // Surface seams to be an attached one
1716 i = 0;
1717 while((DPA_GetPtrCount(me->DPA_SurfaceAttached)>i ) && !Found)
1718 {
1719 if (DPA_FastGetPtr(me->DPA_SurfaceAttached,i) == AttachedSurface)
1720 {
1721 Found = TRUE;
1722 DPA_DeletePtr(me->DPA_SurfaceAttached,i);
1723 AttachedSurface->lpVtbl->fnRelease(AttachedSurface);
1724 }
1725 i++;
1726 }
1727 }
1728
1729
1730 return(Found?DD_OK:DDERR_SURFACENOTATTACHED);
1731}
1732//******************************************************************************
1733//******************************************************************************
1734HRESULT WIN32API SurfEnumAttachedSurfaces(THIS This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpCallBack)
1735{
1736 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1737 dprintf(("DDRAW: SurfEnumAttachedSurfaces\n"));
1738
1739 return(SurfEnumAttachedSurfaces4(me,lpContext, (LPDDENUMSURFACESCALLBACK2) lpCallBack));
1740}
1741//******************************************************************************
1742//******************************************************************************
1743HRESULT WIN32API SurfEnumAttachedSurfaces4(THIS This, LPVOID lpContext ,LPDDENUMSURFACESCALLBACK2 lpCallBack)
1744{
1745 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1746 OS2IDirectDrawSurface *EnumSurface;
1747 DDSURFACEDESC2 EnumDesc;
1748 int i,count;
1749 HRESULT rc;
1750
1751 dprintf(("DDRAW: SurfEnumAttachedSurfaces\n"));
1752 if (NULL==lpCallBack)
1753 return (DDERR_INVALIDPARAMS);
1754
1755 rc = DDENUMRET_OK;
1756
1757
1758 if(me->BackBuffer != NULL)
1759 {
1760 memcpy(&EnumDesc,&(me->DDSurfaceDesc),sizeof(DDSURFACEDESC2));
1761 rc = lpCallBack((LPDIRECTDRAWSURFACE4)me->BackBuffer,&EnumDesc,lpContext);
1762 }
1763
1764 count = DPA_GetPtrCount(me->DPA_SurfaceMipMaps);
1765
1766 if(count>0)
1767 {
1768 i=0;
1769 while( (DDENUMRET_OK == rc) && i<count )
1770 {
1771 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i);
1772 memcpy( &EnumDesc,
1773 &(EnumSurface->DDSurfaceDesc),
1774 sizeof(DDSURFACEDESC2));
1775 // Calling back into WIN32 app so we had to reset FS
1776 rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
1777 i++;
1778 }
1779 }
1780
1781 count = DPA_GetPtrCount(me->DPA_SurfaceAttached);
1782
1783 if(count>0)
1784 {
1785 i=0;
1786 while( (DDENUMRET_OK == rc) && i<count )
1787 {
1788 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceAttached,i);
1789 memcpy( &EnumDesc,
1790 &(EnumSurface->DDSurfaceDesc),
1791 sizeof(DDSURFACEDESC2));
1792 rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
1793 i++;
1794 }
1795 }
1796
1797 return(DD_OK);
1798}
1799//******************************************************************************
1800//******************************************************************************
1801HRESULT WIN32API SurfFlip(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurf, DWORD dwFlags)
1802{
1803 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1804
1805 dprintf(("DDRAW: SurfFlip\n"));
1806
1807 return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags));
1808}
1809//******************************************************************************
1810//******************************************************************************
1811HRESULT WIN32API SurfFlip3(THIS This, LPDIRECTDRAWSURFACE3 lpDDSurf, DWORD dwFlags)
1812{
1813 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1814
1815 dprintf(("DDRAW: SurfFlip\n"));
1816
1817 return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags));
1818}
1819//******************************************************************************
1820//******************************************************************************
1821HRESULT WIN32API SurfFlip4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurf, DWORD dwFlags)
1822{
1823 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1824 OS2IDirectDrawSurface *FlipSurface;
1825 OS2IDirectDrawSurface *FlipCursor;
1826 LPVOID Data;
1827 char *pcrFB,*pcFB,*pcrDB,*pcDB;
1828
1829 dprintf(("DDRAW: SurfFlip4\n"));
1830
1831 if(!((me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) &&
1832 (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FLIP))
1833 )
1834 {
1835 dprintf(("DDRAW: Flip called on none Frontbuffer/Flip surface\n Flags:\n"));
1836 _dump_DDSCAPS(me->DDSurfaceDesc.ddsCaps.dwCaps);
1837 dprintf(("DDRAW: \n"));
1838 return(DDERR_NOTFLIPPABLE);
1839 }
1840
1841 if(NULL!=lpDDSurf)
1842 {
1843 dprintf(("DDRAW: Check if Surface is in Flipchain!\n"));
1844
1845 // We got an override surface check if it is in the flipchain
1846 FlipSurface = (OS2IDirectDrawSurface*) lpDDSurf;
1847 FlipCursor = me->BackBuffer;
1848 while((NULL!=FlipCursor)&&(FlipCursor!=FlipSurface))
1849 {
1850 FlipCursor = FlipCursor->BackBuffer;
1851 }
1852
1853 if(FlipCursor!=FlipSurface)
1854 {
1855 dprintf(("DDRAW: Surface not in Flipchain!\n"));
1856
1857 return (DDERR_INVALIDPARAMS); // Not sure if the returnvalue is right
1858 }
1859 }
1860 else
1861 {
1862 FlipSurface = me->NextFlip; // Take the next Surface in the Flipchain
1863 dprintf(("DDRAW: Next Surface @ 0x%08X\n",FlipSurface));
1864 }
1865
1866 if((me->fLocked)||(FlipSurface->fLocked))
1867 {
1868 dprintf(("DDRAW: Locked surface(s) Dest %d Src %d\n",me->fLocked,FlipSurface->fLocked));
1869
1870 return(DDERR_SURFACEBUSY);
1871 }
1872
1873 if (-1 != me->diveBufNr)
1874 {
1875 //dprintf(("DDRAW: DIVE Flipchain DiveBuffer #%d",FlipSurface->diveBufNr));
1876
1877 // we got some DIVE surfaces
1878 // On Dive Buffers More then Double buffering won't get any perf. gain
1879 // as we have to move all the data to the Frontbuffer and can't simply exchange the pointers
1880 // Doulebuffering should work best.
1881
1882 //rc = DiveBlitImage(me->hDive, FlipSurface->diveBufNr, me->diveBufNr);
1883 //dprintf(("DDRAW: DiveBlitImage rc = 0x%08X\n"));
1884 SurfBltFast4( me,
1885 0,
1886 0,
1887 (LPDIRECTDRAWSURFACE4)FlipSurface,
1888 NULL,
1889 DDBLTFAST_NOCOLORKEY);
1890
1891 if(NULL==lpDDSurf)
1892 {
1893 // advance in the flipchain if no valid override surface was passed in
1894 // if we reached the end of the flipchain The Frontbuffer is the next to flip to
1895 me->NextFlip = FlipSurface->BackBuffer!=NULL?FlipSurface->BackBuffer:me->BackBuffer;
1896 }
1897 }
1898 else
1899 {
1900 dprintf(("DDRAW: Memory Flipchain"));
1901 // Memory Flipchain
1902 //
1903 // ToDo : Check what happens to src/dest colorkeys etc do the move also ?
1904 //
1905 // We only change the memory pointer to the buffers no need to copy all the data
1906 // So the NextFlip is here allways the Backbuffer so we won't advance this
1907 //
1908 // Sample (triple buffering) : Before Flip After Flip
1909 // Buffer: FB BB TB FB BB TB
1910 // Memory: 11 22 33 22 33 11
1911 //
1912
1913 Data = me->DDSurfaceDesc.lpSurface;
1914 pcrFB = me->pFBreal;
1915 pcFB = me->pFrameBuffer;
1916 pcrDB = me->pDBreal;
1917 pcDB = me->pDiveBuffer;
1918 me->DDSurfaceDesc.lpSurface = FlipSurface->DDSurfaceDesc.lpSurface;
1919 me->pFBreal = FlipSurface->pFBreal;
1920 me->pFrameBuffer = FlipSurface->pFrameBuffer;
1921 me->pDBreal = FlipSurface->pDBreal;
1922 me->pDiveBuffer = FlipSurface->pDiveBuffer;
1923
1924 if (NULL==lpDDSurf)
1925 {
1926 while (NULL!=FlipSurface->BackBuffer)
1927 {
1928 FlipSurface->DDSurfaceDesc.lpSurface = FlipSurface->BackBuffer->DDSurfaceDesc.lpSurface;
1929 FlipSurface->pFBreal = FlipSurface->BackBuffer->pFBreal;
1930 FlipSurface->pFrameBuffer = FlipSurface->BackBuffer->pFrameBuffer;
1931 FlipSurface->pDBreal = FlipSurface->BackBuffer->pDBreal;
1932 FlipSurface->pDiveBuffer = FlipSurface->BackBuffer->pDiveBuffer;
1933 FlipSurface = FlipSurface->BackBuffer;
1934 }
1935 }
1936 FlipSurface->DDSurfaceDesc.lpSurface = Data;
1937 FlipSurface->pFBreal = pcrFB;
1938 FlipSurface->pFrameBuffer = pcFB;
1939 FlipSurface->pDBreal = pcrDB;
1940 FlipSurface->pDiveBuffer = pcDB;
1941 }
1942
1943 return DD_OK;
1944}
1945
1946//******************************************************************************
1947//******************************************************************************
1948HRESULT WIN32API SurfGetAttachedSurface(THIS This, LPDDSCAPS lpDDCaps,
1949 LPDIRECTDRAWSURFACE2 FAR * lpDDSurf)
1950{
1951 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1952 dprintf(("DDRAW: SurfGetAttachedSurface\n"));
1953
1954 return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf));
1955}
1956//******************************************************************************
1957//******************************************************************************
1958HRESULT WIN32API SurfGetAttachedSurface3(THIS This, LPDDSCAPS lpDDCaps,
1959 LPDIRECTDRAWSURFACE3 FAR * lpDDSurf)
1960{
1961 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1962 dprintf(("DDRAW: SurfGetAttachedSurface3\n"));
1963
1964 return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf));
1965}
1966//******************************************************************************
1967//******************************************************************************
1968HRESULT WIN32API SurfGetAttachedSurface4(THIS This, LPDDSCAPS2 lpDDCaps,
1969 LPDIRECTDRAWSURFACE4 FAR * lpDDSurf)
1970{
1971 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1972 OS2IDirectDrawSurface *EnumSurface = NULL;
1973 OS2IDirectDrawSurface *AttachedSurface = NULL;
1974 HRESULT rc;
1975 int i;
1976
1977 dprintf(("DDRAW: SurfGetAttachedSurface4\n>Requested Caps: "));
1978 _dump_DDSCAPS(lpDDCaps->dwCaps);
1979 dprintf(("DDRAW: \n"));
1980
1981 if( (NULL==lpDDCaps)||(NULL==lpDDSurf))
1982 {
1983 dprintf(("DDRAW: Invalid params\n\n"));
1984 return (DDERR_INVALIDPARAMS);
1985 }
1986
1987
1988 rc = DD_OK;
1989
1990 if( (me->BackBuffer!=NULL) &&
1991 (me->BackBuffer->DDSurfaceDesc.ddsCaps.dwCaps & lpDDCaps->dwCaps) )
1992 {
1993 dprintf(("DDRAW: Return Backbuffer\n"));
1994 AttachedSurface = me->BackBuffer;
1995 }
1996
1997 if(DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>0)
1998 {
1999 i=0;
2000 while( i<DPA_GetPtrCount(me->DPA_SurfaceMipMaps) )
2001 {
2002 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i);
2003 if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
2004 {
2005 if(NULL==AttachedSurface)
2006 AttachedSurface = EnumSurface;
2007 else
2008 rc = DDERR_NOTFOUND; // Not sure if this is the right return value,
2009 // but function must fail if more then one surface fits
2010
2011 }
2012 i++;
2013 }
2014 }
2015
2016 if(DPA_GetPtrCount(me->DPA_SurfaceAttached)>0)
2017 {
2018 i=0;
2019 while( i<DPA_GetPtrCount(me->DPA_SurfaceAttached) )
2020 {
2021 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceAttached,i);
2022 if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
2023 {
2024 if(NULL==AttachedSurface)
2025 AttachedSurface = EnumSurface;
2026 else
2027 rc = DDERR_NOTFOUND; // Not sure if this is the right return value,
2028 // but function must fail if more then one surface fits
2029
2030 }
2031 i++;
2032 }
2033 }
2034
2035 if( (DD_OK==rc) &&
2036 (NULL!=AttachedSurface) )
2037 {
2038 *lpDDSurf = (IDirectDrawSurface4*)AttachedSurface;
2039 // not sure but as we returned an reference rains usage count
2040 AttachedSurface->lpVtbl->fnAddRef(AttachedSurface);
2041 }
2042 else
2043 {
2044 *lpDDSurf = NULL;
2045 rc = DDERR_NOTFOUND;
2046 }
2047
2048
2049 return rc;
2050}
2051//******************************************************************************
2052//******************************************************************************
2053HRESULT WIN32API SurfGetBltStatus(THIS This, DWORD)
2054{
2055 dprintf(("DDRAW: SurfGetBltStatus\n"));
2056
2057 return(DD_OK);
2058}
2059//******************************************************************************
2060//******************************************************************************
2061HRESULT WIN32API SurfGetCaps(THIS This, LPDDSCAPS lpDDCaps)
2062{
2063 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2064
2065 dprintf(("DDRAW: SurfGetCaps\n"));
2066
2067 if(NULL==lpDDCaps)
2068 return(DDERR_INVALIDPARAMS);
2069
2070 lpDDCaps->dwCaps = me->DDSurfaceDesc.ddsCaps.dwCaps;
2071 _dump_DDSCAPS(lpDDCaps->dwCaps);
2072 return(DD_OK);
2073}
2074//******************************************************************************
2075//******************************************************************************
2076HRESULT WIN32API SurfGetCaps4(THIS This, LPDDSCAPS2 lpDDCaps)
2077{
2078 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2079 dprintf(("DDRAW: SurfGetCaps4\n"));
2080
2081 if(NULL==lpDDCaps)
2082 return(DDERR_INVALIDPARAMS);
2083
2084 memcpy(lpDDCaps, &(me->DDSurfaceDesc.ddsCaps), sizeof(DDSCAPS2) );
2085 _dump_DDSCAPS(lpDDCaps->dwCaps);
2086 _dump_DDSCAPS2(lpDDCaps->dwCaps2);
2087
2088 return(DD_OK);
2089}
2090//******************************************************************************
2091//******************************************************************************
2092HRESULT WIN32API SurfGetClipper(THIS This, LPDIRECTDRAWCLIPPER FAR *lplpClipper)
2093{
2094 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2095
2096 dprintf(("DDRAW: SurfGetClipper\n"));
2097
2098 if(me->lpClipper)
2099 {
2100 *lplpClipper = (LPDIRECTDRAWCLIPPER) me->lpClipper;
2101 return(DD_OK);
2102 }
2103 else
2104 return(DDERR_NOCLIPPERATTACHED);
2105}
2106//******************************************************************************
2107//******************************************************************************
2108HRESULT WIN32API SurfGetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
2109{
2110 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2111 dprintf(("DDRAW: SurfGetColorKey\n"));
2112
2113 if ((0==dwFlags) || (NULL==lpDDColKey))
2114 return (DDERR_INVALIDPARAMS);
2115
2116 // as we report only src colorkey in the caps return error on all others flags
2117 if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY) & dwFlags)
2118 return(DDERR_UNSUPPORTED);
2119
2120 if(me->DDSurfaceDesc.dwFlags & dwFlags)
2121 {
2122 if(DDCKEY_SRCBLT & dwFlags)
2123 {
2124 memcpy(lpDDColKey,&(me->DDSurfaceDesc.ddckCKSrcBlt),sizeof(DDCOLORKEY) );
2125 }
2126 else
2127 return (DDERR_INVALIDPARAMS); // some other flags where set => error
2128 }
2129 else
2130 return(DDERR_NOCOLORKEY); // surface doesn't have a color key set
2131
2132 return (DD_OK);
2133}
2134//******************************************************************************
2135//******************************************************************************
2136HRESULT WIN32API SurfGetFlipStatus(THIS This, DWORD dwFlags)
2137{
2138 dprintf(("DDRAW: SurfGetFlipStatus\n"));
2139
2140 if( (DDGFS_CANFLIP!=dwFlags) && (DDGFS_ISFLIPDONE!=dwFlags) )
2141 return DDERR_INVALIDPARAMS;
2142
2143 return(DD_OK);
2144}
2145//******************************************************************************
2146//******************************************************************************
2147HRESULT WIN32API SurfGetPalette(THIS This, LPDIRECTDRAWPALETTE FAR *lplpPalette)
2148{
2149 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2150
2151 dprintf(("DDRAW: SurfGetPalette\n"));
2152
2153 if(me->lpPalette)
2154 {
2155 *lplpPalette = (LPDIRECTDRAWPALETTE)me->lpPalette;
2156 return(DD_OK);
2157 }
2158 else
2159 return(DDERR_NOPALETTEATTACHED);
2160}
2161//******************************************************************************
2162//******************************************************************************
2163HRESULT WIN32API SurfGetPixelFormat(THIS This, LPDDPIXELFORMAT lpPixelFormat)
2164{
2165 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2166
2167 dprintf(("DDRAW: SurfGetPixelFormat %x %x", This, lpPixelFormat));
2168
2169 if(NULL==lpPixelFormat)
2170 return DDERR_INVALIDPARAMS;
2171
2172 _dump_pixelformat(&me->DDSurfaceDesc.ddpfPixelFormat);
2173
2174 memcpy( (char*)lpPixelFormat,
2175 (char*)&(me->DDSurfaceDesc.ddpfPixelFormat),
2176 sizeof(DDPIXELFORMAT));
2177
2178 return(DD_OK);
2179}
2180//******************************************************************************
2181//******************************************************************************
2182HRESULT WIN32API SurfGetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurface)
2183{
2184 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2185
2186 dprintf(("DDRAW: SurfGetSurfaceDesc\n"));
2187
2188 if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC)) )
2189 return(DDERR_INVALIDPARAMS);
2190
2191 memcpy( (char *)lpSurface,
2192 (char *)&me->DDSurfaceDesc,
2193 sizeof(DDSURFACEDESC));
2194
2195 return(DD_OK);
2196}
2197//******************************************************************************
2198//******************************************************************************
2199HRESULT WIN32API SurfGetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurface)
2200{
2201 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2202
2203 dprintf(("DDRAW: SurfGetSurfaceDesc4\n"));
2204
2205 if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC2)) )
2206 return(DDERR_INVALIDPARAMS);
2207
2208 memcpy( (char *)lpSurface,
2209 (char *)&me->DDSurfaceDesc,
2210 sizeof(DDSURFACEDESC2));
2211
2212 return(DD_OK);
2213}
2214//******************************************************************************
2215//******************************************************************************
2216HRESULT WIN32API SurfInitialize(THIS, LPDIRECTDRAW, LPDDSURFACEDESC)
2217{
2218 dprintf(("DDRAW: SurfInitialize\n"));
2219
2220 return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
2221}
2222//******************************************************************************
2223//******************************************************************************
2224HRESULT WIN32API SurfInitialize4(THIS, LPDIRECTDRAW, LPDDSURFACEDESC2)
2225{
2226 dprintf(("DDRAW: SurfInitialize\n"));
2227
2228 return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
2229}
2230//******************************************************************************
2231//******************************************************************************
2232HRESULT WIN32API SurfIsLost(THIS)
2233{
2234 // We don't loose any surface ;)
2235 // But we might shoud check for primary and/or Dive Buffers as I don't know
2236 // if they are preserved if switching to a FS DOS/OS2 session
2237 //
2238 dprintf(("DDRAW: SurfIsLost\n"));
2239
2240 return(DD_OK);
2241}
2242//******************************************************************************
2243//******************************************************************************
2244HRESULT WIN32API SurfLock( THIS This,
2245 LPRECT lpRect,
2246 LPDDSURFACEDESC lpSurfaceDesc,
2247 DWORD dwFlags,
2248 HANDLE hEvent)
2249{
2250 DDSURFACEDESC2 SurfaceDesc4;
2251 HRESULT rc;
2252
2253 dprintf(("DDRAW: SurfLock %d %08X %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent));
2254
2255 if((NULL==lpSurfaceDesc)|| ((dwFlags & DDLOCK_EVENT) && NULL != hEvent)) {
2256 dprintf(("Invalid parameters"));
2257 return DDERR_INVALIDPARAMS;
2258 }
2259
2260 if(lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC) && lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC2)) {
2261 dprintf(("Invalid parameters"));
2262 return DDERR_INVALIDPARAMS;
2263 }
2264
2265 SurfaceDesc4.dwSize = sizeof(DDSURFACEDESC2);
2266
2267 rc = SurfLock4( This,
2268 lpRect,
2269 &SurfaceDesc4,
2270 dwFlags,
2271 hEvent);
2272 if (DD_OK==rc)
2273 {
2274 memcpy( (char*)lpSurfaceDesc,
2275 (char*)&SurfaceDesc4,
2276 lpSurfaceDesc->dwSize );
2277 }
2278
2279 return(rc);
2280}
2281//******************************************************************************
2282//******************************************************************************
2283HRESULT WIN32API SurfLock4( THIS This,
2284 LPRECT lpRect,
2285 LPDDSURFACEDESC2 lpSurfaceDesc,
2286 DWORD dwFlags,
2287 HANDLE hEvent)
2288{
2289
2290 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2291 int i;
2292
2293 BOOL Found;
2294 DDRectangle *pIRectCurrent,*pIRectNew;
2295 HRESULT rc;
2296
2297 dprintf( ("SurfLock4 %08X %08X %08X %d %d\n",
2298 me,
2299 (int)lpRect,
2300 (int)lpSurfaceDesc,
2301 dwFlags,
2302 hEvent) );
2303
2304 if( (NULL==lpSurfaceDesc) ||
2305 (NULL!=hEvent)
2306 )
2307 {
2308 dprintf(("DDERR_INVALIDPARAMS"));
2309 return DDERR_INVALIDPARAMS;
2310 }
2311
2312 if (NULL!=lpRect)
2313 pIRectNew = new DDRectangle( lpRect->left, lpRect->top, lpRect->right, lpRect->bottom );
2314 else
2315 pIRectNew = new DDRectangle( 0, 0, me->width, me->height);
2316
2317 // ToDo : the lockchecking should be done in a critcal seq.
2318 dprintf( ("Lock Rectangle (%d/%d) x (%d/%d)\n",
2319 pIRectNew->Left(),
2320 pIRectNew->Top(),
2321 pIRectNew->Right(),
2322 pIRectNew->Bottom()));
2323
2324 rc = DD_OK;
2325
2326 if(me->fLocked)
2327 {
2328 if (NULL==lpRect)
2329 {
2330 // If anything is locked we can't lock the complete surface
2331 dprintf(("DDRAW: Surface has locked Rectangles and we want to completely lock it\n"));
2332 Found = TRUE;
2333 }
2334 else
2335 {
2336 // If the new Rectangle intersects with any of the already locked rectangles it can't
2337 // be locked so check for this
2338
2339 dprintf(("DDRAW: Surface has locked Rectangles, check if they overlap\n"));
2340
2341 i=0;
2342 Found = FALSE;
2343
2344 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
2345 {
2346 pIRectCurrent = (DDRectangle*) DPA_FastGetPtr(me->DPA_LockedRects,i);
2347 dprintf( ("Test with Rectangle (%d/%d) x (%d/%d)\n",
2348 pIRectCurrent->Top(),
2349 pIRectCurrent->Left(),
2350 pIRectCurrent->Bottom(),
2351 pIRectCurrent->Right() ));
2352 Found = pIRectCurrent->intersects(*pIRectNew);
2353 i++;
2354 }
2355
2356 }
2357
2358 if (Found)
2359 {
2360 delete pIRectNew;
2361 dprintf(("DDRAW: SurfLock4: Surface already locked\n\n"));
2362 rc = DDERR_SURFACEBUSY;
2363 }
2364
2365 }
2366
2367 if(DD_OK == rc)
2368 {
2369 memcpy((char *)lpSurfaceDesc, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC2));
2370
2371 if(lpRect != NULL)
2372 {
2373 lpSurfaceDesc->lpSurface = (LPVOID)((char*)me->pFrameBuffer +
2374 (lpRect->top * me->dwPitchFB) +
2375 (lpRect->left * (lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount>>3)));
2376 dprintf(("DDRAW: SurfLock4 %08X (x,y) = (%d,%d)\n\n", lpSurfaceDesc->lpSurface, lpRect->top, lpRect->left));
2377 }
2378 else
2379 {
2380 dprintf(("DDRAW: SurfLock4 %08X \n\n", lpSurfaceDesc->lpSurface));
2381 }
2382 // Add the rectangle to the list of locked rectangles
2383
2384 pIRectNew->SetMemPtr(lpSurfaceDesc->lpSurface);
2385
2386 DPA_InsertPtr( me->DPA_LockedRects,
2387 DPA_GetPtrCount(me->DPA_LockedRects),
2388 pIRectNew);
2389
2390#if 0
2391 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
2392 {
2393 OS2RECTL rectOS2;
2394
2395 rectOS2.xLeft = pIRectNew->Left();
2396 rectOS2.yBottom = me->DDSurfaceDesc.dwHeight - pIRectNew->Bottom();
2397 rectOS2.xRight = pIRectNew->Right();
2398 rectOS2.yTop = me->DDSurfaceDesc.dwHeight - pIRectNew->Top();
2399 dprintf(("DiveAcquireFrameBuffer (%d,%d)(%d,%d)", rectOS2.xLeft, rectOS2.yBottom, rectOS2.xRight, rectOS2.yTop));
2400 int ret = DiveAcquireFrameBuffer(me->hDive, (PRECTL)&rectOS2);
2401 if(ret) {
2402 dprintf(("ERROR: DiveAcquireFrameBuffer failed with %d", ret));
2403 }
2404 }
2405#endif
2406 me->fLocked = TRUE;
2407
2408 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
2409 {
2410 //If fHideCursorOnLock is set, then we hide the cursor to prevent
2411 //the app from corruption the mouse cursor (color/animated pointers)
2412 if(fHideCursorOnLock) ShowCursor(FALSE);
2413 }
2414 }
2415
2416 return rc;
2417}
2418//******************************************************************************
2419//******************************************************************************
2420HRESULT WIN32API SurfGetDC(THIS This, HDC FAR *hdc)
2421{
2422 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2423 DDSURFACEDESC2 LockedSurfaceDesc;
2424 HRESULT rc;
2425 BITMAP bmpSurface;
2426 struct
2427 {
2428 BITMAPINFOHEADER bmiHead;
2429 RGBQUAD bmiCols[256];
2430 } BitmapInfo;
2431
2432 dprintf(("DDRAW: SurfGetDC\n"));
2433
2434 if (hdc == NULL)
2435 return(DDERR_INVALIDPARAMS);
2436
2437 LockedSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
2438
2439 if(DD_OK != me->Vtbl.fnLock(me,NULL,&LockedSurfaceDesc,0,0))
2440 {
2441 return(DDERR_DCALREADYCREATED);
2442 }
2443
2444 rc = DD_OK;
2445
2446 if(me->hdcImage == NULL)
2447 {
2448 // Create a Device context
2449 me->hdcImage = CreateCompatibleDC(NULL);
2450 if(me->hdcImage == NULL)
2451 {
2452 dprintf(("DDRAW: Can't create compatible DC!\n"));
2453 me->Vtbl.fnUnlock(me,NULL);
2454 rc = DDERR_GENERIC;
2455 }
2456 }
2457
2458 if( (DD_OK==rc) && (me->hbmImage == NULL) )
2459 {
2460 OS2IDirectDrawPalette *ddpal = NULL;
2461
2462 dprintf( ("Trying to create Bitmap (%d/%d) at %d Bit\n",
2463 LockedSurfaceDesc.dwWidth,
2464 LockedSurfaceDesc.dwHeight,
2465 LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount
2466 ));
2467 memset(&BitmapInfo, 0, sizeof(BitmapInfo));
2468 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
2469 BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.dwWidth;
2470 BitmapInfo.bmiHead.biHeight = -LockedSurfaceDesc.dwHeight;
2471 BitmapInfo.bmiHead.biPlanes = 1;
2472 BitmapInfo.bmiHead.biBitCount = (WORD)LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
2473
2474 switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2475 {
2476 case 1:
2477 case 4:
2478 dprintf(("DDRAW: 1/4 Bit Not yet supported\n"));
2479 break;
2480 case 8:
2481 BitmapInfo.bmiHead.biCompression = BI_RGB;
2482 if (me->lpPalette != NULL)
2483 ddpal = me->lpPalette;
2484 if ((me->FrontBuffer != NULL) && (me->FrontBuffer->lpPalette != NULL))
2485 ddpal = me->FrontBuffer->lpPalette;
2486 if (ddpal != NULL) {
2487 ddpal->Vtbl.fnGetEntries((IDirectDrawPalette*)ddpal,
2488 0, 0, 256, (PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
2489 }
2490 else {
2491 dprintf(("DDRAW: Using default palette\n"));
2492 for (DWORD i = 0; i < 256; i++) {
2493 BitmapInfo.bmiCols[i].rgbBlue = DefaultPalette[i*3+2];
2494 BitmapInfo.bmiCols[i].rgbGreen = DefaultPalette[i*3+1];
2495 BitmapInfo.bmiCols[i].rgbRed = DefaultPalette[i*3];
2496 BitmapInfo.bmiCols[i].rgbReserved = 0;
2497 }
2498 }
2499 me->hbmImage = CreateDIBitmap( me->hdcImage,
2500 &BitmapInfo.bmiHead,
2501 CBM_INIT,
2502 LockedSurfaceDesc.lpSurface,
2503 (PBITMAPINFO)&BitmapInfo,
2504 DIB_RGB_COLORS);
2505 break;
2506
2507 case 16:
2508 case 24:
2509 case 32:
2510 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
2511 BitmapInfo.bmiHead.biClrUsed = 3;
2512 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
2513 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
2514 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
2515 me->hbmImage = CreateDIBitmap( me->hdcImage,
2516 &BitmapInfo.bmiHead,
2517 CBM_INIT,
2518 LockedSurfaceDesc.lpSurface,
2519 (PBITMAPINFO)&BitmapInfo,
2520 DIB_RGB_COLORS );
2521 break;
2522
2523 default:
2524 dprintf( ("Unexpected BitCount %d \n",
2525 LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
2526 me->hbmImage=NULL;
2527 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2528
2529 if(me->hbmImage == NULL)
2530 {
2531 dprintf(("DDRAW: Can't create bitmap!\n"));
2532 DeleteDC(me->hdcImage);
2533 me->hdcImage = NULL;
2534 me->Vtbl.fnUnlock(me,NULL);
2535 rc = DDERR_GENERIC;
2536 }
2537 }
2538 else
2539 {
2540 if( (DD_OK==rc) && (me->dwLastDCUnique != me->dwUniqueValue) )
2541 {
2542 dprintf(("DDRAW: The Surface was locked/unlocked after the last DC was created =>Update Bitmap!\n"));
2543
2544 memset(&BitmapInfo,0, sizeof(BitmapInfo));
2545 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
2546 BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.dwWidth;
2547 BitmapInfo.bmiHead.biHeight = -LockedSurfaceDesc.dwHeight;
2548 BitmapInfo.bmiHead.biPlanes = 1;
2549 BitmapInfo.bmiHead.biBitCount = (WORD)LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
2550
2551 switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2552 {
2553 case 1:
2554 case 4:
2555 case 8:
2556 BitmapInfo.bmiHead.biCompression = BI_RGB;
2557 GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
2558 SetDIBits(me->hdcImage, me->hbmImage, 0, LockedSurfaceDesc.dwHeight,
2559 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2560 break;
2561 case 16:
2562 case 32:
2563 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
2564 BitmapInfo.bmiHead.biClrUsed = 3;
2565 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
2566 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
2567 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
2568 SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
2569 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2570 break;
2571 case 24:
2572 BitmapInfo.bmiHead.biCompression = BI_RGB;
2573 SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
2574 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2575 break;
2576 default:
2577 dprintf(("DDRAW: Unexpected BitCount %d => Bitmap not updated!\n",LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
2578 break;
2579 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2580
2581 }
2582 }
2583
2584 // Allways select the bitmap into the DC! No matter if the old or a new one
2585
2586 if (DD_OK==rc)
2587 {
2588 if ((me->hgdiOld = SelectObject(me->hdcImage, me->hbmImage)) == NULL)
2589 {
2590 dprintf(("DDRAW: Can't select bitmap into DC!\n"));
2591 DeleteDC(me->hdcImage);
2592 me->hdcImage = NULL;
2593 DeleteObject(me->hbmImage);
2594 me->hbmImage = NULL;
2595 me->Vtbl.fnUnlock(me,NULL);
2596 rc = DDERR_GENERIC;
2597 }
2598 else
2599 {
2600 *hdc = me->hdcImage;
2601 }
2602 }
2603
2604 return rc;
2605}
2606//******************************************************************************
2607//******************************************************************************
2608HRESULT WIN32API SurfReleaseDC(THIS This, HDC hdc)
2609{
2610 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2611 struct
2612 {
2613 BITMAPINFOHEADER bmiHead;
2614 RGBQUAD bmiCols[256];
2615 } BitmapInfo;
2616 int rc;
2617
2618 dprintf(("DDRAW: SurfReleaseDC\n"));
2619
2620 if(hdc != me->hdcImage)
2621 return(DDERR_INVALIDOBJECT);
2622
2623 //unselect our bitmap
2624 SelectObject(me->hdcImage, me->hgdiOld);
2625
2626 memset(&BitmapInfo,0, sizeof(BitmapInfo));
2627 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
2628 BitmapInfo.bmiHead.biBitCount = me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
2629 BitmapInfo.bmiHead.biPlanes = 1;
2630 BitmapInfo.bmiHead.biWidth = me->DDSurfaceDesc.dwWidth; /// (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3);
2631 BitmapInfo.bmiHead.biHeight = -me->DDSurfaceDesc.dwHeight;
2632
2633 switch(me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2634 {
2635 case 1:
2636 case 4:
2637 case 8:
2638 BitmapInfo.bmiHead.biCompression = BI_RGB;
2639 //GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
2640 rc = GetDIBits( hdc,
2641 me->hbmImage,
2642 0,
2643 me->DDSurfaceDesc.dwHeight,
2644 NULL,
2645 (PBITMAPINFO)&BitmapInfo,
2646 DIB_RGB_COLORS);
2647 BitmapInfo.bmiHead.biHeight = -BitmapInfo.bmiHead.biHeight;
2648 dprintf( ("GetDIBits rc=%d\n Size :%d\n Width :%d\n Height :%d\n"
2649 " Planes :%d\n BitCount :%d\nLastEror = %d\nPixel[0,0] = 0x%02X\n",
2650 rc,
2651 BitmapInfo.bmiHead.biSize,
2652 BitmapInfo.bmiHead.biWidth,
2653 BitmapInfo.bmiHead.biHeight,
2654 BitmapInfo.bmiHead.biPlanes,
2655 BitmapInfo.bmiHead.biBitCount,
2656 GetLastError(),
2657 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
2658
2659 rc = GetDIBits( hdc,
2660 me->hbmImage,
2661 0,
2662 me->DDSurfaceDesc.dwHeight,
2663 me->DDSurfaceDesc.lpSurface,
2664 (PBITMAPINFO)&BitmapInfo,
2665 DIB_RGB_COLORS);
2666 dprintf( ("GetDIBits rc=%d\n LastEror = %d\nPixel[0,0] = 0x%02X\n",
2667 rc,
2668 GetLastError(),
2669 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
2670 break;
2671 case 16:
2672 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
2673 BitmapInfo.bmiHead.biClrUsed = 3;
2674 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
2675 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
2676 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
2677 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
2678 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2679 break;
2680
2681 case 32:
2682 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
2683 BitmapInfo.bmiHead.biClrUsed = 3;
2684 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
2685 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
2686 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
2687 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
2688 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2689 break;
2690
2691 case 24:
2692 BitmapInfo.bmiHead.biCompression = BI_RGB;
2693 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
2694 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2695 break;
2696 default:
2697 dprintf(("DDRAW: Unexpected BitCount %d => Surface unlocked but no data copied back\n",me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
2698 // we might could keep the surface locked and return an error but this is more "safe"
2699 break;
2700 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2701
2702 me->Vtbl.fnUnlock(me,NULL);
2703 me->dwLastDCUnique = me->dwUniqueValue; // Store this to see if the surface was locked after we released the DC
2704
2705 return(DD_OK);
2706}
2707//******************************************************************************
2708//******************************************************************************
2709HRESULT WIN32API SurfRestore(THIS)
2710{
2711 dprintf(("DDRAW: SurfRestore\n"));
2712
2713 return(DD_OK);
2714}
2715//******************************************************************************
2716//******************************************************************************
2717HRESULT WIN32API SurfSetClipper(THIS This, LPDIRECTDRAWCLIPPER lpClipper)
2718{
2719 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2720
2721 dprintf(("DDRAW: SurfSetClipper %x %x", This, lpClipper));
2722
2723 if(lpClipper == NULL)
2724 {
2725 //deattach surface
2726 if(me->lpClipper)
2727 {
2728 me->lpClipper->Vtbl.fnRelease((IDirectDrawClipper*)me->lpClipper);
2729 me->lpClipper = NULL;
2730 return(DD_OK);
2731 }
2732 else
2733 return(DDERR_NOCLIPPERATTACHED);
2734 }
2735
2736 if(lpClipper == (LPDIRECTDRAWCLIPPER)me->lpClipper)
2737 return(DD_OK); //already attached
2738
2739 if(me->lpClipper != NULL)
2740 {
2741 me->lpClipper->Vtbl.fnRelease((IDirectDrawClipper*)me->lpClipper); //attach other surface
2742 return(DD_OK);
2743 }
2744
2745 me->lpClipper = (OS2IDirectDrawClipper *)lpClipper;
2746 me->lpClipper->Vtbl.fnAddRef((IDirectDrawClipper*)me->lpClipper);
2747
2748 return(DD_OK);
2749}
2750//******************************************************************************
2751//******************************************************************************
2752HRESULT WIN32API SurfSetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
2753{
2754 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2755 HRESULT rc;
2756
2757 dprintf(("DDRAW: SurfSetColorKey %d %08X\n", dwFlags, lpDDColKey));
2758
2759 if (0==dwFlags)
2760 {
2761 return (DDERR_INVALIDPARAMS);
2762 }
2763
2764 // as we report only src colorkey in the caps return error on all others flags
2765 if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY|DDCKEY_COLORSPACE) & dwFlags)
2766 {
2767 dprintf(("Unspported colorkey\n"));
2768 return(DDERR_UNSUPPORTED);
2769 }
2770
2771 if(DDCKEY_SRCBLT & dwFlags)
2772 {
2773
2774 //(me->lpVtbl == me->Vtbl4)
2775 // me->Vtbl4->ChangeUniquenessValue(me); // we changed somethin so change this value
2776 if(NULL!=lpDDColKey)
2777 {
2778 dprintf(("copy colorkey"));
2779 memcpy(&(me->DDSurfaceDesc.ddckCKSrcBlt), lpDDColKey, sizeof(DDCOLORKEY) );
2780 me->DDSurfaceDesc.dwFlags |= DDCKEY_SRCBLT;
2781
2782 // ToDo: Generate a maskbitmap for transparent blitting here
2783 }
2784 else
2785 {
2786 dprintf(("clear colorkey"));
2787 memset(&(me->DDSurfaceDesc.ddckCKSrcBlt), 0, sizeof(DDCOLORKEY) );
2788 me->DDSurfaceDesc.dwFlags &= ~DDCKEY_SRCBLT;
2789 }
2790 rc = DD_OK;
2791 }
2792 else
2793 {
2794 dprintf(("Unsupported flags"));
2795 _dump_DDCOLORKEY(dwFlags);
2796 rc = DDERR_INVALIDPARAMS; // some other flags where set => error
2797 }
2798 return rc;
2799}
2800//******************************************************************************
2801//******************************************************************************
2802HRESULT WIN32API SurfSetPalette(THIS This, LPDIRECTDRAWPALETTE lpPalette)
2803{
2804 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2805
2806 dprintf(("DDRAW: SurfSetPalette\n"));
2807
2808 if(lpPalette == NULL)
2809 {
2810 //deattach palette
2811 if(me->lpPalette)
2812 {
2813 // If removed from a primary surface notify
2814 // palette that it is no longer attached to the
2815 // primary surface => doesn't modify physical palette
2816 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
2817 {
2818 me->lpPalette->SetIsPrimary(FALSE);
2819 }
2820 me->lpPalette->Vtbl.fnRelease((IDirectDrawPalette*)me->lpPalette);
2821 me->lpPalette = NULL;
2822 return(DD_OK);
2823 }
2824 else
2825 return(DDERR_NOPALETTEATTACHED);
2826 }
2827
2828 if(lpPalette == (LPDIRECTDRAWPALETTE)me->lpPalette)
2829 return(DD_OK); //already attached
2830
2831 if(me->lpPalette != NULL)
2832 {
2833 me->lpPalette->Vtbl.fnRelease((IDirectDrawPalette*)me->lpPalette); //attach other palette
2834 //return(DD_OK);
2835 }
2836 me->lpPalette = (OS2IDirectDrawPalette *)lpPalette;
2837 me->lpPalette->Vtbl.fnAddRef((IDirectDrawPalette*)me->lpPalette);
2838
2839 // If Attached to a primary surface notify
2840 // palette that it is attached to the primary surface
2841 // => It does modify physical palette.
2842 // This is important as an palette can be attached to
2843 // multiple surfaces. If one is the primary surface
2844 // changes done to it via any surface must result in
2845 // changes in the phys pal.
2846
2847 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
2848 {
2849 me->lpPalette->SetIsPrimary(TRUE);
2850 }
2851 // me->lpVtbl->ChangeUniquenessValue(me);
2852
2853 return(DD_OK);
2854}
2855//******************************************************************************
2856//******************************************************************************
2857HRESULT WIN32API SurfUnlock(THIS This, LPVOID lpSurfaceData)
2858{
2859
2860 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2861 int i;
2862 DDRectangle *pIRectUnlock, *pIRectEnum;
2863 BOOL Found = FALSE;
2864 OS2RECTL CCRect;
2865 HRESULT rc;
2866
2867 dprintf(("DDRAW: SurfUnlock at %08X\n",lpSurfaceData));
2868
2869 if(me->fLocked == FALSE)
2870 {
2871 dprintf(("DDRAW: Surface not locked!\n"));
2872 return(DDERR_NOTLOCKED);
2873 }
2874
2875 i=0;
2876 if(NULL!=lpSurfaceData)
2877 {
2878 dprintf(("DDRAW: Buffer Pointer Compare"));
2879
2880 // We got a pinter to the surface memory so we must search for
2881 // this pointer in the locked rects DPA to unlock the right rect.
2882
2883 while(i < DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
2884 {
2885 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
2886 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
2887 i,
2888 pIRectEnum->Top(),
2889 pIRectEnum->Left(),
2890 pIRectEnum->Bottom(),
2891 pIRectEnum->Right(),
2892 pIRectEnum->GetMemPtr() ));
2893
2894 Found = ( pIRectEnum->GetMemPtr() == lpSurfaceData);
2895 if(!Found)
2896 {
2897 dprintf(("DDRAW: Not Found, try Next rect\n"));
2898 i++;
2899 }
2900 else
2901 {
2902 dprintf(("DDRAW: Found Rect\n"));
2903 }
2904 }
2905 }
2906 else
2907 {
2908 // If a NULL pointer was passed in the SW tries to unlock the
2909 // complete surface so we must compare the rects.
2910 dprintf(("DDRAW: Rectangle compare"));
2911
2912#if 1
2913 i = 0;
2914 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,0);
2915 Found = (pIRectEnum != NULL);
2916#else
2917 pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height);
2918
2919 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
2920 {
2921 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
2922 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
2923 i,
2924 pIRectEnum->Top(),
2925 pIRectEnum->Left(),
2926 pIRectEnum->Bottom(),
2927 pIRectEnum->Right(),
2928 pIRectEnum->GetMemPtr() ));
2929
2930 Found = (*pIRectEnum == *pIRectUnlock);
2931 if(!Found)
2932 {
2933 dprintf(("DDRAW: Not Found, try Next rect\n"));
2934 i++;
2935 }
2936 else
2937 {
2938 dprintf(("DDRAW: Found Rect\n"));
2939 }
2940 }
2941 delete pIRectUnlock;
2942#endif
2943 }
2944
2945 if(!Found)
2946 {
2947 dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n"));
2948 rc = DDERR_INVALIDRECT;
2949 }
2950 else
2951 {
2952 dprintf(("DDRAW: Remove Rect %d from Seq.\n",i));
2953
2954 DPA_DeletePtr(me->DPA_LockedRects,i);
2955
2956 dprintf(("DDRAW: Test if locked Rects main\n"));
2957
2958 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
2959 {
2960 dprintf(("DDRAW: No Locked Rects left for surface\n"));
2961 me->fLocked = FALSE;
2962 }
2963 else
2964 dprintf(( "%d Rects in Seq\n",
2965 DPA_GetPtrCount(me->DPA_LockedRects)));
2966
2967 if(me->pFrameBuffer != me->pDiveBuffer)
2968 {
2969 dprintf(( "ColorConversion Needed %08X != %08X\n",
2970 me->pFrameBuffer,
2971 me->pDiveBuffer));
2972 if(NULL!=lpSurfaceData)
2973 {
2974 CCRect.yTop = pIRectEnum->Top();
2975 CCRect.xLeft = pIRectEnum->Left();
2976 CCRect.xRight = pIRectEnum->Right();
2977 CCRect.yBottom = pIRectEnum->Bottom();
2978
2979 me->ColorConversion( (LPRECT)&CCRect);
2980 }
2981 else
2982 {
2983 me->ColorConversion(NULL);
2984 }
2985 }
2986 else
2987 dprintf( ("No ColorConversion Needed"));
2988
2989
2990#if 0
2991 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
2992 {
2993 OS2RECTL rectOS2;
2994
2995 rectOS2.xLeft = pIRectEnum->Left();
2996 rectOS2.yBottom = me->DDSurfaceDesc.dwHeight - pIRectEnum->Bottom();
2997 rectOS2.xRight = pIRectEnum->Right();
2998 rectOS2.yTop = me->DDSurfaceDesc.dwHeight - pIRectEnum->Top();
2999 dprintf(("DiveDeacquireFrameBuffer (%d,%d)(%d,%d)", rectOS2.xLeft, rectOS2.yBottom, rectOS2.xRight, rectOS2.yTop));
3000 int ret = DiveDeacquireFrameBuffer(me->hDive);
3001 if(ret) {
3002 dprintf(("ERROR: DiveDeacquireFrameBuffer failed with %d", ret));
3003 }
3004 }
3005#endif
3006
3007 // delete tne DDRectobject of the found rectangle
3008 delete pIRectEnum;
3009
3010 // me->lpVtbl->ChangeUniquenessValue(me);
3011
3012 dprintf(("DDRAW: Unlock OK\n\n"));
3013
3014 rc = DD_OK;
3015
3016 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
3017 {
3018 //If fHideCursorOnLock is set, then we hide the cursor to prevent in SurfLock4
3019 //the app from corruption the mouse cursor (color/animated pointers)
3020 //We need to show it again here
3021 if(fHideCursorOnLock) ShowCursor(TRUE);
3022 }
3023 }
3024
3025 return rc;
3026}
3027//******************************************************************************
3028//******************************************************************************
3029HRESULT WIN32API SurfUnlock4(THIS This, LPRECT lpSurfaceRect)
3030{
3031 // MS changed the parameter from LPVOID to LPRECT with DX6
3032 // as DX-6 allways returns a DDSurface4 on create surface this
3033 // is a problem i not NULL is passed in.
3034 // Solution We first test with the pointer ns assuming a rectangle
3035 // if we don't find a rect Which is very likely if we get a pointer
3036 // SurfaceMemory we call SurfUnlock and test for the pointer there.
3037
3038
3039 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3040 int i;
3041 DDRectangle *pIRectUnlock, *pIRectEnum;
3042 BOOL Found = FALSE;
3043 HRESULT rc;
3044
3045 dprintf(("DDRAW: SurfUnlock4\n"));
3046
3047 if(me->fLocked == FALSE)
3048 {
3049 dprintf(("DDRAW: Surface not locked!\n"));
3050 return(DDERR_NOTLOCKED);
3051 }
3052
3053 if(NULL!=lpSurfaceRect)
3054 {
3055 dprintf(("DDRAW: Unlock rectangle\n"));
3056 pIRectUnlock = new DDRectangle( lpSurfaceRect->left, lpSurfaceRect->top,
3057 lpSurfaceRect->right, lpSurfaceRect->bottom);
3058 }
3059 else
3060 {
3061 dprintf(("DDRAW: Unlock complete surface\n"));
3062 pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height);
3063 }
3064
3065 dprintf(( "Try to Unlock Rectangle (%d/%d) x (%d/%d)\n",
3066 pIRectUnlock->Top(),
3067 pIRectUnlock->Left(),
3068 pIRectUnlock->Bottom(),
3069 pIRectUnlock->Right() ));
3070
3071 dprintf(("DDRAW: Start Enumeration of Locked Rects\n"));
3072
3073 i=0;
3074 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
3075 {
3076 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
3077 dprintf(( "Test with Rectangle (%d/%d) x (%d/%d)\n",
3078 pIRectEnum->Top(),
3079 pIRectEnum->Left(),
3080 pIRectEnum->Bottom(),
3081 pIRectEnum->Right() ));
3082
3083 Found = (*pIRectEnum == *pIRectUnlock);
3084 if(!Found)
3085 {
3086 dprintf(("DDRAW: Not Found, try Next rect\n"));
3087 i++;
3088 }
3089 else
3090 {
3091 dprintf(("DDRAW: Found Rect\n"));
3092 }
3093 }
3094
3095 if(!Found)
3096 {
3097
3098 if(NULL==lpSurfaceRect)
3099 {
3100 dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n"));
3101 return(DDERR_INVALIDRECT);
3102 }
3103 else
3104 rc = SurfUnlock(This, (LPVOID)lpSurfaceRect);
3105 }
3106 else
3107 {
3108 dprintf(("DDRAW: Remove Rect from Seq.\n"));
3109
3110 DPA_DeletePtr(me->DPA_LockedRects,i);
3111
3112 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
3113 {
3114 dprintf(("DDRAW: No Locked Rects left for surface\n"));
3115 me->fLocked = FALSE;
3116 }
3117
3118 if(me->pFrameBuffer != me->pDiveBuffer)
3119 {
3120 dprintf(( "ColorConversion Needed %08X != %08X\n",
3121 me->pFrameBuffer,
3122 me->pDiveBuffer));
3123 me->ColorConversion(lpSurfaceRect);
3124 }
3125
3126 // me->lpVtbl->ChangeUniquenessValue(me);
3127
3128 dprintf(("DDRAW: Unlock OK\n\n"));
3129 rc = DD_OK;
3130 }
3131
3132 return rc;
3133}
3134//******************************************************************************
3135//******************************************************************************
3136HRESULT WIN32API SurfGetDDInterface(THIS This, LPVOID FAR *lplpDirectDraw)
3137{
3138 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3139
3140 dprintf(("DDRAW: SurfGetDDInterface\n"));
3141 *lplpDirectDraw = (LPVOID FAR *)me->lpDraw;
3142 return(DD_OK);
3143}
3144//******************************************************************************
3145//******************************************************************************
3146HRESULT WIN32API SurfPageLock(THIS, DWORD)
3147{
3148 // Only used for DMA memory access
3149 // If we implement this for the None dive buffers with a pdd the we must change
3150 // from malloc to DosAllocMem and use OBJ_TILE flag
3151 dprintf(("DDRAW: SurfPageLock\n"));
3152 return(DD_OK);
3153}
3154//******************************************************************************
3155//******************************************************************************
3156HRESULT WIN32API SurfPageUnlock(THIS, DWORD)
3157{
3158 dprintf(("DDRAW: SurfPageUnlock\n"));
3159 return(DD_OK);
3160}
3161//******************************************************************************
3162//******************************************************************************
3163// V3 Interface Functions
3164
3165HRESULT WIN32API SurfSetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurfDesc, DWORD dwFlags)
3166{
3167 dprintf(("DDRAW: SurfSetSurfaceDesc\n"));
3168
3169 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3170 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
3171 return DDERR_INVALIDPARAMS;
3172
3173 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
3174 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
3175 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
3176 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
3177 if(-1==me->diveBufNr)
3178 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
3179
3180 if (!me->Updated)
3181 {
3182 me->Updated = TRUE;
3183 // free our allocated Memory
3184 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
3185 {
3186 if(me->pFBreal)
3187 free(me->pFBreal);
3188 if(me->pDBreal)
3189 free(me->pFBreal);
3190 }
3191 }
3192 // me->lpVtbl->ChangeUniquenessValue(me);
3193 memcpy( (char*)&(me->DDSurfaceDesc),
3194 (char*)lpSurfDesc,
3195 sizeof(DDSURFACEDESC));
3196
3197 me->dwPitchFB = me->DDSurfaceDesc.lPitch;
3198
3199 if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() )
3200 {
3201 // create CC buffer ....
3202 me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7;
3203 me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24);
3204 me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD
3205 }
3206 return DD_OK;
3207}
3208//******************************************************************************
3209//******************************************************************************
3210HRESULT WIN32API SurfSetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurfDesc, DWORD dwFlags)
3211{
3212 dprintf(("DDRAW: SurfSetSurfaceDesc4\n"));
3213
3214 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3215 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
3216 return DDERR_INVALIDPARAMS;
3217
3218 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
3219 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
3220 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
3221 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
3222 if(-1==me->diveBufNr)
3223 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
3224
3225 if (!me->Updated)
3226 {
3227 me->Updated = TRUE;
3228 // free our allocated Memory
3229 // free our allocated Memory
3230 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
3231 {
3232 if(me->pFBreal)
3233 free(me->pFBreal);
3234 if(me->pDBreal)
3235 free(me->pFBreal);
3236 }
3237 }
3238 // me->lpVtbl->ChangeUniquenessValue(me);
3239 memcpy( (char *)&(me->DDSurfaceDesc),
3240 (char*)lpSurfDesc,
3241 sizeof(DDSURFACEDESC2));
3242 me->dwPitchFB = me->DDSurfaceDesc.lPitch;
3243
3244 if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() )
3245 {
3246 // create CC buffer ....
3247 me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7;
3248 me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24);
3249 me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD
3250 }
3251
3252 return DD_OK;
3253}
3254//******************************************************************************
3255//******************************************************************************
3256// V4 Interface Functions
3257
3258HRESULT WIN32API SurfSetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData,
3259 DWORD dwDataSize, DWORD dwFlags)
3260{
3261 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3262 int i;
3263 PSURFPRIVATEDATA pSData;
3264 void *pBuffer;
3265 BOOL bFound = FALSE;
3266 HRESULT rc;
3267
3268 dprintf(("DDRAW: SurfSetPrivateData\n"));
3269
3270 if(NULL==me)
3271 return(DDERR_INVALIDOBJECT);
3272
3273 if((NULL==lpData)||(0==dwDataSize)||
3274 (dwFlags & ~(DDSPD_IUNKNOWNPOINTER|DDSPD_VOLATILE)))
3275 return(DDERR_INVALIDPARAMS);
3276
3277 // first check if the refGUID is stored as then the content will be updated
3278 if( DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0 )
3279 {
3280 i=0;
3281 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
3282 {
3283 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
3284
3285 if (IsEqualGUID(&pSData->guidTag,refGUID))
3286 bFound = TRUE;
3287
3288 i++;
3289 }
3290 }
3291
3292 if(bFound)
3293 {
3294 // update Private Data
3295
3296 if (!pSData->isValid)
3297 {
3298 // Current data is invalid we need to update/allocate
3299
3300 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
3301 {
3302 pSData->pData = lpData;
3303 pSData->dwSize = 4;
3304 pSData->dwFlags = dwFlags;
3305 pSData->isValid = TRUE;
3306 ((OS2IDirectDrawSurface *) lpData)->lpVtbl->fnAddRef(lpData);
3307 }
3308 else
3309 {
3310 pSData->pData = malloc(dwDataSize);
3311 if(NULL!=pSData->pData)
3312 {
3313 memcpy(pSData->pData,lpData,dwDataSize);
3314 pSData->dwSize = dwDataSize;
3315 pSData->dwFlags = dwFlags;
3316 pSData->isValid = TRUE;
3317 }
3318 else
3319 {
3320 delete pSData;
3321 rc = DDERR_OUTOFMEMORY;
3322 }
3323 }
3324 }
3325 else
3326 {
3327 if(pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
3328 {
3329 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
3330 {
3331 if(pSData->pData != lpData)
3332 {
3333 // Change of IUNKOWNPOINTER => release old and add ref to new one
3334 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->fnRelease(pSData->pData);
3335 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->fnAddRef(lpData);
3336 pSData->pData = lpData;
3337 }
3338 pSData->dwFlags = dwFlags; // Update the flags, size is the same
3339 }
3340 else
3341 {
3342 // Replace IUNKOWN through data
3343 pBuffer = malloc(dwDataSize); // get new buffer first
3344 if(NULL!=pBuffer)
3345 {
3346 // release old ref and copy data
3347 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->fnRelease(pSData->pData);
3348 memcpy(pBuffer,lpData,dwDataSize);
3349 pSData->pData = pBuffer;
3350 pSData->dwSize = dwDataSize; // Update the size
3351 pSData->dwFlags = dwFlags; // Update the flags
3352 }
3353 else
3354 rc = DDERR_OUTOFMEMORY;
3355 }
3356 }
3357 else
3358 {
3359 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
3360 {
3361 // Change of data to IUNKOWNPOINTER => free old memory and add ref to new one
3362 free(pSData->pData);
3363 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->fnAddRef(lpData);
3364 pSData->pData = lpData;
3365 pSData->dwSize = dwDataSize; // Update the size
3366 pSData->dwFlags = dwFlags; // Update the flags
3367 }
3368 else
3369 {
3370 // Update/Replace data
3371 if(pSData->dwSize!=dwDataSize)
3372 pBuffer = realloc(pSData->pData,dwDataSize); // update buffer to new size
3373 else
3374 pBuffer = pSData->pData;
3375
3376 if(NULL!=pBuffer)
3377 {
3378 // release old ref and copy data
3379 memcpy(pBuffer,lpData,dwDataSize);
3380 pSData->pData = pBuffer;
3381 pSData->dwSize = dwDataSize; // Update the size
3382 pSData->dwFlags = dwFlags; // Update the flags
3383 }
3384 else
3385 rc = DDERR_OUTOFMEMORY;
3386 }
3387 }
3388 }
3389 }
3390 else
3391 {
3392 // New data
3393
3394 pSData = new(SURFPRIVATEDATA);
3395 if (NULL!=pSData)
3396 {
3397 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
3398 {
3399 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
3400 pSData->pData = lpData;
3401 pSData->dwSize = 4;
3402 pSData->dwFlags = dwFlags;
3403 pSData->isValid = TRUE;
3404 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->fnAddRef(lpData);
3405 }
3406 else
3407 {
3408 pSData->pData = malloc(dwDataSize);
3409 if(NULL!=pSData->pData)
3410 {
3411 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
3412 memcpy(pSData->pData,lpData,dwDataSize);
3413 pSData->dwSize = dwDataSize;
3414 pSData->dwFlags = dwFlags;
3415 pSData->isValid = TRUE;
3416
3417 if( DPA_InsertPtr( me->DPA_SurfacePrivateData,
3418 DPA_GetPtrCount(me->DPA_SurfacePrivateData),
3419 pSData) <0)
3420 {
3421 delete(pSData);
3422 rc = DDERR_OUTOFMEMORY;
3423 }
3424 }
3425 else
3426 {
3427 delete(pSData);
3428 rc = DDERR_OUTOFMEMORY;
3429 }
3430 }
3431
3432 }
3433 else
3434 rc = DDERR_OUTOFMEMORY;
3435 }
3436
3437 return rc;
3438}
3439//******************************************************************************
3440//******************************************************************************
3441HRESULT WIN32API SurfGetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData, LPDWORD lpDataSize)
3442{
3443 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3444 int i;
3445 PSURFPRIVATEDATA pSData;
3446 HRESULT rc;
3447 BOOL bFound = FALSE;
3448
3449 dprintf(("DDRAW: SurfGetPrivateData\n"));
3450
3451 if(NULL==me)
3452 return(DDERR_INVALIDOBJECT);
3453
3454 if((NULL==lpData)||(NULL==lpDataSize))
3455 return(DDERR_INVALIDPARAMS);
3456
3457 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
3458 {
3459 i=0;
3460 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
3461 {
3462 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
3463
3464 if (IsEqualGUID(&pSData->guidTag,refGUID))
3465 bFound = TRUE;
3466
3467 i++;
3468 }
3469 }
3470
3471 if(bFound)
3472 {
3473 if(!pSData->isValid)
3474 {
3475 rc =DDERR_EXPIRED;
3476 }
3477 else
3478 {
3479 if(pSData->dwSize > *lpDataSize)
3480 {
3481 // Buffer to small return needed Size
3482 *lpDataSize = pSData->dwSize;
3483 rc = DDERR_MOREDATA;
3484 }
3485 else
3486 {
3487 memcpy(lpData,pSData->pData,pSData->dwSize);
3488 rc = DD_OK;
3489 }
3490 }
3491 }
3492 else
3493 rc = DDERR_NOTFOUND;
3494
3495
3496 return rc;
3497}
3498//******************************************************************************
3499//******************************************************************************
3500HRESULT WIN32API SurfFreePrivateData(THIS This, REFGUID refGUID)
3501{
3502 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3503 int i;
3504 PSURFPRIVATEDATA pSData;
3505 BOOL bFound = FALSE;
3506
3507 dprintf(("DDRAW: SurfFreePrivateData\n"));
3508
3509 if(NULL==me)
3510 return(DDERR_INVALIDOBJECT);
3511
3512 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
3513 {
3514 i=0;
3515 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
3516 {
3517 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
3518
3519 if (IsEqualGUID(&pSData->guidTag,refGUID))
3520 {
3521 bFound = TRUE;
3522
3523 if(pSData->isValid)
3524 {
3525 // delete the data if valid
3526 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
3527 {
3528 // pointer to com stored so calll its release
3529 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->fnRelease(pSData->pData);
3530 }
3531 else
3532 {
3533 // Free allocated data
3534 free( pSData->pData);
3535 }
3536 }
3537 // Now remove the entry from the list
3538 DPA_DeletePtr(me->DPA_SurfacePrivateData,i);
3539 }
3540 i++;
3541 }
3542 }
3543
3544 return (bFound?DD_OK:DDERR_NOTFOUND);
3545}
3546//******************************************************************************
3547//******************************************************************************
3548HRESULT WIN32API SurfGetUniquenessValue(THIS This, LPDWORD lpValue)
3549{
3550 dprintf(("DDRAW: SurfGetUniquenessValue\n"));
3551 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3552 if (NULL==lpValue)
3553 return DDERR_INVALIDPARAMS;
3554
3555 *lpValue = me->dwUniqueValue;
3556 return DD_OK;
3557}
3558//******************************************************************************
3559//******************************************************************************
3560HRESULT WIN32API SurfChangeUniquenessValue(THIS This)
3561{
3562 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3563 int i;
3564 PSURFPRIVATEDATA pSData;
3565
3566
3567 dprintf(("DDRAW: SurfChangeUniquenessValue\n"));
3568 me->dwUniqueValue++;
3569
3570 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
3571 {
3572 i=0;
3573 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData))
3574 {
3575 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
3576 if (pSData->dwFlags & DDSPD_VOLATILE)
3577 {
3578 // Data becomes unvalid after a Surface change
3579 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
3580 {
3581 // pointer to com stored so call its release
3582 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->fnRelease(pSData->pData);
3583 }
3584 else
3585 {
3586 // Free allocated data
3587 free( pSData->pData);
3588 }
3589 pSData->pData = NULL;
3590 pSData->isValid = FALSE; // set flag to invalid
3591 }
3592 i++;
3593 }
3594 }
3595
3596 return (DD_OK);
3597}
3598
3599//******************************************************************************
3600//******************************************************************************
3601IDirectDrawSurface4Vtbl DDrawSurfaceV4Table =
3602{
3603 SurfQueryInterface,
3604 SurfAddRef,
3605 SurfRelease,
3606 SurfAddAttachedSurface4,
3607 SurfAddOverlayDirtyRect,
3608 SurfBlt4,
3609 SurfBltBatch,
3610 SurfBltFast4,
3611 SurfDeleteAttachedSurface4,
3612 SurfEnumAttachedSurfaces4,
3613 SurfEnumOverlayZOrders4,
3614 SurfFlip4,
3615 SurfGetAttachedSurface4,
3616 SurfGetBltStatus,
3617 SurfGetCaps4,
3618 SurfGetClipper,
3619 SurfGetColorKey,
3620 SurfGetDC,
3621 SurfGetFlipStatus,
3622 SurfGetOverlayPosition,
3623 SurfGetPalette,
3624 SurfGetPixelFormat,
3625 SurfGetSurfaceDesc4,
3626 SurfInitialize4,
3627 SurfIsLost,
3628 SurfLock4,
3629 SurfReleaseDC,
3630 SurfRestore,
3631 SurfSetClipper,
3632 SurfSetColorKey,
3633 SurfSetOverlayPosition,
3634 SurfSetPalette,
3635 SurfUnlock4,
3636 SurfUpdateOverlay4,
3637 SurfUpdateOverlayDisplay,
3638 SurfUpdateOverlayZOrder4,
3639 SurfGetDDInterface,
3640 SurfPageLock,
3641 SurfPageUnlock,
3642 SurfSetSurfaceDesc4,
3643 SurfSetPrivateData,
3644 SurfGetPrivateData,
3645 SurfFreePrivateData,
3646 SurfGetUniquenessValue,
3647 SurfChangeUniquenessValue
3648};
3649//******************************************************************************
3650//******************************************************************************
3651IDirectDrawSurface3Vtbl DDrawSurfaceV3Table =
3652{
3653 SurfQueryInterface,
3654 SurfAddRef,
3655 SurfRelease,
3656 SurfAddAttachedSurface3,
3657 SurfAddOverlayDirtyRect,
3658 SurfBlt3,
3659 SurfBltBatch,
3660 SurfBltFast3,
3661 SurfDeleteAttachedSurface3,
3662 SurfEnumAttachedSurfaces,
3663 SurfEnumOverlayZOrders,
3664 SurfFlip3,
3665 SurfGetAttachedSurface3,
3666 SurfGetBltStatus,
3667 SurfGetCaps,
3668 SurfGetClipper,
3669 SurfGetColorKey,
3670 SurfGetDC,
3671 SurfGetFlipStatus,
3672 SurfGetOverlayPosition,
3673 SurfGetPalette,
3674 SurfGetPixelFormat,
3675 SurfGetSurfaceDesc,
3676 SurfInitialize,
3677 SurfIsLost,
3678 SurfLock,
3679 SurfReleaseDC,
3680 SurfRestore,
3681 SurfSetClipper,
3682 SurfSetColorKey,
3683 SurfSetOverlayPosition,
3684 SurfSetPalette,
3685 SurfUnlock,
3686 SurfUpdateOverlay3,
3687 SurfUpdateOverlayDisplay,
3688 SurfUpdateOverlayZOrder3,
3689 SurfGetDDInterface,
3690 SurfPageLock,
3691 SurfPageUnlock,
3692 SurfSetSurfaceDesc
3693};
3694//******************************************************************************
3695//******************************************************************************
3696IDirectDrawSurface2Vtbl DDrawSurfaceV2Table =
3697{
3698 SurfQueryInterface,
3699 SurfAddRef,
3700 SurfRelease,
3701 SurfAddAttachedSurface,
3702 SurfAddOverlayDirtyRect,
3703 SurfBlt,
3704 SurfBltBatch,
3705 SurfBltFast,
3706 SurfDeleteAttachedSurface,
3707 SurfEnumAttachedSurfaces,
3708 SurfEnumOverlayZOrders,
3709 SurfFlip,
3710 SurfGetAttachedSurface,
3711 SurfGetBltStatus,
3712 SurfGetCaps,
3713 SurfGetClipper,
3714 SurfGetColorKey,
3715 SurfGetDC,
3716 SurfGetFlipStatus,
3717 SurfGetOverlayPosition,
3718 SurfGetPalette,
3719 SurfGetPixelFormat,
3720 SurfGetSurfaceDesc,
3721 SurfInitialize,
3722 SurfIsLost,
3723 SurfLock,
3724 SurfReleaseDC,
3725 SurfRestore,
3726 SurfSetClipper,
3727 SurfSetColorKey,
3728 SurfSetOverlayPosition,
3729 SurfSetPalette,
3730 SurfUnlock,
3731 SurfUpdateOverlay,
3732 SurfUpdateOverlayDisplay,
3733 SurfUpdateOverlayZOrder,
3734 SurfGetDDInterface,
3735 SurfPageLock,
3736 SurfPageUnlock
3737};
3738//******************************************************************************
3739//******************************************************************************
Note: See TracBrowser for help on using the repository browser.