source: trunk/src/ddraw/surface.cpp@ 21483

Last change on this file since 21483 was 21483, checked in by dmik, 15 years ago

ddraw: Don't define CINTERFACE twice.

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