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

Last change on this file since 9566 was 9566, checked in by sandervl, 23 years ago

Fixed pitch for offscreen surfaces so it doesn't conflict with GetDIBits/SetDIBits alignment; Use GetDIBits & SetDIBits with negative height. Origin must be top left

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